arch/arm/mach-imx/mmdc.c

Source file repositories/reference/linux-study-clean/arch/arm/mach-imx/mmdc.c

File Facts

System
Linux kernel
Corpus path
arch/arm/mach-imx/mmdc.c
Extension
.c
Size
14927 bytes
Lines
606
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fsl_mmdc_devtype_data {
	unsigned int flags;
};

static const struct fsl_mmdc_devtype_data imx6q_data = {
};

static const struct fsl_mmdc_devtype_data imx6qp_data = {
	.flags = MMDC_FLAG_PROFILE_SEL,
};

static const struct of_device_id imx_mmdc_dt_ids[] = {
	{ .compatible = "fsl,imx6q-mmdc", .data = (void *)&imx6q_data},
	{ .compatible = "fsl,imx6qp-mmdc", .data = (void *)&imx6qp_data},
	{ /* sentinel */ }
};

#ifdef CONFIG_PERF_EVENTS

static enum cpuhp_state cpuhp_mmdc_state;
static DEFINE_IDA(mmdc_ida);

PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00")
PMU_EVENT_ATTR_STRING(busy-cycles, mmdc_pmu_busy_cycles, "event=0x01")
PMU_EVENT_ATTR_STRING(read-accesses, mmdc_pmu_read_accesses, "event=0x02")
PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "event=0x03")
PMU_EVENT_ATTR_STRING(read-bytes, mmdc_pmu_read_bytes, "event=0x04")
PMU_EVENT_ATTR_STRING(read-bytes.unit, mmdc_pmu_read_bytes_unit, "MB");
PMU_EVENT_ATTR_STRING(read-bytes.scale, mmdc_pmu_read_bytes_scale, "0.000001");
PMU_EVENT_ATTR_STRING(write-bytes, mmdc_pmu_write_bytes, "event=0x05")
PMU_EVENT_ATTR_STRING(write-bytes.unit, mmdc_pmu_write_bytes_unit, "MB");
PMU_EVENT_ATTR_STRING(write-bytes.scale, mmdc_pmu_write_bytes_scale, "0.000001");

struct mmdc_pmu {
	struct pmu pmu;
	void __iomem *mmdc_base;
	cpumask_t cpu;
	struct hrtimer hrtimer;
	unsigned int active_events;
	int id;
	struct device *dev;
	struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
	struct hlist_node node;
	const struct fsl_mmdc_devtype_data *devtype_data;
	struct clk *mmdc_ipg_clk;
};

/*
 * Polling period is set to one second, overflow of total-cycles (the fastest
 * increasing counter) takes ten seconds so one second is safe
 */
static unsigned int mmdc_pmu_poll_period_us = 1000000;

module_param_named(pmu_pmu_poll_period_us, mmdc_pmu_poll_period_us, uint,
		S_IRUGO | S_IWUSR);

static ktime_t mmdc_pmu_timer_period(void)
{
	return ns_to_ktime((u64)mmdc_pmu_poll_period_us * 1000);
}

static ssize_t mmdc_pmu_cpumask_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct mmdc_pmu *pmu_mmdc = dev_get_drvdata(dev);

	return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu);
}

static struct device_attribute mmdc_pmu_cpumask_attr =
	__ATTR(cpumask, S_IRUGO, mmdc_pmu_cpumask_show, NULL);

static struct attribute *mmdc_pmu_cpumask_attrs[] = {
	&mmdc_pmu_cpumask_attr.attr,
	NULL,
};

static struct attribute_group mmdc_pmu_cpumask_attr_group = {
	.attrs = mmdc_pmu_cpumask_attrs,
};

static struct attribute *mmdc_pmu_events_attrs[] = {
	&mmdc_pmu_total_cycles.attr.attr,
	&mmdc_pmu_busy_cycles.attr.attr,
	&mmdc_pmu_read_accesses.attr.attr,
	&mmdc_pmu_write_accesses.attr.attr,
	&mmdc_pmu_read_bytes.attr.attr,
	&mmdc_pmu_read_bytes_unit.attr.attr,
	&mmdc_pmu_read_bytes_scale.attr.attr,
	&mmdc_pmu_write_bytes.attr.attr,

Annotation

Implementation Notes