adreno_a5xx_snapshot.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "adreno.h"
  7. #include "adreno_a5xx.h"
  8. #include "adreno_snapshot.h"
  9. enum a5xx_rbbm_debbus_id {
  10. A5XX_RBBM_DBGBUS_CP = 0x1,
  11. A5XX_RBBM_DBGBUS_RBBM = 0x2,
  12. A5XX_RBBM_DBGBUS_VBIF = 0x3,
  13. A5XX_RBBM_DBGBUS_HLSQ = 0x4,
  14. A5XX_RBBM_DBGBUS_UCHE = 0x5,
  15. A5XX_RBBM_DBGBUS_DPM = 0x6,
  16. A5XX_RBBM_DBGBUS_TESS = 0x7,
  17. A5XX_RBBM_DBGBUS_PC = 0x8,
  18. A5XX_RBBM_DBGBUS_VFDP = 0x9,
  19. A5XX_RBBM_DBGBUS_VPC = 0xa,
  20. A5XX_RBBM_DBGBUS_TSE = 0xb,
  21. A5XX_RBBM_DBGBUS_RAS = 0xc,
  22. A5XX_RBBM_DBGBUS_VSC = 0xd,
  23. A5XX_RBBM_DBGBUS_COM = 0xe,
  24. A5XX_RBBM_DBGBUS_DCOM = 0xf,
  25. A5XX_RBBM_DBGBUS_LRZ = 0x10,
  26. A5XX_RBBM_DBGBUS_A2D_DSP = 0x11,
  27. A5XX_RBBM_DBGBUS_CCUFCHE = 0x12,
  28. A5XX_RBBM_DBGBUS_GPMU = 0x13,
  29. A5XX_RBBM_DBGBUS_RBP = 0x14,
  30. A5XX_RBBM_DBGBUS_HM = 0x15,
  31. A5XX_RBBM_DBGBUS_RBBM_CFG = 0x16,
  32. A5XX_RBBM_DBGBUS_VBIF_CX = 0x17,
  33. A5XX_RBBM_DBGBUS_GPC = 0x1d,
  34. A5XX_RBBM_DBGBUS_LARC = 0x1e,
  35. A5XX_RBBM_DBGBUS_HLSQ_SPTP = 0x1f,
  36. A5XX_RBBM_DBGBUS_RB_0 = 0x20,
  37. A5XX_RBBM_DBGBUS_RB_1 = 0x21,
  38. A5XX_RBBM_DBGBUS_RB_2 = 0x22,
  39. A5XX_RBBM_DBGBUS_RB_3 = 0x23,
  40. A5XX_RBBM_DBGBUS_CCU_0 = 0x28,
  41. A5XX_RBBM_DBGBUS_CCU_1 = 0x29,
  42. A5XX_RBBM_DBGBUS_CCU_2 = 0x2a,
  43. A5XX_RBBM_DBGBUS_CCU_3 = 0x2b,
  44. A5XX_RBBM_DBGBUS_A2D_RAS_0 = 0x30,
  45. A5XX_RBBM_DBGBUS_A2D_RAS_1 = 0x31,
  46. A5XX_RBBM_DBGBUS_A2D_RAS_2 = 0x32,
  47. A5XX_RBBM_DBGBUS_A2D_RAS_3 = 0x33,
  48. A5XX_RBBM_DBGBUS_VFD_0 = 0x38,
  49. A5XX_RBBM_DBGBUS_VFD_1 = 0x39,
  50. A5XX_RBBM_DBGBUS_VFD_2 = 0x3a,
  51. A5XX_RBBM_DBGBUS_VFD_3 = 0x3b,
  52. A5XX_RBBM_DBGBUS_SP_0 = 0x40,
  53. A5XX_RBBM_DBGBUS_SP_1 = 0x41,
  54. A5XX_RBBM_DBGBUS_SP_2 = 0x42,
  55. A5XX_RBBM_DBGBUS_SP_3 = 0x43,
  56. A5XX_RBBM_DBGBUS_TPL1_0 = 0x48,
  57. A5XX_RBBM_DBGBUS_TPL1_1 = 0x49,
  58. A5XX_RBBM_DBGBUS_TPL1_2 = 0x4a,
  59. A5XX_RBBM_DBGBUS_TPL1_3 = 0x4b
  60. };
  61. static const struct adreno_debugbus_block a5xx_debugbus_blocks[] = {
  62. { A5XX_RBBM_DBGBUS_CP, 0x100, },
  63. { A5XX_RBBM_DBGBUS_RBBM, 0x100, },
  64. { A5XX_RBBM_DBGBUS_VBIF, 0x100, },
  65. { A5XX_RBBM_DBGBUS_HLSQ, 0x100, },
  66. { A5XX_RBBM_DBGBUS_UCHE, 0x100, },
  67. { A5XX_RBBM_DBGBUS_DPM, 0x100, },
  68. { A5XX_RBBM_DBGBUS_TESS, 0x100, },
  69. { A5XX_RBBM_DBGBUS_PC, 0x100, },
  70. { A5XX_RBBM_DBGBUS_VFDP, 0x100, },
  71. { A5XX_RBBM_DBGBUS_VPC, 0x100, },
  72. { A5XX_RBBM_DBGBUS_TSE, 0x100, },
  73. { A5XX_RBBM_DBGBUS_RAS, 0x100, },
  74. { A5XX_RBBM_DBGBUS_VSC, 0x100, },
  75. { A5XX_RBBM_DBGBUS_COM, 0x100, },
  76. { A5XX_RBBM_DBGBUS_DCOM, 0x100, },
  77. { A5XX_RBBM_DBGBUS_LRZ, 0x100, },
  78. { A5XX_RBBM_DBGBUS_A2D_DSP, 0x100, },
  79. { A5XX_RBBM_DBGBUS_CCUFCHE, 0x100, },
  80. { A5XX_RBBM_DBGBUS_GPMU, 0x100, },
  81. { A5XX_RBBM_DBGBUS_RBP, 0x100, },
  82. { A5XX_RBBM_DBGBUS_HM, 0x100, },
  83. { A5XX_RBBM_DBGBUS_RBBM_CFG, 0x100, },
  84. { A5XX_RBBM_DBGBUS_VBIF_CX, 0x100, },
  85. { A5XX_RBBM_DBGBUS_GPC, 0x100, },
  86. { A5XX_RBBM_DBGBUS_LARC, 0x100, },
  87. { A5XX_RBBM_DBGBUS_HLSQ_SPTP, 0x100, },
  88. { A5XX_RBBM_DBGBUS_RB_0, 0x100, },
  89. { A5XX_RBBM_DBGBUS_RB_1, 0x100, },
  90. { A5XX_RBBM_DBGBUS_RB_2, 0x100, },
  91. { A5XX_RBBM_DBGBUS_RB_3, 0x100, },
  92. { A5XX_RBBM_DBGBUS_CCU_0, 0x100, },
  93. { A5XX_RBBM_DBGBUS_CCU_1, 0x100, },
  94. { A5XX_RBBM_DBGBUS_CCU_2, 0x100, },
  95. { A5XX_RBBM_DBGBUS_CCU_3, 0x100, },
  96. { A5XX_RBBM_DBGBUS_A2D_RAS_0, 0x100, },
  97. { A5XX_RBBM_DBGBUS_A2D_RAS_1, 0x100, },
  98. { A5XX_RBBM_DBGBUS_A2D_RAS_2, 0x100, },
  99. { A5XX_RBBM_DBGBUS_A2D_RAS_3, 0x100, },
  100. { A5XX_RBBM_DBGBUS_VFD_0, 0x100, },
  101. { A5XX_RBBM_DBGBUS_VFD_1, 0x100, },
  102. { A5XX_RBBM_DBGBUS_VFD_2, 0x100, },
  103. { A5XX_RBBM_DBGBUS_VFD_3, 0x100, },
  104. { A5XX_RBBM_DBGBUS_SP_0, 0x100, },
  105. { A5XX_RBBM_DBGBUS_SP_1, 0x100, },
  106. { A5XX_RBBM_DBGBUS_SP_2, 0x100, },
  107. { A5XX_RBBM_DBGBUS_SP_3, 0x100, },
  108. { A5XX_RBBM_DBGBUS_TPL1_0, 0x100, },
  109. { A5XX_RBBM_DBGBUS_TPL1_1, 0x100, },
  110. { A5XX_RBBM_DBGBUS_TPL1_2, 0x100, },
  111. { A5XX_RBBM_DBGBUS_TPL1_3, 0x100, },
  112. };
  113. #define A5XX_NUM_AXI_ARB_BLOCKS 2
  114. #define A5XX_NUM_XIN_BLOCKS 4
  115. /* Width of A5XX_CP_DRAW_STATE_ADDR is 8 bits */
  116. #define A5XX_CP_DRAW_STATE_ADDR_WIDTH 8
  117. /* a5xx_snapshot_cp_pm4() - Dump PM4 data in snapshot */
  118. static size_t a5xx_snapshot_cp_pm4(struct kgsl_device *device, u8 *buf,
  119. size_t remain, void *priv)
  120. {
  121. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  122. struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
  123. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  124. struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_PM4);
  125. size_t size = fw->size;
  126. if (remain < DEBUG_SECTION_SZ(size)) {
  127. SNAPSHOT_ERR_NOMEM(device, "CP PM4 RAM DEBUG");
  128. return 0;
  129. }
  130. header->type = SNAPSHOT_DEBUG_CP_PM4_RAM;
  131. header->size = size;
  132. memcpy(data, fw->memdesc->hostptr, size * sizeof(uint32_t));
  133. return DEBUG_SECTION_SZ(size);
  134. }
  135. /* a5xx_snapshot_cp_pfp() - Dump the PFP data on snapshot */
  136. static size_t a5xx_snapshot_cp_pfp(struct kgsl_device *device, u8 *buf,
  137. size_t remain, void *priv)
  138. {
  139. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  140. struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
  141. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  142. struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_PFP);
  143. int size = fw->size;
  144. if (remain < DEBUG_SECTION_SZ(size)) {
  145. SNAPSHOT_ERR_NOMEM(device, "CP PFP RAM DEBUG");
  146. return 0;
  147. }
  148. header->type = SNAPSHOT_DEBUG_CP_PFP_RAM;
  149. header->size = size;
  150. memcpy(data, fw->memdesc->hostptr, size * sizeof(uint32_t));
  151. return DEBUG_SECTION_SZ(size);
  152. }
  153. /* a5xx_rbbm_debug_bus_read() - Read data from trace bus */
  154. static void a5xx_rbbm_debug_bus_read(struct kgsl_device *device,
  155. unsigned int block_id, unsigned int index, unsigned int *val)
  156. {
  157. unsigned int reg;
  158. reg = (block_id << A5XX_RBBM_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
  159. (index << A5XX_RBBM_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
  160. kgsl_regwrite(device, A5XX_RBBM_CFG_DBGBUS_SEL_A, reg);
  161. kgsl_regwrite(device, A5XX_RBBM_CFG_DBGBUS_SEL_B, reg);
  162. kgsl_regwrite(device, A5XX_RBBM_CFG_DBGBUS_SEL_C, reg);
  163. kgsl_regwrite(device, A5XX_RBBM_CFG_DBGBUS_SEL_D, reg);
  164. kgsl_regread(device, A5XX_RBBM_CFG_DBGBUS_TRACE_BUF2, val);
  165. val++;
  166. kgsl_regread(device, A5XX_RBBM_CFG_DBGBUS_TRACE_BUF1, val);
  167. }
  168. /* a5xx_snapshot_vbif_debugbus() - Dump the VBIF debug data */
  169. static size_t a5xx_snapshot_vbif_debugbus(struct kgsl_device *device,
  170. u8 *buf, size_t remain, void *priv)
  171. {
  172. struct kgsl_snapshot_debugbus *header =
  173. (struct kgsl_snapshot_debugbus *)buf;
  174. struct adreno_debugbus_block *block = priv;
  175. int i, j;
  176. /*
  177. * Total number of VBIF data words considering 3 sections:
  178. * 2 arbiter blocks of 16 words
  179. * 4 AXI XIN blocks of 18 dwords each
  180. * 4 core clock side XIN blocks of 12 dwords each
  181. */
  182. unsigned int dwords = (16 * A5XX_NUM_AXI_ARB_BLOCKS) +
  183. (18 * A5XX_NUM_XIN_BLOCKS) + (12 * A5XX_NUM_XIN_BLOCKS);
  184. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  185. size_t size;
  186. unsigned int reg_clk;
  187. size = (dwords * sizeof(unsigned int)) + sizeof(*header);
  188. if (remain < size) {
  189. SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
  190. return 0;
  191. }
  192. header->id = block->block_id;
  193. header->count = dwords;
  194. kgsl_regread(device, A5XX_VBIF_CLKON, &reg_clk);
  195. kgsl_regwrite(device, A5XX_VBIF_CLKON, reg_clk |
  196. (A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_MASK <<
  197. A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_SHIFT));
  198. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS1_CTRL0, 0);
  199. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS_OUT_CTRL,
  200. (A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_MASK <<
  201. A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_SHIFT));
  202. for (i = 0; i < A5XX_NUM_AXI_ARB_BLOCKS; i++) {
  203. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS2_CTRL0,
  204. (1 << (i + 16)));
  205. for (j = 0; j < 16; j++) {
  206. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS2_CTRL1,
  207. ((j & A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_MASK)
  208. << A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_SHIFT));
  209. kgsl_regread(device, A5XX_VBIF_TEST_BUS_OUT,
  210. data);
  211. data++;
  212. }
  213. }
  214. /* XIN blocks AXI side */
  215. for (i = 0; i < A5XX_NUM_XIN_BLOCKS; i++) {
  216. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS2_CTRL0, 1 << i);
  217. for (j = 0; j < 18; j++) {
  218. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS2_CTRL1,
  219. ((j & A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_MASK)
  220. << A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_SHIFT));
  221. kgsl_regread(device, A5XX_VBIF_TEST_BUS_OUT,
  222. data);
  223. data++;
  224. }
  225. }
  226. /* XIN blocks core clock side */
  227. for (i = 0; i < A5XX_NUM_XIN_BLOCKS; i++) {
  228. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS1_CTRL0, 1 << i);
  229. for (j = 0; j < 12; j++) {
  230. kgsl_regwrite(device, A5XX_VBIF_TEST_BUS1_CTRL1,
  231. ((j & A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_MASK)
  232. << A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_SHIFT));
  233. kgsl_regread(device, A5XX_VBIF_TEST_BUS_OUT,
  234. data);
  235. data++;
  236. }
  237. }
  238. /* restore the clock of VBIF */
  239. kgsl_regwrite(device, A5XX_VBIF_CLKON, reg_clk);
  240. return size;
  241. }
  242. /* a5xx_snapshot_debugbus_block() - Capture debug data for a gpu block */
  243. static size_t a5xx_snapshot_debugbus_block(struct kgsl_device *device,
  244. u8 *buf, size_t remain, void *priv)
  245. {
  246. struct kgsl_snapshot_debugbus *header =
  247. (struct kgsl_snapshot_debugbus *)buf;
  248. struct adreno_debugbus_block *block = priv;
  249. int i;
  250. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  251. unsigned int dwords;
  252. size_t size;
  253. dwords = block->dwords;
  254. /* For a5xx each debug bus data unit is 2 DWRODS */
  255. size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
  256. if (remain < size) {
  257. SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
  258. return 0;
  259. }
  260. header->id = block->block_id;
  261. header->count = dwords * 2;
  262. for (i = 0; i < dwords; i++)
  263. a5xx_rbbm_debug_bus_read(device, block->block_id, i,
  264. &data[i*2]);
  265. return size;
  266. }
  267. /* a5xx_snapshot_debugbus() - Capture debug bus data */
  268. static void a5xx_snapshot_debugbus(struct kgsl_device *device,
  269. struct kgsl_snapshot *snapshot)
  270. {
  271. int i;
  272. kgsl_regwrite(device, A5XX_RBBM_CFG_DBGBUS_CNTLM,
  273. 0xf << A5XX_RBBM_CFG_DEBBUS_CTLTM_ENABLE_SHIFT);
  274. for (i = 0; i < ARRAY_SIZE(a5xx_debugbus_blocks); i++) {
  275. if (a5xx_debugbus_blocks[i].block_id == A5XX_RBBM_DBGBUS_VBIF)
  276. kgsl_snapshot_add_section(device,
  277. KGSL_SNAPSHOT_SECTION_DEBUGBUS,
  278. snapshot, a5xx_snapshot_vbif_debugbus,
  279. (void *) &a5xx_debugbus_blocks[i]);
  280. else
  281. kgsl_snapshot_add_section(device,
  282. KGSL_SNAPSHOT_SECTION_DEBUGBUS,
  283. snapshot, a5xx_snapshot_debugbus_block,
  284. (void *) &a5xx_debugbus_blocks[i]);
  285. }
  286. }
  287. static const unsigned int a5xx_vbif_registers[] = {
  288. 0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302C, 0x3030, 0x3030,
  289. 0x3034, 0x3036, 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040,
  290. 0x3042, 0x3042, 0x3049, 0x3049, 0x3058, 0x3058, 0x305A, 0x3061,
  291. 0x3064, 0x3068, 0x306C, 0x306D, 0x3080, 0x3088, 0x308C, 0x308C,
  292. 0x3090, 0x3094, 0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0,
  293. 0x30C8, 0x30C8, 0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0,
  294. 0x3100, 0x3100, 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118,
  295. 0x3120, 0x3120, 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131,
  296. 0x340C, 0x340C, 0x3410, 0x3410, 0x3800, 0x3801,
  297. };
  298. /*
  299. * Set of registers to dump for A5XX on snapshot.
  300. * Registers in pairs - first value is the start offset, second
  301. * is the stop offset (inclusive)
  302. */
  303. static const unsigned int a5xx_registers[] = {
  304. /* RBBM */
  305. 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
  306. 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
  307. 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
  308. 0x04E0, 0x04F4, 0X04F8, 0x0529, 0x0531, 0x0533, 0x0540, 0x0555,
  309. 0xF400, 0xF400, 0xF800, 0xF807,
  310. /* CP */
  311. 0x0800, 0x0803, 0x0806, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860,
  312. 0x0880, 0x08A0, 0x0B00, 0x0B12, 0x0B15, 0X0B1C, 0X0B1E, 0x0B28,
  313. 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD,
  314. /* VSC */
  315. 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61,
  316. /* GRAS */
  317. 0x0C80, 0x0C82, 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0,
  318. 0x0CB0, 0x0CB2, 0x2180, 0x2185, 0x2580, 0x2585,
  319. /* RB */
  320. 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7, 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8,
  321. 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8, 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E,
  322. 0x2100, 0x211E, 0x2140, 0x2145, 0x2500, 0x251E, 0x2540, 0x2545,
  323. /* PC */
  324. 0x0D10, 0x0D17, 0x0D20, 0x0D23, 0x0D30, 0x0D30, 0x20C0, 0x20C0,
  325. 0x24C0, 0x24C0,
  326. /* VFD */
  327. 0x0E40, 0x0E43, 0x0E4A, 0x0E4A, 0x0E50, 0x0E57,
  328. /* VPC */
  329. 0x0E60, 0x0E7C,
  330. /* UCHE */
  331. 0x0E80, 0x0E8F, 0x0E90, 0x0E96, 0xEA0, 0xEA8, 0xEB0, 0xEB2,
  332. /* RB CTX 0 */
  333. 0xE140, 0xE147, 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6,
  334. 0xE1C0, 0xE1C7, 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C,
  335. 0xE240, 0xE268,
  336. /* GRAS CTX 0 */
  337. 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB,
  338. 0xE100, 0xE105,
  339. /* PC CTX 0 */
  340. 0xE380, 0xE38F, 0xE3B0, 0xE3B0,
  341. /* VFD CTX 0 */
  342. 0xE400, 0xE405, 0xE408, 0xE4E9, 0xE4F0, 0xE4F0,
  343. /* VPC CTX 0 */
  344. 0xE280, 0xE280, 0xE282, 0xE2A3, 0xE2A5, 0xE2C2,
  345. /* RB CTX 1 */
  346. 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9, 0xE9B0, 0xE9B6,
  347. 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01, 0xEA10, 0xEA1C,
  348. 0xEA40, 0xEA68,
  349. /* GRAS CTX 1 */
  350. 0xE800, 0xE806, 0xE810, 0xE89A, 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB,
  351. 0xE900, 0xE905,
  352. /* PC CTX 1 */
  353. 0xEB80, 0xEB8F, 0xEBB0, 0xEBB0,
  354. /* VFD CTX 1 */
  355. 0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
  356. /* VPC CTX 1 */
  357. 0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2,
  358. };
  359. /*
  360. * GPMU registers to dump for A5XX on snapshot.
  361. * Registers in pairs - first value is the start offset, second
  362. * is the stop offset (inclusive)
  363. */
  364. static const unsigned int a5xx_gpmu_registers[] = {
  365. /* GPMU */
  366. 0xA800, 0xA8FF, 0xAC60, 0xAC60,
  367. };
  368. /*
  369. * Set of registers to dump for A5XX before actually triggering crash dumper.
  370. * Registers in pairs - first value is the start offset, second
  371. * is the stop offset (inclusive)
  372. */
  373. static const unsigned int a5xx_pre_crashdumper_registers[] = {
  374. /* RBBM: RBBM_STATUS - RBBM_STATUS3 */
  375. 0x04F5, 0x04F7, 0x0530, 0x0530,
  376. /* CP: CP_STATUS_1 */
  377. 0x0B1D, 0x0B1D,
  378. };
  379. struct a5xx_hlsq_sp_tp_regs {
  380. unsigned int statetype;
  381. unsigned int ahbaddr;
  382. unsigned int size;
  383. uint64_t offset;
  384. };
  385. static struct a5xx_hlsq_sp_tp_regs a5xx_hlsq_sp_tp_registers[] = {
  386. /* HSLQ non context. 0xe32 - 0xe3f are holes so don't include them */
  387. { 0x35, 0xE00, 0x32 },
  388. /* HLSQ CTX 0 2D */
  389. { 0x31, 0x2080, 0x1 },
  390. /* HLSQ CTX 1 2D */
  391. { 0x33, 0x2480, 0x1 },
  392. /* HLSQ CTX 0 3D. 0xe7e2 - 0xe7ff are holes so don't include them */
  393. { 0x32, 0xE780, 0x62 },
  394. /* HLSQ CTX 1 3D. 0xefe2 - 0xefff are holes so don't include them */
  395. { 0x34, 0xEF80, 0x62 },
  396. /* SP non context */
  397. { 0x3f, 0x0EC0, 0x40 },
  398. /* SP CTX 0 2D */
  399. { 0x3d, 0x2040, 0x1 },
  400. /* SP CTX 1 2D */
  401. { 0x3b, 0x2440, 0x1 },
  402. /* SP CTX 0 3D */
  403. { 0x3e, 0xE580, 0x180 },
  404. /* SP CTX 1 3D */
  405. { 0x3c, 0xED80, 0x180 },
  406. /* TP non context. 0x0f1c - 0x0f3f are holes so don't include them */
  407. { 0x3a, 0x0F00, 0x1c },
  408. /* TP CTX 0 2D. 0x200a - 0x200f are holes so don't include them */
  409. { 0x38, 0x2000, 0xa },
  410. /* TP CTX 1 2D. 0x240a - 0x240f are holes so don't include them */
  411. { 0x36, 0x2400, 0xa },
  412. /* TP CTX 0 3D */
  413. { 0x39, 0xE700, 0x80 },
  414. /* TP CTX 1 3D */
  415. { 0x37, 0xEF00, 0x80 },
  416. };
  417. #define A5XX_NUM_SHADER_BANKS 4
  418. #define A5XX_SHADER_STATETYPE_SHIFT 8
  419. enum a5xx_shader_obj {
  420. A5XX_TP_W_MEMOBJ = 1,
  421. A5XX_TP_W_SAMPLER = 2,
  422. A5XX_TP_W_MIPMAP_BASE = 3,
  423. A5XX_TP_W_MEMOBJ_TAG = 4,
  424. A5XX_TP_W_SAMPLER_TAG = 5,
  425. A5XX_TP_S_3D_MEMOBJ = 6,
  426. A5XX_TP_S_3D_SAMPLER = 0x7,
  427. A5XX_TP_S_3D_MEMOBJ_TAG = 0x8,
  428. A5XX_TP_S_3D_SAMPLER_TAG = 0x9,
  429. A5XX_TP_S_CS_MEMOBJ = 0xA,
  430. A5XX_TP_S_CS_SAMPLER = 0xB,
  431. A5XX_TP_S_CS_MEMOBJ_TAG = 0xC,
  432. A5XX_TP_S_CS_SAMPLER_TAG = 0xD,
  433. A5XX_SP_W_INSTR = 0xE,
  434. A5XX_SP_W_CONST = 0xF,
  435. A5XX_SP_W_UAV_SIZE = 0x10,
  436. A5XX_SP_W_CB_SIZE = 0x11,
  437. A5XX_SP_W_UAV_BASE = 0x12,
  438. A5XX_SP_W_CB_BASE = 0x13,
  439. A5XX_SP_W_INST_TAG = 0x14,
  440. A5XX_SP_W_STATE = 0x15,
  441. A5XX_SP_S_3D_INSTR = 0x16,
  442. A5XX_SP_S_3D_CONST = 0x17,
  443. A5XX_SP_S_3D_CB_BASE = 0x18,
  444. A5XX_SP_S_3D_CB_SIZE = 0x19,
  445. A5XX_SP_S_3D_UAV_BASE = 0x1A,
  446. A5XX_SP_S_3D_UAV_SIZE = 0x1B,
  447. A5XX_SP_S_CS_INSTR = 0x1C,
  448. A5XX_SP_S_CS_CONST = 0x1D,
  449. A5XX_SP_S_CS_CB_BASE = 0x1E,
  450. A5XX_SP_S_CS_CB_SIZE = 0x1F,
  451. A5XX_SP_S_CS_UAV_BASE = 0x20,
  452. A5XX_SP_S_CS_UAV_SIZE = 0x21,
  453. A5XX_SP_S_3D_INSTR_DIRTY = 0x22,
  454. A5XX_SP_S_3D_CONST_DIRTY = 0x23,
  455. A5XX_SP_S_3D_CB_BASE_DIRTY = 0x24,
  456. A5XX_SP_S_3D_CB_SIZE_DIRTY = 0x25,
  457. A5XX_SP_S_3D_UAV_BASE_DIRTY = 0x26,
  458. A5XX_SP_S_3D_UAV_SIZE_DIRTY = 0x27,
  459. A5XX_SP_S_CS_INSTR_DIRTY = 0x28,
  460. A5XX_SP_S_CS_CONST_DIRTY = 0x29,
  461. A5XX_SP_S_CS_CB_BASE_DIRTY = 0x2A,
  462. A5XX_SP_S_CS_CB_SIZE_DIRTY = 0x2B,
  463. A5XX_SP_S_CS_UAV_BASE_DIRTY = 0x2C,
  464. A5XX_SP_S_CS_UAV_SIZE_DIRTY = 0x2D,
  465. A5XX_HLSQ_ICB = 0x2E,
  466. A5XX_HLSQ_ICB_DIRTY = 0x2F,
  467. A5XX_HLSQ_ICB_CB_BASE_DIRTY = 0x30,
  468. A5XX_SP_POWER_RESTORE_RAM = 0x40,
  469. A5XX_SP_POWER_RESTORE_RAM_TAG = 0x41,
  470. A5XX_TP_POWER_RESTORE_RAM = 0x42,
  471. A5XX_TP_POWER_RESTORE_RAM_TAG = 0x43,
  472. };
  473. struct a5xx_shader_block {
  474. unsigned int statetype;
  475. unsigned int sz;
  476. uint64_t offset;
  477. };
  478. struct a5xx_shader_block_info {
  479. struct a5xx_shader_block *block;
  480. unsigned int bank;
  481. uint64_t offset;
  482. };
  483. static struct a5xx_shader_block a5xx_shader_blocks[] = {
  484. {A5XX_TP_W_MEMOBJ, 0x200},
  485. {A5XX_TP_W_MIPMAP_BASE, 0x3C0},
  486. {A5XX_TP_W_SAMPLER_TAG, 0x40},
  487. {A5XX_TP_S_3D_SAMPLER, 0x80},
  488. {A5XX_TP_S_3D_SAMPLER_TAG, 0x20},
  489. {A5XX_TP_S_CS_SAMPLER, 0x40},
  490. {A5XX_TP_S_CS_SAMPLER_TAG, 0x10},
  491. {A5XX_SP_W_CONST, 0x800},
  492. {A5XX_SP_W_CB_SIZE, 0x30},
  493. {A5XX_SP_W_CB_BASE, 0xF0},
  494. {A5XX_SP_W_STATE, 0x1},
  495. {A5XX_SP_S_3D_CONST, 0x800},
  496. {A5XX_SP_S_3D_CB_SIZE, 0x28},
  497. {A5XX_SP_S_3D_UAV_SIZE, 0x80},
  498. {A5XX_SP_S_CS_CONST, 0x400},
  499. {A5XX_SP_S_CS_CB_SIZE, 0x8},
  500. {A5XX_SP_S_CS_UAV_SIZE, 0x80},
  501. {A5XX_SP_S_3D_CONST_DIRTY, 0x12},
  502. {A5XX_SP_S_3D_CB_SIZE_DIRTY, 0x1},
  503. {A5XX_SP_S_3D_UAV_SIZE_DIRTY, 0x2},
  504. {A5XX_SP_S_CS_CONST_DIRTY, 0xA},
  505. {A5XX_SP_S_CS_CB_SIZE_DIRTY, 0x1},
  506. {A5XX_SP_S_CS_UAV_SIZE_DIRTY, 0x2},
  507. {A5XX_HLSQ_ICB_DIRTY, 0xB},
  508. {A5XX_SP_POWER_RESTORE_RAM_TAG, 0xA},
  509. {A5XX_TP_POWER_RESTORE_RAM_TAG, 0xA},
  510. {A5XX_TP_W_SAMPLER, 0x80},
  511. {A5XX_TP_W_MEMOBJ_TAG, 0x40},
  512. {A5XX_TP_S_3D_MEMOBJ, 0x200},
  513. {A5XX_TP_S_3D_MEMOBJ_TAG, 0x20},
  514. {A5XX_TP_S_CS_MEMOBJ, 0x100},
  515. {A5XX_TP_S_CS_MEMOBJ_TAG, 0x10},
  516. {A5XX_SP_W_INSTR, 0x800},
  517. {A5XX_SP_W_UAV_SIZE, 0x80},
  518. {A5XX_SP_W_UAV_BASE, 0x80},
  519. {A5XX_SP_W_INST_TAG, 0x40},
  520. {A5XX_SP_S_3D_INSTR, 0x800},
  521. {A5XX_SP_S_3D_CB_BASE, 0xC8},
  522. {A5XX_SP_S_3D_UAV_BASE, 0x80},
  523. {A5XX_SP_S_CS_INSTR, 0x400},
  524. {A5XX_SP_S_CS_CB_BASE, 0x28},
  525. {A5XX_SP_S_CS_UAV_BASE, 0x80},
  526. {A5XX_SP_S_3D_INSTR_DIRTY, 0x1},
  527. {A5XX_SP_S_3D_CB_BASE_DIRTY, 0x5},
  528. {A5XX_SP_S_3D_UAV_BASE_DIRTY, 0x2},
  529. {A5XX_SP_S_CS_INSTR_DIRTY, 0x1},
  530. {A5XX_SP_S_CS_CB_BASE_DIRTY, 0x1},
  531. {A5XX_SP_S_CS_UAV_BASE_DIRTY, 0x2},
  532. {A5XX_HLSQ_ICB, 0x200},
  533. {A5XX_HLSQ_ICB_CB_BASE_DIRTY, 0x4},
  534. {A5XX_SP_POWER_RESTORE_RAM, 0x140},
  535. {A5XX_TP_POWER_RESTORE_RAM, 0x40},
  536. };
  537. static struct kgsl_memdesc *capturescript;
  538. static struct kgsl_memdesc *registers;
  539. static bool crash_dump_valid;
  540. static size_t a5xx_snapshot_shader_memory(struct kgsl_device *device,
  541. u8 *buf, size_t remain, void *priv)
  542. {
  543. struct kgsl_snapshot_shader *header =
  544. (struct kgsl_snapshot_shader *) buf;
  545. struct a5xx_shader_block_info *info =
  546. (struct a5xx_shader_block_info *) priv;
  547. struct a5xx_shader_block *block = info->block;
  548. unsigned int *data = (unsigned int *) (buf + sizeof(*header));
  549. if (remain < SHADER_SECTION_SZ(block->sz)) {
  550. SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
  551. return 0;
  552. }
  553. header->type = block->statetype;
  554. header->index = info->bank;
  555. header->size = block->sz;
  556. memcpy(data, registers->hostptr + info->offset,
  557. block->sz * sizeof(unsigned int));
  558. return SHADER_SECTION_SZ(block->sz);
  559. }
  560. static void a5xx_snapshot_shader(struct kgsl_device *device,
  561. struct kgsl_snapshot *snapshot)
  562. {
  563. unsigned int i, j;
  564. struct a5xx_shader_block_info info;
  565. /* Shader blocks can only be read by the crash dumper */
  566. if (!crash_dump_valid)
  567. return;
  568. for (i = 0; i < ARRAY_SIZE(a5xx_shader_blocks); i++) {
  569. for (j = 0; j < A5XX_NUM_SHADER_BANKS; j++) {
  570. info.block = &a5xx_shader_blocks[i];
  571. info.bank = j;
  572. info.offset = a5xx_shader_blocks[i].offset +
  573. (j * a5xx_shader_blocks[i].sz);
  574. /* Shader working/shadow memory */
  575. kgsl_snapshot_add_section(device,
  576. KGSL_SNAPSHOT_SECTION_SHADER,
  577. snapshot, a5xx_snapshot_shader_memory, &info);
  578. }
  579. }
  580. }
  581. /* Dump registers which get affected by crash dumper trigger */
  582. static size_t a5xx_snapshot_pre_crashdump_regs(struct kgsl_device *device,
  583. u8 *buf, size_t remain, void *priv)
  584. {
  585. struct kgsl_snapshot_registers pre_cdregs = {
  586. .regs = a5xx_pre_crashdumper_registers,
  587. .count = ARRAY_SIZE(a5xx_pre_crashdumper_registers)/2,
  588. };
  589. return kgsl_snapshot_dump_registers(device, buf, remain, &pre_cdregs);
  590. }
  591. struct registers {
  592. const unsigned int *regs;
  593. size_t size;
  594. };
  595. static size_t a5xx_legacy_snapshot_registers(struct kgsl_device *device,
  596. u8 *buf, size_t remain, const unsigned int *regs, size_t size)
  597. {
  598. struct kgsl_snapshot_registers snapshot_regs = {
  599. .regs = regs,
  600. .count = size / 2,
  601. };
  602. return kgsl_snapshot_dump_registers(device, buf, remain,
  603. &snapshot_regs);
  604. }
  605. #define REG_PAIR_COUNT(_a, _i) \
  606. (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
  607. static size_t a5xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
  608. size_t remain, void *priv)
  609. {
  610. struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
  611. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  612. unsigned int *src = (unsigned int *) registers->hostptr;
  613. struct registers *regs = (struct registers *)priv;
  614. unsigned int j, k;
  615. unsigned int count = 0;
  616. if (!crash_dump_valid)
  617. return a5xx_legacy_snapshot_registers(device, buf, remain,
  618. regs->regs, regs->size);
  619. if (remain < sizeof(*header)) {
  620. SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
  621. return 0;
  622. }
  623. remain -= sizeof(*header);
  624. for (j = 0; j < regs->size / 2; j++) {
  625. unsigned int start = regs->regs[2 * j];
  626. unsigned int end = regs->regs[(2 * j) + 1];
  627. if (remain < ((end - start) + 1) * 8) {
  628. SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
  629. goto out;
  630. }
  631. remain -= ((end - start) + 1) * 8;
  632. for (k = start; k <= end; k++, count++) {
  633. *data++ = k;
  634. *data++ = *src++;
  635. }
  636. }
  637. out:
  638. header->count = count;
  639. /* Return the size of the section */
  640. return (count * 8) + sizeof(*header);
  641. }
  642. /* Snapshot a preemption record buffer */
  643. static size_t snapshot_preemption_record(struct kgsl_device *device, u8 *buf,
  644. size_t remain, void *priv)
  645. {
  646. struct kgsl_memdesc *memdesc = priv;
  647. struct kgsl_snapshot_gpu_object_v2 *header =
  648. (struct kgsl_snapshot_gpu_object_v2 *)buf;
  649. u8 *ptr = buf + sizeof(*header);
  650. if (remain < (SZ_64K + sizeof(*header))) {
  651. SNAPSHOT_ERR_NOMEM(device, "PREEMPTION RECORD");
  652. return 0;
  653. }
  654. header->size = SZ_64K >> 2;
  655. header->gpuaddr = memdesc->gpuaddr;
  656. header->ptbase =
  657. kgsl_mmu_pagetable_get_ttbr0(device->mmu.defaultpagetable);
  658. header->type = SNAPSHOT_GPU_OBJECT_GLOBAL;
  659. memcpy(ptr, memdesc->hostptr, SZ_64K);
  660. return SZ_64K + sizeof(*header);
  661. }
  662. static void _a5xx_do_crashdump(struct kgsl_device *device)
  663. {
  664. unsigned long wait_time;
  665. unsigned int reg = 0;
  666. crash_dump_valid = false;
  667. if (!device->snapshot_crashdumper)
  668. return;
  669. if (IS_ERR_OR_NULL(capturescript) || IS_ERR_OR_NULL(registers))
  670. return;
  671. /* IF the SMMU is stalled we cannot do a crash dump */
  672. if (adreno_smmu_is_stalled(ADRENO_DEVICE(device)))
  673. return;
  674. /* Turn on APRIV so we can access the buffers */
  675. kgsl_regwrite(device, A5XX_CP_CNTL, 1);
  676. kgsl_regwrite(device, A5XX_CP_CRASH_SCRIPT_BASE_LO,
  677. lower_32_bits(capturescript->gpuaddr));
  678. kgsl_regwrite(device, A5XX_CP_CRASH_SCRIPT_BASE_HI,
  679. upper_32_bits(capturescript->gpuaddr));
  680. kgsl_regwrite(device, A5XX_CP_CRASH_DUMP_CNTL, 1);
  681. wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
  682. while (!time_after(jiffies, wait_time)) {
  683. kgsl_regread(device, A5XX_CP_CRASH_DUMP_CNTL, &reg);
  684. if (reg & 0x4)
  685. break;
  686. cpu_relax();
  687. }
  688. kgsl_regwrite(device, A5XX_CP_CNTL, 0);
  689. if (!(reg & 0x4)) {
  690. dev_err(device->dev, "Crash dump timed out: 0x%X\n", reg);
  691. return;
  692. }
  693. crash_dump_valid = true;
  694. }
  695. static int get_hlsq_registers(struct kgsl_device *device,
  696. const struct a5xx_hlsq_sp_tp_regs *regs, unsigned int *data)
  697. {
  698. unsigned int i;
  699. unsigned int *src = registers->hostptr + regs->offset;
  700. for (i = 0; i < regs->size; i++) {
  701. *data++ = regs->ahbaddr + i;
  702. *data++ = *(src + i);
  703. }
  704. return (2 * regs->size);
  705. }
  706. static size_t a5xx_snapshot_dump_hlsq_sp_tp_regs(struct kgsl_device *device,
  707. u8 *buf, size_t remain, void *priv)
  708. {
  709. struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
  710. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  711. int count = 0, i;
  712. /* Figure out how many registers we are going to dump */
  713. for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++)
  714. count += a5xx_hlsq_sp_tp_registers[i].size;
  715. if (remain < (count * 8) + sizeof(*header)) {
  716. SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
  717. return 0;
  718. }
  719. for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++)
  720. data += get_hlsq_registers(device,
  721. &a5xx_hlsq_sp_tp_registers[i], data);
  722. header->count = count;
  723. /* Return the size of the section */
  724. return (count * 8) + sizeof(*header);
  725. }
  726. static size_t a5xx_snapshot_cp_merciu(struct kgsl_device *device, u8 *buf,
  727. size_t remain, void *priv)
  728. {
  729. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  730. struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
  731. unsigned int *data = (unsigned int *)(buf + sizeof(*header));
  732. int i, size;
  733. if (adreno_is_a505_or_a506(adreno_dev) || adreno_is_a508(adreno_dev) ||
  734. adreno_is_a540(adreno_dev) || adreno_is_a512(adreno_dev))
  735. size = 1024;
  736. else if (adreno_is_a510(adreno_dev))
  737. size = 32;
  738. else
  739. size = 64;
  740. /* The MERCIU data is two dwords per entry */
  741. size = size << 1;
  742. if (remain < DEBUG_SECTION_SZ(size)) {
  743. SNAPSHOT_ERR_NOMEM(device, "CP MERCIU DEBUG");
  744. return 0;
  745. }
  746. header->type = SNAPSHOT_DEBUG_CP_MERCIU;
  747. header->size = size;
  748. kgsl_regwrite(device, A5XX_CP_MERCIU_DBG_ADDR, 0);
  749. for (i = 0; i < size; i++) {
  750. kgsl_regread(device, A5XX_CP_MERCIU_DBG_DATA_1,
  751. &data[(i * 2)]);
  752. kgsl_regread(device, A5XX_CP_MERCIU_DBG_DATA_2,
  753. &data[(i * 2) + 1]);
  754. }
  755. return DEBUG_SECTION_SZ(size);
  756. }
  757. static size_t a5xx_snapshot_cp_roq(struct kgsl_device *device, u8 *buf,
  758. size_t remain, void *priv)
  759. {
  760. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  761. struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *) buf;
  762. u32 size, *data = (u32 *) (buf + sizeof(*header));
  763. if (adreno_is_a505_or_a506(adreno_dev) || adreno_is_a508(adreno_dev) ||
  764. adreno_is_a510(adreno_dev))
  765. size = 256;
  766. else
  767. size = 512;
  768. if (remain < DEBUG_SECTION_SZ(size)) {
  769. SNAPSHOT_ERR_NOMEM(device, "CP ROQ DEBUG");
  770. return 0;
  771. }
  772. header->type = SNAPSHOT_DEBUG_CP_ROQ;
  773. header->size = size;
  774. kgsl_regmap_read_indexed(&device->regmap, A5XX_CP_ROQ_DBG_ADDR,
  775. A5XX_CP_ROQ_DBG_DATA, data, size);
  776. return DEBUG_SECTION_SZ(size);
  777. }
  778. static size_t a5xx_snapshot_cp_meq(struct kgsl_device *device, u8 *buf,
  779. size_t remain, void *priv)
  780. {
  781. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  782. struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *) buf;
  783. u32 size, *data = (u32 *) (buf + sizeof(*header));
  784. if (adreno_is_a505_or_a506(adreno_dev) || adreno_is_a508(adreno_dev) ||
  785. adreno_is_a510(adreno_dev))
  786. size = 32;
  787. else
  788. size = 64;
  789. if (remain < DEBUG_SECTION_SZ(size)) {
  790. SNAPSHOT_ERR_NOMEM(device, "CP MEQ DEBUG");
  791. return 0;
  792. }
  793. header->type = SNAPSHOT_DEBUG_CP_MEQ;
  794. header->size = size;
  795. kgsl_regmap_read_indexed(&device->regmap, A5XX_CP_MEQ_DBG_ADDR,
  796. A5XX_CP_MEQ_DBG_DATA, data, size);
  797. return DEBUG_SECTION_SZ(size);
  798. }
  799. /*
  800. * a5xx_snapshot() - A5XX GPU snapshot function
  801. * @adreno_dev: Device being snapshotted
  802. * @snapshot: Pointer to the snapshot instance
  803. *
  804. * This is where all of the A5XX specific bits and pieces are grabbed
  805. * into the snapshot memory
  806. */
  807. void a5xx_snapshot(struct adreno_device *adreno_dev,
  808. struct kgsl_snapshot *snapshot)
  809. {
  810. struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
  811. unsigned int i;
  812. u32 hi, lo;
  813. struct adreno_ringbuffer *rb;
  814. struct registers regs;
  815. /* Disable Clock gating temporarily for the debug bus to work */
  816. a5xx_hwcg_set(adreno_dev, false);
  817. /* Save some CP information that the generic snapshot uses */
  818. kgsl_regread(device, A5XX_CP_IB1_BASE, &lo);
  819. kgsl_regread(device, A5XX_CP_IB1_BASE_HI, &hi);
  820. snapshot->ib1base = (((u64) hi) << 32) | lo;
  821. kgsl_regread(device, A5XX_CP_IB2_BASE, &lo);
  822. kgsl_regread(device, A5XX_CP_IB2_BASE_HI, &hi);
  823. snapshot->ib2base = (((u64) hi) << 32) | lo;
  824. kgsl_regread(device, A5XX_CP_IB1_BUFSZ, &snapshot->ib1size);
  825. kgsl_regread(device, A5XX_CP_IB2_BUFSZ, &snapshot->ib2size);
  826. /* Dump the registers which get affected by crash dumper trigger */
  827. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
  828. snapshot, a5xx_snapshot_pre_crashdump_regs, NULL);
  829. /* Dump vbif registers as well which get affected by crash dumper */
  830. SNAPSHOT_REGISTERS(device, snapshot, a5xx_vbif_registers);
  831. /* Try to run the crash dumper */
  832. _a5xx_do_crashdump(device);
  833. regs.regs = a5xx_registers;
  834. regs.size = ARRAY_SIZE(a5xx_registers);
  835. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
  836. a5xx_snapshot_registers, &regs);
  837. if (a5xx_has_gpmu(adreno_dev)) {
  838. regs.regs = a5xx_gpmu_registers;
  839. regs.size = ARRAY_SIZE(a5xx_gpmu_registers);
  840. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
  841. snapshot, a5xx_snapshot_registers, &regs);
  842. }
  843. /* Dump SP TP HLSQ registers */
  844. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
  845. a5xx_snapshot_dump_hlsq_sp_tp_regs, NULL);
  846. /* CP_PFP indexed registers */
  847. kgsl_snapshot_indexed_registers(device, snapshot,
  848. A5XX_CP_PFP_STAT_ADDR, A5XX_CP_PFP_STAT_DATA, 0, 36);
  849. /* CP_ME indexed registers */
  850. kgsl_snapshot_indexed_registers(device, snapshot,
  851. A5XX_CP_ME_STAT_ADDR, A5XX_CP_ME_STAT_DATA, 0, 29);
  852. /* CP_DRAW_STATE */
  853. kgsl_snapshot_indexed_registers(device, snapshot,
  854. A5XX_CP_DRAW_STATE_ADDR, A5XX_CP_DRAW_STATE_DATA,
  855. 0, 1 << A5XX_CP_DRAW_STATE_ADDR_WIDTH);
  856. /* ME_UCODE Cache */
  857. kgsl_snapshot_indexed_registers(device, snapshot,
  858. A5XX_CP_ME_UCODE_DBG_ADDR, A5XX_CP_ME_UCODE_DBG_DATA,
  859. 0, 0x53F);
  860. /* PFP_UCODE Cache */
  861. kgsl_snapshot_indexed_registers(device, snapshot,
  862. A5XX_CP_PFP_UCODE_DBG_ADDR, A5XX_CP_PFP_UCODE_DBG_DATA,
  863. 0, 0x53F);
  864. /* CP MEQ */
  865. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
  866. snapshot, a5xx_snapshot_cp_meq, NULL);
  867. /* CP ROQ */
  868. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
  869. snapshot, a5xx_snapshot_cp_roq, NULL);
  870. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
  871. snapshot, a5xx_snapshot_cp_merciu, NULL);
  872. /* CP PFP and PM4 */
  873. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
  874. snapshot, a5xx_snapshot_cp_pfp, NULL);
  875. kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
  876. snapshot, a5xx_snapshot_cp_pm4, NULL);
  877. /* Debug bus */
  878. a5xx_snapshot_debugbus(device, snapshot);
  879. /* Shader memory */
  880. a5xx_snapshot_shader(device, snapshot);
  881. /* Preemption record */
  882. if (adreno_is_preemption_enabled(adreno_dev)) {
  883. FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
  884. kgsl_snapshot_add_section(device,
  885. KGSL_SNAPSHOT_SECTION_GPU_OBJECT_V2,
  886. snapshot, snapshot_preemption_record,
  887. rb->preemption_desc);
  888. }
  889. }
  890. }
  891. static int _a5xx_crashdump_init_shader(struct a5xx_shader_block *block,
  892. uint64_t *ptr, uint64_t *offset)
  893. {
  894. int qwords = 0;
  895. unsigned int j;
  896. /* Capture each bank in the block */
  897. for (j = 0; j < A5XX_NUM_SHADER_BANKS; j++) {
  898. /* Program the aperture */
  899. ptr[qwords++] =
  900. (block->statetype << A5XX_SHADER_STATETYPE_SHIFT) | j;
  901. ptr[qwords++] = (((uint64_t) A5XX_HLSQ_DBG_READ_SEL << 44)) |
  902. (1 << 21) | 1;
  903. /* Read all the data in one chunk */
  904. ptr[qwords++] = registers->gpuaddr + *offset;
  905. ptr[qwords++] =
  906. (((uint64_t) A5XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
  907. block->sz;
  908. /* Remember the offset of the first bank for easy access */
  909. if (j == 0)
  910. block->offset = *offset;
  911. *offset += block->sz * sizeof(unsigned int);
  912. }
  913. return qwords;
  914. }
  915. static int _a5xx_crashdump_init_hlsq(struct a5xx_hlsq_sp_tp_regs *regs,
  916. uint64_t *ptr, uint64_t *offset)
  917. {
  918. int qwords = 0;
  919. /* Program the aperture */
  920. ptr[qwords++] =
  921. (regs->statetype << A5XX_SHADER_STATETYPE_SHIFT);
  922. ptr[qwords++] = (((uint64_t) A5XX_HLSQ_DBG_READ_SEL << 44)) |
  923. (1 << 21) | 1;
  924. /* Read all the data in one chunk */
  925. ptr[qwords++] = registers->gpuaddr + *offset;
  926. ptr[qwords++] =
  927. (((uint64_t) A5XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
  928. regs->size;
  929. /* Remember the offset of the first bank for easy access */
  930. regs->offset = *offset;
  931. *offset += regs->size * sizeof(unsigned int);
  932. return qwords;
  933. }
  934. void a5xx_crashdump_init(struct adreno_device *adreno_dev)
  935. {
  936. struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
  937. unsigned int script_size = 0;
  938. unsigned int data_size = 0;
  939. unsigned int i, j;
  940. uint64_t *ptr;
  941. uint64_t offset = 0;
  942. if (!IS_ERR_OR_NULL(capturescript) && !IS_ERR_OR_NULL(registers))
  943. return;
  944. /*
  945. * We need to allocate two buffers:
  946. * 1 - the buffer to hold the draw script
  947. * 2 - the buffer to hold the data
  948. */
  949. /*
  950. * To save the registers, we need 16 bytes per register pair for the
  951. * script and a dword for each register int the data
  952. */
  953. /* Each pair needs 16 bytes (2 qwords) */
  954. script_size += (ARRAY_SIZE(a5xx_registers) / 2) * 16;
  955. /* Each register needs a dword in the data */
  956. for (j = 0; j < ARRAY_SIZE(a5xx_registers) / 2; j++)
  957. data_size += REG_PAIR_COUNT(a5xx_registers, j) *
  958. sizeof(unsigned int);
  959. if (a5xx_has_gpmu(adreno_dev)) {
  960. /* Each pair needs 16 bytes (2 qwords) */
  961. script_size += (ARRAY_SIZE(a5xx_gpmu_registers) / 2) * 16;
  962. /* Each register needs a dword in the data */
  963. for (j = 0; j < ARRAY_SIZE(a5xx_gpmu_registers) / 2; j++)
  964. data_size += REG_PAIR_COUNT(a5xx_gpmu_registers, j) *
  965. sizeof(unsigned int);
  966. }
  967. /*
  968. * To save the shader blocks for each block in each type we need 32
  969. * bytes for the script (16 bytes to program the aperture and 16 to
  970. * read the data) and then a block specific number of bytes to hold
  971. * the data
  972. */
  973. for (i = 0; i < ARRAY_SIZE(a5xx_shader_blocks); i++) {
  974. script_size += 32 * A5XX_NUM_SHADER_BANKS;
  975. data_size += a5xx_shader_blocks[i].sz * sizeof(unsigned int) *
  976. A5XX_NUM_SHADER_BANKS;
  977. }
  978. for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++) {
  979. script_size += 32;
  980. data_size +=
  981. a5xx_hlsq_sp_tp_registers[i].size * sizeof(unsigned int);
  982. }
  983. /* Now allocate the script and data buffers */
  984. /* The script buffers needs 2 extra qwords on the end */
  985. if (!IS_ERR_OR_NULL(capturescript))
  986. capturescript = kgsl_allocate_global(device,
  987. script_size + 16, 0, KGSL_MEMFLAGS_GPUREADONLY,
  988. KGSL_MEMDESC_PRIVILEGED, "capturescript");
  989. if (IS_ERR(capturescript))
  990. return;
  991. if (!IS_ERR_OR_NULL(registers))
  992. registers = kgsl_allocate_global(device, data_size, 0, 0,
  993. KGSL_MEMDESC_PRIVILEGED, "capturescript_regs");
  994. if (IS_ERR(registers))
  995. return;
  996. /* Build the crash script */
  997. ptr = (uint64_t *) capturescript->hostptr;
  998. /* For the registers, program a read command for each pair */
  999. for (j = 0; j < ARRAY_SIZE(a5xx_registers) / 2; j++) {
  1000. unsigned int r = REG_PAIR_COUNT(a5xx_registers, j);
  1001. *ptr++ = registers->gpuaddr + offset;
  1002. *ptr++ = (((uint64_t) a5xx_registers[2 * j]) << 44)
  1003. | r;
  1004. offset += r * sizeof(unsigned int);
  1005. }
  1006. if (a5xx_has_gpmu(adreno_dev)) {
  1007. for (j = 0; j < ARRAY_SIZE(a5xx_gpmu_registers) / 2; j++) {
  1008. unsigned int r = REG_PAIR_COUNT(a5xx_gpmu_registers, j);
  1009. *ptr++ = registers->gpuaddr + offset;
  1010. *ptr++ = (((uint64_t) a5xx_gpmu_registers[2 * j]) << 44)
  1011. | r;
  1012. offset += r * sizeof(unsigned int);
  1013. }
  1014. }
  1015. /* Program each shader block */
  1016. for (i = 0; i < ARRAY_SIZE(a5xx_shader_blocks); i++) {
  1017. ptr += _a5xx_crashdump_init_shader(&a5xx_shader_blocks[i], ptr,
  1018. &offset);
  1019. }
  1020. /* Program the hlsq sp tp register sets */
  1021. for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_sp_tp_registers); i++)
  1022. ptr += _a5xx_crashdump_init_hlsq(&a5xx_hlsq_sp_tp_registers[i],
  1023. ptr, &offset);
  1024. *ptr++ = 0;
  1025. *ptr++ = 0;
  1026. }