fa527935ffd4230a546000d5f382a912625e9f56
[sfrench/cifs-2.6.git] / drivers / gpu / drm / msm / adreno / adreno_device.c
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
11 bool hang_debug = false;
12 MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)");
13 module_param_named(hang_debug, hang_debug, bool, 0600);
14
15 bool snapshot_debugbus = false;
16 MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)");
17 module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
18
19 bool allow_vram_carveout = false;
20 MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU");
21 module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600);
22
23 static 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(0x06010900),
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(0x06080000),
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
496 MODULE_FIRMWARE("qcom/a300_pm4.fw");
497 MODULE_FIRMWARE("qcom/a300_pfp.fw");
498 MODULE_FIRMWARE("qcom/a330_pm4.fw");
499 MODULE_FIRMWARE("qcom/a330_pfp.fw");
500 MODULE_FIRMWARE("qcom/a420_pm4.fw");
501 MODULE_FIRMWARE("qcom/a420_pfp.fw");
502 MODULE_FIRMWARE("qcom/a530_pm4.fw");
503 MODULE_FIRMWARE("qcom/a530_pfp.fw");
504 MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
505 MODULE_FIRMWARE("qcom/a530_zap.mdt");
506 MODULE_FIRMWARE("qcom/a530_zap.b00");
507 MODULE_FIRMWARE("qcom/a530_zap.b01");
508 MODULE_FIRMWARE("qcom/a530_zap.b02");
509 MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
510 MODULE_FIRMWARE("qcom/a619_gmu.bin");
511 MODULE_FIRMWARE("qcom/a630_sqe.fw");
512 MODULE_FIRMWARE("qcom/a630_gmu.bin");
513 MODULE_FIRMWARE("qcom/a630_zap.mbn");
514 MODULE_FIRMWARE("qcom/a640_gmu.bin");
515 MODULE_FIRMWARE("qcom/a650_gmu.bin");
516 MODULE_FIRMWARE("qcom/a650_sqe.fw");
517 MODULE_FIRMWARE("qcom/a660_gmu.bin");
518 MODULE_FIRMWARE("qcom/a660_sqe.fw");
519 MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
520 MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
521 MODULE_FIRMWARE("qcom/yamato_pfp.fw");
522 MODULE_FIRMWARE("qcom/yamato_pm4.fw");
523
524 static 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
539 struct 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
605 err_put_rpm:
606         pm_runtime_put_sync_suspend(&pdev->dev);
607 err_disable_rpm:
608         pm_runtime_disable(&pdev->dev);
609
610         return NULL;
611 }
612
613 static 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
658 static 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
702 static int adreno_system_suspend(struct device *dev);
703 static 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
716 static const struct component_ops a3xx_ops = {
717         .bind   = adreno_bind,
718         .unbind = adreno_unbind,
719 };
720
721 static 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
739 static 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
754 static void adreno_remove(struct platform_device *pdev)
755 {
756         component_del(&pdev->dev, &a3xx_ops);
757 }
758
759 static void adreno_shutdown(struct platform_device *pdev)
760 {
761         WARN_ON_ONCE(adreno_system_suspend(&pdev->dev));
762 }
763
764 static const struct of_device_id dt_match[] = {
765         { .compatible = "qcom,adreno" },
766         { .compatible = "qcom,adreno-3xx" },
767         /* for compatibility with imx5 gpu: */
768         { .compatible = "amd,imageon" },
769         /* for backwards compat w/ downstream kgsl DT files: */
770         { .compatible = "qcom,kgsl-3d0" },
771         {}
772 };
773
774 static int adreno_runtime_resume(struct device *dev)
775 {
776         struct msm_gpu *gpu = dev_to_gpu(dev);
777
778         return gpu->funcs->pm_resume(gpu);
779 }
780
781 static int adreno_runtime_suspend(struct device *dev)
782 {
783         struct msm_gpu *gpu = dev_to_gpu(dev);
784
785         /*
786          * We should be holding a runpm ref, which will prevent
787          * runtime suspend.  In the system suspend path, we've
788          * already waited for active jobs to complete.
789          */
790         WARN_ON_ONCE(gpu->active_submits);
791
792         return gpu->funcs->pm_suspend(gpu);
793 }
794
795 static void suspend_scheduler(struct msm_gpu *gpu)
796 {
797         int i;
798
799         /*
800          * Shut down the scheduler before we force suspend, so that
801          * suspend isn't racing with scheduler kthread feeding us
802          * more work.
803          *
804          * Note, we just want to park the thread, and let any jobs
805          * that are already on the hw queue complete normally, as
806          * opposed to the drm_sched_stop() path used for handling
807          * faulting/timed-out jobs.  We can't really cancel any jobs
808          * already on the hw queue without racing with the GPU.
809          */
810         for (i = 0; i < gpu->nr_rings; i++) {
811                 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
812                 kthread_park(sched->thread);
813         }
814 }
815
816 static void resume_scheduler(struct msm_gpu *gpu)
817 {
818         int i;
819
820         for (i = 0; i < gpu->nr_rings; i++) {
821                 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
822                 kthread_unpark(sched->thread);
823         }
824 }
825
826 static int adreno_system_suspend(struct device *dev)
827 {
828         struct msm_gpu *gpu = dev_to_gpu(dev);
829         int remaining, ret;
830
831         if (!gpu)
832                 return 0;
833
834         suspend_scheduler(gpu);
835
836         remaining = wait_event_timeout(gpu->retire_event,
837                                        gpu->active_submits == 0,
838                                        msecs_to_jiffies(1000));
839         if (remaining == 0) {
840                 dev_err(dev, "Timeout waiting for GPU to suspend\n");
841                 ret = -EBUSY;
842                 goto out;
843         }
844
845         ret = pm_runtime_force_suspend(dev);
846 out:
847         if (ret)
848                 resume_scheduler(gpu);
849
850         return ret;
851 }
852
853 static int adreno_system_resume(struct device *dev)
854 {
855         struct msm_gpu *gpu = dev_to_gpu(dev);
856
857         if (!gpu)
858                 return 0;
859
860         resume_scheduler(gpu);
861         return pm_runtime_force_resume(dev);
862 }
863
864 static const struct dev_pm_ops adreno_pm_ops = {
865         SYSTEM_SLEEP_PM_OPS(adreno_system_suspend, adreno_system_resume)
866         RUNTIME_PM_OPS(adreno_runtime_suspend, adreno_runtime_resume, NULL)
867 };
868
869 static struct platform_driver adreno_driver = {
870         .probe = adreno_probe,
871         .remove_new = adreno_remove,
872         .shutdown = adreno_shutdown,
873         .driver = {
874                 .name = "adreno",
875                 .of_match_table = dt_match,
876                 .pm = &adreno_pm_ops,
877         },
878 };
879
880 void __init adreno_register(void)
881 {
882         platform_driver_register(&adreno_driver);
883 }
884
885 void __exit adreno_unregister(void)
886 {
887         platform_driver_unregister(&adreno_driver);
888 }