diff options
| -rw-r--r-- | Documentation/devicetree/bindings/arm/cci.txt | 2 | ||||
| -rw-r--r-- | drivers/bus/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/bus/arm-cci.c | 85 |
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 | ||
| 37 | config ARM_CCI5xx_PMU | 37 | config 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 | */ | ||
| 626 | static 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 | }; |
