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