e6500-pmu.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Performance counter support for e6500 family processors.
  4. *
  5. * Author: Priyanka Jain, [email protected]
  6. * Based on e500-pmu.c
  7. * Copyright 2013 Freescale Semiconductor, Inc.
  8. * Copyright 2008-2009 Paul Mackerras, IBM Corporation.
  9. */
  10. #include <linux/string.h>
  11. #include <linux/perf_event.h>
  12. #include <asm/reg.h>
  13. #include <asm/cputable.h>
  14. /*
  15. * Map of generic hardware event types to hardware events
  16. * Zero if unsupported
  17. */
  18. static int e6500_generic_events[] = {
  19. [PERF_COUNT_HW_CPU_CYCLES] = 1,
  20. [PERF_COUNT_HW_INSTRUCTIONS] = 2,
  21. [PERF_COUNT_HW_CACHE_MISSES] = 221,
  22. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 12,
  23. [PERF_COUNT_HW_BRANCH_MISSES] = 15,
  24. };
  25. #define C(x) PERF_COUNT_HW_CACHE_##x
  26. /*
  27. * Table of generalized cache-related events.
  28. * 0 means not supported, -1 means nonsensical, other values
  29. * are event codes.
  30. */
  31. static int e6500_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
  32. [C(L1D)] = {
  33. /*RESULT_ACCESS RESULT_MISS */
  34. [C(OP_READ)] = { 27, 222 },
  35. [C(OP_WRITE)] = { 28, 223 },
  36. [C(OP_PREFETCH)] = { 29, 0 },
  37. },
  38. [C(L1I)] = {
  39. /*RESULT_ACCESS RESULT_MISS */
  40. [C(OP_READ)] = { 2, 254 },
  41. [C(OP_WRITE)] = { -1, -1 },
  42. [C(OP_PREFETCH)] = { 37, 0 },
  43. },
  44. /*
  45. * Assuming LL means L2, it's not a good match for this model.
  46. * It does not have separate read/write events (but it does have
  47. * separate instruction/data events).
  48. */
  49. [C(LL)] = {
  50. /*RESULT_ACCESS RESULT_MISS */
  51. [C(OP_READ)] = { 0, 0 },
  52. [C(OP_WRITE)] = { 0, 0 },
  53. [C(OP_PREFETCH)] = { 0, 0 },
  54. },
  55. /*
  56. * There are data/instruction MMU misses, but that's a miss on
  57. * the chip's internal level-one TLB which is probably not
  58. * what the user wants. Instead, unified level-two TLB misses
  59. * are reported here.
  60. */
  61. [C(DTLB)] = {
  62. /*RESULT_ACCESS RESULT_MISS */
  63. [C(OP_READ)] = { 26, 66 },
  64. [C(OP_WRITE)] = { -1, -1 },
  65. [C(OP_PREFETCH)] = { -1, -1 },
  66. },
  67. [C(BPU)] = {
  68. /*RESULT_ACCESS RESULT_MISS */
  69. [C(OP_READ)] = { 12, 15 },
  70. [C(OP_WRITE)] = { -1, -1 },
  71. [C(OP_PREFETCH)] = { -1, -1 },
  72. },
  73. [C(NODE)] = {
  74. /* RESULT_ACCESS RESULT_MISS */
  75. [C(OP_READ)] = { -1, -1 },
  76. [C(OP_WRITE)] = { -1, -1 },
  77. [C(OP_PREFETCH)] = { -1, -1 },
  78. },
  79. };
  80. static int num_events = 512;
  81. /* Upper half of event id is PMLCb, for threshold events */
  82. static u64 e6500_xlate_event(u64 event_id)
  83. {
  84. u32 event_low = (u32)event_id;
  85. if (event_low >= num_events ||
  86. (event_id & (FSL_EMB_EVENT_THRESHMUL | FSL_EMB_EVENT_THRESH)))
  87. return 0;
  88. return FSL_EMB_EVENT_VALID;
  89. }
  90. static struct fsl_emb_pmu e6500_pmu = {
  91. .name = "e6500 family",
  92. .n_counter = 6,
  93. .n_restricted = 0,
  94. .xlate_event = e6500_xlate_event,
  95. .n_generic = ARRAY_SIZE(e6500_generic_events),
  96. .generic_events = e6500_generic_events,
  97. .cache_events = &e6500_cache_events,
  98. };
  99. static int init_e6500_pmu(void)
  100. {
  101. unsigned int pvr = mfspr(SPRN_PVR);
  102. if (PVR_VER(pvr) != PVR_VER_E6500)
  103. return -ENODEV;
  104. return register_fsl_emb_pmu(&e6500_pmu);
  105. }
  106. early_initcall(init_e6500_pmu);