blob: cccce127def7b8697aef049183f5438403028e8b [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 Vaz461e2382017-01-16 19:35:41 +0530568static inline unsigned int a6xx_read_dbgahb(struct kgsl_device *device,
569 unsigned int regbase, unsigned int reg)
570{
571 unsigned int read_reg = A6XX_HLSQ_DBG_AHB_READ_APERTURE +
572 reg - regbase / 4;
573 unsigned int val;
574
575 kgsl_regread(device, read_reg, &val);
576 return val;
577}
578
579static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf,
580 size_t remain, void *priv)
581{
582 struct kgsl_snapshot_mvc_regs *header =
583 (struct kgsl_snapshot_mvc_regs *)buf;
584 struct a6xx_cluster_dbgahb_regs_info *info =
585 (struct a6xx_cluster_dbgahb_regs_info *)priv;
586 struct a6xx_cluster_dbgahb_registers *cur_cluster = info->cluster;
587 unsigned int read_sel;
588 unsigned int data_size = 0;
589 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
590 int i, j;
591
592 if (remain < sizeof(*header)) {
593 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
594 return 0;
595 }
596
597 remain -= sizeof(*header);
598
599 header->ctxt_id = info->ctxt_id;
600 header->cluster_id = cur_cluster->id;
601
602 read_sel = ((cur_cluster->statetype + info->ctxt_id * 2) & 0xff) << 8;
603 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
604
605 for (i = 0; i < cur_cluster->num_sets; i++) {
606 unsigned int start = cur_cluster->regs[2 * i];
607 unsigned int end = cur_cluster->regs[2 * i + 1];
608
609 if (remain < (end - start + 3) * 4) {
610 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
611 goto out;
612 }
613
614 remain -= (end - start + 3) * 4;
615 data_size += (end - start + 3) * 4;
616
617 *data++ = start | (1 << 31);
618 *data++ = end;
619
620 for (j = start; j <= end; j++) {
621 unsigned int val;
622
623 val = a6xx_read_dbgahb(device, cur_cluster->regbase, j);
624 *data++ = val;
625
626 }
627 }
628
629out:
630 return data_size + sizeof(*header);
631}
632
633static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
634 size_t remain, void *priv)
635{
636 struct kgsl_snapshot_regs *header =
637 (struct kgsl_snapshot_regs *)buf;
638 struct a6xx_non_ctx_dbgahb_registers *regs =
639 (struct a6xx_non_ctx_dbgahb_registers *)priv;
640 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
641 int count = 0;
642 unsigned int read_sel;
643 int i, j;
644
645 /* Figure out how many registers we are going to dump */
646 for (i = 0; i < regs->num_sets; i++) {
647 int start = regs->regs[i * 2];
648 int end = regs->regs[i * 2 + 1];
649
650 count += (end - start + 1);
651 }
652
653 if (remain < (count * 8) + sizeof(*header)) {
654 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
655 return 0;
656 }
657
658 header->count = count;
659
660 read_sel = (regs->statetype & 0xff) << 8;
661 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
662
663 for (i = 0; i < regs->num_sets; i++) {
664 unsigned int start = regs->regs[2 * i];
665 unsigned int end = regs->regs[2 * i + 1];
666
667 for (j = start; j <= end; j++) {
668 unsigned int val;
669
670 val = a6xx_read_dbgahb(device, regs->regbase, j);
671 *data++ = j;
672 *data++ = val;
673
674 }
675 }
676 return (count * 8) + sizeof(*header);
677}
678
679static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
680 struct kgsl_snapshot *snapshot)
681{
682 int i, j;
683
684 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
685 struct a6xx_cluster_dbgahb_registers *cluster =
686 &a6xx_dbgahb_ctx_clusters[i];
687 struct a6xx_cluster_dbgahb_regs_info info;
688
689 info.cluster = cluster;
690 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
691 info.ctxt_id = j;
692
693 kgsl_snapshot_add_section(device,
694 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
695 a6xx_snapshot_cluster_dbgahb, &info);
696 }
697 }
698
699 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
700 kgsl_snapshot_add_section(device,
701 KGSL_SNAPSHOT_SECTION_REGS, snapshot,
702 a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
703 }
704}
705
Shrenuj Bansal41665402016-12-16 15:25:54 -0800706static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
707 size_t remain, void *priv)
708{
709 struct kgsl_snapshot_mvc_regs *header =
710 (struct kgsl_snapshot_mvc_regs *)buf;
711 struct a6xx_cluster_regs_info *info =
712 (struct a6xx_cluster_regs_info *)priv;
713 struct a6xx_cluster_registers *cur_cluster = info->cluster;
714 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
715 unsigned int ctxt = info->ctxt_id;
716 unsigned int start, end, i, j, aperture_cntl = 0;
717 unsigned int data_size = 0;
718
719 if (remain < sizeof(*header)) {
720 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
721 return 0;
722 }
723
724 remain -= sizeof(*header);
725
726 header->ctxt_id = info->ctxt_id;
727 header->cluster_id = cur_cluster->id;
728
729 /*
730 * Set the AHB control for the Host to read from the
731 * cluster/context for this iteration.
732 */
733 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
734 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
735
736 for (i = 0; i < cur_cluster->num_sets; i++) {
737 start = cur_cluster->regs[2 * i];
738 end = cur_cluster->regs[2 * i + 1];
739
740 if (remain < (end - start + 3) * 4) {
741 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
742 goto out;
743 }
744
745 remain -= (end - start + 3) * 4;
746 data_size += (end - start + 3) * 4;
747
748 *data++ = start | (1 << 31);
749 *data++ = end;
750 for (j = start; j <= end; j++) {
751 unsigned int val;
752
753 kgsl_regread(device, j, &val);
754 *data++ = val;
755 }
756 }
757out:
758 return data_size + sizeof(*header);
759}
760
761static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
762 size_t remain, void *priv)
763{
764 struct kgsl_snapshot_mvc_regs *header =
765 (struct kgsl_snapshot_mvc_regs *)buf;
766 struct a6xx_cluster_regs_info *info =
767 (struct a6xx_cluster_regs_info *)priv;
768 struct a6xx_cluster_registers *cluster = info->cluster;
769 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
770 unsigned int *src;
771 int i, j;
772 unsigned int start, end;
773 size_t data_size = 0;
774
775 if (crash_dump_valid == false)
776 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
777
778 if (remain < sizeof(*header)) {
779 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
780 return 0;
781 }
782
783 remain -= sizeof(*header);
784
785 header->ctxt_id = info->ctxt_id;
786 header->cluster_id = cluster->id;
787
788 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
789 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
790
791 for (i = 0; i < cluster->num_sets; i++) {
792 start = cluster->regs[2 * i];
793 end = cluster->regs[2 * i + 1];
794
795 if (remain < (end - start + 3) * 4) {
796 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
797 goto out;
798 }
799
800 remain -= (end - start + 3) * 4;
801 data_size += (end - start + 3) * 4;
802
803 *data++ = start | (1 << 31);
804 *data++ = end;
805 for (j = start; j <= end; j++)
806 *data++ = *src++;
807 }
808
809out:
810 return data_size + sizeof(*header);
811
812}
813
814static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
815 struct kgsl_snapshot *snapshot)
816{
817 int i, j;
818 struct a6xx_cluster_regs_info info;
819
820 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
821 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
822
823 info.cluster = cluster;
824 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
825 info.ctxt_id = j;
826
827 kgsl_snapshot_add_section(device,
828 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
829 a6xx_snapshot_mvc, &info);
830 }
831 }
832}
833
Lynus Vaz20c81272017-02-10 16:22:12 +0530834/* a6xx_dbgc_debug_bus_read() - Read data from trace bus */
835static void a6xx_dbgc_debug_bus_read(struct kgsl_device *device,
836 unsigned int block_id, unsigned int index, unsigned int *val)
837{
838 unsigned int reg;
839
840 reg = (block_id << A6XX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
841 (index << A6XX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
842
843 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
844 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
845 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
846 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
847
848 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
849 val++;
850 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
851}
852
853/* a6xx_snapshot_cbgc_debugbus_block() - Capture debug data for a gpu block */
854static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
855 u8 *buf, size_t remain, void *priv)
856{
857 struct kgsl_snapshot_debugbus *header =
858 (struct kgsl_snapshot_debugbus *)buf;
859 struct adreno_debugbus_block *block = priv;
860 int i;
861 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
862 unsigned int dwords;
863 size_t size;
864
865 dwords = block->dwords;
866
867 /* For a6xx each debug bus data unit is 2 DWORDS */
868 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
869
870 if (remain < size) {
871 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
872 return 0;
873 }
874
875 header->id = block->block_id;
876 header->count = dwords * 2;
877
878 for (i = 0; i < dwords; i++)
879 a6xx_dbgc_debug_bus_read(device, block->block_id, i,
880 &data[i*2]);
881
882 return size;
883}
884
885/* a6xx_snapshot_debugbus() - Capture debug bus data */
886static void a6xx_snapshot_debugbus(struct kgsl_device *device,
887 struct kgsl_snapshot *snapshot)
888{
889 int i;
890
891 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
892 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
893 (0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
894 (0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
895
896 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLM,
897 0xf << A6XX_DBGC_CFG_DBGBUS_CTLTM_ENABLE_SHIFT);
898
899 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
900 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
901 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
902 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
903
904 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_0,
905 (0 << A6XX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
906 (1 << A6XX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
907 (2 << A6XX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
908 (3 << A6XX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
909 (4 << A6XX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
910 (5 << A6XX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
911 (6 << A6XX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
912 (7 << A6XX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
913 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_1,
914 (8 << A6XX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
915 (9 << A6XX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
916 (10 << A6XX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
917 (11 << A6XX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
918 (12 << A6XX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
919 (13 << A6XX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
920 (14 << A6XX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
921 (15 << A6XX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
922
923 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
924 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
925 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
926 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
927
928 for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
929 kgsl_snapshot_add_section(device,
930 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
931 snapshot, a6xx_snapshot_dbgc_debugbus_block,
932 (void *) &a6xx_dbgc_debugbus_blocks[i]);
933 }
934}
935
Shrenuj Bansal41665402016-12-16 15:25:54 -0800936static void _a6xx_do_crashdump(struct kgsl_device *device)
937{
938 unsigned long wait_time;
939 unsigned int reg = 0;
940 unsigned int val;
941
942 crash_dump_valid = false;
943
944 if (a6xx_capturescript.gpuaddr == 0 ||
945 a6xx_crashdump_registers.gpuaddr == 0)
946 return;
947
948 /* IF the SMMU is stalled we cannot do a crash dump */
949 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
950 if (val & BIT(24))
951 return;
952
953 /* Turn on APRIV so we can access the buffers */
954 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
955
956 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
957 lower_32_bits(a6xx_capturescript.gpuaddr));
958 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
959 upper_32_bits(a6xx_capturescript.gpuaddr));
960 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
961
962 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
963 while (!time_after(jiffies, wait_time)) {
964 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
965 if (reg & 0x2)
966 break;
967 cpu_relax();
968 }
969
970 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
971
972 if (!(reg & 0x2)) {
973 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
974 return;
975 }
976
977 crash_dump_valid = true;
978}
979
980/*
981 * a6xx_snapshot() - A6XX GPU snapshot function
982 * @adreno_dev: Device being snapshotted
983 * @snapshot: Pointer to the snapshot instance
984 *
985 * This is where all of the A6XX specific bits and pieces are grabbed
986 * into the snapshot memory
987 */
988void a6xx_snapshot(struct adreno_device *adreno_dev,
989 struct kgsl_snapshot *snapshot)
990{
991 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
992 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
993 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
994
995 /* Try to run the crash dumper */
996 _a6xx_do_crashdump(device);
997
998 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
999 snapshot, a6xx_snapshot_registers, NULL);
1000
1001 adreno_snapshot_vbif_registers(device, snapshot,
1002 a6xx_vbif_snapshot_registers,
1003 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
1004
1005 /* CP_SQE indexed registers */
1006 kgsl_snapshot_indexed_registers(device, snapshot,
1007 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
1008 0, snap_data->sect_sizes->cp_pfp);
1009
1010 /* CP_DRAW_STATE */
1011 kgsl_snapshot_indexed_registers(device, snapshot,
1012 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
1013 0, 0x100);
1014
1015 /* SQE_UCODE Cache */
1016 kgsl_snapshot_indexed_registers(device, snapshot,
1017 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
1018 0, 0x6000);
1019
1020 /* CP ROQ */
1021 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1022 snapshot, adreno_snapshot_cp_roq,
1023 &snap_data->sect_sizes->roq);
1024
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301025 /* Shader memory */
1026 a6xx_snapshot_shader(device, snapshot);
1027
Shrenuj Bansal41665402016-12-16 15:25:54 -08001028 /* MVC register section */
1029 a6xx_snapshot_mvc_regs(device, snapshot);
1030
Lynus Vaz461e2382017-01-16 19:35:41 +05301031 /* registers dumped through DBG AHB */
1032 a6xx_snapshot_dbgahb_regs(device, snapshot);
1033
Lynus Vaz20c81272017-02-10 16:22:12 +05301034 a6xx_snapshot_debugbus(device, snapshot);
Shrenuj Bansal41665402016-12-16 15:25:54 -08001035}
1036
1037static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
1038{
1039 int qwords = 0;
1040 unsigned int i, j, k;
1041 unsigned int count;
1042
1043 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1044 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1045
1046 cluster->offset0 = *offset;
1047 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1048
1049 if (j == 1)
1050 cluster->offset1 = *offset;
1051
1052 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
1053 ptr[qwords++] =
1054 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
1055 (1 << 21) | 1;
1056
1057 for (k = 0; k < cluster->num_sets; k++) {
1058 count = REG_PAIR_COUNT(cluster->regs, k);
1059 ptr[qwords++] =
1060 a6xx_crashdump_registers.gpuaddr + *offset;
1061 ptr[qwords++] =
1062 (((uint64_t)cluster->regs[2 * k]) << 44) |
1063 count;
1064
1065 *offset += count * sizeof(unsigned int);
1066 }
1067 }
1068 }
1069
1070 return qwords;
1071}
1072
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301073static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block,
1074 uint64_t *ptr, uint64_t *offset)
1075{
1076 int qwords = 0;
1077 unsigned int j;
1078
1079 /* Capture each bank in the block */
1080 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
1081 /* Program the aperture */
1082 ptr[qwords++] =
1083 (block->statetype << A6XX_SHADER_STATETYPE_SHIFT) | j;
1084 ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_READ_SEL << 44)) |
1085 (1 << 21) | 1;
1086
1087 /* Read all the data in one chunk */
1088 ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset;
1089 ptr[qwords++] =
1090 (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
1091 block->sz;
1092
1093 /* Remember the offset of the first bank for easy access */
1094 if (j == 0)
1095 block->offset = *offset;
1096
1097 *offset += block->sz * sizeof(unsigned int);
1098 }
1099
1100 return qwords;
1101}
1102
Shrenuj Bansal41665402016-12-16 15:25:54 -08001103void a6xx_crashdump_init(struct adreno_device *adreno_dev)
1104{
1105 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1106 unsigned int script_size = 0;
1107 unsigned int data_size = 0;
1108 unsigned int i, j, k;
1109 uint64_t *ptr;
1110 uint64_t offset = 0;
1111
1112 if (a6xx_capturescript.gpuaddr != 0 &&
1113 a6xx_crashdump_registers.gpuaddr != 0)
1114 return;
1115
1116 /*
1117 * We need to allocate two buffers:
1118 * 1 - the buffer to hold the draw script
1119 * 2 - the buffer to hold the data
1120 */
1121
1122 /*
1123 * To save the registers, we need 16 bytes per register pair for the
1124 * script and a dword for each register in the data
1125 */
1126 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1127 struct cdregs *regs = &_a6xx_cd_registers[i];
1128
1129 /* Each pair needs 16 bytes (2 qwords) */
1130 script_size += (regs->size / 2) * 16;
1131
1132 /* Each register needs a dword in the data */
1133 for (j = 0; j < regs->size / 2; j++)
1134 data_size += REG_PAIR_COUNT(regs->regs, j) *
1135 sizeof(unsigned int);
1136
1137 }
1138
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301139 /*
1140 * To save the shader blocks for each block in each type we need 32
1141 * bytes for the script (16 bytes to program the aperture and 16 to
1142 * read the data) and then a block specific number of bytes to hold
1143 * the data
1144 */
1145 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1146 script_size += 32 * A6XX_NUM_SHADER_BANKS;
1147 data_size += a6xx_shader_blocks[i].sz * sizeof(unsigned int) *
1148 A6XX_NUM_SHADER_BANKS;
1149 }
1150
Shrenuj Bansal41665402016-12-16 15:25:54 -08001151 /* Calculate the script and data size for MVC registers */
1152 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1153 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1154
1155 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1156
1157 /* 16 bytes for programming the aperture */
1158 script_size += 16;
1159
1160 /* Reading each pair of registers takes 16 bytes */
1161 script_size += 16 * cluster->num_sets;
1162
1163 /* A dword per register read from the cluster list */
1164 for (k = 0; k < cluster->num_sets; k++)
1165 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1166 sizeof(unsigned int);
1167 }
1168 }
1169
1170 /* Now allocate the script and data buffers */
1171
1172 /* The script buffers needs 2 extra qwords on the end */
1173 if (kgsl_allocate_global(device, &a6xx_capturescript,
1174 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
1175 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
1176 return;
1177
1178 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
1179 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
1180 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
1181 return;
1182 }
1183
1184 /* Build the crash script */
1185
1186 ptr = (uint64_t *)a6xx_capturescript.hostptr;
1187
1188 /* For the registers, program a read command for each pair */
1189 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1190 struct cdregs *regs = &_a6xx_cd_registers[i];
1191
1192 for (j = 0; j < regs->size / 2; j++) {
1193 unsigned int r = REG_PAIR_COUNT(regs->regs, j);
1194 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
1195 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
1196 offset += r * sizeof(unsigned int);
1197 }
1198 }
1199
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301200 /* Program each shader block */
1201 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1202 ptr += _a6xx_crashdump_init_shader(&a6xx_shader_blocks[i], ptr,
1203 &offset);
1204 }
1205
Shrenuj Bansal41665402016-12-16 15:25:54 -08001206 /* Program the capturescript for the MVC regsiters */
1207 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
1208
1209 *ptr++ = 0;
1210 *ptr++ = 0;
1211}