root/arch/csky/kernel/perf_event.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. csky_pmu_read_cc
  2. csky_pmu_write_cc
  3. csky_pmu_read_ic
  4. csky_pmu_write_ic
  5. csky_pmu_read_icac
  6. csky_pmu_write_icac
  7. csky_pmu_read_icmc
  8. csky_pmu_write_icmc
  9. csky_pmu_read_dcac
  10. csky_pmu_write_dcac
  11. csky_pmu_read_dcmc
  12. csky_pmu_write_dcmc
  13. csky_pmu_read_l2ac
  14. csky_pmu_write_l2ac
  15. csky_pmu_read_l2mc
  16. csky_pmu_write_l2mc
  17. csky_pmu_read_iutlbmc
  18. csky_pmu_write_iutlbmc
  19. csky_pmu_read_dutlbmc
  20. csky_pmu_write_dutlbmc
  21. csky_pmu_read_jtlbmc
  22. csky_pmu_write_jtlbmc
  23. csky_pmu_read_softc
  24. csky_pmu_write_softc
  25. csky_pmu_read_cbmc
  26. csky_pmu_write_cbmc
  27. csky_pmu_read_cbic
  28. csky_pmu_write_cbic
  29. csky_pmu_read_ibmc
  30. csky_pmu_write_ibmc
  31. csky_pmu_read_ibic
  32. csky_pmu_write_ibic
  33. csky_pmu_read_lsfc
  34. csky_pmu_write_lsfc
  35. csky_pmu_read_sic
  36. csky_pmu_write_sic
  37. csky_pmu_read_dcrac
  38. csky_pmu_write_dcrac
  39. csky_pmu_read_dcrmc
  40. csky_pmu_write_dcrmc
  41. csky_pmu_read_dcwac
  42. csky_pmu_write_dcwac
  43. csky_pmu_read_dcwmc
  44. csky_pmu_write_dcwmc
  45. csky_pmu_read_l2rac
  46. csky_pmu_write_l2rac
  47. csky_pmu_read_l2rmc
  48. csky_pmu_write_l2rmc
  49. csky_pmu_read_l2wac
  50. csky_pmu_write_l2wac
  51. csky_pmu_read_l2wmc
  52. csky_pmu_write_l2wmc
  53. csky_pmu_event_set_period
  54. csky_perf_event_update
  55. csky_pmu_reset
  56. csky_pmu_read
  57. csky_pmu_cache_event
  58. csky_pmu_event_init
  59. csky_pmu_enable
  60. csky_pmu_disable
  61. csky_pmu_start
  62. csky_pmu_stop_event
  63. csky_pmu_stop
  64. csky_pmu_del
  65. csky_pmu_add
  66. csky_pmu_handle_irq
  67. csky_pmu_request_irq
  68. csky_pmu_free_irq
  69. init_hw_perf_events
  70. csky_pmu_starting_cpu
  71. csky_pmu_dying_cpu
  72. csky_pmu_device_probe
  73. csky_pmu_dev_probe
  74. csky_pmu_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
   3 
   4 #include <linux/errno.h>
   5 #include <linux/interrupt.h>
   6 #include <linux/module.h>
   7 #include <linux/of.h>
   8 #include <linux/perf_event.h>
   9 #include <linux/platform_device.h>
  10 
  11 #define CSKY_PMU_MAX_EVENTS 32
  12 #define DEFAULT_COUNT_WIDTH 48
  13 
  14 #define HPCR            "<0, 0x0>"      /* PMU Control reg */
  15 #define HPSPR           "<0, 0x1>"      /* Start PC reg */
  16 #define HPEPR           "<0, 0x2>"      /* End PC reg */
  17 #define HPSIR           "<0, 0x3>"      /* Soft Counter reg */
  18 #define HPCNTENR        "<0, 0x4>"      /* Count Enable reg */
  19 #define HPINTENR        "<0, 0x5>"      /* Interrupt Enable reg */
  20 #define HPOFSR          "<0, 0x6>"      /* Interrupt Status reg */
  21 
  22 /* The events for a given PMU register set. */
  23 struct pmu_hw_events {
  24         /*
  25          * The events that are active on the PMU for the given index.
  26          */
  27         struct perf_event *events[CSKY_PMU_MAX_EVENTS];
  28 
  29         /*
  30          * A 1 bit for an index indicates that the counter is being used for
  31          * an event. A 0 means that the counter can be used.
  32          */
  33         unsigned long used_mask[BITS_TO_LONGS(CSKY_PMU_MAX_EVENTS)];
  34 };
  35 
  36 static uint64_t (*hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS])(void);
  37 static void (*hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS])(uint64_t val);
  38 
  39 static struct csky_pmu_t {
  40         struct pmu                      pmu;
  41         struct pmu_hw_events __percpu   *hw_events;
  42         struct platform_device          *plat_device;
  43         uint32_t                        count_width;
  44         uint32_t                        hpcr;
  45         u64                             max_period;
  46 } csky_pmu;
  47 static int csky_pmu_irq;
  48 
  49 #define to_csky_pmu(p)  (container_of(p, struct csky_pmu, pmu))
  50 
  51 #define cprgr(reg)                              \
  52 ({                                              \
  53         unsigned int tmp;                       \
  54         asm volatile("cprgr %0, "reg"\n"        \
  55                      : "=r"(tmp)                \
  56                      :                          \
  57                      : "memory");               \
  58         tmp;                                    \
  59 })
  60 
  61 #define cpwgr(reg, val)         \
  62 ({                              \
  63         asm volatile(           \
  64         "cpwgr %0, "reg"\n"     \
  65         :                       \
  66         : "r"(val)              \
  67         : "memory");            \
  68 })
  69 
  70 #define cprcr(reg)                              \
  71 ({                                              \
  72         unsigned int tmp;                       \
  73         asm volatile("cprcr %0, "reg"\n"        \
  74                      : "=r"(tmp)                \
  75                      :                          \
  76                      : "memory");               \
  77         tmp;                                    \
  78 })
  79 
  80 #define cpwcr(reg, val)         \
  81 ({                              \
  82         asm volatile(           \
  83         "cpwcr %0, "reg"\n"     \
  84         :                       \
  85         : "r"(val)              \
  86         : "memory");            \
  87 })
  88 
  89 /* cycle counter */
  90 static uint64_t csky_pmu_read_cc(void)
  91 {
  92         uint32_t lo, hi, tmp;
  93         uint64_t result;
  94 
  95         do {
  96                 tmp = cprgr("<0, 0x3>");
  97                 lo  = cprgr("<0, 0x2>");
  98                 hi  = cprgr("<0, 0x3>");
  99         } while (hi != tmp);
 100 
 101         result = (uint64_t) (hi) << 32;
 102         result |= lo;
 103 
 104         return result;
 105 }
 106 
 107 static void csky_pmu_write_cc(uint64_t val)
 108 {
 109         cpwgr("<0, 0x2>", (uint32_t)  val);
 110         cpwgr("<0, 0x3>", (uint32_t) (val >> 32));
 111 }
 112 
 113 /* instruction counter */
 114 static uint64_t csky_pmu_read_ic(void)
 115 {
 116         uint32_t lo, hi, tmp;
 117         uint64_t result;
 118 
 119         do {
 120                 tmp = cprgr("<0, 0x5>");
 121                 lo  = cprgr("<0, 0x4>");
 122                 hi  = cprgr("<0, 0x5>");
 123         } while (hi != tmp);
 124 
 125         result = (uint64_t) (hi) << 32;
 126         result |= lo;
 127 
 128         return result;
 129 }
 130 
 131 static void csky_pmu_write_ic(uint64_t val)
 132 {
 133         cpwgr("<0, 0x4>", (uint32_t)  val);
 134         cpwgr("<0, 0x5>", (uint32_t) (val >> 32));
 135 }
 136 
 137 /* l1 icache access counter */
 138 static uint64_t csky_pmu_read_icac(void)
 139 {
 140         uint32_t lo, hi, tmp;
 141         uint64_t result;
 142 
 143         do {
 144                 tmp = cprgr("<0, 0x7>");
 145                 lo  = cprgr("<0, 0x6>");
 146                 hi  = cprgr("<0, 0x7>");
 147         } while (hi != tmp);
 148 
 149         result = (uint64_t) (hi) << 32;
 150         result |= lo;
 151 
 152         return result;
 153 }
 154 
 155 static void csky_pmu_write_icac(uint64_t val)
 156 {
 157         cpwgr("<0, 0x6>", (uint32_t)  val);
 158         cpwgr("<0, 0x7>", (uint32_t) (val >> 32));
 159 }
 160 
 161 /* l1 icache miss counter */
 162 static uint64_t csky_pmu_read_icmc(void)
 163 {
 164         uint32_t lo, hi, tmp;
 165         uint64_t result;
 166 
 167         do {
 168                 tmp = cprgr("<0, 0x9>");
 169                 lo  = cprgr("<0, 0x8>");
 170                 hi  = cprgr("<0, 0x9>");
 171         } while (hi != tmp);
 172 
 173         result = (uint64_t) (hi) << 32;
 174         result |= lo;
 175 
 176         return result;
 177 }
 178 
 179 static void csky_pmu_write_icmc(uint64_t val)
 180 {
 181         cpwgr("<0, 0x8>", (uint32_t)  val);
 182         cpwgr("<0, 0x9>", (uint32_t) (val >> 32));
 183 }
 184 
 185 /* l1 dcache access counter */
 186 static uint64_t csky_pmu_read_dcac(void)
 187 {
 188         uint32_t lo, hi, tmp;
 189         uint64_t result;
 190 
 191         do {
 192                 tmp = cprgr("<0, 0xb>");
 193                 lo  = cprgr("<0, 0xa>");
 194                 hi  = cprgr("<0, 0xb>");
 195         } while (hi != tmp);
 196 
 197         result = (uint64_t) (hi) << 32;
 198         result |= lo;
 199 
 200         return result;
 201 }
 202 
 203 static void csky_pmu_write_dcac(uint64_t val)
 204 {
 205         cpwgr("<0, 0xa>", (uint32_t)  val);
 206         cpwgr("<0, 0xb>", (uint32_t) (val >> 32));
 207 }
 208 
 209 /* l1 dcache miss counter */
 210 static uint64_t csky_pmu_read_dcmc(void)
 211 {
 212         uint32_t lo, hi, tmp;
 213         uint64_t result;
 214 
 215         do {
 216                 tmp = cprgr("<0, 0xd>");
 217                 lo  = cprgr("<0, 0xc>");
 218                 hi  = cprgr("<0, 0xd>");
 219         } while (hi != tmp);
 220 
 221         result = (uint64_t) (hi) << 32;
 222         result |= lo;
 223 
 224         return result;
 225 }
 226 
 227 static void csky_pmu_write_dcmc(uint64_t val)
 228 {
 229         cpwgr("<0, 0xc>", (uint32_t)  val);
 230         cpwgr("<0, 0xd>", (uint32_t) (val >> 32));
 231 }
 232 
 233 /* l2 cache access counter */
 234 static uint64_t csky_pmu_read_l2ac(void)
 235 {
 236         uint32_t lo, hi, tmp;
 237         uint64_t result;
 238 
 239         do {
 240                 tmp = cprgr("<0, 0xf>");
 241                 lo  = cprgr("<0, 0xe>");
 242                 hi  = cprgr("<0, 0xf>");
 243         } while (hi != tmp);
 244 
 245         result = (uint64_t) (hi) << 32;
 246         result |= lo;
 247 
 248         return result;
 249 }
 250 
 251 static void csky_pmu_write_l2ac(uint64_t val)
 252 {
 253         cpwgr("<0, 0xe>", (uint32_t)  val);
 254         cpwgr("<0, 0xf>", (uint32_t) (val >> 32));
 255 }
 256 
 257 /* l2 cache miss counter */
 258 static uint64_t csky_pmu_read_l2mc(void)
 259 {
 260         uint32_t lo, hi, tmp;
 261         uint64_t result;
 262 
 263         do {
 264                 tmp = cprgr("<0, 0x11>");
 265                 lo  = cprgr("<0, 0x10>");
 266                 hi  = cprgr("<0, 0x11>");
 267         } while (hi != tmp);
 268 
 269         result = (uint64_t) (hi) << 32;
 270         result |= lo;
 271 
 272         return result;
 273 }
 274 
 275 static void csky_pmu_write_l2mc(uint64_t val)
 276 {
 277         cpwgr("<0, 0x10>", (uint32_t)  val);
 278         cpwgr("<0, 0x11>", (uint32_t) (val >> 32));
 279 }
 280 
 281 /* I-UTLB miss counter */
 282 static uint64_t csky_pmu_read_iutlbmc(void)
 283 {
 284         uint32_t lo, hi, tmp;
 285         uint64_t result;
 286 
 287         do {
 288                 tmp = cprgr("<0, 0x15>");
 289                 lo  = cprgr("<0, 0x14>");
 290                 hi  = cprgr("<0, 0x15>");
 291         } while (hi != tmp);
 292 
 293         result = (uint64_t) (hi) << 32;
 294         result |= lo;
 295 
 296         return result;
 297 }
 298 
 299 static void csky_pmu_write_iutlbmc(uint64_t val)
 300 {
 301         cpwgr("<0, 0x14>", (uint32_t)  val);
 302         cpwgr("<0, 0x15>", (uint32_t) (val >> 32));
 303 }
 304 
 305 /* D-UTLB miss counter */
 306 static uint64_t csky_pmu_read_dutlbmc(void)
 307 {
 308         uint32_t lo, hi, tmp;
 309         uint64_t result;
 310 
 311         do {
 312                 tmp = cprgr("<0, 0x17>");
 313                 lo  = cprgr("<0, 0x16>");
 314                 hi  = cprgr("<0, 0x17>");
 315         } while (hi != tmp);
 316 
 317         result = (uint64_t) (hi) << 32;
 318         result |= lo;
 319 
 320         return result;
 321 }
 322 
 323 static void csky_pmu_write_dutlbmc(uint64_t val)
 324 {
 325         cpwgr("<0, 0x16>", (uint32_t)  val);
 326         cpwgr("<0, 0x17>", (uint32_t) (val >> 32));
 327 }
 328 
 329 /* JTLB miss counter */
 330 static uint64_t csky_pmu_read_jtlbmc(void)
 331 {
 332         uint32_t lo, hi, tmp;
 333         uint64_t result;
 334 
 335         do {
 336                 tmp = cprgr("<0, 0x19>");
 337                 lo  = cprgr("<0, 0x18>");
 338                 hi  = cprgr("<0, 0x19>");
 339         } while (hi != tmp);
 340 
 341         result = (uint64_t) (hi) << 32;
 342         result |= lo;
 343 
 344         return result;
 345 }
 346 
 347 static void csky_pmu_write_jtlbmc(uint64_t val)
 348 {
 349         cpwgr("<0, 0x18>", (uint32_t)  val);
 350         cpwgr("<0, 0x19>", (uint32_t) (val >> 32));
 351 }
 352 
 353 /* software counter */
 354 static uint64_t csky_pmu_read_softc(void)
 355 {
 356         uint32_t lo, hi, tmp;
 357         uint64_t result;
 358 
 359         do {
 360                 tmp = cprgr("<0, 0x1b>");
 361                 lo  = cprgr("<0, 0x1a>");
 362                 hi  = cprgr("<0, 0x1b>");
 363         } while (hi != tmp);
 364 
 365         result = (uint64_t) (hi) << 32;
 366         result |= lo;
 367 
 368         return result;
 369 }
 370 
 371 static void csky_pmu_write_softc(uint64_t val)
 372 {
 373         cpwgr("<0, 0x1a>", (uint32_t)  val);
 374         cpwgr("<0, 0x1b>", (uint32_t) (val >> 32));
 375 }
 376 
 377 /* conditional branch mispredict counter */
 378 static uint64_t csky_pmu_read_cbmc(void)
 379 {
 380         uint32_t lo, hi, tmp;
 381         uint64_t result;
 382 
 383         do {
 384                 tmp = cprgr("<0, 0x1d>");
 385                 lo  = cprgr("<0, 0x1c>");
 386                 hi  = cprgr("<0, 0x1d>");
 387         } while (hi != tmp);
 388 
 389         result = (uint64_t) (hi) << 32;
 390         result |= lo;
 391 
 392         return result;
 393 }
 394 
 395 static void csky_pmu_write_cbmc(uint64_t val)
 396 {
 397         cpwgr("<0, 0x1c>", (uint32_t)  val);
 398         cpwgr("<0, 0x1d>", (uint32_t) (val >> 32));
 399 }
 400 
 401 /* conditional branch instruction counter */
 402 static uint64_t csky_pmu_read_cbic(void)
 403 {
 404         uint32_t lo, hi, tmp;
 405         uint64_t result;
 406 
 407         do {
 408                 tmp = cprgr("<0, 0x1f>");
 409                 lo  = cprgr("<0, 0x1e>");
 410                 hi  = cprgr("<0, 0x1f>");
 411         } while (hi != tmp);
 412 
 413         result = (uint64_t) (hi) << 32;
 414         result |= lo;
 415 
 416         return result;
 417 }
 418 
 419 static void csky_pmu_write_cbic(uint64_t val)
 420 {
 421         cpwgr("<0, 0x1e>", (uint32_t)  val);
 422         cpwgr("<0, 0x1f>", (uint32_t) (val >> 32));
 423 }
 424 
 425 /* indirect branch mispredict counter */
 426 static uint64_t csky_pmu_read_ibmc(void)
 427 {
 428         uint32_t lo, hi, tmp;
 429         uint64_t result;
 430 
 431         do {
 432                 tmp = cprgr("<0, 0x21>");
 433                 lo  = cprgr("<0, 0x20>");
 434                 hi  = cprgr("<0, 0x21>");
 435         } while (hi != tmp);
 436 
 437         result = (uint64_t) (hi) << 32;
 438         result |= lo;
 439 
 440         return result;
 441 }
 442 
 443 static void csky_pmu_write_ibmc(uint64_t val)
 444 {
 445         cpwgr("<0, 0x20>", (uint32_t)  val);
 446         cpwgr("<0, 0x21>", (uint32_t) (val >> 32));
 447 }
 448 
 449 /* indirect branch instruction counter */
 450 static uint64_t csky_pmu_read_ibic(void)
 451 {
 452         uint32_t lo, hi, tmp;
 453         uint64_t result;
 454 
 455         do {
 456                 tmp = cprgr("<0, 0x23>");
 457                 lo  = cprgr("<0, 0x22>");
 458                 hi  = cprgr("<0, 0x23>");
 459         } while (hi != tmp);
 460 
 461         result = (uint64_t) (hi) << 32;
 462         result |= lo;
 463 
 464         return result;
 465 }
 466 
 467 static void csky_pmu_write_ibic(uint64_t val)
 468 {
 469         cpwgr("<0, 0x22>", (uint32_t)  val);
 470         cpwgr("<0, 0x23>", (uint32_t) (val >> 32));
 471 }
 472 
 473 /* LSU spec fail counter */
 474 static uint64_t csky_pmu_read_lsfc(void)
 475 {
 476         uint32_t lo, hi, tmp;
 477         uint64_t result;
 478 
 479         do {
 480                 tmp = cprgr("<0, 0x25>");
 481                 lo  = cprgr("<0, 0x24>");
 482                 hi  = cprgr("<0, 0x25>");
 483         } while (hi != tmp);
 484 
 485         result = (uint64_t) (hi) << 32;
 486         result |= lo;
 487 
 488         return result;
 489 }
 490 
 491 static void csky_pmu_write_lsfc(uint64_t val)
 492 {
 493         cpwgr("<0, 0x24>", (uint32_t)  val);
 494         cpwgr("<0, 0x25>", (uint32_t) (val >> 32));
 495 }
 496 
 497 /* store instruction counter */
 498 static uint64_t csky_pmu_read_sic(void)
 499 {
 500         uint32_t lo, hi, tmp;
 501         uint64_t result;
 502 
 503         do {
 504                 tmp = cprgr("<0, 0x27>");
 505                 lo  = cprgr("<0, 0x26>");
 506                 hi  = cprgr("<0, 0x27>");
 507         } while (hi != tmp);
 508 
 509         result = (uint64_t) (hi) << 32;
 510         result |= lo;
 511 
 512         return result;
 513 }
 514 
 515 static void csky_pmu_write_sic(uint64_t val)
 516 {
 517         cpwgr("<0, 0x26>", (uint32_t)  val);
 518         cpwgr("<0, 0x27>", (uint32_t) (val >> 32));
 519 }
 520 
 521 /* dcache read access counter */
 522 static uint64_t csky_pmu_read_dcrac(void)
 523 {
 524         uint32_t lo, hi, tmp;
 525         uint64_t result;
 526 
 527         do {
 528                 tmp = cprgr("<0, 0x29>");
 529                 lo  = cprgr("<0, 0x28>");
 530                 hi  = cprgr("<0, 0x29>");
 531         } while (hi != tmp);
 532 
 533         result = (uint64_t) (hi) << 32;
 534         result |= lo;
 535 
 536         return result;
 537 }
 538 
 539 static void csky_pmu_write_dcrac(uint64_t val)
 540 {
 541         cpwgr("<0, 0x28>", (uint32_t)  val);
 542         cpwgr("<0, 0x29>", (uint32_t) (val >> 32));
 543 }
 544 
 545 /* dcache read miss counter */
 546 static uint64_t csky_pmu_read_dcrmc(void)
 547 {
 548         uint32_t lo, hi, tmp;
 549         uint64_t result;
 550 
 551         do {
 552                 tmp = cprgr("<0, 0x2b>");
 553                 lo  = cprgr("<0, 0x2a>");
 554                 hi  = cprgr("<0, 0x2b>");
 555         } while (hi != tmp);
 556 
 557         result = (uint64_t) (hi) << 32;
 558         result |= lo;
 559 
 560         return result;
 561 }
 562 
 563 static void csky_pmu_write_dcrmc(uint64_t val)
 564 {
 565         cpwgr("<0, 0x2a>", (uint32_t)  val);
 566         cpwgr("<0, 0x2b>", (uint32_t) (val >> 32));
 567 }
 568 
 569 /* dcache write access counter */
 570 static uint64_t csky_pmu_read_dcwac(void)
 571 {
 572         uint32_t lo, hi, tmp;
 573         uint64_t result;
 574 
 575         do {
 576                 tmp = cprgr("<0, 0x2d>");
 577                 lo  = cprgr("<0, 0x2c>");
 578                 hi  = cprgr("<0, 0x2d>");
 579         } while (hi != tmp);
 580 
 581         result = (uint64_t) (hi) << 32;
 582         result |= lo;
 583 
 584         return result;
 585 }
 586 
 587 static void csky_pmu_write_dcwac(uint64_t val)
 588 {
 589         cpwgr("<0, 0x2c>", (uint32_t)  val);
 590         cpwgr("<0, 0x2d>", (uint32_t) (val >> 32));
 591 }
 592 
 593 /* dcache write miss counter */
 594 static uint64_t csky_pmu_read_dcwmc(void)
 595 {
 596         uint32_t lo, hi, tmp;
 597         uint64_t result;
 598 
 599         do {
 600                 tmp = cprgr("<0, 0x2f>");
 601                 lo  = cprgr("<0, 0x2e>");
 602                 hi  = cprgr("<0, 0x2f>");
 603         } while (hi != tmp);
 604 
 605         result = (uint64_t) (hi) << 32;
 606         result |= lo;
 607 
 608         return result;
 609 }
 610 
 611 static void csky_pmu_write_dcwmc(uint64_t val)
 612 {
 613         cpwgr("<0, 0x2e>", (uint32_t)  val);
 614         cpwgr("<0, 0x2f>", (uint32_t) (val >> 32));
 615 }
 616 
 617 /* l2cache read access counter */
 618 static uint64_t csky_pmu_read_l2rac(void)
 619 {
 620         uint32_t lo, hi, tmp;
 621         uint64_t result;
 622 
 623         do {
 624                 tmp = cprgr("<0, 0x31>");
 625                 lo  = cprgr("<0, 0x30>");
 626                 hi  = cprgr("<0, 0x31>");
 627         } while (hi != tmp);
 628 
 629         result = (uint64_t) (hi) << 32;
 630         result |= lo;
 631 
 632         return result;
 633 }
 634 
 635 static void csky_pmu_write_l2rac(uint64_t val)
 636 {
 637         cpwgr("<0, 0x30>", (uint32_t)  val);
 638         cpwgr("<0, 0x31>", (uint32_t) (val >> 32));
 639 }
 640 
 641 /* l2cache read miss counter */
 642 static uint64_t csky_pmu_read_l2rmc(void)
 643 {
 644         uint32_t lo, hi, tmp;
 645         uint64_t result;
 646 
 647         do {
 648                 tmp = cprgr("<0, 0x33>");
 649                 lo  = cprgr("<0, 0x32>");
 650                 hi  = cprgr("<0, 0x33>");
 651         } while (hi != tmp);
 652 
 653         result = (uint64_t) (hi) << 32;
 654         result |= lo;
 655 
 656         return result;
 657 }
 658 
 659 static void csky_pmu_write_l2rmc(uint64_t val)
 660 {
 661         cpwgr("<0, 0x32>", (uint32_t)  val);
 662         cpwgr("<0, 0x33>", (uint32_t) (val >> 32));
 663 }
 664 
 665 /* l2cache write access counter */
 666 static uint64_t csky_pmu_read_l2wac(void)
 667 {
 668         uint32_t lo, hi, tmp;
 669         uint64_t result;
 670 
 671         do {
 672                 tmp = cprgr("<0, 0x35>");
 673                 lo  = cprgr("<0, 0x34>");
 674                 hi  = cprgr("<0, 0x35>");
 675         } while (hi != tmp);
 676 
 677         result = (uint64_t) (hi) << 32;
 678         result |= lo;
 679 
 680         return result;
 681 }
 682 
 683 static void csky_pmu_write_l2wac(uint64_t val)
 684 {
 685         cpwgr("<0, 0x34>", (uint32_t)  val);
 686         cpwgr("<0, 0x35>", (uint32_t) (val >> 32));
 687 }
 688 
 689 /* l2cache write miss counter */
 690 static uint64_t csky_pmu_read_l2wmc(void)
 691 {
 692         uint32_t lo, hi, tmp;
 693         uint64_t result;
 694 
 695         do {
 696                 tmp = cprgr("<0, 0x37>");
 697                 lo  = cprgr("<0, 0x36>");
 698                 hi  = cprgr("<0, 0x37>");
 699         } while (hi != tmp);
 700 
 701         result = (uint64_t) (hi) << 32;
 702         result |= lo;
 703 
 704         return result;
 705 }
 706 
 707 static void csky_pmu_write_l2wmc(uint64_t val)
 708 {
 709         cpwgr("<0, 0x36>", (uint32_t)  val);
 710         cpwgr("<0, 0x37>", (uint32_t) (val >> 32));
 711 }
 712 
 713 #define HW_OP_UNSUPPORTED       0xffff
 714 static const int csky_pmu_hw_map[PERF_COUNT_HW_MAX] = {
 715         [PERF_COUNT_HW_CPU_CYCLES]              = 0x1,
 716         [PERF_COUNT_HW_INSTRUCTIONS]            = 0x2,
 717         [PERF_COUNT_HW_CACHE_REFERENCES]        = HW_OP_UNSUPPORTED,
 718         [PERF_COUNT_HW_CACHE_MISSES]            = HW_OP_UNSUPPORTED,
 719         [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]     = 0xf,
 720         [PERF_COUNT_HW_BRANCH_MISSES]           = 0xe,
 721         [PERF_COUNT_HW_BUS_CYCLES]              = HW_OP_UNSUPPORTED,
 722         [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
 723         [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]  = HW_OP_UNSUPPORTED,
 724         [PERF_COUNT_HW_REF_CPU_CYCLES]          = HW_OP_UNSUPPORTED,
 725 };
 726 
 727 #define C(_x)                   PERF_COUNT_HW_CACHE_##_x
 728 #define CACHE_OP_UNSUPPORTED    0xffff
 729 static const int csky_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
 730         [C(L1D)] = {
 731 #ifdef CONFIG_CPU_CK810
 732                 [C(OP_READ)] = {
 733                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 734                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 735                 },
 736                 [C(OP_WRITE)] = {
 737                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 738                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 739                 },
 740                 [C(OP_PREFETCH)] = {
 741                         [C(RESULT_ACCESS)]      = 0x5,
 742                         [C(RESULT_MISS)]        = 0x6,
 743                 },
 744 #else
 745                 [C(OP_READ)] = {
 746                         [C(RESULT_ACCESS)]      = 0x14,
 747                         [C(RESULT_MISS)]        = 0x15,
 748                 },
 749                 [C(OP_WRITE)] = {
 750                         [C(RESULT_ACCESS)]      = 0x16,
 751                         [C(RESULT_MISS)]        = 0x17,
 752                 },
 753                 [C(OP_PREFETCH)] = {
 754                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 755                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 756                 },
 757 #endif
 758         },
 759         [C(L1I)] = {
 760                 [C(OP_READ)] = {
 761                         [C(RESULT_ACCESS)]      = 0x3,
 762                         [C(RESULT_MISS)]        = 0x4,
 763                 },
 764                 [C(OP_WRITE)] = {
 765                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 766                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 767                 },
 768                 [C(OP_PREFETCH)] = {
 769                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 770                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 771                 },
 772         },
 773         [C(LL)] = {
 774 #ifdef CONFIG_CPU_CK810
 775                 [C(OP_READ)] = {
 776                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 777                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 778                 },
 779                 [C(OP_WRITE)] = {
 780                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 781                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 782                 },
 783                 [C(OP_PREFETCH)] = {
 784                         [C(RESULT_ACCESS)]      = 0x7,
 785                         [C(RESULT_MISS)]        = 0x8,
 786                 },
 787 #else
 788                 [C(OP_READ)] = {
 789                         [C(RESULT_ACCESS)]      = 0x18,
 790                         [C(RESULT_MISS)]        = 0x19,
 791                 },
 792                 [C(OP_WRITE)] = {
 793                         [C(RESULT_ACCESS)]      = 0x1a,
 794                         [C(RESULT_MISS)]        = 0x1b,
 795                 },
 796                 [C(OP_PREFETCH)] = {
 797                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 798                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 799                 },
 800 #endif
 801         },
 802         [C(DTLB)] = {
 803 #ifdef CONFIG_CPU_CK810
 804                 [C(OP_READ)] = {
 805                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 806                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 807                 },
 808                 [C(OP_WRITE)] = {
 809                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 810                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 811                 },
 812 #else
 813                 [C(OP_READ)] = {
 814                         [C(RESULT_ACCESS)]      = 0x14,
 815                         [C(RESULT_MISS)]        = 0xb,
 816                 },
 817                 [C(OP_WRITE)] = {
 818                         [C(RESULT_ACCESS)]      = 0x16,
 819                         [C(RESULT_MISS)]        = 0xb,
 820                 },
 821 #endif
 822                 [C(OP_PREFETCH)] = {
 823                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 824                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 825                 },
 826         },
 827         [C(ITLB)] = {
 828 #ifdef CONFIG_CPU_CK810
 829                 [C(OP_READ)] = {
 830                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 831                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 832                 },
 833 #else
 834                 [C(OP_READ)] = {
 835                         [C(RESULT_ACCESS)]      = 0x3,
 836                         [C(RESULT_MISS)]        = 0xa,
 837                 },
 838 #endif
 839                 [C(OP_WRITE)] = {
 840                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 841                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 842                 },
 843                 [C(OP_PREFETCH)] = {
 844                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 845                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 846                 },
 847         },
 848         [C(BPU)] = {
 849                 [C(OP_READ)] = {
 850                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 851                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 852                 },
 853                 [C(OP_WRITE)] = {
 854                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 855                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 856                 },
 857                 [C(OP_PREFETCH)] = {
 858                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 859                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 860                 },
 861         },
 862         [C(NODE)] = {
 863                 [C(OP_READ)] = {
 864                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 865                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 866                 },
 867                 [C(OP_WRITE)] = {
 868                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 869                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 870                 },
 871                 [C(OP_PREFETCH)] = {
 872                         [C(RESULT_ACCESS)]      = CACHE_OP_UNSUPPORTED,
 873                         [C(RESULT_MISS)]        = CACHE_OP_UNSUPPORTED,
 874                 },
 875         },
 876 };
 877 
 878 int  csky_pmu_event_set_period(struct perf_event *event)
 879 {
 880         struct hw_perf_event *hwc = &event->hw;
 881         s64 left = local64_read(&hwc->period_left);
 882         s64 period = hwc->sample_period;
 883         int ret = 0;
 884 
 885         if (unlikely(left <= -period)) {
 886                 left = period;
 887                 local64_set(&hwc->period_left, left);
 888                 hwc->last_period = period;
 889                 ret = 1;
 890         }
 891 
 892         if (unlikely(left <= 0)) {
 893                 left += period;
 894                 local64_set(&hwc->period_left, left);
 895                 hwc->last_period = period;
 896                 ret = 1;
 897         }
 898 
 899         if (left > (s64)csky_pmu.max_period)
 900                 left = csky_pmu.max_period;
 901 
 902         /*
 903          * The hw event starts counting from this event offset,
 904          * mark it to be able to extract future "deltas":
 905          */
 906         local64_set(&hwc->prev_count, (u64)(-left));
 907 
 908         if (hw_raw_write_mapping[hwc->idx] != NULL)
 909                 hw_raw_write_mapping[hwc->idx]((u64)(-left) &
 910                                                 csky_pmu.max_period);
 911 
 912         cpwcr(HPOFSR, ~BIT(hwc->idx) & cprcr(HPOFSR));
 913 
 914         perf_event_update_userpage(event);
 915 
 916         return ret;
 917 }
 918 
 919 static void csky_perf_event_update(struct perf_event *event,
 920                                    struct hw_perf_event *hwc)
 921 {
 922         uint64_t prev_raw_count = local64_read(&hwc->prev_count);
 923         /*
 924          * Sign extend count value to 64bit, otherwise delta calculation
 925          * would be incorrect when overflow occurs.
 926          */
 927         uint64_t new_raw_count = sign_extend64(
 928                 hw_raw_read_mapping[hwc->idx](), csky_pmu.count_width - 1);
 929         int64_t delta = new_raw_count - prev_raw_count;
 930 
 931         /*
 932          * We aren't afraid of hwc->prev_count changing beneath our feet
 933          * because there's no way for us to re-enter this function anytime.
 934          */
 935         local64_set(&hwc->prev_count, new_raw_count);
 936         local64_add(delta, &event->count);
 937         local64_sub(delta, &hwc->period_left);
 938 }
 939 
 940 static void csky_pmu_reset(void *info)
 941 {
 942         cpwcr(HPCR, BIT(31) | BIT(30) | BIT(1));
 943 }
 944 
 945 static void csky_pmu_read(struct perf_event *event)
 946 {
 947         csky_perf_event_update(event, &event->hw);
 948 }
 949 
 950 static int csky_pmu_cache_event(u64 config)
 951 {
 952         unsigned int cache_type, cache_op, cache_result;
 953 
 954         cache_type      = (config >>  0) & 0xff;
 955         cache_op        = (config >>  8) & 0xff;
 956         cache_result    = (config >> 16) & 0xff;
 957 
 958         if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
 959                 return -EINVAL;
 960         if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
 961                 return -EINVAL;
 962         if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
 963                 return -EINVAL;
 964 
 965         return csky_pmu_cache_map[cache_type][cache_op][cache_result];
 966 }
 967 
 968 static int csky_pmu_event_init(struct perf_event *event)
 969 {
 970         struct hw_perf_event *hwc = &event->hw;
 971         int ret;
 972 
 973         switch (event->attr.type) {
 974         case PERF_TYPE_HARDWARE:
 975                 if (event->attr.config >= PERF_COUNT_HW_MAX)
 976                         return -ENOENT;
 977                 ret = csky_pmu_hw_map[event->attr.config];
 978                 if (ret == HW_OP_UNSUPPORTED)
 979                         return -ENOENT;
 980                 hwc->idx = ret;
 981                 break;
 982         case PERF_TYPE_HW_CACHE:
 983                 ret = csky_pmu_cache_event(event->attr.config);
 984                 if (ret == CACHE_OP_UNSUPPORTED)
 985                         return -ENOENT;
 986                 hwc->idx = ret;
 987                 break;
 988         case PERF_TYPE_RAW:
 989                 if (hw_raw_read_mapping[event->attr.config] == NULL)
 990                         return -ENOENT;
 991                 hwc->idx = event->attr.config;
 992                 break;
 993         default:
 994                 return -ENOENT;
 995         }
 996 
 997         if (event->attr.exclude_user)
 998                 csky_pmu.hpcr = BIT(2);
 999         else if (event->attr.exclude_kernel)
1000                 csky_pmu.hpcr = BIT(3);
1001         else
1002                 csky_pmu.hpcr = BIT(2) | BIT(3);
1003 
1004         csky_pmu.hpcr |= BIT(1) | BIT(0);
1005 
1006         return 0;
1007 }
1008 
1009 /* starts all counters */
1010 static void csky_pmu_enable(struct pmu *pmu)
1011 {
1012         cpwcr(HPCR, csky_pmu.hpcr);
1013 }
1014 
1015 /* stops all counters */
1016 static void csky_pmu_disable(struct pmu *pmu)
1017 {
1018         cpwcr(HPCR, BIT(1));
1019 }
1020 
1021 static void csky_pmu_start(struct perf_event *event, int flags)
1022 {
1023         unsigned long flg;
1024         struct hw_perf_event *hwc = &event->hw;
1025         int idx = hwc->idx;
1026 
1027         if (WARN_ON_ONCE(idx == -1))
1028                 return;
1029 
1030         if (flags & PERF_EF_RELOAD)
1031                 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
1032 
1033         hwc->state = 0;
1034 
1035         csky_pmu_event_set_period(event);
1036 
1037         local_irq_save(flg);
1038 
1039         cpwcr(HPINTENR, BIT(idx) | cprcr(HPINTENR));
1040         cpwcr(HPCNTENR, BIT(idx) | cprcr(HPCNTENR));
1041 
1042         local_irq_restore(flg);
1043 }
1044 
1045 static void csky_pmu_stop_event(struct perf_event *event)
1046 {
1047         unsigned long flg;
1048         struct hw_perf_event *hwc = &event->hw;
1049         int idx = hwc->idx;
1050 
1051         local_irq_save(flg);
1052 
1053         cpwcr(HPINTENR, ~BIT(idx) & cprcr(HPINTENR));
1054         cpwcr(HPCNTENR, ~BIT(idx) & cprcr(HPCNTENR));
1055 
1056         local_irq_restore(flg);
1057 }
1058 
1059 static void csky_pmu_stop(struct perf_event *event, int flags)
1060 {
1061         if (!(event->hw.state & PERF_HES_STOPPED)) {
1062                 csky_pmu_stop_event(event);
1063                 event->hw.state |= PERF_HES_STOPPED;
1064         }
1065 
1066         if ((flags & PERF_EF_UPDATE) &&
1067             !(event->hw.state & PERF_HES_UPTODATE)) {
1068                 csky_perf_event_update(event, &event->hw);
1069                 event->hw.state |= PERF_HES_UPTODATE;
1070         }
1071 }
1072 
1073 static void csky_pmu_del(struct perf_event *event, int flags)
1074 {
1075         struct pmu_hw_events *hw_events = this_cpu_ptr(csky_pmu.hw_events);
1076         struct hw_perf_event *hwc = &event->hw;
1077 
1078         csky_pmu_stop(event, PERF_EF_UPDATE);
1079 
1080         hw_events->events[hwc->idx] = NULL;
1081 
1082         perf_event_update_userpage(event);
1083 }
1084 
1085 /* allocate hardware counter and optionally start counting */
1086 static int csky_pmu_add(struct perf_event *event, int flags)
1087 {
1088         struct pmu_hw_events *hw_events = this_cpu_ptr(csky_pmu.hw_events);
1089         struct hw_perf_event *hwc = &event->hw;
1090 
1091         hw_events->events[hwc->idx] = event;
1092 
1093         hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
1094 
1095         if (flags & PERF_EF_START)
1096                 csky_pmu_start(event, PERF_EF_RELOAD);
1097 
1098         perf_event_update_userpage(event);
1099 
1100         return 0;
1101 }
1102 
1103 static irqreturn_t csky_pmu_handle_irq(int irq_num, void *dev)
1104 {
1105         struct perf_sample_data data;
1106         struct pmu_hw_events *cpuc = this_cpu_ptr(csky_pmu.hw_events);
1107         struct pt_regs *regs;
1108         int idx;
1109 
1110         /*
1111          * Did an overflow occur?
1112          */
1113         if (!cprcr(HPOFSR))
1114                 return IRQ_NONE;
1115 
1116         /*
1117          * Handle the counter(s) overflow(s)
1118          */
1119         regs = get_irq_regs();
1120 
1121         csky_pmu_disable(&csky_pmu.pmu);
1122 
1123         for (idx = 0; idx < CSKY_PMU_MAX_EVENTS; ++idx) {
1124                 struct perf_event *event = cpuc->events[idx];
1125                 struct hw_perf_event *hwc;
1126 
1127                 /* Ignore if we don't have an event. */
1128                 if (!event)
1129                         continue;
1130                 /*
1131                  * We have a single interrupt for all counters. Check that
1132                  * each counter has overflowed before we process it.
1133                  */
1134                 if (!(cprcr(HPOFSR) & BIT(idx)))
1135                         continue;
1136 
1137                 hwc = &event->hw;
1138                 csky_perf_event_update(event, &event->hw);
1139                 perf_sample_data_init(&data, 0, hwc->last_period);
1140                 csky_pmu_event_set_period(event);
1141 
1142                 if (perf_event_overflow(event, &data, regs))
1143                         csky_pmu_stop_event(event);
1144         }
1145 
1146         csky_pmu_enable(&csky_pmu.pmu);
1147 
1148         /*
1149          * Handle the pending perf events.
1150          *
1151          * Note: this call *must* be run with interrupts disabled. For
1152          * platforms that can have the PMU interrupts raised as an NMI, this
1153          * will not work.
1154          */
1155         irq_work_run();
1156 
1157         return IRQ_HANDLED;
1158 }
1159 
1160 static int csky_pmu_request_irq(irq_handler_t handler)
1161 {
1162         int err, irqs;
1163         struct platform_device *pmu_device = csky_pmu.plat_device;
1164 
1165         if (!pmu_device)
1166                 return -ENODEV;
1167 
1168         irqs = min(pmu_device->num_resources, num_possible_cpus());
1169         if (irqs < 1) {
1170                 pr_err("no irqs for PMUs defined\n");
1171                 return -ENODEV;
1172         }
1173 
1174         csky_pmu_irq = platform_get_irq(pmu_device, 0);
1175         if (csky_pmu_irq < 0)
1176                 return -ENODEV;
1177         err = request_percpu_irq(csky_pmu_irq, handler, "csky-pmu",
1178                                  this_cpu_ptr(csky_pmu.hw_events));
1179         if (err) {
1180                 pr_err("unable to request IRQ%d for CSKY PMU counters\n",
1181                        csky_pmu_irq);
1182                 return err;
1183         }
1184 
1185         return 0;
1186 }
1187 
1188 static void csky_pmu_free_irq(void)
1189 {
1190         int irq;
1191         struct platform_device *pmu_device = csky_pmu.plat_device;
1192 
1193         irq = platform_get_irq(pmu_device, 0);
1194         if (irq >= 0)
1195                 free_percpu_irq(irq, this_cpu_ptr(csky_pmu.hw_events));
1196 }
1197 
1198 int init_hw_perf_events(void)
1199 {
1200         csky_pmu.hw_events = alloc_percpu_gfp(struct pmu_hw_events,
1201                                               GFP_KERNEL);
1202         if (!csky_pmu.hw_events) {
1203                 pr_info("failed to allocate per-cpu PMU data.\n");
1204                 return -ENOMEM;
1205         }
1206 
1207         csky_pmu.pmu = (struct pmu) {
1208                 .pmu_enable     = csky_pmu_enable,
1209                 .pmu_disable    = csky_pmu_disable,
1210                 .event_init     = csky_pmu_event_init,
1211                 .add            = csky_pmu_add,
1212                 .del            = csky_pmu_del,
1213                 .start          = csky_pmu_start,
1214                 .stop           = csky_pmu_stop,
1215                 .read           = csky_pmu_read,
1216         };
1217 
1218         memset((void *)hw_raw_read_mapping, 0,
1219                 sizeof(hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS]));
1220 
1221         hw_raw_read_mapping[0x1]  = csky_pmu_read_cc;
1222         hw_raw_read_mapping[0x2]  = csky_pmu_read_ic;
1223         hw_raw_read_mapping[0x3]  = csky_pmu_read_icac;
1224         hw_raw_read_mapping[0x4]  = csky_pmu_read_icmc;
1225         hw_raw_read_mapping[0x5]  = csky_pmu_read_dcac;
1226         hw_raw_read_mapping[0x6]  = csky_pmu_read_dcmc;
1227         hw_raw_read_mapping[0x7]  = csky_pmu_read_l2ac;
1228         hw_raw_read_mapping[0x8]  = csky_pmu_read_l2mc;
1229         hw_raw_read_mapping[0xa]  = csky_pmu_read_iutlbmc;
1230         hw_raw_read_mapping[0xb]  = csky_pmu_read_dutlbmc;
1231         hw_raw_read_mapping[0xc]  = csky_pmu_read_jtlbmc;
1232         hw_raw_read_mapping[0xd]  = csky_pmu_read_softc;
1233         hw_raw_read_mapping[0xe]  = csky_pmu_read_cbmc;
1234         hw_raw_read_mapping[0xf]  = csky_pmu_read_cbic;
1235         hw_raw_read_mapping[0x10] = csky_pmu_read_ibmc;
1236         hw_raw_read_mapping[0x11] = csky_pmu_read_ibic;
1237         hw_raw_read_mapping[0x12] = csky_pmu_read_lsfc;
1238         hw_raw_read_mapping[0x13] = csky_pmu_read_sic;
1239         hw_raw_read_mapping[0x14] = csky_pmu_read_dcrac;
1240         hw_raw_read_mapping[0x15] = csky_pmu_read_dcrmc;
1241         hw_raw_read_mapping[0x16] = csky_pmu_read_dcwac;
1242         hw_raw_read_mapping[0x17] = csky_pmu_read_dcwmc;
1243         hw_raw_read_mapping[0x18] = csky_pmu_read_l2rac;
1244         hw_raw_read_mapping[0x19] = csky_pmu_read_l2rmc;
1245         hw_raw_read_mapping[0x1a] = csky_pmu_read_l2wac;
1246         hw_raw_read_mapping[0x1b] = csky_pmu_read_l2wmc;
1247 
1248         memset((void *)hw_raw_write_mapping, 0,
1249                 sizeof(hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS]));
1250 
1251         hw_raw_write_mapping[0x1]  = csky_pmu_write_cc;
1252         hw_raw_write_mapping[0x2]  = csky_pmu_write_ic;
1253         hw_raw_write_mapping[0x3]  = csky_pmu_write_icac;
1254         hw_raw_write_mapping[0x4]  = csky_pmu_write_icmc;
1255         hw_raw_write_mapping[0x5]  = csky_pmu_write_dcac;
1256         hw_raw_write_mapping[0x6]  = csky_pmu_write_dcmc;
1257         hw_raw_write_mapping[0x7]  = csky_pmu_write_l2ac;
1258         hw_raw_write_mapping[0x8]  = csky_pmu_write_l2mc;
1259         hw_raw_write_mapping[0xa]  = csky_pmu_write_iutlbmc;
1260         hw_raw_write_mapping[0xb]  = csky_pmu_write_dutlbmc;
1261         hw_raw_write_mapping[0xc]  = csky_pmu_write_jtlbmc;
1262         hw_raw_write_mapping[0xd]  = csky_pmu_write_softc;
1263         hw_raw_write_mapping[0xe]  = csky_pmu_write_cbmc;
1264         hw_raw_write_mapping[0xf]  = csky_pmu_write_cbic;
1265         hw_raw_write_mapping[0x10] = csky_pmu_write_ibmc;
1266         hw_raw_write_mapping[0x11] = csky_pmu_write_ibic;
1267         hw_raw_write_mapping[0x12] = csky_pmu_write_lsfc;
1268         hw_raw_write_mapping[0x13] = csky_pmu_write_sic;
1269         hw_raw_write_mapping[0x14] = csky_pmu_write_dcrac;
1270         hw_raw_write_mapping[0x15] = csky_pmu_write_dcrmc;
1271         hw_raw_write_mapping[0x16] = csky_pmu_write_dcwac;
1272         hw_raw_write_mapping[0x17] = csky_pmu_write_dcwmc;
1273         hw_raw_write_mapping[0x18] = csky_pmu_write_l2rac;
1274         hw_raw_write_mapping[0x19] = csky_pmu_write_l2rmc;
1275         hw_raw_write_mapping[0x1a] = csky_pmu_write_l2wac;
1276         hw_raw_write_mapping[0x1b] = csky_pmu_write_l2wmc;
1277 
1278         return 0;
1279 }
1280 
1281 static int csky_pmu_starting_cpu(unsigned int cpu)
1282 {
1283         enable_percpu_irq(csky_pmu_irq, 0);
1284         return 0;
1285 }
1286 
1287 static int csky_pmu_dying_cpu(unsigned int cpu)
1288 {
1289         disable_percpu_irq(csky_pmu_irq);
1290         return 0;
1291 }
1292 
1293 int csky_pmu_device_probe(struct platform_device *pdev,
1294                           const struct of_device_id *of_table)
1295 {
1296         struct device_node *node = pdev->dev.of_node;
1297         int ret;
1298 
1299         ret = init_hw_perf_events();
1300         if (ret) {
1301                 pr_notice("[perf] failed to probe PMU!\n");
1302                 return ret;
1303         }
1304 
1305         if (of_property_read_u32(node, "count-width",
1306                                  &csky_pmu.count_width)) {
1307                 csky_pmu.count_width = DEFAULT_COUNT_WIDTH;
1308         }
1309         csky_pmu.max_period = BIT_ULL(csky_pmu.count_width) - 1;
1310 
1311         csky_pmu.plat_device = pdev;
1312 
1313         /* Ensure the PMU has sane values out of reset. */
1314         on_each_cpu(csky_pmu_reset, &csky_pmu, 1);
1315 
1316         ret = csky_pmu_request_irq(csky_pmu_handle_irq);
1317         if (ret) {
1318                 csky_pmu.pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
1319                 pr_notice("[perf] PMU request irq fail!\n");
1320         }
1321 
1322         ret = cpuhp_setup_state(CPUHP_AP_PERF_ONLINE, "AP_PERF_ONLINE",
1323                                 csky_pmu_starting_cpu,
1324                                 csky_pmu_dying_cpu);
1325         if (ret) {
1326                 csky_pmu_free_irq();
1327                 free_percpu(csky_pmu.hw_events);
1328                 return ret;
1329         }
1330 
1331         ret = perf_pmu_register(&csky_pmu.pmu, "cpu", PERF_TYPE_RAW);
1332         if (ret) {
1333                 csky_pmu_free_irq();
1334                 free_percpu(csky_pmu.hw_events);
1335         }
1336 
1337         return ret;
1338 }
1339 
1340 static const struct of_device_id csky_pmu_of_device_ids[] = {
1341         {.compatible = "csky,csky-pmu"},
1342         {},
1343 };
1344 
1345 static int csky_pmu_dev_probe(struct platform_device *pdev)
1346 {
1347         return csky_pmu_device_probe(pdev, csky_pmu_of_device_ids);
1348 }
1349 
1350 static struct platform_driver csky_pmu_driver = {
1351         .driver = {
1352                    .name = "csky-pmu",
1353                    .of_match_table = csky_pmu_of_device_ids,
1354                    },
1355         .probe = csky_pmu_dev_probe,
1356 };
1357 
1358 static int __init csky_pmu_probe(void)
1359 {
1360         int ret;
1361 
1362         ret = platform_driver_register(&csky_pmu_driver);
1363         if (ret)
1364                 pr_notice("[perf] PMU initialization failed\n");
1365         else
1366                 pr_notice("[perf] PMU initialization done\n");
1367 
1368         return ret;
1369 }
1370 
1371 device_initcall(csky_pmu_probe);

/* [<][>][^][v][top][bottom][index][help] */