1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2013-2014 Red Hat
4 * Author: Rob Clark <robdclark@gmail.com>
5 *
6 * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
7 */
8
9#include "adreno_gpu.h"
10
11bool hang_debug = false;
12MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)");
13module_param_named(hang_debug, hang_debug, bool, 0600);
14
15bool snapshot_debugbus = false;
16MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)");
17module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
18
19bool allow_vram_carveout = false;
20MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU");
21module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600);
22
23static const struct adreno_info gpulist[] = {
24 {
25 .chip_ids = ADRENO_CHIP_IDS(0x02000000),
26 .family = ADRENO_2XX_GEN1,
27 .revn = 200,
28 .fw = {
29 [ADRENO_FW_PM4] = "yamato_pm4.fw",
30 [ADRENO_FW_PFP] = "yamato_pfp.fw",
31 },
32 .gmem = SZ_256K,
33 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
34 .init = a2xx_gpu_init,
35 }, { /* a200 on i.mx51 has only 128kib gmem */
36 .chip_ids = ADRENO_CHIP_IDS(0x02000001),
37 .family = ADRENO_2XX_GEN1,
38 .revn = 201,
39 .fw = {
40 [ADRENO_FW_PM4] = "yamato_pm4.fw",
41 [ADRENO_FW_PFP] = "yamato_pfp.fw",
42 },
43 .gmem = SZ_128K,
44 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
45 .init = a2xx_gpu_init,
46 }, {
47 .chip_ids = ADRENO_CHIP_IDS(0x02020000),
48 .family = ADRENO_2XX_GEN2,
49 .revn = 220,
50 .fw = {
51 [ADRENO_FW_PM4] = "leia_pm4_470.fw",
52 [ADRENO_FW_PFP] = "leia_pfp_470.fw",
53 },
54 .gmem = SZ_512K,
55 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
56 .init = a2xx_gpu_init,
57 }, {
58 .chip_ids = ADRENO_CHIP_IDS(0x03000512),
59 .family = ADRENO_3XX,
60 .fw = {
61 [ADRENO_FW_PM4] = "a330_pm4.fw",
62 [ADRENO_FW_PFP] = "a330_pfp.fw",
63 },
64 .gmem = SZ_128K,
65 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
66 .init = a3xx_gpu_init,
67 }, {
68 .chip_ids = ADRENO_CHIP_IDS(0x03000520),
69 .family = ADRENO_3XX,
70 .revn = 305,
71 .fw = {
72 [ADRENO_FW_PM4] = "a300_pm4.fw",
73 [ADRENO_FW_PFP] = "a300_pfp.fw",
74 },
75 .gmem = SZ_256K,
76 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
77 .init = a3xx_gpu_init,
78 }, {
79 .chip_ids = ADRENO_CHIP_IDS(0x03000600),
80 .family = ADRENO_3XX,
81 .revn = 307, /* because a305c is revn==306 */
82 .fw = {
83 [ADRENO_FW_PM4] = "a300_pm4.fw",
84 [ADRENO_FW_PFP] = "a300_pfp.fw",
85 },
86 .gmem = SZ_128K,
87 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
88 .init = a3xx_gpu_init,
89 }, {
90 .chip_ids = ADRENO_CHIP_IDS(
91 0x03020000,
92 0x03020001,
93 0x03020002
94 ),
95 .family = ADRENO_3XX,
96 .revn = 320,
97 .fw = {
98 [ADRENO_FW_PM4] = "a300_pm4.fw",
99 [ADRENO_FW_PFP] = "a300_pfp.fw",
100 },
101 .gmem = SZ_512K,
102 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
103 .init = a3xx_gpu_init,
104 }, {
105 .chip_ids = ADRENO_CHIP_IDS(
106 0x03030000,
107 0x03030001,
108 0x03030002
109 ),
110 .family = ADRENO_3XX,
111 .revn = 330,
112 .fw = {
113 [ADRENO_FW_PM4] = "a330_pm4.fw",
114 [ADRENO_FW_PFP] = "a330_pfp.fw",
115 },
116 .gmem = SZ_1M,
117 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
118 .init = a3xx_gpu_init,
119 }, {
120 .chip_ids = ADRENO_CHIP_IDS(0x04000500),
121 .family = ADRENO_4XX,
122 .revn = 405,
123 .fw = {
124 [ADRENO_FW_PM4] = "a420_pm4.fw",
125 [ADRENO_FW_PFP] = "a420_pfp.fw",
126 },
127 .gmem = SZ_256K,
128 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
129 .init = a4xx_gpu_init,
130 }, {
131 .chip_ids = ADRENO_CHIP_IDS(0x04020000),
132 .family = ADRENO_4XX,
133 .revn = 420,
134 .fw = {
135 [ADRENO_FW_PM4] = "a420_pm4.fw",
136 [ADRENO_FW_PFP] = "a420_pfp.fw",
137 },
138 .gmem = (SZ_1M + SZ_512K),
139 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
140 .init = a4xx_gpu_init,
141 }, {
142 .chip_ids = ADRENO_CHIP_IDS(0x04030002),
143 .family = ADRENO_4XX,
144 .revn = 430,
145 .fw = {
146 [ADRENO_FW_PM4] = "a420_pm4.fw",
147 [ADRENO_FW_PFP] = "a420_pfp.fw",
148 },
149 .gmem = (SZ_1M + SZ_512K),
150 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
151 .init = a4xx_gpu_init,
152 }, {
153 .chip_ids = ADRENO_CHIP_IDS(0x05000600),
154 .family = ADRENO_5XX,
155 .revn = 506,
156 .fw = {
157 [ADRENO_FW_PM4] = "a530_pm4.fw",
158 [ADRENO_FW_PFP] = "a530_pfp.fw",
159 },
160 .gmem = (SZ_128K + SZ_8K),
161 /*
162 * Increase inactive period to 250 to avoid bouncing
163 * the GDSC which appears to make it grumpy
164 */
165 .inactive_period = 250,
166 .quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
167 ADRENO_QUIRK_LMLOADKILL_DISABLE,
168 .init = a5xx_gpu_init,
169 .zapfw = "a506_zap.mdt",
170 }, {
171 .chip_ids = ADRENO_CHIP_IDS(0x05000800),
172 .family = ADRENO_5XX,
173 .revn = 508,
174 .fw = {
175 [ADRENO_FW_PM4] = "a530_pm4.fw",
176 [ADRENO_FW_PFP] = "a530_pfp.fw",
177 },
178 .gmem = (SZ_128K + SZ_8K),
179 /*
180 * Increase inactive period to 250 to avoid bouncing
181 * the GDSC which appears to make it grumpy
182 */
183 .inactive_period = 250,
184 .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
185 .init = a5xx_gpu_init,
186 .zapfw = "a508_zap.mdt",
187 }, {
188 .chip_ids = ADRENO_CHIP_IDS(0x05000900),
189 .family = ADRENO_5XX,
190 .revn = 509,
191 .fw = {
192 [ADRENO_FW_PM4] = "a530_pm4.fw",
193 [ADRENO_FW_PFP] = "a530_pfp.fw",
194 },
195 .gmem = (SZ_256K + SZ_16K),
196 /*
197 * Increase inactive period to 250 to avoid bouncing
198 * the GDSC which appears to make it grumpy
199 */
200 .inactive_period = 250,
201 .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
202 .init = a5xx_gpu_init,
203 /* Adreno 509 uses the same ZAP as 512 */
204 .zapfw = "a512_zap.mdt",
205 }, {
206 .chip_ids = ADRENO_CHIP_IDS(0x05010000),
207 .family = ADRENO_5XX,
208 .revn = 510,
209 .fw = {
210 [ADRENO_FW_PM4] = "a530_pm4.fw",
211 [ADRENO_FW_PFP] = "a530_pfp.fw",
212 },
213 .gmem = SZ_256K,
214 /*
215 * Increase inactive period to 250 to avoid bouncing
216 * the GDSC which appears to make it grumpy
217 */
218 .inactive_period = 250,
219 .init = a5xx_gpu_init,
220 }, {
221 .chip_ids = ADRENO_CHIP_IDS(0x05010200),
222 .family = ADRENO_5XX,
223 .revn = 512,
224 .fw = {
225 [ADRENO_FW_PM4] = "a530_pm4.fw",
226 [ADRENO_FW_PFP] = "a530_pfp.fw",
227 },
228 .gmem = (SZ_256K + SZ_16K),
229 /*
230 * Increase inactive period to 250 to avoid bouncing
231 * the GDSC which appears to make it grumpy
232 */
233 .inactive_period = 250,
234 .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
235 .init = a5xx_gpu_init,
236 .zapfw = "a512_zap.mdt",
237 }, {
238 .chip_ids = ADRENO_CHIP_IDS(
239 0x05030002,
240 0x05030004
241 ),
242 .family = ADRENO_5XX,
243 .revn = 530,
244 .fw = {
245 [ADRENO_FW_PM4] = "a530_pm4.fw",
246 [ADRENO_FW_PFP] = "a530_pfp.fw",
247 [ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
248 },
249 .gmem = SZ_1M,
250 /*
251 * Increase inactive period to 250 to avoid bouncing
252 * the GDSC which appears to make it grumpy
253 */
254 .inactive_period = 250,
255 .quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
256 ADRENO_QUIRK_FAULT_DETECT_MASK,
257 .init = a5xx_gpu_init,
258 .zapfw = "a530_zap.mdt",
259 }, {
260 .chip_ids = ADRENO_CHIP_IDS(0x05040001),
261 .family = ADRENO_5XX,
262 .revn = 540,
263 .fw = {
264 [ADRENO_FW_PM4] = "a530_pm4.fw",
265 [ADRENO_FW_PFP] = "a530_pfp.fw",
266 [ADRENO_FW_GPMU] = "a540_gpmu.fw2",
267 },
268 .gmem = SZ_1M,
269 /*
270 * Increase inactive period to 250 to avoid bouncing
271 * the GDSC which appears to make it grumpy
272 */
273 .inactive_period = 250,
274 .quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
275 .init = a5xx_gpu_init,
276 .zapfw = "a540_zap.mdt",
277 }, {
278 .chip_ids = ADRENO_CHIP_IDS(0x06010000),
279 .family = ADRENO_6XX_GEN1,
280 .revn = 610,
281 .fw = {
282 [ADRENO_FW_SQE] = "a630_sqe.fw",
283 },
284 .gmem = (SZ_128K + SZ_4K),
285 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
286 .init = a6xx_gpu_init,
287 .zapfw = "a610_zap.mdt",
288 .hwcg = a612_hwcg,
289 /*
290 * There are (at least) three SoCs implementing A610: SM6125
291 * (trinket), SM6115 (bengal) and SM6225 (khaje). Trinket does
292 * not have speedbinning, as only a single SKU exists and we
293 * don't support khaje upstream yet. Hence, this matching
294 * table is only valid for bengal.
295 */
296 .speedbins = ADRENO_SPEEDBINS(
297 { 0, 0 },
298 { 206, 1 },
299 { 200, 2 },
300 { 157, 3 },
301 { 127, 4 },
302 ),
303 }, {
304 .machine = "qcom,sm7150",
305 .chip_ids = ADRENO_CHIP_IDS(0x06010800),
306 .family = ADRENO_6XX_GEN1,
307 .fw = {
308 [ADRENO_FW_SQE] = "a630_sqe.fw",
309 [ADRENO_FW_GMU] = "a630_gmu.bin",
310 },
311 .gmem = SZ_512K,
312 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
313 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
314 .init = a6xx_gpu_init,
315 .zapfw = "a615_zap.mbn",
316 .hwcg = a615_hwcg,
317 .speedbins = ADRENO_SPEEDBINS(
318 { 0, 0 },
319 { 128, 1 },
320 { 146, 2 },
321 { 167, 3 },
322 { 172, 4 },
323 ),
324 }, {
325 .chip_ids = ADRENO_CHIP_IDS(0x06010800),
326 .family = ADRENO_6XX_GEN1,
327 .revn = 618,
328 .fw = {
329 [ADRENO_FW_SQE] = "a630_sqe.fw",
330 [ADRENO_FW_GMU] = "a630_gmu.bin",
331 },
332 .gmem = SZ_512K,
333 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
334 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
335 .init = a6xx_gpu_init,
336 .speedbins = ADRENO_SPEEDBINS(
337 { 0, 0 },
338 { 169, 1 },
339 { 174, 2 },
340 ),
341 }, {
342 .machine = "qcom,sm4350",
343 .chip_ids = ADRENO_CHIP_IDS(0x06010900),
344 .family = ADRENO_6XX_GEN1,
345 .revn = 619,
346 .fw = {
347 [ADRENO_FW_SQE] = "a630_sqe.fw",
348 [ADRENO_FW_GMU] = "a619_gmu.bin",
349 },
350 .gmem = SZ_512K,
351 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
352 .init = a6xx_gpu_init,
353 .zapfw = "a615_zap.mdt",
354 .hwcg = a615_hwcg,
355 .speedbins = ADRENO_SPEEDBINS(
356 { 0, 0 },
357 { 138, 1 },
358 { 92, 2 },
359 ),
360 }, {
361 .machine = "qcom,sm6375",
362 .chip_ids = ADRENO_CHIP_IDS(0x06010901),
363 .family = ADRENO_6XX_GEN1,
364 .revn = 619,
365 .fw = {
366 [ADRENO_FW_SQE] = "a630_sqe.fw",
367 [ADRENO_FW_GMU] = "a619_gmu.bin",
368 },
369 .gmem = SZ_512K,
370 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
371 .init = a6xx_gpu_init,
372 .zapfw = "a615_zap.mdt",
373 .hwcg = a615_hwcg,
374 .speedbins = ADRENO_SPEEDBINS(
375 { 0, 0 },
376 { 190, 1 },
377 { 177, 2 },
378 ),
379 }, {
380 .chip_ids = ADRENO_CHIP_IDS(0x06010900),
381 .family = ADRENO_6XX_GEN1,
382 .revn = 619,
383 .fw = {
384 [ADRENO_FW_SQE] = "a630_sqe.fw",
385 [ADRENO_FW_GMU] = "a619_gmu.bin",
386 },
387 .gmem = SZ_512K,
388 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
389 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
390 .init = a6xx_gpu_init,
391 .zapfw = "a615_zap.mdt",
392 .hwcg = a615_hwcg,
393 .speedbins = ADRENO_SPEEDBINS(
394 { 0, 0 },
395 { 120, 4 },
396 { 138, 3 },
397 { 169, 2 },
398 { 180, 1 },
399 ),
400 }, {
401 .chip_ids = ADRENO_CHIP_IDS(
402 0x06030001,
403 0x06030002
404 ),
405 .family = ADRENO_6XX_GEN1,
406 .revn = 630,
407 .fw = {
408 [ADRENO_FW_SQE] = "a630_sqe.fw",
409 [ADRENO_FW_GMU] = "a630_gmu.bin",
410 },
411 .gmem = SZ_1M,
412 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
413 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
414 .init = a6xx_gpu_init,
415 .zapfw = "a630_zap.mdt",
416 .hwcg = a630_hwcg,
417 }, {
418 .chip_ids = ADRENO_CHIP_IDS(0x06040001),
419 .family = ADRENO_6XX_GEN2,
420 .revn = 640,
421 .fw = {
422 [ADRENO_FW_SQE] = "a630_sqe.fw",
423 [ADRENO_FW_GMU] = "a640_gmu.bin",
424 },
425 .gmem = SZ_1M,
426 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
427 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
428 .init = a6xx_gpu_init,
429 .zapfw = "a640_zap.mdt",
430 .hwcg = a640_hwcg,
431 .speedbins = ADRENO_SPEEDBINS(
432 { 0, 0 },
433 { 1, 1 },
434 ),
435 }, {
436 .chip_ids = ADRENO_CHIP_IDS(0x06050002),
437 .family = ADRENO_6XX_GEN3,
438 .revn = 650,
439 .fw = {
440 [ADRENO_FW_SQE] = "a650_sqe.fw",
441 [ADRENO_FW_GMU] = "a650_gmu.bin",
442 },
443 .gmem = SZ_1M + SZ_128K,
444 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
445 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
446 ADRENO_QUIRK_HAS_HW_APRIV,
447 .init = a6xx_gpu_init,
448 .zapfw = "a650_zap.mdt",
449 .hwcg = a650_hwcg,
450 .address_space_size = SZ_16G,
451 .speedbins = ADRENO_SPEEDBINS(
452 { 0, 0 },
453 { 1, 1 },
454 { 2, 3 }, /* Yep, 2 and 3 are swapped! :/ */
455 { 3, 2 },
456 ),
457 }, {
458 .chip_ids = ADRENO_CHIP_IDS(0x06060001),
459 .family = ADRENO_6XX_GEN4,
460 .revn = 660,
461 .fw = {
462 [ADRENO_FW_SQE] = "a660_sqe.fw",
463 [ADRENO_FW_GMU] = "a660_gmu.bin",
464 },
465 .gmem = SZ_1M + SZ_512K,
466 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
467 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
468 ADRENO_QUIRK_HAS_HW_APRIV,
469 .init = a6xx_gpu_init,
470 .zapfw = "a660_zap.mdt",
471 .hwcg = a660_hwcg,
472 .address_space_size = SZ_16G,
473 }, {
474 .chip_ids = ADRENO_CHIP_IDS(0x06030500),
475 .family = ADRENO_6XX_GEN4,
476 .fw = {
477 [ADRENO_FW_SQE] = "a660_sqe.fw",
478 [ADRENO_FW_GMU] = "a660_gmu.bin",
479 },
480 .gmem = SZ_512K,
481 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
482 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
483 ADRENO_QUIRK_HAS_HW_APRIV,
484 .init = a6xx_gpu_init,
485 .zapfw = "a660_zap.mbn",
486 .hwcg = a660_hwcg,
487 .address_space_size = SZ_16G,
488 .speedbins = ADRENO_SPEEDBINS(
489 { 0, 0 },
490 { 117, 0 },
491 { 172, 2 }, /* Called speedbin 1 downstream, but let's not break things! */
492 { 190, 1 },
493 ),
494 }, {
495 .chip_ids = ADRENO_CHIP_IDS(0x06080001),
496 .family = ADRENO_6XX_GEN2,
497 .revn = 680,
498 .fw = {
499 [ADRENO_FW_SQE] = "a630_sqe.fw",
500 [ADRENO_FW_GMU] = "a640_gmu.bin",
501 },
502 .gmem = SZ_2M,
503 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
504 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
505 .init = a6xx_gpu_init,
506 .zapfw = "a640_zap.mdt",
507 .hwcg = a640_hwcg,
508 }, {
509 .chip_ids = ADRENO_CHIP_IDS(0x06090000),
510 .family = ADRENO_6XX_GEN4,
511 .fw = {
512 [ADRENO_FW_SQE] = "a660_sqe.fw",
513 [ADRENO_FW_GMU] = "a660_gmu.bin",
514 },
515 .gmem = SZ_4M,
516 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
517 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
518 ADRENO_QUIRK_HAS_HW_APRIV,
519 .init = a6xx_gpu_init,
520 .zapfw = "a690_zap.mdt",
521 .hwcg = a690_hwcg,
522 .address_space_size = SZ_16G,
523 }, {
524 .chip_ids = ADRENO_CHIP_IDS(0x07000200),
525 .family = ADRENO_6XX_GEN1, /* NOT a mistake! */
526 .fw = {
527 [ADRENO_FW_SQE] = "a702_sqe.fw",
528 },
529 .gmem = SZ_128K,
530 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
531 .quirks = ADRENO_QUIRK_HAS_HW_APRIV,
532 .init = a6xx_gpu_init,
533 .zapfw = "a702_zap.mbn",
534 .hwcg = a702_hwcg,
535 .speedbins = ADRENO_SPEEDBINS(
536 { 0, 0 },
537 { 236, 1 },
538 { 178, 2 },
539 { 142, 3 },
540 ),
541 }, {
542 .chip_ids = ADRENO_CHIP_IDS(0x07030001),
543 .family = ADRENO_7XX_GEN1,
544 .fw = {
545 [ADRENO_FW_SQE] = "a730_sqe.fw",
546 [ADRENO_FW_GMU] = "gmu_gen70000.bin",
547 },
548 .gmem = SZ_2M,
549 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
550 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
551 ADRENO_QUIRK_HAS_HW_APRIV,
552 .init = a6xx_gpu_init,
553 .zapfw = "a730_zap.mdt",
554 .hwcg = a730_hwcg,
555 .address_space_size = SZ_16G,
556 }, {
557 .chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
558 .family = ADRENO_7XX_GEN2,
559 .fw = {
560 [ADRENO_FW_SQE] = "a740_sqe.fw",
561 [ADRENO_FW_GMU] = "gmu_gen70200.bin",
562 },
563 .gmem = 3 * SZ_1M,
564 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
565 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
566 ADRENO_QUIRK_HAS_HW_APRIV,
567 .init = a6xx_gpu_init,
568 .zapfw = "a740_zap.mdt",
569 .hwcg = a740_hwcg,
570 .address_space_size = SZ_16G,
571 }, {
572 .chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
573 .family = ADRENO_7XX_GEN3,
574 .fw = {
575 [ADRENO_FW_SQE] = "gen70900_sqe.fw",
576 [ADRENO_FW_GMU] = "gmu_gen70900.bin",
577 },
578 .gmem = 3 * SZ_1M,
579 .inactive_period = DRM_MSM_INACTIVE_PERIOD,
580 .quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
581 ADRENO_QUIRK_HAS_HW_APRIV,
582 .init = a6xx_gpu_init,
583 .zapfw = "gen70900_zap.mbn",
584 .address_space_size = SZ_16G,
585 },
586};
587
588MODULE_FIRMWARE("qcom/a300_pm4.fw");
589MODULE_FIRMWARE("qcom/a300_pfp.fw");
590MODULE_FIRMWARE("qcom/a330_pm4.fw");
591MODULE_FIRMWARE("qcom/a330_pfp.fw");
592MODULE_FIRMWARE("qcom/a420_pm4.fw");
593MODULE_FIRMWARE("qcom/a420_pfp.fw");
594MODULE_FIRMWARE("qcom/a530_pm4.fw");
595MODULE_FIRMWARE("qcom/a530_pfp.fw");
596MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
597MODULE_FIRMWARE("qcom/a530_zap.mdt");
598MODULE_FIRMWARE("qcom/a530_zap.b00");
599MODULE_FIRMWARE("qcom/a530_zap.b01");
600MODULE_FIRMWARE("qcom/a530_zap.b02");
601MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
602MODULE_FIRMWARE("qcom/a615_zap.mbn");
603MODULE_FIRMWARE("qcom/a619_gmu.bin");
604MODULE_FIRMWARE("qcom/a630_sqe.fw");
605MODULE_FIRMWARE("qcom/a630_gmu.bin");
606MODULE_FIRMWARE("qcom/a630_zap.mbn");
607MODULE_FIRMWARE("qcom/a640_gmu.bin");
608MODULE_FIRMWARE("qcom/a650_gmu.bin");
609MODULE_FIRMWARE("qcom/a650_sqe.fw");
610MODULE_FIRMWARE("qcom/a660_gmu.bin");
611MODULE_FIRMWARE("qcom/a660_sqe.fw");
612MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
613MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
614MODULE_FIRMWARE("qcom/yamato_pfp.fw");
615MODULE_FIRMWARE("qcom/yamato_pm4.fw");
616
617static const struct adreno_info *adreno_info(uint32_t chip_id)
618{
619 /* identify gpu: */
620 for (int i = 0; i < ARRAY_SIZE(gpulist); i++) {
621 const struct adreno_info *info = &gpulist[i];
622 if (info->machine && !of_machine_is_compatible(info->machine))
623 continue;
624 for (int j = 0; info->chip_ids[j]; j++)
625 if (info->chip_ids[j] == chip_id)
626 return info;
627 }
628
629 return NULL;
630}
631
632struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
633{
634 struct msm_drm_private *priv = dev->dev_private;
635 struct platform_device *pdev = priv->gpu_pdev;
636 struct msm_gpu *gpu = NULL;
637 struct adreno_gpu *adreno_gpu;
638 int ret;
639
640 if (pdev)
641 gpu = dev_to_gpu(&pdev->dev);
642
643 if (!gpu) {
644 dev_err_once(dev->dev, "no GPU device was found\n");
645 return NULL;
646 }
647
648 adreno_gpu = to_adreno_gpu(gpu);
649
650 /*
651 * The number one reason for HW init to fail is if the firmware isn't
652 * loaded yet. Try that first and don't bother continuing on
653 * otherwise
654 */
655
656 ret = adreno_load_fw(adreno_gpu);
657 if (ret)
658 return NULL;
659
660 if (gpu->funcs->ucode_load) {
661 ret = gpu->funcs->ucode_load(gpu);
662 if (ret)
663 return NULL;
664 }
665
666 /*
667 * Now that we have firmware loaded, and are ready to begin
668 * booting the gpu, go ahead and enable runpm:
669 */
670 pm_runtime_enable(&pdev->dev);
671
672 ret = pm_runtime_get_sync(&pdev->dev);
673 if (ret < 0) {
674 pm_runtime_put_noidle(&pdev->dev);
675 DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
676 goto err_disable_rpm;
677 }
678
679 mutex_lock(&gpu->lock);
680 ret = msm_gpu_hw_init(gpu);
681 mutex_unlock(lock: &gpu->lock);
682 if (ret) {
683 DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
684 goto err_put_rpm;
685 }
686
687 pm_runtime_put_autosuspend(&pdev->dev);
688
689#ifdef CONFIG_DEBUG_FS
690 if (gpu->funcs->debugfs_init) {
691 gpu->funcs->debugfs_init(gpu, dev->primary);
692 gpu->funcs->debugfs_init(gpu, dev->render);
693 }
694#endif
695
696 return gpu;
697
698err_put_rpm:
699 pm_runtime_put_sync_suspend(&pdev->dev);
700err_disable_rpm:
701 pm_runtime_disable(&pdev->dev);
702
703 return NULL;
704}
705
706static int find_chipid(struct device *dev, uint32_t *chipid)
707{
708 struct device_node *node = dev->of_node;
709 const char *compat;
710 int ret;
711
712 /* first search the compat strings for qcom,adreno-XYZ.W: */
713 ret = of_property_read_string_index(node, "compatible", 0, &compat);
714 if (ret == 0) {
715 unsigned int r, patch;
716
717 if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 ||
718 sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) {
719 uint32_t core, major, minor;
720
721 core = r / 100;
722 r %= 100;
723 major = r / 10;
724 r %= 10;
725 minor = r;
726
727 *chipid = (core << 24) |
728 (major << 16) |
729 (minor << 8) |
730 patch;
731
732 return 0;
733 }
734
735 if (sscanf(compat, "qcom,adreno-%08x", chipid) == 1)
736 return 0;
737 }
738
739 /* and if that fails, fall back to legacy "qcom,chipid" property: */
740 ret = of_property_read_u32(node, "qcom,chipid", chipid);
741 if (ret) {
742 DRM_DEV_ERROR(dev, "could not parse qcom,chipid: %d\n", ret);
743 return ret;
744 }
745
746 dev_warn(dev, "Using legacy qcom,chipid binding!\n");
747
748 return 0;
749}
750
751static int adreno_bind(struct device *dev, struct device *master, void *data)
752{
753 static struct adreno_platform_config config = {};
754 const struct adreno_info *info;
755 struct msm_drm_private *priv = dev_get_drvdata(master);
756 struct drm_device *drm = priv->dev;
757 struct msm_gpu *gpu;
758 int ret;
759
760 ret = find_chipid(dev, chipid: &config.chip_id);
761 if (ret)
762 return ret;
763
764 dev->platform_data = &config;
765 priv->gpu_pdev = to_platform_device(dev);
766
767 info = adreno_info(chip_id: config.chip_id);
768 if (!info) {
769 dev_warn(drm->dev, "Unknown GPU revision: %"ADRENO_CHIPID_FMT"\n",
770 ADRENO_CHIPID_ARGS(config.chip_id));
771 return -ENXIO;
772 }
773
774 config.info = info;
775
776 DBG("Found GPU: %"ADRENO_CHIPID_FMT, ADRENO_CHIPID_ARGS(config.chip_id));
777
778 priv->is_a2xx = info->family < ADRENO_3XX;
779 priv->has_cached_coherent =
780 !!(info->quirks & ADRENO_QUIRK_HAS_CACHED_COHERENT);
781
782 gpu = info->init(drm);
783 if (IS_ERR(ptr: gpu)) {
784 dev_warn(drm->dev, "failed to load adreno gpu\n");
785 return PTR_ERR(ptr: gpu);
786 }
787
788 ret = dev_pm_opp_of_find_icc_paths(dev, NULL);
789 if (ret)
790 return ret;
791
792 return 0;
793}
794
795static int adreno_system_suspend(struct device *dev);
796static void adreno_unbind(struct device *dev, struct device *master,
797 void *data)
798{
799 struct msm_drm_private *priv = dev_get_drvdata(master);
800 struct msm_gpu *gpu = dev_to_gpu(dev);
801
802 if (pm_runtime_enabled(dev))
803 WARN_ON_ONCE(adreno_system_suspend(dev));
804 gpu->funcs->destroy(gpu);
805
806 priv->gpu_pdev = NULL;
807}
808
809static const struct component_ops a3xx_ops = {
810 .bind = adreno_bind,
811 .unbind = adreno_unbind,
812};
813
814static void adreno_device_register_headless(void)
815{
816 /* on imx5, we don't have a top-level mdp/dpu node
817 * this creates a dummy node for the driver for that case
818 */
819 struct platform_device_info dummy_info = {
820 .parent = NULL,
821 .name = "msm",
822 .id = -1,
823 .res = NULL,
824 .num_res = 0,
825 .data = NULL,
826 .size_data = 0,
827 .dma_mask = ~0,
828 };
829 platform_device_register_full(&dummy_info);
830}
831
832static int adreno_probe(struct platform_device *pdev)
833{
834
835 int ret;
836
837 ret = component_add(&pdev->dev, &a3xx_ops);
838 if (ret)
839 return ret;
840
841 if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon"))
842 adreno_device_register_headless();
843
844 return 0;
845}
846
847static void adreno_remove(struct platform_device *pdev)
848{
849 component_del(&pdev->dev, &a3xx_ops);
850}
851
852static void adreno_shutdown(struct platform_device *pdev)
853{
854 WARN_ON_ONCE(adreno_system_suspend(&pdev->dev));
855}
856
857static const struct of_device_id dt_match[] = {
858 { .compatible = "qcom,adreno" },
859 { .compatible = "qcom,adreno-3xx" },
860 /* for compatibility with imx5 gpu: */
861 { .compatible = "amd,imageon" },
862 /* for backwards compat w/ downstream kgsl DT files: */
863 { .compatible = "qcom,kgsl-3d0" },
864 {}
865};
866
867static int adreno_runtime_resume(struct device *dev)
868{
869 struct msm_gpu *gpu = dev_to_gpu(dev);
870
871 return gpu->funcs->pm_resume(gpu);
872}
873
874static int adreno_runtime_suspend(struct device *dev)
875{
876 struct msm_gpu *gpu = dev_to_gpu(dev);
877
878 /*
879 * We should be holding a runpm ref, which will prevent
880 * runtime suspend. In the system suspend path, we've
881 * already waited for active jobs to complete.
882 */
883 WARN_ON_ONCE(gpu->active_submits);
884
885 return gpu->funcs->pm_suspend(gpu);
886}
887
888static void suspend_scheduler(struct msm_gpu *gpu)
889{
890 int i;
891
892 /*
893 * Shut down the scheduler before we force suspend, so that
894 * suspend isn't racing with scheduler kthread feeding us
895 * more work.
896 *
897 * Note, we just want to park the thread, and let any jobs
898 * that are already on the hw queue complete normally, as
899 * opposed to the drm_sched_stop() path used for handling
900 * faulting/timed-out jobs. We can't really cancel any jobs
901 * already on the hw queue without racing with the GPU.
902 */
903 for (i = 0; i < gpu->nr_rings; i++) {
904 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
905
906 drm_sched_wqueue_stop(sched);
907 }
908}
909
910static void resume_scheduler(struct msm_gpu *gpu)
911{
912 int i;
913
914 for (i = 0; i < gpu->nr_rings; i++) {
915 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
916
917 drm_sched_wqueue_start(sched);
918 }
919}
920
921static int adreno_system_suspend(struct device *dev)
922{
923 struct msm_gpu *gpu = dev_to_gpu(dev);
924 int remaining, ret;
925
926 if (!gpu)
927 return 0;
928
929 suspend_scheduler(gpu);
930
931 remaining = wait_event_timeout(gpu->retire_event,
932 gpu->active_submits == 0,
933 msecs_to_jiffies(1000));
934 if (remaining == 0) {
935 dev_err(dev, "Timeout waiting for GPU to suspend\n");
936 ret = -EBUSY;
937 goto out;
938 }
939
940 ret = pm_runtime_force_suspend(dev);
941out:
942 if (ret)
943 resume_scheduler(gpu);
944
945 return ret;
946}
947
948static int adreno_system_resume(struct device *dev)
949{
950 struct msm_gpu *gpu = dev_to_gpu(dev);
951
952 if (!gpu)
953 return 0;
954
955 resume_scheduler(gpu);
956 return pm_runtime_force_resume(dev);
957}
958
959static const struct dev_pm_ops adreno_pm_ops = {
960 SYSTEM_SLEEP_PM_OPS(adreno_system_suspend, adreno_system_resume)
961 RUNTIME_PM_OPS(adreno_runtime_suspend, adreno_runtime_resume, NULL)
962};
963
964static struct platform_driver adreno_driver = {
965 .probe = adreno_probe,
966 .remove_new = adreno_remove,
967 .shutdown = adreno_shutdown,
968 .driver = {
969 .name = "adreno",
970 .of_match_table = dt_match,
971 .pm = &adreno_pm_ops,
972 },
973};
974
975void __init adreno_register(void)
976{
977 platform_driver_register(&adreno_driver);
978}
979
980void __exit adreno_unregister(void)
981{
982 platform_driver_unregister(&adreno_driver);
983}
984

source code of linux/drivers/gpu/drm/msm/adreno/adreno_device.c