b9b26b2bf9c548d38b81347fb745d811ccf20db4
[linux-2.6-microblaze.git] / drivers / gpu / drm / msm / adreno / a4xx_gpu.c
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 }