blob: 54acd73998e2da0831da5fe4fdfb445aae6e1818 [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;
Lynus Vaz1e258612017-04-27 21:35:22 +0530124 unsigned int offset0;
125 unsigned int offset1;
Lynus Vaz461e2382017-01-16 19:35:41 +0530126} a6xx_dbgahb_ctx_clusters[] = {
127 { CP_CLUSTER_SP_VS, 0x0002E000, 0x41, a6xx_sp_vs_hlsq_cluster,
128 ARRAY_SIZE(a6xx_sp_vs_hlsq_cluster) / 2 },
129 { CP_CLUSTER_SP_VS, 0x0002A000, 0x21, a6xx_sp_vs_sp_cluster,
130 ARRAY_SIZE(a6xx_sp_vs_sp_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700131 { CP_CLUSTER_SP_VS, 0x0002E000, 0x41, a6xx_hlsq_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530132 ARRAY_SIZE(a6xx_hlsq_duplicate_cluster) / 2 },
133 { CP_CLUSTER_SP_VS, 0x0002F000, 0x45, a6xx_hlsq_2d_duplicate_cluster,
134 ARRAY_SIZE(a6xx_hlsq_2d_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700135 { CP_CLUSTER_SP_VS, 0x0002A000, 0x21, a6xx_sp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530136 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700137 { CP_CLUSTER_SP_VS, 0x0002C000, 0x1, a6xx_tp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530138 ARRAY_SIZE(a6xx_tp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700139 { CP_CLUSTER_SP_PS, 0x0002E000, 0x42, a6xx_sp_ps_hlsq_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530140 ARRAY_SIZE(a6xx_sp_ps_hlsq_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700141 { CP_CLUSTER_SP_PS, 0x0002F000, 0x46, a6xx_sp_ps_hlsq_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530142 ARRAY_SIZE(a6xx_sp_ps_hlsq_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700143 { CP_CLUSTER_SP_PS, 0x0002A000, 0x22, a6xx_sp_ps_sp_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530144 ARRAY_SIZE(a6xx_sp_ps_sp_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700145 { CP_CLUSTER_SP_PS, 0x0002B000, 0x26, a6xx_sp_ps_sp_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530146 ARRAY_SIZE(a6xx_sp_ps_sp_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700147 { CP_CLUSTER_SP_PS, 0x0002C000, 0x2, a6xx_sp_ps_tp_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530148 ARRAY_SIZE(a6xx_sp_ps_tp_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700149 { CP_CLUSTER_SP_PS, 0x0002D000, 0x6, a6xx_sp_ps_tp_2d_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530150 ARRAY_SIZE(a6xx_sp_ps_tp_2d_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700151 { CP_CLUSTER_SP_PS, 0x0002E000, 0x42, a6xx_hlsq_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530152 ARRAY_SIZE(a6xx_hlsq_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700153 { CP_CLUSTER_SP_VS, 0x0002A000, 0x22, a6xx_sp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530154 ARRAY_SIZE(a6xx_sp_duplicate_cluster) / 2 },
Shrenuj Bansalcbdf19b2017-04-13 11:28:51 -0700155 { CP_CLUSTER_SP_VS, 0x0002C000, 0x2, a6xx_tp_duplicate_cluster,
Lynus Vaz461e2382017-01-16 19:35:41 +0530156 ARRAY_SIZE(a6xx_tp_duplicate_cluster) / 2 },
157};
158
159struct a6xx_cluster_dbgahb_regs_info {
160 struct a6xx_cluster_dbgahb_registers *cluster;
161 unsigned int ctxt_id;
162};
163
164static const unsigned int a6xx_hlsq_non_ctx_registers[] = {
165 0xBE00, 0xBE01, 0xBE04, 0xBE05, 0xBE08, 0xBE09, 0xBE10, 0xBE15,
166 0xBE20, 0xBE23,
167};
168
169static const unsigned int a6xx_sp_non_ctx_registers[] = {
170 0xAE00, 0xAE04, 0xAE0C, 0xAE0C, 0xAE0F, 0xAE2B, 0xAE30, 0xAE32,
171 0xAE35, 0xAE35, 0xAE3A, 0xAE3F, 0xAE50, 0xAE52,
172};
173
174static const unsigned int a6xx_tp_non_ctx_registers[] = {
175 0xB600, 0xB601, 0xB604, 0xB605, 0xB610, 0xB61B, 0xB620, 0xB623,
176};
177
178static struct a6xx_non_ctx_dbgahb_registers {
179 unsigned int regbase;
180 unsigned int statetype;
181 const unsigned int *regs;
182 unsigned int num_sets;
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -0600183 unsigned int offset;
Lynus Vaz461e2382017-01-16 19:35:41 +0530184} a6xx_non_ctx_dbgahb[] = {
185 { 0x0002F800, 0x40, a6xx_hlsq_non_ctx_registers,
186 ARRAY_SIZE(a6xx_hlsq_non_ctx_registers) / 2 },
187 { 0x0002B800, 0x20, a6xx_sp_non_ctx_registers,
188 ARRAY_SIZE(a6xx_sp_non_ctx_registers) / 2 },
189 { 0x0002D800, 0x0, a6xx_tp_non_ctx_registers,
190 ARRAY_SIZE(a6xx_tp_non_ctx_registers) / 2 },
191};
192
Shrenuj Bansal41665402016-12-16 15:25:54 -0800193static const unsigned int a6xx_vbif_ver_20xxxxxx_registers[] = {
194 /* VBIF */
195 0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302D, 0x3030, 0x3031,
196 0x3034, 0x3036, 0x303C, 0x303D, 0x3040, 0x3040, 0x3042, 0x3042,
197 0x3049, 0x3049, 0x3058, 0x3058, 0x305A, 0x3061, 0x3064, 0x3068,
198 0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094,
199 0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8,
200 0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100,
201 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
202 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x3154, 0x3154,
203 0x3156, 0x3156, 0x3158, 0x3158, 0x315A, 0x315A, 0x315C, 0x315C,
204 0x315E, 0x315E, 0x3160, 0x3160, 0x3162, 0x3162, 0x340C, 0x340C,
205 0x3410, 0x3410, 0x3800, 0x3801,
206};
207
Kyle Piefer60733aa2017-03-21 11:24:01 -0700208static const unsigned int a6xx_gmu_registers[] = {
Kyle Pieferbce21702017-06-08 09:21:28 -0700209 /* GMU GX */
210 0x1A800, 0x1A800, 0x1A810, 0x1A813, 0x1A816, 0x1A816, 0x1A818, 0x1A81B,
211 0x1A81E, 0x1A81E, 0x1A820, 0x1A823, 0x1A826, 0x1A826, 0x1A828, 0x1A82B,
212 0x1A82E, 0x1A82E, 0x1A830, 0x1A833, 0x1A836, 0x1A836, 0x1A838, 0x1A83B,
213 0x1A83E, 0x1A83E, 0x1A840, 0x1A843, 0x1A846, 0x1A846, 0x1A880, 0x1A884,
214 0x1A900, 0x1A92B, 0x1A940, 0x1A940,
215 /* GMU TCM */
Kyle Piefer60733aa2017-03-21 11:24:01 -0700216 0x1B400, 0x1C3FF, 0x1C400, 0x1D3FF,
Kyle Pieferbce21702017-06-08 09:21:28 -0700217 /* GMU CX */
218 0x1F400, 0x1F407, 0x1F410, 0x1F412, 0x1F500, 0x1F500, 0x1F507, 0x1F50A,
219 0x1F800, 0x1F804, 0x1F807, 0x1F808, 0x1F80B, 0x1F80C, 0x1F80F, 0x1F81C,
220 0x1F824, 0x1F82A, 0x1F82D, 0x1F830, 0x1F840, 0x1F853, 0x1F887, 0x1F889,
221 0x1F8A0, 0x1F8A2, 0x1F8A4, 0x1F8AF, 0x1F8C0, 0x1F8C3, 0x1F8D0, 0x1F8D0,
222 0x1F8E4, 0x1F8E4, 0x1F8E8, 0x1F8EC, 0x1F900, 0x1F903, 0x1F940, 0x1F940,
223 0x1F942, 0x1F944, 0x1F94C, 0x1F94D, 0x1F94F, 0x1F951, 0x1F954, 0x1F954,
224 0x1F957, 0x1F958, 0x1F95D, 0x1F95D, 0x1F962, 0x1F962, 0x1F964, 0x1F965,
225 0x1F980, 0x1F986, 0x1F990, 0x1F99E, 0x1F9C0, 0x1F9C0, 0x1F9C5, 0x1F9CC,
226 0x1F9E0, 0x1F9E2, 0x1F9F0, 0x1F9F0, 0x1FA00, 0x1FA03,
227 /* GPU RSCC */
228 0x23740, 0x23742, 0x23744, 0x23747, 0x2374C, 0x23787, 0x237EC, 0x237EF,
229 0x237F4, 0x2382F, 0x23894, 0x23897, 0x2389C, 0x238D7, 0x2393C, 0x2393F,
230 0x23944, 0x2397F,
231 /* GMU AO */
232 0x23B00, 0x23B16, 0x23C00, 0x23C00,
233 /* GPU CC */
234 0x24000, 0x24012, 0x24040, 0x24052, 0x24400, 0x24404, 0x24407, 0x2440B,
235 0x24415, 0x2441C, 0x2441E, 0x2442D, 0x2443C, 0x2443D, 0x2443F, 0x24440,
236 0x24442, 0x24449, 0x24458, 0x2445A, 0x24540, 0x2455E, 0x24800, 0x24802,
237 0x24C00, 0x24C02, 0x25400, 0x25402, 0x25800, 0x25802, 0x25C00, 0x25C02,
238 0x26000, 0x26002,
239 /* GPU CC ACD */
240 0x26400, 0x26416, 0x26420, 0x26427,
Kyle Piefer60733aa2017-03-21 11:24:01 -0700241};
242
Shrenuj Bansal41665402016-12-16 15:25:54 -0800243static const struct adreno_vbif_snapshot_registers
244a6xx_vbif_snapshot_registers[] = {
245 { 0x20040000, 0xFF000000, a6xx_vbif_ver_20xxxxxx_registers,
246 ARRAY_SIZE(a6xx_vbif_ver_20xxxxxx_registers)/2},
247};
248
249/*
250 * Set of registers to dump for A6XX on snapshot.
251 * Registers in pairs - first value is the start offset, second
252 * is the stop offset (inclusive)
253 */
254
255static const unsigned int a6xx_registers[] = {
256 /* RBBM */
Lynus Vazdb0be0a2017-04-20 18:09:17 +0530257 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001B,
258 0x001e, 0x0032, 0x0038, 0x003C, 0x0042, 0x0042, 0x0044, 0x0044,
259 0x0047, 0x0047, 0x0056, 0x0056, 0x00AD, 0x00AE, 0x00B0, 0x00FB,
260 0x0100, 0x011D, 0x0200, 0x020D, 0x0210, 0x0213, 0x0218, 0x023D,
261 0x0400, 0x04F9, 0x0500, 0x0500, 0x0505, 0x050B, 0x050E, 0x0511,
262 0x0533, 0x0533, 0x0540, 0x0555,
Shrenuj Bansal41665402016-12-16 15:25:54 -0800263 /* CP */
264 0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0827,
265 0x0830, 0x0833, 0x0840, 0x0843, 0x084F, 0x086F, 0x0880, 0x088A,
266 0x08A0, 0x08AB, 0x08C0, 0x08C4, 0x08D0, 0x08DD, 0x08F0, 0x08F3,
267 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093E, 0x0942, 0x094D,
268 0x0980, 0x0984, 0x098D, 0x0996, 0x0998, 0x099E, 0x09A0, 0x09A6,
269 0x09A8, 0x09AE, 0x09B0, 0x09B1, 0x09C2, 0x09C8, 0x0A00, 0x0A03,
270 /* VSC */
271 0x0C00, 0x0C04, 0x0C06, 0x0C06, 0x0C10, 0x0CD9, 0x0E00, 0x0E0E,
272 /* UCHE */
273 0x0E10, 0x0E13, 0x0E17, 0x0E19, 0x0E1C, 0x0E2B, 0x0E30, 0x0E32,
274 0x0E38, 0x0E39,
275 /* GRAS */
Lynus Vazdb0be0a2017-04-20 18:09:17 +0530276 0x8600, 0x8601, 0x8610, 0x861B, 0x8620, 0x8620, 0x8628, 0x862B,
277 0x8630, 0x8637,
Shrenuj Bansal41665402016-12-16 15:25:54 -0800278 /* RB */
279 0x8E01, 0x8E01, 0x8E04, 0x8E05, 0x8E07, 0x8E08, 0x8E0C, 0x8E0C,
280 0x8E10, 0x8E1C, 0x8E20, 0x8E25, 0x8E28, 0x8E28, 0x8E2C, 0x8E2F,
281 0x8E3B, 0x8E3E, 0x8E40, 0x8E43, 0x8E50, 0x8E5E, 0x8E70, 0x8E77,
282 /* VPC */
283 0x9600, 0x9604, 0x9624, 0x9637,
284 /* PC */
285 0x9E00, 0x9E01, 0x9E03, 0x9E0E, 0x9E11, 0x9E16, 0x9E19, 0x9E19,
286 0x9E1C, 0x9E1C, 0x9E20, 0x9E23, 0x9E30, 0x9E31, 0x9E34, 0x9E34,
287 0x9E70, 0x9E72, 0x9E78, 0x9E79, 0x9E80, 0x9FFF,
288 /* VFD */
289 0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
Lynus Vazdb0be0a2017-04-20 18:09:17 +0530290 0xA630, 0xA630,
Shrenuj Bansal41665402016-12-16 15:25:54 -0800291};
292
Lynus Vaz20c81272017-02-10 16:22:12 +0530293enum a6xx_debugbus_id {
294 A6XX_DBGBUS_CP = 0x1,
295 A6XX_DBGBUS_RBBM = 0x2,
296 A6XX_DBGBUS_VBIF = 0x3,
297 A6XX_DBGBUS_HLSQ = 0x4,
298 A6XX_DBGBUS_UCHE = 0x5,
299 A6XX_DBGBUS_DPM = 0x6,
300 A6XX_DBGBUS_TESS = 0x7,
301 A6XX_DBGBUS_PC = 0x8,
302 A6XX_DBGBUS_VFDP = 0x9,
303 A6XX_DBGBUS_VPC = 0xa,
304 A6XX_DBGBUS_TSE = 0xb,
305 A6XX_DBGBUS_RAS = 0xc,
306 A6XX_DBGBUS_VSC = 0xd,
307 A6XX_DBGBUS_COM = 0xe,
308 A6XX_DBGBUS_LRZ = 0x10,
309 A6XX_DBGBUS_A2D = 0x11,
310 A6XX_DBGBUS_CCUFCHE = 0x12,
Lynus Vazecd472c2017-04-18 14:15:57 +0530311 A6XX_DBGBUS_GMU_CX = 0x13,
Lynus Vaz20c81272017-02-10 16:22:12 +0530312 A6XX_DBGBUS_RBP = 0x14,
313 A6XX_DBGBUS_DCS = 0x15,
314 A6XX_DBGBUS_RBBM_CFG = 0x16,
315 A6XX_DBGBUS_CX = 0x17,
Lynus Vazecd472c2017-04-18 14:15:57 +0530316 A6XX_DBGBUS_GMU_GX = 0x18,
Lynus Vaz20c81272017-02-10 16:22:12 +0530317 A6XX_DBGBUS_TPFCHE = 0x19,
318 A6XX_DBGBUS_GPC = 0x1d,
319 A6XX_DBGBUS_LARC = 0x1e,
320 A6XX_DBGBUS_HLSQ_SPTP = 0x1f,
321 A6XX_DBGBUS_RB_0 = 0x20,
322 A6XX_DBGBUS_RB_1 = 0x21,
323 A6XX_DBGBUS_UCHE_WRAPPER = 0x24,
324 A6XX_DBGBUS_CCU_0 = 0x28,
325 A6XX_DBGBUS_CCU_1 = 0x29,
326 A6XX_DBGBUS_VFD_0 = 0x38,
327 A6XX_DBGBUS_VFD_1 = 0x39,
328 A6XX_DBGBUS_VFD_2 = 0x3a,
329 A6XX_DBGBUS_VFD_3 = 0x3b,
330 A6XX_DBGBUS_SP_0 = 0x40,
331 A6XX_DBGBUS_SP_1 = 0x41,
332 A6XX_DBGBUS_TPL1_0 = 0x48,
333 A6XX_DBGBUS_TPL1_1 = 0x49,
334 A6XX_DBGBUS_TPL1_2 = 0x4a,
335 A6XX_DBGBUS_TPL1_3 = 0x4b,
336};
337
338static const struct adreno_debugbus_block a6xx_dbgc_debugbus_blocks[] = {
339 { A6XX_DBGBUS_CP, 0x100, },
340 { A6XX_DBGBUS_RBBM, 0x100, },
341 { A6XX_DBGBUS_HLSQ, 0x100, },
342 { A6XX_DBGBUS_UCHE, 0x100, },
343 { A6XX_DBGBUS_DPM, 0x100, },
344 { A6XX_DBGBUS_TESS, 0x100, },
345 { A6XX_DBGBUS_PC, 0x100, },
346 { A6XX_DBGBUS_VFDP, 0x100, },
347 { A6XX_DBGBUS_VPC, 0x100, },
348 { A6XX_DBGBUS_TSE, 0x100, },
349 { A6XX_DBGBUS_RAS, 0x100, },
350 { A6XX_DBGBUS_VSC, 0x100, },
351 { A6XX_DBGBUS_COM, 0x100, },
352 { A6XX_DBGBUS_LRZ, 0x100, },
353 { A6XX_DBGBUS_A2D, 0x100, },
354 { A6XX_DBGBUS_CCUFCHE, 0x100, },
355 { A6XX_DBGBUS_RBP, 0x100, },
356 { A6XX_DBGBUS_DCS, 0x100, },
357 { A6XX_DBGBUS_RBBM_CFG, 0x100, },
Lynus Vazecd472c2017-04-18 14:15:57 +0530358 { A6XX_DBGBUS_GMU_GX, 0x100, },
Lynus Vaz20c81272017-02-10 16:22:12 +0530359 { A6XX_DBGBUS_TPFCHE, 0x100, },
360 { A6XX_DBGBUS_GPC, 0x100, },
361 { A6XX_DBGBUS_LARC, 0x100, },
362 { A6XX_DBGBUS_HLSQ_SPTP, 0x100, },
363 { A6XX_DBGBUS_RB_0, 0x100, },
364 { A6XX_DBGBUS_RB_1, 0x100, },
365 { A6XX_DBGBUS_UCHE_WRAPPER, 0x100, },
366 { A6XX_DBGBUS_CCU_0, 0x100, },
367 { A6XX_DBGBUS_CCU_1, 0x100, },
368 { A6XX_DBGBUS_VFD_0, 0x100, },
369 { A6XX_DBGBUS_VFD_1, 0x100, },
370 { A6XX_DBGBUS_VFD_2, 0x100, },
371 { A6XX_DBGBUS_VFD_3, 0x100, },
372 { A6XX_DBGBUS_SP_0, 0x100, },
373 { A6XX_DBGBUS_SP_1, 0x100, },
374 { A6XX_DBGBUS_TPL1_0, 0x100, },
375 { A6XX_DBGBUS_TPL1_1, 0x100, },
376 { A6XX_DBGBUS_TPL1_2, 0x100, },
377 { A6XX_DBGBUS_TPL1_3, 0x100, },
378};
Shrenuj Bansal41665402016-12-16 15:25:54 -0800379
Lynus Vazff24c972017-03-07 19:27:46 +0530380static void __iomem *a6xx_cx_dbgc;
381static const struct adreno_debugbus_block a6xx_cx_dbgc_debugbus_blocks[] = {
382 { A6XX_DBGBUS_VBIF, 0x100, },
Lynus Vazecd472c2017-04-18 14:15:57 +0530383 { A6XX_DBGBUS_GMU_CX, 0x100, },
Lynus Vazff24c972017-03-07 19:27:46 +0530384 { A6XX_DBGBUS_CX, 0x100, },
385};
386
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530387#define A6XX_NUM_SHADER_BANKS 3
388#define A6XX_SHADER_STATETYPE_SHIFT 8
389
390enum a6xx_shader_obj {
391 A6XX_TP0_TMO_DATA = 0x9,
392 A6XX_TP0_SMO_DATA = 0xa,
393 A6XX_TP0_MIPMAP_BASE_DATA = 0xb,
394 A6XX_TP1_TMO_DATA = 0x19,
395 A6XX_TP1_SMO_DATA = 0x1a,
396 A6XX_TP1_MIPMAP_BASE_DATA = 0x1b,
397 A6XX_SP_INST_DATA = 0x29,
398 A6XX_SP_LB_0_DATA = 0x2a,
399 A6XX_SP_LB_1_DATA = 0x2b,
400 A6XX_SP_LB_2_DATA = 0x2c,
401 A6XX_SP_LB_3_DATA = 0x2d,
402 A6XX_SP_LB_4_DATA = 0x2e,
403 A6XX_SP_LB_5_DATA = 0x2f,
404 A6XX_SP_CB_BINDLESS_DATA = 0x30,
405 A6XX_SP_CB_LEGACY_DATA = 0x31,
406 A6XX_SP_UAV_DATA = 0x32,
407 A6XX_SP_INST_TAG = 0x33,
408 A6XX_SP_CB_BINDLESS_TAG = 0x34,
409 A6XX_SP_TMO_UMO_TAG = 0x35,
410 A6XX_SP_SMO_TAG = 0x36,
411 A6XX_SP_STATE_DATA = 0x37,
412 A6XX_HLSQ_CHUNK_CVS_RAM = 0x49,
413 A6XX_HLSQ_CHUNK_CPS_RAM = 0x4a,
414 A6XX_HLSQ_CHUNK_CVS_RAM_TAG = 0x4b,
415 A6XX_HLSQ_CHUNK_CPS_RAM_TAG = 0x4c,
416 A6XX_HLSQ_ICB_CVS_CB_BASE_TAG = 0x4d,
417 A6XX_HLSQ_ICB_CPS_CB_BASE_TAG = 0x4e,
418 A6XX_HLSQ_CVS_MISC_RAM = 0x50,
419 A6XX_HLSQ_CPS_MISC_RAM = 0x51,
420 A6XX_HLSQ_INST_RAM = 0x52,
421 A6XX_HLSQ_GFX_CVS_CONST_RAM = 0x53,
422 A6XX_HLSQ_GFX_CPS_CONST_RAM = 0x54,
423 A6XX_HLSQ_CVS_MISC_RAM_TAG = 0x55,
424 A6XX_HLSQ_CPS_MISC_RAM_TAG = 0x56,
425 A6XX_HLSQ_INST_RAM_TAG = 0x57,
426 A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG = 0x58,
427 A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG = 0x59,
428 A6XX_HLSQ_PWR_REST_RAM = 0x5a,
429 A6XX_HLSQ_PWR_REST_TAG = 0x5b,
430 A6XX_HLSQ_DATAPATH_META = 0x60,
431 A6XX_HLSQ_FRONTEND_META = 0x61,
432 A6XX_HLSQ_INDIRECT_META = 0x62,
433 A6XX_HLSQ_BACKEND_META = 0x63
434};
435
436struct a6xx_shader_block {
437 unsigned int statetype;
438 unsigned int sz;
439 uint64_t offset;
440};
441
442struct a6xx_shader_block_info {
443 struct a6xx_shader_block *block;
444 unsigned int bank;
445 uint64_t offset;
446};
447
448static struct a6xx_shader_block a6xx_shader_blocks[] = {
449 {A6XX_TP0_TMO_DATA, 0x200},
450 {A6XX_TP0_SMO_DATA, 0x80,},
451 {A6XX_TP0_MIPMAP_BASE_DATA, 0x3C0},
452 {A6XX_TP1_TMO_DATA, 0x200},
453 {A6XX_TP1_SMO_DATA, 0x80,},
454 {A6XX_TP1_MIPMAP_BASE_DATA, 0x3C0},
455 {A6XX_SP_INST_DATA, 0x800},
456 {A6XX_SP_LB_0_DATA, 0x800},
457 {A6XX_SP_LB_1_DATA, 0x800},
458 {A6XX_SP_LB_2_DATA, 0x800},
459 {A6XX_SP_LB_3_DATA, 0x800},
460 {A6XX_SP_LB_4_DATA, 0x800},
461 {A6XX_SP_LB_5_DATA, 0x200},
462 {A6XX_SP_CB_BINDLESS_DATA, 0x2000},
463 {A6XX_SP_CB_LEGACY_DATA, 0x280,},
464 {A6XX_SP_UAV_DATA, 0x80,},
465 {A6XX_SP_INST_TAG, 0x80,},
466 {A6XX_SP_CB_BINDLESS_TAG, 0x80,},
467 {A6XX_SP_TMO_UMO_TAG, 0x80,},
468 {A6XX_SP_SMO_TAG, 0x80},
469 {A6XX_SP_STATE_DATA, 0x3F},
470 {A6XX_HLSQ_CHUNK_CVS_RAM, 0x1C0},
471 {A6XX_HLSQ_CHUNK_CPS_RAM, 0x280},
472 {A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40,},
473 {A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40,},
474 {A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4,},
475 {A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4,},
476 {A6XX_HLSQ_CVS_MISC_RAM, 0x1C0},
477 {A6XX_HLSQ_CPS_MISC_RAM, 0x580},
478 {A6XX_HLSQ_INST_RAM, 0x800},
479 {A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800},
480 {A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800},
481 {A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8,},
482 {A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4,},
483 {A6XX_HLSQ_INST_RAM_TAG, 0x80,},
484 {A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xC,},
485 {A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10},
486 {A6XX_HLSQ_PWR_REST_RAM, 0x28},
487 {A6XX_HLSQ_PWR_REST_TAG, 0x14},
488 {A6XX_HLSQ_DATAPATH_META, 0x40,},
489 {A6XX_HLSQ_FRONTEND_META, 0x40},
490 {A6XX_HLSQ_INDIRECT_META, 0x40,}
491};
492
Shrenuj Bansal41665402016-12-16 15:25:54 -0800493static struct kgsl_memdesc a6xx_capturescript;
494static struct kgsl_memdesc a6xx_crashdump_registers;
495static bool crash_dump_valid;
496
497static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
498 u8 *buf, size_t remain)
499{
500 struct kgsl_snapshot_registers regs = {
501 .regs = a6xx_registers,
502 .count = ARRAY_SIZE(a6xx_registers) / 2,
503 };
504
505 return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
506}
507
508static struct cdregs {
509 const unsigned int *regs;
510 unsigned int size;
511} _a6xx_cd_registers[] = {
512 { a6xx_registers, ARRAY_SIZE(a6xx_registers) },
513};
514
515#define REG_PAIR_COUNT(_a, _i) \
516 (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
517
518static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
519 size_t remain, void *priv)
520{
521 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
522 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
523 unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
524 unsigned int i, j, k;
525 unsigned int count = 0;
526
527 if (crash_dump_valid == false)
528 return a6xx_legacy_snapshot_registers(device, buf, remain);
529
530 if (remain < sizeof(*header)) {
531 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
532 return 0;
533 }
534
535 remain -= sizeof(*header);
536
537 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
538 struct cdregs *regs = &_a6xx_cd_registers[i];
539
540 for (j = 0; j < regs->size / 2; j++) {
541 unsigned int start = regs->regs[2 * j];
542 unsigned int end = regs->regs[(2 * j) + 1];
543
544 if (remain < ((end - start) + 1) * 8) {
545 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
546 goto out;
547 }
548
549 remain -= ((end - start) + 1) * 8;
550
551 for (k = start; k <= end; k++, count++) {
552 *data++ = k;
553 *data++ = *src++;
554 }
555 }
556 }
557
558out:
559 header->count = count;
560
561 /* Return the size of the section */
562 return (count * 8) + sizeof(*header);
563}
564
Lynus Vaz9ad67a32017-03-10 14:55:02 +0530565static size_t a6xx_snapshot_shader_memory(struct kgsl_device *device,
566 u8 *buf, size_t remain, void *priv)
567{
568 struct kgsl_snapshot_shader *header =
569 (struct kgsl_snapshot_shader *) buf;
570 struct a6xx_shader_block_info *info =
571 (struct a6xx_shader_block_info *) priv;
572 struct a6xx_shader_block *block = info->block;
573 unsigned int *data = (unsigned int *) (buf + sizeof(*header));
574
575 if (remain < SHADER_SECTION_SZ(block->sz)) {
576 SNAPSHOT_ERR_NOMEM(device, "SHADER MEMORY");
577 return 0;
578 }
579
580 header->type = block->statetype;
581 header->index = info->bank;
582 header->size = block->sz;
583
584 memcpy(data, a6xx_crashdump_registers.hostptr + info->offset,
585 block->sz);
586
587 return SHADER_SECTION_SZ(block->sz);
588}
589
590static void a6xx_snapshot_shader(struct kgsl_device *device,
591 struct kgsl_snapshot *snapshot)
592{
593 unsigned int i, j;
594 struct a6xx_shader_block_info info;
595
596 /* Shader blocks can only be read by the crash dumper */
597 if (crash_dump_valid == false)
598 return;
599
600 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
601 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
602 info.block = &a6xx_shader_blocks[i];
603 info.bank = j;
604 info.offset = a6xx_shader_blocks[i].offset +
605 (j * a6xx_shader_blocks[i].sz);
606
607 /* Shader working/shadow memory */
608 kgsl_snapshot_add_section(device,
609 KGSL_SNAPSHOT_SECTION_SHADER,
610 snapshot, a6xx_snapshot_shader_memory, &info);
611 }
612 }
613}
614
Lynus Vaza5922742017-03-14 18:50:54 +0530615static void a6xx_snapshot_mempool(struct kgsl_device *device,
616 struct kgsl_snapshot *snapshot)
617{
618 unsigned int pool_size;
Lynus Vazb8e43d52017-04-20 14:47:37 +0530619 u8 *buf = snapshot->ptr;
Lynus Vaza5922742017-03-14 18:50:54 +0530620
Lynus Vazb8e43d52017-04-20 14:47:37 +0530621 /* Set the mempool size to 0 to stabilize it while dumping */
Lynus Vaza5922742017-03-14 18:50:54 +0530622 kgsl_regread(device, A6XX_CP_MEM_POOL_SIZE, &pool_size);
623 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, 0);
624
625 kgsl_snapshot_indexed_registers(device, snapshot,
626 A6XX_CP_MEM_POOL_DBG_ADDR, A6XX_CP_MEM_POOL_DBG_DATA,
627 0, 0x2060);
628
Lynus Vazb8e43d52017-04-20 14:47:37 +0530629 /*
630 * Data at offset 0x2000 in the mempool section is the mempool size.
631 * Since we set it to 0, patch in the original size so that the data
632 * is consistent.
633 */
634 if (buf < snapshot->ptr) {
635 unsigned int *data;
636
637 /* Skip over the headers */
638 buf += sizeof(struct kgsl_snapshot_section_header) +
639 sizeof(struct kgsl_snapshot_indexed_regs);
640
641 data = (unsigned int *)buf + 0x2000;
642 *data = pool_size;
643 }
644
Lynus Vaza5922742017-03-14 18:50:54 +0530645 /* Restore the saved mempool size */
646 kgsl_regwrite(device, A6XX_CP_MEM_POOL_SIZE, pool_size);
647}
648
Lynus Vaz461e2382017-01-16 19:35:41 +0530649static inline unsigned int a6xx_read_dbgahb(struct kgsl_device *device,
650 unsigned int regbase, unsigned int reg)
651{
652 unsigned int read_reg = A6XX_HLSQ_DBG_AHB_READ_APERTURE +
653 reg - regbase / 4;
654 unsigned int val;
655
656 kgsl_regread(device, read_reg, &val);
657 return val;
658}
659
Lynus Vaz1e258612017-04-27 21:35:22 +0530660static size_t a6xx_legacy_snapshot_cluster_dbgahb(struct kgsl_device *device,
661 u8 *buf, size_t remain, void *priv)
Lynus Vaz461e2382017-01-16 19:35:41 +0530662{
663 struct kgsl_snapshot_mvc_regs *header =
664 (struct kgsl_snapshot_mvc_regs *)buf;
665 struct a6xx_cluster_dbgahb_regs_info *info =
666 (struct a6xx_cluster_dbgahb_regs_info *)priv;
667 struct a6xx_cluster_dbgahb_registers *cur_cluster = info->cluster;
668 unsigned int read_sel;
669 unsigned int data_size = 0;
670 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
671 int i, j;
672
Harshdeep Dhatt134f7af2017-05-17 13:54:41 -0600673 if (!device->snapshot_legacy)
674 return 0;
675
Lynus Vaz461e2382017-01-16 19:35:41 +0530676 if (remain < sizeof(*header)) {
677 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
678 return 0;
679 }
680
681 remain -= sizeof(*header);
682
683 header->ctxt_id = info->ctxt_id;
684 header->cluster_id = cur_cluster->id;
685
686 read_sel = ((cur_cluster->statetype + info->ctxt_id * 2) & 0xff) << 8;
687 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
688
689 for (i = 0; i < cur_cluster->num_sets; i++) {
690 unsigned int start = cur_cluster->regs[2 * i];
691 unsigned int end = cur_cluster->regs[2 * i + 1];
692
693 if (remain < (end - start + 3) * 4) {
694 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
695 goto out;
696 }
697
698 remain -= (end - start + 3) * 4;
699 data_size += (end - start + 3) * 4;
700
701 *data++ = start | (1 << 31);
702 *data++ = end;
703
704 for (j = start; j <= end; j++) {
705 unsigned int val;
706
707 val = a6xx_read_dbgahb(device, cur_cluster->regbase, j);
708 *data++ = val;
709
710 }
711 }
712
713out:
714 return data_size + sizeof(*header);
715}
716
Lynus Vaz1e258612017-04-27 21:35:22 +0530717static size_t a6xx_snapshot_cluster_dbgahb(struct kgsl_device *device, u8 *buf,
718 size_t remain, void *priv)
719{
720 struct kgsl_snapshot_mvc_regs *header =
721 (struct kgsl_snapshot_mvc_regs *)buf;
722 struct a6xx_cluster_dbgahb_regs_info *info =
723 (struct a6xx_cluster_dbgahb_regs_info *)priv;
724 struct a6xx_cluster_dbgahb_registers *cluster = info->cluster;
725 unsigned int data_size = 0;
726 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
727 int i, j;
728 unsigned int *src;
729
730
731 if (crash_dump_valid == false)
732 return a6xx_legacy_snapshot_cluster_dbgahb(device, buf, remain,
733 info);
734
735 if (remain < sizeof(*header)) {
736 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
737 return 0;
738 }
739
740 remain -= sizeof(*header);
741
742 header->ctxt_id = info->ctxt_id;
743 header->cluster_id = cluster->id;
744
745 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
746 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
747
748 for (i = 0; i < cluster->num_sets; i++) {
749 unsigned int start;
750 unsigned int end;
751
752 start = cluster->regs[2 * i];
753 end = cluster->regs[2 * i + 1];
754
755 if (remain < (end - start + 3) * 4) {
756 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
757 goto out;
758 }
759
760 remain -= (end - start + 3) * 4;
761 data_size += (end - start + 3) * 4;
762
763 *data++ = start | (1 << 31);
764 *data++ = end;
765 for (j = start; j <= end; j++)
766 *data++ = *src++;
767 }
768out:
769 return data_size + sizeof(*header);
770}
771
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -0600772static size_t a6xx_legacy_snapshot_non_ctx_dbgahb(struct kgsl_device *device,
773 u8 *buf, size_t remain, void *priv)
Lynus Vaz461e2382017-01-16 19:35:41 +0530774{
775 struct kgsl_snapshot_regs *header =
776 (struct kgsl_snapshot_regs *)buf;
777 struct a6xx_non_ctx_dbgahb_registers *regs =
778 (struct a6xx_non_ctx_dbgahb_registers *)priv;
779 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
780 int count = 0;
781 unsigned int read_sel;
782 int i, j;
783
Harshdeep Dhatt134f7af2017-05-17 13:54:41 -0600784 if (!device->snapshot_legacy)
785 return 0;
786
Lynus Vaz461e2382017-01-16 19:35:41 +0530787 /* Figure out how many registers we are going to dump */
788 for (i = 0; i < regs->num_sets; i++) {
789 int start = regs->regs[i * 2];
790 int end = regs->regs[i * 2 + 1];
791
792 count += (end - start + 1);
793 }
794
795 if (remain < (count * 8) + sizeof(*header)) {
796 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
797 return 0;
798 }
799
800 header->count = count;
801
802 read_sel = (regs->statetype & 0xff) << 8;
803 kgsl_regwrite(device, A6XX_HLSQ_DBG_READ_SEL, read_sel);
804
805 for (i = 0; i < regs->num_sets; i++) {
806 unsigned int start = regs->regs[2 * i];
807 unsigned int end = regs->regs[2 * i + 1];
808
809 for (j = start; j <= end; j++) {
810 unsigned int val;
811
812 val = a6xx_read_dbgahb(device, regs->regbase, j);
813 *data++ = j;
814 *data++ = val;
815
816 }
817 }
818 return (count * 8) + sizeof(*header);
819}
820
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -0600821static size_t a6xx_snapshot_non_ctx_dbgahb(struct kgsl_device *device, u8 *buf,
822 size_t remain, void *priv)
823{
824 struct kgsl_snapshot_regs *header =
825 (struct kgsl_snapshot_regs *)buf;
826 struct a6xx_non_ctx_dbgahb_registers *regs =
827 (struct a6xx_non_ctx_dbgahb_registers *)priv;
828 unsigned int count = 0;
829 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
830 unsigned int i, k;
831 unsigned int *src;
832
833 if (crash_dump_valid == false)
834 return a6xx_legacy_snapshot_non_ctx_dbgahb(device, buf, remain,
835 regs);
836
837 if (remain < sizeof(*header)) {
838 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
839 return 0;
840 }
841
842 remain -= sizeof(*header);
843
844 src = (unsigned int *)(a6xx_crashdump_registers.hostptr + regs->offset);
845
846 for (i = 0; i < regs->num_sets; i++) {
847 unsigned int start;
848 unsigned int end;
849
850 start = regs->regs[2 * i];
851 end = regs->regs[(2 * i) + 1];
852
853 if (remain < (end - start + 1) * 8) {
854 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
855 goto out;
856 }
857
858 remain -= ((end - start) + 1) * 8;
859
860 for (k = start; k <= end; k++, count++) {
861 *data++ = k;
862 *data++ = *src++;
863 }
864 }
865out:
866 header->count = count;
867
868 /* Return the size of the section */
869 return (count * 8) + sizeof(*header);
870}
871
Lynus Vaz461e2382017-01-16 19:35:41 +0530872static void a6xx_snapshot_dbgahb_regs(struct kgsl_device *device,
873 struct kgsl_snapshot *snapshot)
874{
875 int i, j;
876
877 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
878 struct a6xx_cluster_dbgahb_registers *cluster =
879 &a6xx_dbgahb_ctx_clusters[i];
880 struct a6xx_cluster_dbgahb_regs_info info;
881
882 info.cluster = cluster;
883 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
884 info.ctxt_id = j;
885
886 kgsl_snapshot_add_section(device,
887 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
888 a6xx_snapshot_cluster_dbgahb, &info);
889 }
890 }
891
892 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
893 kgsl_snapshot_add_section(device,
894 KGSL_SNAPSHOT_SECTION_REGS, snapshot,
895 a6xx_snapshot_non_ctx_dbgahb, &a6xx_non_ctx_dbgahb[i]);
896 }
897}
898
Shrenuj Bansal41665402016-12-16 15:25:54 -0800899static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
900 size_t remain, void *priv)
901{
902 struct kgsl_snapshot_mvc_regs *header =
903 (struct kgsl_snapshot_mvc_regs *)buf;
904 struct a6xx_cluster_regs_info *info =
905 (struct a6xx_cluster_regs_info *)priv;
906 struct a6xx_cluster_registers *cur_cluster = info->cluster;
907 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
908 unsigned int ctxt = info->ctxt_id;
909 unsigned int start, end, i, j, aperture_cntl = 0;
910 unsigned int data_size = 0;
911
912 if (remain < sizeof(*header)) {
913 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
914 return 0;
915 }
916
917 remain -= sizeof(*header);
918
919 header->ctxt_id = info->ctxt_id;
920 header->cluster_id = cur_cluster->id;
921
922 /*
923 * Set the AHB control for the Host to read from the
924 * cluster/context for this iteration.
925 */
926 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
927 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
928
929 for (i = 0; i < cur_cluster->num_sets; i++) {
930 start = cur_cluster->regs[2 * i];
931 end = cur_cluster->regs[2 * i + 1];
932
933 if (remain < (end - start + 3) * 4) {
934 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
935 goto out;
936 }
937
938 remain -= (end - start + 3) * 4;
939 data_size += (end - start + 3) * 4;
940
941 *data++ = start | (1 << 31);
942 *data++ = end;
943 for (j = start; j <= end; j++) {
944 unsigned int val;
945
946 kgsl_regread(device, j, &val);
947 *data++ = val;
948 }
949 }
950out:
951 return data_size + sizeof(*header);
952}
953
954static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
955 size_t remain, void *priv)
956{
957 struct kgsl_snapshot_mvc_regs *header =
958 (struct kgsl_snapshot_mvc_regs *)buf;
959 struct a6xx_cluster_regs_info *info =
960 (struct a6xx_cluster_regs_info *)priv;
961 struct a6xx_cluster_registers *cluster = info->cluster;
962 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
963 unsigned int *src;
964 int i, j;
965 unsigned int start, end;
966 size_t data_size = 0;
967
968 if (crash_dump_valid == false)
969 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
970
971 if (remain < sizeof(*header)) {
972 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
973 return 0;
974 }
975
976 remain -= sizeof(*header);
977
978 header->ctxt_id = info->ctxt_id;
979 header->cluster_id = cluster->id;
980
981 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
982 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
983
984 for (i = 0; i < cluster->num_sets; i++) {
985 start = cluster->regs[2 * i];
986 end = cluster->regs[2 * i + 1];
987
988 if (remain < (end - start + 3) * 4) {
989 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
990 goto out;
991 }
992
993 remain -= (end - start + 3) * 4;
994 data_size += (end - start + 3) * 4;
995
996 *data++ = start | (1 << 31);
997 *data++ = end;
998 for (j = start; j <= end; j++)
999 *data++ = *src++;
1000 }
1001
1002out:
1003 return data_size + sizeof(*header);
1004
1005}
1006
1007static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
1008 struct kgsl_snapshot *snapshot)
1009{
1010 int i, j;
1011 struct a6xx_cluster_regs_info info;
1012
1013 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1014 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1015
1016 info.cluster = cluster;
1017 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1018 info.ctxt_id = j;
1019
1020 kgsl_snapshot_add_section(device,
1021 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
1022 a6xx_snapshot_mvc, &info);
1023 }
1024 }
1025}
1026
Lynus Vaz20c81272017-02-10 16:22:12 +05301027/* a6xx_dbgc_debug_bus_read() - Read data from trace bus */
1028static void a6xx_dbgc_debug_bus_read(struct kgsl_device *device,
1029 unsigned int block_id, unsigned int index, unsigned int *val)
1030{
1031 unsigned int reg;
1032
1033 reg = (block_id << A6XX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
1034 (index << A6XX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
1035
1036 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
1037 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
1038 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
1039 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
1040
Shrenuj Bansald4508ba2017-05-11 15:59:37 -07001041 /*
1042 * There needs to be a delay of 1 us to ensure enough time for correct
1043 * data is funneled into the trace buffer
1044 */
1045 udelay(1);
1046
Lynus Vaz20c81272017-02-10 16:22:12 +05301047 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
1048 val++;
1049 kgsl_regread(device, A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
1050}
1051
1052/* a6xx_snapshot_cbgc_debugbus_block() - Capture debug data for a gpu block */
1053static size_t a6xx_snapshot_dbgc_debugbus_block(struct kgsl_device *device,
1054 u8 *buf, size_t remain, void *priv)
1055{
Lynus Vazecd472c2017-04-18 14:15:57 +05301056 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
Lynus Vaz20c81272017-02-10 16:22:12 +05301057 struct kgsl_snapshot_debugbus *header =
1058 (struct kgsl_snapshot_debugbus *)buf;
1059 struct adreno_debugbus_block *block = priv;
1060 int i;
1061 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1062 unsigned int dwords;
Lynus Vazecd472c2017-04-18 14:15:57 +05301063 unsigned int block_id;
Lynus Vaz20c81272017-02-10 16:22:12 +05301064 size_t size;
1065
1066 dwords = block->dwords;
1067
1068 /* For a6xx each debug bus data unit is 2 DWORDS */
1069 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
1070
1071 if (remain < size) {
1072 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
1073 return 0;
1074 }
1075
1076 header->id = block->block_id;
1077 header->count = dwords * 2;
1078
Lynus Vazecd472c2017-04-18 14:15:57 +05301079 block_id = block->block_id;
1080 /* GMU_GX data is read using the GMU_CX block id on A630 */
1081 if (adreno_is_a630(adreno_dev) &&
1082 (block_id == A6XX_DBGBUS_GMU_GX))
1083 block_id = A6XX_DBGBUS_GMU_CX;
1084
Lynus Vaz20c81272017-02-10 16:22:12 +05301085 for (i = 0; i < dwords; i++)
Lynus Vazecd472c2017-04-18 14:15:57 +05301086 a6xx_dbgc_debug_bus_read(device, block_id, i, &data[i*2]);
Lynus Vaz20c81272017-02-10 16:22:12 +05301087
1088 return size;
1089}
1090
Lynus Vazff24c972017-03-07 19:27:46 +05301091static void _cx_dbgc_regread(unsigned int offsetwords, unsigned int *value)
1092{
1093 void __iomem *reg;
1094
1095 if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
1096 (offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
1097 "Read beyond CX_DBGC block: 0x%x\n", offsetwords))
1098 return;
1099
1100 reg = a6xx_cx_dbgc +
1101 ((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);
1102 *value = __raw_readl(reg);
1103
1104 /*
1105 * ensure this read finishes before the next one.
1106 * i.e. act like normal readl()
1107 */
1108 rmb();
1109}
1110
1111static void _cx_dbgc_regwrite(unsigned int offsetwords, unsigned int value)
1112{
1113 void __iomem *reg;
1114
1115 if (WARN((offsetwords < A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) ||
1116 (offsetwords > A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2),
1117 "Write beyond CX_DBGC block: 0x%x\n", offsetwords))
1118 return;
1119
1120 reg = a6xx_cx_dbgc +
1121 ((offsetwords - A6XX_CX_DBGC_CFG_DBGBUS_SEL_A) << 2);
1122
1123 /*
1124 * ensure previous writes post before this one,
1125 * i.e. act like normal writel()
1126 */
1127 wmb();
1128 __raw_writel(value, reg);
1129}
1130
1131/* a6xx_cx_dbgc_debug_bus_read() - Read data from trace bus */
1132static void a6xx_cx_debug_bus_read(struct kgsl_device *device,
1133 unsigned int block_id, unsigned int index, unsigned int *val)
1134{
1135 unsigned int reg;
1136
1137 reg = (block_id << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT) |
1138 (index << A6XX_CX_DBGC_CFG_DBGBUS_SEL_PING_INDEX_SHIFT);
1139
1140 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_A, reg);
1141 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_B, reg);
1142 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_C, reg);
1143 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_SEL_D, reg);
1144
Shrenuj Bansald4508ba2017-05-11 15:59:37 -07001145 /*
1146 * There needs to be a delay of 1 us to ensure enough time for correct
1147 * data is funneled into the trace buffer
1148 */
1149 udelay(1);
1150
Lynus Vazff24c972017-03-07 19:27:46 +05301151 _cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2, val);
1152 val++;
1153 _cx_dbgc_regread(A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1, val);
1154}
1155
1156/*
1157 * a6xx_snapshot_cx_dbgc_debugbus_block() - Capture debug data for a gpu
1158 * block from the CX DBGC block
1159 */
1160static size_t a6xx_snapshot_cx_dbgc_debugbus_block(struct kgsl_device *device,
1161 u8 *buf, size_t remain, void *priv)
1162{
1163 struct kgsl_snapshot_debugbus *header =
1164 (struct kgsl_snapshot_debugbus *)buf;
1165 struct adreno_debugbus_block *block = priv;
1166 int i;
1167 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1168 unsigned int dwords;
1169 size_t size;
1170
1171 dwords = block->dwords;
1172
1173 /* For a6xx each debug bus data unit is 2 DWRODS */
1174 size = (dwords * sizeof(unsigned int) * 2) + sizeof(*header);
1175
1176 if (remain < size) {
1177 SNAPSHOT_ERR_NOMEM(device, "DEBUGBUS");
1178 return 0;
1179 }
1180
1181 header->id = block->block_id;
1182 header->count = dwords * 2;
1183
1184 for (i = 0; i < dwords; i++)
1185 a6xx_cx_debug_bus_read(device, block->block_id, i,
1186 &data[i*2]);
1187
1188 return size;
1189}
1190
Lynus Vaz20c81272017-02-10 16:22:12 +05301191/* a6xx_snapshot_debugbus() - Capture debug bus data */
1192static void a6xx_snapshot_debugbus(struct kgsl_device *device,
1193 struct kgsl_snapshot *snapshot)
1194{
1195 int i;
1196
1197 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLT,
1198 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
Shrenuj Bansald4508ba2017-05-11 15:59:37 -07001199 (0x0 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
1200 (0x0 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
Lynus Vaz20c81272017-02-10 16:22:12 +05301201
1202 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_CNTLM,
1203 0xf << A6XX_DBGC_CFG_DBGBUS_CTLTM_ENABLE_SHIFT);
1204
1205 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
1206 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
1207 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
1208 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
1209
1210 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_0,
1211 (0 << A6XX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
1212 (1 << A6XX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
1213 (2 << A6XX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
1214 (3 << A6XX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
1215 (4 << A6XX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
1216 (5 << A6XX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
1217 (6 << A6XX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
1218 (7 << A6XX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
1219 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_BYTEL_1,
1220 (8 << A6XX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
1221 (9 << A6XX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
1222 (10 << A6XX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
1223 (11 << A6XX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
1224 (12 << A6XX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
1225 (13 << A6XX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
1226 (14 << A6XX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
1227 (15 << A6XX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
1228
1229 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
1230 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
1231 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
1232 kgsl_regwrite(device, A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
1233
Lynus Vazff24c972017-03-07 19:27:46 +05301234 a6xx_cx_dbgc = ioremap(device->reg_phys +
1235 (A6XX_CX_DBGC_CFG_DBGBUS_SEL_A << 2),
1236 (A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2 -
1237 A6XX_CX_DBGC_CFG_DBGBUS_SEL_A + 1) << 2);
1238
1239 if (a6xx_cx_dbgc) {
1240 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLT,
1241 (0xf << A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT_SHIFT) |
Shrenuj Bansald4508ba2017-05-11 15:59:37 -07001242 (0x0 << A6XX_DBGC_CFG_DBGBUS_CNTLT_GRANU_SHIFT) |
1243 (0x0 << A6XX_DBGC_CFG_DBGBUS_CNTLT_TRACEEN_SHIFT));
Lynus Vazff24c972017-03-07 19:27:46 +05301244
1245 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_CNTLM,
1246 0xf << A6XX_CX_DBGC_CFG_DBGBUS_CNTLM_ENABLE_SHIFT);
1247
1248 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0);
1249 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0);
1250 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0);
1251 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0);
1252
1253 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0,
1254 (0 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL0_SHIFT) |
1255 (1 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL1_SHIFT) |
1256 (2 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL2_SHIFT) |
1257 (3 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL3_SHIFT) |
1258 (4 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL4_SHIFT) |
1259 (5 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL5_SHIFT) |
1260 (6 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL6_SHIFT) |
1261 (7 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL7_SHIFT));
1262 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1,
1263 (8 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL8_SHIFT) |
1264 (9 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL9_SHIFT) |
1265 (10 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL10_SHIFT) |
1266 (11 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL11_SHIFT) |
1267 (12 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL12_SHIFT) |
1268 (13 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL13_SHIFT) |
1269 (14 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL14_SHIFT) |
1270 (15 << A6XX_CX_DBGC_CFG_DBGBUS_BYTEL15_SHIFT));
1271
1272 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0);
1273 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0);
1274 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0);
1275 _cx_dbgc_regwrite(A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0);
1276 } else
1277 KGSL_DRV_ERR(device, "Unable to ioremap CX_DBGC_CFG block\n");
1278
Lynus Vaz20c81272017-02-10 16:22:12 +05301279 for (i = 0; i < ARRAY_SIZE(a6xx_dbgc_debugbus_blocks); i++) {
1280 kgsl_snapshot_add_section(device,
1281 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
1282 snapshot, a6xx_snapshot_dbgc_debugbus_block,
1283 (void *) &a6xx_dbgc_debugbus_blocks[i]);
1284 }
Lynus Vazff24c972017-03-07 19:27:46 +05301285
1286 if (a6xx_cx_dbgc) {
1287 for (i = 0; i < ARRAY_SIZE(a6xx_cx_dbgc_debugbus_blocks); i++) {
1288 kgsl_snapshot_add_section(device,
1289 KGSL_SNAPSHOT_SECTION_DEBUGBUS,
1290 snapshot, a6xx_snapshot_cx_dbgc_debugbus_block,
1291 (void *) &a6xx_cx_dbgc_debugbus_blocks[i]);
1292 }
1293 iounmap(a6xx_cx_dbgc);
1294 }
Lynus Vaz20c81272017-02-10 16:22:12 +05301295}
1296
Kyle Piefer60733aa2017-03-21 11:24:01 -07001297static void a6xx_snapshot_gmu(struct kgsl_device *device,
1298 struct kgsl_snapshot *snapshot)
1299{
Kyle Piefer60733aa2017-03-21 11:24:01 -07001300 if (!kgsl_gmu_isenabled(device))
1301 return;
1302
Lynus Vazd37f1d82017-05-24 16:39:15 +05301303 adreno_snapshot_registers(device, snapshot, a6xx_gmu_registers,
1304 ARRAY_SIZE(a6xx_gmu_registers) / 2);
Kyle Piefer60733aa2017-03-21 11:24:01 -07001305}
1306
Lynus Vaz85150052017-02-21 17:57:48 +05301307/* a6xx_snapshot_sqe() - Dump SQE data in snapshot */
1308static size_t a6xx_snapshot_sqe(struct kgsl_device *device, u8 *buf,
1309 size_t remain, void *priv)
1310{
1311 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1312 struct kgsl_snapshot_debug *header = (struct kgsl_snapshot_debug *)buf;
1313 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
1314 struct adreno_firmware *fw = ADRENO_FW(adreno_dev, ADRENO_FW_SQE);
1315
1316 if (remain < DEBUG_SECTION_SZ(1)) {
1317 SNAPSHOT_ERR_NOMEM(device, "SQE VERSION DEBUG");
1318 return 0;
1319 }
1320
1321 /* Dump the SQE firmware version */
1322 header->type = SNAPSHOT_DEBUG_SQE_VERSION;
1323 header->size = 1;
1324 *data = fw->version;
1325
1326 return DEBUG_SECTION_SZ(1);
1327}
1328
Shrenuj Bansal41665402016-12-16 15:25:54 -08001329static void _a6xx_do_crashdump(struct kgsl_device *device)
1330{
1331 unsigned long wait_time;
1332 unsigned int reg = 0;
1333 unsigned int val;
1334
1335 crash_dump_valid = false;
1336
1337 if (a6xx_capturescript.gpuaddr == 0 ||
1338 a6xx_crashdump_registers.gpuaddr == 0)
1339 return;
1340
1341 /* IF the SMMU is stalled we cannot do a crash dump */
1342 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
1343 if (val & BIT(24))
1344 return;
1345
1346 /* Turn on APRIV so we can access the buffers */
1347 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
1348
1349 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
1350 lower_32_bits(a6xx_capturescript.gpuaddr));
1351 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
1352 upper_32_bits(a6xx_capturescript.gpuaddr));
1353 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
1354
1355 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
1356 while (!time_after(jiffies, wait_time)) {
1357 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
1358 if (reg & 0x2)
1359 break;
1360 cpu_relax();
1361 }
1362
1363 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
1364
1365 if (!(reg & 0x2)) {
1366 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
1367 return;
1368 }
1369
1370 crash_dump_valid = true;
1371}
1372
1373/*
1374 * a6xx_snapshot() - A6XX GPU snapshot function
1375 * @adreno_dev: Device being snapshotted
1376 * @snapshot: Pointer to the snapshot instance
1377 *
1378 * This is where all of the A6XX specific bits and pieces are grabbed
1379 * into the snapshot memory
1380 */
1381void a6xx_snapshot(struct adreno_device *adreno_dev,
1382 struct kgsl_snapshot *snapshot)
1383{
1384 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1385 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
1386 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
1387
1388 /* Try to run the crash dumper */
1389 _a6xx_do_crashdump(device);
1390
1391 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
1392 snapshot, a6xx_snapshot_registers, NULL);
1393
1394 adreno_snapshot_vbif_registers(device, snapshot,
1395 a6xx_vbif_snapshot_registers,
1396 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
1397
1398 /* CP_SQE indexed registers */
1399 kgsl_snapshot_indexed_registers(device, snapshot,
1400 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
1401 0, snap_data->sect_sizes->cp_pfp);
1402
1403 /* CP_DRAW_STATE */
1404 kgsl_snapshot_indexed_registers(device, snapshot,
1405 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
1406 0, 0x100);
1407
1408 /* SQE_UCODE Cache */
1409 kgsl_snapshot_indexed_registers(device, snapshot,
1410 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
1411 0, 0x6000);
1412
1413 /* CP ROQ */
1414 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1415 snapshot, adreno_snapshot_cp_roq,
1416 &snap_data->sect_sizes->roq);
1417
Lynus Vaz85150052017-02-21 17:57:48 +05301418 /* SQE Firmware */
1419 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
1420 snapshot, a6xx_snapshot_sqe, NULL);
1421
Lynus Vaza5922742017-03-14 18:50:54 +05301422 /* Mempool debug data */
1423 a6xx_snapshot_mempool(device, snapshot);
1424
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301425 /* Shader memory */
1426 a6xx_snapshot_shader(device, snapshot);
1427
Shrenuj Bansal41665402016-12-16 15:25:54 -08001428 /* MVC register section */
1429 a6xx_snapshot_mvc_regs(device, snapshot);
1430
Lynus Vaz461e2382017-01-16 19:35:41 +05301431 /* registers dumped through DBG AHB */
1432 a6xx_snapshot_dbgahb_regs(device, snapshot);
1433
Lynus Vaz20c81272017-02-10 16:22:12 +05301434 a6xx_snapshot_debugbus(device, snapshot);
Kyle Piefer60733aa2017-03-21 11:24:01 -07001435
1436 /* GMU TCM data dumped through AHB */
1437 a6xx_snapshot_gmu(device, snapshot);
Shrenuj Bansal41665402016-12-16 15:25:54 -08001438}
1439
1440static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
1441{
1442 int qwords = 0;
1443 unsigned int i, j, k;
1444 unsigned int count;
1445
1446 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1447 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1448
1449 cluster->offset0 = *offset;
1450 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1451
1452 if (j == 1)
1453 cluster->offset1 = *offset;
1454
1455 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
1456 ptr[qwords++] =
1457 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
1458 (1 << 21) | 1;
1459
1460 for (k = 0; k < cluster->num_sets; k++) {
1461 count = REG_PAIR_COUNT(cluster->regs, k);
1462 ptr[qwords++] =
1463 a6xx_crashdump_registers.gpuaddr + *offset;
1464 ptr[qwords++] =
1465 (((uint64_t)cluster->regs[2 * k]) << 44) |
1466 count;
1467
1468 *offset += count * sizeof(unsigned int);
1469 }
1470 }
1471 }
1472
1473 return qwords;
1474}
1475
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301476static int _a6xx_crashdump_init_shader(struct a6xx_shader_block *block,
1477 uint64_t *ptr, uint64_t *offset)
1478{
1479 int qwords = 0;
1480 unsigned int j;
1481
1482 /* Capture each bank in the block */
1483 for (j = 0; j < A6XX_NUM_SHADER_BANKS; j++) {
1484 /* Program the aperture */
1485 ptr[qwords++] =
1486 (block->statetype << A6XX_SHADER_STATETYPE_SHIFT) | j;
1487 ptr[qwords++] = (((uint64_t) A6XX_HLSQ_DBG_READ_SEL << 44)) |
1488 (1 << 21) | 1;
1489
1490 /* Read all the data in one chunk */
1491 ptr[qwords++] = a6xx_crashdump_registers.gpuaddr + *offset;
1492 ptr[qwords++] =
1493 (((uint64_t) A6XX_HLSQ_DBG_AHB_READ_APERTURE << 44)) |
1494 block->sz;
1495
1496 /* Remember the offset of the first bank for easy access */
1497 if (j == 0)
1498 block->offset = *offset;
1499
1500 *offset += block->sz * sizeof(unsigned int);
1501 }
1502
1503 return qwords;
1504}
1505
Lynus Vaz1e258612017-04-27 21:35:22 +05301506static int _a6xx_crashdump_init_ctx_dbgahb(uint64_t *ptr, uint64_t *offset)
1507{
1508 int qwords = 0;
1509 unsigned int i, j, k;
1510 unsigned int count;
1511
1512 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
1513 struct a6xx_cluster_dbgahb_registers *cluster =
1514 &a6xx_dbgahb_ctx_clusters[i];
1515
1516 cluster->offset0 = *offset;
1517
1518 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1519 if (j == 1)
1520 cluster->offset1 = *offset;
1521
1522 /* Program the aperture */
1523 ptr[qwords++] =
1524 ((cluster->statetype + j * 2) & 0xff) << 8;
1525 ptr[qwords++] =
1526 (((uint64_t)A6XX_HLSQ_DBG_READ_SEL << 44)) |
1527 (1 << 21) | 1;
1528
1529 for (k = 0; k < cluster->num_sets; k++) {
1530 unsigned int start = cluster->regs[2 * k];
1531
1532 count = REG_PAIR_COUNT(cluster->regs, k);
1533 ptr[qwords++] =
1534 a6xx_crashdump_registers.gpuaddr + *offset;
1535 ptr[qwords++] =
1536 (((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE +
1537 start - cluster->regbase / 4) << 44)) |
1538 count;
1539
1540 *offset += count * sizeof(unsigned int);
1541 }
1542 }
1543 }
1544 return qwords;
1545}
1546
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -06001547static int _a6xx_crashdump_init_non_ctx_dbgahb(uint64_t *ptr, uint64_t *offset)
1548{
1549 int qwords = 0;
1550 unsigned int i, k;
1551 unsigned int count;
1552
1553 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
1554 struct a6xx_non_ctx_dbgahb_registers *regs =
1555 &a6xx_non_ctx_dbgahb[i];
1556
1557 regs->offset = *offset;
1558
1559 /* Program the aperture */
1560 ptr[qwords++] = (regs->statetype & 0xff) << 8;
1561 ptr[qwords++] = (((uint64_t)A6XX_HLSQ_DBG_READ_SEL << 44)) |
1562 (1 << 21) | 1;
1563
1564 for (k = 0; k < regs->num_sets; k++) {
1565 unsigned int start = regs->regs[2 * k];
1566
1567 count = REG_PAIR_COUNT(regs->regs, k);
1568 ptr[qwords++] =
1569 a6xx_crashdump_registers.gpuaddr + *offset;
1570 ptr[qwords++] =
1571 (((uint64_t)(A6XX_HLSQ_DBG_AHB_READ_APERTURE +
1572 start - regs->regbase / 4) << 44)) |
1573 count;
1574
1575 *offset += count * sizeof(unsigned int);
1576 }
1577 }
1578 return qwords;
1579}
1580
Shrenuj Bansal41665402016-12-16 15:25:54 -08001581void a6xx_crashdump_init(struct adreno_device *adreno_dev)
1582{
1583 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
1584 unsigned int script_size = 0;
1585 unsigned int data_size = 0;
1586 unsigned int i, j, k;
1587 uint64_t *ptr;
1588 uint64_t offset = 0;
1589
1590 if (a6xx_capturescript.gpuaddr != 0 &&
1591 a6xx_crashdump_registers.gpuaddr != 0)
1592 return;
1593
1594 /*
1595 * We need to allocate two buffers:
1596 * 1 - the buffer to hold the draw script
1597 * 2 - the buffer to hold the data
1598 */
1599
1600 /*
1601 * To save the registers, we need 16 bytes per register pair for the
1602 * script and a dword for each register in the data
1603 */
1604 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1605 struct cdregs *regs = &_a6xx_cd_registers[i];
1606
1607 /* Each pair needs 16 bytes (2 qwords) */
1608 script_size += (regs->size / 2) * 16;
1609
1610 /* Each register needs a dword in the data */
1611 for (j = 0; j < regs->size / 2; j++)
1612 data_size += REG_PAIR_COUNT(regs->regs, j) *
1613 sizeof(unsigned int);
1614
1615 }
1616
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301617 /*
1618 * To save the shader blocks for each block in each type we need 32
1619 * bytes for the script (16 bytes to program the aperture and 16 to
1620 * read the data) and then a block specific number of bytes to hold
1621 * the data
1622 */
1623 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1624 script_size += 32 * A6XX_NUM_SHADER_BANKS;
1625 data_size += a6xx_shader_blocks[i].sz * sizeof(unsigned int) *
1626 A6XX_NUM_SHADER_BANKS;
1627 }
1628
Shrenuj Bansal41665402016-12-16 15:25:54 -08001629 /* Calculate the script and data size for MVC registers */
1630 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
1631 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
1632
1633 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1634
1635 /* 16 bytes for programming the aperture */
1636 script_size += 16;
1637
1638 /* Reading each pair of registers takes 16 bytes */
1639 script_size += 16 * cluster->num_sets;
1640
1641 /* A dword per register read from the cluster list */
1642 for (k = 0; k < cluster->num_sets; k++)
1643 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1644 sizeof(unsigned int);
1645 }
1646 }
1647
Lynus Vaz1e258612017-04-27 21:35:22 +05301648 /* Calculate the script and data size for debug AHB registers */
1649 for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_ctx_clusters); i++) {
1650 struct a6xx_cluster_dbgahb_registers *cluster =
1651 &a6xx_dbgahb_ctx_clusters[i];
1652
1653 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
1654
1655 /* 16 bytes for programming the aperture */
1656 script_size += 16;
1657
1658 /* Reading each pair of registers takes 16 bytes */
1659 script_size += 16 * cluster->num_sets;
1660
1661 /* A dword per register read from the cluster list */
1662 for (k = 0; k < cluster->num_sets; k++)
1663 data_size += REG_PAIR_COUNT(cluster->regs, k) *
1664 sizeof(unsigned int);
1665 }
1666 }
1667
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -06001668 /*
1669 * Calculate the script and data size for non context debug
1670 * AHB registers
1671 */
1672 for (i = 0; i < ARRAY_SIZE(a6xx_non_ctx_dbgahb); i++) {
1673 struct a6xx_non_ctx_dbgahb_registers *regs =
1674 &a6xx_non_ctx_dbgahb[i];
1675
1676 /* 16 bytes for programming the aperture */
1677 script_size += 16;
1678
1679 /* Reading each pair of registers takes 16 bytes */
1680 script_size += 16 * regs->num_sets;
1681
1682 /* A dword per register read from the cluster list */
1683 for (k = 0; k < regs->num_sets; k++)
1684 data_size += REG_PAIR_COUNT(regs->regs, k) *
1685 sizeof(unsigned int);
1686 }
1687
Shrenuj Bansal41665402016-12-16 15:25:54 -08001688 /* Now allocate the script and data buffers */
1689
1690 /* The script buffers needs 2 extra qwords on the end */
1691 if (kgsl_allocate_global(device, &a6xx_capturescript,
1692 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
1693 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
1694 return;
1695
1696 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
1697 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
1698 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
1699 return;
1700 }
1701
1702 /* Build the crash script */
1703
1704 ptr = (uint64_t *)a6xx_capturescript.hostptr;
1705
1706 /* For the registers, program a read command for each pair */
1707 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
1708 struct cdregs *regs = &_a6xx_cd_registers[i];
1709
1710 for (j = 0; j < regs->size / 2; j++) {
1711 unsigned int r = REG_PAIR_COUNT(regs->regs, j);
1712 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
1713 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
1714 offset += r * sizeof(unsigned int);
1715 }
1716 }
1717
Lynus Vaz9ad67a32017-03-10 14:55:02 +05301718 /* Program each shader block */
1719 for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++) {
1720 ptr += _a6xx_crashdump_init_shader(&a6xx_shader_blocks[i], ptr,
1721 &offset);
1722 }
1723
Shrenuj Bansal41665402016-12-16 15:25:54 -08001724 /* Program the capturescript for the MVC regsiters */
1725 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
1726
Lynus Vaz1e258612017-04-27 21:35:22 +05301727 ptr += _a6xx_crashdump_init_ctx_dbgahb(ptr, &offset);
1728
Harshdeep Dhatt52ccc942017-05-10 12:35:30 -06001729 ptr += _a6xx_crashdump_init_non_ctx_dbgahb(ptr, &offset);
1730
Shrenuj Bansal41665402016-12-16 15:25:54 -08001731 *ptr++ = 0;
1732 *ptr++ = 0;
1733}