1 /* 2 * ARMv5 [xscale] Performance counter handling code. 3 * 4 * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com> 5 * 6 * Based on the previous xscale OProfile code. 7 * 8 * There are two variants of the xscale PMU that we support: 9 * - xscale1pmu: 2 event counters and a cycle counter 10 * - xscale2pmu: 4 event counters and a cycle counter 11 * The two variants share event definitions, but have different 12 * PMU structures. 13 */ 14 15 #ifdef CONFIG_CPU_XSCALE 16 enum xscale_perf_types { 17 XSCALE_PERFCTR_ICACHE_MISS = 0x00, 18 XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01, 19 XSCALE_PERFCTR_DATA_STALL = 0x02, 20 XSCALE_PERFCTR_ITLB_MISS = 0x03, 21 XSCALE_PERFCTR_DTLB_MISS = 0x04, 22 XSCALE_PERFCTR_BRANCH = 0x05, 23 XSCALE_PERFCTR_BRANCH_MISS = 0x06, 24 XSCALE_PERFCTR_INSTRUCTION = 0x07, 25 XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08, 26 XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09, 27 XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A, 28 XSCALE_PERFCTR_DCACHE_MISS = 0x0B, 29 XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C, 30 XSCALE_PERFCTR_PC_CHANGED = 0x0D, 31 XSCALE_PERFCTR_BCU_REQUEST = 0x10, 32 XSCALE_PERFCTR_BCU_FULL = 0x11, 33 XSCALE_PERFCTR_BCU_DRAIN = 0x12, 34 XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14, 35 XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15, 36 XSCALE_PERFCTR_RMW = 0x16, 37 /* XSCALE_PERFCTR_CCNT is not hardware defined */ 38 XSCALE_PERFCTR_CCNT = 0xFE, 39 XSCALE_PERFCTR_UNUSED = 0xFF, 40 }; 41 42 enum xscale_counters { 43 XSCALE_CYCLE_COUNTER = 0, 44 XSCALE_COUNTER0, 45 XSCALE_COUNTER1, 46 XSCALE_COUNTER2, 47 XSCALE_COUNTER3, 48 }; 49 50 static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { 51 [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT, 52 [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION, 53 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED, 54 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED, 55 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH, 56 [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS, 57 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED, 58 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = XSCALE_PERFCTR_ICACHE_NO_DELIVER, 59 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, 60 }; 61 62 static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] 63 [PERF_COUNT_HW_CACHE_OP_MAX] 64 [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 65 [C(L1D)] = { 66 [C(OP_READ)] = { 67 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, 68 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, 69 }, 70 [C(OP_WRITE)] = { 71 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS, 72 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS, 73 }, 74 [C(OP_PREFETCH)] = { 75 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 76 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 77 }, 78 }, 79 [C(L1I)] = { 80 [C(OP_READ)] = { 81 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 82 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, 83 }, 84 [C(OP_WRITE)] = { 85 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 86 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS, 87 }, 88 [C(OP_PREFETCH)] = { 89 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 90 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 91 }, 92 }, 93 [C(LL)] = { 94 [C(OP_READ)] = { 95 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 96 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 97 }, 98 [C(OP_WRITE)] = { 99 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 100 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 101 }, 102 [C(OP_PREFETCH)] = { 103 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 104 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 105 }, 106 }, 107 [C(DTLB)] = { 108 [C(OP_READ)] = { 109 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 110 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, 111 }, 112 [C(OP_WRITE)] = { 113 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 114 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS, 115 }, 116 [C(OP_PREFETCH)] = { 117 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 118 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 119 }, 120 }, 121 [C(ITLB)] = { 122 [C(OP_READ)] = { 123 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 124 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, 125 }, 126 [C(OP_WRITE)] = { 127 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 128 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS, 129 }, 130 [C(OP_PREFETCH)] = { 131 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 132 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 133 }, 134 }, 135 [C(BPU)] = { 136 [C(OP_READ)] = { 137 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 138 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 139 }, 140 [C(OP_WRITE)] = { 141 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 142 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 143 }, 144 [C(OP_PREFETCH)] = { 145 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 146 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 147 }, 148 }, 149 [C(NODE)] = { 150 [C(OP_READ)] = { 151 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 152 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 153 }, 154 [C(OP_WRITE)] = { 155 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 156 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 157 }, 158 [C(OP_PREFETCH)] = { 159 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, 160 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, 161 }, 162 }, 163 }; 164 165 #define XSCALE_PMU_ENABLE 0x001 166 #define XSCALE_PMN_RESET 0x002 167 #define XSCALE_CCNT_RESET 0x004 168 #define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET) 169 #define XSCALE_PMU_CNT64 0x008 170 171 #define XSCALE1_OVERFLOWED_MASK 0x700 172 #define XSCALE1_CCOUNT_OVERFLOW 0x400 173 #define XSCALE1_COUNT0_OVERFLOW 0x100 174 #define XSCALE1_COUNT1_OVERFLOW 0x200 175 #define XSCALE1_CCOUNT_INT_EN 0x040 176 #define XSCALE1_COUNT0_INT_EN 0x010 177 #define XSCALE1_COUNT1_INT_EN 0x020 178 #define XSCALE1_COUNT0_EVT_SHFT 12 179 #define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT) 180 #define XSCALE1_COUNT1_EVT_SHFT 20 181 #define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT) 182 183 static inline u32 184 xscale1pmu_read_pmnc(void) 185 { 186 u32 val; 187 asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val)); 188 return val; 189 } 190 191 static inline void 192 xscale1pmu_write_pmnc(u32 val) 193 { 194 /* upper 4bits and 7, 11 are write-as-0 */ 195 val &= 0xffff77f; 196 asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val)); 197 } 198 199 static inline int 200 xscale1_pmnc_counter_has_overflowed(unsigned long pmnc, 201 enum xscale_counters counter) 202 { 203 int ret = 0; 204 205 switch (counter) { 206 case XSCALE_CYCLE_COUNTER: 207 ret = pmnc & XSCALE1_CCOUNT_OVERFLOW; 208 break; 209 case XSCALE_COUNTER0: 210 ret = pmnc & XSCALE1_COUNT0_OVERFLOW; 211 break; 212 case XSCALE_COUNTER1: 213 ret = pmnc & XSCALE1_COUNT1_OVERFLOW; 214 break; 215 default: 216 WARN_ONCE(1, "invalid counter number (%d)\n", counter); 217 } 218 219 return ret; 220 } 221 222 static irqreturn_t 223 xscale1pmu_handle_irq(int irq_num, void *dev) 224 { 225 unsigned long pmnc; 226 struct perf_sample_data data; 227 struct pmu_hw_events *cpuc; 228 struct pt_regs *regs; 229 int idx; 230 231 /* 232 * NOTE: there's an A stepping erratum that states if an overflow 233 * bit already exists and another occurs, the previous 234 * Overflow bit gets cleared. There's no workaround. 235 * Fixed in B stepping or later. 236 */ 237 pmnc = xscale1pmu_read_pmnc(); 238 239 /* 240 * Write the value back to clear the overflow flags. Overflow 241 * flags remain in pmnc for use below. We also disable the PMU 242 * while we process the interrupt. 243 */ 244 xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); 245 246 if (!(pmnc & XSCALE1_OVERFLOWED_MASK)) 247 return IRQ_NONE; 248 249 regs = get_irq_regs(); 250 251 perf_sample_data_init(&data, 0); 252 253 cpuc = &__get_cpu_var(cpu_hw_events); 254 for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 255 struct perf_event *event = cpuc->events[idx]; 256 struct hw_perf_event *hwc; 257 258 if (!event) 259 continue; 260 261 if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx)) 262 continue; 263 264 hwc = &event->hw; 265 armpmu_event_update(event, hwc, idx); 266 data.period = event->hw.last_period; 267 if (!armpmu_event_set_period(event, hwc, idx)) 268 continue; 269 270 if (perf_event_overflow(event, &data, regs)) 271 cpu_pmu->disable(hwc, idx); 272 } 273 274 irq_work_run(); 275 276 /* 277 * Re-enable the PMU. 278 */ 279 pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE; 280 xscale1pmu_write_pmnc(pmnc); 281 282 return IRQ_HANDLED; 283 } 284 285 static void 286 xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx) 287 { 288 unsigned long val, mask, evt, flags; 289 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 290 291 switch (idx) { 292 case XSCALE_CYCLE_COUNTER: 293 mask = 0; 294 evt = XSCALE1_CCOUNT_INT_EN; 295 break; 296 case XSCALE_COUNTER0: 297 mask = XSCALE1_COUNT0_EVT_MASK; 298 evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) | 299 XSCALE1_COUNT0_INT_EN; 300 break; 301 case XSCALE_COUNTER1: 302 mask = XSCALE1_COUNT1_EVT_MASK; 303 evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) | 304 XSCALE1_COUNT1_INT_EN; 305 break; 306 default: 307 WARN_ONCE(1, "invalid counter number (%d)\n", idx); 308 return; 309 } 310 311 raw_spin_lock_irqsave(&events->pmu_lock, flags); 312 val = xscale1pmu_read_pmnc(); 313 val &= ~mask; 314 val |= evt; 315 xscale1pmu_write_pmnc(val); 316 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 317 } 318 319 static void 320 xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx) 321 { 322 unsigned long val, mask, evt, flags; 323 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 324 325 switch (idx) { 326 case XSCALE_CYCLE_COUNTER: 327 mask = XSCALE1_CCOUNT_INT_EN; 328 evt = 0; 329 break; 330 case XSCALE_COUNTER0: 331 mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK; 332 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT; 333 break; 334 case XSCALE_COUNTER1: 335 mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK; 336 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT; 337 break; 338 default: 339 WARN_ONCE(1, "invalid counter number (%d)\n", idx); 340 return; 341 } 342 343 raw_spin_lock_irqsave(&events->pmu_lock, flags); 344 val = xscale1pmu_read_pmnc(); 345 val &= ~mask; 346 val |= evt; 347 xscale1pmu_write_pmnc(val); 348 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 349 } 350 351 static int 352 xscale1pmu_get_event_idx(struct pmu_hw_events *cpuc, 353 struct hw_perf_event *event) 354 { 355 if (XSCALE_PERFCTR_CCNT == event->config_base) { 356 if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask)) 357 return -EAGAIN; 358 359 return XSCALE_CYCLE_COUNTER; 360 } else { 361 if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) 362 return XSCALE_COUNTER1; 363 364 if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) 365 return XSCALE_COUNTER0; 366 367 return -EAGAIN; 368 } 369 } 370 371 static void 372 xscale1pmu_start(void) 373 { 374 unsigned long flags, val; 375 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 376 377 raw_spin_lock_irqsave(&events->pmu_lock, flags); 378 val = xscale1pmu_read_pmnc(); 379 val |= XSCALE_PMU_ENABLE; 380 xscale1pmu_write_pmnc(val); 381 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 382 } 383 384 static void 385 xscale1pmu_stop(void) 386 { 387 unsigned long flags, val; 388 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 389 390 raw_spin_lock_irqsave(&events->pmu_lock, flags); 391 val = xscale1pmu_read_pmnc(); 392 val &= ~XSCALE_PMU_ENABLE; 393 xscale1pmu_write_pmnc(val); 394 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 395 } 396 397 static inline u32 398 xscale1pmu_read_counter(int counter) 399 { 400 u32 val = 0; 401 402 switch (counter) { 403 case XSCALE_CYCLE_COUNTER: 404 asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val)); 405 break; 406 case XSCALE_COUNTER0: 407 asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val)); 408 break; 409 case XSCALE_COUNTER1: 410 asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val)); 411 break; 412 } 413 414 return val; 415 } 416 417 static inline void 418 xscale1pmu_write_counter(int counter, u32 val) 419 { 420 switch (counter) { 421 case XSCALE_CYCLE_COUNTER: 422 asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val)); 423 break; 424 case XSCALE_COUNTER0: 425 asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val)); 426 break; 427 case XSCALE_COUNTER1: 428 asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val)); 429 break; 430 } 431 } 432 433 static int xscale_map_event(struct perf_event *event) 434 { 435 return map_cpu_event(event, &xscale_perf_map, 436 &xscale_perf_cache_map, 0xFF); 437 } 438 439 static struct arm_pmu xscale1pmu = { 440 .id = ARM_PERF_PMU_ID_XSCALE1, 441 .name = "xscale1", 442 .handle_irq = xscale1pmu_handle_irq, 443 .enable = xscale1pmu_enable_event, 444 .disable = xscale1pmu_disable_event, 445 .read_counter = xscale1pmu_read_counter, 446 .write_counter = xscale1pmu_write_counter, 447 .get_event_idx = xscale1pmu_get_event_idx, 448 .start = xscale1pmu_start, 449 .stop = xscale1pmu_stop, 450 .map_event = xscale_map_event, 451 .num_events = 3, 452 .max_period = (1LLU << 32) - 1, 453 }; 454 455 static struct arm_pmu *__init xscale1pmu_init(void) 456 { 457 return &xscale1pmu; 458 } 459 460 #define XSCALE2_OVERFLOWED_MASK 0x01f 461 #define XSCALE2_CCOUNT_OVERFLOW 0x001 462 #define XSCALE2_COUNT0_OVERFLOW 0x002 463 #define XSCALE2_COUNT1_OVERFLOW 0x004 464 #define XSCALE2_COUNT2_OVERFLOW 0x008 465 #define XSCALE2_COUNT3_OVERFLOW 0x010 466 #define XSCALE2_CCOUNT_INT_EN 0x001 467 #define XSCALE2_COUNT0_INT_EN 0x002 468 #define XSCALE2_COUNT1_INT_EN 0x004 469 #define XSCALE2_COUNT2_INT_EN 0x008 470 #define XSCALE2_COUNT3_INT_EN 0x010 471 #define XSCALE2_COUNT0_EVT_SHFT 0 472 #define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT) 473 #define XSCALE2_COUNT1_EVT_SHFT 8 474 #define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT) 475 #define XSCALE2_COUNT2_EVT_SHFT 16 476 #define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT) 477 #define XSCALE2_COUNT3_EVT_SHFT 24 478 #define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT) 479 480 static inline u32 481 xscale2pmu_read_pmnc(void) 482 { 483 u32 val; 484 asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val)); 485 /* bits 1-2 and 4-23 are read-unpredictable */ 486 return val & 0xff000009; 487 } 488 489 static inline void 490 xscale2pmu_write_pmnc(u32 val) 491 { 492 /* bits 4-23 are write-as-0, 24-31 are write ignored */ 493 val &= 0xf; 494 asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val)); 495 } 496 497 static inline u32 498 xscale2pmu_read_overflow_flags(void) 499 { 500 u32 val; 501 asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val)); 502 return val; 503 } 504 505 static inline void 506 xscale2pmu_write_overflow_flags(u32 val) 507 { 508 asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val)); 509 } 510 511 static inline u32 512 xscale2pmu_read_event_select(void) 513 { 514 u32 val; 515 asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val)); 516 return val; 517 } 518 519 static inline void 520 xscale2pmu_write_event_select(u32 val) 521 { 522 asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val)); 523 } 524 525 static inline u32 526 xscale2pmu_read_int_enable(void) 527 { 528 u32 val; 529 asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val)); 530 return val; 531 } 532 533 static void 534 xscale2pmu_write_int_enable(u32 val) 535 { 536 asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val)); 537 } 538 539 static inline int 540 xscale2_pmnc_counter_has_overflowed(unsigned long of_flags, 541 enum xscale_counters counter) 542 { 543 int ret = 0; 544 545 switch (counter) { 546 case XSCALE_CYCLE_COUNTER: 547 ret = of_flags & XSCALE2_CCOUNT_OVERFLOW; 548 break; 549 case XSCALE_COUNTER0: 550 ret = of_flags & XSCALE2_COUNT0_OVERFLOW; 551 break; 552 case XSCALE_COUNTER1: 553 ret = of_flags & XSCALE2_COUNT1_OVERFLOW; 554 break; 555 case XSCALE_COUNTER2: 556 ret = of_flags & XSCALE2_COUNT2_OVERFLOW; 557 break; 558 case XSCALE_COUNTER3: 559 ret = of_flags & XSCALE2_COUNT3_OVERFLOW; 560 break; 561 default: 562 WARN_ONCE(1, "invalid counter number (%d)\n", counter); 563 } 564 565 return ret; 566 } 567 568 static irqreturn_t 569 xscale2pmu_handle_irq(int irq_num, void *dev) 570 { 571 unsigned long pmnc, of_flags; 572 struct perf_sample_data data; 573 struct pmu_hw_events *cpuc; 574 struct pt_regs *regs; 575 int idx; 576 577 /* Disable the PMU. */ 578 pmnc = xscale2pmu_read_pmnc(); 579 xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE); 580 581 /* Check the overflow flag register. */ 582 of_flags = xscale2pmu_read_overflow_flags(); 583 if (!(of_flags & XSCALE2_OVERFLOWED_MASK)) 584 return IRQ_NONE; 585 586 /* Clear the overflow bits. */ 587 xscale2pmu_write_overflow_flags(of_flags); 588 589 regs = get_irq_regs(); 590 591 perf_sample_data_init(&data, 0); 592 593 cpuc = &__get_cpu_var(cpu_hw_events); 594 for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 595 struct perf_event *event = cpuc->events[idx]; 596 struct hw_perf_event *hwc; 597 598 if (!event) 599 continue; 600 601 if (!xscale2_pmnc_counter_has_overflowed(of_flags, idx)) 602 continue; 603 604 hwc = &event->hw; 605 armpmu_event_update(event, hwc, idx); 606 data.period = event->hw.last_period; 607 if (!armpmu_event_set_period(event, hwc, idx)) 608 continue; 609 610 if (perf_event_overflow(event, &data, regs)) 611 cpu_pmu->disable(hwc, idx); 612 } 613 614 irq_work_run(); 615 616 /* 617 * Re-enable the PMU. 618 */ 619 pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE; 620 xscale2pmu_write_pmnc(pmnc); 621 622 return IRQ_HANDLED; 623 } 624 625 static void 626 xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx) 627 { 628 unsigned long flags, ien, evtsel; 629 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 630 631 ien = xscale2pmu_read_int_enable(); 632 evtsel = xscale2pmu_read_event_select(); 633 634 switch (idx) { 635 case XSCALE_CYCLE_COUNTER: 636 ien |= XSCALE2_CCOUNT_INT_EN; 637 break; 638 case XSCALE_COUNTER0: 639 ien |= XSCALE2_COUNT0_INT_EN; 640 evtsel &= ~XSCALE2_COUNT0_EVT_MASK; 641 evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT; 642 break; 643 case XSCALE_COUNTER1: 644 ien |= XSCALE2_COUNT1_INT_EN; 645 evtsel &= ~XSCALE2_COUNT1_EVT_MASK; 646 evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT; 647 break; 648 case XSCALE_COUNTER2: 649 ien |= XSCALE2_COUNT2_INT_EN; 650 evtsel &= ~XSCALE2_COUNT2_EVT_MASK; 651 evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT; 652 break; 653 case XSCALE_COUNTER3: 654 ien |= XSCALE2_COUNT3_INT_EN; 655 evtsel &= ~XSCALE2_COUNT3_EVT_MASK; 656 evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT; 657 break; 658 default: 659 WARN_ONCE(1, "invalid counter number (%d)\n", idx); 660 return; 661 } 662 663 raw_spin_lock_irqsave(&events->pmu_lock, flags); 664 xscale2pmu_write_event_select(evtsel); 665 xscale2pmu_write_int_enable(ien); 666 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 667 } 668 669 static void 670 xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx) 671 { 672 unsigned long flags, ien, evtsel, of_flags; 673 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 674 675 ien = xscale2pmu_read_int_enable(); 676 evtsel = xscale2pmu_read_event_select(); 677 678 switch (idx) { 679 case XSCALE_CYCLE_COUNTER: 680 ien &= ~XSCALE2_CCOUNT_INT_EN; 681 of_flags = XSCALE2_CCOUNT_OVERFLOW; 682 break; 683 case XSCALE_COUNTER0: 684 ien &= ~XSCALE2_COUNT0_INT_EN; 685 evtsel &= ~XSCALE2_COUNT0_EVT_MASK; 686 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT; 687 of_flags = XSCALE2_COUNT0_OVERFLOW; 688 break; 689 case XSCALE_COUNTER1: 690 ien &= ~XSCALE2_COUNT1_INT_EN; 691 evtsel &= ~XSCALE2_COUNT1_EVT_MASK; 692 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT; 693 of_flags = XSCALE2_COUNT1_OVERFLOW; 694 break; 695 case XSCALE_COUNTER2: 696 ien &= ~XSCALE2_COUNT2_INT_EN; 697 evtsel &= ~XSCALE2_COUNT2_EVT_MASK; 698 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT; 699 of_flags = XSCALE2_COUNT2_OVERFLOW; 700 break; 701 case XSCALE_COUNTER3: 702 ien &= ~XSCALE2_COUNT3_INT_EN; 703 evtsel &= ~XSCALE2_COUNT3_EVT_MASK; 704 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT; 705 of_flags = XSCALE2_COUNT3_OVERFLOW; 706 break; 707 default: 708 WARN_ONCE(1, "invalid counter number (%d)\n", idx); 709 return; 710 } 711 712 raw_spin_lock_irqsave(&events->pmu_lock, flags); 713 xscale2pmu_write_event_select(evtsel); 714 xscale2pmu_write_int_enable(ien); 715 xscale2pmu_write_overflow_flags(of_flags); 716 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 717 } 718 719 static int 720 xscale2pmu_get_event_idx(struct pmu_hw_events *cpuc, 721 struct hw_perf_event *event) 722 { 723 int idx = xscale1pmu_get_event_idx(cpuc, event); 724 if (idx >= 0) 725 goto out; 726 727 if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask)) 728 idx = XSCALE_COUNTER3; 729 else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask)) 730 idx = XSCALE_COUNTER2; 731 out: 732 return idx; 733 } 734 735 static void 736 xscale2pmu_start(void) 737 { 738 unsigned long flags, val; 739 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 740 741 raw_spin_lock_irqsave(&events->pmu_lock, flags); 742 val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64; 743 val |= XSCALE_PMU_ENABLE; 744 xscale2pmu_write_pmnc(val); 745 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 746 } 747 748 static void 749 xscale2pmu_stop(void) 750 { 751 unsigned long flags, val; 752 struct pmu_hw_events *events = cpu_pmu->get_hw_events(); 753 754 raw_spin_lock_irqsave(&events->pmu_lock, flags); 755 val = xscale2pmu_read_pmnc(); 756 val &= ~XSCALE_PMU_ENABLE; 757 xscale2pmu_write_pmnc(val); 758 raw_spin_unlock_irqrestore(&events->pmu_lock, flags); 759 } 760 761 static inline u32 762 xscale2pmu_read_counter(int counter) 763 { 764 u32 val = 0; 765 766 switch (counter) { 767 case XSCALE_CYCLE_COUNTER: 768 asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val)); 769 break; 770 case XSCALE_COUNTER0: 771 asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val)); 772 break; 773 case XSCALE_COUNTER1: 774 asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val)); 775 break; 776 case XSCALE_COUNTER2: 777 asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val)); 778 break; 779 case XSCALE_COUNTER3: 780 asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val)); 781 break; 782 } 783 784 return val; 785 } 786 787 static inline void 788 xscale2pmu_write_counter(int counter, u32 val) 789 { 790 switch (counter) { 791 case XSCALE_CYCLE_COUNTER: 792 asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); 793 break; 794 case XSCALE_COUNTER0: 795 asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val)); 796 break; 797 case XSCALE_COUNTER1: 798 asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val)); 799 break; 800 case XSCALE_COUNTER2: 801 asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val)); 802 break; 803 case XSCALE_COUNTER3: 804 asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val)); 805 break; 806 } 807 } 808 809 static struct arm_pmu xscale2pmu = { 810 .id = ARM_PERF_PMU_ID_XSCALE2, 811 .name = "xscale2", 812 .handle_irq = xscale2pmu_handle_irq, 813 .enable = xscale2pmu_enable_event, 814 .disable = xscale2pmu_disable_event, 815 .read_counter = xscale2pmu_read_counter, 816 .write_counter = xscale2pmu_write_counter, 817 .get_event_idx = xscale2pmu_get_event_idx, 818 .start = xscale2pmu_start, 819 .stop = xscale2pmu_stop, 820 .map_event = xscale_map_event, 821 .num_events = 5, 822 .max_period = (1LLU << 32) - 1, 823 }; 824 825 static struct arm_pmu *__init xscale2pmu_init(void) 826 { 827 return &xscale2pmu; 828 } 829 #else 830 static struct arm_pmu *__init xscale1pmu_init(void) 831 { 832 return NULL; 833 } 834 835 static struct arm_pmu *__init xscale2pmu_init(void) 836 { 837 return NULL; 838 } 839 #endif /* CONFIG_CPU_XSCALE */ 840