blob: 7d87096b32646601b8887e17a65c1c155243b78d [file] [log] [blame]
Shrenuj Bansal41665402016-12-16 15:25:54 -08001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/io.h>
15#include "kgsl.h"
16#include "adreno.h"
17#include "kgsl_snapshot.h"
18#include "adreno_snapshot.h"
19#include "a6xx_reg.h"
20#include "adreno_a6xx.h"
Kyle Piefer60733aa2017-03-21 11:24:01 -070021#include "kgsl_gmu.h"
Shrenuj Bansal41665402016-12-16 15:25:54 -080022
23#define A6XX_NUM_CTXTS 2
24
25static const unsigned int a6xx_gras_cluster[] = {
26 0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809D, 0x80A0, 0x80A6,
27 0x80AF, 0x80F1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110,
28 0x8400, 0x840B,
29};
30
31static const unsigned int a6xx_ps_cluster[] = {
32 0x8800, 0x8806, 0x8809, 0x8811, 0x8818, 0x881E, 0x8820, 0x8865,
33 0x8870, 0x8879, 0x8880, 0x8889, 0x8890, 0x8891, 0x8898, 0x8898,
34 0x88C0, 0x88c1, 0x88D0, 0x88E3, 0x88F0, 0x88F3, 0x8900, 0x891A,
35 0x8927, 0x8928, 0x8C00, 0x8C01, 0x8C17, 0x8C33, 0x9200, 0x9216,
36 0x9218, 0x9236, 0x9300, 0x9306,
37};
38
39static const unsigned int a6xx_fe_cluster[] = {
40 0x9300, 0x9306, 0x9800, 0x9806, 0x9B00, 0x9B07, 0xA000, 0xA009,
41 0xA00E, 0xA0EF, 0xA0F8, 0xA0F8,
42};
43
44static const unsigned int a6xx_pc_vs_cluster[] = {
45 0x9100, 0x9108, 0x9300, 0x9306, 0x9980, 0x9981, 0x9B00, 0x9B07,
46};
47
48static struct a6xx_cluster_registers {
49 unsigned int id;
50 const unsigned int *regs;
51 unsigned int num_sets;
52 unsigned int offset0;
53 unsigned int offset1;
54} a6xx_clusters[] = {
55 { CP_CLUSTER_GRAS, a6xx_gras_cluster, ARRAY_SIZE(a6xx_gras_cluster)/2 },
56 { CP_CLUSTER_PS, a6xx_ps_cluster, ARRAY_SIZE(a6xx_ps_cluster)/2 },
57 { CP_CLUSTER_FE, a6xx_fe_cluster, ARRAY_SIZE(a6xx_fe_cluster)/2 },
58 { CP_CLUSTER_PC_VS, a6xx_pc_vs_cluster,
59 ARRAY_SIZE(a6xx_pc_vs_cluster)/2 },
60};
61
62struct a6xx_cluster_regs_info {
63 struct a6xx_cluster_registers *cluster;
64 unsigned int ctxt_id;
65};
66
Lynus Vaz461e2382017-01-16 19:35:41 +053067static const unsigned int a6xx_sp_vs_hlsq_cluster[] = {
68 0xB800, 0xB803, 0xB820, 0xB822,
69};
70
71static const unsigned int a6xx_sp_vs_sp_cluster[] = {
72 0xA800, 0xA824, 0xA830, 0xA83C, 0xA840, 0xA864, 0xA870, 0xA895,
73 0xA8A0, 0xA8AF, 0xA8C0, 0xA8C3,
74};
75
76static const unsigned int a6xx_hlsq_duplicate_cluster[] = {
77 0xBB10, 0xBB11, 0xBB20, 0xBB29,
78};
79
80static const unsigned int a6xx_hlsq_2d_duplicate_cluster[] = {
81 0xBD80, 0xBD80,
82};
83
84static const unsigned int a6xx_sp_duplicate_cluster[] = {
85 0xAB00, 0xAB00, 0xAB04, 0xAB05, 0xAB10, 0xAB1B, 0xAB20, 0xAB20,
86};
87
88static const unsigned int a6xx_tp_duplicate_cluster[] = {
89 0xB300, 0xB307, 0xB309, 0xB309, 0xB380, 0xB382,
90};
91
92static const unsigned int a6xx_sp_ps_hlsq_cluster[] = {
93 0xB980, 0xB980, 0xB982, 0xB987, 0xB990, 0xB99B, 0xB9A0, 0xB9A2,
94 0xB9C0, 0xB9C9,
95};
96
97static const unsigned int a6xx_sp_ps_hlsq_2d_cluster[] = {
98 0xBD80, 0xBD80,
99};
100
101static const unsigned int a6xx_sp_ps_sp_cluster[] = {
102 0xA980, 0xA9A8, 0xA9B0, 0xA9BC, 0xA9D0, 0xA9D3, 0xA9E0, 0xA9F3,
103 0xAA00, 0xAA00, 0xAA30, 0xAA31,
104};
105
106static const unsigned int a6xx_sp_ps_sp_2d_cluster[] = {
107 0xACC0, 0xACC0,
108};
109
110static const unsigned int a6xx_sp_ps_tp_cluster[] = {
111 0xB180, 0xB183, 0xB190, 0xB191,
112};
113
114static const unsigned int a6xx_sp_ps_tp_2d_cluster[] = {
115 0xB4C0, 0xB4D1,
116};
117
118static struct a6xx_cluster_dbgahb_registers {
119 unsigned int id;
120 unsigned int regbase;
121 unsigned int statetype;
122 const unsigned int *regs;
123 unsigned int num_sets;
124} a6xx_dbgahb_ctx_clusters[] = {
125 { CP_CLUSTER_SP_VS, 0x0002E000, 0x41, a6xx_sp_vs_hlsq_cluster,
126 ARRAY_SIZE(a6xx_sp_vs_hlsq_cluster) / 2 },
127 { CP_CLUSTER_SP_VS, 0x0002A000, 0x21, a6xx_sp_vs_sp_cluster,
128 ARRAY_SIZE(a6xx_sp_vs_sp_cluster) / 2 },
129 { CP_CLUSTER_SP_VS, 0x0002EC00, 0x41, a6xx_hlsq_duplicate_cluster,
130 ARRAY_SIZE(a6xx_hlsq_duplicate_cluster) / 2 },
131 { CP_CLUSTER_SP_VS, 0x0002F000, 0x45, a6xx_hlsq_2d_duplicate_cluster,
132 ARRAY_SIZE(a6xx_hlsq_2d_duplicate_cluster) / 2 },
133 { CP_CLUSTER_SP_VS, 0x0002AC00, 0x21, a6xx_sp_duplicate_cluster,
134 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
135 { CP_CLUSTER_SP_VS, 0x0002CC00, 0x1, a6xx_tp_duplicate_cluster,
136 ARRAY_SIZE(a6xx_tp_duplicate_cluster) / 2 },
137 { CP_CLUSTER_SP_PS, 0x0002E600, 0x42, a6xx_sp_ps_hlsq_cluster,
138 ARRAY_SIZE(a6xx_sp_ps_hlsq_cluster) / 2 },
139 { CP_CLUSTER_SP_PS, 0x0002F300, 0x46, a6xx_sp_ps_hlsq_2d_cluster,
140 ARRAY_SIZE(a6xx_sp_ps_hlsq_2d_cluster) / 2 },
141 { CP_CLUSTER_SP_PS, 0x0002A600, 0x22, a6xx_sp_ps_sp_cluster,
142 ARRAY_SIZE(a6xx_sp_ps_sp_cluster) / 2 },
143 { CP_CLUSTER_SP_PS, 0x0002B300, 0x26, a6xx_sp_ps_sp_2d_cluster,
144 ARRAY_SIZE(a6xx_sp_ps_sp_2d_cluster) / 2 },
145 { CP_CLUSTER_SP_PS, 0x0002C600, 0x2, a6xx_sp_ps_tp_cluster,
146 ARRAY_SIZE(a6xx_sp_ps_tp_cluster) / 2 },
147 { CP_CLUSTER_SP_PS, 0x0002D300, 0x6, a6xx_sp_ps_tp_2d_cluster,
148 ARRAY_SIZE(a6xx_sp_ps_tp_2d_cluster) / 2 },
149 { CP_CLUSTER_SP_PS, 0x0002EC00, 0x42, a6xx_hlsq_duplicate_cluster,
150 ARRAY_SIZE(a6xx_hlsq_duplicate_cluster) / 2 },
151 { CP_CLUSTER_SP_VS, 0x0002AC00, 0x22, a6xx_sp_duplicate_cluster,
152 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
153 { CP_CLUSTER_SP_VS, 0x0002CC00, 0x2, a6xx_tp_duplicate_cluster,
154 ARRAY_SIZE(a6xx_tp_duplicate_cluster) / 2 },
155};
156
157struct a6xx_cluster_dbgahb_regs_info {
158 struct a6xx_cluster_dbgahb_registers *cluster;
159 unsigned int ctxt_id;
160};
161
162static const unsigned int a6xx_hlsq_non_ctx_registers[] = {
163 0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
164 0xBE20, 0xBE23,
165};
166
167static const unsigned int a6xx_sp_non_ctx_registers[] = {
168 0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
169 0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
170};
171
172static const unsigned int a6xx_tp_non_ctx_registers[] = {
173 0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
174};
175
176static struct a6xx_non_ctx_dbgahb_registers {
177 unsigned int regbase;
178 unsigned int statetype;
179 const unsigned int *regs;
180 unsigned int num_sets;
181} a6xx_non_ctx_dbgahb[] = {
182 { 0x0002F800, 0x40, a6xx_hlsq_non_ctx_registers,
183 ARRAY_SIZE(a6xx_hlsq_non_ctx_registers) / 2 },
184 { 0x0002B800, 0x20, a6xx_sp_non_ctx_registers,
185 ARRAY_SIZE(a6xx_sp_non_ctx_registers) / 2 },
186 { 0x0002D800, 0x0, a6xx_tp_non_ctx_registers,
187 ARRAY_SIZE(a6xx_tp_non_ctx_registers) / 2 },
188};
189
Shrenuj Bansal41665402016-12-16 15:25:54 -0800190static const unsigned int a6xx_vbif_ver_20xxxxxx_registers[] = {
191 /* VBIF */
192 0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302D, 0x3030, 0x3031,
193 0x3034, 0x3036, 0x303C, 0x303D, 0x3040, 0x3040, 0x3042, 0x3042,
194 0x3049, 0x3049, 0x3058, 0x3058, 0x305A, 0x3061, 0x3064, 0x3068,
195 0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094,
196 0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8,
197 0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100,
198 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
199 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x3154, 0x3154,
200 0x3156, 0x3156, 0x3158, 0x3158, 0x315A, 0x315A, 0x315C, 0x315C,
201 0x315E, 0x315E, 0x3160, 0x3160, 0x3162, 0x3162, 0x340C, 0x340C,
202 0x3410, 0x3410, 0x3800, 0x3801,
203};
204
Kyle Piefer60733aa2017-03-21 11:24:01 -0700205static const unsigned int a6xx_gmu_registers[] = {
206 /* GMU */
207 0x1B400, 0x1C3FF, 0x1C400, 0x1D3FF,
208};
209
Shrenuj Bansal41665402016-12-16 15:25:54 -0800210static const struct adreno_vbif_snapshot_registers
211a6xx_vbif_snapshot_registers[] = {
212 { 0x20040000, 0xFF000000, a6xx_vbif_ver_20xxxxxx_registers,
213 ARRAY_SIZE(a6xx_vbif_ver_20xxxxxx_registers)/2},
214};
215
216/*
217 * Set of registers to dump for A6XX on snapshot.
218 * Registers in pairs - first value is the start offset, second
219 * is the stop offset (inclusive)
220 */
221
222static const unsigned int a6xx_registers[] = {
223 /* RBBM */
224 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0014, 0x0014,
225 0x0018, 0x001B, 0x001e, 0x0032, 0x0038, 0x003C, 0x0042, 0x0042,
226 0x0044, 0x0044, 0x0047, 0x0047, 0x0056, 0x0056, 0x00AD, 0x00AE,
227 0x00B0, 0x00FB, 0x0100, 0x011D, 0x0200, 0x020D, 0x0210, 0x0213,
228 0x0218, 0x023D, 0x0400, 0x04F9, 0x0500, 0x0500, 0x0505, 0x050B,
229 0x050E, 0x0511, 0x0533, 0x0533, 0x0540, 0x0555,
230 /* CP */
231 0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0827,
232 0x0830, 0x0833, 0x0840, 0x0843, 0x084F, 0x086F, 0x0880, 0x088A,
233 0x08A0, 0x08AB, 0x08C0, 0x08C4, 0x08D0, 0x08DD, 0x08F0, 0x08F3,
234 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093E, 0x0942, 0x094D,
235 0x0980, 0x0984, 0x098D, 0x0996, 0x0998, 0x099E, 0x09A0, 0x09A6,
236 0x09A8, 0x09AE, 0x09B0, 0x09B1, 0x09C2, 0x09C8, 0x0A00, 0x0A03,
237 /* VSC */
238 0x0C00, 0x0C04, 0x0C06, 0x0C06, 0x0C10, 0x0CD9, 0x0E00, 0x0E0E,
239 /* UCHE */
240 0x0E10, 0x0E13, 0x0E17, 0x0E19, 0x0E1C, 0x0E2B, 0x0E30, 0x0E32,
241 0x0E38, 0x0E39,
242 /* GRAS */
243 0x8600, 0x8601, 0x8604, 0x8605, 0x8610, 0x861B, 0x8620, 0x8620,
244 0x8628, 0x862B, 0x8630, 0x8637,
245 /* RB */
246 0x8E01, 0x8E01, 0x8E04, 0x8E05, 0x8E07, 0x8E08, 0x8E0C, 0x8E0C,
247 0x8E10, 0x8E1C, 0x8E20, 0x8E25, 0x8E28, 0x8E28, 0x8E2C, 0x8E2F,
248 0x8E3B, 0x8E3E, 0x8E40, 0x8E43, 0x8E50, 0x8E5E, 0x8E70, 0x8E77,
249 /* VPC */
250 0x9600, 0x9604, 0x9624, 0x9637,
251 /* PC */
252 0x9E00, 0x9E01, 0x9E03, 0x9E0E, 0x9E11, 0x9E16, 0x9E19, 0x9E19,
253 0x9E1C, 0x9E1C, 0x9E20, 0x9E23, 0x9E30, 0x9E31, 0x9E34, 0x9E34,
254 0x9E70, 0x9E72, 0x9E78, 0x9E79, 0x9E80, 0x9FFF,
255 /* VFD */
256 0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
257 0xA630, 0xA630, 0xD200, 0xD263,
258};
259
Lynus Vaz20c81272017-02-10 16:22:12 +0530260enum a6xx_debugbus_id {
261 A6XX_DBGBUS_CP = 0x1,
262 A6XX_DBGBUS_RBBM = 0x2,
263 A6XX_DBGBUS_VBIF = 0x3,
264 A6XX_DBGBUS_HLSQ = 0x4,
265 A6XX_DBGBUS_UCHE = 0x5,
266 A6XX_DBGBUS_DPM = 0x6,
267 A6XX_DBGBUS_TESS = 0x7,
268 A6XX_DBGBUS_PC = 0x8,
269 A6XX_DBGBUS_VFDP = 0x9,
270 A6XX_DBGBUS_VPC = 0xa,
271 A6XX_DBGBUS_TSE = 0xb,
272 A6XX_DBGBUS_RAS = 0xc,
273 A6XX_DBGBUS_VSC = 0xd,
274 A6XX_DBGBUS_COM = 0xe,
275 A6XX_DBGBUS_LRZ = 0x10,
276 A6XX_DBGBUS_A2D = 0x11,
277 A6XX_DBGBUS_CCUFCHE = 0x12,
278 A6XX_DBGBUS_GMU = 0x13,
279 A6XX_DBGBUS_RBP = 0x14,
280 A6XX_DBGBUS_DCS = 0x15,
281 A6XX_DBGBUS_RBBM_CFG = 0x16,
282 A6XX_DBGBUS_CX = 0x17,
283 A6XX_DBGBUS_TPFCHE = 0x19,
284 A6XX_DBGBUS_GPC = 0x1d,
285 A6XX_DBGBUS_LARC = 0x1e,
286 A6XX_DBGBUS_HLSQ_SPTP = 0x1f,
287 A6XX_DBGBUS_RB_0 = 0x20,
288 A6XX_DBGBUS_RB_1 = 0x21,
289 A6XX_DBGBUS_UCHE_WRAPPER = 0x24,
290 A6XX_DBGBUS_CCU_0 = 0x28,
291 A6XX_DBGBUS_CCU_1 = 0x29,
292 A6XX_DBGBUS_VFD_0 = 0x38,
293 A6XX_DBGBUS_VFD_1 = 0x39,
294 A6XX_DBGBUS_VFD_2 = 0x3a,
295 A6XX_DBGBUS_VFD_3 = 0x3b,
296 A6XX_DBGBUS_SP_0 = 0x40,
297 A6XX_DBGBUS_SP_1 = 0x41,
298 A6XX_DBGBUS_TPL1_0 = 0x48,
299 A6XX_DBGBUS_TPL1_1 = 0x49,
300 A6XX_DBGBUS_TPL1_2 = 0x4a,
301 A6XX_DBGBUS_TPL1_3 = 0x4b,
302};
303
304static const struct adreno_debugbus_block a6xx_dbgc_debugbus_blocks[] = {
305 { A6XX_DBGBUS_CP, 0x100, },
306 { A6XX_DBGBUS_RBBM, 0x100, },
307 { A6XX_DBGBUS_HLSQ, 0x100, },
308 { A6XX_DBGBUS_UCHE, 0x100, },
309 { A6XX_DBGBUS_DPM, 0x100, },
310 { A6XX_DBGBUS_TESS, 0x100, },
311 { A6XX_DBGBUS_PC, 0x100, },
312 { A6XX_DBGBUS_VFDP, 0x100, },
313 { A6XX_DBGBUS_VPC, 0x100, },
314 { A6XX_DBGBUS_TSE, 0x100, },
315 { A6XX_DBGBUS_RAS, 0x100, },
316 { A6XX_DBGBUS_VSC, 0x100, },
317 { A6XX_DBGBUS_COM, 0x100, },
318 { A6XX_DBGBUS_LRZ, 0x100, },
319 { A6XX_DBGBUS_A2D, 0x100, },
320 { A6XX_DBGBUS_CCUFCHE, 0x100, },
321 { A6XX_DBGBUS_RBP, 0x100, },
322 { A6XX_DBGBUS_DCS, 0x100, },
323 { A6XX_DBGBUS_RBBM_CFG, 0x100, },
324 { A6XX_DBGBUS_TPFCHE, 0x100, },
325 { A6XX_DBGBUS_GPC, 0x100, },
326 { A6XX_DBGBUS_LARC, 0x100, },
327 { A6XX_DBGBUS_HLSQ_SPTP, 0x100, },
328 { A6XX_DBGBUS_RB_0, 0x100, },
329 { A6XX_DBGBUS_RB_1, 0x100, },
330 { A6XX_DBGBUS_UCHE_WRAPPER, 0x100, },
331 { A6XX_DBGBUS_CCU_0, 0x100, },
332 { A6XX_DBGBUS_CCU_1, 0x100, },
333 { A6XX_DBGBUS_VFD_0, 0x100, },
334 { A6XX_DBGBUS_VFD_1, 0x100, },
335 { A6XX_DBGBUS_VFD_2, 0x100, },
336 { A6XX_DBGBUS_VFD_3, 0x100, },
337 { A6XX_DBGBUS_SP_0, 0x100, },
338 { A6XX_DBGBUS_SP_1, 0x100, },
339 { A6XX_DBGBUS_TPL1_0, 0x100, },
340 { A6XX_DBGBUS_TPL1_1, 0x100, },
341 { A6XX_DBGBUS_TPL1_2, 0x100, },
342 { A6XX_DBGBUS_TPL1_3, 0x100, },
343};
Shrenuj Bansal41665402016-12-16 15:25:54 -0800344
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530345#define A6XX_NUM_SHADER_BANKS 3
346#define A6XX_SHADER_STATETYPE_SHIFT 8
347
348enum a6xx_shader_obj {
349 A6XX_TP0_TMO_DATA = 0x9,
350 A6XX_TP0_SMO_DATA = 0xa,
351 A6XX_TP0_MIPMAP_BASE_DATA = 0xb,
352 A6XX_TP1_TMO_DATA = 0x19,
353 A6XX_TP1_SMO_DATA = 0x1a,
354 A6XX_TP1_MIPMAP_BASE_DATA = 0x1b,
355 A6XX_SP_INST_DATA = 0x29,
356 A6XX_SP_LB_0_DATA = 0x2a,
357 A6XX_SP_LB_1_DATA = 0x2b,
358 A6XX_SP_LB_2_DATA = 0x2c,
359 A6XX_SP_LB_3_DATA = 0x2d,
360 A6XX_SP_LB_4_DATA = 0x2e,
361 A6XX_SP_LB_5_DATA = 0x2f,
362 A6XX_SP_CB_BINDLESS_DATA = 0x30,
363 A6XX_SP_CB_LEGACY_DATA = 0x31,
364 A6XX_SP_UAV_DATA = 0x32,
365 A6XX_SP_INST_TAG = 0x33,
366 A6XX_SP_CB_BINDLESS_TAG = 0x34,
367 A6XX_SP_TMO_UMO_TAG = 0x35,
368 A6XX_SP_SMO_TAG = 0x36,
369 A6XX_SP_STATE_DATA = 0x37,
370 A6XX_HLSQ_CHUNK_CVS_RAM = 0x49,
371 A6XX_HLSQ_CHUNK_CPS_RAM = 0x4a,
372 A6XX_HLSQ_CHUNK_CVS_RAM_TAG = 0x4b,
373 A6XX_HLSQ_CHUNK_CPS_RAM_TAG = 0x4c,
374 A6XX_HLSQ_ICB_CVS_CB_BASE_TAG = 0x4d,
375 A6XX_HLSQ_ICB_CPS_CB_BASE_TAG = 0x4e,
376 A6XX_HLSQ_CVS_MISC_RAM = 0x50,
377 A6XX_HLSQ_CPS_MISC_RAM = 0x51,
378 A6XX_HLSQ_INST_RAM = 0x52,
379 A6XX_HLSQ_GFX_CVS_CONST_RAM = 0x53,
380 A6XX_HLSQ_GFX_CPS_CONST_RAM = 0x54,
381 A6XX_HLSQ_CVS_MISC_RAM_TAG = 0x55,
382 A6XX_HLSQ_CPS_MISC_RAM_TAG = 0x56,
383 A6XX_HLSQ_INST_RAM_TAG = 0x57,
384 A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG = 0x58,
385 A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG = 0x59,
386 A6XX_HLSQ_PWR_REST_RAM = 0x5a,
387 A6XX_HLSQ_PWR_REST_TAG = 0x5b,
388 A6XX_HLSQ_DATAPATH_META = 0x60,
389 A6XX_HLSQ_FRONTEND_META = 0x61,
390 A6XX_HLSQ_INDIRECT_META = 0x62,
391 A6XX_HLSQ_BACKEND_META = 0x63
392};
393
394struct a6xx_shader_block {
395 unsigned int statetype;
396 unsigned int sz;
397 uint64_t offset;
398};
399
400struct a6xx_shader_block_info {
401 struct a6xx_shader_block *block;
402 unsigned int bank;
403 uint64_t offset;
404};
405
406static struct a6xx_shader_block a6xx_shader_blocks[] = {
407 {A6XX_TP0_TMO_DATA, 0x200},
408 {A6XX_TP0_SMO_DATA, 0x80,},
409 {A6XX_TP0_MIPMAP_BASE_DATA, 0x3C0},
410 {A6XX_TP1_TMO_DATA, 0x200},
411 {A6XX_TP1_SMO_DATA, 0x80,},
412 {A6XX_TP1_MIPMAP_BASE_DATA, 0x3C0},
413 {A6XX_SP_INST_DATA, 0x800},
414 {A6XX_SP_LB_0_DATA, 0x800},
415 {A6XX_SP_LB_1_DATA, 0x800},
416 {A6XX_SP_LB_2_DATA, 0x800},
417 {A6XX_SP_LB_3_DATA, 0x800},
418 {A6XX_SP_LB_4_DATA, 0x800},
419 {A6XX_SP_LB_5_DATA, 0x200},
420 {A6XX_SP_CB_BINDLESS_DATA, 0x2000},
421 {A6XX_SP_CB_LEGACY_DATA, 0x280,},
422 {A6XX_SP_UAV_DATA, 0x80,},
423 {A6XX_SP_INST_TAG, 0x80,},
424 {A6XX_SP_CB_BINDLESS_TAG, 0x80,},
425 {A6XX_SP_TMO_UMO_TAG, 0x80,},
426 {A6XX_SP_SMO_TAG, 0x80},
427 {A6XX_SP_STATE_DATA, 0x3F},
428 {A6XX_HLSQ_CHUNK_CVS_RAM, 0x1C0},
429 {A6XX_HLSQ_CHUNK_CPS_RAM, 0x280},
430 {A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40,},
431 {A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40,},
432 {A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4,},
433 {A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4,},
434 {A6XX_HLSQ_CVS_MISC_RAM, 0x1C0},
435 {A6XX_HLSQ_CPS_MISC_RAM, 0x580},
436 {A6XX_HLSQ_INST_RAM, 0x800},
437 {A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800},
438 {A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800},
439 {A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8,},
440 {A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4,},
441 {A6XX_HLSQ_INST_RAM_TAG, 0x80,},
442 {A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xC,},
443 {A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10},
444 {A6XX_HLSQ_PWR_REST_RAM, 0x28},
445 {A6XX_HLSQ_PWR_REST_TAG, 0x14},
446 {A6XX_HLSQ_DATAPATH_META, 0x40,},
447 {A6XX_HLSQ_FRONTEND_META, 0x40},
448 {A6XX_HLSQ_INDIRECT_META, 0x40,}
449};
450
Shrenuj Bansal41665402016-12-16 15:25:54 -0800451static struct kgsl_memdesc a6xx_capturescript;
452static struct kgsl_memdesc a6xx_crashdump_registers;
453static bool crash_dump_valid;
454
455static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
456 u8 *buf, size_t remain)
457{
458 struct kgsl_snapshot_registers regs = {
459 .regs = a6xx_registers,
460 .count = ARRAY_SIZE(a6xx_registers) / 2,
461 };
462
463 return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
464}
465
466static struct cdregs {
467 const unsigned int *regs;
468 unsigned int size;
469} _a6xx_cd_registers[] = {
470 { a6xx_registers, ARRAY_SIZE(a6xx_registers) },
471};
472
473#define REG_PAIR_COUNT(_a, _i) \
474 (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
475
476static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
477 size_t remain, void *priv)
478{
479 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
480 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
481 unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
482 unsigned int i, j, k;
483 unsigned int count = 0;
484
485 if (crash_dump_valid == false)
486 return a6xx_legacy_snapshot_registers(device, buf, remain);
487
488 if (remain < sizeof(*header)) {
489 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
490 return 0;
491 }
492
493 remain -= sizeof(*header);
494
495 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
496 struct cdregs *regs = &_a6xx_cd_registers[i];
497
498 for (j = 0; j < regs->size / 2; j++) {
499 unsigned int start = regs->regs[2 * j];
500 unsigned int end = regs->regs[(2 * j) + 1];
501
502 if (remain < ((end - start) + 1) * 8) {
503 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
504 goto out;
505 }
506
507 remain -= ((end - start) + 1) * 8;
508
509 for (k = start; k <= end; k++, count++) {
510 *data++ = k;
511 *data++ = *src++;
512 }
513 }
514 }
515
516out:
517 header->count = count;
518
519 /* Return the size of the section */
520 return (count * 8) + sizeof(*header);
521}
522
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530523static size_t a6xx_snapshot_shader_memory(struct kgsl_device *device,
524 u8 *buf, size_t remain, void *priv)
525{
526 struct kgsl_snapshot_shader *header =
527 (struct kgsl_snapshot_shader *) buf;
528 struct a6xx_shader_block_info *info =
529 (struct a6xx_shader_block_info *) priv;
530 struct a6xx_shader_block *block = info->block;
531 unsigned int *data = (unsigned int *) (buf + sizeof(*header));
532
533 if (remain < SHADER_SECTION_SZ(block->sz)) {
534 SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
535 return 0;
536 }
537
538 header->type = block->statetype;
539 header->index = info->bank;
540 header->size = block->sz;
541
542 memcpy(data, a6xx_crashdump_registers.hostptr + info->offset,
543 block->sz);
544
545 return SHADER_SECTION_SZ(block->sz);
546}
547
548static void a6xx_snapshot_shader(struct kgsl_device *device,
549 struct kgsl_snapshot *snapshot)
550{
551 unsigned int i, j;
552 struct a6xx_shader_block_info info;
553
554 /* Shader blocks can only be read by the crash dumper */
555 if (crash_dump_valid == false)
556 return;
557
558 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
559 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
560 info.block = &a6xx_shader_blocks[i];
561 info.bank = j;
562 info.offset = a6xx_shader_blocks[i].offset +
563 (j * a6xx_shader_blocks[i].sz);
564
565 /* Shader working/shadow memory */
566 kgsl_snapshot_add_section(device,
567 KGSL_SNAPSHOT_SECTION_SHADER,
568 snapshot, a6xx_snapshot_shader_memory, &info);
569 }
570 }
571}
572
Lynus Vaza5922742017-03-14 18:50:54 +0530573static void a6xx_snapshot_mempool(struct kgsl_device *device,
574 struct kgsl_snapshot *snapshot)
575{
576 unsigned int pool_size;
577
578 /* Save the mempool size to 0 to stabilize it while dumping */
579 kgsl_regread(device, A6XX_CP_MEM_POOL_SIZE, &pool_size);
580 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, 0);
581
582 kgsl_snapshot_indexed_registers(device, snapshot,
583 A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
584 0, 0x2060);
585
586 /* Restore the saved mempool size */
587 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, pool_size);
588}
589
Lynus Vaz461e2382017-01-16 19:35:41 +0530590static inline unsigned int a6xx_read_dbgahb(struct kgsl_device *device,
591 unsigned int regbase, unsigned int reg)
592{
593 unsigned int read_reg = A6XX_HLSQ_DBG_AHB_READ_APERTURE +
594 reg - regbase / 4;
595 unsigned int val;
596
597 kgsl_regread(device, read_reg, &val);
598 return val;
599}
600
601static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf,
602 size_t remain, void *priv)
603{
604 struct kgsl_snapshot_mvc_regs *header =
605 (struct kgsl_snapshot_mvc_regs *)buf;
606 struct a6xx_cluster_dbgahb_regs_info *info =
607 (struct a6xx_cluster_dbgahb_regs_info *)priv;
608 struct a6xx_cluster_dbgahb_registers *cur_cluster = info->cluster;
609 unsigned int read_sel;
610 unsigned int data_size = 0;
611 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
612 int i, j;
613
614 if (remain < sizeof(*header)) {
615 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
616 return 0;
617 }
618
619 remain -= sizeof(*header);
620
621 header->ctxt_id = info->ctxt_id;
622 header->cluster_id = cur_cluster->id;
623
624 read_sel = ((cur_cluster->statetype + info->ctxt_id * 2) & 0xff) << 8;
625 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
626
627 for (i = 0; i < cur_cluster->num_sets; i++) {
628 unsigned int start = cur_cluster->regs[2 * i];
629 unsigned int end = cur_cluster->regs[2 * i + 1];
630
631 if (remain < (end - start + 3) * 4) {
632 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
633 goto out;
634 }
635
636 remain -= (end - start + 3) * 4;
637 data_size += (end - start + 3) * 4;
638
639 *data++ = start | (1 << 31);
640 *data++ = end;
641
642 for (j = start; j <= end; j++) {
643 unsigned int val;
644
645 val = a6xx_read_dbgahb(device, cur_cluster->regbase, j);
646 *data++ = val;
647
648 }
649 }
650
651out:
652 return data_size + sizeof(*header);
653}
654
655static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
656 size_t remain, void *priv)
657{
658 struct kgsl_snapshot_regs *header =
659 (struct kgsl_snapshot_regs *)buf;
660 struct a6xx_non_ctx_dbgahb_registers *regs =
661 (struct a6xx_non_ctx_dbgahb_registers *)priv;
662 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
663 int count = 0;
664 unsigned int read_sel;
665 int i, j;
666
667 /* Figure out how many registers we are going to dump */
668 for (i = 0; i < regs->num_sets; i++) {
669 int start = regs->regs[i * 2];
670 int end = regs->regs[i * 2 + 1];
671
672 count += (end - start + 1);
673 }
674
675 if (remain < (count * 8) + sizeof(*header)) {
676 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
677 return 0;
678 }
679
680 header->count = count;
681
682 read_sel = (regs->statetype & 0xff) << 8;
683 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
684
685 for (i = 0; i < regs->num_sets; i++) {
686 unsigned int start = regs->regs[2 * i];
687 unsigned int end = regs->regs[2 * i + 1];
688
689 for (j = start; j <= end; j++) {
690 unsigned int val;
691
692 val = a6xx_read_dbgahb(device, regs->regbase, j);
693 *data++ = j;
694 *data++ = val;
695
696 }
697 }
698 return (count * 8) + sizeof(*header);
699}
700
701static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
702 struct kgsl_snapshot *snapshot)
703{
704 int i, j;
705
706 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
707 struct a6xx_cluster_dbgahb_registers *cluster =
708 &a6xx_dbgahb_ctx_clusters[i];
709 struct a6xx_cluster_dbgahb_regs_info info;
710
711 info.cluster = cluster;
712 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
713 info.ctxt_id = j;
714
715 kgsl_snapshot_add_section(device,
716 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
717 a6xx_snapshot_cluster_dbgahb, &info);
718 }
719 }
720
721 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
722 kgsl_snapshot_add_section(device,
723 KGSL_SNAPSHOT_SECTION_REGS, snapshot,
724 a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
725 }
726}
727
Shrenuj Bansal41665402016-12-16 15:25:54 -0800728static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
729 size_t remain, void *priv)
730{
731 struct kgsl_snapshot_mvc_regs *header =
732 (struct kgsl_snapshot_mvc_regs *)buf;
733 struct a6xx_cluster_regs_info *info =
734 (struct a6xx_cluster_regs_info *)priv;
735 struct a6xx_cluster_registers *cur_cluster = info->cluster;
736 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
737 unsigned int ctxt = info->ctxt_id;
738 unsigned int start, end, i, j, aperture_cntl = 0;
739 unsigned int data_size = 0;
740
741 if (remain < sizeof(*header)) {
742 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
743 return 0;
744 }
745
746 remain -= sizeof(*header);
747
748 header->ctxt_id = info->ctxt_id;
749 header->cluster_id = cur_cluster->id;
750
751 /*
752 * Set the AHB control for the Host to read from the
753 * cluster/context for this iteration.
754 */
755 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
756 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
757
758 for (i = 0; i < cur_cluster->num_sets; i++) {
759 start = cur_cluster->regs[2 * i];
760 end = cur_cluster->regs[2 * i + 1];
761
762 if (remain < (end - start + 3) * 4) {
763 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
764 goto out;
765 }
766
767 remain -= (end - start + 3) * 4;
768 data_size += (end - start + 3) * 4;
769
770 *data++ = start | (1 << 31);
771 *data++ = end;
772 for (j = start; j <= end; j++) {
773 unsigned int val;
774
775 kgsl_regread(device, j, &val);
776 *data++ = val;
777 }
778 }
779out:
780 return data_size + sizeof(*header);
781}
782
783static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
784 size_t remain, void *priv)
785{
786 struct kgsl_snapshot_mvc_regs *header =
787 (struct kgsl_snapshot_mvc_regs *)buf;
788 struct a6xx_cluster_regs_info *info =
789 (struct a6xx_cluster_regs_info *)priv;
790 struct a6xx_cluster_registers *cluster = info->cluster;
791 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
792 unsigned int *src;
793 int i, j;
794 unsigned int start, end;
795 size_t data_size = 0;
796
797 if (crash_dump_valid == false)
798 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
799
800 if (remain < sizeof(*header)) {
801 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
802 return 0;
803 }
804
805 remain -= sizeof(*header);
806
807 header->ctxt_id = info->ctxt_id;
808 header->cluster_id = cluster->id;
809
810 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
811 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
812
813 for (i = 0; i < cluster->num_sets; i++) {
814 start = cluster->regs[2 * i];
815 end = cluster->regs[2 * i + 1];
816
817 if (remain < (end - start + 3) * 4) {
818 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
819 goto out;
820 }
821
822 remain -= (end - start + 3) * 4;
823 data_size += (end - start + 3) * 4;
824
825 *data++ = start | (1 << 31);
826 *data++ = end;
827 for (j = start; j <= end; j++)
828 *data++ = *src++;
829 }
830
831out:
832 return data_size + sizeof(*header);
833
834}
835
836static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
837 struct kgsl_snapshot *snapshot)
838{
839 int i, j;
840 struct a6xx_cluster_regs_info info;
841
842 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
843 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
844
845 info.cluster = cluster;
846 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
847 info.ctxt_id = j;
848
849 kgsl_snapshot_add_section(device,
850 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
851 a6xx_snapshot_mvc, &info);
852 }
853 }
854}
855
Lynus Vaz20c81272017-02-10 16:22:12 +0530856/* a6xx_dbgc_debug_bus_read() - Read data from trace bus */
857static void a6xx_dbgc_debug_bus_read(struct kgsl_device *device,
858 unsigned int block_id, unsigned int index, unsigned int *val)
859{
860 unsigned int reg;
861
862 reg = (block_id << A6XX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
863 (index << A6XX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
864
865 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
866 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
867 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
868 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
869
870 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
871 val++;
872 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
873}
874
875/* a6xx_snapshot_cbgc_debugbus_block() - Capture debug data for a gpu block */
876static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
877 u8 *buf, size_t remain, void *priv)
878{
879 struct kgsl_snapshot_debugbus *header =
880 (struct kgsl_snapshot_debugbus *)buf;
881 struct adreno_debugbus_block *block = priv;
882 int i;
883 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
884 unsigned int dwords;
885 size_t size;
886
887 dwords = block->dwords;
888
889 /* For a6xx each debug bus data unit is 2 DWORDS */
890 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
891
892 if (remain < size) {
893 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
894 return 0;
895 }
896
897 header->id = block->block_id;
898 header->count = dwords * 2;
899
900 for (i = 0; i < dwords; i++)
901 a6xx_dbgc_debug_bus_read(device, block->block_id, i,
902 &data[i*2]);
903
904 return size;
905}
906
907/* a6xx_snapshot_debugbus() - Capture debug bus data */
908static void a6xx_snapshot_debugbus(struct kgsl_device *device,
909 struct kgsl_snapshot *snapshot)
910{
911 int i;
912
913 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
914 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
915 (0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
916 (0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
917
918 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLM,
919 0xf << A6XX_DBGC_CFG_DBGBUS_CTLTM_ENABLE_SHIFT);
920
921 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
922 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
923 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
924 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
925
926 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_0,
927 (0 << A6XX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
928 (1 << A6XX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
929 (2 << A6XX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
930 (3 << A6XX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
931 (4 << A6XX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
932 (5 << A6XX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
933 (6 << A6XX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
934 (7 << A6XX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
935 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_1,
936 (8 << A6XX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
937 (9 << A6XX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
938 (10 << A6XX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
939 (11 << A6XX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
940 (12 << A6XX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
941 (13 << A6XX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
942 (14 << A6XX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
943 (15 << A6XX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
944
945 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
946 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
947 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
948 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
949
950 for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
951 kgsl_snapshot_add_section(device,
952 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
953 snapshot, a6xx_snapshot_dbgc_debugbus_block,
954 (void *) &a6xx_dbgc_debugbus_blocks[i]);
955 }
956}
957
Kyle Piefer60733aa2017-03-21 11:24:01 -0700958static size_t a6xx_snapshot_dump_gmu_registers(struct kgsl_device *device,
959 u8 *buf, size_t remain, void *priv)
960{
961 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
962 struct kgsl_snapshot_registers *regs = priv;
963 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
964 int count = 0, j, k;
965
966 /* Figure out how many registers we are going to dump */
967 for (j = 0; j < regs->count; j++) {
968 int start = regs->regs[j * 2];
969 int end = regs->regs[j * 2 + 1];
970
971 count += (end - start + 1);
972 }
973
974 if (remain < (count * 8) + sizeof(*header)) {
975 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
976 return 0;
977 }
978
979 for (j = 0; j < regs->count; j++) {
980 unsigned int start = regs->regs[j * 2];
981 unsigned int end = regs->regs[j * 2 + 1];
982
983 for (k = start; k <= end; k++) {
984 unsigned int val;
985
986 kgsl_gmu_regread(device, k, &val);
987 *data++ = k;
988 *data++ = val;
989 }
990 }
991
992 header->count = count;
993
994 /* Return the size of the section */
995 return (count * 8) + sizeof(*header);
996}
997
998static void a6xx_snapshot_gmu(struct kgsl_device *device,
999 struct kgsl_snapshot *snapshot)
1000{
1001 struct kgsl_snapshot_registers gmu_regs = {
1002 .regs = a6xx_gmu_registers,
1003 .count = ARRAY_SIZE(a6xx_gmu_registers) / 2,
1004 };
1005
1006 if (!kgsl_gmu_isenabled(device))
1007 return;
1008
1009 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1010 snapshot, a6xx_snapshot_dump_gmu_registers, &gmu_regs);
1011}
1012
Shrenuj Bansal41665402016-12-16 15:25:54 -08001013static void _a6xx_do_crashdump(struct kgsl_device *device)
1014{
1015 unsigned long wait_time;
1016 unsigned int reg = 0;
1017 unsigned int val;
1018
1019 crash_dump_valid = false;
1020
1021 if (a6xx_capturescript.gpuaddr == 0 ||
1022 a6xx_crashdump_registers.gpuaddr == 0)
1023 return;
1024
1025 /* IF the SMMU is stalled we cannot do a crash dump */
1026 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
1027 if (val & BIT(24))
1028 return;
1029
1030 /* Turn on APRIV so we can access the buffers */
1031 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
1032
1033 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
1034 lower_32_bits(a6xx_capturescript.gpuaddr));
1035 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
1036 upper_32_bits(a6xx_capturescript.gpuaddr));
1037 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
1038
1039 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
1040 while (!time_after(jiffies, wait_time)) {
1041 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
1042 if (reg & 0x2)
1043 break;
1044 cpu_relax();
1045 }
1046
1047 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
1048
1049 if (!(reg & 0x2)) {
1050 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
1051 return;
1052 }
1053
1054 crash_dump_valid = true;
1055}
1056
1057/*
1058 * a6xx_snapshot() - A6XX GPU snapshot function
1059 * @adreno_dev: Device being snapshotted
1060 * @snapshot: Pointer to the snapshot instance
1061 *
1062 * This is where all of the A6XX specific bits and pieces are grabbed
1063 * into the snapshot memory
1064 */
1065void a6xx_snapshot(struct adreno_device *adreno_dev,
1066 struct kgsl_snapshot *snapshot)
1067{
1068 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1069 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
1070 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
1071
1072 /* Try to run the crash dumper */
1073 _a6xx_do_crashdump(device);
1074
1075 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1076 snapshot, a6xx_snapshot_registers, NULL);
1077
1078 adreno_snapshot_vbif_registers(device, snapshot,
1079 a6xx_vbif_snapshot_registers,
1080 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
1081
1082 /* CP_SQE indexed registers */
1083 kgsl_snapshot_indexed_registers(device, snapshot,
1084 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
1085 0, snap_data->sect_sizes->cp_pfp);
1086
1087 /* CP_DRAW_STATE */
1088 kgsl_snapshot_indexed_registers(device, snapshot,
1089 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
1090 0, 0x100);
1091
1092 /* SQE_UCODE Cache */
1093 kgsl_snapshot_indexed_registers(device, snapshot,
1094 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
1095 0, 0x6000);
1096
1097 /* CP ROQ */
1098 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1099 snapshot, adreno_snapshot_cp_roq,
1100 &snap_data->sect_sizes->roq);
1101
Lynus Vaza5922742017-03-14 18:50:54 +05301102 /* Mempool debug data */
1103 a6xx_snapshot_mempool(device, snapshot);
1104
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301105 /* Shader memory */
1106 a6xx_snapshot_shader(device, snapshot);
1107
Shrenuj Bansal41665402016-12-16 15:25:54 -08001108 /* MVC register section */
1109 a6xx_snapshot_mvc_regs(device, snapshot);
1110
Lynus Vaz461e2382017-01-16 19:35:41 +05301111 /* registers dumped through DBG AHB */
1112 a6xx_snapshot_dbgahb_regs(device, snapshot);
1113
Lynus Vaz20c81272017-02-10 16:22:12 +05301114 a6xx_snapshot_debugbus(device, snapshot);
Kyle Piefer60733aa2017-03-21 11:24:01 -07001115
1116 /* GMU TCM data dumped through AHB */
1117 a6xx_snapshot_gmu(device, snapshot);
Shrenuj Bansal41665402016-12-16 15:25:54 -08001118}
1119
1120static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
1121{
1122 int qwords = 0;
1123 unsigned int i, j, k;
1124 unsigned int count;
1125
1126 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1127 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1128
1129 cluster->offset0 = *offset;
1130 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1131
1132 if (j == 1)
1133 cluster->offset1 = *offset;
1134
1135 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
1136 ptr[qwords++] =
1137 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
1138 (1 << 21) | 1;
1139
1140 for (k = 0; k < cluster->num_sets; k++) {
1141 count = REG_PAIR_COUNT(cluster->regs, k);
1142 ptr[qwords++] =
1143 a6xx_crashdump_registers.gpuaddr + *offset;
1144 ptr[qwords++] =
1145 (((uint64_t)cluster->regs[2 * k]) << 44) |
1146 count;
1147
1148 *offset += count * sizeof(unsigned int);
1149 }
1150 }
1151 }
1152
1153 return qwords;
1154}
1155
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301156static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block,
1157 uint64_t *ptr, uint64_t *offset)
1158{
1159 int qwords = 0;
1160 unsigned int j;
1161
1162 /* Capture each bank in the block */
1163 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
1164 /* Program the aperture */
1165 ptr[qwords++] =
1166 (block->statetype << A6XX_SHADER_STATETYPE_SHIFT) | j;
1167 ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_READ_SEL << 44)) |
1168 (1 << 21) | 1;
1169
1170 /* Read all the data in one chunk */
1171 ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset;
1172 ptr[qwords++] =
1173 (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
1174 block->sz;
1175
1176 /* Remember the offset of the first bank for easy access */
1177 if (j == 0)
1178 block->offset = *offset;
1179
1180 *offset += block->sz * sizeof(unsigned int);
1181 }
1182
1183 return qwords;
1184}
1185
Shrenuj Bansal41665402016-12-16 15:25:54 -08001186void a6xx_crashdump_init(struct adreno_device *adreno_dev)
1187{
1188 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1189 unsigned int script_size = 0;
1190 unsigned int data_size = 0;
1191 unsigned int i, j, k;
1192 uint64_t *ptr;
1193 uint64_t offset = 0;
1194
1195 if (a6xx_capturescript.gpuaddr != 0 &&
1196 a6xx_crashdump_registers.gpuaddr != 0)
1197 return;
1198
1199 /*
1200 * We need to allocate two buffers:
1201 * 1 - the buffer to hold the draw script
1202 * 2 - the buffer to hold the data
1203 */
1204
1205 /*
1206 * To save the registers, we need 16 bytes per register pair for the
1207 * script and a dword for each register in the data
1208 */
1209 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1210 struct cdregs *regs = &_a6xx_cd_registers[i];
1211
1212 /* Each pair needs 16 bytes (2 qwords) */
1213 script_size += (regs->size / 2) * 16;
1214
1215 /* Each register needs a dword in the data */
1216 for (j = 0; j < regs->size / 2; j++)
1217 data_size += REG_PAIR_COUNT(regs->regs, j) *
1218 sizeof(unsigned int);
1219
1220 }
1221
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301222 /*
1223 * To save the shader blocks for each block in each type we need 32
1224 * bytes for the script (16 bytes to program the aperture and 16 to
1225 * read the data) and then a block specific number of bytes to hold
1226 * the data
1227 */
1228 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1229 script_size += 32 * A6XX_NUM_SHADER_BANKS;
1230 data_size += a6xx_shader_blocks[i].sz * sizeof(unsigned int) *
1231 A6XX_NUM_SHADER_BANKS;
1232 }
1233
Shrenuj Bansal41665402016-12-16 15:25:54 -08001234 /* Calculate the script and data size for MVC registers */
1235 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1236 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1237
1238 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1239
1240 /* 16 bytes for programming the aperture */
1241 script_size += 16;
1242
1243 /* Reading each pair of registers takes 16 bytes */
1244 script_size += 16 * cluster->num_sets;
1245
1246 /* A dword per register read from the cluster list */
1247 for (k = 0; k < cluster->num_sets; k++)
1248 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1249 sizeof(unsigned int);
1250 }
1251 }
1252
1253 /* Now allocate the script and data buffers */
1254
1255 /* The script buffers needs 2 extra qwords on the end */
1256 if (kgsl_allocate_global(device, &a6xx_capturescript,
1257 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
1258 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
1259 return;
1260
1261 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
1262 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
1263 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
1264 return;
1265 }
1266
1267 /* Build the crash script */
1268
1269 ptr = (uint64_t *)a6xx_capturescript.hostptr;
1270
1271 /* For the registers, program a read command for each pair */
1272 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1273 struct cdregs *regs = &_a6xx_cd_registers[i];
1274
1275 for (j = 0; j < regs->size / 2; j++) {
1276 unsigned int r = REG_PAIR_COUNT(regs->regs, j);
1277 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
1278 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
1279 offset += r * sizeof(unsigned int);
1280 }
1281 }
1282
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301283 /* Program each shader block */
1284 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1285 ptr += _a6xx_crashdump_init_shader(&a6xx_shader_blocks[i], ptr,
1286 &offset);
1287 }
1288
Shrenuj Bansal41665402016-12-16 15:25:54 -08001289 /* Program the capturescript for the MVC regsiters */
1290 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
1291
1292 *ptr++ = 0;
1293 *ptr++ = 0;
1294}