aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2013-01-23 12:17:52 -0500
committerWill Deacon <will.deacon@arm.com>2013-01-23 12:17:52 -0500
commit6abc749f635005be78dfcb562c2235511965db6d (patch)
tree885c469162ee1e518ca8715cef9dd58536991bf3
parent9931faca02c604c22335f5a935a501bb2ace6e20 (diff)
parent9dcbf466559f6f2f55d60eb5a1bbebc8e694b52a (diff)
Merge branch 'for-rmk/perf' into for-rmk/virt/kvm/core
-rw-r--r--arch/arm/include/asm/cputype.h33
-rw-r--r--arch/arm/kernel/perf_event.c16
-rw-r--r--arch/arm/kernel/perf_event_cpu.c51
-rw-r--r--arch/arm/kernel/perf_event_v6.c4
-rw-r--r--arch/arm/kernel/perf_event_v7.c18
-rw-r--r--arch/arm/kernel/perf_event_xscale.c2
6 files changed, 75 insertions, 49 deletions
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index a59dcb5ab5fc..ad41ec2471e8 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -64,6 +64,24 @@ extern unsigned int processor_id;
64#define read_cpuid_ext(reg) 0 64#define read_cpuid_ext(reg) 0
65#endif 65#endif
66 66
67#define ARM_CPU_IMP_ARM 0x41
68#define ARM_CPU_IMP_INTEL 0x69
69
70#define ARM_CPU_PART_ARM1136 0xB360
71#define ARM_CPU_PART_ARM1156 0xB560
72#define ARM_CPU_PART_ARM1176 0xB760
73#define ARM_CPU_PART_ARM11MPCORE 0xB020
74#define ARM_CPU_PART_CORTEX_A8 0xC080
75#define ARM_CPU_PART_CORTEX_A9 0xC090
76#define ARM_CPU_PART_CORTEX_A5 0xC050
77#define ARM_CPU_PART_CORTEX_A15 0xC0F0
78#define ARM_CPU_PART_CORTEX_A7 0xC070
79
80#define ARM_CPU_XSCALE_ARCH_MASK 0xe000
81#define ARM_CPU_XSCALE_ARCH_V1 0x2000
82#define ARM_CPU_XSCALE_ARCH_V2 0x4000
83#define ARM_CPU_XSCALE_ARCH_V3 0x6000
84
67/* 85/*
68 * The CPU ID never changes at run time, so we might as well tell the 86 * The CPU ID never changes at run time, so we might as well tell the
69 * compiler that it's constant. Use this function to read the CPU ID 87 * compiler that it's constant. Use this function to read the CPU ID
@@ -74,6 +92,21 @@ static inline unsigned int __attribute_const__ read_cpuid_id(void)
74 return read_cpuid(CPUID_ID); 92 return read_cpuid(CPUID_ID);
75} 93}
76 94
95static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
96{
97 return (read_cpuid_id() & 0xFF000000) >> 24;
98}
99
100static inline unsigned int __attribute_const__ read_cpuid_part_number(void)
101{
102 return read_cpuid_id() & 0xFFF0;
103}
104
105static inline unsigned int __attribute_const__ xscale_cpu_arch_version(void)
106{
107 return read_cpuid_part_number() & ARM_CPU_XSCALE_ARCH_MASK;
108}
109
77static inline unsigned int __attribute_const__ read_cpuid_cachetype(void) 110static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
78{ 111{
79 return read_cpuid(CPUID_CACHETYPE); 112 return read_cpuid(CPUID_CACHETYPE);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index f9e8657dd241..31e0eb353cd8 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -149,12 +149,6 @@ again:
149static void 149static void
150armpmu_read(struct perf_event *event) 150armpmu_read(struct perf_event *event)
151{ 151{
152 struct hw_perf_event *hwc = &event->hw;
153
154 /* Don't read disabled counters! */
155 if (hwc->idx < 0)
156 return;
157
158 armpmu_event_update(event); 152 armpmu_event_update(event);
159} 153}
160 154
@@ -207,8 +201,6 @@ armpmu_del(struct perf_event *event, int flags)
207 struct hw_perf_event *hwc = &event->hw; 201 struct hw_perf_event *hwc = &event->hw;
208 int idx = hwc->idx; 202 int idx = hwc->idx;
209 203
210 WARN_ON(idx < 0);
211
212 armpmu_stop(event, PERF_EF_UPDATE); 204 armpmu_stop(event, PERF_EF_UPDATE);
213 hw_events->events[idx] = NULL; 205 hw_events->events[idx] = NULL;
214 clear_bit(idx, hw_events->used_mask); 206 clear_bit(idx, hw_events->used_mask);
@@ -358,7 +350,7 @@ __hw_perf_event_init(struct perf_event *event)
358{ 350{
359 struct arm_pmu *armpmu = to_arm_pmu(event->pmu); 351 struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
360 struct hw_perf_event *hwc = &event->hw; 352 struct hw_perf_event *hwc = &event->hw;
361 int mapping, err; 353 int mapping;
362 354
363 mapping = armpmu->map_event(event); 355 mapping = armpmu->map_event(event);
364 356
@@ -407,14 +399,12 @@ __hw_perf_event_init(struct perf_event *event)
407 local64_set(&hwc->period_left, hwc->sample_period); 399 local64_set(&hwc->period_left, hwc->sample_period);
408 } 400 }
409 401
410 err = 0;
411 if (event->group_leader != event) { 402 if (event->group_leader != event) {
412 err = validate_group(event); 403 if (validate_group(event) != 0);
413 if (err)
414 return -EINVAL; 404 return -EINVAL;
415 } 405 }
416 406
417 return err; 407 return 0;
418} 408}
419 409
420static int armpmu_event_init(struct perf_event *event) 410static int armpmu_event_init(struct perf_event *event)
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 5f6620684e25..1f2740e3dbc0 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -147,7 +147,7 @@ static void cpu_pmu_init(struct arm_pmu *cpu_pmu)
147 cpu_pmu->free_irq = cpu_pmu_free_irq; 147 cpu_pmu->free_irq = cpu_pmu_free_irq;
148 148
149 /* Ensure the PMU has sane values out of reset. */ 149 /* Ensure the PMU has sane values out of reset. */
150 if (cpu_pmu && cpu_pmu->reset) 150 if (cpu_pmu->reset)
151 on_each_cpu(cpu_pmu->reset, cpu_pmu, 1); 151 on_each_cpu(cpu_pmu->reset, cpu_pmu, 1);
152} 152}
153 153
@@ -201,48 +201,46 @@ static struct platform_device_id cpu_pmu_plat_device_ids[] = {
201static int probe_current_pmu(struct arm_pmu *pmu) 201static int probe_current_pmu(struct arm_pmu *pmu)
202{ 202{
203 int cpu = get_cpu(); 203 int cpu = get_cpu();
204 unsigned long cpuid = read_cpuid_id(); 204 unsigned long implementor = read_cpuid_implementor();
205 unsigned long implementor = (cpuid & 0xFF000000) >> 24; 205 unsigned long part_number = read_cpuid_part_number();
206 unsigned long part_number = (cpuid & 0xFFF0);
207 int ret = -ENODEV; 206 int ret = -ENODEV;
208 207
209 pr_info("probing PMU on CPU %d\n", cpu); 208 pr_info("probing PMU on CPU %d\n", cpu);
210 209
211 /* ARM Ltd CPUs. */ 210 /* ARM Ltd CPUs. */
212 if (0x41 == implementor) { 211 if (implementor == ARM_CPU_IMP_ARM) {
213 switch (part_number) { 212 switch (part_number) {
214 case 0xB360: /* ARM1136 */ 213 case ARM_CPU_PART_ARM1136:
215 case 0xB560: /* ARM1156 */ 214 case ARM_CPU_PART_ARM1156:
216 case 0xB760: /* ARM1176 */ 215 case ARM_CPU_PART_ARM1176:
217 ret = armv6pmu_init(pmu); 216 ret = armv6pmu_init(pmu);
218 break; 217 break;
219 case 0xB020: /* ARM11mpcore */ 218 case ARM_CPU_PART_ARM11MPCORE:
220 ret = armv6mpcore_pmu_init(pmu); 219 ret = armv6mpcore_pmu_init(pmu);
221 break; 220 break;
222 case 0xC080: /* Cortex-A8 */ 221 case ARM_CPU_PART_CORTEX_A8:
223 ret = armv7_a8_pmu_init(pmu); 222 ret = armv7_a8_pmu_init(pmu);
224 break; 223 break;
225 case 0xC090: /* Cortex-A9 */ 224 case ARM_CPU_PART_CORTEX_A9:
226 ret = armv7_a9_pmu_init(pmu); 225 ret = armv7_a9_pmu_init(pmu);
227 break; 226 break;
228 case 0xC050: /* Cortex-A5 */ 227 case ARM_CPU_PART_CORTEX_A5:
229 ret = armv7_a5_pmu_init(pmu); 228 ret = armv7_a5_pmu_init(pmu);
230 break; 229 break;
231 case 0xC0F0: /* Cortex-A15 */ 230 case ARM_CPU_PART_CORTEX_A15:
232 ret = armv7_a15_pmu_init(pmu); 231 ret = armv7_a15_pmu_init(pmu);
233 break; 232 break;
234 case 0xC070: /* Cortex-A7 */ 233 case ARM_CPU_PART_CORTEX_A7:
235 ret = armv7_a7_pmu_init(pmu); 234 ret = armv7_a7_pmu_init(pmu);
236 break; 235 break;
237 } 236 }
238 /* Intel CPUs [xscale]. */ 237 /* Intel CPUs [xscale]. */
239 } else if (0x69 == implementor) { 238 } else if (implementor == ARM_CPU_IMP_INTEL) {
240 part_number = (cpuid >> 13) & 0x7; 239 switch (xscale_cpu_arch_version()) {
241 switch (part_number) { 240 case ARM_CPU_XSCALE_ARCH_V1:
242 case 1:
243 ret = xscale1pmu_init(pmu); 241 ret = xscale1pmu_init(pmu);
244 break; 242 break;
245 case 2: 243 case ARM_CPU_XSCALE_ARCH_V2:
246 ret = xscale2pmu_init(pmu); 244 ret = xscale2pmu_init(pmu);
247 break; 245 break;
248 } 246 }
@@ -279,17 +277,22 @@ static int cpu_pmu_device_probe(struct platform_device *pdev)
279 } 277 }
280 278
281 if (ret) { 279 if (ret) {
282 pr_info("failed to register PMU devices!"); 280 pr_info("failed to probe PMU!");
283 kfree(pmu); 281 goto out_free;
284 return ret;
285 } 282 }
286 283
287 cpu_pmu = pmu; 284 cpu_pmu = pmu;
288 cpu_pmu->plat_device = pdev; 285 cpu_pmu->plat_device = pdev;
289 cpu_pmu_init(cpu_pmu); 286 cpu_pmu_init(cpu_pmu);
290 armpmu_register(cpu_pmu, PERF_TYPE_RAW); 287 ret = armpmu_register(cpu_pmu, PERF_TYPE_RAW);
291 288
292 return 0; 289 if (!ret)
290 return 0;
291
292out_free:
293 pr_info("failed to register PMU devices!");
294 kfree(pmu);
295 return ret;
293} 296}
294 297
295static struct platform_driver cpu_pmu_driver = { 298static struct platform_driver cpu_pmu_driver = {
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index 041d0526a288..03664b0e8fa4 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -106,7 +106,7 @@ static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
106 }, 106 },
107 [C(OP_WRITE)] = { 107 [C(OP_WRITE)] = {
108 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 108 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
109 [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS, 109 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
110 }, 110 },
111 [C(OP_PREFETCH)] = { 111 [C(OP_PREFETCH)] = {
112 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 112 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
@@ -259,7 +259,7 @@ static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
259 }, 259 },
260 [C(OP_WRITE)] = { 260 [C(OP_WRITE)] = {
261 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 261 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
262 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS, 262 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
263 }, 263 },
264 [C(OP_PREFETCH)] = { 264 [C(OP_PREFETCH)] = {
265 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 265 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 4fbc757d9cff..8c79a9e70b83 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -157,8 +157,8 @@ static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
157 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 157 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
158 }, 158 },
159 [C(OP_WRITE)] = { 159 [C(OP_WRITE)] = {
160 [C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS, 160 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
161 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 161 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
162 }, 162 },
163 [C(OP_PREFETCH)] = { 163 [C(OP_PREFETCH)] = {
164 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 164 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
@@ -282,7 +282,7 @@ static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
282 }, 282 },
283 [C(OP_WRITE)] = { 283 [C(OP_WRITE)] = {
284 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 284 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
285 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 285 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
286 }, 286 },
287 [C(OP_PREFETCH)] = { 287 [C(OP_PREFETCH)] = {
288 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 288 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
@@ -399,8 +399,8 @@ static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
399 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 399 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
400 }, 400 },
401 [C(OP_WRITE)] = { 401 [C(OP_WRITE)] = {
402 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 402 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
403 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 403 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
404 }, 404 },
405 /* 405 /*
406 * The prefetch counters don't differentiate between the I 406 * The prefetch counters don't differentiate between the I
@@ -527,8 +527,8 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
527 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 527 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
528 }, 528 },
529 [C(OP_WRITE)] = { 529 [C(OP_WRITE)] = {
530 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 530 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
531 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 531 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
532 }, 532 },
533 [C(OP_PREFETCH)] = { 533 [C(OP_PREFETCH)] = {
534 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 534 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
@@ -651,8 +651,8 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
651 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 651 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
652 }, 652 },
653 [C(OP_WRITE)] = { 653 [C(OP_WRITE)] = {
654 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, 654 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
655 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, 655 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
656 }, 656 },
657 [C(OP_PREFETCH)] = { 657 [C(OP_PREFETCH)] = {
658 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 658 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 2b0fe30ec12e..63990c42fac9 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -83,7 +83,7 @@ static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
83 }, 83 },
84 [C(OP_WRITE)] = { 84 [C(OP_WRITE)] = {
85 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 85 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
86 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, 86 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
87 }, 87 },
88 [C(OP_PREFETCH)] = { 88 [C(OP_PREFETCH)] = {
89 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 89 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,