blob: 4a7f189614180d238c8369fa8eaac1c966e4d4b0 [file] [log] [blame]
Shrenuj Bansal41665402016-12-16 15:25:54 -08001/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/io.h>
15#include "kgsl.h"
16#include "adreno.h"
17#include "kgsl_snapshot.h"
18#include "adreno_snapshot.h"
19#include "a6xx_reg.h"
20#include "adreno_a6xx.h"
21
22
23#define A6XX_NUM_CTXTS 2
24
25static const unsigned int a6xx_gras_cluster[] = {
26 0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809D, 0x80A0, 0x80A6,
27 0x80AF, 0x80F1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110,
28 0x8400, 0x840B,
29};
30
31static const unsigned int a6xx_ps_cluster[] = {
32 0x8800, 0x8806, 0x8809, 0x8811, 0x8818, 0x881E, 0x8820, 0x8865,
33 0x8870, 0x8879, 0x8880, 0x8889, 0x8890, 0x8891, 0x8898, 0x8898,
34 0x88C0, 0x88c1, 0x88D0, 0x88E3, 0x88F0, 0x88F3, 0x8900, 0x891A,
35 0x8927, 0x8928, 0x8C00, 0x8C01, 0x8C17, 0x8C33, 0x9200, 0x9216,
36 0x9218, 0x9236, 0x9300, 0x9306,
37};
38
39static const unsigned int a6xx_fe_cluster[] = {
40 0x9300, 0x9306, 0x9800, 0x9806, 0x9B00, 0x9B07, 0xA000, 0xA009,
41 0xA00E, 0xA0EF, 0xA0F8, 0xA0F8,
42};
43
44static const unsigned int a6xx_pc_vs_cluster[] = {
45 0x9100, 0x9108, 0x9300, 0x9306, 0x9980, 0x9981, 0x9B00, 0x9B07,
46};
47
48static struct a6xx_cluster_registers {
49 unsigned int id;
50 const unsigned int *regs;
51 unsigned int num_sets;
52 unsigned int offset0;
53 unsigned int offset1;
54} a6xx_clusters[] = {
55 { CP_CLUSTER_GRAS, a6xx_gras_cluster, ARRAY_SIZE(a6xx_gras_cluster)/2 },
56 { CP_CLUSTER_PS, a6xx_ps_cluster, ARRAY_SIZE(a6xx_ps_cluster)/2 },
57 { CP_CLUSTER_FE, a6xx_fe_cluster, ARRAY_SIZE(a6xx_fe_cluster)/2 },
58 { CP_CLUSTER_PC_VS, a6xx_pc_vs_cluster,
59 ARRAY_SIZE(a6xx_pc_vs_cluster)/2 },
60};
61
62struct a6xx_cluster_regs_info {
63 struct a6xx_cluster_registers *cluster;
64 unsigned int ctxt_id;
65};
66
67static const unsigned int a6xx_vbif_ver_20xxxxxx_registers[] = {
68 /* VBIF */
69 0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x302D, 0x3030, 0x3031,
70 0x3034, 0x3036, 0x303C, 0x303D, 0x3040, 0x3040, 0x3042, 0x3042,
71 0x3049, 0x3049, 0x3058, 0x3058, 0x305A, 0x3061, 0x3064, 0x3068,
72 0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094,
73 0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8,
74 0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100,
75 0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
76 0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x3154, 0x3154,
77 0x3156, 0x3156, 0x3158, 0x3158, 0x315A, 0x315A, 0x315C, 0x315C,
78 0x315E, 0x315E, 0x3160, 0x3160, 0x3162, 0x3162, 0x340C, 0x340C,
79 0x3410, 0x3410, 0x3800, 0x3801,
80};
81
82static const struct adreno_vbif_snapshot_registers
83a6xx_vbif_snapshot_registers[] = {
84 { 0x20040000, 0xFF000000, a6xx_vbif_ver_20xxxxxx_registers,
85 ARRAY_SIZE(a6xx_vbif_ver_20xxxxxx_registers)/2},
86};
87
88/*
89 * Set of registers to dump for A6XX on snapshot.
90 * Registers in pairs - first value is the start offset, second
91 * is the stop offset (inclusive)
92 */
93
94static const unsigned int a6xx_registers[] = {
95 /* RBBM */
96 0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0014, 0x0014,
97 0x0018, 0x001B, 0x001e, 0x0032, 0x0038, 0x003C, 0x0042, 0x0042,
98 0x0044, 0x0044, 0x0047, 0x0047, 0x0056, 0x0056, 0x00AD, 0x00AE,
99 0x00B0, 0x00FB, 0x0100, 0x011D, 0x0200, 0x020D, 0x0210, 0x0213,
100 0x0218, 0x023D, 0x0400, 0x04F9, 0x0500, 0x0500, 0x0505, 0x050B,
101 0x050E, 0x0511, 0x0533, 0x0533, 0x0540, 0x0555,
102 /* CP */
103 0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0827,
104 0x0830, 0x0833, 0x0840, 0x0843, 0x084F, 0x086F, 0x0880, 0x088A,
105 0x08A0, 0x08AB, 0x08C0, 0x08C4, 0x08D0, 0x08DD, 0x08F0, 0x08F3,
106 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093E, 0x0942, 0x094D,
107 0x0980, 0x0984, 0x098D, 0x0996, 0x0998, 0x099E, 0x09A0, 0x09A6,
108 0x09A8, 0x09AE, 0x09B0, 0x09B1, 0x09C2, 0x09C8, 0x0A00, 0x0A03,
109 /* VSC */
110 0x0C00, 0x0C04, 0x0C06, 0x0C06, 0x0C10, 0x0CD9, 0x0E00, 0x0E0E,
111 /* UCHE */
112 0x0E10, 0x0E13, 0x0E17, 0x0E19, 0x0E1C, 0x0E2B, 0x0E30, 0x0E32,
113 0x0E38, 0x0E39,
114 /* GRAS */
115 0x8600, 0x8601, 0x8604, 0x8605, 0x8610, 0x861B, 0x8620, 0x8620,
116 0x8628, 0x862B, 0x8630, 0x8637,
117 /* RB */
118 0x8E01, 0x8E01, 0x8E04, 0x8E05, 0x8E07, 0x8E08, 0x8E0C, 0x8E0C,
119 0x8E10, 0x8E1C, 0x8E20, 0x8E25, 0x8E28, 0x8E28, 0x8E2C, 0x8E2F,
120 0x8E3B, 0x8E3E, 0x8E40, 0x8E43, 0x8E50, 0x8E5E, 0x8E70, 0x8E77,
121 /* VPC */
122 0x9600, 0x9604, 0x9624, 0x9637,
123 /* PC */
124 0x9E00, 0x9E01, 0x9E03, 0x9E0E, 0x9E11, 0x9E16, 0x9E19, 0x9E19,
125 0x9E1C, 0x9E1C, 0x9E20, 0x9E23, 0x9E30, 0x9E31, 0x9E34, 0x9E34,
126 0x9E70, 0x9E72, 0x9E78, 0x9E79, 0x9E80, 0x9FFF,
127 /* VFD */
128 0xA600, 0xA601, 0xA603, 0xA603, 0xA60A, 0xA60A, 0xA610, 0xA617,
129 0xA630, 0xA630, 0xD200, 0xD263,
130};
131
132
133static struct kgsl_memdesc a6xx_capturescript;
134static struct kgsl_memdesc a6xx_crashdump_registers;
135static bool crash_dump_valid;
136
137static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
138 u8 *buf, size_t remain)
139{
140 struct kgsl_snapshot_registers regs = {
141 .regs = a6xx_registers,
142 .count = ARRAY_SIZE(a6xx_registers) / 2,
143 };
144
145 return kgsl_snapshot_dump_registers(device, buf, remain, &regs);
146}
147
148static struct cdregs {
149 const unsigned int *regs;
150 unsigned int size;
151} _a6xx_cd_registers[] = {
152 { a6xx_registers, ARRAY_SIZE(a6xx_registers) },
153};
154
155#define REG_PAIR_COUNT(_a, _i) \
156 (((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
157
158static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
159 size_t remain, void *priv)
160{
161 struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
162 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
163 unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
164 unsigned int i, j, k;
165 unsigned int count = 0;
166
167 if (crash_dump_valid == false)
168 return a6xx_legacy_snapshot_registers(device, buf, remain);
169
170 if (remain < sizeof(*header)) {
171 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
172 return 0;
173 }
174
175 remain -= sizeof(*header);
176
177 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
178 struct cdregs *regs = &_a6xx_cd_registers[i];
179
180 for (j = 0; j < regs->size / 2; j++) {
181 unsigned int start = regs->regs[2 * j];
182 unsigned int end = regs->regs[(2 * j) + 1];
183
184 if (remain < ((end - start) + 1) * 8) {
185 SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
186 goto out;
187 }
188
189 remain -= ((end - start) + 1) * 8;
190
191 for (k = start; k <= end; k++, count++) {
192 *data++ = k;
193 *data++ = *src++;
194 }
195 }
196 }
197
198out:
199 header->count = count;
200
201 /* Return the size of the section */
202 return (count * 8) + sizeof(*header);
203}
204
205static size_t a6xx_legacy_snapshot_mvc(struct kgsl_device *device, u8 *buf,
206 size_t remain, void *priv)
207{
208 struct kgsl_snapshot_mvc_regs *header =
209 (struct kgsl_snapshot_mvc_regs *)buf;
210 struct a6xx_cluster_regs_info *info =
211 (struct a6xx_cluster_regs_info *)priv;
212 struct a6xx_cluster_registers *cur_cluster = info->cluster;
213 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
214 unsigned int ctxt = info->ctxt_id;
215 unsigned int start, end, i, j, aperture_cntl = 0;
216 unsigned int data_size = 0;
217
218 if (remain < sizeof(*header)) {
219 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
220 return 0;
221 }
222
223 remain -= sizeof(*header);
224
225 header->ctxt_id = info->ctxt_id;
226 header->cluster_id = cur_cluster->id;
227
228 /*
229 * Set the AHB control for the Host to read from the
230 * cluster/context for this iteration.
231 */
232 aperture_cntl = ((cur_cluster->id & 0x7) << 8) | (ctxt << 4) | ctxt;
233 kgsl_regwrite(device, A6XX_CP_APERTURE_CNTL_HOST, aperture_cntl);
234
235 for (i = 0; i < cur_cluster->num_sets; i++) {
236 start = cur_cluster->regs[2 * i];
237 end = cur_cluster->regs[2 * i + 1];
238
239 if (remain < (end - start + 3) * 4) {
240 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
241 goto out;
242 }
243
244 remain -= (end - start + 3) * 4;
245 data_size += (end - start + 3) * 4;
246
247 *data++ = start | (1 << 31);
248 *data++ = end;
249 for (j = start; j <= end; j++) {
250 unsigned int val;
251
252 kgsl_regread(device, j, &val);
253 *data++ = val;
254 }
255 }
256out:
257 return data_size + sizeof(*header);
258}
259
260static size_t a6xx_snapshot_mvc(struct kgsl_device *device, u8 *buf,
261 size_t remain, void *priv)
262{
263 struct kgsl_snapshot_mvc_regs *header =
264 (struct kgsl_snapshot_mvc_regs *)buf;
265 struct a6xx_cluster_regs_info *info =
266 (struct a6xx_cluster_regs_info *)priv;
267 struct a6xx_cluster_registers *cluster = info->cluster;
268 unsigned int *data = (unsigned int *)(buf + sizeof(*header));
269 unsigned int *src;
270 int i, j;
271 unsigned int start, end;
272 size_t data_size = 0;
273
274 if (crash_dump_valid == false)
275 return a6xx_legacy_snapshot_mvc(device, buf, remain, info);
276
277 if (remain < sizeof(*header)) {
278 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
279 return 0;
280 }
281
282 remain -= sizeof(*header);
283
284 header->ctxt_id = info->ctxt_id;
285 header->cluster_id = cluster->id;
286
287 src = (unsigned int *)(a6xx_crashdump_registers.hostptr +
288 (header->ctxt_id ? cluster->offset1 : cluster->offset0));
289
290 for (i = 0; i < cluster->num_sets; i++) {
291 start = cluster->regs[2 * i];
292 end = cluster->regs[2 * i + 1];
293
294 if (remain < (end - start + 3) * 4) {
295 SNAPSHOT_ERR_NOMEM(device, "MVC REGISTERS");
296 goto out;
297 }
298
299 remain -= (end - start + 3) * 4;
300 data_size += (end - start + 3) * 4;
301
302 *data++ = start | (1 << 31);
303 *data++ = end;
304 for (j = start; j <= end; j++)
305 *data++ = *src++;
306 }
307
308out:
309 return data_size + sizeof(*header);
310
311}
312
313static void a6xx_snapshot_mvc_regs(struct kgsl_device *device,
314 struct kgsl_snapshot *snapshot)
315{
316 int i, j;
317 struct a6xx_cluster_regs_info info;
318
319 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
320 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
321
322 info.cluster = cluster;
323 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
324 info.ctxt_id = j;
325
326 kgsl_snapshot_add_section(device,
327 KGSL_SNAPSHOT_SECTION_MVC, snapshot,
328 a6xx_snapshot_mvc, &info);
329 }
330 }
331}
332
333static void _a6xx_do_crashdump(struct kgsl_device *device)
334{
335 unsigned long wait_time;
336 unsigned int reg = 0;
337 unsigned int val;
338
339 crash_dump_valid = false;
340
341 if (a6xx_capturescript.gpuaddr == 0 ||
342 a6xx_crashdump_registers.gpuaddr == 0)
343 return;
344
345 /* IF the SMMU is stalled we cannot do a crash dump */
346 kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
347 if (val & BIT(24))
348 return;
349
350 /* Turn on APRIV so we can access the buffers */
351 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 1);
352
353 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_LO,
354 lower_32_bits(a6xx_capturescript.gpuaddr));
355 kgsl_regwrite(device, A6XX_CP_CRASH_SCRIPT_BASE_HI,
356 upper_32_bits(a6xx_capturescript.gpuaddr));
357 kgsl_regwrite(device, A6XX_CP_CRASH_DUMP_CNTL, 1);
358
359 wait_time = jiffies + msecs_to_jiffies(CP_CRASH_DUMPER_TIMEOUT);
360 while (!time_after(jiffies, wait_time)) {
361 kgsl_regread(device, A6XX_CP_CRASH_DUMP_STATUS, &reg);
362 if (reg & 0x2)
363 break;
364 cpu_relax();
365 }
366
367 kgsl_regwrite(device, A6XX_CP_MISC_CNTL, 0);
368
369 if (!(reg & 0x2)) {
370 KGSL_CORE_ERR("Crash dump timed out: 0x%X\n", reg);
371 return;
372 }
373
374 crash_dump_valid = true;
375}
376
377/*
378 * a6xx_snapshot() - A6XX GPU snapshot function
379 * @adreno_dev: Device being snapshotted
380 * @snapshot: Pointer to the snapshot instance
381 *
382 * This is where all of the A6XX specific bits and pieces are grabbed
383 * into the snapshot memory
384 */
385void a6xx_snapshot(struct adreno_device *adreno_dev,
386 struct kgsl_snapshot *snapshot)
387{
388 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
389 struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
390 struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
391
392 /* Try to run the crash dumper */
393 _a6xx_do_crashdump(device);
394
395 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
396 snapshot, a6xx_snapshot_registers, NULL);
397
398 adreno_snapshot_vbif_registers(device, snapshot,
399 a6xx_vbif_snapshot_registers,
400 ARRAY_SIZE(a6xx_vbif_snapshot_registers));
401
402 /* CP_SQE indexed registers */
403 kgsl_snapshot_indexed_registers(device, snapshot,
404 A6XX_CP_SQE_STAT_ADDR, A6XX_CP_SQE_STAT_DATA,
405 0, snap_data->sect_sizes->cp_pfp);
406
407 /* CP_DRAW_STATE */
408 kgsl_snapshot_indexed_registers(device, snapshot,
409 A6XX_CP_DRAW_STATE_ADDR, A6XX_CP_DRAW_STATE_DATA,
410 0, 0x100);
411
412 /* SQE_UCODE Cache */
413 kgsl_snapshot_indexed_registers(device, snapshot,
414 A6XX_CP_SQE_UCODE_DBG_ADDR, A6XX_CP_SQE_UCODE_DBG_DATA,
415 0, 0x6000);
416
417 /* CP ROQ */
418 kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_DEBUG,
419 snapshot, adreno_snapshot_cp_roq,
420 &snap_data->sect_sizes->roq);
421
422 /* MVC register section */
423 a6xx_snapshot_mvc_regs(device, snapshot);
424
425}
426
427static int _a6xx_crashdump_init_mvc(uint64_t *ptr, uint64_t *offset)
428{
429 int qwords = 0;
430 unsigned int i, j, k;
431 unsigned int count;
432
433 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
434 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
435
436 cluster->offset0 = *offset;
437 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
438
439 if (j == 1)
440 cluster->offset1 = *offset;
441
442 ptr[qwords++] = (cluster->id << 8) | (j << 4) | j;
443 ptr[qwords++] =
444 ((uint64_t)A6XX_CP_APERTURE_CNTL_HOST << 44) |
445 (1 << 21) | 1;
446
447 for (k = 0; k < cluster->num_sets; k++) {
448 count = REG_PAIR_COUNT(cluster->regs, k);
449 ptr[qwords++] =
450 a6xx_crashdump_registers.gpuaddr + *offset;
451 ptr[qwords++] =
452 (((uint64_t)cluster->regs[2 * k]) << 44) |
453 count;
454
455 *offset += count * sizeof(unsigned int);
456 }
457 }
458 }
459
460 return qwords;
461}
462
463void a6xx_crashdump_init(struct adreno_device *adreno_dev)
464{
465 struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
466 unsigned int script_size = 0;
467 unsigned int data_size = 0;
468 unsigned int i, j, k;
469 uint64_t *ptr;
470 uint64_t offset = 0;
471
472 if (a6xx_capturescript.gpuaddr != 0 &&
473 a6xx_crashdump_registers.gpuaddr != 0)
474 return;
475
476 /*
477 * We need to allocate two buffers:
478 * 1 - the buffer to hold the draw script
479 * 2 - the buffer to hold the data
480 */
481
482 /*
483 * To save the registers, we need 16 bytes per register pair for the
484 * script and a dword for each register in the data
485 */
486 for (i = 0; i < ARRAY_SIZE(_a6xx_cd_registers); i++) {
487 struct cdregs *regs = &_a6xx_cd_registers[i];
488
489 /* Each pair needs 16 bytes (2 qwords) */
490 script_size += (regs->size / 2) * 16;
491
492 /* Each register needs a dword in the data */
493 for (j = 0; j < regs->size / 2; j++)
494 data_size += REG_PAIR_COUNT(regs->regs, j) *
495 sizeof(unsigned int);
496
497 }
498
499 /* Calculate the script and data size for MVC registers */
500 for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++) {
501 struct a6xx_cluster_registers *cluster = &a6xx_clusters[i];
502
503 for (j = 0; j < A6XX_NUM_CTXTS; j++) {
504
505 /* 16 bytes for programming the aperture */
506 script_size += 16;
507
508 /* Reading each pair of registers takes 16 bytes */
509 script_size += 16 * cluster->num_sets;
510
511 /* A dword per register read from the cluster list */
512 for (k = 0; k < cluster->num_sets; k++)
513 data_size += REG_PAIR_COUNT(cluster->regs, k) *
514 sizeof(unsigned int);
515 }
516 }
517
518 /* Now allocate the script and data buffers */
519
520 /* The script buffers needs 2 extra qwords on the end */
521 if (kgsl_allocate_global(device, &a6xx_capturescript,
522 script_size + 16, KGSL_MEMFLAGS_GPUREADONLY,
523 KGSL_MEMDESC_PRIVILEGED, "capturescript"))
524 return;
525
526 if (kgsl_allocate_global(device, &a6xx_crashdump_registers, data_size,
527 0, KGSL_MEMDESC_PRIVILEGED, "capturescript_regs")) {
528 kgsl_free_global(KGSL_DEVICE(adreno_dev), &a6xx_capturescript);
529 return;
530 }
531
532 /* Build the crash script */
533
534 ptr = (uint64_t *)a6xx_capturescript.hostptr;
535
536 /* For the registers, program a read command for each pair */
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 r = REG_PAIR_COUNT(regs->regs, j);
542 *ptr++ = a6xx_crashdump_registers.gpuaddr + offset;
543 *ptr++ = (((uint64_t) regs->regs[2 * j]) << 44) | r;
544 offset += r * sizeof(unsigned int);
545 }
546 }
547
548 /* Program the capturescript for the MVC regsiters */
549 ptr += _a6xx_crashdump_init_mvc(ptr, &offset);
550
551 *ptr++ = 0;
552 *ptr++ = 0;
553}