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