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