perf_event_v7.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903
  1. /*
  2. * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
  3. *
  4. * ARMv7 support: Jean Pihet <jpihet@mvista.com>
  5. * 2010 (c) MontaVista Software, LLC.
  6. *
  7. * Copied from ARMv6 code, with the low level code inspired
  8. * by the ARMv7 Oprofile code.
  9. *
  10. * Cortex-A8 has up to 4 configurable performance counters and
  11. * a single cycle counter.
  12. * Cortex-A9 has up to 31 configurable performance counters and
  13. * a single cycle counter.
  14. *
  15. * All counters can be enabled/disabled and IRQ masked separately. The cycle
  16. * counter and all 4 performance counters together can be reset separately.
  17. */
  18. #ifdef CONFIG_CPU_V7
  19. #include <asm/cp15.h>
  20. #include <asm/cputype.h>
  21. #include <asm/irq_regs.h>
  22. #include <asm/vfp.h>
  23. #include "../vfp/vfpinstr.h"
  24. #include <linux/of.h>
  25. #include <linux/perf/arm_pmu.h>
  26. #include <linux/platform_device.h>
  27. /*
  28. * Common ARMv7 event types
  29. *
  30. * Note: An implementation may not be able to count all of these events
  31. * but the encodings are considered to be `reserved' in the case that
  32. * they are not available.
  33. */
  34. enum armv7_perf_types {
  35. ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
  36. ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
  37. ARMV7_PERFCTR_ITLB_REFILL = 0x02,
  38. ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
  39. ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
  40. ARMV7_PERFCTR_DTLB_REFILL = 0x05,
  41. ARMV7_PERFCTR_MEM_READ = 0x06,
  42. ARMV7_PERFCTR_MEM_WRITE = 0x07,
  43. ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
  44. ARMV7_PERFCTR_EXC_TAKEN = 0x09,
  45. ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
  46. ARMV7_PERFCTR_CID_WRITE = 0x0B,
  47. /*
  48. * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
  49. * It counts:
  50. * - all (taken) branch instructions,
  51. * - instructions that explicitly write the PC,
  52. * - exception generating instructions.
  53. */
  54. ARMV7_PERFCTR_PC_WRITE = 0x0C,
  55. ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
  56. ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
  57. ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
  58. ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
  59. ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
  60. ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
  61. /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
  62. ARMV7_PERFCTR_MEM_ACCESS = 0x13,
  63. ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
  64. ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
  65. ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
  66. ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
  67. ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
  68. ARMV7_PERFCTR_BUS_ACCESS = 0x19,
  69. ARMV7_PERFCTR_MEM_ERROR = 0x1A,
  70. ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
  71. ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
  72. ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
  73. ARMV7_PERFCTR_CPU_CYCLES = 0xFF
  74. };
  75. /* ARMv7 Cortex-A8 specific event types */
  76. enum armv7_a8_perf_types {
  77. ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
  78. ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
  79. ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
  80. ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
  81. };
  82. /* ARMv7 Cortex-A9 specific event types */
  83. enum armv7_a9_perf_types {
  84. ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
  85. ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
  86. ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
  87. };
  88. /* ARMv7 Cortex-A5 specific event types */
  89. enum armv7_a5_perf_types {
  90. ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
  91. ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
  92. };
  93. /* ARMv7 Cortex-A15 specific event types */
  94. enum armv7_a15_perf_types {
  95. ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
  96. ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
  97. ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
  98. ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
  99. ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
  100. ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
  101. ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
  102. ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
  103. ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
  104. ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
  105. ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
  106. };
  107. /* ARMv7 Cortex-A12 specific event types */
  108. enum armv7_a12_perf_types {
  109. ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
  110. ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
  111. ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
  112. ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
  113. ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
  114. ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
  115. };
  116. /* ARMv7 Krait specific event types */
  117. enum krait_perf_types {
  118. KRAIT_PMRESR0_GROUP0 = 0xcc,
  119. KRAIT_PMRESR1_GROUP0 = 0xd0,
  120. KRAIT_PMRESR2_GROUP0 = 0xd4,
  121. KRAIT_VPMRESR0_GROUP0 = 0xd8,
  122. KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
  123. KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
  124. KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
  125. KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
  126. };
  127. /* ARMv7 Scorpion specific event types */
  128. enum scorpion_perf_types {
  129. SCORPION_LPM0_GROUP0 = 0x4c,
  130. SCORPION_LPM1_GROUP0 = 0x50,
  131. SCORPION_LPM2_GROUP0 = 0x54,
  132. SCORPION_L2LPM_GROUP0 = 0x58,
  133. SCORPION_VLPM_GROUP0 = 0x5c,
  134. SCORPION_ICACHE_ACCESS = 0x10053,
  135. SCORPION_ICACHE_MISS = 0x10052,
  136. SCORPION_DTLB_ACCESS = 0x12013,
  137. SCORPION_DTLB_MISS = 0x12012,
  138. SCORPION_ITLB_MISS = 0x12021,
  139. };
  140. /*
  141. * Cortex-A8 HW events mapping
  142. *
  143. * The hardware events that we support. We do support cache operations but
  144. * we have harvard caches and no way to combine instruction and data
  145. * accesses/misses in hardware.
  146. */
  147. static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
  148. PERF_MAP_ALL_UNSUPPORTED,
  149. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  150. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  151. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  152. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  153. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  154. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  155. [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
  156. };
  157. static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  158. [PERF_COUNT_HW_CACHE_OP_MAX]
  159. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  160. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  161. /*
  162. * The performance counters don't differentiate between read and write
  163. * accesses/misses so this isn't strictly correct, but it's the best we
  164. * can do. Writes and reads get combined.
  165. */
  166. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  167. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  168. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  169. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  170. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
  171. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  172. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
  173. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
  174. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
  175. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
  176. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  177. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  178. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  179. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  180. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  181. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  182. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  183. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  184. };
  185. /*
  186. * Cortex-A9 HW events mapping
  187. */
  188. static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
  189. PERF_MAP_ALL_UNSUPPORTED,
  190. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  191. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
  192. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  193. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  194. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  195. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  196. [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
  197. [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
  198. };
  199. static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  200. [PERF_COUNT_HW_CACHE_OP_MAX]
  201. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  202. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  203. /*
  204. * The performance counters don't differentiate between read and write
  205. * accesses/misses so this isn't strictly correct, but it's the best we
  206. * can do. Writes and reads get combined.
  207. */
  208. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  209. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  210. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  211. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  212. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  213. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  214. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  215. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  216. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  217. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  218. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  219. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  220. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  221. };
  222. /*
  223. * Cortex-A5 HW events mapping
  224. */
  225. static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
  226. PERF_MAP_ALL_UNSUPPORTED,
  227. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  228. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  229. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  230. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  231. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  232. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  233. };
  234. static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  235. [PERF_COUNT_HW_CACHE_OP_MAX]
  236. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  237. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  238. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  239. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  240. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  241. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  242. [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
  243. [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
  244. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  245. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  246. /*
  247. * The prefetch counters don't differentiate between the I side and the
  248. * D side.
  249. */
  250. [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
  251. [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
  252. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  253. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  254. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  255. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  256. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  257. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  258. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  259. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  260. };
  261. /*
  262. * Cortex-A15 HW events mapping
  263. */
  264. static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
  265. PERF_MAP_ALL_UNSUPPORTED,
  266. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  267. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  268. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  269. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  270. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
  271. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  272. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  273. };
  274. static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  275. [PERF_COUNT_HW_CACHE_OP_MAX]
  276. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  277. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  278. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
  279. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
  280. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
  281. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
  282. /*
  283. * Not all performance counters differentiate between read and write
  284. * accesses/misses so we're not always strictly correct, but it's the
  285. * best we can do. Writes and reads get combined in these cases.
  286. */
  287. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  288. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  289. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
  290. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
  291. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
  292. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
  293. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
  294. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
  295. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  296. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  297. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  298. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  299. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  300. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  301. };
  302. /*
  303. * Cortex-A7 HW events mapping
  304. */
  305. static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
  306. PERF_MAP_ALL_UNSUPPORTED,
  307. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  308. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  309. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  310. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  311. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  312. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  313. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  314. };
  315. static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  316. [PERF_COUNT_HW_CACHE_OP_MAX]
  317. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  318. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  319. /*
  320. * The performance counters don't differentiate between read and write
  321. * accesses/misses so this isn't strictly correct, but it's the best we
  322. * can do. Writes and reads get combined.
  323. */
  324. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  325. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  326. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  327. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  328. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  329. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  330. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
  331. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  332. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
  333. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  334. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  335. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  336. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  337. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  338. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  339. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  340. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  341. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  342. };
  343. /*
  344. * Cortex-A12 HW events mapping
  345. */
  346. static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
  347. PERF_MAP_ALL_UNSUPPORTED,
  348. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  349. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  350. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  351. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  352. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
  353. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  354. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  355. };
  356. static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  357. [PERF_COUNT_HW_CACHE_OP_MAX]
  358. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  359. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  360. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
  361. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  362. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
  363. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  364. /*
  365. * Not all performance counters differentiate between read and write
  366. * accesses/misses so we're not always strictly correct, but it's the
  367. * best we can do. Writes and reads get combined in these cases.
  368. */
  369. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  370. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  371. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
  372. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  373. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
  374. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  375. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  376. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  377. [C(DTLB)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
  378. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  379. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  380. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  381. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  382. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  383. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  384. };
  385. /*
  386. * Krait HW events mapping
  387. */
  388. static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
  389. PERF_MAP_ALL_UNSUPPORTED,
  390. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  391. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  392. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  393. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  394. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  395. };
  396. static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
  397. PERF_MAP_ALL_UNSUPPORTED,
  398. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  399. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  400. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  401. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  402. };
  403. static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  404. [PERF_COUNT_HW_CACHE_OP_MAX]
  405. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  406. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  407. /*
  408. * The performance counters don't differentiate between read and write
  409. * accesses/misses so this isn't strictly correct, but it's the best we
  410. * can do. Writes and reads get combined.
  411. */
  412. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  413. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  414. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  415. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  416. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
  417. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
  418. [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
  419. [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
  420. [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
  421. [C(ITLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
  422. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  423. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  424. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  425. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  426. };
  427. /*
  428. * Scorpion HW events mapping
  429. */
  430. static const unsigned scorpion_perf_map[PERF_COUNT_HW_MAX] = {
  431. PERF_MAP_ALL_UNSUPPORTED,
  432. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  433. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  434. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  435. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  436. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  437. };
  438. static const unsigned scorpion_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  439. [PERF_COUNT_HW_CACHE_OP_MAX]
  440. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  441. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  442. /*
  443. * The performance counters don't differentiate between read and write
  444. * accesses/misses so this isn't strictly correct, but it's the best we
  445. * can do. Writes and reads get combined.
  446. */
  447. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  448. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  449. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  450. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  451. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_ICACHE_ACCESS,
  452. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ICACHE_MISS,
  453. /*
  454. * Only ITLB misses and DTLB refills are supported. If users want the
  455. * DTLB refills misses a raw counter must be used.
  456. */
  457. [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
  458. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
  459. [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = SCORPION_DTLB_ACCESS,
  460. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_DTLB_MISS,
  461. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
  462. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = SCORPION_ITLB_MISS,
  463. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  464. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  465. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  466. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  467. };
  468. /*
  469. * Perf Events' indices
  470. */
  471. #define ARMV7_IDX_CYCLE_COUNTER 0
  472. #define ARMV7_IDX_COUNTER0 1
  473. #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
  474. (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
  475. #define ARMV7_MAX_COUNTERS 32
  476. #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
  477. /*
  478. * ARMv7 low level PMNC access
  479. */
  480. /*
  481. * Perf Event to low level counters mapping
  482. */
  483. #define ARMV7_IDX_TO_COUNTER(x) \
  484. (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
  485. /*
  486. * Per-CPU PMNC: config reg
  487. */
  488. #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
  489. #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
  490. #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
  491. #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
  492. #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
  493. #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
  494. #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
  495. #define ARMV7_PMNC_N_MASK 0x1f
  496. #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
  497. /*
  498. * FLAG: counters overflow flag status reg
  499. */
  500. #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
  501. #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
  502. /*
  503. * PMXEVTYPER: Event selection reg
  504. */
  505. #define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
  506. #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
  507. /*
  508. * Event filters for PMUv2
  509. */
  510. #define ARMV7_EXCLUDE_PL1 (1 << 31)
  511. #define ARMV7_EXCLUDE_USER (1 << 30)
  512. #define ARMV7_INCLUDE_HYP (1 << 27)
  513. static inline u32 armv7_pmnc_read(void)
  514. {
  515. u32 val;
  516. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
  517. return val;
  518. }
  519. static inline void armv7_pmnc_write(u32 val)
  520. {
  521. val &= ARMV7_PMNC_MASK;
  522. isb();
  523. asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
  524. }
  525. static inline int armv7_pmnc_has_overflowed(u32 pmnc)
  526. {
  527. return pmnc & ARMV7_OVERFLOWED_MASK;
  528. }
  529. static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
  530. {
  531. return idx >= ARMV7_IDX_CYCLE_COUNTER &&
  532. idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
  533. }
  534. static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
  535. {
  536. return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
  537. }
  538. static inline void armv7_pmnc_select_counter(int idx)
  539. {
  540. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  541. asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
  542. isb();
  543. }
  544. static inline u32 armv7pmu_read_counter(struct perf_event *event)
  545. {
  546. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  547. struct hw_perf_event *hwc = &event->hw;
  548. int idx = hwc->idx;
  549. u32 value = 0;
  550. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  551. pr_err("CPU%u reading wrong counter %d\n",
  552. smp_processor_id(), idx);
  553. } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
  554. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
  555. } else {
  556. armv7_pmnc_select_counter(idx);
  557. asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
  558. }
  559. return value;
  560. }
  561. static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
  562. {
  563. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  564. struct hw_perf_event *hwc = &event->hw;
  565. int idx = hwc->idx;
  566. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  567. pr_err("CPU%u writing wrong counter %d\n",
  568. smp_processor_id(), idx);
  569. } else if (idx == ARMV7_IDX_CYCLE_COUNTER) {
  570. asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
  571. } else {
  572. armv7_pmnc_select_counter(idx);
  573. asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
  574. }
  575. }
  576. static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
  577. {
  578. armv7_pmnc_select_counter(idx);
  579. val &= ARMV7_EVTYPE_MASK;
  580. asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
  581. }
  582. static inline void armv7_pmnc_enable_counter(int idx)
  583. {
  584. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  585. asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
  586. }
  587. static inline void armv7_pmnc_disable_counter(int idx)
  588. {
  589. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  590. asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
  591. }
  592. static inline void armv7_pmnc_enable_intens(int idx)
  593. {
  594. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  595. asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
  596. }
  597. static inline void armv7_pmnc_disable_intens(int idx)
  598. {
  599. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  600. asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
  601. isb();
  602. /* Clear the overflow flag in case an interrupt is pending. */
  603. asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
  604. isb();
  605. }
  606. static inline u32 armv7_pmnc_getreset_flags(void)
  607. {
  608. u32 val;
  609. /* Read */
  610. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  611. /* Write to clear flags */
  612. val &= ARMV7_FLAG_MASK;
  613. asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
  614. return val;
  615. }
  616. #ifdef DEBUG
  617. static void armv7_pmnc_dump_regs(struct arm_pmu *cpu_pmu)
  618. {
  619. u32 val;
  620. unsigned int cnt;
  621. pr_info("PMNC registers dump:\n");
  622. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
  623. pr_info("PMNC =0x%08x\n", val);
  624. asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
  625. pr_info("CNTENS=0x%08x\n", val);
  626. asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
  627. pr_info("INTENS=0x%08x\n", val);
  628. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  629. pr_info("FLAGS =0x%08x\n", val);
  630. asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
  631. pr_info("SELECT=0x%08x\n", val);
  632. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
  633. pr_info("CCNT =0x%08x\n", val);
  634. for (cnt = ARMV7_IDX_COUNTER0;
  635. cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  636. armv7_pmnc_select_counter(cnt);
  637. asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
  638. pr_info("CNT[%d] count =0x%08x\n",
  639. ARMV7_IDX_TO_COUNTER(cnt), val);
  640. asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
  641. pr_info("CNT[%d] evtsel=0x%08x\n",
  642. ARMV7_IDX_TO_COUNTER(cnt), val);
  643. }
  644. }
  645. #endif
  646. static void armv7pmu_enable_event(struct perf_event *event)
  647. {
  648. unsigned long flags;
  649. struct hw_perf_event *hwc = &event->hw;
  650. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  651. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  652. int idx = hwc->idx;
  653. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  654. pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
  655. smp_processor_id(), idx);
  656. return;
  657. }
  658. /*
  659. * Enable counter and interrupt, and set the counter to count
  660. * the event that we're interested in.
  661. */
  662. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  663. /*
  664. * Disable counter
  665. */
  666. armv7_pmnc_disable_counter(idx);
  667. /*
  668. * Set event (if destined for PMNx counters)
  669. * We only need to set the event for the cycle counter if we
  670. * have the ability to perform event filtering.
  671. */
  672. if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
  673. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  674. /*
  675. * Enable interrupt for this counter
  676. */
  677. armv7_pmnc_enable_intens(idx);
  678. /*
  679. * Enable counter
  680. */
  681. armv7_pmnc_enable_counter(idx);
  682. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  683. }
  684. static void armv7pmu_disable_event(struct perf_event *event)
  685. {
  686. unsigned long flags;
  687. struct hw_perf_event *hwc = &event->hw;
  688. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  689. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  690. int idx = hwc->idx;
  691. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  692. pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
  693. smp_processor_id(), idx);
  694. return;
  695. }
  696. /*
  697. * Disable counter and interrupt
  698. */
  699. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  700. /*
  701. * Disable counter
  702. */
  703. armv7_pmnc_disable_counter(idx);
  704. /*
  705. * Disable interrupt for this counter
  706. */
  707. armv7_pmnc_disable_intens(idx);
  708. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  709. }
  710. static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
  711. {
  712. u32 pmnc;
  713. struct perf_sample_data data;
  714. struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
  715. struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
  716. struct pt_regs *regs;
  717. int idx;
  718. /*
  719. * Get and reset the IRQ flags
  720. */
  721. pmnc = armv7_pmnc_getreset_flags();
  722. /*
  723. * Did an overflow occur?
  724. */
  725. if (!armv7_pmnc_has_overflowed(pmnc))
  726. return IRQ_NONE;
  727. /*
  728. * Handle the counter(s) overflow(s)
  729. */
  730. regs = get_irq_regs();
  731. for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
  732. struct perf_event *event = cpuc->events[idx];
  733. struct hw_perf_event *hwc;
  734. /* Ignore if we don't have an event. */
  735. if (!event)
  736. continue;
  737. /*
  738. * We have a single interrupt for all counters. Check that
  739. * each counter has overflowed before we process it.
  740. */
  741. if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
  742. continue;
  743. hwc = &event->hw;
  744. armpmu_event_update(event);
  745. perf_sample_data_init(&data, 0, hwc->last_period);
  746. if (!armpmu_event_set_period(event))
  747. continue;
  748. if (perf_event_overflow(event, &data, regs))
  749. cpu_pmu->disable(event);
  750. }
  751. /*
  752. * Handle the pending perf events.
  753. *
  754. * Note: this call *must* be run with interrupts disabled. For
  755. * platforms that can have the PMU interrupts raised as an NMI, this
  756. * will not work.
  757. */
  758. irq_work_run();
  759. return IRQ_HANDLED;
  760. }
  761. static void armv7pmu_start(struct arm_pmu *cpu_pmu)
  762. {
  763. unsigned long flags;
  764. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  765. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  766. /* Enable all counters */
  767. armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
  768. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  769. }
  770. static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
  771. {
  772. unsigned long flags;
  773. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  774. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  775. /* Disable all counters */
  776. armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
  777. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  778. }
  779. static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
  780. struct perf_event *event)
  781. {
  782. int idx;
  783. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  784. struct hw_perf_event *hwc = &event->hw;
  785. unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
  786. /* Always place a cycle counter into the cycle counter. */
  787. if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
  788. if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
  789. return -EAGAIN;
  790. return ARMV7_IDX_CYCLE_COUNTER;
  791. }
  792. /*
  793. * For anything other than a cycle counter, try and use
  794. * the events counters
  795. */
  796. for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
  797. if (!test_and_set_bit(idx, cpuc->used_mask))
  798. return idx;
  799. }
  800. /* The counters are all in use. */
  801. return -EAGAIN;
  802. }
  803. /*
  804. * Add an event filter to a given event. This will only work for PMUv2 PMUs.
  805. */
  806. static int armv7pmu_set_event_filter(struct hw_perf_event *event,
  807. struct perf_event_attr *attr)
  808. {
  809. unsigned long config_base = 0;
  810. if (attr->exclude_idle)
  811. return -EPERM;
  812. if (attr->exclude_user)
  813. config_base |= ARMV7_EXCLUDE_USER;
  814. if (attr->exclude_kernel)
  815. config_base |= ARMV7_EXCLUDE_PL1;
  816. if (!attr->exclude_hv)
  817. config_base |= ARMV7_INCLUDE_HYP;
  818. /*
  819. * Install the filter into config_base as this is used to
  820. * construct the event type.
  821. */
  822. event->config_base = config_base;
  823. return 0;
  824. }
  825. static void armv7pmu_reset(void *info)
  826. {
  827. struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
  828. u32 idx, nb_cnt = cpu_pmu->num_events;
  829. /* The counter and interrupt enable registers are unknown at reset. */
  830. for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
  831. armv7_pmnc_disable_counter(idx);
  832. armv7_pmnc_disable_intens(idx);
  833. }
  834. /* Initialize & Reset PMNC: C and P bits */
  835. armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
  836. }
  837. static int armv7_a8_map_event(struct perf_event *event)
  838. {
  839. return armpmu_map_event(event, &armv7_a8_perf_map,
  840. &armv7_a8_perf_cache_map, 0xFF);
  841. }
  842. static int armv7_a9_map_event(struct perf_event *event)
  843. {
  844. return armpmu_map_event(event, &armv7_a9_perf_map,
  845. &armv7_a9_perf_cache_map, 0xFF);
  846. }
  847. static int armv7_a5_map_event(struct perf_event *event)
  848. {
  849. return armpmu_map_event(event, &armv7_a5_perf_map,
  850. &armv7_a5_perf_cache_map, 0xFF);
  851. }
  852. static int armv7_a15_map_event(struct perf_event *event)
  853. {
  854. return armpmu_map_event(event, &armv7_a15_perf_map,
  855. &armv7_a15_perf_cache_map, 0xFF);
  856. }
  857. static int armv7_a7_map_event(struct perf_event *event)
  858. {
  859. return armpmu_map_event(event, &armv7_a7_perf_map,
  860. &armv7_a7_perf_cache_map, 0xFF);
  861. }
  862. static int armv7_a12_map_event(struct perf_event *event)
  863. {
  864. return armpmu_map_event(event, &armv7_a12_perf_map,
  865. &armv7_a12_perf_cache_map, 0xFF);
  866. }
  867. static int krait_map_event(struct perf_event *event)
  868. {
  869. return armpmu_map_event(event, &krait_perf_map,
  870. &krait_perf_cache_map, 0xFFFFF);
  871. }
  872. static int krait_map_event_no_branch(struct perf_event *event)
  873. {
  874. return armpmu_map_event(event, &krait_perf_map_no_branch,
  875. &krait_perf_cache_map, 0xFFFFF);
  876. }
  877. static int scorpion_map_event(struct perf_event *event)
  878. {
  879. return armpmu_map_event(event, &scorpion_perf_map,
  880. &scorpion_perf_cache_map, 0xFFFFF);
  881. }
  882. static void armv7pmu_init(struct arm_pmu *cpu_pmu)
  883. {
  884. cpu_pmu->handle_irq = armv7pmu_handle_irq;
  885. cpu_pmu->enable = armv7pmu_enable_event;
  886. cpu_pmu->disable = armv7pmu_disable_event;
  887. cpu_pmu->read_counter = armv7pmu_read_counter;
  888. cpu_pmu->write_counter = armv7pmu_write_counter;
  889. cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
  890. cpu_pmu->start = armv7pmu_start;
  891. cpu_pmu->stop = armv7pmu_stop;
  892. cpu_pmu->reset = armv7pmu_reset;
  893. cpu_pmu->max_period = (1LLU << 32) - 1;
  894. };
  895. static void armv7_read_num_pmnc_events(void *info)
  896. {
  897. int *nb_cnt = info;
  898. /* Read the nb of CNTx counters supported from PMNC */
  899. *nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
  900. /* Add the CPU cycles counter */
  901. *nb_cnt += 1;
  902. }
  903. static int armv7_probe_num_events(struct arm_pmu *arm_pmu)
  904. {
  905. return smp_call_function_any(&arm_pmu->supported_cpus,
  906. armv7_read_num_pmnc_events,
  907. &arm_pmu->num_events, 1);
  908. }
  909. static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  910. {
  911. armv7pmu_init(cpu_pmu);
  912. cpu_pmu->name = "armv7_cortex_a8";
  913. cpu_pmu->map_event = armv7_a8_map_event;
  914. return armv7_probe_num_events(cpu_pmu);
  915. }
  916. static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  917. {
  918. armv7pmu_init(cpu_pmu);
  919. cpu_pmu->name = "armv7_cortex_a9";
  920. cpu_pmu->map_event = armv7_a9_map_event;
  921. return armv7_probe_num_events(cpu_pmu);
  922. }
  923. static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  924. {
  925. armv7pmu_init(cpu_pmu);
  926. cpu_pmu->name = "armv7_cortex_a5";
  927. cpu_pmu->map_event = armv7_a5_map_event;
  928. return armv7_probe_num_events(cpu_pmu);
  929. }
  930. static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  931. {
  932. armv7pmu_init(cpu_pmu);
  933. cpu_pmu->name = "armv7_cortex_a15";
  934. cpu_pmu->map_event = armv7_a15_map_event;
  935. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  936. return armv7_probe_num_events(cpu_pmu);
  937. }
  938. static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  939. {
  940. armv7pmu_init(cpu_pmu);
  941. cpu_pmu->name = "armv7_cortex_a7";
  942. cpu_pmu->map_event = armv7_a7_map_event;
  943. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  944. return armv7_probe_num_events(cpu_pmu);
  945. }
  946. static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
  947. {
  948. armv7pmu_init(cpu_pmu);
  949. cpu_pmu->name = "armv7_cortex_a12";
  950. cpu_pmu->map_event = armv7_a12_map_event;
  951. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  952. return armv7_probe_num_events(cpu_pmu);
  953. }
  954. static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
  955. {
  956. int ret = armv7_a12_pmu_init(cpu_pmu);
  957. cpu_pmu->name = "armv7_cortex_a17";
  958. return ret;
  959. }
  960. /*
  961. * Krait Performance Monitor Region Event Selection Register (PMRESRn)
  962. *
  963. * 31 30 24 16 8 0
  964. * +--------------------------------+
  965. * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
  966. * +--------------------------------+
  967. * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
  968. * +--------------------------------+
  969. * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
  970. * +--------------------------------+
  971. * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
  972. * +--------------------------------+
  973. * EN | G=3 | G=2 | G=1 | G=0
  974. *
  975. * Event Encoding:
  976. *
  977. * hwc->config_base = 0xNRCCG
  978. *
  979. * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
  980. * R = region register
  981. * CC = class of events the group G is choosing from
  982. * G = group or particular event
  983. *
  984. * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
  985. *
  986. * A region (R) corresponds to a piece of the CPU (execution unit, instruction
  987. * unit, etc.) while the event code (CC) corresponds to a particular class of
  988. * events (interrupts for example). An event code is broken down into
  989. * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
  990. * example).
  991. */
  992. #define KRAIT_EVENT (1 << 16)
  993. #define VENUM_EVENT (2 << 16)
  994. #define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
  995. #define PMRESRn_EN BIT(31)
  996. #define EVENT_REGION(event) (((event) >> 12) & 0xf) /* R */
  997. #define EVENT_GROUP(event) ((event) & 0xf) /* G */
  998. #define EVENT_CODE(event) (((event) >> 4) & 0xff) /* CC */
  999. #define EVENT_VENUM(event) (!!(event & VENUM_EVENT)) /* N=2 */
  1000. #define EVENT_CPU(event) (!!(event & KRAIT_EVENT)) /* N=1 */
  1001. static u32 krait_read_pmresrn(int n)
  1002. {
  1003. u32 val;
  1004. switch (n) {
  1005. case 0:
  1006. asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
  1007. break;
  1008. case 1:
  1009. asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
  1010. break;
  1011. case 2:
  1012. asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
  1013. break;
  1014. default:
  1015. BUG(); /* Should be validated in krait_pmu_get_event_idx() */
  1016. }
  1017. return val;
  1018. }
  1019. static void krait_write_pmresrn(int n, u32 val)
  1020. {
  1021. switch (n) {
  1022. case 0:
  1023. asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
  1024. break;
  1025. case 1:
  1026. asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
  1027. break;
  1028. case 2:
  1029. asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
  1030. break;
  1031. default:
  1032. BUG(); /* Should be validated in krait_pmu_get_event_idx() */
  1033. }
  1034. }
  1035. static u32 venum_read_pmresr(void)
  1036. {
  1037. u32 val;
  1038. asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
  1039. return val;
  1040. }
  1041. static void venum_write_pmresr(u32 val)
  1042. {
  1043. asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
  1044. }
  1045. static void venum_pre_pmresr(u32 *venum_orig_val, u32 *fp_orig_val)
  1046. {
  1047. u32 venum_new_val;
  1048. u32 fp_new_val;
  1049. BUG_ON(preemptible());
  1050. /* CPACR Enable CP10 and CP11 access */
  1051. *venum_orig_val = get_copro_access();
  1052. venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
  1053. set_copro_access(venum_new_val);
  1054. /* Enable FPEXC */
  1055. *fp_orig_val = fmrx(FPEXC);
  1056. fp_new_val = *fp_orig_val | FPEXC_EN;
  1057. fmxr(FPEXC, fp_new_val);
  1058. }
  1059. static void venum_post_pmresr(u32 venum_orig_val, u32 fp_orig_val)
  1060. {
  1061. BUG_ON(preemptible());
  1062. /* Restore FPEXC */
  1063. fmxr(FPEXC, fp_orig_val);
  1064. isb();
  1065. /* Restore CPACR */
  1066. set_copro_access(venum_orig_val);
  1067. }
  1068. static u32 krait_get_pmresrn_event(unsigned int region)
  1069. {
  1070. static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
  1071. KRAIT_PMRESR1_GROUP0,
  1072. KRAIT_PMRESR2_GROUP0 };
  1073. return pmresrn_table[region];
  1074. }
  1075. static void krait_evt_setup(int idx, u32 config_base)
  1076. {
  1077. u32 val;
  1078. u32 mask;
  1079. u32 vval, fval;
  1080. unsigned int region = EVENT_REGION(config_base);
  1081. unsigned int group = EVENT_GROUP(config_base);
  1082. unsigned int code = EVENT_CODE(config_base);
  1083. unsigned int group_shift;
  1084. bool venum_event = EVENT_VENUM(config_base);
  1085. group_shift = group * 8;
  1086. mask = 0xff << group_shift;
  1087. /* Configure evtsel for the region and group */
  1088. if (venum_event)
  1089. val = KRAIT_VPMRESR0_GROUP0;
  1090. else
  1091. val = krait_get_pmresrn_event(region);
  1092. val += group;
  1093. /* Mix in mode-exclusion bits */
  1094. val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
  1095. armv7_pmnc_write_evtsel(idx, val);
  1096. if (venum_event) {
  1097. venum_pre_pmresr(&vval, &fval);
  1098. val = venum_read_pmresr();
  1099. val &= ~mask;
  1100. val |= code << group_shift;
  1101. val |= PMRESRn_EN;
  1102. venum_write_pmresr(val);
  1103. venum_post_pmresr(vval, fval);
  1104. } else {
  1105. val = krait_read_pmresrn(region);
  1106. val &= ~mask;
  1107. val |= code << group_shift;
  1108. val |= PMRESRn_EN;
  1109. krait_write_pmresrn(region, val);
  1110. }
  1111. }
  1112. static u32 clear_pmresrn_group(u32 val, int group)
  1113. {
  1114. u32 mask;
  1115. int group_shift;
  1116. group_shift = group * 8;
  1117. mask = 0xff << group_shift;
  1118. val &= ~mask;
  1119. /* Don't clear enable bit if entire region isn't disabled */
  1120. if (val & ~PMRESRn_EN)
  1121. return val |= PMRESRn_EN;
  1122. return 0;
  1123. }
  1124. static void krait_clearpmu(u32 config_base)
  1125. {
  1126. u32 val;
  1127. u32 vval, fval;
  1128. unsigned int region = EVENT_REGION(config_base);
  1129. unsigned int group = EVENT_GROUP(config_base);
  1130. bool venum_event = EVENT_VENUM(config_base);
  1131. if (venum_event) {
  1132. venum_pre_pmresr(&vval, &fval);
  1133. val = venum_read_pmresr();
  1134. val = clear_pmresrn_group(val, group);
  1135. venum_write_pmresr(val);
  1136. venum_post_pmresr(vval, fval);
  1137. } else {
  1138. val = krait_read_pmresrn(region);
  1139. val = clear_pmresrn_group(val, group);
  1140. krait_write_pmresrn(region, val);
  1141. }
  1142. }
  1143. static void krait_pmu_disable_event(struct perf_event *event)
  1144. {
  1145. unsigned long flags;
  1146. struct hw_perf_event *hwc = &event->hw;
  1147. int idx = hwc->idx;
  1148. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1149. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  1150. /* Disable counter and interrupt */
  1151. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1152. /* Disable counter */
  1153. armv7_pmnc_disable_counter(idx);
  1154. /*
  1155. * Clear pmresr code (if destined for PMNx counters)
  1156. */
  1157. if (hwc->config_base & KRAIT_EVENT_MASK)
  1158. krait_clearpmu(hwc->config_base);
  1159. /* Disable interrupt for this counter */
  1160. armv7_pmnc_disable_intens(idx);
  1161. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1162. }
  1163. static void krait_pmu_enable_event(struct perf_event *event)
  1164. {
  1165. unsigned long flags;
  1166. struct hw_perf_event *hwc = &event->hw;
  1167. int idx = hwc->idx;
  1168. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1169. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  1170. /*
  1171. * Enable counter and interrupt, and set the counter to count
  1172. * the event that we're interested in.
  1173. */
  1174. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1175. /* Disable counter */
  1176. armv7_pmnc_disable_counter(idx);
  1177. /*
  1178. * Set event (if destined for PMNx counters)
  1179. * We set the event for the cycle counter because we
  1180. * have the ability to perform event filtering.
  1181. */
  1182. if (hwc->config_base & KRAIT_EVENT_MASK)
  1183. krait_evt_setup(idx, hwc->config_base);
  1184. else
  1185. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  1186. /* Enable interrupt for this counter */
  1187. armv7_pmnc_enable_intens(idx);
  1188. /* Enable counter */
  1189. armv7_pmnc_enable_counter(idx);
  1190. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1191. }
  1192. static void krait_pmu_reset(void *info)
  1193. {
  1194. u32 vval, fval;
  1195. struct arm_pmu *cpu_pmu = info;
  1196. u32 idx, nb_cnt = cpu_pmu->num_events;
  1197. armv7pmu_reset(info);
  1198. /* Clear all pmresrs */
  1199. krait_write_pmresrn(0, 0);
  1200. krait_write_pmresrn(1, 0);
  1201. krait_write_pmresrn(2, 0);
  1202. venum_pre_pmresr(&vval, &fval);
  1203. venum_write_pmresr(0);
  1204. venum_post_pmresr(vval, fval);
  1205. /* Reset PMxEVNCTCR to sane default */
  1206. for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
  1207. armv7_pmnc_select_counter(idx);
  1208. asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
  1209. }
  1210. }
  1211. static int krait_event_to_bit(struct perf_event *event, unsigned int region,
  1212. unsigned int group)
  1213. {
  1214. int bit;
  1215. struct hw_perf_event *hwc = &event->hw;
  1216. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1217. if (hwc->config_base & VENUM_EVENT)
  1218. bit = KRAIT_VPMRESR0_GROUP0;
  1219. else
  1220. bit = krait_get_pmresrn_event(region);
  1221. bit -= krait_get_pmresrn_event(0);
  1222. bit += group;
  1223. /*
  1224. * Lower bits are reserved for use by the counters (see
  1225. * armv7pmu_get_event_idx() for more info)
  1226. */
  1227. bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
  1228. return bit;
  1229. }
  1230. /*
  1231. * We check for column exclusion constraints here.
  1232. * Two events cant use the same group within a pmresr register.
  1233. */
  1234. static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
  1235. struct perf_event *event)
  1236. {
  1237. int idx;
  1238. int bit = -1;
  1239. struct hw_perf_event *hwc = &event->hw;
  1240. unsigned int region = EVENT_REGION(hwc->config_base);
  1241. unsigned int code = EVENT_CODE(hwc->config_base);
  1242. unsigned int group = EVENT_GROUP(hwc->config_base);
  1243. bool venum_event = EVENT_VENUM(hwc->config_base);
  1244. bool krait_event = EVENT_CPU(hwc->config_base);
  1245. if (venum_event || krait_event) {
  1246. /* Ignore invalid events */
  1247. if (group > 3 || region > 2)
  1248. return -EINVAL;
  1249. if (venum_event && (code & 0xe0))
  1250. return -EINVAL;
  1251. bit = krait_event_to_bit(event, region, group);
  1252. if (test_and_set_bit(bit, cpuc->used_mask))
  1253. return -EAGAIN;
  1254. }
  1255. idx = armv7pmu_get_event_idx(cpuc, event);
  1256. if (idx < 0 && bit >= 0)
  1257. clear_bit(bit, cpuc->used_mask);
  1258. return idx;
  1259. }
  1260. static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
  1261. struct perf_event *event)
  1262. {
  1263. int bit;
  1264. struct hw_perf_event *hwc = &event->hw;
  1265. unsigned int region = EVENT_REGION(hwc->config_base);
  1266. unsigned int group = EVENT_GROUP(hwc->config_base);
  1267. bool venum_event = EVENT_VENUM(hwc->config_base);
  1268. bool krait_event = EVENT_CPU(hwc->config_base);
  1269. if (venum_event || krait_event) {
  1270. bit = krait_event_to_bit(event, region, group);
  1271. clear_bit(bit, cpuc->used_mask);
  1272. }
  1273. }
  1274. static int krait_pmu_init(struct arm_pmu *cpu_pmu)
  1275. {
  1276. armv7pmu_init(cpu_pmu);
  1277. cpu_pmu->name = "armv7_krait";
  1278. /* Some early versions of Krait don't support PC write events */
  1279. if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
  1280. "qcom,no-pc-write"))
  1281. cpu_pmu->map_event = krait_map_event_no_branch;
  1282. else
  1283. cpu_pmu->map_event = krait_map_event;
  1284. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  1285. cpu_pmu->reset = krait_pmu_reset;
  1286. cpu_pmu->enable = krait_pmu_enable_event;
  1287. cpu_pmu->disable = krait_pmu_disable_event;
  1288. cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
  1289. cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
  1290. return armv7_probe_num_events(cpu_pmu);
  1291. }
  1292. /*
  1293. * Scorpion Local Performance Monitor Register (LPMn)
  1294. *
  1295. * 31 30 24 16 8 0
  1296. * +--------------------------------+
  1297. * LPM0 | EN | CC | CC | CC | CC | N = 1, R = 0
  1298. * +--------------------------------+
  1299. * LPM1 | EN | CC | CC | CC | CC | N = 1, R = 1
  1300. * +--------------------------------+
  1301. * LPM2 | EN | CC | CC | CC | CC | N = 1, R = 2
  1302. * +--------------------------------+
  1303. * L2LPM | EN | CC | CC | CC | CC | N = 1, R = 3
  1304. * +--------------------------------+
  1305. * VLPM | EN | CC | CC | CC | CC | N = 2, R = ?
  1306. * +--------------------------------+
  1307. * EN | G=3 | G=2 | G=1 | G=0
  1308. *
  1309. *
  1310. * Event Encoding:
  1311. *
  1312. * hwc->config_base = 0xNRCCG
  1313. *
  1314. * N = prefix, 1 for Scorpion CPU (LPMn/L2LPM), 2 for Venum VFP (VLPM)
  1315. * R = region register
  1316. * CC = class of events the group G is choosing from
  1317. * G = group or particular event
  1318. *
  1319. * Example: 0x12021 is a Scorpion CPU event in LPM2's group 1 with code 2
  1320. *
  1321. * A region (R) corresponds to a piece of the CPU (execution unit, instruction
  1322. * unit, etc.) while the event code (CC) corresponds to a particular class of
  1323. * events (interrupts for example). An event code is broken down into
  1324. * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
  1325. * example).
  1326. */
  1327. static u32 scorpion_read_pmresrn(int n)
  1328. {
  1329. u32 val;
  1330. switch (n) {
  1331. case 0:
  1332. asm volatile("mrc p15, 0, %0, c15, c0, 0" : "=r" (val));
  1333. break;
  1334. case 1:
  1335. asm volatile("mrc p15, 1, %0, c15, c0, 0" : "=r" (val));
  1336. break;
  1337. case 2:
  1338. asm volatile("mrc p15, 2, %0, c15, c0, 0" : "=r" (val));
  1339. break;
  1340. case 3:
  1341. asm volatile("mrc p15, 3, %0, c15, c2, 0" : "=r" (val));
  1342. break;
  1343. default:
  1344. BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
  1345. }
  1346. return val;
  1347. }
  1348. static void scorpion_write_pmresrn(int n, u32 val)
  1349. {
  1350. switch (n) {
  1351. case 0:
  1352. asm volatile("mcr p15, 0, %0, c15, c0, 0" : : "r" (val));
  1353. break;
  1354. case 1:
  1355. asm volatile("mcr p15, 1, %0, c15, c0, 0" : : "r" (val));
  1356. break;
  1357. case 2:
  1358. asm volatile("mcr p15, 2, %0, c15, c0, 0" : : "r" (val));
  1359. break;
  1360. case 3:
  1361. asm volatile("mcr p15, 3, %0, c15, c2, 0" : : "r" (val));
  1362. break;
  1363. default:
  1364. BUG(); /* Should be validated in scorpion_pmu_get_event_idx() */
  1365. }
  1366. }
  1367. static u32 scorpion_get_pmresrn_event(unsigned int region)
  1368. {
  1369. static const u32 pmresrn_table[] = { SCORPION_LPM0_GROUP0,
  1370. SCORPION_LPM1_GROUP0,
  1371. SCORPION_LPM2_GROUP0,
  1372. SCORPION_L2LPM_GROUP0 };
  1373. return pmresrn_table[region];
  1374. }
  1375. static void scorpion_evt_setup(int idx, u32 config_base)
  1376. {
  1377. u32 val;
  1378. u32 mask;
  1379. u32 vval, fval;
  1380. unsigned int region = EVENT_REGION(config_base);
  1381. unsigned int group = EVENT_GROUP(config_base);
  1382. unsigned int code = EVENT_CODE(config_base);
  1383. unsigned int group_shift;
  1384. bool venum_event = EVENT_VENUM(config_base);
  1385. group_shift = group * 8;
  1386. mask = 0xff << group_shift;
  1387. /* Configure evtsel for the region and group */
  1388. if (venum_event)
  1389. val = SCORPION_VLPM_GROUP0;
  1390. else
  1391. val = scorpion_get_pmresrn_event(region);
  1392. val += group;
  1393. /* Mix in mode-exclusion bits */
  1394. val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
  1395. armv7_pmnc_write_evtsel(idx, val);
  1396. asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
  1397. if (venum_event) {
  1398. venum_pre_pmresr(&vval, &fval);
  1399. val = venum_read_pmresr();
  1400. val &= ~mask;
  1401. val |= code << group_shift;
  1402. val |= PMRESRn_EN;
  1403. venum_write_pmresr(val);
  1404. venum_post_pmresr(vval, fval);
  1405. } else {
  1406. val = scorpion_read_pmresrn(region);
  1407. val &= ~mask;
  1408. val |= code << group_shift;
  1409. val |= PMRESRn_EN;
  1410. scorpion_write_pmresrn(region, val);
  1411. }
  1412. }
  1413. static void scorpion_clearpmu(u32 config_base)
  1414. {
  1415. u32 val;
  1416. u32 vval, fval;
  1417. unsigned int region = EVENT_REGION(config_base);
  1418. unsigned int group = EVENT_GROUP(config_base);
  1419. bool venum_event = EVENT_VENUM(config_base);
  1420. if (venum_event) {
  1421. venum_pre_pmresr(&vval, &fval);
  1422. val = venum_read_pmresr();
  1423. val = clear_pmresrn_group(val, group);
  1424. venum_write_pmresr(val);
  1425. venum_post_pmresr(vval, fval);
  1426. } else {
  1427. val = scorpion_read_pmresrn(region);
  1428. val = clear_pmresrn_group(val, group);
  1429. scorpion_write_pmresrn(region, val);
  1430. }
  1431. }
  1432. static void scorpion_pmu_disable_event(struct perf_event *event)
  1433. {
  1434. unsigned long flags;
  1435. struct hw_perf_event *hwc = &event->hw;
  1436. int idx = hwc->idx;
  1437. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1438. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  1439. /* Disable counter and interrupt */
  1440. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1441. /* Disable counter */
  1442. armv7_pmnc_disable_counter(idx);
  1443. /*
  1444. * Clear pmresr code (if destined for PMNx counters)
  1445. */
  1446. if (hwc->config_base & KRAIT_EVENT_MASK)
  1447. scorpion_clearpmu(hwc->config_base);
  1448. /* Disable interrupt for this counter */
  1449. armv7_pmnc_disable_intens(idx);
  1450. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1451. }
  1452. static void scorpion_pmu_enable_event(struct perf_event *event)
  1453. {
  1454. unsigned long flags;
  1455. struct hw_perf_event *hwc = &event->hw;
  1456. int idx = hwc->idx;
  1457. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1458. struct pmu_hw_events *events = this_cpu_ptr(cpu_pmu->hw_events);
  1459. /*
  1460. * Enable counter and interrupt, and set the counter to count
  1461. * the event that we're interested in.
  1462. */
  1463. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1464. /* Disable counter */
  1465. armv7_pmnc_disable_counter(idx);
  1466. /*
  1467. * Set event (if destined for PMNx counters)
  1468. * We don't set the event for the cycle counter because we
  1469. * don't have the ability to perform event filtering.
  1470. */
  1471. if (hwc->config_base & KRAIT_EVENT_MASK)
  1472. scorpion_evt_setup(idx, hwc->config_base);
  1473. else if (idx != ARMV7_IDX_CYCLE_COUNTER)
  1474. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  1475. /* Enable interrupt for this counter */
  1476. armv7_pmnc_enable_intens(idx);
  1477. /* Enable counter */
  1478. armv7_pmnc_enable_counter(idx);
  1479. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1480. }
  1481. static void scorpion_pmu_reset(void *info)
  1482. {
  1483. u32 vval, fval;
  1484. struct arm_pmu *cpu_pmu = info;
  1485. u32 idx, nb_cnt = cpu_pmu->num_events;
  1486. armv7pmu_reset(info);
  1487. /* Clear all pmresrs */
  1488. scorpion_write_pmresrn(0, 0);
  1489. scorpion_write_pmresrn(1, 0);
  1490. scorpion_write_pmresrn(2, 0);
  1491. scorpion_write_pmresrn(3, 0);
  1492. venum_pre_pmresr(&vval, &fval);
  1493. venum_write_pmresr(0);
  1494. venum_post_pmresr(vval, fval);
  1495. /* Reset PMxEVNCTCR to sane default */
  1496. for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
  1497. armv7_pmnc_select_counter(idx);
  1498. asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
  1499. }
  1500. }
  1501. static int scorpion_event_to_bit(struct perf_event *event, unsigned int region,
  1502. unsigned int group)
  1503. {
  1504. int bit;
  1505. struct hw_perf_event *hwc = &event->hw;
  1506. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1507. if (hwc->config_base & VENUM_EVENT)
  1508. bit = SCORPION_VLPM_GROUP0;
  1509. else
  1510. bit = scorpion_get_pmresrn_event(region);
  1511. bit -= scorpion_get_pmresrn_event(0);
  1512. bit += group;
  1513. /*
  1514. * Lower bits are reserved for use by the counters (see
  1515. * armv7pmu_get_event_idx() for more info)
  1516. */
  1517. bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
  1518. return bit;
  1519. }
  1520. /*
  1521. * We check for column exclusion constraints here.
  1522. * Two events cant use the same group within a pmresr register.
  1523. */
  1524. static int scorpion_pmu_get_event_idx(struct pmu_hw_events *cpuc,
  1525. struct perf_event *event)
  1526. {
  1527. int idx;
  1528. int bit = -1;
  1529. struct hw_perf_event *hwc = &event->hw;
  1530. unsigned int region = EVENT_REGION(hwc->config_base);
  1531. unsigned int group = EVENT_GROUP(hwc->config_base);
  1532. bool venum_event = EVENT_VENUM(hwc->config_base);
  1533. bool scorpion_event = EVENT_CPU(hwc->config_base);
  1534. if (venum_event || scorpion_event) {
  1535. /* Ignore invalid events */
  1536. if (group > 3 || region > 3)
  1537. return -EINVAL;
  1538. bit = scorpion_event_to_bit(event, region, group);
  1539. if (test_and_set_bit(bit, cpuc->used_mask))
  1540. return -EAGAIN;
  1541. }
  1542. idx = armv7pmu_get_event_idx(cpuc, event);
  1543. if (idx < 0 && bit >= 0)
  1544. clear_bit(bit, cpuc->used_mask);
  1545. return idx;
  1546. }
  1547. static void scorpion_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
  1548. struct perf_event *event)
  1549. {
  1550. int bit;
  1551. struct hw_perf_event *hwc = &event->hw;
  1552. unsigned int region = EVENT_REGION(hwc->config_base);
  1553. unsigned int group = EVENT_GROUP(hwc->config_base);
  1554. bool venum_event = EVENT_VENUM(hwc->config_base);
  1555. bool scorpion_event = EVENT_CPU(hwc->config_base);
  1556. if (venum_event || scorpion_event) {
  1557. bit = scorpion_event_to_bit(event, region, group);
  1558. clear_bit(bit, cpuc->used_mask);
  1559. }
  1560. }
  1561. static int scorpion_pmu_init(struct arm_pmu *cpu_pmu)
  1562. {
  1563. armv7pmu_init(cpu_pmu);
  1564. cpu_pmu->name = "armv7_scorpion";
  1565. cpu_pmu->map_event = scorpion_map_event;
  1566. cpu_pmu->reset = scorpion_pmu_reset;
  1567. cpu_pmu->enable = scorpion_pmu_enable_event;
  1568. cpu_pmu->disable = scorpion_pmu_disable_event;
  1569. cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
  1570. cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
  1571. return armv7_probe_num_events(cpu_pmu);
  1572. }
  1573. static int scorpion_mp_pmu_init(struct arm_pmu *cpu_pmu)
  1574. {
  1575. armv7pmu_init(cpu_pmu);
  1576. cpu_pmu->name = "armv7_scorpion_mp";
  1577. cpu_pmu->map_event = scorpion_map_event;
  1578. cpu_pmu->reset = scorpion_pmu_reset;
  1579. cpu_pmu->enable = scorpion_pmu_enable_event;
  1580. cpu_pmu->disable = scorpion_pmu_disable_event;
  1581. cpu_pmu->get_event_idx = scorpion_pmu_get_event_idx;
  1582. cpu_pmu->clear_event_idx = scorpion_pmu_clear_event_idx;
  1583. return armv7_probe_num_events(cpu_pmu);
  1584. }
  1585. static const struct of_device_id armv7_pmu_of_device_ids[] = {
  1586. {.compatible = "arm,cortex-a17-pmu", .data = armv7_a17_pmu_init},
  1587. {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
  1588. {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
  1589. {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
  1590. {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
  1591. {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
  1592. {.compatible = "arm,cortex-a5-pmu", .data = armv7_a5_pmu_init},
  1593. {.compatible = "qcom,krait-pmu", .data = krait_pmu_init},
  1594. {.compatible = "qcom,scorpion-pmu", .data = scorpion_pmu_init},
  1595. {.compatible = "qcom,scorpion-mp-pmu", .data = scorpion_mp_pmu_init},
  1596. {},
  1597. };
  1598. static const struct pmu_probe_info armv7_pmu_probe_table[] = {
  1599. ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A8, armv7_a8_pmu_init),
  1600. ARM_PMU_PROBE(ARM_CPU_PART_CORTEX_A9, armv7_a9_pmu_init),
  1601. { /* sentinel value */ }
  1602. };
  1603. static int armv7_pmu_device_probe(struct platform_device *pdev)
  1604. {
  1605. return arm_pmu_device_probe(pdev, armv7_pmu_of_device_ids,
  1606. armv7_pmu_probe_table);
  1607. }
  1608. static struct platform_driver armv7_pmu_driver = {
  1609. .driver = {
  1610. .name = "armv7-pmu",
  1611. .of_match_table = armv7_pmu_of_device_ids,
  1612. },
  1613. .probe = armv7_pmu_device_probe,
  1614. };
  1615. static int __init register_armv7_pmu_driver(void)
  1616. {
  1617. return platform_driver_register(&armv7_pmu_driver);
  1618. }
  1619. device_initcall(register_armv7_pmu_driver);
  1620. #endif /* CONFIG_CPU_V7 */