xref: /openbmc/linux/drivers/gpu/drm/msm/adreno/a4xx_gpu.c (revision e3d786a3)
1 /* Copyright (c) 2014 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 #include "a4xx_gpu.h"
14 #ifdef CONFIG_MSM_OCMEM
15 #  include <soc/qcom/ocmem.h>
16 #endif
17 
18 #define A4XX_INT0_MASK \
19 	(A4XX_INT0_RBBM_AHB_ERROR |        \
20 	 A4XX_INT0_RBBM_ATB_BUS_OVERFLOW | \
21 	 A4XX_INT0_CP_T0_PACKET_IN_IB |    \
22 	 A4XX_INT0_CP_OPCODE_ERROR |       \
23 	 A4XX_INT0_CP_RESERVED_BIT_ERROR | \
24 	 A4XX_INT0_CP_HW_FAULT |           \
25 	 A4XX_INT0_CP_IB1_INT |            \
26 	 A4XX_INT0_CP_IB2_INT |            \
27 	 A4XX_INT0_CP_RB_INT |             \
28 	 A4XX_INT0_CP_REG_PROTECT_FAULT |  \
29 	 A4XX_INT0_CP_AHB_ERROR_HALT |     \
30 	 A4XX_INT0_CACHE_FLUSH_TS |        \
31 	 A4XX_INT0_UCHE_OOB_ACCESS)
32 
33 extern bool hang_debug;
34 static void a4xx_dump(struct msm_gpu *gpu);
35 static bool a4xx_idle(struct msm_gpu *gpu);
36 
37 /*
38  * a4xx_enable_hwcg() - Program the clock control registers
39  * @device: The adreno device pointer
40  */
41 static void a4xx_enable_hwcg(struct msm_gpu *gpu)
42 {
43 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
44 	unsigned int i;
45 	for (i = 0; i < 4; i++)
46 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TP(i), 0x02222202);
47 	for (i = 0; i < 4; i++)
48 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_TP(i), 0x00002222);
49 	for (i = 0; i < 4; i++)
50 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TP(i), 0x0E739CE7);
51 	for (i = 0; i < 4; i++)
52 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TP(i), 0x00111111);
53 	for (i = 0; i < 4; i++)
54 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_SP(i), 0x22222222);
55 	for (i = 0; i < 4; i++)
56 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_SP(i), 0x00222222);
57 	for (i = 0; i < 4; i++)
58 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_SP(i), 0x00000104);
59 	for (i = 0; i < 4; i++)
60 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_SP(i), 0x00000081);
61 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_UCHE, 0x22222222);
62 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_UCHE, 0x02222222);
63 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL3_UCHE, 0x00000000);
64 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL4_UCHE, 0x00000000);
65 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_UCHE, 0x00004444);
66 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_UCHE, 0x00001112);
67 	for (i = 0; i < 4; i++)
68 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_RB(i), 0x22222222);
69 
70 	/* Disable L1 clocking in A420 due to CCU issues with it */
71 	for (i = 0; i < 4; i++) {
72 		if (adreno_is_a420(adreno_gpu)) {
73 			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i),
74 					0x00002020);
75 		} else {
76 			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i),
77 					0x00022020);
78 		}
79 	}
80 
81 	for (i = 0; i < 4; i++) {
82 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
83 				0x00000922);
84 	}
85 
86 	for (i = 0; i < 4; i++) {
87 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
88 				0x00000000);
89 	}
90 
91 	for (i = 0; i < 4; i++) {
92 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
93 				0x00000001);
94 	}
95 
96 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_MODE_GPC, 0x02222222);
97 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_GPC, 0x04100104);
98 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_GPC, 0x00022222);
99 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_COM_DCOM, 0x00000022);
100 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_COM_DCOM, 0x0000010F);
101 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_COM_DCOM, 0x00000022);
102 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TSE_RAS_RBBM, 0x00222222);
103 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00004104);
104 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000222);
105 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_HLSQ , 0x00000000);
106 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000);
107 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, 0x00220000);
108 	/* Early A430's have a timing issue with SP/TP power collapse;
109 	   disabling HW clock gating prevents it. */
110 	if (adreno_is_a430(adreno_gpu) && adreno_gpu->rev.patchid < 2)
111 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0);
112 	else
113 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA);
114 	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2, 0);
115 }
116 
117 
118 static bool a4xx_me_init(struct msm_gpu *gpu)
119 {
120 	struct msm_ringbuffer *ring = gpu->rb[0];
121 
122 	OUT_PKT3(ring, CP_ME_INIT, 17);
123 	OUT_RING(ring, 0x000003f7);
124 	OUT_RING(ring, 0x00000000);
125 	OUT_RING(ring, 0x00000000);
126 	OUT_RING(ring, 0x00000000);
127 	OUT_RING(ring, 0x00000080);
128 	OUT_RING(ring, 0x00000100);
129 	OUT_RING(ring, 0x00000180);
130 	OUT_RING(ring, 0x00006600);
131 	OUT_RING(ring, 0x00000150);
132 	OUT_RING(ring, 0x0000014e);
133 	OUT_RING(ring, 0x00000154);
134 	OUT_RING(ring, 0x00000001);
135 	OUT_RING(ring, 0x00000000);
136 	OUT_RING(ring, 0x00000000);
137 	OUT_RING(ring, 0x00000000);
138 	OUT_RING(ring, 0x00000000);
139 	OUT_RING(ring, 0x00000000);
140 
141 	gpu->funcs->flush(gpu, ring);
142 	return a4xx_idle(gpu);
143 }
144 
145 static int a4xx_hw_init(struct msm_gpu *gpu)
146 {
147 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
148 	struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu);
149 	uint32_t *ptr, len;
150 	int i, ret;
151 
152 	if (adreno_is_a420(adreno_gpu)) {
153 		gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F);
154 		gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
155 		gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
156 		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
157 		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018);
158 		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
159 		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
160 		gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
161 	} else if (adreno_is_a430(adreno_gpu)) {
162 		gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
163 		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
164 		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018);
165 		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
166 		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
167 		gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
168 	} else {
169 		BUG();
170 	}
171 
172 	/* Make all blocks contribute to the GPU BUSY perf counter */
173 	gpu_write(gpu, REG_A4XX_RBBM_GPU_BUSY_MASKED, 0xffffffff);
174 
175 	/* Tune the hystersis counters for SP and CP idle detection */
176 	gpu_write(gpu, REG_A4XX_RBBM_SP_HYST_CNT, 0x10);
177 	gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
178 
179 	if (adreno_is_a430(adreno_gpu)) {
180 		gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL2, 0x30);
181 	}
182 
183 	 /* Enable the RBBM error reporting bits */
184 	gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL0, 0x00000001);
185 
186 	/* Enable AHB error reporting*/
187 	gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL1, 0xa6ffffff);
188 
189 	/* Enable power counters*/
190 	gpu_write(gpu, REG_A4XX_RBBM_RBBM_CTL, 0x00000030);
191 
192 	/*
193 	 * Turn on hang detection - this spews a lot of useful information
194 	 * into the RBBM registers on a hang:
195 	 */
196 	gpu_write(gpu, REG_A4XX_RBBM_INTERFACE_HANG_INT_CTL,
197 			(1 << 30) | 0xFFFF);
198 
199 	gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR,
200 			(unsigned int)(a4xx_gpu->ocmem_base >> 14));
201 
202 	/* Turn on performance counters: */
203 	gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01);
204 
205 	/* use the first CP counter for timestamp queries.. userspace may set
206 	 * this as well but it selects the same counter/countable:
207 	 */
208 	gpu_write(gpu, REG_A4XX_CP_PERFCTR_CP_SEL_0, CP_ALWAYS_COUNT);
209 
210 	if (adreno_is_a430(adreno_gpu))
211 		gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07);
212 
213 	/* Disable L2 bypass to avoid UCHE out of bounds errors */
214 	gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_LO, 0xffff0000);
215 	gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_HI, 0xffff0000);
216 
217 	gpu_write(gpu, REG_A4XX_CP_DEBUG, (1 << 25) |
218 			(adreno_is_a420(adreno_gpu) ? (1 << 29) : 0));
219 
220 	/* On A430 enable SP regfile sleep for power savings */
221 	/* TODO downstream does this for !420, so maybe applies for 405 too? */
222 	if (!adreno_is_a420(adreno_gpu)) {
223 		gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_0,
224 			0x00000441);
225 		gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_1,
226 			0x00000441);
227 	}
228 
229 	a4xx_enable_hwcg(gpu);
230 
231 	/*
232 	 * For A420 set RBBM_CLOCK_DELAY_HLSQ.CGC_HLSQ_TP_EARLY_CYC >= 2
233 	 * due to timing issue with HLSQ_TP_CLK_EN
234 	 */
235 	if (adreno_is_a420(adreno_gpu)) {
236 		unsigned int val;
237 		val = gpu_read(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ);
238 		val &= ~A4XX_CGC_HLSQ_EARLY_CYC__MASK;
239 		val |= 2 << A4XX_CGC_HLSQ_EARLY_CYC__SHIFT;
240 		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, val);
241 	}
242 
243 	/* setup access protection: */
244 	gpu_write(gpu, REG_A4XX_CP_PROTECT_CTRL, 0x00000007);
245 
246 	/* RBBM registers */
247 	gpu_write(gpu, REG_A4XX_CP_PROTECT(0), 0x62000010);
248 	gpu_write(gpu, REG_A4XX_CP_PROTECT(1), 0x63000020);
249 	gpu_write(gpu, REG_A4XX_CP_PROTECT(2), 0x64000040);
250 	gpu_write(gpu, REG_A4XX_CP_PROTECT(3), 0x65000080);
251 	gpu_write(gpu, REG_A4XX_CP_PROTECT(4), 0x66000100);
252 	gpu_write(gpu, REG_A4XX_CP_PROTECT(5), 0x64000200);
253 
254 	/* CP registers */
255 	gpu_write(gpu, REG_A4XX_CP_PROTECT(6), 0x67000800);
256 	gpu_write(gpu, REG_A4XX_CP_PROTECT(7), 0x64001600);
257 
258 
259 	/* RB registers */
260 	gpu_write(gpu, REG_A4XX_CP_PROTECT(8), 0x60003300);
261 
262 	/* HLSQ registers */
263 	gpu_write(gpu, REG_A4XX_CP_PROTECT(9), 0x60003800);
264 
265 	/* VPC registers */
266 	gpu_write(gpu, REG_A4XX_CP_PROTECT(10), 0x61003980);
267 
268 	/* SMMU registers */
269 	gpu_write(gpu, REG_A4XX_CP_PROTECT(11), 0x6e010000);
270 
271 	gpu_write(gpu, REG_A4XX_RBBM_INT_0_MASK, A4XX_INT0_MASK);
272 
273 	ret = adreno_hw_init(gpu);
274 	if (ret)
275 		return ret;
276 
277 	/* Load PM4: */
278 	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
279 	len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
280 	DBG("loading PM4 ucode version: %u", ptr[0]);
281 	gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0);
282 	for (i = 1; i < len; i++)
283 		gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]);
284 
285 	/* Load PFP: */
286 	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
287 	len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
288 	DBG("loading PFP ucode version: %u", ptr[0]);
289 
290 	gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0);
291 	for (i = 1; i < len; i++)
292 		gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_DATA, ptr[i]);
293 
294 	/* clear ME_HALT to start micro engine */
295 	gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0);
296 
297 	return a4xx_me_init(gpu) ? 0 : -EINVAL;
298 }
299 
300 static void a4xx_recover(struct msm_gpu *gpu)
301 {
302 	int i;
303 
304 	adreno_dump_info(gpu);
305 
306 	for (i = 0; i < 8; i++) {
307 		printk("CP_SCRATCH_REG%d: %u\n", i,
308 			gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i));
309 	}
310 
311 	/* dump registers before resetting gpu, if enabled: */
312 	if (hang_debug)
313 		a4xx_dump(gpu);
314 
315 	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 1);
316 	gpu_read(gpu, REG_A4XX_RBBM_SW_RESET_CMD);
317 	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 0);
318 	adreno_recover(gpu);
319 }
320 
321 static void a4xx_destroy(struct msm_gpu *gpu)
322 {
323 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
324 	struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu);
325 
326 	DBG("%s", gpu->name);
327 
328 	adreno_gpu_cleanup(adreno_gpu);
329 
330 #ifdef CONFIG_MSM_OCMEM
331 	if (a4xx_gpu->ocmem_base)
332 		ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl);
333 #endif
334 
335 	kfree(a4xx_gpu);
336 }
337 
338 static bool a4xx_idle(struct msm_gpu *gpu)
339 {
340 	/* wait for ringbuffer to drain: */
341 	if (!adreno_idle(gpu, gpu->rb[0]))
342 		return false;
343 
344 	/* then wait for GPU to finish: */
345 	if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) &
346 					A4XX_RBBM_STATUS_GPU_BUSY))) {
347 		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
348 		/* TODO maybe we need to reset GPU here to recover from hang? */
349 		return false;
350 	}
351 
352 	return true;
353 }
354 
355 static irqreturn_t a4xx_irq(struct msm_gpu *gpu)
356 {
357 	uint32_t status;
358 
359 	status = gpu_read(gpu, REG_A4XX_RBBM_INT_0_STATUS);
360 	DBG("%s: Int status %08x", gpu->name, status);
361 
362 	if (status & A4XX_INT0_CP_REG_PROTECT_FAULT) {
363 		uint32_t reg = gpu_read(gpu, REG_A4XX_CP_PROTECT_STATUS);
364 		printk("CP | Protected mode error| %s | addr=%x\n",
365 			reg & (1 << 24) ? "WRITE" : "READ",
366 			(reg & 0xFFFFF) >> 2);
367 	}
368 
369 	gpu_write(gpu, REG_A4XX_RBBM_INT_CLEAR_CMD, status);
370 
371 	msm_gpu_retire(gpu);
372 
373 	return IRQ_HANDLED;
374 }
375 
376 static const unsigned int a4xx_registers[] = {
377 	/* RBBM */
378 	0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026,
379 	0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066,
380 	0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF,
381 	/* CP */
382 	0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B,
383 	0x0578, 0x058F,
384 	/* VSC */
385 	0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51,
386 	/* GRAS */
387 	0x0C80, 0x0C81, 0x0C88, 0x0C8F,
388 	/* RB */
389 	0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2,
390 	/* PC */
391 	0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
392 	/* VFD */
393 	0x0E40, 0x0E4A,
394 	/* VPC */
395 	0x0E60, 0x0E61, 0x0E63, 0x0E68,
396 	/* UCHE */
397 	0x0E80, 0x0E84, 0x0E88, 0x0E95,
398 	/* VMIDMT */
399 	0x1000, 0x1000, 0x1002, 0x1002, 0x1004, 0x1004, 0x1008, 0x100A,
400 	0x100C, 0x100D, 0x100F, 0x1010, 0x1012, 0x1016, 0x1024, 0x1024,
401 	0x1027, 0x1027, 0x1100, 0x1100, 0x1102, 0x1102, 0x1104, 0x1104,
402 	0x1110, 0x1110, 0x1112, 0x1116, 0x1124, 0x1124, 0x1300, 0x1300,
403 	0x1380, 0x1380,
404 	/* GRAS CTX 0 */
405 	0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E,
406 	/* PC CTX 0 */
407 	0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7,
408 	/* VFD CTX 0 */
409 	0x2200, 0x2204, 0x2208, 0x22A9,
410 	/* GRAS CTX 1 */
411 	0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E,
412 	/* PC CTX 1 */
413 	0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7,
414 	/* VFD CTX 1 */
415 	0x2600, 0x2604, 0x2608, 0x26A9,
416 	/* XPU */
417 	0x2C00, 0x2C01, 0x2C10, 0x2C10, 0x2C12, 0x2C16, 0x2C1D, 0x2C20,
418 	0x2C28, 0x2C28, 0x2C30, 0x2C30, 0x2C32, 0x2C36, 0x2C40, 0x2C40,
419 	0x2C50, 0x2C50, 0x2C52, 0x2C56, 0x2C80, 0x2C80, 0x2C94, 0x2C95,
420 	/* VBIF */
421 	0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x301D, 0x3020, 0x3022,
422 	0x3024, 0x3026, 0x3028, 0x302A, 0x302C, 0x302D, 0x3030, 0x3031,
423 	0x3034, 0x3036, 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040,
424 	0x3049, 0x3049, 0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068,
425 	0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094,
426 	0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8,
427 	0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100,
428 	0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
429 	0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x330C, 0x330C,
430 	0x3310, 0x3310, 0x3400, 0x3401, 0x3410, 0x3410, 0x3412, 0x3416,
431 	0x341D, 0x3420, 0x3428, 0x3428, 0x3430, 0x3430, 0x3432, 0x3436,
432 	0x3440, 0x3440, 0x3450, 0x3450, 0x3452, 0x3456, 0x3480, 0x3480,
433 	0x3494, 0x3495, 0x4000, 0x4000, 0x4002, 0x4002, 0x4004, 0x4004,
434 	0x4008, 0x400A, 0x400C, 0x400D, 0x400F, 0x4012, 0x4014, 0x4016,
435 	0x401D, 0x401D, 0x4020, 0x4027, 0x4060, 0x4062, 0x4200, 0x4200,
436 	0x4300, 0x4300, 0x4400, 0x4400, 0x4500, 0x4500, 0x4800, 0x4802,
437 	0x480F, 0x480F, 0x4811, 0x4811, 0x4813, 0x4813, 0x4815, 0x4816,
438 	0x482B, 0x482B, 0x4857, 0x4857, 0x4883, 0x4883, 0x48AF, 0x48AF,
439 	0x48C5, 0x48C5, 0x48E5, 0x48E5, 0x4905, 0x4905, 0x4925, 0x4925,
440 	0x4945, 0x4945, 0x4950, 0x4950, 0x495B, 0x495B, 0x4980, 0x498E,
441 	0x4B00, 0x4B00, 0x4C00, 0x4C00, 0x4D00, 0x4D00, 0x4E00, 0x4E00,
442 	0x4E80, 0x4E80, 0x4F00, 0x4F00, 0x4F08, 0x4F08, 0x4F10, 0x4F10,
443 	0x4F18, 0x4F18, 0x4F20, 0x4F20, 0x4F30, 0x4F30, 0x4F60, 0x4F60,
444 	0x4F80, 0x4F81, 0x4F88, 0x4F89, 0x4FEE, 0x4FEE, 0x4FF3, 0x4FF3,
445 	0x6000, 0x6001, 0x6008, 0x600F, 0x6014, 0x6016, 0x6018, 0x601B,
446 	0x61FD, 0x61FD, 0x623C, 0x623C, 0x6380, 0x6380, 0x63A0, 0x63A0,
447 	0x63C0, 0x63C1, 0x63C8, 0x63C9, 0x63D0, 0x63D4, 0x63D6, 0x63D6,
448 	0x63EE, 0x63EE, 0x6400, 0x6401, 0x6408, 0x640F, 0x6414, 0x6416,
449 	0x6418, 0x641B, 0x65FD, 0x65FD, 0x663C, 0x663C, 0x6780, 0x6780,
450 	0x67A0, 0x67A0, 0x67C0, 0x67C1, 0x67C8, 0x67C9, 0x67D0, 0x67D4,
451 	0x67D6, 0x67D6, 0x67EE, 0x67EE, 0x6800, 0x6801, 0x6808, 0x680F,
452 	0x6814, 0x6816, 0x6818, 0x681B, 0x69FD, 0x69FD, 0x6A3C, 0x6A3C,
453 	0x6B80, 0x6B80, 0x6BA0, 0x6BA0, 0x6BC0, 0x6BC1, 0x6BC8, 0x6BC9,
454 	0x6BD0, 0x6BD4, 0x6BD6, 0x6BD6, 0x6BEE, 0x6BEE,
455 	~0 /* sentinel */
456 };
457 
458 static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
459 {
460 	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
461 
462 	if (!state)
463 		return ERR_PTR(-ENOMEM);
464 
465 	adreno_gpu_state_get(gpu, state);
466 
467 	state->rbbm_status = gpu_read(gpu, REG_A4XX_RBBM_STATUS);
468 
469 	return state;
470 }
471 
472 /* Register offset defines for A4XX, in order of enum adreno_regs */
473 static const unsigned int a4xx_register_offsets[REG_ADRENO_REGISTER_MAX] = {
474 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_BASE, REG_A4XX_CP_RB_BASE),
475 	REG_ADRENO_SKIP(REG_ADRENO_CP_RB_BASE_HI),
476 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR_ADDR, REG_A4XX_CP_RB_RPTR_ADDR),
477 	REG_ADRENO_SKIP(REG_ADRENO_CP_RB_RPTR_ADDR_HI),
478 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_RPTR, REG_A4XX_CP_RB_RPTR),
479 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_WPTR, REG_A4XX_CP_RB_WPTR),
480 	REG_ADRENO_DEFINE(REG_ADRENO_CP_RB_CNTL, REG_A4XX_CP_RB_CNTL),
481 };
482 
483 static void a4xx_dump(struct msm_gpu *gpu)
484 {
485 	printk("status:   %08x\n",
486 			gpu_read(gpu, REG_A4XX_RBBM_STATUS));
487 	adreno_dump(gpu);
488 }
489 
490 static int a4xx_pm_resume(struct msm_gpu *gpu) {
491 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
492 	int ret;
493 
494 	ret = msm_gpu_pm_resume(gpu);
495 	if (ret)
496 		return ret;
497 
498 	if (adreno_is_a430(adreno_gpu)) {
499 		unsigned int reg;
500 		/* Set the default register values; set SW_COLLAPSE to 0 */
501 		gpu_write(gpu, REG_A4XX_RBBM_POWER_CNTL_IP, 0x778000);
502 		do {
503 			udelay(5);
504 			reg = gpu_read(gpu, REG_A4XX_RBBM_POWER_STATUS);
505 		} while (!(reg & A4XX_RBBM_POWER_CNTL_IP_SP_TP_PWR_ON));
506 	}
507 	return 0;
508 }
509 
510 static int a4xx_pm_suspend(struct msm_gpu *gpu) {
511 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
512 	int ret;
513 
514 	ret = msm_gpu_pm_suspend(gpu);
515 	if (ret)
516 		return ret;
517 
518 	if (adreno_is_a430(adreno_gpu)) {
519 		/* Set the default register values; set SW_COLLAPSE to 1 */
520 		gpu_write(gpu, REG_A4XX_RBBM_POWER_CNTL_IP, 0x778001);
521 	}
522 	return 0;
523 }
524 
525 static int a4xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
526 {
527 	*value = gpu_read64(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_LO,
528 		REG_A4XX_RBBM_PERFCTR_CP_0_HI);
529 
530 	return 0;
531 }
532 
533 static const struct adreno_gpu_funcs funcs = {
534 	.base = {
535 		.get_param = adreno_get_param,
536 		.hw_init = a4xx_hw_init,
537 		.pm_suspend = a4xx_pm_suspend,
538 		.pm_resume = a4xx_pm_resume,
539 		.recover = a4xx_recover,
540 		.submit = adreno_submit,
541 		.flush = adreno_flush,
542 		.active_ring = adreno_active_ring,
543 		.irq = a4xx_irq,
544 		.destroy = a4xx_destroy,
545 #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
546 		.show = adreno_show,
547 #endif
548 		.gpu_state_get = a4xx_gpu_state_get,
549 		.gpu_state_put = adreno_gpu_state_put,
550 	},
551 	.get_timestamp = a4xx_get_timestamp,
552 };
553 
554 struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
555 {
556 	struct a4xx_gpu *a4xx_gpu = NULL;
557 	struct adreno_gpu *adreno_gpu;
558 	struct msm_gpu *gpu;
559 	struct msm_drm_private *priv = dev->dev_private;
560 	struct platform_device *pdev = priv->gpu_pdev;
561 	int ret;
562 
563 	if (!pdev) {
564 		dev_err(dev->dev, "no a4xx device\n");
565 		ret = -ENXIO;
566 		goto fail;
567 	}
568 
569 	a4xx_gpu = kzalloc(sizeof(*a4xx_gpu), GFP_KERNEL);
570 	if (!a4xx_gpu) {
571 		ret = -ENOMEM;
572 		goto fail;
573 	}
574 
575 	adreno_gpu = &a4xx_gpu->base;
576 	gpu = &adreno_gpu->base;
577 
578 	gpu->perfcntrs = NULL;
579 	gpu->num_perfcntrs = 0;
580 
581 	adreno_gpu->registers = a4xx_registers;
582 	adreno_gpu->reg_offsets = a4xx_register_offsets;
583 
584 	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
585 	if (ret)
586 		goto fail;
587 
588 	/* if needed, allocate gmem: */
589 	if (adreno_is_a4xx(adreno_gpu)) {
590 #ifdef CONFIG_MSM_OCMEM
591 		/* TODO this is different/missing upstream: */
592 		struct ocmem_buf *ocmem_hdl =
593 				ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem);
594 
595 		a4xx_gpu->ocmem_hdl = ocmem_hdl;
596 		a4xx_gpu->ocmem_base = ocmem_hdl->addr;
597 		adreno_gpu->gmem = ocmem_hdl->len;
598 		DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024,
599 				a4xx_gpu->ocmem_base);
600 #endif
601 	}
602 
603 	if (!gpu->aspace) {
604 		/* TODO we think it is possible to configure the GPU to
605 		 * restrict access to VRAM carveout.  But the required
606 		 * registers are unknown.  For now just bail out and
607 		 * limp along with just modesetting.  If it turns out
608 		 * to not be possible to restrict access, then we must
609 		 * implement a cmdstream validator.
610 		 */
611 		dev_err(dev->dev, "No memory protection without IOMMU\n");
612 		ret = -ENXIO;
613 		goto fail;
614 	}
615 
616 	return gpu;
617 
618 fail:
619 	if (a4xx_gpu)
620 		a4xx_destroy(&a4xx_gpu->base.base);
621 
622 	return ERR_PTR(ret);
623 }
624