]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/gpu/drm/msm/adreno/a5xx_gpu.c
BackMerge tag 'v4.12-rc5' into drm-next
[mirror_ubuntu-bionic-kernel.git] / drivers / gpu / drm / msm / adreno / a5xx_gpu.c
CommitLineData
2002c9c3 1/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
b5f103ab
JC
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include "msm_gem.h"
7f8036b7 15#include "msm_mmu.h"
b5f103ab
JC
16#include "a5xx_gpu.h"
17
18extern bool hang_debug;
19static void a5xx_dump(struct msm_gpu *gpu);
20
21static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
22 struct msm_file_private *ctx)
23{
24 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
25 struct msm_drm_private *priv = gpu->dev->dev_private;
26 struct msm_ringbuffer *ring = gpu->rb;
27 unsigned int i, ibs = 0;
28
29 for (i = 0; i < submit->nr_cmds; i++) {
30 switch (submit->cmd[i].type) {
31 case MSM_SUBMIT_CMD_IB_TARGET_BUF:
32 break;
33 case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
34 if (priv->lastctx == ctx)
35 break;
36 case MSM_SUBMIT_CMD_BUF:
37 OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
38 OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
39 OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
40 OUT_RING(ring, submit->cmd[i].size);
41 ibs++;
42 break;
43 }
44 }
45
46 OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
47 OUT_RING(ring, submit->fence->seqno);
48
49 OUT_PKT7(ring, CP_EVENT_WRITE, 4);
50 OUT_RING(ring, CACHE_FLUSH_TS | (1 << 31));
51 OUT_RING(ring, lower_32_bits(rbmemptr(adreno_gpu, fence)));
52 OUT_RING(ring, upper_32_bits(rbmemptr(adreno_gpu, fence)));
53 OUT_RING(ring, submit->fence->seqno);
54
55 gpu->funcs->flush(gpu);
56}
57
58struct a5xx_hwcg {
59 u32 offset;
60 u32 value;
61};
62
63static const struct a5xx_hwcg a530_hwcg[] = {
64 {REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
65 {REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
66 {REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
67 {REG_A5XX_RBBM_CLOCK_CNTL_SP3, 0x02222222},
68 {REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
69 {REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220},
70 {REG_A5XX_RBBM_CLOCK_CNTL2_SP2, 0x02222220},
71 {REG_A5XX_RBBM_CLOCK_CNTL2_SP3, 0x02222220},
72 {REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
73 {REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF},
74 {REG_A5XX_RBBM_CLOCK_HYST_SP2, 0x0000F3CF},
75 {REG_A5XX_RBBM_CLOCK_HYST_SP3, 0x0000F3CF},
76 {REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
77 {REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
78 {REG_A5XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
79 {REG_A5XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
80 {REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
81 {REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222},
82 {REG_A5XX_RBBM_CLOCK_CNTL_TP2, 0x22222222},
83 {REG_A5XX_RBBM_CLOCK_CNTL_TP3, 0x22222222},
84 {REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
85 {REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
86 {REG_A5XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
87 {REG_A5XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
88 {REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
89 {REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222},
90 {REG_A5XX_RBBM_CLOCK_CNTL3_TP2, 0x00002222},
91 {REG_A5XX_RBBM_CLOCK_CNTL3_TP3, 0x00002222},
92 {REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
93 {REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
94 {REG_A5XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
95 {REG_A5XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
96 {REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
97 {REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
98 {REG_A5XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
99 {REG_A5XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
100 {REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
101 {REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777},
102 {REG_A5XX_RBBM_CLOCK_HYST3_TP2, 0x00007777},
103 {REG_A5XX_RBBM_CLOCK_HYST3_TP3, 0x00007777},
104 {REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
105 {REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
106 {REG_A5XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
107 {REG_A5XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
108 {REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
109 {REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
110 {REG_A5XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
111 {REG_A5XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
112 {REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
113 {REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111},
114 {REG_A5XX_RBBM_CLOCK_DELAY3_TP2, 0x00001111},
115 {REG_A5XX_RBBM_CLOCK_DELAY3_TP3, 0x00001111},
116 {REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
117 {REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
118 {REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
119 {REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
120 {REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444},
121 {REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
122 {REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
123 {REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
124 {REG_A5XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
125 {REG_A5XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
126 {REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
127 {REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222},
128 {REG_A5XX_RBBM_CLOCK_CNTL2_RB2, 0x00222222},
129 {REG_A5XX_RBBM_CLOCK_CNTL2_RB3, 0x00222222},
130 {REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
131 {REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
132 {REG_A5XX_RBBM_CLOCK_CNTL_CCU2, 0x00022220},
133 {REG_A5XX_RBBM_CLOCK_CNTL_CCU3, 0x00022220},
134 {REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
135 {REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
136 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
137 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
138 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU2, 0x04040404},
139 {REG_A5XX_RBBM_CLOCK_HYST_RB_CCU3, 0x04040404},
140 {REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
141 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
142 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002},
143 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_2, 0x00000002},
144 {REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_3, 0x00000002},
145 {REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
146 {REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
147 {REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
148 {REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
149 {REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
150 {REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
151 {REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
152 {REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
153 {REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
154 {REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
155 {REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
156};
157
158static const struct {
159 int (*test)(struct adreno_gpu *gpu);
160 const struct a5xx_hwcg *regs;
161 unsigned int count;
162} a5xx_hwcg_regs[] = {
163 { adreno_is_a530, a530_hwcg, ARRAY_SIZE(a530_hwcg), },
164};
165
166static void _a5xx_enable_hwcg(struct msm_gpu *gpu,
167 const struct a5xx_hwcg *regs, unsigned int count)
168{
169 unsigned int i;
170
171 for (i = 0; i < count; i++)
172 gpu_write(gpu, regs[i].offset, regs[i].value);
173
174 gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xAAA8AA00);
175 gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, 0x182);
176}
177
178static void a5xx_enable_hwcg(struct msm_gpu *gpu)
179{
180 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
181 unsigned int i;
182
183 for (i = 0; i < ARRAY_SIZE(a5xx_hwcg_regs); i++) {
184 if (a5xx_hwcg_regs[i].test(adreno_gpu)) {
185 _a5xx_enable_hwcg(gpu, a5xx_hwcg_regs[i].regs,
186 a5xx_hwcg_regs[i].count);
187 return;
188 }
189 }
190}
191
192static int a5xx_me_init(struct msm_gpu *gpu)
193{
194 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
195 struct msm_ringbuffer *ring = gpu->rb;
196
197 OUT_PKT7(ring, CP_ME_INIT, 8);
198
199 OUT_RING(ring, 0x0000002F);
200
201 /* Enable multiple hardware contexts */
202 OUT_RING(ring, 0x00000003);
203
204 /* Enable error detection */
205 OUT_RING(ring, 0x20000000);
206
207 /* Don't enable header dump */
208 OUT_RING(ring, 0x00000000);
209 OUT_RING(ring, 0x00000000);
210
211 /* Specify workarounds for various microcode issues */
212 if (adreno_is_a530(adreno_gpu)) {
213 /* Workaround for token end syncs
214 * Force a WFI after every direct-render 3D mode draw and every
215 * 2D mode 3 draw
216 */
217 OUT_RING(ring, 0x0000000B);
218 } else {
219 /* No workarounds enabled */
220 OUT_RING(ring, 0x00000000);
221 }
222
223 OUT_RING(ring, 0x00000000);
224 OUT_RING(ring, 0x00000000);
225
226 gpu->funcs->flush(gpu);
227
228 return gpu->funcs->idle(gpu) ? 0 : -EINVAL;
229}
230
231static struct drm_gem_object *a5xx_ucode_load_bo(struct msm_gpu *gpu,
232 const struct firmware *fw, u64 *iova)
233{
234 struct drm_device *drm = gpu->dev;
235 struct drm_gem_object *bo;
236 void *ptr;
237
238 mutex_lock(&drm->struct_mutex);
239 bo = msm_gem_new(drm, fw->size - 4, MSM_BO_UNCACHED);
240 mutex_unlock(&drm->struct_mutex);
241
242 if (IS_ERR(bo))
243 return bo;
244
245 ptr = msm_gem_get_vaddr(bo);
246 if (!ptr) {
247 drm_gem_object_unreference_unlocked(bo);
248 return ERR_PTR(-ENOMEM);
249 }
250
251 if (iova) {
252 int ret = msm_gem_get_iova(bo, gpu->id, iova);
253
254 if (ret) {
255 drm_gem_object_unreference_unlocked(bo);
256 return ERR_PTR(ret);
257 }
258 }
259
260 memcpy(ptr, &fw->data[4], fw->size - 4);
261
262 msm_gem_put_vaddr(bo);
263 return bo;
264}
265
266static int a5xx_ucode_init(struct msm_gpu *gpu)
267{
268 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
269 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
270 int ret;
271
272 if (!a5xx_gpu->pm4_bo) {
273 a5xx_gpu->pm4_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pm4,
274 &a5xx_gpu->pm4_iova);
275
276 if (IS_ERR(a5xx_gpu->pm4_bo)) {
277 ret = PTR_ERR(a5xx_gpu->pm4_bo);
278 a5xx_gpu->pm4_bo = NULL;
279 dev_err(gpu->dev->dev, "could not allocate PM4: %d\n",
280 ret);
281 return ret;
282 }
283 }
284
285 if (!a5xx_gpu->pfp_bo) {
286 a5xx_gpu->pfp_bo = a5xx_ucode_load_bo(gpu, adreno_gpu->pfp,
287 &a5xx_gpu->pfp_iova);
288
289 if (IS_ERR(a5xx_gpu->pfp_bo)) {
290 ret = PTR_ERR(a5xx_gpu->pfp_bo);
291 a5xx_gpu->pfp_bo = NULL;
292 dev_err(gpu->dev->dev, "could not allocate PFP: %d\n",
293 ret);
294 return ret;
295 }
296 }
297
298 gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO,
299 REG_A5XX_CP_ME_INSTR_BASE_HI, a5xx_gpu->pm4_iova);
300
301 gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO,
302 REG_A5XX_CP_PFP_INSTR_BASE_HI, a5xx_gpu->pfp_iova);
303
304 return 0;
305}
306
307#define A5XX_INT_MASK (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
308 A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
309 A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
310 A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
311 A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
312 A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
313 A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
314 A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
315 A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
316 A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
317
318static int a5xx_hw_init(struct msm_gpu *gpu)
319{
320 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
321 int ret;
322
323 gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
324
325 /* Make all blocks contribute to the GPU BUSY perf counter */
326 gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xFFFFFFFF);
327
328 /* Enable RBBM error reporting bits */
329 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001);
330
4e09b95d 331 if (adreno_gpu->info->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) {
b5f103ab
JC
332 /*
333 * Mask out the activity signals from RB1-3 to avoid false
334 * positives
335 */
336
337 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL11,
338 0xF0000000);
339 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL12,
340 0xFFFFFFFF);
341 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL13,
342 0xFFFFFFFF);
343 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL14,
344 0xFFFFFFFF);
345 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL15,
346 0xFFFFFFFF);
347 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL16,
348 0xFFFFFFFF);
349 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL17,
350 0xFFFFFFFF);
351 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL18,
352 0xFFFFFFFF);
353 }
354
355 /* Enable fault detection */
356 gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_INT_CNTL,
357 (1 << 30) | 0xFFFF);
358
359 /* Turn on performance counters */
360 gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_CNTL, 0x01);
361
362 /* Increase VFD cache access so LRZ and other data gets evicted less */
363 gpu_write(gpu, REG_A5XX_UCHE_CACHE_WAYS, 0x02);
364
365 /* Disable L2 bypass in the UCHE */
366 gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_LO, 0xFFFF0000);
367 gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_HI, 0x0001FFFF);
368 gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_LO, 0xFFFF0000);
369 gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_HI, 0x0001FFFF);
370
371 /* Set the GMEM VA range (0 to gpu->gmem) */
372 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_LO, 0x00100000);
373 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_HI, 0x00000000);
374 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_LO,
375 0x00100000 + adreno_gpu->gmem - 1);
376 gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
377
378 gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
379 gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
380 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
381 gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
382
383 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, (0x400 << 11 | 0x300 << 22));
384
4e09b95d 385 if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
b5f103ab
JC
386 gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
387
388 gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100);
389
390 /* Enable USE_RETENTION_FLOPS */
391 gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000);
392
393 /* Enable ME/PFP split notification */
394 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
395
396 /* Enable HWCG */
397 a5xx_enable_hwcg(gpu);
398
399 gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
400
401 /* Set the highest bank bit */
402 gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, 2 << 7);
403 gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, 2 << 1);
404
405 /* Protect registers from the CP */
406 gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x00000007);
407
408 /* RBBM */
409 gpu_write(gpu, REG_A5XX_CP_PROTECT(0), ADRENO_PROTECT_RW(0x04, 4));
410 gpu_write(gpu, REG_A5XX_CP_PROTECT(1), ADRENO_PROTECT_RW(0x08, 8));
411 gpu_write(gpu, REG_A5XX_CP_PROTECT(2), ADRENO_PROTECT_RW(0x10, 16));
412 gpu_write(gpu, REG_A5XX_CP_PROTECT(3), ADRENO_PROTECT_RW(0x20, 32));
413 gpu_write(gpu, REG_A5XX_CP_PROTECT(4), ADRENO_PROTECT_RW(0x40, 64));
414 gpu_write(gpu, REG_A5XX_CP_PROTECT(5), ADRENO_PROTECT_RW(0x80, 64));
415
416 /* Content protect */
417 gpu_write(gpu, REG_A5XX_CP_PROTECT(6),
418 ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
419 16));
420 gpu_write(gpu, REG_A5XX_CP_PROTECT(7),
421 ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TRUST_CNTL, 2));
422
423 /* CP */
424 gpu_write(gpu, REG_A5XX_CP_PROTECT(8), ADRENO_PROTECT_RW(0x800, 64));
425 gpu_write(gpu, REG_A5XX_CP_PROTECT(9), ADRENO_PROTECT_RW(0x840, 8));
426 gpu_write(gpu, REG_A5XX_CP_PROTECT(10), ADRENO_PROTECT_RW(0x880, 32));
427 gpu_write(gpu, REG_A5XX_CP_PROTECT(11), ADRENO_PROTECT_RW(0xAA0, 1));
428
429 /* RB */
430 gpu_write(gpu, REG_A5XX_CP_PROTECT(12), ADRENO_PROTECT_RW(0xCC0, 1));
431 gpu_write(gpu, REG_A5XX_CP_PROTECT(13), ADRENO_PROTECT_RW(0xCF0, 2));
432
433 /* VPC */
434 gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8));
435 gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 4));
436
437 /* UCHE */
438 gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16));
439
440 if (adreno_is_a530(adreno_gpu))
441 gpu_write(gpu, REG_A5XX_CP_PROTECT(17),
442 ADRENO_PROTECT_RW(0x10000, 0x8000));
443
444 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0);
445 /*
446 * Disable the trusted memory range - we don't actually supported secure
447 * memory rendering at this point in time and we don't want to block off
448 * part of the virtual memory space.
449 */
450 gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
451 REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_HI, 0x00000000);
452 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
453
2401a008
JC
454 /* Load the GPMU firmware before starting the HW init */
455 a5xx_gpmu_ucode_init(gpu);
456
b5f103ab
JC
457 ret = adreno_hw_init(gpu);
458 if (ret)
459 return ret;
460
461 ret = a5xx_ucode_init(gpu);
462 if (ret)
463 return ret;
464
465 /* Disable the interrupts through the initial bringup stage */
466 gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK);
467
468 /* Clear ME_HALT to start the micro engine */
469 gpu_write(gpu, REG_A5XX_CP_PFP_ME_CNTL, 0);
470 ret = a5xx_me_init(gpu);
471 if (ret)
472 return ret;
473
2401a008
JC
474 ret = a5xx_power_init(gpu);
475 if (ret)
476 return ret;
b5f103ab
JC
477
478 /*
479 * Send a pipeline event stat to get misbehaving counters to start
480 * ticking correctly
481 */
482 if (adreno_is_a530(adreno_gpu)) {
483 OUT_PKT7(gpu->rb, CP_EVENT_WRITE, 1);
484 OUT_RING(gpu->rb, 0x0F);
485
486 gpu->funcs->flush(gpu);
487 if (!gpu->funcs->idle(gpu))
488 return -EINVAL;
489 }
490
2401a008
JC
491 /* Put the GPU into unsecure mode */
492 gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0);
493
b5f103ab
JC
494 return 0;
495}
496
497static void a5xx_recover(struct msm_gpu *gpu)
498{
499 int i;
500
501 adreno_dump_info(gpu);
502
503 for (i = 0; i < 8; i++) {
504 printk("CP_SCRATCH_REG%d: %u\n", i,
505 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(i)));
506 }
507
508 if (hang_debug)
509 a5xx_dump(gpu);
510
511 gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 1);
512 gpu_read(gpu, REG_A5XX_RBBM_SW_RESET_CMD);
513 gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 0);
514 adreno_recover(gpu);
515}
516
517static void a5xx_destroy(struct msm_gpu *gpu)
518{
519 struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
520 struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
521
522 DBG("%s", gpu->name);
523
524 if (a5xx_gpu->pm4_bo) {
525 if (a5xx_gpu->pm4_iova)
526 msm_gem_put_iova(a5xx_gpu->pm4_bo, gpu->id);
527 drm_gem_object_unreference_unlocked(a5xx_gpu->pm4_bo);
528 }
529
530 if (a5xx_gpu->pfp_bo) {
531 if (a5xx_gpu->pfp_iova)
532 msm_gem_put_iova(a5xx_gpu->pfp_bo, gpu->id);
533 drm_gem_object_unreference_unlocked(a5xx_gpu->pfp_bo);
534 }
535
2401a008 536 if (a5xx_gpu->gpmu_bo) {
2002c9c3 537 if (a5xx_gpu->gpmu_iova)
2401a008
JC
538 msm_gem_put_iova(a5xx_gpu->gpmu_bo, gpu->id);
539 drm_gem_object_unreference_unlocked(a5xx_gpu->gpmu_bo);
540 }
541
b5f103ab
JC
542 adreno_gpu_cleanup(adreno_gpu);
543 kfree(a5xx_gpu);
544}
545
546static inline bool _a5xx_check_idle(struct msm_gpu *gpu)
547{
548 if (gpu_read(gpu, REG_A5XX_RBBM_STATUS) & ~A5XX_RBBM_STATUS_HI_BUSY)
549 return false;
550
551 /*
552 * Nearly every abnormality ends up pausing the GPU and triggering a
553 * fault so we can safely just watch for this one interrupt to fire
554 */
555 return !(gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS) &
556 A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT);
557}
558
559static bool a5xx_idle(struct msm_gpu *gpu)
560{
561 /* wait for CP to drain ringbuffer: */
562 if (!adreno_idle(gpu))
563 return false;
564
565 if (spin_until(_a5xx_check_idle(gpu))) {
566 DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X\n",
567 gpu->name, __builtin_return_address(0),
568 gpu_read(gpu, REG_A5XX_RBBM_STATUS),
569 gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS));
570
571 return false;
572 }
573
574 return true;
575}
576
7f8036b7
RC
577static int a5xx_fault_handler(void *arg, unsigned long iova, int flags)
578{
579 struct msm_gpu *gpu = arg;
580 pr_warn_ratelimited("*** gpu fault: iova=%08lx, flags=%d (%u,%u,%u,%u)\n",
581 iova, flags,
582 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)),
583 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)),
584 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
585 gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)));
586
587 return -EFAULT;
588}
589
b5f103ab
JC
590static void a5xx_cp_err_irq(struct msm_gpu *gpu)
591{
592 u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
593
594 if (status & A5XX_CP_INT_CP_OPCODE_ERROR) {
595 u32 val;
596
597 gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, 0);
598
599 /*
600 * REG_A5XX_CP_PFP_STAT_DATA is indexed, and we want index 1 so
601 * read it twice
602 */
603
604 gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
605 val = gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
606
607 dev_err_ratelimited(gpu->dev->dev, "CP | opcode error | possible opcode=0x%8.8X\n",
608 val);
609 }
610
611 if (status & A5XX_CP_INT_CP_HW_FAULT_ERROR)
612 dev_err_ratelimited(gpu->dev->dev, "CP | HW fault | status=0x%8.8X\n",
613 gpu_read(gpu, REG_A5XX_CP_HW_FAULT));
614
615 if (status & A5XX_CP_INT_CP_DMA_ERROR)
616 dev_err_ratelimited(gpu->dev->dev, "CP | DMA error\n");
617
618 if (status & A5XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) {
619 u32 val = gpu_read(gpu, REG_A5XX_CP_PROTECT_STATUS);
620
621 dev_err_ratelimited(gpu->dev->dev,
622 "CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n",
623 val & (1 << 24) ? "WRITE" : "READ",
624 (val & 0xFFFFF) >> 2, val);
625 }
626
627 if (status & A5XX_CP_INT_CP_AHB_ERROR) {
628 u32 status = gpu_read(gpu, REG_A5XX_CP_AHB_FAULT);
629 const char *access[16] = { "reserved", "reserved",
630 "timestamp lo", "timestamp hi", "pfp read", "pfp write",
631 "", "", "me read", "me write", "", "", "crashdump read",
632 "crashdump write" };
633
634 dev_err_ratelimited(gpu->dev->dev,
635 "CP | AHB error | addr=%X access=%s error=%d | status=0x%8.8X\n",
636 status & 0xFFFFF, access[(status >> 24) & 0xF],
637 (status & (1 << 31)), status);
638 }
639}
640
7352fb5a 641static void a5xx_rbbm_err_irq(struct msm_gpu *gpu, u32 status)
b5f103ab 642{
b5f103ab
JC
643 if (status & A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR) {
644 u32 val = gpu_read(gpu, REG_A5XX_RBBM_AHB_ERROR_STATUS);
645
646 dev_err_ratelimited(gpu->dev->dev,
647 "RBBM | AHB bus error | %s | addr=0x%X | ports=0x%X:0x%X\n",
648 val & (1 << 28) ? "WRITE" : "READ",
649 (val & 0xFFFFF) >> 2, (val >> 20) & 0x3,
650 (val >> 24) & 0xF);
651
652 /* Clear the error */
653 gpu_write(gpu, REG_A5XX_RBBM_AHB_CMD, (1 << 4));
7352fb5a
JC
654
655 /* Clear the interrupt */
656 gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD,
657 A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
b5f103ab
JC
658 }
659
660 if (status & A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT)
661 dev_err_ratelimited(gpu->dev->dev, "RBBM | AHB transfer timeout\n");
662
663 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT)
664 dev_err_ratelimited(gpu->dev->dev, "RBBM | ME master split | status=0x%X\n",
665 gpu_read(gpu, REG_A5XX_RBBM_AHB_ME_SPLIT_STATUS));
666
667 if (status & A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT)
668 dev_err_ratelimited(gpu->dev->dev, "RBBM | PFP master split | status=0x%X\n",
669 gpu_read(gpu, REG_A5XX_RBBM_AHB_PFP_SPLIT_STATUS));
670
671 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT)
672 dev_err_ratelimited(gpu->dev->dev, "RBBM | ETS master split | status=0x%X\n",
673 gpu_read(gpu, REG_A5XX_RBBM_AHB_ETS_SPLIT_STATUS));
674
675 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
676 dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB ASYNC overflow\n");
677
678 if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW)
679 dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB bus overflow\n");
680}
681
682static void a5xx_uche_err_irq(struct msm_gpu *gpu)
683{
684 uint64_t addr = (uint64_t) gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_HI);
685
686 addr |= gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_LO);
687
688 dev_err_ratelimited(gpu->dev->dev, "UCHE | Out of bounds access | addr=0x%llX\n",
689 addr);
690}
691
692static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
693{
694 dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
695}
696
697#define RBBM_ERROR_MASK \
698 (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
699 A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
700 A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
701 A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
702 A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
703 A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
704
705static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
706{
707 u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS);
708
7352fb5a
JC
709 /*
710 * Clear all the interrupts except RBBM_AHB_ERROR - if we clear it
711 * before the source is cleared the interrupt will storm.
712 */
713 gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD,
714 status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
b5f103ab 715
7352fb5a 716 /* Pass status to a5xx_rbbm_err_irq because we've already cleared it */
b5f103ab 717 if (status & RBBM_ERROR_MASK)
7352fb5a 718 a5xx_rbbm_err_irq(gpu, status);
b5f103ab
JC
719
720 if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
721 a5xx_cp_err_irq(gpu);
722
723 if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
724 a5xx_uche_err_irq(gpu);
725
726 if (status & A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
727 a5xx_gpmu_err_irq(gpu);
728
729 if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
730 msm_gpu_retire(gpu);
731
732 return IRQ_HANDLED;
733}
734
735static const u32 a5xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
736 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A5XX_CP_RB_BASE),
737 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE_HI, REG_A5XX_CP_RB_BASE_HI),
738 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A5XX_CP_RB_RPTR_ADDR),
739 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR_HI,
740 REG_A5XX_CP_RB_RPTR_ADDR_HI),
741 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A5XX_CP_RB_RPTR),
742 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A5XX_CP_RB_WPTR),
743 REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A5XX_CP_RB_CNTL),
744};
745
746static const u32 a5xx_registers[] = {
747 0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
748 0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
749 0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
750 0x04E0, 0x0533, 0x0540, 0x0555, 0xF400, 0xF400, 0xF800, 0xF807,
751 0x0800, 0x081A, 0x081F, 0x0841, 0x0860, 0x0860, 0x0880, 0x08A0,
752 0x0B00, 0x0B12, 0x0B15, 0x0B28, 0x0B78, 0x0B7F, 0x0BB0, 0x0BBD,
753 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53, 0x0C60, 0x0C61, 0x0C80, 0x0C82,
754 0x0C84, 0x0C85, 0x0C90, 0x0C98, 0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2,
755 0x2180, 0x2185, 0x2580, 0x2585, 0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7,
756 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8, 0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8,
757 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E, 0x2100, 0x211E, 0x2140, 0x2145,
758 0x2500, 0x251E, 0x2540, 0x2545, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
759 0x0D30, 0x0D30, 0x20C0, 0x20C0, 0x24C0, 0x24C0, 0x0E40, 0x0E43,
760 0x0E4A, 0x0E4A, 0x0E50, 0x0E57, 0x0E60, 0x0E7C, 0x0E80, 0x0E8E,
761 0x0E90, 0x0E96, 0x0EA0, 0x0EA8, 0x0EB0, 0x0EB2, 0xE140, 0xE147,
762 0xE150, 0xE187, 0xE1A0, 0xE1A9, 0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7,
763 0xE1D0, 0xE1D1, 0xE200, 0xE201, 0xE210, 0xE21C, 0xE240, 0xE268,
764 0xE000, 0xE006, 0xE010, 0xE09A, 0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB,
765 0xE100, 0xE105, 0xE380, 0xE38F, 0xE3B0, 0xE3B0, 0xE400, 0xE405,
766 0xE408, 0xE4E9, 0xE4F0, 0xE4F0, 0xE280, 0xE280, 0xE282, 0xE2A3,
767 0xE2A5, 0xE2C2, 0xE940, 0xE947, 0xE950, 0xE987, 0xE9A0, 0xE9A9,
768 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7, 0xE9D0, 0xE9D1, 0xEA00, 0xEA01,
769 0xEA10, 0xEA1C, 0xEA40, 0xEA68, 0xE800, 0xE806, 0xE810, 0xE89A,
770 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB, 0xE900, 0xE905, 0xEB80, 0xEB8F,
771 0xEBB0, 0xEBB0, 0xEC00, 0xEC05, 0xEC08, 0xECE9, 0xECF0, 0xECF0,
772 0xEA80, 0xEA80, 0xEA82, 0xEAA3, 0xEAA5, 0xEAC2, 0xA800, 0xA8FF,
773 0xAC60, 0xAC60, 0xB000, 0xB97F, 0xB9A0, 0xB9BF,
774 ~0
775};
776
777static void a5xx_dump(struct msm_gpu *gpu)
778{
779 dev_info(gpu->dev->dev, "status: %08x\n",
780 gpu_read(gpu, REG_A5XX_RBBM_STATUS));
781 adreno_dump(gpu);
782}
783
784static int a5xx_pm_resume(struct msm_gpu *gpu)
785{
2401a008
JC
786 int ret;
787
788 /* Turn on the core power */
789 ret = msm_gpu_pm_resume(gpu);
790 if (ret)
791 return ret;
792
793 /* Turn the RBCCU domain first to limit the chances of voltage droop */
794 gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000);
795
796 /* Wait 3 usecs before polling */
797 udelay(3);
798
799 ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS,
800 (1 << 20), (1 << 20));
801 if (ret) {
802 DRM_ERROR("%s: timeout waiting for RBCCU GDSC enable: %X\n",
803 gpu->name,
804 gpu_read(gpu, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS));
805 return ret;
806 }
807
808 /* Turn on the SP domain */
809 gpu_write(gpu, REG_A5XX_GPMU_SP_POWER_CNTL, 0x778000);
810 ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_SP_PWR_CLK_STATUS,
811 (1 << 20), (1 << 20));
812 if (ret)
813 DRM_ERROR("%s: timeout waiting for SP GDSC enable\n",
814 gpu->name);
815
816 return ret;
b5f103ab
JC
817}
818
819static int a5xx_pm_suspend(struct msm_gpu *gpu)
820{
2401a008
JC
821 /* Clear the VBIF pipe before shutting down */
822 gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0xF);
823 spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) & 0xF) == 0xF);
824
825 gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0);
826
827 /*
828 * Reset the VBIF before power collapse to avoid issue with FIFO
829 * entries
830 */
831 gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000);
832 gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000);
833
b5f103ab
JC
834 return msm_gpu_pm_suspend(gpu);
835}
836
837static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
838{
839 *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO,
840 REG_A5XX_RBBM_PERFCTR_CP_0_HI);
841
842 return 0;
843}
844
845#ifdef CONFIG_DEBUG_FS
846static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
847{
b5f103ab
JC
848 seq_printf(m, "status: %08x\n",
849 gpu_read(gpu, REG_A5XX_RBBM_STATUS));
b5f103ab
JC
850 adreno_show(gpu, m);
851}
852#endif
853
854static const struct adreno_gpu_funcs funcs = {
855 .base = {
856 .get_param = adreno_get_param,
857 .hw_init = a5xx_hw_init,
858 .pm_suspend = a5xx_pm_suspend,
859 .pm_resume = a5xx_pm_resume,
860 .recover = a5xx_recover,
861 .last_fence = adreno_last_fence,
862 .submit = a5xx_submit,
863 .flush = adreno_flush,
864 .idle = a5xx_idle,
865 .irq = a5xx_irq,
866 .destroy = a5xx_destroy,
0c3eaf1f 867#ifdef CONFIG_DEBUG_FS
b5f103ab 868 .show = a5xx_show,
0c3eaf1f 869#endif
b5f103ab
JC
870 },
871 .get_timestamp = a5xx_get_timestamp,
872};
873
874struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
875{
876 struct msm_drm_private *priv = dev->dev_private;
877 struct platform_device *pdev = priv->gpu_pdev;
878 struct a5xx_gpu *a5xx_gpu = NULL;
879 struct adreno_gpu *adreno_gpu;
880 struct msm_gpu *gpu;
881 int ret;
882
883 if (!pdev) {
884 dev_err(dev->dev, "No A5XX device is defined\n");
885 return ERR_PTR(-ENXIO);
886 }
887
888 a5xx_gpu = kzalloc(sizeof(*a5xx_gpu), GFP_KERNEL);
889 if (!a5xx_gpu)
890 return ERR_PTR(-ENOMEM);
891
892 adreno_gpu = &a5xx_gpu->base;
893 gpu = &adreno_gpu->base;
894
895 a5xx_gpu->pdev = pdev;
896 adreno_gpu->registers = a5xx_registers;
897 adreno_gpu->reg_offsets = a5xx_register_offsets;
898
2401a008
JC
899 a5xx_gpu->lm_leakage = 0x4E001A;
900
b5f103ab
JC
901 ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs);
902 if (ret) {
903 a5xx_destroy(&(a5xx_gpu->base.base));
904 return ERR_PTR(ret);
905 }
906
7f8036b7
RC
907 if (gpu->aspace)
908 msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler);
909
b5f103ab
JC
910 return gpu;
911}