blob: e82975e6a5aa6b00bae71bb4caab1b4f3c38fdb4 [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"
21
22
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
205static const struct adreno_vbif_snapshot_registers
206a6xx_vbif_snapshot_registers[] = {
207 { 0x20040000, 0xFF000000, a6xx_vbif_ver_20xxxxxx_registers,
208 ARRAY_SIZE(a6xx_vbif_ver_20xxxxxx_registers)/2},
209};
210
211/*
212 * Set of registers to dump for A6XX on snapshot.
213 * Registers in pairs - first value is the start offset, second
214 * is the stop offset (inclusive)
215 */
216
217static const unsigned int a6xx_registers[] = {
218 /* RBBM */
219 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0014, 0x0014,
220 0x0018, 0x001B, 0x001e, 0x0032, 0x0038, 0x003C, 0x0042, 0x0042,
221 0x0044, 0x0044, 0x0047, 0x0047, 0x0056, 0x0056, 0x00AD, 0x00AE,
222 0x00B0, 0x00FB, 0x0100, 0x011D, 0x0200, 0x020D, 0x0210, 0x0213,
223 0x0218, 0x023D, 0x0400, 0x04F9, 0x0500, 0x0500, 0x0505, 0x050B,
224 0x050E, 0x0511, 0x0533, 0x0533, 0x0540, 0x0555,
225 /* CP */
226 0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0827,
227 0x0830, 0x0833, 0x0840, 0x0843, 0x084F, 0x086F, 0x0880, 0x088A,
228 0x08A0, 0x08AB, 0x08C0, 0x08C4, 0x08D0, 0x08DD, 0x08F0, 0x08F3,
229 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093E, 0x0942, 0x094D,
230 0x0980, 0x0984, 0x098D, 0x0996, 0x0998, 0x099E, 0x09A0, 0x09A6,
231 0x09A8, 0x09AE, 0x09B0, 0x09B1, 0x09C2, 0x09C8, 0x0A00, 0x0A03,
232 /* VSC */
233 0x0C00, 0x0C04, 0x0C06, 0x0C06, 0x0C10, 0x0CD9, 0x0E00, 0x0E0E,
234 /* UCHE */
235 0x0E10, 0x0E13, 0x0E17, 0x0E19, 0x0E1C, 0x0E2B, 0x0E30, 0x0E32,
236 0x0E38, 0x0E39,
237 /* GRAS */
238 0x8600, 0x8601, 0x8604, 0x8605, 0x8610, 0x861B, 0x8620, 0x8620,
239 0x8628, 0x862B, 0x8630, 0x8637,
240 /* RB */
241 0x8E01, 0x8E01, 0x8E04, 0x8E05, 0x8E07, 0x8E08, 0x8E0C, 0x8E0C,
242 0x8E10, 0x8E1C, 0x8E20, 0x8E25, 0x8E28, 0x8E28, 0x8E2C, 0x8E2F,
243 0x8E3B, 0x8E3E, 0x8E40, 0x8E43, 0x8E50, 0x8E5E, 0x8E70, 0x8E77,
244 /* VPC */
245 0x9600, 0x9604, 0x9624, 0x9637,
246 /* PC */
247 0x9E00, 0x9E01, 0x9E03, 0x9E0E, 0x9E11, 0x9E16, 0x9E19, 0x9E19,
248 0x9E1C, 0x9E1C, 0x9E20, 0x9E23, 0x9E30, 0x9E31, 0x9E34, 0x9E34,
249 0x9E70, 0x9E72, 0x9E78, 0x9E79, 0x9E80, 0x9FFF,
250 /* VFD */
251 0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
252 0xA630, 0xA630, 0xD200, 0xD263,
253};
254
Lynus Vaz20c81272017-02-10 16:22:12 +0530255enum a6xx_debugbus_id {
256 A6XX_DBGBUS_CP = 0x1,
257 A6XX_DBGBUS_RBBM = 0x2,
258 A6XX_DBGBUS_VBIF = 0x3,
259 A6XX_DBGBUS_HLSQ = 0x4,
260 A6XX_DBGBUS_UCHE = 0x5,
261 A6XX_DBGBUS_DPM = 0x6,
262 A6XX_DBGBUS_TESS = 0x7,
263 A6XX_DBGBUS_PC = 0x8,
264 A6XX_DBGBUS_VFDP = 0x9,
265 A6XX_DBGBUS_VPC = 0xa,
266 A6XX_DBGBUS_TSE = 0xb,
267 A6XX_DBGBUS_RAS = 0xc,
268 A6XX_DBGBUS_VSC = 0xd,
269 A6XX_DBGBUS_COM = 0xe,
270 A6XX_DBGBUS_LRZ = 0x10,
271 A6XX_DBGBUS_A2D = 0x11,
272 A6XX_DBGBUS_CCUFCHE = 0x12,
273 A6XX_DBGBUS_GMU = 0x13,
274 A6XX_DBGBUS_RBP = 0x14,
275 A6XX_DBGBUS_DCS = 0x15,
276 A6XX_DBGBUS_RBBM_CFG = 0x16,
277 A6XX_DBGBUS_CX = 0x17,
278 A6XX_DBGBUS_TPFCHE = 0x19,
279 A6XX_DBGBUS_GPC = 0x1d,
280 A6XX_DBGBUS_LARC = 0x1e,
281 A6XX_DBGBUS_HLSQ_SPTP = 0x1f,
282 A6XX_DBGBUS_RB_0 = 0x20,
283 A6XX_DBGBUS_RB_1 = 0x21,
284 A6XX_DBGBUS_UCHE_WRAPPER = 0x24,
285 A6XX_DBGBUS_CCU_0 = 0x28,
286 A6XX_DBGBUS_CCU_1 = 0x29,
287 A6XX_DBGBUS_VFD_0 = 0x38,
288 A6XX_DBGBUS_VFD_1 = 0x39,
289 A6XX_DBGBUS_VFD_2 = 0x3a,
290 A6XX_DBGBUS_VFD_3 = 0x3b,
291 A6XX_DBGBUS_SP_0 = 0x40,
292 A6XX_DBGBUS_SP_1 = 0x41,
293 A6XX_DBGBUS_TPL1_0 = 0x48,
294 A6XX_DBGBUS_TPL1_1 = 0x49,
295 A6XX_DBGBUS_TPL1_2 = 0x4a,
296 A6XX_DBGBUS_TPL1_3 = 0x4b,
297};
298
299static const struct adreno_debugbus_block a6xx_dbgc_debugbus_blocks[] = {
300 { A6XX_DBGBUS_CP, 0x100, },
301 { A6XX_DBGBUS_RBBM, 0x100, },
302 { A6XX_DBGBUS_HLSQ, 0x100, },
303 { A6XX_DBGBUS_UCHE, 0x100, },
304 { A6XX_DBGBUS_DPM, 0x100, },
305 { A6XX_DBGBUS_TESS, 0x100, },
306 { A6XX_DBGBUS_PC, 0x100, },
307 { A6XX_DBGBUS_VFDP, 0x100, },
308 { A6XX_DBGBUS_VPC, 0x100, },
309 { A6XX_DBGBUS_TSE, 0x100, },
310 { A6XX_DBGBUS_RAS, 0x100, },
311 { A6XX_DBGBUS_VSC, 0x100, },
312 { A6XX_DBGBUS_COM, 0x100, },
313 { A6XX_DBGBUS_LRZ, 0x100, },
314 { A6XX_DBGBUS_A2D, 0x100, },
315 { A6XX_DBGBUS_CCUFCHE, 0x100, },
316 { A6XX_DBGBUS_RBP, 0x100, },
317 { A6XX_DBGBUS_DCS, 0x100, },
318 { A6XX_DBGBUS_RBBM_CFG, 0x100, },
319 { A6XX_DBGBUS_TPFCHE, 0x100, },
320 { A6XX_DBGBUS_GPC, 0x100, },
321 { A6XX_DBGBUS_LARC, 0x100, },
322 { A6XX_DBGBUS_HLSQ_SPTP, 0x100, },
323 { A6XX_DBGBUS_RB_0, 0x100, },
324 { A6XX_DBGBUS_RB_1, 0x100, },
325 { A6XX_DBGBUS_UCHE_WRAPPER, 0x100, },
326 { A6XX_DBGBUS_CCU_0, 0x100, },
327 { A6XX_DBGBUS_CCU_1, 0x100, },
328 { A6XX_DBGBUS_VFD_0, 0x100, },
329 { A6XX_DBGBUS_VFD_1, 0x100, },
330 { A6XX_DBGBUS_VFD_2, 0x100, },
331 { A6XX_DBGBUS_VFD_3, 0x100, },
332 { A6XX_DBGBUS_SP_0, 0x100, },
333 { A6XX_DBGBUS_SP_1, 0x100, },
334 { A6XX_DBGBUS_TPL1_0, 0x100, },
335 { A6XX_DBGBUS_TPL1_1, 0x100, },
336 { A6XX_DBGBUS_TPL1_2, 0x100, },
337 { A6XX_DBGBUS_TPL1_3, 0x100, },
338};
Shrenuj Bansal41665402016-12-16 15:25:54 -0800339
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530340#define A6XX_NUM_SHADER_BANKS 3
341#define A6XX_SHADER_STATETYPE_SHIFT 8
342
343enum a6xx_shader_obj {
344 A6XX_TP0_TMO_DATA = 0x9,
345 A6XX_TP0_SMO_DATA = 0xa,
346 A6XX_TP0_MIPMAP_BASE_DATA = 0xb,
347 A6XX_TP1_TMO_DATA = 0x19,
348 A6XX_TP1_SMO_DATA = 0x1a,
349 A6XX_TP1_MIPMAP_BASE_DATA = 0x1b,
350 A6XX_SP_INST_DATA = 0x29,
351 A6XX_SP_LB_0_DATA = 0x2a,
352 A6XX_SP_LB_1_DATA = 0x2b,
353 A6XX_SP_LB_2_DATA = 0x2c,
354 A6XX_SP_LB_3_DATA = 0x2d,
355 A6XX_SP_LB_4_DATA = 0x2e,
356 A6XX_SP_LB_5_DATA = 0x2f,
357 A6XX_SP_CB_BINDLESS_DATA = 0x30,
358 A6XX_SP_CB_LEGACY_DATA = 0x31,
359 A6XX_SP_UAV_DATA = 0x32,
360 A6XX_SP_INST_TAG = 0x33,
361 A6XX_SP_CB_BINDLESS_TAG = 0x34,
362 A6XX_SP_TMO_UMO_TAG = 0x35,
363 A6XX_SP_SMO_TAG = 0x36,
364 A6XX_SP_STATE_DATA = 0x37,
365 A6XX_HLSQ_CHUNK_CVS_RAM = 0x49,
366 A6XX_HLSQ_CHUNK_CPS_RAM = 0x4a,
367 A6XX_HLSQ_CHUNK_CVS_RAM_TAG = 0x4b,
368 A6XX_HLSQ_CHUNK_CPS_RAM_TAG = 0x4c,
369 A6XX_HLSQ_ICB_CVS_CB_BASE_TAG = 0x4d,
370 A6XX_HLSQ_ICB_CPS_CB_BASE_TAG = 0x4e,
371 A6XX_HLSQ_CVS_MISC_RAM = 0x50,
372 A6XX_HLSQ_CPS_MISC_RAM = 0x51,
373 A6XX_HLSQ_INST_RAM = 0x52,
374 A6XX_HLSQ_GFX_CVS_CONST_RAM = 0x53,
375 A6XX_HLSQ_GFX_CPS_CONST_RAM = 0x54,
376 A6XX_HLSQ_CVS_MISC_RAM_TAG = 0x55,
377 A6XX_HLSQ_CPS_MISC_RAM_TAG = 0x56,
378 A6XX_HLSQ_INST_RAM_TAG = 0x57,
379 A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG = 0x58,
380 A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG = 0x59,
381 A6XX_HLSQ_PWR_REST_RAM = 0x5a,
382 A6XX_HLSQ_PWR_REST_TAG = 0x5b,
383 A6XX_HLSQ_DATAPATH_META = 0x60,
384 A6XX_HLSQ_FRONTEND_META = 0x61,
385 A6XX_HLSQ_INDIRECT_META = 0x62,
386 A6XX_HLSQ_BACKEND_META = 0x63
387};
388
389struct a6xx_shader_block {
390 unsigned int statetype;
391 unsigned int sz;
392 uint64_t offset;
393};
394
395struct a6xx_shader_block_info {
396 struct a6xx_shader_block *block;
397 unsigned int bank;
398 uint64_t offset;
399};
400
401static struct a6xx_shader_block a6xx_shader_blocks[] = {
402 {A6XX_TP0_TMO_DATA, 0x200},
403 {A6XX_TP0_SMO_DATA, 0x80,},
404 {A6XX_TP0_MIPMAP_BASE_DATA, 0x3C0},
405 {A6XX_TP1_TMO_DATA, 0x200},
406 {A6XX_TP1_SMO_DATA, 0x80,},
407 {A6XX_TP1_MIPMAP_BASE_DATA, 0x3C0},
408 {A6XX_SP_INST_DATA, 0x800},
409 {A6XX_SP_LB_0_DATA, 0x800},
410 {A6XX_SP_LB_1_DATA, 0x800},
411 {A6XX_SP_LB_2_DATA, 0x800},
412 {A6XX_SP_LB_3_DATA, 0x800},
413 {A6XX_SP_LB_4_DATA, 0x800},
414 {A6XX_SP_LB_5_DATA, 0x200},
415 {A6XX_SP_CB_BINDLESS_DATA, 0x2000},
416 {A6XX_SP_CB_LEGACY_DATA, 0x280,},
417 {A6XX_SP_UAV_DATA, 0x80,},
418 {A6XX_SP_INST_TAG, 0x80,},
419 {A6XX_SP_CB_BINDLESS_TAG, 0x80,},
420 {A6XX_SP_TMO_UMO_TAG, 0x80,},
421 {A6XX_SP_SMO_TAG, 0x80},
422 {A6XX_SP_STATE_DATA, 0x3F},
423 {A6XX_HLSQ_CHUNK_CVS_RAM, 0x1C0},
424 {A6XX_HLSQ_CHUNK_CPS_RAM, 0x280},
425 {A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40,},
426 {A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40,},
427 {A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4,},
428 {A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4,},
429 {A6XX_HLSQ_CVS_MISC_RAM, 0x1C0},
430 {A6XX_HLSQ_CPS_MISC_RAM, 0x580},
431 {A6XX_HLSQ_INST_RAM, 0x800},
432 {A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800},
433 {A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800},
434 {A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8,},
435 {A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4,},
436 {A6XX_HLSQ_INST_RAM_TAG, 0x80,},
437 {A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xC,},
438 {A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10},
439 {A6XX_HLSQ_PWR_REST_RAM, 0x28},
440 {A6XX_HLSQ_PWR_REST_TAG, 0x14},
441 {A6XX_HLSQ_DATAPATH_META, 0x40,},
442 {A6XX_HLSQ_FRONTEND_META, 0x40},
443 {A6XX_HLSQ_INDIRECT_META, 0x40,}
444};
445
Shrenuj Bansal41665402016-12-16 15:25:54 -0800446static struct kgsl_memdesc a6xx_capturescript;
447static struct kgsl_memdesc a6xx_crashdump_registers;
448static bool crash_dump_valid;
449
450static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
451 u8 *buf, size_t remain)
452{
453 struct kgsl_snapshot_registers regs = {
454 .regs = a6xx_registers,
455 .count = ARRAY_SIZE(a6xx_registers) / 2,
456 };
457
458 return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
459}
460
461static struct cdregs {
462 const unsigned int *regs;
463 unsigned int size;
464} _a6xx_cd_registers[] = {
465 { a6xx_registers, ARRAY_SIZE(a6xx_registers) },
466};
467
468#define REG_PAIR_COUNT(_a, _i) \
469 (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
470
471static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
472 size_t remain, void *priv)
473{
474 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
475 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
476 unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
477 unsigned int i, j, k;
478 unsigned int count = 0;
479
480 if (crash_dump_valid == false)
481 return a6xx_legacy_snapshot_registers(device, buf, remain);
482
483 if (remain < sizeof(*header)) {
484 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
485 return 0;
486 }
487
488 remain -= sizeof(*header);
489
490 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
491 struct cdregs *regs = &_a6xx_cd_registers[i];
492
493 for (j = 0; j < regs->size / 2; j++) {
494 unsigned int start = regs->regs[2 * j];
495 unsigned int end = regs->regs[(2 * j) + 1];
496
497 if (remain < ((end - start) + 1) * 8) {
498 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
499 goto out;
500 }
501
502 remain -= ((end - start) + 1) * 8;
503
504 for (k = start; k <= end; k++, count++) {
505 *data++ = k;
506 *data++ = *src++;
507 }
508 }
509 }
510
511out:
512 header->count = count;
513
514 /* Return the size of the section */
515 return (count * 8) + sizeof(*header);
516}
517
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530518static size_t a6xx_snapshot_shader_memory(struct kgsl_device *device,
519 u8 *buf, size_t remain, void *priv)
520{
521 struct kgsl_snapshot_shader *header =
522 (struct kgsl_snapshot_shader *) buf;
523 struct a6xx_shader_block_info *info =
524 (struct a6xx_shader_block_info *) priv;
525 struct a6xx_shader_block *block = info->block;
526 unsigned int *data = (unsigned int *) (buf + sizeof(*header));
527
528 if (remain < SHADER_SECTION_SZ(block->sz)) {
529 SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
530 return 0;
531 }
532
533 header->type = block->statetype;
534 header->index = info->bank;
535 header->size = block->sz;
536
537 memcpy(data, a6xx_crashdump_registers.hostptr + info->offset,
538 block->sz);
539
540 return SHADER_SECTION_SZ(block->sz);
541}
542
543static void a6xx_snapshot_shader(struct kgsl_device *device,
544 struct kgsl_snapshot *snapshot)
545{
546 unsigned int i, j;
547 struct a6xx_shader_block_info info;
548
549 /* Shader blocks can only be read by the crash dumper */
550 if (crash_dump_valid == false)
551 return;
552
553 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
554 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
555 info.block = &a6xx_shader_blocks[i];
556 info.bank = j;
557 info.offset = a6xx_shader_blocks[i].offset +
558 (j * a6xx_shader_blocks[i].sz);
559
560 /* Shader working/shadow memory */
561 kgsl_snapshot_add_section(device,
562 KGSL_SNAPSHOT_SECTION_SHADER,
563 snapshot, a6xx_snapshot_shader_memory, &info);
564 }
565 }
566}
567
Lynus Vaza5922742017-03-14 18:50:54 +0530568static void a6xx_snapshot_mempool(struct kgsl_device *device,
569 struct kgsl_snapshot *snapshot)
570{
571 unsigned int pool_size;
572
573 /* Save the mempool size to 0 to stabilize it while dumping */
574 kgsl_regread(device, A6XX_CP_MEM_POOL_SIZE, &pool_size);
575 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, 0);
576
577 kgsl_snapshot_indexed_registers(device, snapshot,
578 A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
579 0, 0x2060);
580
581 /* Restore the saved mempool size */
582 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, pool_size);
583}
584
Lynus Vaz461e2382017-01-16 19:35:41 +0530585static inline unsigned int a6xx_read_dbgahb(struct kgsl_device *device,
586 unsigned int regbase, unsigned int reg)
587{
588 unsigned int read_reg = A6XX_HLSQ_DBG_AHB_READ_APERTURE +
589 reg - regbase / 4;
590 unsigned int val;
591
592 kgsl_regread(device, read_reg, &val);
593 return val;
594}
595
596static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf,
597 size_t remain, void *priv)
598{
599 struct kgsl_snapshot_mvc_regs *header =
600 (struct kgsl_snapshot_mvc_regs *)buf;
601 struct a6xx_cluster_dbgahb_regs_info *info =
602 (struct a6xx_cluster_dbgahb_regs_info *)priv;
603 struct a6xx_cluster_dbgahb_registers *cur_cluster = info->cluster;
604 unsigned int read_sel;
605 unsigned int data_size = 0;
606 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
607 int i, j;
608
609 if (remain < sizeof(*header)) {
610 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
611 return 0;
612 }
613
614 remain -= sizeof(*header);
615
616 header->ctxt_id = info->ctxt_id;
617 header->cluster_id = cur_cluster->id;
618
619 read_sel = ((cur_cluster->statetype + info->ctxt_id * 2) & 0xff) << 8;
620 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
621
622 for (i = 0; i < cur_cluster->num_sets; i++) {
623 unsigned int start = cur_cluster->regs[2 * i];
624 unsigned int end = cur_cluster->regs[2 * i + 1];
625
626 if (remain < (end - start + 3) * 4) {
627 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
628 goto out;
629 }
630
631 remain -= (end - start + 3) * 4;
632 data_size += (end - start + 3) * 4;
633
634 *data++ = start | (1 << 31);
635 *data++ = end;
636
637 for (j = start; j <= end; j++) {
638 unsigned int val;
639
640 val = a6xx_read_dbgahb(device, cur_cluster->regbase, j);
641 *data++ = val;
642
643 }
644 }
645
646out:
647 return data_size + sizeof(*header);
648}
649
650static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
651 size_t remain, void *priv)
652{
653 struct kgsl_snapshot_regs *header =
654 (struct kgsl_snapshot_regs *)buf;
655 struct a6xx_non_ctx_dbgahb_registers *regs =
656 (struct a6xx_non_ctx_dbgahb_registers *)priv;
657 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
658 int count = 0;
659 unsigned int read_sel;
660 int i, j;
661
662 /* Figure out how many registers we are going to dump */
663 for (i = 0; i < regs->num_sets; i++) {
664 int start = regs->regs[i * 2];
665 int end = regs->regs[i * 2 + 1];
666
667 count += (end - start + 1);
668 }
669
670 if (remain < (count * 8) + sizeof(*header)) {
671 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
672 return 0;
673 }
674
675 header->count = count;
676
677 read_sel = (regs->statetype & 0xff) << 8;
678 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
679
680 for (i = 0; i < regs->num_sets; i++) {
681 unsigned int start = regs->regs[2 * i];
682 unsigned int end = regs->regs[2 * i + 1];
683
684 for (j = start; j <= end; j++) {
685 unsigned int val;
686
687 val = a6xx_read_dbgahb(device, regs->regbase, j);
688 *data++ = j;
689 *data++ = val;
690
691 }
692 }
693 return (count * 8) + sizeof(*header);
694}
695
696static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
697 struct kgsl_snapshot *snapshot)
698{
699 int i, j;
700
701 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
702 struct a6xx_cluster_dbgahb_registers *cluster =
703 &a6xx_dbgahb_ctx_clusters[i];
704 struct a6xx_cluster_dbgahb_regs_info info;
705
706 info.cluster = cluster;
707 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
708 info.ctxt_id = j;
709
710 kgsl_snapshot_add_section(device,
711 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
712 a6xx_snapshot_cluster_dbgahb, &info);
713 }
714 }
715
716 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
717 kgsl_snapshot_add_section(device,
718 KGSL_SNAPSHOT_SECTION_REGS, snapshot,
719 a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
720 }
721}
722
Shrenuj Bansal41665402016-12-16 15:25:54 -0800723static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
724 size_t remain, void *priv)
725{
726 struct kgsl_snapshot_mvc_regs *header =
727 (struct kgsl_snapshot_mvc_regs *)buf;
728 struct a6xx_cluster_regs_info *info =
729 (struct a6xx_cluster_regs_info *)priv;
730 struct a6xx_cluster_registers *cur_cluster = info->cluster;
731 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
732 unsigned int ctxt = info->ctxt_id;
733 unsigned int start, end, i, j, aperture_cntl = 0;
734 unsigned int data_size = 0;
735
736 if (remain < sizeof(*header)) {
737 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
738 return 0;
739 }
740
741 remain -= sizeof(*header);
742
743 header->ctxt_id = info->ctxt_id;
744 header->cluster_id = cur_cluster->id;
745
746 /*
747 * Set the AHB control for the Host to read from the
748 * cluster/context for this iteration.
749 */
750 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
751 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
752
753 for (i = 0; i < cur_cluster->num_sets; i++) {
754 start = cur_cluster->regs[2 * i];
755 end = cur_cluster->regs[2 * i + 1];
756
757 if (remain < (end - start + 3) * 4) {
758 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
759 goto out;
760 }
761
762 remain -= (end - start + 3) * 4;
763 data_size += (end - start + 3) * 4;
764
765 *data++ = start | (1 << 31);
766 *data++ = end;
767 for (j = start; j <= end; j++) {
768 unsigned int val;
769
770 kgsl_regread(device, j, &val);
771 *data++ = val;
772 }
773 }
774out:
775 return data_size + sizeof(*header);
776}
777
778static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
779 size_t remain, void *priv)
780{
781 struct kgsl_snapshot_mvc_regs *header =
782 (struct kgsl_snapshot_mvc_regs *)buf;
783 struct a6xx_cluster_regs_info *info =
784 (struct a6xx_cluster_regs_info *)priv;
785 struct a6xx_cluster_registers *cluster = info->cluster;
786 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
787 unsigned int *src;
788 int i, j;
789 unsigned int start, end;
790 size_t data_size = 0;
791
792 if (crash_dump_valid == false)
793 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
794
795 if (remain < sizeof(*header)) {
796 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
797 return 0;
798 }
799
800 remain -= sizeof(*header);
801
802 header->ctxt_id = info->ctxt_id;
803 header->cluster_id = cluster->id;
804
805 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
806 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
807
808 for (i = 0; i < cluster->num_sets; i++) {
809 start = cluster->regs[2 * i];
810 end = cluster->regs[2 * i + 1];
811
812 if (remain < (end - start + 3) * 4) {
813 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
814 goto out;
815 }
816
817 remain -= (end - start + 3) * 4;
818 data_size += (end - start + 3) * 4;
819
820 *data++ = start | (1 << 31);
821 *data++ = end;
822 for (j = start; j <= end; j++)
823 *data++ = *src++;
824 }
825
826out:
827 return data_size + sizeof(*header);
828
829}
830
831static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
832 struct kgsl_snapshot *snapshot)
833{
834 int i, j;
835 struct a6xx_cluster_regs_info info;
836
837 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
838 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
839
840 info.cluster = cluster;
841 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
842 info.ctxt_id = j;
843
844 kgsl_snapshot_add_section(device,
845 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
846 a6xx_snapshot_mvc, &info);
847 }
848 }
849}
850
Lynus Vaz20c81272017-02-10 16:22:12 +0530851/* a6xx_dbgc_debug_bus_read() - Read data from trace bus */
852static void a6xx_dbgc_debug_bus_read(struct kgsl_device *device,
853 unsigned int block_id, unsigned int index, unsigned int *val)
854{
855 unsigned int reg;
856
857 reg = (block_id << A6XX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
858 (index << A6XX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
859
860 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
861 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
862 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
863 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
864
865 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
866 val++;
867 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
868}
869
870/* a6xx_snapshot_cbgc_debugbus_block() - Capture debug data for a gpu block */
871static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
872 u8 *buf, size_t remain, void *priv)
873{
874 struct kgsl_snapshot_debugbus *header =
875 (struct kgsl_snapshot_debugbus *)buf;
876 struct adreno_debugbus_block *block = priv;
877 int i;
878 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
879 unsigned int dwords;
880 size_t size;
881
882 dwords = block->dwords;
883
884 /* For a6xx each debug bus data unit is 2 DWORDS */
885 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
886
887 if (remain < size) {
888 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
889 return 0;
890 }
891
892 header->id = block->block_id;
893 header->count = dwords * 2;
894
895 for (i = 0; i < dwords; i++)
896 a6xx_dbgc_debug_bus_read(device, block->block_id, i,
897 &data[i*2]);
898
899 return size;
900}
901
902/* a6xx_snapshot_debugbus() - Capture debug bus data */
903static void a6xx_snapshot_debugbus(struct kgsl_device *device,
904 struct kgsl_snapshot *snapshot)
905{
906 int i;
907
908 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
909 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
910 (0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
911 (0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
912
913 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLM,
914 0xf << A6XX_DBGC_CFG_DBGBUS_CTLTM_ENABLE_SHIFT);
915
916 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
917 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
918 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
919 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
920
921 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_0,
922 (0 << A6XX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
923 (1 << A6XX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
924 (2 << A6XX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
925 (3 << A6XX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
926 (4 << A6XX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
927 (5 << A6XX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
928 (6 << A6XX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
929 (7 << A6XX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
930 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_1,
931 (8 << A6XX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
932 (9 << A6XX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
933 (10 << A6XX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
934 (11 << A6XX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
935 (12 << A6XX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
936 (13 << A6XX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
937 (14 << A6XX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
938 (15 << A6XX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
939
940 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
941 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
942 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
943 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
944
945 for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
946 kgsl_snapshot_add_section(device,
947 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
948 snapshot, a6xx_snapshot_dbgc_debugbus_block,
949 (void *) &a6xx_dbgc_debugbus_blocks[i]);
950 }
951}
952
Shrenuj Bansal41665402016-12-16 15:25:54 -0800953static void _a6xx_do_crashdump(struct kgsl_device *device)
954{
955 unsigned long wait_time;
956 unsigned int reg = 0;
957 unsigned int val;
958
959 crash_dump_valid = false;
960
961 if (a6xx_capturescript.gpuaddr == 0 ||
962 a6xx_crashdump_registers.gpuaddr == 0)
963 return;
964
965 /* IF the SMMU is stalled we cannot do a crash dump */
966 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
967 if (val & BIT(24))
968 return;
969
970 /* Turn on APRIV so we can access the buffers */
971 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
972
973 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
974 lower_32_bits(a6xx_capturescript.gpuaddr));
975 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
976 upper_32_bits(a6xx_capturescript.gpuaddr));
977 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
978
979 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
980 while (!time_after(jiffies, wait_time)) {
981 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
982 if (reg & 0x2)
983 break;
984 cpu_relax();
985 }
986
987 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
988
989 if (!(reg & 0x2)) {
990 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
991 return;
992 }
993
994 crash_dump_valid = true;
995}
996
997/*
998 * a6xx_snapshot() - A6XX GPU snapshot function
999 * @adreno_dev: Device being snapshotted
1000 * @snapshot: Pointer to the snapshot instance
1001 *
1002 * This is where all of the A6XX specific bits and pieces are grabbed
1003 * into the snapshot memory
1004 */
1005void a6xx_snapshot(struct adreno_device *adreno_dev,
1006 struct kgsl_snapshot *snapshot)
1007{
1008 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1009 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
1010 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
1011
1012 /* Try to run the crash dumper */
1013 _a6xx_do_crashdump(device);
1014
1015 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1016 snapshot, a6xx_snapshot_registers, NULL);
1017
1018 adreno_snapshot_vbif_registers(device, snapshot,
1019 a6xx_vbif_snapshot_registers,
1020 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
1021
1022 /* CP_SQE indexed registers */
1023 kgsl_snapshot_indexed_registers(device, snapshot,
1024 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
1025 0, snap_data->sect_sizes->cp_pfp);
1026
1027 /* CP_DRAW_STATE */
1028 kgsl_snapshot_indexed_registers(device, snapshot,
1029 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
1030 0, 0x100);
1031
1032 /* SQE_UCODE Cache */
1033 kgsl_snapshot_indexed_registers(device, snapshot,
1034 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
1035 0, 0x6000);
1036
1037 /* CP ROQ */
1038 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1039 snapshot, adreno_snapshot_cp_roq,
1040 &snap_data->sect_sizes->roq);
1041
Lynus Vaza5922742017-03-14 18:50:54 +05301042 /* Mempool debug data */
1043 a6xx_snapshot_mempool(device, snapshot);
1044
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301045 /* Shader memory */
1046 a6xx_snapshot_shader(device, snapshot);
1047
Shrenuj Bansal41665402016-12-16 15:25:54 -08001048 /* MVC register section */
1049 a6xx_snapshot_mvc_regs(device, snapshot);
1050
Lynus Vaz461e2382017-01-16 19:35:41 +05301051 /* registers dumped through DBG AHB */
1052 a6xx_snapshot_dbgahb_regs(device, snapshot);
1053
Lynus Vaz20c81272017-02-10 16:22:12 +05301054 a6xx_snapshot_debugbus(device, snapshot);
Shrenuj Bansal41665402016-12-16 15:25:54 -08001055}
1056
1057static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
1058{
1059 int qwords = 0;
1060 unsigned int i, j, k;
1061 unsigned int count;
1062
1063 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1064 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1065
1066 cluster->offset0 = *offset;
1067 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1068
1069 if (j == 1)
1070 cluster->offset1 = *offset;
1071
1072 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
1073 ptr[qwords++] =
1074 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
1075 (1 << 21) | 1;
1076
1077 for (k = 0; k < cluster->num_sets; k++) {
1078 count = REG_PAIR_COUNT(cluster->regs, k);
1079 ptr[qwords++] =
1080 a6xx_crashdump_registers.gpuaddr + *offset;
1081 ptr[qwords++] =
1082 (((uint64_t)cluster->regs[2 * k]) << 44) |
1083 count;
1084
1085 *offset += count * sizeof(unsigned int);
1086 }
1087 }
1088 }
1089
1090 return qwords;
1091}
1092
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301093static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block,
1094 uint64_t *ptr, uint64_t *offset)
1095{
1096 int qwords = 0;
1097 unsigned int j;
1098
1099 /* Capture each bank in the block */
1100 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
1101 /* Program the aperture */
1102 ptr[qwords++] =
1103 (block->statetype << A6XX_SHADER_STATETYPE_SHIFT) | j;
1104 ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_READ_SEL << 44)) |
1105 (1 << 21) | 1;
1106
1107 /* Read all the data in one chunk */
1108 ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset;
1109 ptr[qwords++] =
1110 (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
1111 block->sz;
1112
1113 /* Remember the offset of the first bank for easy access */
1114 if (j == 0)
1115 block->offset = *offset;
1116
1117 *offset += block->sz * sizeof(unsigned int);
1118 }
1119
1120 return qwords;
1121}
1122
Shrenuj Bansal41665402016-12-16 15:25:54 -08001123void a6xx_crashdump_init(struct adreno_device *adreno_dev)
1124{
1125 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1126 unsigned int script_size = 0;
1127 unsigned int data_size = 0;
1128 unsigned int i, j, k;
1129 uint64_t *ptr;
1130 uint64_t offset = 0;
1131
1132 if (a6xx_capturescript.gpuaddr != 0 &&
1133 a6xx_crashdump_registers.gpuaddr != 0)
1134 return;
1135
1136 /*
1137 * We need to allocate two buffers:
1138 * 1 - the buffer to hold the draw script
1139 * 2 - the buffer to hold the data
1140 */
1141
1142 /*
1143 * To save the registers, we need 16 bytes per register pair for the
1144 * script and a dword for each register in the data
1145 */
1146 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1147 struct cdregs *regs = &_a6xx_cd_registers[i];
1148
1149 /* Each pair needs 16 bytes (2 qwords) */
1150 script_size += (regs->size / 2) * 16;
1151
1152 /* Each register needs a dword in the data */
1153 for (j = 0; j < regs->size / 2; j++)
1154 data_size += REG_PAIR_COUNT(regs->regs, j) *
1155 sizeof(unsigned int);
1156
1157 }
1158
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301159 /*
1160 * To save the shader blocks for each block in each type we need 32
1161 * bytes for the script (16 bytes to program the aperture and 16 to
1162 * read the data) and then a block specific number of bytes to hold
1163 * the data
1164 */
1165 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1166 script_size += 32 * A6XX_NUM_SHADER_BANKS;
1167 data_size += a6xx_shader_blocks[i].sz * sizeof(unsigned int) *
1168 A6XX_NUM_SHADER_BANKS;
1169 }
1170
Shrenuj Bansal41665402016-12-16 15:25:54 -08001171 /* Calculate the script and data size for MVC registers */
1172 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1173 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1174
1175 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1176
1177 /* 16 bytes for programming the aperture */
1178 script_size += 16;
1179
1180 /* Reading each pair of registers takes 16 bytes */
1181 script_size += 16 * cluster->num_sets;
1182
1183 /* A dword per register read from the cluster list */
1184 for (k = 0; k < cluster->num_sets; k++)
1185 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1186 sizeof(unsigned int);
1187 }
1188 }
1189
1190 /* Now allocate the script and data buffers */
1191
1192 /* The script buffers needs 2 extra qwords on the end */
1193 if (kgsl_allocate_global(device, &a6xx_capturescript,
1194 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
1195 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
1196 return;
1197
1198 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
1199 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
1200 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
1201 return;
1202 }
1203
1204 /* Build the crash script */
1205
1206 ptr = (uint64_t *)a6xx_capturescript.hostptr;
1207
1208 /* For the registers, program a read command for each pair */
1209 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1210 struct cdregs *regs = &_a6xx_cd_registers[i];
1211
1212 for (j = 0; j < regs->size / 2; j++) {
1213 unsigned int r = REG_PAIR_COUNT(regs->regs, j);
1214 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
1215 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
1216 offset += r * sizeof(unsigned int);
1217 }
1218 }
1219
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301220 /* Program each shader block */
1221 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1222 ptr += _a6xx_crashdump_init_shader(&a6xx_shader_blocks[i], ptr,
1223 &offset);
1224 }
1225
Shrenuj Bansal41665402016-12-16 15:25:54 -08001226 /* Program the capturescript for the MVC regsiters */
1227 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
1228
1229 *ptr++ = 0;
1230 *ptr++ = 0;
1231}