From 8d1a0ae724ad74ef7946a45e3b2d3e01f39df02b Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Wed, 13 Jan 2016 23:36:26 -0500 Subject: ARM: perf: Set ARMv7 SDER SUNIDEN bit ARMv7 counters other than the CPU cycle counter only work if the Secure Debug Enable Register (SDER) SUNIDEN bit is set. Since access to the SDER is only possible in secure state, it will only be done if the device tree property "secure-reg-access" is set. Without this: Performance counter stats for 'sleep 1': 14606094 cycles # 0.000 GHz 0 instructions # 0.00 insns per cycle After applying: Performance counter stats for 'sleep 1': 5843809 cycles 2566484 instructions # 0.44 insns per cycle 1.020144000 seconds time elapsed Some platforms (eg i.MX53) may also need additional platform specific setup. Acked-by: Rob Herring Signed-off-by: Martin Fuzzey Signed-off-by: Pooya Keshavarzi Signed-off-by: George G. Davis [will: add warning if property is found on arm64] Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/arm/pmu.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 56518839f52a..b6056d3bca06 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -46,6 +46,16 @@ Optional properties: - qcom,no-pc-write : Indicates that this PMU doesn't support the 0xc and 0xd events. +- secure-reg-access : Indicates that the ARMv7 Secure Debug Enable Register + (SDER) is accessible. This will cause the driver to do + any setup required that is only possible in ARMv7 secure + state. If not present the ARMv7 SDER will not be touched, + which means the PMU may fail to operate unless external + code (bootloader or security monitor) has performed the + appropriate initialisation. Note that this property is + not valid for non-ARMv7 CPUs or ARMv7 CPUs booting Linux + in Non-secure state. + Example: pmu { -- cgit v1.2.3-59-g8ed1b From 94085fe570e7b87597d4695e6fa77d4256efd29e Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Thu, 18 Feb 2016 17:50:12 +0100 Subject: arm64: dts: Add Cavium ThunderX specific PMU Add a compatible string for the Cavium ThunderX PMU. Signed-off-by: Jan Glauber Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/arm/pmu.txt | 1 + arch/arm64/boot/dts/cavium/thunder-88xx.dtsi | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index b6056d3bca06..6eb73be9433e 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -25,6 +25,7 @@ Required properties: "qcom,scorpion-pmu" "qcom,scorpion-mp-pmu" "qcom,krait-pmu" + "cavium,thunder-pmu" - interrupts : 1 combined interrupt or 1 per core. If the interrupt is a per-cpu interrupt (PPI) then 1 interrupt should be specified. diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi index 9cb7cf94284a..2eb9b225f0bc 100644 --- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi +++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi @@ -360,6 +360,11 @@ <1 10 0xff01>; }; + pmu { + compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3"; + interrupts = <1 7 4>; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; -- cgit v1.2.3-59-g8ed1b From d7dd5fd773497d7b63e7a35fcaa270c9f859432b Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Tue, 23 Feb 2016 10:49:55 +0000 Subject: arm-cci: CoreLink CCI-550 PMU driver Add ARM CoreLink CCI-550 cache coherent interconnect PMU driver support. The CCI-550 PMU shares all the attributes of CCI-500 PMU, except for an additional master interface (MI-6 - 0xe). CCI-550 requires the same work around as for CCI-500 to write to the PMU counter. Acked-by: Olof Johansson Acked-by: Punit Agrawal Acked-by: Mark Rutland Signed-off-by: Suzuki K Poulose Signed-off-by: Will Deacon --- Documentation/devicetree/bindings/arm/cci.txt | 2 + drivers/bus/Kconfig | 8 +-- drivers/bus/arm-cci.c | 85 ++++++++++++++++++++++++++- 3 files changed, 90 insertions(+), 5 deletions(-) (limited to 'Documentation') 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. Definition: must contain one of the following: "arm,cci-400" "arm,cci-500" + "arm,cci-550" - reg Usage: required @@ -101,6 +102,7 @@ specific to ARM. "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has secure acces to CCI registers "arm,cci-500-pmu,r0" + "arm,cci-550-pmu,r0" - reg: Usage: required 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 interconnect for ARM platforms. config ARM_CCI5xx_PMU - bool "ARM CCI500 PMU support" + bool "ARM CCI-500/CCI-550 PMU support" depends on (ARM && CPU_V7) || ARM64 depends on PERF_EVENTS select ARM_CCI_PMU help - Support for PMU events monitoring on the ARM CCI-500 cache coherent - interconnect. CCI-500 provides 8 independent event counters, which - can count events pertaining to the slave/master interfaces as well + Support for PMU events monitoring on the ARM CCI-500/CCI-550 cache + coherent interconnects. Both of them provide 8 independent event counters, + which can count events pertaining to the slave/master interfaces as well as the internal events to the CCI. 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[] = { #endif #ifdef CONFIG_ARM_CCI5xx_PMU { .compatible = "arm,cci-500", }, + { .compatible = "arm,cci-550", }, #endif {}, }; @@ -156,6 +157,7 @@ enum cci_models { #endif #ifdef CONFIG_ARM_CCI5xx_PMU CCI500_R0, + CCI550_R0, #endif CCI_MODEL_MAX }; @@ -451,6 +453,7 @@ static inline struct cci_pmu_model *probe_cci_model(struct platform_device *pdev #define CCI5xx_PORT_M3 0xb #define CCI5xx_PORT_M4 0xc #define CCI5xx_PORT_M5 0xd +#define CCI5xx_PORT_M6 0xe #define CCI5xx_PORT_GLOBAL 0xf @@ -611,6 +614,58 @@ static int cci500_validate_hw_event(struct cci_pmu *cci_pmu, return -ENOENT; } +/* + * CCI550 provides 8 independent event counters that can count + * any of the events available. + * CCI550 PMU event source ids + * 0x0-0x6 - Slave interfaces + * 0x8-0xe - Master interfaces + * 0xf - Global Events + * 0x7 - Reserved + */ +static int cci550_validate_hw_event(struct cci_pmu *cci_pmu, + unsigned long hw_event) +{ + u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event); + u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event); + int if_type; + + if (hw_event & ~CCI5xx_PMU_EVENT_MASK) + return -ENOENT; + + switch (ev_source) { + case CCI5xx_PORT_S0: + case CCI5xx_PORT_S1: + case CCI5xx_PORT_S2: + case CCI5xx_PORT_S3: + case CCI5xx_PORT_S4: + case CCI5xx_PORT_S5: + case CCI5xx_PORT_S6: + if_type = CCI_IF_SLAVE; + break; + case CCI5xx_PORT_M0: + case CCI5xx_PORT_M1: + case CCI5xx_PORT_M2: + case CCI5xx_PORT_M3: + case CCI5xx_PORT_M4: + case CCI5xx_PORT_M5: + case CCI5xx_PORT_M6: + if_type = CCI_IF_MASTER; + break; + case CCI5xx_PORT_GLOBAL: + if_type = CCI_IF_GLOBAL; + break; + default: + return -ENOENT; + } + + if (ev_code >= cci_pmu->model->event_ranges[if_type].min && + ev_code <= cci_pmu->model->event_ranges[if_type].max) + return hw_event; + + return -ENOENT; +} + #endif /* CONFIG_ARM_CCI5xx_PMU */ /* @@ -898,7 +953,7 @@ static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask) #ifdef CONFIG_ARM_CCI5xx_PMU /* - * CCI-500 has advanced power saving policies, which could gate the + * CCI-500/CCI-550 has advanced power saving policies, which could gate the * clocks to the PMU counters, which makes the writes to them ineffective. * The only way to write to those counters is when the global counters * are enabled and the particular counter is enabled. @@ -1546,6 +1601,30 @@ static struct cci_pmu_model cci_pmu_models[] = { .validate_hw_event = cci500_validate_hw_event, .write_counters = cci5xx_pmu_write_counters, }, + [CCI550_R0] = { + .name = "CCI_550", + .fixed_hw_cntrs = 0, + .num_hw_cntrs = 8, + .cntr_size = SZ_64K, + .format_attrs = cci5xx_pmu_format_attrs, + .event_attrs = cci5xx_pmu_event_attrs, + .event_ranges = { + [CCI_IF_SLAVE] = { + CCI5xx_SLAVE_PORT_MIN_EV, + CCI5xx_SLAVE_PORT_MAX_EV, + }, + [CCI_IF_MASTER] = { + CCI5xx_MASTER_PORT_MIN_EV, + CCI5xx_MASTER_PORT_MAX_EV, + }, + [CCI_IF_GLOBAL] = { + CCI5xx_GLOBAL_PORT_MIN_EV, + CCI5xx_GLOBAL_PORT_MAX_EV, + }, + }, + .validate_hw_event = cci550_validate_hw_event, + .write_counters = cci5xx_pmu_write_counters, + }, #endif }; @@ -1569,6 +1648,10 @@ static const struct of_device_id arm_cci_pmu_matches[] = { .compatible = "arm,cci-500-pmu,r0", .data = &cci_pmu_models[CCI500_R0], }, + { + .compatible = "arm,cci-550-pmu,r0", + .data = &cci_pmu_models[CCI550_R0], + }, #endif {}, }; -- cgit v1.2.3-59-g8ed1b