aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/mmdc.c
diff options
context:
space:
mode:
authorFrank Li <Frank.Li@nxp.com>2016-11-07 12:30:48 -0500
committerShawn Guo <shawnguo@kernel.org>2016-11-14 00:34:45 -0500
commitc47c6fe41c152a1b6dd5c195bdea06c24cf2ac30 (patch)
tree74cb6c3b0a2fcf7ba7deab764c4910fd312dc4b1 /arch/arm/mach-imx/mmdc.c
parente76bdfd7403aae582461901955d0136381e34435 (diff)
ARM: imx: mmdc perf function support i.MX6QP
i.MX6QP added new register bit PROFILE_SEL in MADPCR0. need set it at perf start. Signed-off-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
Diffstat (limited to 'arch/arm/mach-imx/mmdc.c')
-rw-r--r--arch/arm/mach-imx/mmdc.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c
index d82d14ceb2e9..ba96bf979625 100644
--- a/arch/arm/mach-imx/mmdc.c
+++ b/arch/arm/mach-imx/mmdc.c
@@ -44,6 +44,7 @@
44#define DBG_RST 0x2 44#define DBG_RST 0x2
45#define PRF_FRZ 0x4 45#define PRF_FRZ 0x4
46#define CYC_OVF 0x8 46#define CYC_OVF 0x8
47#define PROFILE_SEL 0x10
47 48
48#define MMDC_MADPCR0 0x410 49#define MMDC_MADPCR0 0x410
49#define MMDC_MADPSR0 0x418 50#define MMDC_MADPSR0 0x418
@@ -55,10 +56,29 @@
55 56
56#define MMDC_NUM_COUNTERS 6 57#define MMDC_NUM_COUNTERS 6
57 58
59#define MMDC_FLAG_PROFILE_SEL 0x1
60
58#define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu) 61#define to_mmdc_pmu(p) container_of(p, struct mmdc_pmu, pmu)
59 62
60static int ddr_type; 63static int ddr_type;
61 64
65struct fsl_mmdc_devtype_data {
66 unsigned int flags;
67};
68
69static const struct fsl_mmdc_devtype_data imx6q_data = {
70};
71
72static const struct fsl_mmdc_devtype_data imx6qp_data = {
73 .flags = MMDC_FLAG_PROFILE_SEL,
74};
75
76static const struct of_device_id imx_mmdc_dt_ids[] = {
77 { .compatible = "fsl,imx6q-mmdc", .data = (void *)&imx6q_data},
78 { .compatible = "fsl,imx6qp-mmdc", .data = (void *)&imx6qp_data},
79 { /* sentinel */ }
80};
81
62#ifdef CONFIG_PERF_EVENTS 82#ifdef CONFIG_PERF_EVENTS
63 83
64static DEFINE_IDA(mmdc_ida); 84static DEFINE_IDA(mmdc_ida);
@@ -83,6 +103,7 @@ struct mmdc_pmu {
83 struct device *dev; 103 struct device *dev;
84 struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; 104 struct perf_event *mmdc_events[MMDC_NUM_COUNTERS];
85 struct hlist_node node; 105 struct hlist_node node;
106 struct fsl_mmdc_devtype_data *devtype_data;
86}; 107};
87 108
88/* 109/*
@@ -307,6 +328,7 @@ static void mmdc_pmu_event_start(struct perf_event *event, int flags)
307 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); 328 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu);
308 struct hw_perf_event *hwc = &event->hw; 329 struct hw_perf_event *hwc = &event->hw;
309 void __iomem *mmdc_base, *reg; 330 void __iomem *mmdc_base, *reg;
331 u32 val;
310 332
311 mmdc_base = pmu_mmdc->mmdc_base; 333 mmdc_base = pmu_mmdc->mmdc_base;
312 reg = mmdc_base + MMDC_MADPCR0; 334 reg = mmdc_base + MMDC_MADPCR0;
@@ -321,7 +343,12 @@ static void mmdc_pmu_event_start(struct perf_event *event, int flags)
321 local64_set(&hwc->prev_count, 0); 343 local64_set(&hwc->prev_count, 0);
322 344
323 writel(DBG_RST, reg); 345 writel(DBG_RST, reg);
324 writel(DBG_EN, reg); 346
347 val = DBG_EN;
348 if (pmu_mmdc->devtype_data->flags & MMDC_FLAG_PROFILE_SEL)
349 val |= PROFILE_SEL;
350
351 writel(val, reg);
325} 352}
326 353
327static int mmdc_pmu_event_add(struct perf_event *event, int flags) 354static int mmdc_pmu_event_add(struct perf_event *event, int flags)
@@ -436,6 +463,8 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
436 char *name; 463 char *name;
437 int mmdc_num; 464 int mmdc_num;
438 int ret; 465 int ret;
466 const struct of_device_id *of_id =
467 of_match_device(imx_mmdc_dt_ids, &pdev->dev);
439 468
440 pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL); 469 pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL);
441 if (!pmu_mmdc) { 470 if (!pmu_mmdc) {
@@ -450,6 +479,8 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b
450 name = devm_kasprintf(&pdev->dev, 479 name = devm_kasprintf(&pdev->dev,
451 GFP_KERNEL, "mmdc%d", mmdc_num); 480 GFP_KERNEL, "mmdc%d", mmdc_num);
452 481
482 pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data;
483
453 hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, 484 hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC,
454 HRTIMER_MODE_REL); 485 HRTIMER_MODE_REL);
455 pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler; 486 pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler;
@@ -524,11 +555,6 @@ int imx_mmdc_get_ddr_type(void)
524 return ddr_type; 555 return ddr_type;
525} 556}
526 557
527static const struct of_device_id imx_mmdc_dt_ids[] = {
528 { .compatible = "fsl,imx6q-mmdc", },
529 { /* sentinel */ }
530};
531
532static struct platform_driver imx_mmdc_driver = { 558static struct platform_driver imx_mmdc_driver = {
533 .driver = { 559 .driver = {
534 .name = "imx-mmdc", 560 .name = "imx-mmdc",