perf_event_v7.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505
  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/vfp.h>
  21. #include "../vfp/vfpinstr.h"
  22. /*
  23. * Common ARMv7 event types
  24. *
  25. * Note: An implementation may not be able to count all of these events
  26. * but the encodings are considered to be `reserved' in the case that
  27. * they are not available.
  28. */
  29. enum armv7_perf_types {
  30. ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
  31. ARMV7_PERFCTR_L1_ICACHE_REFILL = 0x01,
  32. ARMV7_PERFCTR_ITLB_REFILL = 0x02,
  33. ARMV7_PERFCTR_L1_DCACHE_REFILL = 0x03,
  34. ARMV7_PERFCTR_L1_DCACHE_ACCESS = 0x04,
  35. ARMV7_PERFCTR_DTLB_REFILL = 0x05,
  36. ARMV7_PERFCTR_MEM_READ = 0x06,
  37. ARMV7_PERFCTR_MEM_WRITE = 0x07,
  38. ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
  39. ARMV7_PERFCTR_EXC_TAKEN = 0x09,
  40. ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
  41. ARMV7_PERFCTR_CID_WRITE = 0x0B,
  42. /*
  43. * ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
  44. * It counts:
  45. * - all (taken) branch instructions,
  46. * - instructions that explicitly write the PC,
  47. * - exception generating instructions.
  48. */
  49. ARMV7_PERFCTR_PC_WRITE = 0x0C,
  50. ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
  51. ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
  52. ARMV7_PERFCTR_MEM_UNALIGNED_ACCESS = 0x0F,
  53. ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
  54. ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
  55. ARMV7_PERFCTR_PC_BRANCH_PRED = 0x12,
  56. /* These events are defined by the PMUv2 supplement (ARM DDI 0457A). */
  57. ARMV7_PERFCTR_MEM_ACCESS = 0x13,
  58. ARMV7_PERFCTR_L1_ICACHE_ACCESS = 0x14,
  59. ARMV7_PERFCTR_L1_DCACHE_WB = 0x15,
  60. ARMV7_PERFCTR_L2_CACHE_ACCESS = 0x16,
  61. ARMV7_PERFCTR_L2_CACHE_REFILL = 0x17,
  62. ARMV7_PERFCTR_L2_CACHE_WB = 0x18,
  63. ARMV7_PERFCTR_BUS_ACCESS = 0x19,
  64. ARMV7_PERFCTR_MEM_ERROR = 0x1A,
  65. ARMV7_PERFCTR_INSTR_SPEC = 0x1B,
  66. ARMV7_PERFCTR_TTBR_WRITE = 0x1C,
  67. ARMV7_PERFCTR_BUS_CYCLES = 0x1D,
  68. ARMV7_PERFCTR_CPU_CYCLES = 0xFF
  69. };
  70. /* ARMv7 Cortex-A8 specific event types */
  71. enum armv7_a8_perf_types {
  72. ARMV7_A8_PERFCTR_L2_CACHE_ACCESS = 0x43,
  73. ARMV7_A8_PERFCTR_L2_CACHE_REFILL = 0x44,
  74. ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS = 0x50,
  75. ARMV7_A8_PERFCTR_STALL_ISIDE = 0x56,
  76. };
  77. /* ARMv7 Cortex-A9 specific event types */
  78. enum armv7_a9_perf_types {
  79. ARMV7_A9_PERFCTR_INSTR_CORE_RENAME = 0x68,
  80. ARMV7_A9_PERFCTR_STALL_ICACHE = 0x60,
  81. ARMV7_A9_PERFCTR_STALL_DISPATCH = 0x66,
  82. };
  83. /* ARMv7 Cortex-A5 specific event types */
  84. enum armv7_a5_perf_types {
  85. ARMV7_A5_PERFCTR_PREFETCH_LINEFILL = 0xc2,
  86. ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP = 0xc3,
  87. };
  88. /* ARMv7 Cortex-A15 specific event types */
  89. enum armv7_a15_perf_types {
  90. ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
  91. ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
  92. ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ = 0x42,
  93. ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE = 0x43,
  94. ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ = 0x4C,
  95. ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE = 0x4D,
  96. ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
  97. ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
  98. ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ = 0x52,
  99. ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE = 0x53,
  100. ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
  101. };
  102. /* ARMv7 Cortex-A12 specific event types */
  103. enum armv7_a12_perf_types {
  104. ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
  105. ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
  106. ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
  107. ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
  108. ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
  109. ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
  110. };
  111. /* ARMv7 Krait specific event types */
  112. enum krait_perf_types {
  113. KRAIT_PMRESR0_GROUP0 = 0xcc,
  114. KRAIT_PMRESR1_GROUP0 = 0xd0,
  115. KRAIT_PMRESR2_GROUP0 = 0xd4,
  116. KRAIT_VPMRESR0_GROUP0 = 0xd8,
  117. KRAIT_PERFCTR_L1_ICACHE_ACCESS = 0x10011,
  118. KRAIT_PERFCTR_L1_ICACHE_MISS = 0x10010,
  119. KRAIT_PERFCTR_L1_ITLB_ACCESS = 0x12222,
  120. KRAIT_PERFCTR_L1_DTLB_ACCESS = 0x12210,
  121. };
  122. /*
  123. * Cortex-A8 HW events mapping
  124. *
  125. * The hardware events that we support. We do support cache operations but
  126. * we have harvard caches and no way to combine instruction and data
  127. * accesses/misses in hardware.
  128. */
  129. static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
  130. PERF_MAP_ALL_UNSUPPORTED,
  131. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  132. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  133. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  134. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  135. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  136. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  137. [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A8_PERFCTR_STALL_ISIDE,
  138. };
  139. static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  140. [PERF_COUNT_HW_CACHE_OP_MAX]
  141. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  142. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  143. /*
  144. * The performance counters don't differentiate between read and write
  145. * accesses/misses so this isn't strictly correct, but it's the best we
  146. * can do. Writes and reads get combined.
  147. */
  148. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  149. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  150. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  151. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  152. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L1_ICACHE_ACCESS,
  153. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  154. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
  155. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
  156. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A8_PERFCTR_L2_CACHE_ACCESS,
  157. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A8_PERFCTR_L2_CACHE_REFILL,
  158. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  159. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  160. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  161. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  162. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  163. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  164. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  165. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  166. };
  167. /*
  168. * Cortex-A9 HW events mapping
  169. */
  170. static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
  171. PERF_MAP_ALL_UNSUPPORTED,
  172. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  173. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_A9_PERFCTR_INSTR_CORE_RENAME,
  174. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  175. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  176. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  177. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  178. [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV7_A9_PERFCTR_STALL_ICACHE,
  179. [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV7_A9_PERFCTR_STALL_DISPATCH,
  180. };
  181. static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  182. [PERF_COUNT_HW_CACHE_OP_MAX]
  183. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  184. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  185. /*
  186. * The performance counters don't differentiate between read and write
  187. * accesses/misses so this isn't strictly correct, but it's the best we
  188. * can do. Writes and reads get combined.
  189. */
  190. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  191. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  192. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  193. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  194. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  195. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  196. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  197. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  198. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  199. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  200. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  201. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  202. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  203. };
  204. /*
  205. * Cortex-A5 HW events mapping
  206. */
  207. static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
  208. PERF_MAP_ALL_UNSUPPORTED,
  209. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  210. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  211. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  212. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  213. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  214. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  215. };
  216. static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  217. [PERF_COUNT_HW_CACHE_OP_MAX]
  218. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  219. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  220. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  221. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  222. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  223. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  224. [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
  225. [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
  226. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  227. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  228. /*
  229. * The prefetch counters don't differentiate between the I side and the
  230. * D side.
  231. */
  232. [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL,
  233. [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A5_PERFCTR_PREFETCH_LINEFILL_DROP,
  234. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  235. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  236. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  237. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  238. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  239. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  240. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  241. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  242. };
  243. /*
  244. * Cortex-A15 HW events mapping
  245. */
  246. static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
  247. PERF_MAP_ALL_UNSUPPORTED,
  248. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  249. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  250. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  251. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  252. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A15_PERFCTR_PC_WRITE_SPEC,
  253. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  254. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  255. };
  256. static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  257. [PERF_COUNT_HW_CACHE_OP_MAX]
  258. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  259. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  260. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_READ,
  261. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_READ,
  262. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L1_DCACHE_ACCESS_WRITE,
  263. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L1_DCACHE_REFILL_WRITE,
  264. /*
  265. * Not all performance counters differentiate between read and write
  266. * accesses/misses so we're not always strictly correct, but it's the
  267. * best we can do. Writes and reads get combined in these cases.
  268. */
  269. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  270. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  271. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_READ,
  272. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_READ,
  273. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A15_PERFCTR_L2_CACHE_ACCESS_WRITE,
  274. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_L2_CACHE_REFILL_WRITE,
  275. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_READ,
  276. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_A15_PERFCTR_DTLB_REFILL_L1_WRITE,
  277. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  278. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  279. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  280. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  281. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  282. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  283. };
  284. /*
  285. * Cortex-A7 HW events mapping
  286. */
  287. static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = {
  288. PERF_MAP_ALL_UNSUPPORTED,
  289. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  290. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  291. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  292. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  293. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  294. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  295. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  296. };
  297. static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  298. [PERF_COUNT_HW_CACHE_OP_MAX]
  299. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  300. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  301. /*
  302. * The performance counters don't differentiate between read and write
  303. * accesses/misses so this isn't strictly correct, but it's the best we
  304. * can do. Writes and reads get combined.
  305. */
  306. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  307. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  308. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  309. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  310. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  311. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  312. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
  313. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  314. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS,
  315. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  316. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  317. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  318. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  319. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  320. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  321. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  322. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  323. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  324. };
  325. /*
  326. * Cortex-A12 HW events mapping
  327. */
  328. static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
  329. PERF_MAP_ALL_UNSUPPORTED,
  330. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  331. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  332. [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  333. [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  334. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
  335. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  336. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
  337. };
  338. static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  339. [PERF_COUNT_HW_CACHE_OP_MAX]
  340. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  341. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  342. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
  343. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  344. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
  345. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  346. /*
  347. * Not all performance counters differentiate between read and write
  348. * accesses/misses so we're not always strictly correct, but it's the
  349. * best we can do. Writes and reads get combined in these cases.
  350. */
  351. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
  352. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
  353. [C(LL)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
  354. [C(LL)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  355. [C(LL)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
  356. [C(LL)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
  357. [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  358. [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
  359. [C(DTLB)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
  360. [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  361. [C(ITLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
  362. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  363. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  364. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  365. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  366. };
  367. /*
  368. * Krait HW events mapping
  369. */
  370. static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
  371. PERF_MAP_ALL_UNSUPPORTED,
  372. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  373. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  374. [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
  375. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  376. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  377. };
  378. static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
  379. PERF_MAP_ALL_UNSUPPORTED,
  380. [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
  381. [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
  382. [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  383. [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
  384. };
  385. static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
  386. [PERF_COUNT_HW_CACHE_OP_MAX]
  387. [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
  388. PERF_CACHE_MAP_ALL_UNSUPPORTED,
  389. /*
  390. * The performance counters don't differentiate between read and write
  391. * accesses/misses so this isn't strictly correct, but it's the best we
  392. * can do. Writes and reads get combined.
  393. */
  394. [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  395. [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  396. [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
  397. [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
  398. [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ICACHE_ACCESS,
  399. [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = KRAIT_PERFCTR_L1_ICACHE_MISS,
  400. [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
  401. [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_DTLB_ACCESS,
  402. [C(ITLB)][C(OP_READ)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
  403. [C(ITLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = KRAIT_PERFCTR_L1_ITLB_ACCESS,
  404. [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  405. [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  406. [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
  407. [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
  408. };
  409. /*
  410. * Perf Events' indices
  411. */
  412. #define ARMV7_IDX_CYCLE_COUNTER 0
  413. #define ARMV7_IDX_COUNTER0 1
  414. #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \
  415. (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1)
  416. #define ARMV7_MAX_COUNTERS 32
  417. #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1)
  418. /*
  419. * ARMv7 low level PMNC access
  420. */
  421. /*
  422. * Perf Event to low level counters mapping
  423. */
  424. #define ARMV7_IDX_TO_COUNTER(x) \
  425. (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK)
  426. /*
  427. * Per-CPU PMNC: config reg
  428. */
  429. #define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
  430. #define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
  431. #define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
  432. #define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
  433. #define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
  434. #define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
  435. #define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
  436. #define ARMV7_PMNC_N_MASK 0x1f
  437. #define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
  438. /*
  439. * FLAG: counters overflow flag status reg
  440. */
  441. #define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
  442. #define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
  443. /*
  444. * PMXEVTYPER: Event selection reg
  445. */
  446. #define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
  447. #define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
  448. /*
  449. * Event filters for PMUv2
  450. */
  451. #define ARMV7_EXCLUDE_PL1 (1 << 31)
  452. #define ARMV7_EXCLUDE_USER (1 << 30)
  453. #define ARMV7_INCLUDE_HYP (1 << 27)
  454. static inline u32 armv7_pmnc_read(void)
  455. {
  456. u32 val;
  457. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
  458. return val;
  459. }
  460. static inline void armv7_pmnc_write(u32 val)
  461. {
  462. val &= ARMV7_PMNC_MASK;
  463. isb();
  464. asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
  465. }
  466. static inline int armv7_pmnc_has_overflowed(u32 pmnc)
  467. {
  468. return pmnc & ARMV7_OVERFLOWED_MASK;
  469. }
  470. static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx)
  471. {
  472. return idx >= ARMV7_IDX_CYCLE_COUNTER &&
  473. idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu);
  474. }
  475. static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx)
  476. {
  477. return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx));
  478. }
  479. static inline int armv7_pmnc_select_counter(int idx)
  480. {
  481. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  482. asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
  483. isb();
  484. return idx;
  485. }
  486. static inline u32 armv7pmu_read_counter(struct perf_event *event)
  487. {
  488. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  489. struct hw_perf_event *hwc = &event->hw;
  490. int idx = hwc->idx;
  491. u32 value = 0;
  492. if (!armv7_pmnc_counter_valid(cpu_pmu, idx))
  493. pr_err("CPU%u reading wrong counter %d\n",
  494. smp_processor_id(), idx);
  495. else if (idx == ARMV7_IDX_CYCLE_COUNTER)
  496. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
  497. else if (armv7_pmnc_select_counter(idx) == idx)
  498. asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (value));
  499. return value;
  500. }
  501. static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
  502. {
  503. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  504. struct hw_perf_event *hwc = &event->hw;
  505. int idx = hwc->idx;
  506. if (!armv7_pmnc_counter_valid(cpu_pmu, idx))
  507. pr_err("CPU%u writing wrong counter %d\n",
  508. smp_processor_id(), idx);
  509. else if (idx == ARMV7_IDX_CYCLE_COUNTER)
  510. asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
  511. else if (armv7_pmnc_select_counter(idx) == idx)
  512. asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
  513. }
  514. static inline void armv7_pmnc_write_evtsel(int idx, u32 val)
  515. {
  516. if (armv7_pmnc_select_counter(idx) == idx) {
  517. val &= ARMV7_EVTYPE_MASK;
  518. asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
  519. }
  520. }
  521. static inline int armv7_pmnc_enable_counter(int idx)
  522. {
  523. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  524. asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter)));
  525. return idx;
  526. }
  527. static inline int armv7_pmnc_disable_counter(int idx)
  528. {
  529. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  530. asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter)));
  531. return idx;
  532. }
  533. static inline int armv7_pmnc_enable_intens(int idx)
  534. {
  535. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  536. asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter)));
  537. return idx;
  538. }
  539. static inline int armv7_pmnc_disable_intens(int idx)
  540. {
  541. u32 counter = ARMV7_IDX_TO_COUNTER(idx);
  542. asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter)));
  543. isb();
  544. /* Clear the overflow flag in case an interrupt is pending. */
  545. asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter)));
  546. isb();
  547. return idx;
  548. }
  549. static inline u32 armv7_pmnc_getreset_flags(void)
  550. {
  551. u32 val;
  552. /* Read */
  553. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  554. /* Write to clear flags */
  555. val &= ARMV7_FLAG_MASK;
  556. asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
  557. return val;
  558. }
  559. #ifdef DEBUG
  560. static void armv7_pmnc_dump_regs(struct arm_pmu *cpu_pmu)
  561. {
  562. u32 val;
  563. unsigned int cnt;
  564. printk(KERN_INFO "PMNC registers dump:\n");
  565. asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
  566. printk(KERN_INFO "PMNC =0x%08x\n", val);
  567. asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
  568. printk(KERN_INFO "CNTENS=0x%08x\n", val);
  569. asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
  570. printk(KERN_INFO "INTENS=0x%08x\n", val);
  571. asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
  572. printk(KERN_INFO "FLAGS =0x%08x\n", val);
  573. asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
  574. printk(KERN_INFO "SELECT=0x%08x\n", val);
  575. asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
  576. printk(KERN_INFO "CCNT =0x%08x\n", val);
  577. for (cnt = ARMV7_IDX_COUNTER0;
  578. cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) {
  579. armv7_pmnc_select_counter(cnt);
  580. asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
  581. printk(KERN_INFO "CNT[%d] count =0x%08x\n",
  582. ARMV7_IDX_TO_COUNTER(cnt), val);
  583. asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
  584. printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
  585. ARMV7_IDX_TO_COUNTER(cnt), val);
  586. }
  587. }
  588. #endif
  589. static void armv7pmu_enable_event(struct perf_event *event)
  590. {
  591. unsigned long flags;
  592. struct hw_perf_event *hwc = &event->hw;
  593. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  594. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  595. int idx = hwc->idx;
  596. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  597. pr_err("CPU%u enabling wrong PMNC counter IRQ enable %d\n",
  598. smp_processor_id(), idx);
  599. return;
  600. }
  601. /*
  602. * Enable counter and interrupt, and set the counter to count
  603. * the event that we're interested in.
  604. */
  605. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  606. /*
  607. * Disable counter
  608. */
  609. armv7_pmnc_disable_counter(idx);
  610. /*
  611. * Set event (if destined for PMNx counters)
  612. * We only need to set the event for the cycle counter if we
  613. * have the ability to perform event filtering.
  614. */
  615. if (cpu_pmu->set_event_filter || idx != ARMV7_IDX_CYCLE_COUNTER)
  616. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  617. /*
  618. * Enable interrupt for this counter
  619. */
  620. armv7_pmnc_enable_intens(idx);
  621. /*
  622. * Enable counter
  623. */
  624. armv7_pmnc_enable_counter(idx);
  625. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  626. }
  627. static void armv7pmu_disable_event(struct perf_event *event)
  628. {
  629. unsigned long flags;
  630. struct hw_perf_event *hwc = &event->hw;
  631. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  632. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  633. int idx = hwc->idx;
  634. if (!armv7_pmnc_counter_valid(cpu_pmu, idx)) {
  635. pr_err("CPU%u disabling wrong PMNC counter IRQ enable %d\n",
  636. smp_processor_id(), idx);
  637. return;
  638. }
  639. /*
  640. * Disable counter and interrupt
  641. */
  642. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  643. /*
  644. * Disable counter
  645. */
  646. armv7_pmnc_disable_counter(idx);
  647. /*
  648. * Disable interrupt for this counter
  649. */
  650. armv7_pmnc_disable_intens(idx);
  651. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  652. }
  653. static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
  654. {
  655. u32 pmnc;
  656. struct perf_sample_data data;
  657. struct arm_pmu *cpu_pmu = (struct arm_pmu *)dev;
  658. struct pmu_hw_events *cpuc = cpu_pmu->get_hw_events();
  659. struct pt_regs *regs;
  660. int idx;
  661. /*
  662. * Get and reset the IRQ flags
  663. */
  664. pmnc = armv7_pmnc_getreset_flags();
  665. /*
  666. * Did an overflow occur?
  667. */
  668. if (!armv7_pmnc_has_overflowed(pmnc))
  669. return IRQ_NONE;
  670. /*
  671. * Handle the counter(s) overflow(s)
  672. */
  673. regs = get_irq_regs();
  674. for (idx = 0; idx < cpu_pmu->num_events; ++idx) {
  675. struct perf_event *event = cpuc->events[idx];
  676. struct hw_perf_event *hwc;
  677. /* Ignore if we don't have an event. */
  678. if (!event)
  679. continue;
  680. /*
  681. * We have a single interrupt for all counters. Check that
  682. * each counter has overflowed before we process it.
  683. */
  684. if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
  685. continue;
  686. hwc = &event->hw;
  687. armpmu_event_update(event);
  688. perf_sample_data_init(&data, 0, hwc->last_period);
  689. if (!armpmu_event_set_period(event))
  690. continue;
  691. if (perf_event_overflow(event, &data, regs))
  692. cpu_pmu->disable(event);
  693. }
  694. /*
  695. * Handle the pending perf events.
  696. *
  697. * Note: this call *must* be run with interrupts disabled. For
  698. * platforms that can have the PMU interrupts raised as an NMI, this
  699. * will not work.
  700. */
  701. irq_work_run();
  702. return IRQ_HANDLED;
  703. }
  704. static void armv7pmu_start(struct arm_pmu *cpu_pmu)
  705. {
  706. unsigned long flags;
  707. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  708. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  709. /* Enable all counters */
  710. armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
  711. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  712. }
  713. static void armv7pmu_stop(struct arm_pmu *cpu_pmu)
  714. {
  715. unsigned long flags;
  716. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  717. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  718. /* Disable all counters */
  719. armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
  720. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  721. }
  722. static int armv7pmu_get_event_idx(struct pmu_hw_events *cpuc,
  723. struct perf_event *event)
  724. {
  725. int idx;
  726. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  727. struct hw_perf_event *hwc = &event->hw;
  728. unsigned long evtype = hwc->config_base & ARMV7_EVTYPE_EVENT;
  729. /* Always place a cycle counter into the cycle counter. */
  730. if (evtype == ARMV7_PERFCTR_CPU_CYCLES) {
  731. if (test_and_set_bit(ARMV7_IDX_CYCLE_COUNTER, cpuc->used_mask))
  732. return -EAGAIN;
  733. return ARMV7_IDX_CYCLE_COUNTER;
  734. }
  735. /*
  736. * For anything other than a cycle counter, try and use
  737. * the events counters
  738. */
  739. for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) {
  740. if (!test_and_set_bit(idx, cpuc->used_mask))
  741. return idx;
  742. }
  743. /* The counters are all in use. */
  744. return -EAGAIN;
  745. }
  746. /*
  747. * Add an event filter to a given event. This will only work for PMUv2 PMUs.
  748. */
  749. static int armv7pmu_set_event_filter(struct hw_perf_event *event,
  750. struct perf_event_attr *attr)
  751. {
  752. unsigned long config_base = 0;
  753. if (attr->exclude_idle)
  754. return -EPERM;
  755. if (attr->exclude_user)
  756. config_base |= ARMV7_EXCLUDE_USER;
  757. if (attr->exclude_kernel)
  758. config_base |= ARMV7_EXCLUDE_PL1;
  759. if (!attr->exclude_hv)
  760. config_base |= ARMV7_INCLUDE_HYP;
  761. /*
  762. * Install the filter into config_base as this is used to
  763. * construct the event type.
  764. */
  765. event->config_base = config_base;
  766. return 0;
  767. }
  768. static void armv7pmu_reset(void *info)
  769. {
  770. struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
  771. u32 idx, nb_cnt = cpu_pmu->num_events;
  772. /* The counter and interrupt enable registers are unknown at reset. */
  773. for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) {
  774. armv7_pmnc_disable_counter(idx);
  775. armv7_pmnc_disable_intens(idx);
  776. }
  777. /* Initialize & Reset PMNC: C and P bits */
  778. armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
  779. }
  780. static int armv7_a8_map_event(struct perf_event *event)
  781. {
  782. return armpmu_map_event(event, &armv7_a8_perf_map,
  783. &armv7_a8_perf_cache_map, 0xFF);
  784. }
  785. static int armv7_a9_map_event(struct perf_event *event)
  786. {
  787. return armpmu_map_event(event, &armv7_a9_perf_map,
  788. &armv7_a9_perf_cache_map, 0xFF);
  789. }
  790. static int armv7_a5_map_event(struct perf_event *event)
  791. {
  792. return armpmu_map_event(event, &armv7_a5_perf_map,
  793. &armv7_a5_perf_cache_map, 0xFF);
  794. }
  795. static int armv7_a15_map_event(struct perf_event *event)
  796. {
  797. return armpmu_map_event(event, &armv7_a15_perf_map,
  798. &armv7_a15_perf_cache_map, 0xFF);
  799. }
  800. static int armv7_a7_map_event(struct perf_event *event)
  801. {
  802. return armpmu_map_event(event, &armv7_a7_perf_map,
  803. &armv7_a7_perf_cache_map, 0xFF);
  804. }
  805. static int armv7_a12_map_event(struct perf_event *event)
  806. {
  807. return armpmu_map_event(event, &armv7_a12_perf_map,
  808. &armv7_a12_perf_cache_map, 0xFF);
  809. }
  810. static int krait_map_event(struct perf_event *event)
  811. {
  812. return armpmu_map_event(event, &krait_perf_map,
  813. &krait_perf_cache_map, 0xFFFFF);
  814. }
  815. static int krait_map_event_no_branch(struct perf_event *event)
  816. {
  817. return armpmu_map_event(event, &krait_perf_map_no_branch,
  818. &krait_perf_cache_map, 0xFFFFF);
  819. }
  820. static void armv7pmu_init(struct arm_pmu *cpu_pmu)
  821. {
  822. cpu_pmu->handle_irq = armv7pmu_handle_irq;
  823. cpu_pmu->enable = armv7pmu_enable_event;
  824. cpu_pmu->disable = armv7pmu_disable_event;
  825. cpu_pmu->read_counter = armv7pmu_read_counter;
  826. cpu_pmu->write_counter = armv7pmu_write_counter;
  827. cpu_pmu->get_event_idx = armv7pmu_get_event_idx;
  828. cpu_pmu->start = armv7pmu_start;
  829. cpu_pmu->stop = armv7pmu_stop;
  830. cpu_pmu->reset = armv7pmu_reset;
  831. cpu_pmu->max_period = (1LLU << 32) - 1;
  832. };
  833. static u32 armv7_read_num_pmnc_events(void)
  834. {
  835. u32 nb_cnt;
  836. /* Read the nb of CNTx counters supported from PMNC */
  837. nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
  838. /* Add the CPU cycles counter and return */
  839. return nb_cnt + 1;
  840. }
  841. static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  842. {
  843. armv7pmu_init(cpu_pmu);
  844. cpu_pmu->name = "armv7_cortex_a8";
  845. cpu_pmu->map_event = armv7_a8_map_event;
  846. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  847. return 0;
  848. }
  849. static int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  850. {
  851. armv7pmu_init(cpu_pmu);
  852. cpu_pmu->name = "armv7_cortex_a9";
  853. cpu_pmu->map_event = armv7_a9_map_event;
  854. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  855. return 0;
  856. }
  857. static int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  858. {
  859. armv7pmu_init(cpu_pmu);
  860. cpu_pmu->name = "armv7_cortex_a5";
  861. cpu_pmu->map_event = armv7_a5_map_event;
  862. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  863. return 0;
  864. }
  865. static int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  866. {
  867. armv7pmu_init(cpu_pmu);
  868. cpu_pmu->name = "armv7_cortex_a15";
  869. cpu_pmu->map_event = armv7_a15_map_event;
  870. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  871. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  872. return 0;
  873. }
  874. static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  875. {
  876. armv7pmu_init(cpu_pmu);
  877. cpu_pmu->name = "armv7_cortex_a7";
  878. cpu_pmu->map_event = armv7_a7_map_event;
  879. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  880. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  881. return 0;
  882. }
  883. static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
  884. {
  885. armv7pmu_init(cpu_pmu);
  886. cpu_pmu->name = "armv7_cortex_a12";
  887. cpu_pmu->map_event = armv7_a12_map_event;
  888. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  889. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  890. return 0;
  891. }
  892. static int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
  893. {
  894. armv7_a12_pmu_init(cpu_pmu);
  895. cpu_pmu->name = "armv7_cortex_a17";
  896. return 0;
  897. }
  898. /*
  899. * Krait Performance Monitor Region Event Selection Register (PMRESRn)
  900. *
  901. * 31 30 24 16 8 0
  902. * +--------------------------------+
  903. * PMRESR0 | EN | CC | CC | CC | CC | N = 1, R = 0
  904. * +--------------------------------+
  905. * PMRESR1 | EN | CC | CC | CC | CC | N = 1, R = 1
  906. * +--------------------------------+
  907. * PMRESR2 | EN | CC | CC | CC | CC | N = 1, R = 2
  908. * +--------------------------------+
  909. * VPMRESR0 | EN | CC | CC | CC | CC | N = 2, R = ?
  910. * +--------------------------------+
  911. * EN | G=3 | G=2 | G=1 | G=0
  912. *
  913. * Event Encoding:
  914. *
  915. * hwc->config_base = 0xNRCCG
  916. *
  917. * N = prefix, 1 for Krait CPU (PMRESRn), 2 for Venum VFP (VPMRESR)
  918. * R = region register
  919. * CC = class of events the group G is choosing from
  920. * G = group or particular event
  921. *
  922. * Example: 0x12021 is a Krait CPU event in PMRESR2's group 1 with code 2
  923. *
  924. * A region (R) corresponds to a piece of the CPU (execution unit, instruction
  925. * unit, etc.) while the event code (CC) corresponds to a particular class of
  926. * events (interrupts for example). An event code is broken down into
  927. * groups (G) that can be mapped into the PMU (irq, fiqs, and irq+fiqs for
  928. * example).
  929. */
  930. #define KRAIT_EVENT (1 << 16)
  931. #define VENUM_EVENT (2 << 16)
  932. #define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
  933. #define PMRESRn_EN BIT(31)
  934. static u32 krait_read_pmresrn(int n)
  935. {
  936. u32 val;
  937. switch (n) {
  938. case 0:
  939. asm volatile("mrc p15, 1, %0, c9, c15, 0" : "=r" (val));
  940. break;
  941. case 1:
  942. asm volatile("mrc p15, 1, %0, c9, c15, 1" : "=r" (val));
  943. break;
  944. case 2:
  945. asm volatile("mrc p15, 1, %0, c9, c15, 2" : "=r" (val));
  946. break;
  947. default:
  948. BUG(); /* Should be validated in krait_pmu_get_event_idx() */
  949. }
  950. return val;
  951. }
  952. static void krait_write_pmresrn(int n, u32 val)
  953. {
  954. switch (n) {
  955. case 0:
  956. asm volatile("mcr p15, 1, %0, c9, c15, 0" : : "r" (val));
  957. break;
  958. case 1:
  959. asm volatile("mcr p15, 1, %0, c9, c15, 1" : : "r" (val));
  960. break;
  961. case 2:
  962. asm volatile("mcr p15, 1, %0, c9, c15, 2" : : "r" (val));
  963. break;
  964. default:
  965. BUG(); /* Should be validated in krait_pmu_get_event_idx() */
  966. }
  967. }
  968. static u32 krait_read_vpmresr0(void)
  969. {
  970. u32 val;
  971. asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val));
  972. return val;
  973. }
  974. static void krait_write_vpmresr0(u32 val)
  975. {
  976. asm volatile("mcr p10, 7, %0, c11, c0, 0" : : "r" (val));
  977. }
  978. static void krait_pre_vpmresr0(u32 *venum_orig_val, u32 *fp_orig_val)
  979. {
  980. u32 venum_new_val;
  981. u32 fp_new_val;
  982. BUG_ON(preemptible());
  983. /* CPACR Enable CP10 and CP11 access */
  984. *venum_orig_val = get_copro_access();
  985. venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
  986. set_copro_access(venum_new_val);
  987. /* Enable FPEXC */
  988. *fp_orig_val = fmrx(FPEXC);
  989. fp_new_val = *fp_orig_val | FPEXC_EN;
  990. fmxr(FPEXC, fp_new_val);
  991. }
  992. static void krait_post_vpmresr0(u32 venum_orig_val, u32 fp_orig_val)
  993. {
  994. BUG_ON(preemptible());
  995. /* Restore FPEXC */
  996. fmxr(FPEXC, fp_orig_val);
  997. isb();
  998. /* Restore CPACR */
  999. set_copro_access(venum_orig_val);
  1000. }
  1001. static u32 krait_get_pmresrn_event(unsigned int region)
  1002. {
  1003. static const u32 pmresrn_table[] = { KRAIT_PMRESR0_GROUP0,
  1004. KRAIT_PMRESR1_GROUP0,
  1005. KRAIT_PMRESR2_GROUP0 };
  1006. return pmresrn_table[region];
  1007. }
  1008. static void krait_evt_setup(int idx, u32 config_base)
  1009. {
  1010. u32 val;
  1011. u32 mask;
  1012. u32 vval, fval;
  1013. unsigned int region;
  1014. unsigned int group;
  1015. unsigned int code;
  1016. unsigned int group_shift;
  1017. bool venum_event;
  1018. venum_event = !!(config_base & VENUM_EVENT);
  1019. region = (config_base >> 12) & 0xf;
  1020. code = (config_base >> 4) & 0xff;
  1021. group = (config_base >> 0) & 0xf;
  1022. group_shift = group * 8;
  1023. mask = 0xff << group_shift;
  1024. /* Configure evtsel for the region and group */
  1025. if (venum_event)
  1026. val = KRAIT_VPMRESR0_GROUP0;
  1027. else
  1028. val = krait_get_pmresrn_event(region);
  1029. val += group;
  1030. /* Mix in mode-exclusion bits */
  1031. val |= config_base & (ARMV7_EXCLUDE_USER | ARMV7_EXCLUDE_PL1);
  1032. armv7_pmnc_write_evtsel(idx, val);
  1033. asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0));
  1034. if (venum_event) {
  1035. krait_pre_vpmresr0(&vval, &fval);
  1036. val = krait_read_vpmresr0();
  1037. val &= ~mask;
  1038. val |= code << group_shift;
  1039. val |= PMRESRn_EN;
  1040. krait_write_vpmresr0(val);
  1041. krait_post_vpmresr0(vval, fval);
  1042. } else {
  1043. val = krait_read_pmresrn(region);
  1044. val &= ~mask;
  1045. val |= code << group_shift;
  1046. val |= PMRESRn_EN;
  1047. krait_write_pmresrn(region, val);
  1048. }
  1049. }
  1050. static u32 krait_clear_pmresrn_group(u32 val, int group)
  1051. {
  1052. u32 mask;
  1053. int group_shift;
  1054. group_shift = group * 8;
  1055. mask = 0xff << group_shift;
  1056. val &= ~mask;
  1057. /* Don't clear enable bit if entire region isn't disabled */
  1058. if (val & ~PMRESRn_EN)
  1059. return val |= PMRESRn_EN;
  1060. return 0;
  1061. }
  1062. static void krait_clearpmu(u32 config_base)
  1063. {
  1064. u32 val;
  1065. u32 vval, fval;
  1066. unsigned int region;
  1067. unsigned int group;
  1068. bool venum_event;
  1069. venum_event = !!(config_base & VENUM_EVENT);
  1070. region = (config_base >> 12) & 0xf;
  1071. group = (config_base >> 0) & 0xf;
  1072. if (venum_event) {
  1073. krait_pre_vpmresr0(&vval, &fval);
  1074. val = krait_read_vpmresr0();
  1075. val = krait_clear_pmresrn_group(val, group);
  1076. krait_write_vpmresr0(val);
  1077. krait_post_vpmresr0(vval, fval);
  1078. } else {
  1079. val = krait_read_pmresrn(region);
  1080. val = krait_clear_pmresrn_group(val, group);
  1081. krait_write_pmresrn(region, val);
  1082. }
  1083. }
  1084. static void krait_pmu_disable_event(struct perf_event *event)
  1085. {
  1086. unsigned long flags;
  1087. struct hw_perf_event *hwc = &event->hw;
  1088. int idx = hwc->idx;
  1089. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1090. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  1091. /* Disable counter and interrupt */
  1092. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1093. /* Disable counter */
  1094. armv7_pmnc_disable_counter(idx);
  1095. /*
  1096. * Clear pmresr code (if destined for PMNx counters)
  1097. */
  1098. if (hwc->config_base & KRAIT_EVENT_MASK)
  1099. krait_clearpmu(hwc->config_base);
  1100. /* Disable interrupt for this counter */
  1101. armv7_pmnc_disable_intens(idx);
  1102. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1103. }
  1104. static void krait_pmu_enable_event(struct perf_event *event)
  1105. {
  1106. unsigned long flags;
  1107. struct hw_perf_event *hwc = &event->hw;
  1108. int idx = hwc->idx;
  1109. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1110. struct pmu_hw_events *events = cpu_pmu->get_hw_events();
  1111. /*
  1112. * Enable counter and interrupt, and set the counter to count
  1113. * the event that we're interested in.
  1114. */
  1115. raw_spin_lock_irqsave(&events->pmu_lock, flags);
  1116. /* Disable counter */
  1117. armv7_pmnc_disable_counter(idx);
  1118. /*
  1119. * Set event (if destined for PMNx counters)
  1120. * We set the event for the cycle counter because we
  1121. * have the ability to perform event filtering.
  1122. */
  1123. if (hwc->config_base & KRAIT_EVENT_MASK)
  1124. krait_evt_setup(idx, hwc->config_base);
  1125. else
  1126. armv7_pmnc_write_evtsel(idx, hwc->config_base);
  1127. /* Enable interrupt for this counter */
  1128. armv7_pmnc_enable_intens(idx);
  1129. /* Enable counter */
  1130. armv7_pmnc_enable_counter(idx);
  1131. raw_spin_unlock_irqrestore(&events->pmu_lock, flags);
  1132. }
  1133. static void krait_pmu_reset(void *info)
  1134. {
  1135. u32 vval, fval;
  1136. armv7pmu_reset(info);
  1137. /* Clear all pmresrs */
  1138. krait_write_pmresrn(0, 0);
  1139. krait_write_pmresrn(1, 0);
  1140. krait_write_pmresrn(2, 0);
  1141. krait_pre_vpmresr0(&vval, &fval);
  1142. krait_write_vpmresr0(0);
  1143. krait_post_vpmresr0(vval, fval);
  1144. }
  1145. static int krait_event_to_bit(struct perf_event *event, unsigned int region,
  1146. unsigned int group)
  1147. {
  1148. int bit;
  1149. struct hw_perf_event *hwc = &event->hw;
  1150. struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
  1151. if (hwc->config_base & VENUM_EVENT)
  1152. bit = KRAIT_VPMRESR0_GROUP0;
  1153. else
  1154. bit = krait_get_pmresrn_event(region);
  1155. bit -= krait_get_pmresrn_event(0);
  1156. bit += group;
  1157. /*
  1158. * Lower bits are reserved for use by the counters (see
  1159. * armv7pmu_get_event_idx() for more info)
  1160. */
  1161. bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1;
  1162. return bit;
  1163. }
  1164. /*
  1165. * We check for column exclusion constraints here.
  1166. * Two events cant use the same group within a pmresr register.
  1167. */
  1168. static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
  1169. struct perf_event *event)
  1170. {
  1171. int idx;
  1172. int bit = -1;
  1173. unsigned int prefix;
  1174. unsigned int region;
  1175. unsigned int code;
  1176. unsigned int group;
  1177. bool krait_event;
  1178. struct hw_perf_event *hwc = &event->hw;
  1179. region = (hwc->config_base >> 12) & 0xf;
  1180. code = (hwc->config_base >> 4) & 0xff;
  1181. group = (hwc->config_base >> 0) & 0xf;
  1182. krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
  1183. if (krait_event) {
  1184. /* Ignore invalid events */
  1185. if (group > 3 || region > 2)
  1186. return -EINVAL;
  1187. prefix = hwc->config_base & KRAIT_EVENT_MASK;
  1188. if (prefix != KRAIT_EVENT && prefix != VENUM_EVENT)
  1189. return -EINVAL;
  1190. if (prefix == VENUM_EVENT && (code & 0xe0))
  1191. return -EINVAL;
  1192. bit = krait_event_to_bit(event, region, group);
  1193. if (test_and_set_bit(bit, cpuc->used_mask))
  1194. return -EAGAIN;
  1195. }
  1196. idx = armv7pmu_get_event_idx(cpuc, event);
  1197. if (idx < 0 && bit >= 0)
  1198. clear_bit(bit, cpuc->used_mask);
  1199. return idx;
  1200. }
  1201. static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
  1202. struct perf_event *event)
  1203. {
  1204. int bit;
  1205. struct hw_perf_event *hwc = &event->hw;
  1206. unsigned int region;
  1207. unsigned int group;
  1208. bool krait_event;
  1209. region = (hwc->config_base >> 12) & 0xf;
  1210. group = (hwc->config_base >> 0) & 0xf;
  1211. krait_event = !!(hwc->config_base & KRAIT_EVENT_MASK);
  1212. if (krait_event) {
  1213. bit = krait_event_to_bit(event, region, group);
  1214. clear_bit(bit, cpuc->used_mask);
  1215. }
  1216. }
  1217. static int krait_pmu_init(struct arm_pmu *cpu_pmu)
  1218. {
  1219. armv7pmu_init(cpu_pmu);
  1220. cpu_pmu->name = "armv7_krait";
  1221. /* Some early versions of Krait don't support PC write events */
  1222. if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
  1223. "qcom,no-pc-write"))
  1224. cpu_pmu->map_event = krait_map_event_no_branch;
  1225. else
  1226. cpu_pmu->map_event = krait_map_event;
  1227. cpu_pmu->num_events = armv7_read_num_pmnc_events();
  1228. cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
  1229. cpu_pmu->reset = krait_pmu_reset;
  1230. cpu_pmu->enable = krait_pmu_enable_event;
  1231. cpu_pmu->disable = krait_pmu_disable_event;
  1232. cpu_pmu->get_event_idx = krait_pmu_get_event_idx;
  1233. cpu_pmu->clear_event_idx = krait_pmu_clear_event_idx;
  1234. return 0;
  1235. }
  1236. #else
  1237. static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
  1238. {
  1239. return -ENODEV;
  1240. }
  1241. static inline int armv7_a9_pmu_init(struct arm_pmu *cpu_pmu)
  1242. {
  1243. return -ENODEV;
  1244. }
  1245. static inline int armv7_a5_pmu_init(struct arm_pmu *cpu_pmu)
  1246. {
  1247. return -ENODEV;
  1248. }
  1249. static inline int armv7_a15_pmu_init(struct arm_pmu *cpu_pmu)
  1250. {
  1251. return -ENODEV;
  1252. }
  1253. static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
  1254. {
  1255. return -ENODEV;
  1256. }
  1257. static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
  1258. {
  1259. return -ENODEV;
  1260. }
  1261. static inline int armv7_a17_pmu_init(struct arm_pmu *cpu_pmu)
  1262. {
  1263. return -ENODEV;
  1264. }
  1265. static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
  1266. {
  1267. return -ENODEV;
  1268. }
  1269. #endif /* CONFIG_CPU_V7 */