aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/cci.txt2
-rw-r--r--drivers/bus/Kconfig8
-rw-r--r--drivers/bus/arm-cci.c85
3 files changed, 90 insertions, 5 deletions
diff --git a/Documentation/devicetree/bindings/arm/cci.txt b/Documentation/devicetree/bindings/arm/cci.txt
index aef1d200a9b2..a1a5a7ecc2fb 100644
--- a/Documentation/devicetree/bindings/arm/cci.txt
+++ b/Documentation/devicetree/bindings/arm/cci.txt
@@ -34,6 +34,7 @@ specific to ARM.
34 Definition: must contain one of the following: 34 Definition: must contain one of the following:
35 "arm,cci-400" 35 "arm,cci-400"
36 "arm,cci-500" 36 "arm,cci-500"
37 "arm,cci-550"
37 38
38 - reg 39 - reg
39 Usage: required 40 Usage: required
@@ -101,6 +102,7 @@ specific to ARM.
101 "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has 102 "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has
102 secure acces to CCI registers 103 secure acces to CCI registers
103 "arm,cci-500-pmu,r0" 104 "arm,cci-500-pmu,r0"
105 "arm,cci-550-pmu,r0"
104 - reg: 106 - reg:
105 Usage: required 107 Usage: required
106 Value type: Integer cells. A register entry, expressed 108 Value type: Integer cells. A register entry, expressed
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index e25a850799b3..6eff571731b1 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -35,14 +35,14 @@ config ARM_CCI400_PORT_CTRL
35 interconnect for ARM platforms. 35 interconnect for ARM platforms.
36 36
37config ARM_CCI5xx_PMU 37config ARM_CCI5xx_PMU
38 bool "ARM CCI500 PMU support" 38 bool "ARM CCI-500/CCI-550 PMU support"
39 depends on (ARM && CPU_V7) || ARM64 39 depends on (ARM && CPU_V7) || ARM64
40 depends on PERF_EVENTS 40 depends on PERF_EVENTS
41 select ARM_CCI_PMU 41 select ARM_CCI_PMU
42 help 42 help
43 Support for PMU events monitoring on the ARM CCI-500 cache coherent 43 Support for PMU events monitoring on the ARM CCI-500/CCI-550 cache
44 interconnect. CCI-500 provides 8 independent event counters, which 44 coherent interconnects. Both of them provide 8 independent event counters,
45 can count events pertaining to the slave/master interfaces as well 45 which can count events pertaining to the slave/master interfaces as well
46 as the internal events to the CCI. 46 as the internal events to the CCI.
47 47
48 If unsure, say Y 48 If unsure, say Y
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c
index 683e289145d7..494bd39f8434 100644
--- a/drivers/bus/arm-cci.c
+++ b/drivers/bus/arm-cci.c
@@ -54,6 +54,7 @@ static const struct of_device_id arm_cci_matches[] = {
54#endif 54#endif
55#ifdef CONFIG_ARM_CCI5xx_PMU 55#ifdef CONFIG_ARM_CCI5xx_PMU
56 { .compatible = "arm,cci-500", }, 56 { .compatible = "arm,cci-500", },
57 { .compatible = "arm,cci-550", },
57#endif 58#endif
58 {}, 59 {},
59}; 60};
@@ -156,6 +157,7 @@ enum cci_models {
156#endif 157#endif
157#ifdef CONFIG_ARM_CCI5xx_PMU 158#ifdef CONFIG_ARM_CCI5xx_PMU
158 CCI500_R0, 159 CCI500_R0,
160 CCI550_R0,
159#endif 161#endif
160 CCI_MODEL_MAX 162 CCI_MODEL_MAX
161}; 163};
@@ -451,6 +453,7 @@ static inline struct cci_pmu_model *probe_cci_model(struct platform_device *pdev
451#define CCI5xx_PORT_M3 0xb 453#define CCI5xx_PORT_M3 0xb
452#define CCI5xx_PORT_M4 0xc 454#define CCI5xx_PORT_M4 0xc
453#define CCI5xx_PORT_M5 0xd 455#define CCI5xx_PORT_M5 0xd
456#define CCI5xx_PORT_M6 0xe
454 457
455#define CCI5xx_PORT_GLOBAL 0xf 458#define CCI5xx_PORT_GLOBAL 0xf
456 459
@@ -611,6 +614,58 @@ static int cci500_validate_hw_event(struct cci_pmu *cci_pmu,
611 return -ENOENT; 614 return -ENOENT;
612} 615}
613 616
617/*
618 * CCI550 provides 8 independent event counters that can count
619 * any of the events available.
620 * CCI550 PMU event source ids
621 * 0x0-0x6 - Slave interfaces
622 * 0x8-0xe - Master interfaces
623 * 0xf - Global Events
624 * 0x7 - Reserved
625 */
626static int cci550_validate_hw_event(struct cci_pmu *cci_pmu,
627 unsigned long hw_event)
628{
629 u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event);
630 u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event);
631 int if_type;
632
633 if (hw_event & ~CCI5xx_PMU_EVENT_MASK)
634 return -ENOENT;
635
636 switch (ev_source) {
637 case CCI5xx_PORT_S0:
638 case CCI5xx_PORT_S1:
639 case CCI5xx_PORT_S2:
640 case CCI5xx_PORT_S3:
641 case CCI5xx_PORT_S4:
642 case CCI5xx_PORT_S5:
643 case CCI5xx_PORT_S6:
644 if_type = CCI_IF_SLAVE;
645 break;
646 case CCI5xx_PORT_M0:
647 case CCI5xx_PORT_M1:
648 case CCI5xx_PORT_M2:
649 case CCI5xx_PORT_M3:
650 case CCI5xx_PORT_M4:
651 case CCI5xx_PORT_M5:
652 case CCI5xx_PORT_M6:
653 if_type = CCI_IF_MASTER;
654 break;
655 case CCI5xx_PORT_GLOBAL:
656 if_type = CCI_IF_GLOBAL;
657 break;
658 default:
659 return -ENOENT;
660 }
661
662 if (ev_code >= cci_pmu->model->event_ranges[if_type].min &&
663 ev_code <= cci_pmu->model->event_ranges[if_type].max)
664 return hw_event;
665
666 return -ENOENT;
667}
668
614#endif /* CONFIG_ARM_CCI5xx_PMU */ 669#endif /* CONFIG_ARM_CCI5xx_PMU */
615 670
616/* 671/*
@@ -898,7 +953,7 @@ static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask)
898#ifdef CONFIG_ARM_CCI5xx_PMU 953#ifdef CONFIG_ARM_CCI5xx_PMU
899 954
900/* 955/*
901 * CCI-500 has advanced power saving policies, which could gate the 956 * CCI-500/CCI-550 has advanced power saving policies, which could gate the
902 * clocks to the PMU counters, which makes the writes to them ineffective. 957 * clocks to the PMU counters, which makes the writes to them ineffective.
903 * The only way to write to those counters is when the global counters 958 * The only way to write to those counters is when the global counters
904 * are enabled and the particular counter is enabled. 959 * are enabled and the particular counter is enabled.
@@ -1546,6 +1601,30 @@ static struct cci_pmu_model cci_pmu_models[] = {
1546 .validate_hw_event = cci500_validate_hw_event, 1601 .validate_hw_event = cci500_validate_hw_event,
1547 .write_counters = cci5xx_pmu_write_counters, 1602 .write_counters = cci5xx_pmu_write_counters,
1548 }, 1603 },
1604 [CCI550_R0] = {
1605 .name = "CCI_550",
1606 .fixed_hw_cntrs = 0,
1607 .num_hw_cntrs = 8,
1608 .cntr_size = SZ_64K,
1609 .format_attrs = cci5xx_pmu_format_attrs,
1610 .event_attrs = cci5xx_pmu_event_attrs,
1611 .event_ranges = {
1612 [CCI_IF_SLAVE] = {
1613 CCI5xx_SLAVE_PORT_MIN_EV,
1614 CCI5xx_SLAVE_PORT_MAX_EV,
1615 },
1616 [CCI_IF_MASTER] = {
1617 CCI5xx_MASTER_PORT_MIN_EV,
1618 CCI5xx_MASTER_PORT_MAX_EV,
1619 },
1620 [CCI_IF_GLOBAL] = {
1621 CCI5xx_GLOBAL_PORT_MIN_EV,
1622 CCI5xx_GLOBAL_PORT_MAX_EV,
1623 },
1624 },
1625 .validate_hw_event = cci550_validate_hw_event,
1626 .write_counters = cci5xx_pmu_write_counters,
1627 },
1549#endif 1628#endif
1550}; 1629};
1551 1630
@@ -1569,6 +1648,10 @@ static const struct of_device_id arm_cci_pmu_matches[] = {
1569 .compatible = "arm,cci-500-pmu,r0", 1648 .compatible = "arm,cci-500-pmu,r0",
1570 .data = &cci_pmu_models[CCI500_R0], 1649 .data = &cci_pmu_models[CCI500_R0],
1571 }, 1650 },
1651 {
1652 .compatible = "arm,cci-550-pmu,r0",
1653 .data = &cci_pmu_models[CCI550_R0],
1654 },
1572#endif 1655#endif
1573 {}, 1656 {},
1574}; 1657};