1 // SPDX-License-Identifier: GPL-2.0-only
3 * exynos_ppmu.c - Exynos PPMU (Platform Performance Monitoring Unit) support
5 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
6 * Author : Chanwoo Choi <cw00.choi@samsung.com>
8 * This driver is based on drivers/devfreq/exynos/exynos_ppmu.c
11 #include <linux/clk.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of_address.h>
16 #include <linux/of_device.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
19 #include <linux/suspend.h>
20 #include <linux/devfreq-event.h>
22 #include "exynos-ppmu.h"
24 enum exynos_ppmu_type
{
29 struct exynos_ppmu_data
{
34 struct devfreq_event_dev
**edev
;
35 struct devfreq_event_desc
*desc
;
36 unsigned int num_events
;
39 struct regmap
*regmap
;
41 struct exynos_ppmu_data ppmu
;
42 enum exynos_ppmu_type ppmu_type
;
45 #define PPMU_EVENT(name) \
46 { "ppmu-event0-"#name, PPMU_PMNCNT0 }, \
47 { "ppmu-event1-"#name, PPMU_PMNCNT1 }, \
48 { "ppmu-event2-"#name, PPMU_PMNCNT2 }, \
49 { "ppmu-event3-"#name, PPMU_PMNCNT3 }
51 static struct __exynos_ppmu_events
{
55 /* For Exynos3250, Exynos4 and Exynos5260 */
59 /* For Exynos4 SoCs and Exynos3250 */
68 /* Only for Exynos3250 and Exynos5260 */
71 /* Only for Exynos4 SoCs */
73 PPMU_EVENT(mfc
-right
),
75 /* Only for Exynos5260 SoCs */
89 /* Only for Exynos5433 SoCs */
91 PPMU_EVENT(d0
-general
),
94 PPMU_EVENT(d1
-general
),
97 /* For Exynos5422 SoC */
104 static int __exynos_ppmu_find_ppmu_id(const char *edev_name
)
108 for (i
= 0; i
< ARRAY_SIZE(ppmu_events
); i
++)
109 if (!strcmp(edev_name
, ppmu_events
[i
].name
))
110 return ppmu_events
[i
].id
;
115 static int exynos_ppmu_find_ppmu_id(struct devfreq_event_dev
*edev
)
117 return __exynos_ppmu_find_ppmu_id(edev
->desc
->name
);
121 * The devfreq-event ops structure for PPMU v1.1
123 static int exynos_ppmu_disable(struct devfreq_event_dev
*edev
)
125 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
129 /* Disable all counters */
130 ret
= regmap_write(info
->regmap
, PPMU_CNTENC
,
140 ret
= regmap_read(info
->regmap
, PPMU_PMNC
, &pmnc
);
144 pmnc
&= ~PPMU_PMNC_ENABLE_MASK
;
145 ret
= regmap_write(info
->regmap
, PPMU_PMNC
, pmnc
);
152 static int exynos_ppmu_set_event(struct devfreq_event_dev
*edev
)
154 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
155 int id
= exynos_ppmu_find_ppmu_id(edev
);
162 /* Enable specific counter */
163 ret
= regmap_read(info
->regmap
, PPMU_CNTENS
, &cntens
);
167 cntens
|= (PPMU_CCNT_MASK
| (PPMU_ENABLE
<< id
));
168 ret
= regmap_write(info
->regmap
, PPMU_CNTENS
, cntens
);
172 /* Set the event of proper data type monitoring */
173 ret
= regmap_write(info
->regmap
, PPMU_BEVTxSEL(id
),
174 edev
->desc
->event_type
);
178 /* Reset cycle counter/performance counter and enable PPMU */
179 ret
= regmap_read(info
->regmap
, PPMU_PMNC
, &pmnc
);
183 pmnc
&= ~(PPMU_PMNC_ENABLE_MASK
184 | PPMU_PMNC_COUNTER_RESET_MASK
185 | PPMU_PMNC_CC_RESET_MASK
);
186 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_ENABLE_SHIFT
);
187 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_COUNTER_RESET_SHIFT
);
188 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_CC_RESET_SHIFT
);
189 ret
= regmap_write(info
->regmap
, PPMU_PMNC
, pmnc
);
196 static int exynos_ppmu_get_event(struct devfreq_event_dev
*edev
,
197 struct devfreq_event_data
*edata
)
199 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
200 int id
= exynos_ppmu_find_ppmu_id(edev
);
201 unsigned int total_count
, load_count
;
202 unsigned int pmcnt3_high
, pmcnt3_low
;
203 unsigned int pmnc
, cntenc
;
210 ret
= regmap_read(info
->regmap
, PPMU_PMNC
, &pmnc
);
214 pmnc
&= ~PPMU_PMNC_ENABLE_MASK
;
215 ret
= regmap_write(info
->regmap
, PPMU_PMNC
, pmnc
);
219 /* Read cycle count */
220 ret
= regmap_read(info
->regmap
, PPMU_CCNT
, &total_count
);
223 edata
->total_count
= total_count
;
225 /* Read performance count */
230 ret
= regmap_read(info
->regmap
, PPMU_PMNCT(id
), &load_count
);
233 edata
->load_count
= load_count
;
236 ret
= regmap_read(info
->regmap
, PPMU_PMCNT3_HIGH
, &pmcnt3_high
);
240 ret
= regmap_read(info
->regmap
, PPMU_PMCNT3_LOW
, &pmcnt3_low
);
244 edata
->load_count
= ((pmcnt3_high
<< 8) | pmcnt3_low
);
250 /* Disable specific counter */
251 ret
= regmap_read(info
->regmap
, PPMU_CNTENC
, &cntenc
);
255 cntenc
|= (PPMU_CCNT_MASK
| (PPMU_ENABLE
<< id
));
256 ret
= regmap_write(info
->regmap
, PPMU_CNTENC
, cntenc
);
260 dev_dbg(&edev
->dev
, "%s (event: %ld/%ld)\n", edev
->desc
->name
,
261 edata
->load_count
, edata
->total_count
);
266 static const struct devfreq_event_ops exynos_ppmu_ops
= {
267 .disable
= exynos_ppmu_disable
,
268 .set_event
= exynos_ppmu_set_event
,
269 .get_event
= exynos_ppmu_get_event
,
273 * The devfreq-event ops structure for PPMU v2.0
275 static int exynos_ppmu_v2_disable(struct devfreq_event_dev
*edev
)
277 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
281 /* Disable all counters */
282 clear
= (PPMU_CCNT_MASK
| PPMU_PMCNT0_MASK
| PPMU_PMCNT1_MASK
283 | PPMU_PMCNT2_MASK
| PPMU_PMCNT3_MASK
);
284 ret
= regmap_write(info
->regmap
, PPMU_V2_FLAG
, clear
);
288 ret
= regmap_write(info
->regmap
, PPMU_V2_INTENC
, clear
);
292 ret
= regmap_write(info
->regmap
, PPMU_V2_CNTENC
, clear
);
296 ret
= regmap_write(info
->regmap
, PPMU_V2_CNT_RESET
, clear
);
300 ret
= regmap_write(info
->regmap
, PPMU_V2_CIG_CFG0
, 0x0);
304 ret
= regmap_write(info
->regmap
, PPMU_V2_CIG_CFG1
, 0x0);
308 ret
= regmap_write(info
->regmap
, PPMU_V2_CIG_CFG2
, 0x0);
312 ret
= regmap_write(info
->regmap
, PPMU_V2_CIG_RESULT
, 0x0);
316 ret
= regmap_write(info
->regmap
, PPMU_V2_CNT_AUTO
, 0x0);
320 ret
= regmap_write(info
->regmap
, PPMU_V2_CH_EV0_TYPE
, 0x0);
324 ret
= regmap_write(info
->regmap
, PPMU_V2_CH_EV1_TYPE
, 0x0);
328 ret
= regmap_write(info
->regmap
, PPMU_V2_CH_EV2_TYPE
, 0x0);
332 ret
= regmap_write(info
->regmap
, PPMU_V2_CH_EV3_TYPE
, 0x0);
336 ret
= regmap_write(info
->regmap
, PPMU_V2_SM_ID_V
, 0x0);
340 ret
= regmap_write(info
->regmap
, PPMU_V2_SM_ID_A
, 0x0);
344 ret
= regmap_write(info
->regmap
, PPMU_V2_SM_OTHERS_V
, 0x0);
348 ret
= regmap_write(info
->regmap
, PPMU_V2_SM_OTHERS_A
, 0x0);
352 ret
= regmap_write(info
->regmap
, PPMU_V2_INTERRUPT_RESET
, 0x0);
357 ret
= regmap_read(info
->regmap
, PPMU_V2_PMNC
, &pmnc
);
361 pmnc
&= ~PPMU_PMNC_ENABLE_MASK
;
362 ret
= regmap_write(info
->regmap
, PPMU_V2_PMNC
, pmnc
);
369 static int exynos_ppmu_v2_set_event(struct devfreq_event_dev
*edev
)
371 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
372 unsigned int pmnc
, cntens
;
373 int id
= exynos_ppmu_find_ppmu_id(edev
);
376 /* Enable all counters */
377 ret
= regmap_read(info
->regmap
, PPMU_V2_CNTENS
, &cntens
);
381 cntens
|= (PPMU_CCNT_MASK
| (PPMU_ENABLE
<< id
));
382 ret
= regmap_write(info
->regmap
, PPMU_V2_CNTENS
, cntens
);
386 /* Set the event of proper data type monitoring */
387 ret
= regmap_write(info
->regmap
, PPMU_V2_CH_EVx_TYPE(id
),
388 edev
->desc
->event_type
);
392 /* Reset cycle counter/performance counter and enable PPMU */
393 ret
= regmap_read(info
->regmap
, PPMU_V2_PMNC
, &pmnc
);
397 pmnc
&= ~(PPMU_PMNC_ENABLE_MASK
398 | PPMU_PMNC_COUNTER_RESET_MASK
399 | PPMU_PMNC_CC_RESET_MASK
400 | PPMU_PMNC_CC_DIVIDER_MASK
401 | PPMU_V2_PMNC_START_MODE_MASK
);
402 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_ENABLE_SHIFT
);
403 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_COUNTER_RESET_SHIFT
);
404 pmnc
|= (PPMU_ENABLE
<< PPMU_PMNC_CC_RESET_SHIFT
);
405 pmnc
|= (PPMU_V2_MODE_MANUAL
<< PPMU_V2_PMNC_START_MODE_SHIFT
);
407 ret
= regmap_write(info
->regmap
, PPMU_V2_PMNC
, pmnc
);
414 static int exynos_ppmu_v2_get_event(struct devfreq_event_dev
*edev
,
415 struct devfreq_event_data
*edata
)
417 struct exynos_ppmu
*info
= devfreq_event_get_drvdata(edev
);
418 int id
= exynos_ppmu_find_ppmu_id(edev
);
420 unsigned int pmnc
, cntenc
;
421 unsigned int pmcnt_high
, pmcnt_low
;
422 unsigned int total_count
, count
;
423 unsigned long load_count
= 0;
426 ret
= regmap_read(info
->regmap
, PPMU_V2_PMNC
, &pmnc
);
430 pmnc
&= ~PPMU_PMNC_ENABLE_MASK
;
431 ret
= regmap_write(info
->regmap
, PPMU_V2_PMNC
, pmnc
);
435 /* Read cycle count and performance count */
436 ret
= regmap_read(info
->regmap
, PPMU_V2_CCNT
, &total_count
);
439 edata
->total_count
= total_count
;
445 ret
= regmap_read(info
->regmap
, PPMU_V2_PMNCT(id
), &count
);
451 ret
= regmap_read(info
->regmap
, PPMU_V2_PMCNT3_HIGH
,
456 ret
= regmap_read(info
->regmap
, PPMU_V2_PMCNT3_LOW
, &pmcnt_low
);
460 load_count
= ((u64
)((pmcnt_high
& 0xff)) << 32)+ (u64
)pmcnt_low
;
463 edata
->load_count
= load_count
;
465 /* Disable all counters */
466 ret
= regmap_read(info
->regmap
, PPMU_V2_CNTENC
, &cntenc
);
470 cntenc
|= (PPMU_CCNT_MASK
| (PPMU_ENABLE
<< id
));
471 ret
= regmap_write(info
->regmap
, PPMU_V2_CNTENC
, cntenc
);
475 dev_dbg(&edev
->dev
, "%25s (load: %ld / %ld)\n", edev
->desc
->name
,
476 edata
->load_count
, edata
->total_count
);
480 static const struct devfreq_event_ops exynos_ppmu_v2_ops
= {
481 .disable
= exynos_ppmu_v2_disable
,
482 .set_event
= exynos_ppmu_v2_set_event
,
483 .get_event
= exynos_ppmu_v2_get_event
,
486 static const struct of_device_id exynos_ppmu_id_match
[] = {
488 .compatible
= "samsung,exynos-ppmu",
489 .data
= (void *)EXYNOS_TYPE_PPMU
,
491 .compatible
= "samsung,exynos-ppmu-v2",
492 .data
= (void *)EXYNOS_TYPE_PPMU_V2
,
496 MODULE_DEVICE_TABLE(of
, exynos_ppmu_id_match
);
498 static int of_get_devfreq_events(struct device_node
*np
,
499 struct exynos_ppmu
*info
)
501 struct devfreq_event_desc
*desc
;
502 struct device
*dev
= info
->dev
;
503 struct device_node
*events_np
, *node
;
505 const struct of_device_id
*of_id
;
508 events_np
= of_get_child_by_name(np
, "events");
511 "failed to get child node of devfreq-event devices\n");
515 count
= of_get_child_count(events_np
);
516 desc
= devm_kcalloc(dev
, count
, sizeof(*desc
), GFP_KERNEL
);
519 info
->num_events
= count
;
521 of_id
= of_match_device(exynos_ppmu_id_match
, dev
);
523 info
->ppmu_type
= (enum exynos_ppmu_type
)of_id
->data
;
528 for_each_child_of_node(events_np
, node
) {
529 for (i
= 0; i
< ARRAY_SIZE(ppmu_events
); i
++) {
530 if (!ppmu_events
[i
].name
)
533 if (of_node_name_eq(node
, ppmu_events
[i
].name
))
537 if (i
== ARRAY_SIZE(ppmu_events
)) {
539 "don't know how to configure events : %pOFn\n",
544 switch (info
->ppmu_type
) {
545 case EXYNOS_TYPE_PPMU
:
546 desc
[j
].ops
= &exynos_ppmu_ops
;
548 case EXYNOS_TYPE_PPMU_V2
:
549 desc
[j
].ops
= &exynos_ppmu_v2_ops
;
553 desc
[j
].driver_data
= info
;
555 of_property_read_string(node
, "event-name", &desc
[j
].name
);
556 ret
= of_property_read_u32(node
, "event-data-type",
557 &desc
[j
].event_type
);
559 /* Set the event of proper data type counting.
560 * Check if the data type has been defined in DT,
561 * use default if not.
563 if (info
->ppmu_type
== EXYNOS_TYPE_PPMU_V2
) {
565 /* Not all registers take the same value for
566 * read+write data count.
568 id
= __exynos_ppmu_find_ppmu_id(desc
[j
].name
);
574 desc
[j
].event_type
= PPMU_V2_RO_DATA_CNT
575 | PPMU_V2_WO_DATA_CNT
;
579 PPMU_V2_EVT3_RW_DATA_CNT
;
583 desc
[j
].event_type
= PPMU_RO_DATA_CNT
|
592 of_node_put(events_np
);
597 static struct regmap_config exynos_ppmu_regmap_config
= {
603 static int exynos_ppmu_parse_dt(struct platform_device
*pdev
,
604 struct exynos_ppmu
*info
)
606 struct device
*dev
= info
->dev
;
607 struct device_node
*np
= dev
->of_node
;
608 struct resource
*res
;
613 dev_err(dev
, "failed to find devicetree node\n");
617 /* Maps the memory mapped IO to control PPMU register */
618 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
619 base
= devm_ioremap_resource(dev
, res
);
621 return PTR_ERR(base
);
623 exynos_ppmu_regmap_config
.max_register
= resource_size(res
) - 4;
624 info
->regmap
= devm_regmap_init_mmio(dev
, base
,
625 &exynos_ppmu_regmap_config
);
626 if (IS_ERR(info
->regmap
)) {
627 dev_err(dev
, "failed to initialize regmap\n");
628 return PTR_ERR(info
->regmap
);
631 info
->ppmu
.clk
= devm_clk_get(dev
, "ppmu");
632 if (IS_ERR(info
->ppmu
.clk
)) {
633 info
->ppmu
.clk
= NULL
;
634 dev_warn(dev
, "cannot get PPMU clock\n");
637 ret
= of_get_devfreq_events(np
, info
);
639 dev_err(dev
, "failed to parse exynos ppmu dt node\n");
646 static int exynos_ppmu_probe(struct platform_device
*pdev
)
648 struct exynos_ppmu
*info
;
649 struct devfreq_event_dev
**edev
;
650 struct devfreq_event_desc
*desc
;
651 int i
, ret
= 0, size
;
653 info
= devm_kzalloc(&pdev
->dev
, sizeof(*info
), GFP_KERNEL
);
657 info
->dev
= &pdev
->dev
;
659 /* Parse dt data to get resource */
660 ret
= exynos_ppmu_parse_dt(pdev
, info
);
663 "failed to parse devicetree for resource\n");
668 size
= sizeof(struct devfreq_event_dev
*) * info
->num_events
;
669 info
->edev
= devm_kzalloc(&pdev
->dev
, size
, GFP_KERNEL
);
674 platform_set_drvdata(pdev
, info
);
676 for (i
= 0; i
< info
->num_events
; i
++) {
677 edev
[i
] = devm_devfreq_event_add_edev(&pdev
->dev
, &desc
[i
]);
678 if (IS_ERR(edev
[i
])) {
680 "failed to add devfreq-event device\n");
681 return PTR_ERR(edev
[i
]);
684 pr_info("exynos-ppmu: new PPMU device registered %s (%s)\n",
685 dev_name(&pdev
->dev
), desc
[i
].name
);
688 ret
= clk_prepare_enable(info
->ppmu
.clk
);
690 dev_err(&pdev
->dev
, "failed to prepare ppmu clock\n");
697 static int exynos_ppmu_remove(struct platform_device
*pdev
)
699 struct exynos_ppmu
*info
= platform_get_drvdata(pdev
);
701 clk_disable_unprepare(info
->ppmu
.clk
);
706 static struct platform_driver exynos_ppmu_driver
= {
707 .probe
= exynos_ppmu_probe
,
708 .remove
= exynos_ppmu_remove
,
710 .name
= "exynos-ppmu",
711 .of_match_table
= exynos_ppmu_id_match
,
714 module_platform_driver(exynos_ppmu_driver
);
716 MODULE_DESCRIPTION("Exynos PPMU(Platform Performance Monitoring Unit) driver");
717 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
718 MODULE_LICENSE("GPL");