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(&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, &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(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(gpu)) {
784		dev_warn(drm->dev, "failed to load adreno gpu\n");
785		return PTR_ERR(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