blob: 7ebf5fdc49685268bd14df401e3c0aab29b644da [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 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700129 { CP_CLUSTER_SP_VS, 0x0002E000, 0x41, a6xx_hlsq_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530130 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 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700133 { CP_CLUSTER_SP_VS, 0x0002A000, 0x21, a6xx_sp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530134 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700135 { CP_CLUSTER_SP_VS, 0x0002C000, 0x1, a6xx_tp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530136 ARRAY_SIZE(a6xx_tp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700137 { CP_CLUSTER_SP_PS, 0x0002E000, 0x42, a6xx_sp_ps_hlsq_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530138 ARRAY_SIZE(a6xx_sp_ps_hlsq_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700139 { CP_CLUSTER_SP_PS, 0x0002F000, 0x46, a6xx_sp_ps_hlsq_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530140 ARRAY_SIZE(a6xx_sp_ps_hlsq_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700141 { CP_CLUSTER_SP_PS, 0x0002A000, 0x22, a6xx_sp_ps_sp_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530142 ARRAY_SIZE(a6xx_sp_ps_sp_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700143 { CP_CLUSTER_SP_PS, 0x0002B000, 0x26, a6xx_sp_ps_sp_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530144 ARRAY_SIZE(a6xx_sp_ps_sp_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700145 { CP_CLUSTER_SP_PS, 0x0002C000, 0x2, a6xx_sp_ps_tp_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530146 ARRAY_SIZE(a6xx_sp_ps_tp_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700147 { CP_CLUSTER_SP_PS, 0x0002D000, 0x6, a6xx_sp_ps_tp_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530148 ARRAY_SIZE(a6xx_sp_ps_tp_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700149 { CP_CLUSTER_SP_PS, 0x0002E000, 0x42, a6xx_hlsq_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530150 ARRAY_SIZE(a6xx_hlsq_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700151 { CP_CLUSTER_SP_VS, 0x0002A000, 0x22, a6xx_sp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530152 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700153 { CP_CLUSTER_SP_VS, 0x0002C000, 0x2, a6xx_tp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530154 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 Vazff24c972017-03-07 19:27:46 +0530345static void __iomem *a6xx_cx_dbgc;
346static const struct adreno_debugbus_block a6xx_cx_dbgc_debugbus_blocks[] = {
347 { A6XX_DBGBUS_VBIF, 0x100, },
348 { A6XX_DBGBUS_GMU, 0x100, },
349 { A6XX_DBGBUS_CX, 0x100, },
350};
351
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530352#define A6XX_NUM_SHADER_BANKS 3
353#define A6XX_SHADER_STATETYPE_SHIFT 8
354
355enum a6xx_shader_obj {
356 A6XX_TP0_TMO_DATA = 0x9,
357 A6XX_TP0_SMO_DATA = 0xa,
358 A6XX_TP0_MIPMAP_BASE_DATA = 0xb,
359 A6XX_TP1_TMO_DATA = 0x19,
360 A6XX_TP1_SMO_DATA = 0x1a,
361 A6XX_TP1_MIPMAP_BASE_DATA = 0x1b,
362 A6XX_SP_INST_DATA = 0x29,
363 A6XX_SP_LB_0_DATA = 0x2a,
364 A6XX_SP_LB_1_DATA = 0x2b,
365 A6XX_SP_LB_2_DATA = 0x2c,
366 A6XX_SP_LB_3_DATA = 0x2d,
367 A6XX_SP_LB_4_DATA = 0x2e,
368 A6XX_SP_LB_5_DATA = 0x2f,
369 A6XX_SP_CB_BINDLESS_DATA = 0x30,
370 A6XX_SP_CB_LEGACY_DATA = 0x31,
371 A6XX_SP_UAV_DATA = 0x32,
372 A6XX_SP_INST_TAG = 0x33,
373 A6XX_SP_CB_BINDLESS_TAG = 0x34,
374 A6XX_SP_TMO_UMO_TAG = 0x35,
375 A6XX_SP_SMO_TAG = 0x36,
376 A6XX_SP_STATE_DATA = 0x37,
377 A6XX_HLSQ_CHUNK_CVS_RAM = 0x49,
378 A6XX_HLSQ_CHUNK_CPS_RAM = 0x4a,
379 A6XX_HLSQ_CHUNK_CVS_RAM_TAG = 0x4b,
380 A6XX_HLSQ_CHUNK_CPS_RAM_TAG = 0x4c,
381 A6XX_HLSQ_ICB_CVS_CB_BASE_TAG = 0x4d,
382 A6XX_HLSQ_ICB_CPS_CB_BASE_TAG = 0x4e,
383 A6XX_HLSQ_CVS_MISC_RAM = 0x50,
384 A6XX_HLSQ_CPS_MISC_RAM = 0x51,
385 A6XX_HLSQ_INST_RAM = 0x52,
386 A6XX_HLSQ_GFX_CVS_CONST_RAM = 0x53,
387 A6XX_HLSQ_GFX_CPS_CONST_RAM = 0x54,
388 A6XX_HLSQ_CVS_MISC_RAM_TAG = 0x55,
389 A6XX_HLSQ_CPS_MISC_RAM_TAG = 0x56,
390 A6XX_HLSQ_INST_RAM_TAG = 0x57,
391 A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG = 0x58,
392 A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG = 0x59,
393 A6XX_HLSQ_PWR_REST_RAM = 0x5a,
394 A6XX_HLSQ_PWR_REST_TAG = 0x5b,
395 A6XX_HLSQ_DATAPATH_META = 0x60,
396 A6XX_HLSQ_FRONTEND_META = 0x61,
397 A6XX_HLSQ_INDIRECT_META = 0x62,
398 A6XX_HLSQ_BACKEND_META = 0x63
399};
400
401struct a6xx_shader_block {
402 unsigned int statetype;
403 unsigned int sz;
404 uint64_t offset;
405};
406
407struct a6xx_shader_block_info {
408 struct a6xx_shader_block *block;
409 unsigned int bank;
410 uint64_t offset;
411};
412
413static struct a6xx_shader_block a6xx_shader_blocks[] = {
414 {A6XX_TP0_TMO_DATA, 0x200},
415 {A6XX_TP0_SMO_DATA, 0x80,},
416 {A6XX_TP0_MIPMAP_BASE_DATA, 0x3C0},
417 {A6XX_TP1_TMO_DATA, 0x200},
418 {A6XX_TP1_SMO_DATA, 0x80,},
419 {A6XX_TP1_MIPMAP_BASE_DATA, 0x3C0},
420 {A6XX_SP_INST_DATA, 0x800},
421 {A6XX_SP_LB_0_DATA, 0x800},
422 {A6XX_SP_LB_1_DATA, 0x800},
423 {A6XX_SP_LB_2_DATA, 0x800},
424 {A6XX_SP_LB_3_DATA, 0x800},
425 {A6XX_SP_LB_4_DATA, 0x800},
426 {A6XX_SP_LB_5_DATA, 0x200},
427 {A6XX_SP_CB_BINDLESS_DATA, 0x2000},
428 {A6XX_SP_CB_LEGACY_DATA, 0x280,},
429 {A6XX_SP_UAV_DATA, 0x80,},
430 {A6XX_SP_INST_TAG, 0x80,},
431 {A6XX_SP_CB_BINDLESS_TAG, 0x80,},
432 {A6XX_SP_TMO_UMO_TAG, 0x80,},
433 {A6XX_SP_SMO_TAG, 0x80},
434 {A6XX_SP_STATE_DATA, 0x3F},
435 {A6XX_HLSQ_CHUNK_CVS_RAM, 0x1C0},
436 {A6XX_HLSQ_CHUNK_CPS_RAM, 0x280},
437 {A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40,},
438 {A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40,},
439 {A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4,},
440 {A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4,},
441 {A6XX_HLSQ_CVS_MISC_RAM, 0x1C0},
442 {A6XX_HLSQ_CPS_MISC_RAM, 0x580},
443 {A6XX_HLSQ_INST_RAM, 0x800},
444 {A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800},
445 {A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800},
446 {A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8,},
447 {A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4,},
448 {A6XX_HLSQ_INST_RAM_TAG, 0x80,},
449 {A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xC,},
450 {A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10},
451 {A6XX_HLSQ_PWR_REST_RAM, 0x28},
452 {A6XX_HLSQ_PWR_REST_TAG, 0x14},
453 {A6XX_HLSQ_DATAPATH_META, 0x40,},
454 {A6XX_HLSQ_FRONTEND_META, 0x40},
455 {A6XX_HLSQ_INDIRECT_META, 0x40,}
456};
457
Shrenuj Bansal41665402016-12-16 15:25:54 -0800458static struct kgsl_memdesc a6xx_capturescript;
459static struct kgsl_memdesc a6xx_crashdump_registers;
460static bool crash_dump_valid;
461
462static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
463 u8 *buf, size_t remain)
464{
465 struct kgsl_snapshot_registers regs = {
466 .regs = a6xx_registers,
467 .count = ARRAY_SIZE(a6xx_registers) / 2,
468 };
469
470 return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
471}
472
473static struct cdregs {
474 const unsigned int *regs;
475 unsigned int size;
476} _a6xx_cd_registers[] = {
477 { a6xx_registers, ARRAY_SIZE(a6xx_registers) },
478};
479
480#define REG_PAIR_COUNT(_a, _i) \
481 (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
482
483static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
484 size_t remain, void *priv)
485{
486 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
487 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
488 unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
489 unsigned int i, j, k;
490 unsigned int count = 0;
491
492 if (crash_dump_valid == false)
493 return a6xx_legacy_snapshot_registers(device, buf, remain);
494
495 if (remain < sizeof(*header)) {
496 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
497 return 0;
498 }
499
500 remain -= sizeof(*header);
501
502 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
503 struct cdregs *regs = &_a6xx_cd_registers[i];
504
505 for (j = 0; j < regs->size / 2; j++) {
506 unsigned int start = regs->regs[2 * j];
507 unsigned int end = regs->regs[(2 * j) + 1];
508
509 if (remain < ((end - start) + 1) * 8) {
510 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
511 goto out;
512 }
513
514 remain -= ((end - start) + 1) * 8;
515
516 for (k = start; k <= end; k++, count++) {
517 *data++ = k;
518 *data++ = *src++;
519 }
520 }
521 }
522
523out:
524 header->count = count;
525
526 /* Return the size of the section */
527 return (count * 8) + sizeof(*header);
528}
529
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530530static size_t a6xx_snapshot_shader_memory(struct kgsl_device *device,
531 u8 *buf, size_t remain, void *priv)
532{
533 struct kgsl_snapshot_shader *header =
534 (struct kgsl_snapshot_shader *) buf;
535 struct a6xx_shader_block_info *info =
536 (struct a6xx_shader_block_info *) priv;
537 struct a6xx_shader_block *block = info->block;
538 unsigned int *data = (unsigned int *) (buf + sizeof(*header));
539
540 if (remain < SHADER_SECTION_SZ(block->sz)) {
541 SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
542 return 0;
543 }
544
545 header->type = block->statetype;
546 header->index = info->bank;
547 header->size = block->sz;
548
549 memcpy(data, a6xx_crashdump_registers.hostptr + info->offset,
550 block->sz);
551
552 return SHADER_SECTION_SZ(block->sz);
553}
554
555static void a6xx_snapshot_shader(struct kgsl_device *device,
556 struct kgsl_snapshot *snapshot)
557{
558 unsigned int i, j;
559 struct a6xx_shader_block_info info;
560
561 /* Shader blocks can only be read by the crash dumper */
562 if (crash_dump_valid == false)
563 return;
564
565 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
566 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
567 info.block = &a6xx_shader_blocks[i];
568 info.bank = j;
569 info.offset = a6xx_shader_blocks[i].offset +
570 (j * a6xx_shader_blocks[i].sz);
571
572 /* Shader working/shadow memory */
573 kgsl_snapshot_add_section(device,
574 KGSL_SNAPSHOT_SECTION_SHADER,
575 snapshot, a6xx_snapshot_shader_memory, &info);
576 }
577 }
578}
579
Lynus Vaza5922742017-03-14 18:50:54 +0530580static void a6xx_snapshot_mempool(struct kgsl_device *device,
581 struct kgsl_snapshot *snapshot)
582{
583 unsigned int pool_size;
Lynus Vazb8e43d52017-04-20 14:47:37 +0530584 u8 *buf = snapshot->ptr;
Lynus Vaza5922742017-03-14 18:50:54 +0530585
Lynus Vazb8e43d52017-04-20 14:47:37 +0530586 /* Set the mempool size to 0 to stabilize it while dumping */
Lynus Vaza5922742017-03-14 18:50:54 +0530587 kgsl_regread(device, A6XX_CP_MEM_POOL_SIZE, &pool_size);
588 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, 0);
589
590 kgsl_snapshot_indexed_registers(device, snapshot,
591 A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
592 0, 0x2060);
593
Lynus Vazb8e43d52017-04-20 14:47:37 +0530594 /*
595 * Data at offset 0x2000 in the mempool section is the mempool size.
596 * Since we set it to 0, patch in the original size so that the data
597 * is consistent.
598 */
599 if (buf < snapshot->ptr) {
600 unsigned int *data;
601
602 /* Skip over the headers */
603 buf += sizeof(struct kgsl_snapshot_section_header) +
604 sizeof(struct kgsl_snapshot_indexed_regs);
605
606 data = (unsigned int *)buf + 0x2000;
607 *data = pool_size;
608 }
609
Lynus Vaza5922742017-03-14 18:50:54 +0530610 /* Restore the saved mempool size */
611 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, pool_size);
612}
613
Lynus Vaz461e2382017-01-16 19:35:41 +0530614static inline unsigned int a6xx_read_dbgahb(struct kgsl_device *device,
615 unsigned int regbase, unsigned int reg)
616{
617 unsigned int read_reg = A6XX_HLSQ_DBG_AHB_READ_APERTURE +
618 reg - regbase / 4;
619 unsigned int val;
620
621 kgsl_regread(device, read_reg, &val);
622 return val;
623}
624
625static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf,
626 size_t remain, void *priv)
627{
628 struct kgsl_snapshot_mvc_regs *header =
629 (struct kgsl_snapshot_mvc_regs *)buf;
630 struct a6xx_cluster_dbgahb_regs_info *info =
631 (struct a6xx_cluster_dbgahb_regs_info *)priv;
632 struct a6xx_cluster_dbgahb_registers *cur_cluster = info->cluster;
633 unsigned int read_sel;
634 unsigned int data_size = 0;
635 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
636 int i, j;
637
638 if (remain < sizeof(*header)) {
639 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
640 return 0;
641 }
642
643 remain -= sizeof(*header);
644
645 header->ctxt_id = info->ctxt_id;
646 header->cluster_id = cur_cluster->id;
647
648 read_sel = ((cur_cluster->statetype + info->ctxt_id * 2) & 0xff) << 8;
649 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
650
651 for (i = 0; i < cur_cluster->num_sets; i++) {
652 unsigned int start = cur_cluster->regs[2 * i];
653 unsigned int end = cur_cluster->regs[2 * i + 1];
654
655 if (remain < (end - start + 3) * 4) {
656 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
657 goto out;
658 }
659
660 remain -= (end - start + 3) * 4;
661 data_size += (end - start + 3) * 4;
662
663 *data++ = start | (1 << 31);
664 *data++ = end;
665
666 for (j = start; j <= end; j++) {
667 unsigned int val;
668
669 val = a6xx_read_dbgahb(device, cur_cluster->regbase, j);
670 *data++ = val;
671
672 }
673 }
674
675out:
676 return data_size + sizeof(*header);
677}
678
679static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
680 size_t remain, void *priv)
681{
682 struct kgsl_snapshot_regs *header =
683 (struct kgsl_snapshot_regs *)buf;
684 struct a6xx_non_ctx_dbgahb_registers *regs =
685 (struct a6xx_non_ctx_dbgahb_registers *)priv;
686 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
687 int count = 0;
688 unsigned int read_sel;
689 int i, j;
690
691 /* Figure out how many registers we are going to dump */
692 for (i = 0; i < regs->num_sets; i++) {
693 int start = regs->regs[i * 2];
694 int end = regs->regs[i * 2 + 1];
695
696 count += (end - start + 1);
697 }
698
699 if (remain < (count * 8) + sizeof(*header)) {
700 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
701 return 0;
702 }
703
704 header->count = count;
705
706 read_sel = (regs->statetype & 0xff) << 8;
707 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
708
709 for (i = 0; i < regs->num_sets; i++) {
710 unsigned int start = regs->regs[2 * i];
711 unsigned int end = regs->regs[2 * i + 1];
712
713 for (j = start; j <= end; j++) {
714 unsigned int val;
715
716 val = a6xx_read_dbgahb(device, regs->regbase, j);
717 *data++ = j;
718 *data++ = val;
719
720 }
721 }
722 return (count * 8) + sizeof(*header);
723}
724
725static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
726 struct kgsl_snapshot *snapshot)
727{
728 int i, j;
729
730 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
731 struct a6xx_cluster_dbgahb_registers *cluster =
732 &a6xx_dbgahb_ctx_clusters[i];
733 struct a6xx_cluster_dbgahb_regs_info info;
734
735 info.cluster = cluster;
736 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
737 info.ctxt_id = j;
738
739 kgsl_snapshot_add_section(device,
740 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
741 a6xx_snapshot_cluster_dbgahb, &info);
742 }
743 }
744
745 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
746 kgsl_snapshot_add_section(device,
747 KGSL_SNAPSHOT_SECTION_REGS, snapshot,
748 a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
749 }
750}
751
Shrenuj Bansal41665402016-12-16 15:25:54 -0800752static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
753 size_t remain, void *priv)
754{
755 struct kgsl_snapshot_mvc_regs *header =
756 (struct kgsl_snapshot_mvc_regs *)buf;
757 struct a6xx_cluster_regs_info *info =
758 (struct a6xx_cluster_regs_info *)priv;
759 struct a6xx_cluster_registers *cur_cluster = info->cluster;
760 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
761 unsigned int ctxt = info->ctxt_id;
762 unsigned int start, end, i, j, aperture_cntl = 0;
763 unsigned int data_size = 0;
764
765 if (remain < sizeof(*header)) {
766 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
767 return 0;
768 }
769
770 remain -= sizeof(*header);
771
772 header->ctxt_id = info->ctxt_id;
773 header->cluster_id = cur_cluster->id;
774
775 /*
776 * Set the AHB control for the Host to read from the
777 * cluster/context for this iteration.
778 */
779 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
780 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
781
782 for (i = 0; i < cur_cluster->num_sets; i++) {
783 start = cur_cluster->regs[2 * i];
784 end = cur_cluster->regs[2 * i + 1];
785
786 if (remain < (end - start + 3) * 4) {
787 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
788 goto out;
789 }
790
791 remain -= (end - start + 3) * 4;
792 data_size += (end - start + 3) * 4;
793
794 *data++ = start | (1 << 31);
795 *data++ = end;
796 for (j = start; j <= end; j++) {
797 unsigned int val;
798
799 kgsl_regread(device, j, &val);
800 *data++ = val;
801 }
802 }
803out:
804 return data_size + sizeof(*header);
805}
806
807static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
808 size_t remain, void *priv)
809{
810 struct kgsl_snapshot_mvc_regs *header =
811 (struct kgsl_snapshot_mvc_regs *)buf;
812 struct a6xx_cluster_regs_info *info =
813 (struct a6xx_cluster_regs_info *)priv;
814 struct a6xx_cluster_registers *cluster = info->cluster;
815 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
816 unsigned int *src;
817 int i, j;
818 unsigned int start, end;
819 size_t data_size = 0;
820
821 if (crash_dump_valid == false)
822 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
823
824 if (remain < sizeof(*header)) {
825 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
826 return 0;
827 }
828
829 remain -= sizeof(*header);
830
831 header->ctxt_id = info->ctxt_id;
832 header->cluster_id = cluster->id;
833
834 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
835 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
836
837 for (i = 0; i < cluster->num_sets; i++) {
838 start = cluster->regs[2 * i];
839 end = cluster->regs[2 * i + 1];
840
841 if (remain < (end - start + 3) * 4) {
842 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
843 goto out;
844 }
845
846 remain -= (end - start + 3) * 4;
847 data_size += (end - start + 3) * 4;
848
849 *data++ = start | (1 << 31);
850 *data++ = end;
851 for (j = start; j <= end; j++)
852 *data++ = *src++;
853 }
854
855out:
856 return data_size + sizeof(*header);
857
858}
859
860static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
861 struct kgsl_snapshot *snapshot)
862{
863 int i, j;
864 struct a6xx_cluster_regs_info info;
865
866 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
867 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
868
869 info.cluster = cluster;
870 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
871 info.ctxt_id = j;
872
873 kgsl_snapshot_add_section(device,
874 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
875 a6xx_snapshot_mvc, &info);
876 }
877 }
878}
879
Lynus Vaz20c81272017-02-10 16:22:12 +0530880/* a6xx_dbgc_debug_bus_read() - Read data from trace bus */
881static void a6xx_dbgc_debug_bus_read(struct kgsl_device *device,
882 unsigned int block_id, unsigned int index, unsigned int *val)
883{
884 unsigned int reg;
885
886 reg = (block_id << A6XX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
887 (index << A6XX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
888
889 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
890 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
891 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
892 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
893
894 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
895 val++;
896 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
897}
898
899/* a6xx_snapshot_cbgc_debugbus_block() - Capture debug data for a gpu block */
900static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
901 u8 *buf, size_t remain, void *priv)
902{
903 struct kgsl_snapshot_debugbus *header =
904 (struct kgsl_snapshot_debugbus *)buf;
905 struct adreno_debugbus_block *block = priv;
906 int i;
907 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
908 unsigned int dwords;
909 size_t size;
910
911 dwords = block->dwords;
912
913 /* For a6xx each debug bus data unit is 2 DWORDS */
914 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
915
916 if (remain < size) {
917 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
918 return 0;
919 }
920
921 header->id = block->block_id;
922 header->count = dwords * 2;
923
924 for (i = 0; i < dwords; i++)
925 a6xx_dbgc_debug_bus_read(device, block->block_id, i,
926 &data[i*2]);
927
928 return size;
929}
930
Lynus Vazff24c972017-03-07 19:27:46 +0530931static void _cx_dbgc_regread(unsigned int offsetwords, unsigned int *value)
932{
933 void __iomem *reg;
934
935 if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
936 (offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
937 "Read beyond CX_DBGC block: 0x%x\n", offsetwords))
938 return;
939
940 reg = a6xx_cx_dbgc +
941 ((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);
942 *value = __raw_readl(reg);
943
944 /*
945 * ensure this read finishes before the next one.
946 * i.e. act like normal readl()
947 */
948 rmb();
949}
950
951static void _cx_dbgc_regwrite(unsigned int offsetwords, unsigned int value)
952{
953 void __iomem *reg;
954
955 if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
956 (offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
957 "Write beyond CX_DBGC block: 0x%x\n", offsetwords))
958 return;
959
960 reg = a6xx_cx_dbgc +
961 ((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);
962
963 /*
964 * ensure previous writes post before this one,
965 * i.e. act like normal writel()
966 */
967 wmb();
968 __raw_writel(value, reg);
969}
970
971/* a6xx_cx_dbgc_debug_bus_read() - Read data from trace bus */
972static void a6xx_cx_debug_bus_read(struct kgsl_device *device,
973 unsigned int block_id, unsigned int index, unsigned int *val)
974{
975 unsigned int reg;
976
977 reg = (block_id << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
978 (index << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
979
980 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_A, reg);
981 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_B, reg);
982 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_C, reg);
983 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_D, reg);
984
985 _cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
986 val++;
987 _cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
988}
989
990/*
991 * a6xx_snapshot_cx_dbgc_debugbus_block() - Capture debug data for a gpu
992 * block from the CX DBGC block
993 */
994static size_t a6xx_snapshot_cx_dbgc_debugbus_block(struct kgsl_device *device,
995 u8 *buf, size_t remain, void *priv)
996{
997 struct kgsl_snapshot_debugbus *header =
998 (struct kgsl_snapshot_debugbus *)buf;
999 struct adreno_debugbus_block *block = priv;
1000 int i;
1001 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1002 unsigned int dwords;
1003 size_t size;
1004
1005 dwords = block->dwords;
1006
1007 /* For a6xx each debug bus data unit is 2 DWRODS */
1008 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
1009
1010 if (remain < size) {
1011 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
1012 return 0;
1013 }
1014
1015 header->id = block->block_id;
1016 header->count = dwords * 2;
1017
1018 for (i = 0; i < dwords; i++)
1019 a6xx_cx_debug_bus_read(device, block->block_id, i,
1020 &data[i*2]);
1021
1022 return size;
1023}
1024
Lynus Vaz20c81272017-02-10 16:22:12 +05301025/* a6xx_snapshot_debugbus() - Capture debug bus data */
1026static void a6xx_snapshot_debugbus(struct kgsl_device *device,
1027 struct kgsl_snapshot *snapshot)
1028{
1029 int i;
1030
1031 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
1032 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
1033 (0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
1034 (0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
1035
1036 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLM,
1037 0xf << A6XX_DBGC_CFG_DBGBUS_CTLTM_ENABLE_SHIFT);
1038
1039 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
1040 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
1041 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
1042 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
1043
1044 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_0,
1045 (0 << A6XX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
1046 (1 << A6XX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
1047 (2 << A6XX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
1048 (3 << A6XX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
1049 (4 << A6XX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
1050 (5 << A6XX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
1051 (6 << A6XX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
1052 (7 << A6XX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
1053 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_1,
1054 (8 << A6XX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
1055 (9 << A6XX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
1056 (10 << A6XX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
1057 (11 << A6XX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
1058 (12 << A6XX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
1059 (13 << A6XX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
1060 (14 << A6XX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
1061 (15 << A6XX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
1062
1063 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
1064 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
1065 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
1066 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
1067
Lynus Vazff24c972017-03-07 19:27:46 +05301068 a6xx_cx_dbgc = ioremap(device->reg_phys +
1069 (A6XX_CX_DBGC_CFG_DBGBUS_SEL_A << 2),
1070 (A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2 -
1071 A6XX_CX_DBGC_CFG_DBGBUS_SEL_A + 1) << 2);
1072
1073 if (a6xx_cx_dbgc) {
1074 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLT,
1075 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
1076 (0x4 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
1077 (0x20 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
1078
1079 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLM,
1080 0xf << A6XX_CX_DBGC_CFG_DBGBUS_CNTLM_ENABLE_SHIFT);
1081
1082 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0);
1083 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0);
1084 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0);
1085 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0);
1086
1087 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0,
1088 (0 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
1089 (1 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
1090 (2 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
1091 (3 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
1092 (4 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
1093 (5 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
1094 (6 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
1095 (7 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
1096 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1,
1097 (8 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
1098 (9 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
1099 (10 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
1100 (11 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
1101 (12 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
1102 (13 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
1103 (14 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
1104 (15 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
1105
1106 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0);
1107 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0);
1108 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0);
1109 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0);
1110 } else
1111 KGSL_DRV_ERR(device, "Unable to ioremap CX_DBGC_CFG block\n");
1112
Lynus Vaz20c81272017-02-10 16:22:12 +05301113 for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
1114 kgsl_snapshot_add_section(device,
1115 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
1116 snapshot, a6xx_snapshot_dbgc_debugbus_block,
1117 (void *) &a6xx_dbgc_debugbus_blocks[i]);
1118 }
Lynus Vazff24c972017-03-07 19:27:46 +05301119
1120 if (a6xx_cx_dbgc) {
1121 for (i = 0; i < ARRAY_SIZE(a6xx_cx_dbgc_debugbus_blocks); i++) {
1122 kgsl_snapshot_add_section(device,
1123 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
1124 snapshot, a6xx_snapshot_cx_dbgc_debugbus_block,
1125 (void *) &a6xx_cx_dbgc_debugbus_blocks[i]);
1126 }
1127 iounmap(a6xx_cx_dbgc);
1128 }
Lynus Vaz20c81272017-02-10 16:22:12 +05301129}
1130
Kyle Piefer60733aa2017-03-21 11:24:01 -07001131static size_t a6xx_snapshot_dump_gmu_registers(struct kgsl_device *device,
1132 u8 *buf, size_t remain, void *priv)
1133{
1134 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
1135 struct kgsl_snapshot_registers *regs = priv;
1136 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1137 int count = 0, j, k;
1138
1139 /* Figure out how many registers we are going to dump */
1140 for (j = 0; j < regs->count; j++) {
1141 int start = regs->regs[j * 2];
1142 int end = regs->regs[j * 2 + 1];
1143
1144 count += (end - start + 1);
1145 }
1146
1147 if (remain < (count * 8) + sizeof(*header)) {
1148 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
1149 return 0;
1150 }
1151
1152 for (j = 0; j < regs->count; j++) {
1153 unsigned int start = regs->regs[j * 2];
1154 unsigned int end = regs->regs[j * 2 + 1];
1155
1156 for (k = start; k <= end; k++) {
1157 unsigned int val;
1158
1159 kgsl_gmu_regread(device, k, &val);
1160 *data++ = k;
1161 *data++ = val;
1162 }
1163 }
1164
1165 header->count = count;
1166
1167 /* Return the size of the section */
1168 return (count * 8) + sizeof(*header);
1169}
1170
1171static void a6xx_snapshot_gmu(struct kgsl_device *device,
1172 struct kgsl_snapshot *snapshot)
1173{
1174 struct kgsl_snapshot_registers gmu_regs = {
1175 .regs = a6xx_gmu_registers,
1176 .count = ARRAY_SIZE(a6xx_gmu_registers) / 2,
1177 };
1178
1179 if (!kgsl_gmu_isenabled(device))
1180 return;
1181
1182 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1183 snapshot, a6xx_snapshot_dump_gmu_registers, &gmu_regs);
1184}
1185
Lynus Vaz85150052017-02-21 17:57:48 +05301186/* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
1187static size_t a6xx_snapshot_sqe(struct kgsl_device *device, u8 *buf,
1188 size_t remain, void *priv)
1189{
1190 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1191 struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
1192 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1193 struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
1194
1195 if (remain < DEBUG_SECTION_SZ(1)) {
1196 SNAPSHOT_ERR_NOMEM(device, "SQE VERSION DEBUG");
1197 return 0;
1198 }
1199
1200 /* Dump the SQE firmware version */
1201 header->type = SNAPSHOT_DEBUG_SQE_VERSION;
1202 header->size = 1;
1203 *data = fw->version;
1204
1205 return DEBUG_SECTION_SZ(1);
1206}
1207
Shrenuj Bansal41665402016-12-16 15:25:54 -08001208static void _a6xx_do_crashdump(struct kgsl_device *device)
1209{
1210 unsigned long wait_time;
1211 unsigned int reg = 0;
1212 unsigned int val;
1213
1214 crash_dump_valid = false;
1215
1216 if (a6xx_capturescript.gpuaddr == 0 ||
1217 a6xx_crashdump_registers.gpuaddr == 0)
1218 return;
1219
1220 /* IF the SMMU is stalled we cannot do a crash dump */
1221 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
1222 if (val & BIT(24))
1223 return;
1224
1225 /* Turn on APRIV so we can access the buffers */
1226 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
1227
1228 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
1229 lower_32_bits(a6xx_capturescript.gpuaddr));
1230 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
1231 upper_32_bits(a6xx_capturescript.gpuaddr));
1232 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
1233
1234 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
1235 while (!time_after(jiffies, wait_time)) {
1236 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
1237 if (reg & 0x2)
1238 break;
1239 cpu_relax();
1240 }
1241
1242 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
1243
1244 if (!(reg & 0x2)) {
1245 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
1246 return;
1247 }
1248
1249 crash_dump_valid = true;
1250}
1251
1252/*
1253 * a6xx_snapshot() - A6XX GPU snapshot function
1254 * @adreno_dev: Device being snapshotted
1255 * @snapshot: Pointer to the snapshot instance
1256 *
1257 * This is where all of the A6XX specific bits and pieces are grabbed
1258 * into the snapshot memory
1259 */
1260void a6xx_snapshot(struct adreno_device *adreno_dev,
1261 struct kgsl_snapshot *snapshot)
1262{
1263 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1264 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
1265 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
1266
1267 /* Try to run the crash dumper */
1268 _a6xx_do_crashdump(device);
1269
1270 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1271 snapshot, a6xx_snapshot_registers, NULL);
1272
1273 adreno_snapshot_vbif_registers(device, snapshot,
1274 a6xx_vbif_snapshot_registers,
1275 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
1276
1277 /* CP_SQE indexed registers */
1278 kgsl_snapshot_indexed_registers(device, snapshot,
1279 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
1280 0, snap_data->sect_sizes->cp_pfp);
1281
1282 /* CP_DRAW_STATE */
1283 kgsl_snapshot_indexed_registers(device, snapshot,
1284 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
1285 0, 0x100);
1286
1287 /* SQE_UCODE Cache */
1288 kgsl_snapshot_indexed_registers(device, snapshot,
1289 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
1290 0, 0x6000);
1291
1292 /* CP ROQ */
1293 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1294 snapshot, adreno_snapshot_cp_roq,
1295 &snap_data->sect_sizes->roq);
1296
Lynus Vaz85150052017-02-21 17:57:48 +05301297 /* SQE Firmware */
1298 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1299 snapshot, a6xx_snapshot_sqe, NULL);
1300
Lynus Vaza5922742017-03-14 18:50:54 +05301301 /* Mempool debug data */
1302 a6xx_snapshot_mempool(device, snapshot);
1303
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301304 /* Shader memory */
1305 a6xx_snapshot_shader(device, snapshot);
1306
Shrenuj Bansal41665402016-12-16 15:25:54 -08001307 /* MVC register section */
1308 a6xx_snapshot_mvc_regs(device, snapshot);
1309
Lynus Vaz461e2382017-01-16 19:35:41 +05301310 /* registers dumped through DBG AHB */
1311 a6xx_snapshot_dbgahb_regs(device, snapshot);
1312
Lynus Vaz20c81272017-02-10 16:22:12 +05301313 a6xx_snapshot_debugbus(device, snapshot);
Kyle Piefer60733aa2017-03-21 11:24:01 -07001314
1315 /* GMU TCM data dumped through AHB */
1316 a6xx_snapshot_gmu(device, snapshot);
Shrenuj Bansal41665402016-12-16 15:25:54 -08001317}
1318
1319static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
1320{
1321 int qwords = 0;
1322 unsigned int i, j, k;
1323 unsigned int count;
1324
1325 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1326 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1327
1328 cluster->offset0 = *offset;
1329 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1330
1331 if (j == 1)
1332 cluster->offset1 = *offset;
1333
1334 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
1335 ptr[qwords++] =
1336 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
1337 (1 << 21) | 1;
1338
1339 for (k = 0; k < cluster->num_sets; k++) {
1340 count = REG_PAIR_COUNT(cluster->regs, k);
1341 ptr[qwords++] =
1342 a6xx_crashdump_registers.gpuaddr + *offset;
1343 ptr[qwords++] =
1344 (((uint64_t)cluster->regs[2 * k]) << 44) |
1345 count;
1346
1347 *offset += count * sizeof(unsigned int);
1348 }
1349 }
1350 }
1351
1352 return qwords;
1353}
1354
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301355static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block,
1356 uint64_t *ptr, uint64_t *offset)
1357{
1358 int qwords = 0;
1359 unsigned int j;
1360
1361 /* Capture each bank in the block */
1362 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
1363 /* Program the aperture */
1364 ptr[qwords++] =
1365 (block->statetype << A6XX_SHADER_STATETYPE_SHIFT) | j;
1366 ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_READ_SEL << 44)) |
1367 (1 << 21) | 1;
1368
1369 /* Read all the data in one chunk */
1370 ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset;
1371 ptr[qwords++] =
1372 (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
1373 block->sz;
1374
1375 /* Remember the offset of the first bank for easy access */
1376 if (j == 0)
1377 block->offset = *offset;
1378
1379 *offset += block->sz * sizeof(unsigned int);
1380 }
1381
1382 return qwords;
1383}
1384
Shrenuj Bansal41665402016-12-16 15:25:54 -08001385void a6xx_crashdump_init(struct adreno_device *adreno_dev)
1386{
1387 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1388 unsigned int script_size = 0;
1389 unsigned int data_size = 0;
1390 unsigned int i, j, k;
1391 uint64_t *ptr;
1392 uint64_t offset = 0;
1393
1394 if (a6xx_capturescript.gpuaddr != 0 &&
1395 a6xx_crashdump_registers.gpuaddr != 0)
1396 return;
1397
1398 /*
1399 * We need to allocate two buffers:
1400 * 1 - the buffer to hold the draw script
1401 * 2 - the buffer to hold the data
1402 */
1403
1404 /*
1405 * To save the registers, we need 16 bytes per register pair for the
1406 * script and a dword for each register in the data
1407 */
1408 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1409 struct cdregs *regs = &_a6xx_cd_registers[i];
1410
1411 /* Each pair needs 16 bytes (2 qwords) */
1412 script_size += (regs->size / 2) * 16;
1413
1414 /* Each register needs a dword in the data */
1415 for (j = 0; j < regs->size / 2; j++)
1416 data_size += REG_PAIR_COUNT(regs->regs, j) *
1417 sizeof(unsigned int);
1418
1419 }
1420
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301421 /*
1422 * To save the shader blocks for each block in each type we need 32
1423 * bytes for the script (16 bytes to program the aperture and 16 to
1424 * read the data) and then a block specific number of bytes to hold
1425 * the data
1426 */
1427 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1428 script_size += 32 * A6XX_NUM_SHADER_BANKS;
1429 data_size += a6xx_shader_blocks[i].sz * sizeof(unsigned int) *
1430 A6XX_NUM_SHADER_BANKS;
1431 }
1432
Shrenuj Bansal41665402016-12-16 15:25:54 -08001433 /* Calculate the script and data size for MVC registers */
1434 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1435 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1436
1437 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1438
1439 /* 16 bytes for programming the aperture */
1440 script_size += 16;
1441
1442 /* Reading each pair of registers takes 16 bytes */
1443 script_size += 16 * cluster->num_sets;
1444
1445 /* A dword per register read from the cluster list */
1446 for (k = 0; k < cluster->num_sets; k++)
1447 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1448 sizeof(unsigned int);
1449 }
1450 }
1451
1452 /* Now allocate the script and data buffers */
1453
1454 /* The script buffers needs 2 extra qwords on the end */
1455 if (kgsl_allocate_global(device, &a6xx_capturescript,
1456 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
1457 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
1458 return;
1459
1460 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
1461 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
1462 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
1463 return;
1464 }
1465
1466 /* Build the crash script */
1467
1468 ptr = (uint64_t *)a6xx_capturescript.hostptr;
1469
1470 /* For the registers, program a read command for each pair */
1471 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1472 struct cdregs *regs = &_a6xx_cd_registers[i];
1473
1474 for (j = 0; j < regs->size / 2; j++) {
1475 unsigned int r = REG_PAIR_COUNT(regs->regs, j);
1476 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
1477 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
1478 offset += r * sizeof(unsigned int);
1479 }
1480 }
1481
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301482 /* Program each shader block */
1483 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1484 ptr += _a6xx_crashdump_init_shader(&a6xx_shader_blocks[i], ptr,
1485 &offset);
1486 }
1487
Shrenuj Bansal41665402016-12-16 15:25:54 -08001488 /* Program the capturescript for the MVC regsiters */
1489 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
1490
1491 *ptr++ = 0;
1492 *ptr++ = 0;
1493}