blob: e10edeaec3b0402b3dc3d904f0b7486441fd1e0b [file] [log] [blame]
Jordan Crousef7597bf2012-01-03 08:43:34 -07001/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
Jordan Crousea78c9172011-07-11 13:14:09 -06002 *
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
Jordan Crouseb4d31bd2012-02-01 22:11:12 -070014#include <linux/delay.h>
15#include <mach/socinfo.h>
16
Jordan Crousea78c9172011-07-11 13:14:09 -060017#include "kgsl.h"
18#include "kgsl_sharedmem.h"
19#include "kgsl_cffdump.h"
20#include "adreno.h"
Norman Geed7402ff2011-10-28 08:51:11 -060021#include "adreno_a2xx_trace.h"
Jordan Crousea78c9172011-07-11 13:14:09 -060022
23/*
Jordan Crousef7597bf2012-01-03 08:43:34 -070024 * These are the registers that are dumped with GPU snapshot
25 * and postmortem. The lists are dword offset pairs in the
26 * form of {start offset, end offset} inclusive.
27 */
28
29/* A200, A205 */
30const unsigned int a200_registers[] = {
31 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
32 0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
33 0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
34 0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
35 0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
36 0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
37 0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
38 0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
39 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A43, 0x0A45, 0x0A45,
40 0x0A4E, 0x0A4F, 0x0C2C, 0x0C2C, 0x0C30, 0x0C30, 0x0C38, 0x0C3C,
41 0x0C40, 0x0C40, 0x0C44, 0x0C44, 0x0C80, 0x0C86, 0x0C88, 0x0C94,
42 0x0C99, 0x0C9A, 0x0CA4, 0x0CA5, 0x0D00, 0x0D03, 0x0D06, 0x0D06,
43 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
44 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
45 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
46 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x0F0C, 0x0F0C, 0x0F0E, 0x0F12,
47 0x0F26, 0x0F2A, 0x0F2C, 0x0F2C, 0x2000, 0x2002, 0x2006, 0x200F,
48 0x2080, 0x2082, 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184,
49 0x21F5, 0x21F7, 0x2200, 0x2208, 0x2280, 0x2283, 0x2293, 0x2294,
50 0x2300, 0x2308, 0x2312, 0x2312, 0x2316, 0x231D, 0x2324, 0x2326,
51 0x2380, 0x2383, 0x2400, 0x2402, 0x2406, 0x240F, 0x2480, 0x2482,
52 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7,
53 0x2600, 0x2608, 0x2680, 0x2683, 0x2693, 0x2694, 0x2700, 0x2708,
54 0x2712, 0x2712, 0x2716, 0x271D, 0x2724, 0x2726, 0x2780, 0x2783,
55 0x4000, 0x4003, 0x4800, 0x4805, 0x4900, 0x4900, 0x4908, 0x4908,
56};
57
58/* A220, A225 */
59const unsigned int a220_registers[] = {
60 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
61 0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
62 0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
63 0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
64 0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
65 0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
66 0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
67 0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
68 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A40, 0x0A42, 0x0A43,
69 0x0A45, 0x0A45, 0x0A4E, 0x0A4F, 0x0C30, 0x0C30, 0x0C38, 0x0C39,
70 0x0C3C, 0x0C3C, 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03,
71 0x0D05, 0x0D06, 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1,
72 0x0DC8, 0x0DD4, 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04,
73 0x0E17, 0x0E1E, 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0,
74 0x0ED4, 0x0ED7, 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x2002,
75 0x2006, 0x200F, 0x2080, 0x2082, 0x2100, 0x2102, 0x2104, 0x2109,
76 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7, 0x2200, 0x2202,
77 0x2204, 0x2204, 0x2208, 0x2208, 0x2280, 0x2282, 0x2294, 0x2294,
78 0x2300, 0x2308, 0x2309, 0x230A, 0x2312, 0x2312, 0x2316, 0x2316,
79 0x2318, 0x231D, 0x2324, 0x2326, 0x2380, 0x2383, 0x2400, 0x2402,
80 0x2406, 0x240F, 0x2480, 0x2482, 0x2500, 0x2502, 0x2504, 0x2509,
81 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7, 0x2600, 0x2602,
82 0x2604, 0x2606, 0x2608, 0x2608, 0x2680, 0x2682, 0x2694, 0x2694,
83 0x2700, 0x2708, 0x2712, 0x2712, 0x2716, 0x2716, 0x2718, 0x271D,
84 0x2724, 0x2726, 0x2780, 0x2783, 0x4000, 0x4003, 0x4800, 0x4805,
85 0x4900, 0x4900, 0x4908, 0x4908,
86};
87
88const unsigned int a200_registers_count = ARRAY_SIZE(a200_registers) / 2;
89const unsigned int a220_registers_count = ARRAY_SIZE(a220_registers) / 2;
90
91/*
Jordan Crousea78c9172011-07-11 13:14:09 -060092 *
93 * Memory Map for Register, Constant & Instruction Shadow, and Command Buffers
94 * (34.5KB)
95 *
96 * +---------------------+------------+-------------+---+---------------------+
97 * | ALU Constant Shadow | Reg Shadow | C&V Buffers |Tex| Shader Instr Shadow |
98 * +---------------------+------------+-------------+---+---------------------+
99 * ________________________________/ \____________________
100 * / |
101 * +--------------+-----------+------+-----------+------------------------+
102 * | Restore Regs | Save Regs | Quad | Gmem Save | Gmem Restore | unused |
103 * +--------------+-----------+------+-----------+------------------------+
104 *
105 * 8K - ALU Constant Shadow (8K aligned)
106 * 4K - H/W Register Shadow (8K aligned)
107 * 4K - Command and Vertex Buffers
108 * - Indirect command buffer : Const/Reg restore
109 * - includes Loop & Bool const shadows
110 * - Indirect command buffer : Const/Reg save
111 * - Quad vertices & texture coordinates
112 * - Indirect command buffer : Gmem save
113 * - Indirect command buffer : Gmem restore
114 * - Unused (padding to 8KB boundary)
115 * <1K - Texture Constant Shadow (768 bytes) (8K aligned)
116 * 18K - Shader Instruction Shadow
117 * - 6K vertex (32 byte aligned)
118 * - 6K pixel (32 byte aligned)
119 * - 6K shared (32 byte aligned)
120 *
121 * Note: Reading constants into a shadow, one at a time using REG_TO_MEM, takes
122 * 3 DWORDS per DWORD transfered, plus 1 DWORD for the shadow, for a total of
123 * 16 bytes per constant. If the texture constants were transfered this way,
124 * the Command & Vertex Buffers section would extend past the 16K boundary.
125 * By moving the texture constant shadow area to start at 16KB boundary, we
126 * only require approximately 40 bytes more memory, but are able to use the
127 * LOAD_CONSTANT_CONTEXT shadowing feature for the textures, speeding up
128 * context switching.
129 *
130 * [Using LOAD_CONSTANT_CONTEXT shadowing feature for the Loop and/or Bool
131 * constants would require an additional 8KB each, for alignment.]
132 *
133 */
134
135/* Constants */
136
137#define ALU_CONSTANTS 2048 /* DWORDS */
138#define NUM_REGISTERS 1024 /* DWORDS */
139#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
140#define CMD_BUFFER_LEN 9216 /* DWORDS */
141#else
142#define CMD_BUFFER_LEN 3072 /* DWORDS */
143#endif
144#define TEX_CONSTANTS (32*6) /* DWORDS */
145#define BOOL_CONSTANTS 8 /* DWORDS */
146#define LOOP_CONSTANTS 56 /* DWORDS */
Jordan Crousea78c9172011-07-11 13:14:09 -0600147
148/* LOAD_CONSTANT_CONTEXT shadow size */
149#define LCC_SHADOW_SIZE 0x2000 /* 8KB */
150
151#define ALU_SHADOW_SIZE LCC_SHADOW_SIZE /* 8KB */
152#define REG_SHADOW_SIZE 0x1000 /* 4KB */
153#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
154#define CMD_BUFFER_SIZE 0x9000 /* 36KB */
155#else
156#define CMD_BUFFER_SIZE 0x3000 /* 12KB */
157#endif
158#define TEX_SHADOW_SIZE (TEX_CONSTANTS*4) /* 768 bytes */
Jordan Crousea78c9172011-07-11 13:14:09 -0600159
160#define REG_OFFSET LCC_SHADOW_SIZE
161#define CMD_OFFSET (REG_OFFSET + REG_SHADOW_SIZE)
162#define TEX_OFFSET (CMD_OFFSET + CMD_BUFFER_SIZE)
163#define SHADER_OFFSET ((TEX_OFFSET + TEX_SHADOW_SIZE + 32) & ~31)
164
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700165static inline int _shader_shadow_size(struct adreno_device *adreno_dev)
166{
Jordan Crousec6b3a992012-02-04 10:23:51 -0700167 return adreno_dev->istore_size *
168 (adreno_dev->instruction_size * sizeof(unsigned int));
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700169}
170
171static inline int _context_size(struct adreno_device *adreno_dev)
172{
173 return SHADER_OFFSET + 3*_shader_shadow_size(adreno_dev);
174}
Jordan Crousea78c9172011-07-11 13:14:09 -0600175
176/* A scratchpad used to build commands during context create */
177
178static struct tmp_ctx {
179 unsigned int *start; /* Command & Vertex buffer start */
180 unsigned int *cmd; /* Next available dword in C&V buffer */
181
182 /* address of buffers, needed when creating IB1 command buffers. */
183 uint32_t bool_shadow; /* bool constants */
184 uint32_t loop_shadow; /* loop constants */
185
Jordan Crousea78c9172011-07-11 13:14:09 -0600186 uint32_t shader_shared; /* shared shader instruction shadow */
187 uint32_t shader_vertex; /* vertex shader instruction shadow */
188 uint32_t shader_pixel; /* pixel shader instruction shadow */
Jordan Crousea78c9172011-07-11 13:14:09 -0600189
190 /* Addresses in command buffer where separately handled registers
191 * are saved
192 */
193 uint32_t reg_values[33];
194 uint32_t chicken_restore;
195
196 uint32_t gmem_base; /* Base gpu address of GMEM */
197
198} tmp_ctx;
199
200/* context save (gmem -> sys) */
201
202/* pre-compiled vertex shader program
203*
204* attribute vec4 P;
205* void main(void)
206* {
207* gl_Position = P;
208* }
209*/
210#define GMEM2SYS_VTX_PGM_LEN 0x12
211
212static unsigned int gmem2sys_vtx_pgm[GMEM2SYS_VTX_PGM_LEN] = {
213 0x00011003, 0x00001000, 0xc2000000,
214 0x00001004, 0x00001000, 0xc4000000,
215 0x00001005, 0x00002000, 0x00000000,
216 0x1cb81000, 0x00398a88, 0x00000003,
217 0x140f803e, 0x00000000, 0xe2010100,
218 0x14000000, 0x00000000, 0xe2000000
219};
220
221/* pre-compiled fragment shader program
222*
223* precision highp float;
224* uniform vec4 clear_color;
225* void main(void)
226* {
227* gl_FragColor = clear_color;
228* }
229*/
230
231#define GMEM2SYS_FRAG_PGM_LEN 0x0c
232
233static unsigned int gmem2sys_frag_pgm[GMEM2SYS_FRAG_PGM_LEN] = {
234 0x00000000, 0x1002c400, 0x10000000,
235 0x00001003, 0x00002000, 0x00000000,
236 0x140f8000, 0x00000000, 0x22000000,
237 0x14000000, 0x00000000, 0xe2000000
238};
239
240/* context restore (sys -> gmem) */
241/* pre-compiled vertex shader program
242*
243* attribute vec4 position;
244* attribute vec4 texcoord;
245* varying vec4 texcoord0;
246* void main()
247* {
248* gl_Position = position;
249* texcoord0 = texcoord;
250* }
251*/
252
253#define SYS2GMEM_VTX_PGM_LEN 0x18
254
255static unsigned int sys2gmem_vtx_pgm[SYS2GMEM_VTX_PGM_LEN] = {
256 0x00052003, 0x00001000, 0xc2000000, 0x00001005,
257 0x00001000, 0xc4000000, 0x00001006, 0x10071000,
258 0x20000000, 0x18981000, 0x0039ba88, 0x00000003,
259 0x12982000, 0x40257b08, 0x00000002, 0x140f803e,
260 0x00000000, 0xe2010100, 0x140f8000, 0x00000000,
261 0xe2020200, 0x14000000, 0x00000000, 0xe2000000
262};
263
264/* pre-compiled fragment shader program
265*
266* precision mediump float;
267* uniform sampler2D tex0;
268* varying vec4 texcoord0;
269* void main()
270* {
271* gl_FragColor = texture2D(tex0, texcoord0.xy);
272* }
273*/
274
275#define SYS2GMEM_FRAG_PGM_LEN 0x0f
276
277static unsigned int sys2gmem_frag_pgm[SYS2GMEM_FRAG_PGM_LEN] = {
278 0x00011002, 0x00001000, 0xc4000000, 0x00001003,
279 0x10041000, 0x20000000, 0x10000001, 0x1ffff688,
280 0x00000002, 0x140f8000, 0x00000000, 0xe2000000,
281 0x14000000, 0x00000000, 0xe2000000
282};
283
284/* shader texture constants (sysmem -> gmem) */
285#define SYS2GMEM_TEX_CONST_LEN 6
286
287static unsigned int sys2gmem_tex_const[SYS2GMEM_TEX_CONST_LEN] = {
288 /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat,
289 * RFMode=ZeroClamp-1, Dim=1:2d
290 */
291 0x00000002, /* Pitch = TBD */
292
293 /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0,
294 * NearestClamp=1:OGL Mode
295 */
296 0x00000800, /* Address[31:12] = TBD */
297
298 /* Width, Height, EndianSwap=0:None */
299 0, /* Width & Height = TBD */
300
301 /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point,
302 * Mip=2:BaseMap
303 */
304 0 << 1 | 1 << 4 | 2 << 7 | 3 << 10 | 2 << 23,
305
306 /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0,
307 * Dim3d=0
308 */
309 0,
310
311 /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0,
312 * Dim=1:2d, MipPacking=0
313 */
314 1 << 9 /* Mip Address[31:12] = TBD */
315};
316
Jordan Crousea78c9172011-07-11 13:14:09 -0600317#define NUM_COLOR_FORMATS 13
318
319static enum SURFACEFORMAT surface_format_table[NUM_COLOR_FORMATS] = {
320 FMT_4_4_4_4, /* COLORX_4_4_4_4 */
321 FMT_1_5_5_5, /* COLORX_1_5_5_5 */
322 FMT_5_6_5, /* COLORX_5_6_5 */
323 FMT_8, /* COLORX_8 */
324 FMT_8_8, /* COLORX_8_8 */
325 FMT_8_8_8_8, /* COLORX_8_8_8_8 */
326 FMT_8_8_8_8, /* COLORX_S8_8_8_8 */
327 FMT_16_FLOAT, /* COLORX_16_FLOAT */
328 FMT_16_16_FLOAT, /* COLORX_16_16_FLOAT */
329 FMT_16_16_16_16_FLOAT, /* COLORX_16_16_16_16_FLOAT */
330 FMT_32_FLOAT, /* COLORX_32_FLOAT */
331 FMT_32_32_FLOAT, /* COLORX_32_32_FLOAT */
332 FMT_32_32_32_32_FLOAT, /* COLORX_32_32_32_32_FLOAT */
333};
334
335static unsigned int format2bytesperpixel[NUM_COLOR_FORMATS] = {
336 2, /* COLORX_4_4_4_4 */
337 2, /* COLORX_1_5_5_5 */
338 2, /* COLORX_5_6_5 */
339 1, /* COLORX_8 */
340 2, /* COLORX_8_8 8*/
341 4, /* COLORX_8_8_8_8 */
342 4, /* COLORX_S8_8_8_8 */
343 2, /* COLORX_16_FLOAT */
344 4, /* COLORX_16_16_FLOAT */
345 8, /* COLORX_16_16_16_16_FLOAT */
346 4, /* COLORX_32_FLOAT */
347 8, /* COLORX_32_32_FLOAT */
348 16, /* COLORX_32_32_32_32_FLOAT */
349};
350
351/* shader linkage info */
352#define SHADER_CONST_ADDR (11 * 6 + 3)
353
Jordan Crousea78c9172011-07-11 13:14:09 -0600354
355static unsigned int *program_shader(unsigned int *cmds, int vtxfrag,
356 unsigned int *shader_pgm, int dwords)
357{
358 /* load the patched vertex shader stream */
Jordan Crouse084427d2011-07-28 08:37:58 -0600359 *cmds++ = cp_type3_packet(CP_IM_LOAD_IMMEDIATE, 2 + dwords);
Jordan Crousea78c9172011-07-11 13:14:09 -0600360 /* 0=vertex shader, 1=fragment shader */
361 *cmds++ = vtxfrag;
362 /* instruction start & size (in 32-bit words) */
363 *cmds++ = ((0 << 16) | dwords);
364
365 memcpy(cmds, shader_pgm, dwords << 2);
366 cmds += dwords;
367
368 return cmds;
369}
370
371static unsigned int *reg_to_mem(unsigned int *cmds, uint32_t dst,
372 uint32_t src, int dwords)
373{
374 while (dwords-- > 0) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600375 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600376 *cmds++ = src++;
377 *cmds++ = dst;
378 dst += 4;
379 }
380
381 return cmds;
382}
383
384#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
385
386static void build_reg_to_mem_range(unsigned int start, unsigned int end,
387 unsigned int **cmd,
388 struct adreno_context *drawctxt)
389{
390 unsigned int i = start;
391
392 for (i = start; i <= end; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600393 *(*cmd)++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600394 *(*cmd)++ = i;
395 *(*cmd)++ =
396 ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) +
397 (i - 0x2000) * 4;
398 }
399}
400
401#endif
402
403/* chicken restore */
404static unsigned int *build_chicken_restore_cmds(
405 struct adreno_context *drawctxt)
406{
407 unsigned int *start = tmp_ctx.cmd;
408 unsigned int *cmds = start;
409
Jordan Crouse084427d2011-07-28 08:37:58 -0600410 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600411 *cmds++ = 0;
412
Jordan Crouse084427d2011-07-28 08:37:58 -0600413 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600414 tmp_ctx.chicken_restore = virt2gpu(cmds, &drawctxt->gpustate);
415 *cmds++ = 0x00000000;
416
417 /* create indirect buffer command for above command sequence */
418 create_ib1(drawctxt, drawctxt->chicken_restore, start, cmds);
419
420 return cmds;
421}
422
423/****************************************************************************/
424/* context save */
425/****************************************************************************/
426
427static const unsigned int register_ranges_a20x[] = {
428 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
429 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
430 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
431 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
432 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
433 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
434 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
435 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
436 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
437 REG_VGT_MAX_VTX_INDX, REG_RB_FOG_COLOR,
438 REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL,
439 REG_PA_SU_POINT_SIZE, REG_PA_SC_LINE_STIPPLE,
440 REG_PA_SC_VIZ_QUERY, REG_PA_SC_VIZ_QUERY,
441 REG_VGT_VERTEX_REUSE_BLOCK_CNTL, REG_RB_DEPTH_CLEAR
442};
443
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700444static const unsigned int register_ranges_a220[] = {
Jordan Crousea78c9172011-07-11 13:14:09 -0600445 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
446 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
447 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
448 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
449 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
450 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
451 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
452 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
453 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700454 REG_A220_PC_MAX_VTX_INDX, REG_A220_PC_INDX_OFFSET,
Jordan Crousea78c9172011-07-11 13:14:09 -0600455 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
456 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
457 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
458 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
459 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700460 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
461 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
Jordan Crousea78c9172011-07-11 13:14:09 -0600462 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR
463};
464
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700465static const unsigned int register_ranges_a225[] = {
466 REG_RB_SURFACE_INFO, REG_A225_RB_COLOR_INFO3,
467 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
468 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
469 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
470 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
471 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
472 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
473 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
474 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
475 REG_A220_PC_MAX_VTX_INDX, REG_A225_PC_MULTI_PRIM_IB_RESET_INDX,
476 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
477 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
478 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
479 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
480 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
481 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
482 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
483 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR,
Jeremy Gebbene139a042011-11-17 16:20:41 -0700484 REG_A225_GRAS_UCP0X, REG_A225_GRAS_UCP5W,
485 REG_A225_GRAS_UCP_ENABLED, REG_A225_GRAS_UCP_ENABLED
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700486};
487
Jordan Crousea78c9172011-07-11 13:14:09 -0600488
489/* save h/w regs, alu constants, texture contants, etc. ...
490* requires: bool_shadow_gpuaddr, loop_shadow_gpuaddr
491*/
492static void build_regsave_cmds(struct adreno_device *adreno_dev,
493 struct adreno_context *drawctxt)
494{
495 unsigned int *start = tmp_ctx.cmd;
496 unsigned int *cmd = start;
497
Jordan Crouse084427d2011-07-28 08:37:58 -0600498 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600499 *cmd++ = 0;
500
501#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
502 /* Make sure the HW context has the correct register values
503 * before reading them. */
Jordan Crouse084427d2011-07-28 08:37:58 -0600504 *cmd++ = cp_type3_packet(CP_CONTEXT_UPDATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600505 *cmd++ = 0;
506
507 {
508 unsigned int i = 0;
509 unsigned int reg_array_size = 0;
510 const unsigned int *ptr_register_ranges;
511
512 /* Based on chip id choose the register ranges */
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700513 if (adreno_is_a220(adreno_dev)) {
514 ptr_register_ranges = register_ranges_a220;
515 reg_array_size = ARRAY_SIZE(register_ranges_a220);
516 } else if (adreno_is_a225(adreno_dev)) {
517 ptr_register_ranges = register_ranges_a225;
518 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -0600519 } else {
520 ptr_register_ranges = register_ranges_a20x;
521 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
522 }
523
524
525 /* Write HW registers into shadow */
526 for (i = 0; i < (reg_array_size/2) ; i++) {
527 build_reg_to_mem_range(ptr_register_ranges[i*2],
528 ptr_register_ranges[i*2+1],
529 &cmd, drawctxt);
530 }
531 }
532
533 /* Copy ALU constants */
534 cmd =
535 reg_to_mem(cmd, (drawctxt->gpustate.gpuaddr) & 0xFFFFE000,
536 REG_SQ_CONSTANT_0, ALU_CONSTANTS);
537
538 /* Copy Tex constants */
539 cmd =
540 reg_to_mem(cmd,
541 (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000,
542 REG_SQ_FETCH_0, TEX_CONSTANTS);
543#else
544
545 /* Insert a wait for idle packet before reading the registers.
546 * This is to fix a hang/reset seen during stress testing. In this
547 * hang, CP encountered a timeout reading SQ's boolean constant
548 * register. There is logic in the HW that blocks reading of this
549 * register when the SQ block is not idle, which we believe is
550 * contributing to the hang.*/
Jordan Crouse084427d2011-07-28 08:37:58 -0600551 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600552 *cmd++ = 0;
553
554 /* H/w registers are already shadowed; just need to disable shadowing
555 * to prevent corruption.
556 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600557 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600558 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
559 *cmd++ = 4 << 16; /* regs, start=0 */
560 *cmd++ = 0x0; /* count = 0 */
561
562 /* ALU constants are already shadowed; just need to disable shadowing
563 * to prevent corruption.
564 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600565 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600566 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
567 *cmd++ = 0 << 16; /* ALU, start=0 */
568 *cmd++ = 0x0; /* count = 0 */
569
570 /* Tex constants are already shadowed; just need to disable shadowing
571 * to prevent corruption.
572 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600573 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600574 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
575 *cmd++ = 1 << 16; /* Tex, start=0 */
576 *cmd++ = 0x0; /* count = 0 */
577#endif
578
579 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -0600580 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600581 *cmd++ = REG_SQ_GPR_MANAGEMENT;
582 *cmd++ = tmp_ctx.reg_values[0];
583
Jordan Crouse084427d2011-07-28 08:37:58 -0600584 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600585 *cmd++ = REG_TP0_CHICKEN;
586 *cmd++ = tmp_ctx.reg_values[1];
587
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600588 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600589 unsigned int i;
590 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700591 for (i = REG_A220_VSC_BIN_SIZE; i <=
592 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600593 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600594 *cmd++ = i;
595 *cmd++ = tmp_ctx.reg_values[j];
596 j++;
597 }
598 }
599
600 /* Copy Boolean constants */
601 cmd = reg_to_mem(cmd, tmp_ctx.bool_shadow, REG_SQ_CF_BOOLEANS,
602 BOOL_CONSTANTS);
603
604 /* Copy Loop constants */
605 cmd = reg_to_mem(cmd, tmp_ctx.loop_shadow,
606 REG_SQ_CF_LOOP, LOOP_CONSTANTS);
607
608 /* create indirect buffer command for above command sequence */
609 create_ib1(drawctxt, drawctxt->reg_save, start, cmd);
610
611 tmp_ctx.cmd = cmd;
612}
613
614/*copy colour, depth, & stencil buffers from graphics memory to system memory*/
615static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
616 struct adreno_context *drawctxt,
617 struct gmem_shadow_t *shadow)
618{
619 unsigned int *cmds = shadow->gmem_save_commands;
620 unsigned int *start = cmds;
621 /* Calculate the new offset based on the adjusted base */
622 unsigned int bytesperpixel = format2bytesperpixel[shadow->format];
623 unsigned int addr = shadow->gmemshadow.gpuaddr;
624 unsigned int offset = (addr - (addr & 0xfffff000)) / bytesperpixel;
625
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700626 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
627 /* Store TP0_CHICKEN register */
628 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
629 *cmds++ = REG_TP0_CHICKEN;
Jordan Crousea78c9172011-07-11 13:14:09 -0600630
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700631 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600632
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700633 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
634 *cmds++ = 0;
635 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600636
637 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600638 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600639 *cmds++ = 0x00000000;
640
641 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600642 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600643 *cmds++ = 0x00000000;
644
645 /* program shader */
646
647 /* load shader vtx constants ... 5 dwords */
Jordan Crouse084427d2011-07-28 08:37:58 -0600648 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crousea78c9172011-07-11 13:14:09 -0600649 *cmds++ = (0x1 << 16) | SHADER_CONST_ADDR;
650 *cmds++ = 0;
651 /* valid(?) vtx constant flag & addr */
652 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
653 /* limit = 12 dwords */
654 *cmds++ = 0x00000030;
655
656 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600657 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600658 *cmds++ = 0x1;
659
Jordan Crouse084427d2011-07-28 08:37:58 -0600660 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600661 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600662 *cmds++ = 0x00ffffff; /* REG_VGT_MAX_VTX_INDX */
663 *cmds++ = 0x0; /* REG_VGT_MIN_VTX_INDX */
664 *cmds++ = 0x00000000; /* REG_VGT_INDX_OFFSET */
665
Jordan Crouse084427d2011-07-28 08:37:58 -0600666 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600667 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600668 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
669
Jordan Crouse084427d2011-07-28 08:37:58 -0600670 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600671 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600672 *cmds++ = 0x00000c20;
673
Tarun Karra16346b02011-07-24 15:04:26 -0700674 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600675 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700676 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700677
678 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600679 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700680 *cmds++ = 0x00003F00;
681
Jordan Crouse084427d2011-07-28 08:37:58 -0600682 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700683 *cmds++ = adreno_encode_istore_size(adreno_dev)
684 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700685
Jordan Crousea78c9172011-07-11 13:14:09 -0600686 /* load the patched vertex shader stream */
687 cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN);
688
689 /* Load the patched fragment shader stream */
690 cmds =
691 program_shader(cmds, 1, gmem2sys_frag_pgm, GMEM2SYS_FRAG_PGM_LEN);
692
693 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600694 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600695 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600696 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600697 *cmds++ = 0x10018001;
698 else
699 *cmds++ = 0x10010001;
700 *cmds++ = 0x00000008;
701
702 /* resolve */
703
704 /* PA_CL_VTE_CNTL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600705 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600706 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600707 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
708 *cmds++ = 0x00000b00;
709
710 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600711 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600712 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600713 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
714
715 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
716 * Base=gmem_base
717 */
718 /* gmem base assumed 4K aligned. */
719 BUG_ON(tmp_ctx.gmem_base & 0xFFF);
720 *cmds++ =
721 (shadow->
722 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
723
724 /* disable Z */
Jordan Crouse084427d2011-07-28 08:37:58 -0600725 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600726 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600727 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600728 *cmds++ = 0x08;
729 else
730 *cmds++ = 0;
731
732 /* set REG_PA_SU_SC_MODE_CNTL
733 * Front_ptype = draw triangles
734 * Back_ptype = draw triangles
735 * Provoking vertex = last
736 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600737 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600738 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600739 *cmds++ = 0x00080240;
740
741 /* Use maximum scissor values -- quad vertices already have the
742 * correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600743 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600744 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600745 *cmds++ = (0 << 16) | 0;
746 *cmds++ = (0x1fff << 16) | (0x1fff);
Jordan Crouse084427d2011-07-28 08:37:58 -0600747 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600748 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600749 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
750 *cmds++ = (0x1fff << 16) | (0x1fff);
751
752 /* load the viewport so that z scale = clear depth and
753 * z offset = 0.0f
754 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600755 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600756 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600757 *cmds++ = 0xbf800000; /* -1.0f */
758 *cmds++ = 0x0;
759
Jordan Crouse084427d2011-07-28 08:37:58 -0600760 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600761 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600762 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
763
Jordan Crouse084427d2011-07-28 08:37:58 -0600764 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600765 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600766 *cmds++ = 0xffffffff;
767
Jordan Crouse084427d2011-07-28 08:37:58 -0600768 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600769 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -0600770 *cmds++ = 0x00000000;
771 *cmds++ = 0x00000000;
772
773 /* load the stencil ref value
774 * $AAM - do this later
775 */
776
777 /* load the COPY state */
Jordan Crouse084427d2011-07-28 08:37:58 -0600778 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600779 *cmds++ = CP_REG(REG_RB_COPY_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600780 *cmds++ = 0; /* RB_COPY_CONTROL */
781 *cmds++ = addr & 0xfffff000; /* RB_COPY_DEST_BASE */
782 *cmds++ = shadow->pitch >> 5; /* RB_COPY_DEST_PITCH */
783
784 /* Endian=none, Linear, Format=RGBA8888,Swap=0,!Dither,
785 * MaskWrite:R=G=B=A=1
786 */
787 *cmds++ = 0x0003c008 |
788 (shadow->format << RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT);
789 /* Make sure we stay in offsetx field. */
790 BUG_ON(offset & 0xfffff000);
791 *cmds++ = offset;
792
Jordan Crouse084427d2011-07-28 08:37:58 -0600793 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600794 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600795 *cmds++ = 0x6; /* EDRAM copy */
796
Jordan Crouse084427d2011-07-28 08:37:58 -0600797 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600798 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600799 *cmds++ = 0x00010000;
800
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600801 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600802 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600803 *cmds++ = 0;
804
Jordan Crouse084427d2011-07-28 08:37:58 -0600805 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700806 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600807 *cmds++ = 0x0000000;
808
Jordan Crouse084427d2011-07-28 08:37:58 -0600809 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600810 *cmds++ = 0; /* viz query info. */
811 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
812 *cmds++ = 0x00004088;
813 *cmds++ = 3; /* NumIndices=3 */
814 } else {
815 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -0600816 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600817 *cmds++ = 0; /* viz query info. */
818 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
819 *cmds++ = 0x00030088;
820 }
821
822 /* create indirect buffer command for above command sequence */
823 create_ib1(drawctxt, shadow->gmem_save, start, cmds);
824
825 return cmds;
826}
827
828/* context restore */
829
830/*copy colour, depth, & stencil buffers from system memory to graphics memory*/
831static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
832 struct adreno_context *drawctxt,
833 struct gmem_shadow_t *shadow)
834{
835 unsigned int *cmds = shadow->gmem_restore_commands;
836 unsigned int *start = cmds;
837
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700838 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
839 /* Store TP0_CHICKEN register */
840 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
841 *cmds++ = REG_TP0_CHICKEN;
842 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600843
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700844 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
845 *cmds++ = 0;
846 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600847
848 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600849 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600850 *cmds++ = 0x00000000;
851
852 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600853 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600854 *cmds++ = 0x00000000;
855 /* shader constants */
856
857 /* vertex buffer constants */
Jordan Crouse084427d2011-07-28 08:37:58 -0600858 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
Jordan Crousea78c9172011-07-11 13:14:09 -0600859
860 *cmds++ = (0x1 << 16) | (9 * 6);
861 /* valid(?) vtx constant flag & addr */
862 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
863 /* limit = 12 dwords */
864 *cmds++ = 0x00000030;
865 /* valid(?) vtx constant flag & addr */
866 *cmds++ = shadow->quad_texcoords.gpuaddr | 0x3;
867 /* limit = 8 dwords */
868 *cmds++ = 0x00000020;
869 *cmds++ = 0;
870 *cmds++ = 0;
871
872 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600873 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600874 *cmds++ = 0x1;
875
876 cmds = program_shader(cmds, 0, sys2gmem_vtx_pgm, SYS2GMEM_VTX_PGM_LEN);
877
Tarun Karra16346b02011-07-24 15:04:26 -0700878 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600879 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700880 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700881
882 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600883 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700884 *cmds++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
885
Jordan Crouse084427d2011-07-28 08:37:58 -0600886 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700887 *cmds++ = adreno_encode_istore_size(adreno_dev)
888 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700889
Jordan Crousea78c9172011-07-11 13:14:09 -0600890 /* Load the patched fragment shader stream */
891 cmds =
892 program_shader(cmds, 1, sys2gmem_frag_pgm, SYS2GMEM_FRAG_PGM_LEN);
893
894 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600895 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600896 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600897 *cmds++ = 0x10030002;
898 *cmds++ = 0x00000008;
899
Jordan Crouse084427d2011-07-28 08:37:58 -0600900 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600901 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600902 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
903
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600904 if (!adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600905 /* PA_SC_VIZ_QUERY */
Jordan Crouse084427d2011-07-28 08:37:58 -0600906 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600907 *cmds++ = CP_REG(REG_PA_SC_VIZ_QUERY);
Jordan Crousea78c9172011-07-11 13:14:09 -0600908 *cmds++ = 0x0; /*REG_PA_SC_VIZ_QUERY */
909 }
910
911 /* RB_COLORCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600912 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600913 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600914 *cmds++ = 0x00000c20;
915
Jordan Crouse084427d2011-07-28 08:37:58 -0600916 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600917 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600918 *cmds++ = 0x00ffffff; /* mmVGT_MAX_VTX_INDX */
919 *cmds++ = 0x0; /* mmVGT_MIN_VTX_INDX */
920 *cmds++ = 0x00000000; /* mmVGT_INDX_OFFSET */
921
Jordan Crouse084427d2011-07-28 08:37:58 -0600922 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600923 *cmds++ = CP_REG(REG_VGT_VERTEX_REUSE_BLOCK_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600924 *cmds++ = 0x00000002; /* mmVGT_VERTEX_REUSE_BLOCK_CNTL */
925 *cmds++ = 0x00000002; /* mmVGT_OUT_DEALLOC_CNTL */
926
Jordan Crouse084427d2011-07-28 08:37:58 -0600927 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600928 *cmds++ = CP_REG(REG_SQ_INTERPOLATOR_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600929 *cmds++ = 0xffffffff; /* mmSQ_INTERPOLATOR_CNTL */
930
Jordan Crouse084427d2011-07-28 08:37:58 -0600931 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600932 *cmds++ = CP_REG(REG_PA_SC_AA_CONFIG);
Jordan Crousea78c9172011-07-11 13:14:09 -0600933 *cmds++ = 0x00000000; /* REG_PA_SC_AA_CONFIG */
934
935 /* set REG_PA_SU_SC_MODE_CNTL
936 * Front_ptype = draw triangles
937 * Back_ptype = draw triangles
938 * Provoking vertex = last
939 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600940 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600941 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600942 *cmds++ = 0x00080240;
943
944 /* texture constants */
945 *cmds++ =
Jordan Crouse084427d2011-07-28 08:37:58 -0600946 cp_type3_packet(CP_SET_CONSTANT, (SYS2GMEM_TEX_CONST_LEN + 1));
Jordan Crousea78c9172011-07-11 13:14:09 -0600947 *cmds++ = (0x1 << 16) | (0 * 6);
948 memcpy(cmds, sys2gmem_tex_const, SYS2GMEM_TEX_CONST_LEN << 2);
949 cmds[0] |= (shadow->pitch >> 5) << 22;
950 cmds[1] |=
951 shadow->gmemshadow.gpuaddr | surface_format_table[shadow->format];
952 cmds[2] |= (shadow->width - 1) | (shadow->height - 1) << 13;
953 cmds += SYS2GMEM_TEX_CONST_LEN;
954
955 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600956 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600957 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600958 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
959
960 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
961 * Base=gmem_base
962 */
963 *cmds++ =
964 (shadow->
965 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
966
967 /* RB_DEPTHCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600968 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600969 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600970
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600971 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600972 *cmds++ = 8; /* disable Z */
973 else
974 *cmds++ = 0; /* disable Z */
975
976 /* Use maximum scissor values -- quad vertices already
977 * have the correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600978 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600979 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600980 *cmds++ = (0 << 16) | 0;
981 *cmds++ = ((0x1fff) << 16) | 0x1fff;
Jordan Crouse084427d2011-07-28 08:37:58 -0600982 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600983 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600984 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
985 *cmds++ = ((0x1fff) << 16) | 0x1fff;
986
Jordan Crouse084427d2011-07-28 08:37:58 -0600987 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600988 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600989 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
990 *cmds++ = 0x00000b00;
991
992 /*load the viewport so that z scale = clear depth and z offset = 0.0f */
Jordan Crouse084427d2011-07-28 08:37:58 -0600993 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600994 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600995 *cmds++ = 0xbf800000;
996 *cmds++ = 0x0;
997
Jordan Crouse084427d2011-07-28 08:37:58 -0600998 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600999 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001000 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
1001
Jordan Crouse084427d2011-07-28 08:37:58 -06001002 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001003 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001004 *cmds++ = 0xffffffff;
1005
Jordan Crouse084427d2011-07-28 08:37:58 -06001006 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001007 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -06001008 *cmds++ = 0x00000000;
1009 *cmds++ = 0x00000000;
1010
1011 /* load the stencil ref value
1012 * $AAM - do this later
1013 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001014 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001015 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001016 /* draw pixels with color and depth/stencil component */
1017 *cmds++ = 0x4;
1018
Jordan Crouse084427d2011-07-28 08:37:58 -06001019 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001020 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001021 *cmds++ = 0x00010000;
1022
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001023 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001024 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001025 *cmds++ = 0;
1026
Jordan Crouse084427d2011-07-28 08:37:58 -06001027 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001028 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001029 *cmds++ = 0x0000000;
1030
Jordan Crouse084427d2011-07-28 08:37:58 -06001031 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001032 *cmds++ = 0; /* viz query info. */
1033 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
1034 *cmds++ = 0x00004088;
1035 *cmds++ = 3; /* NumIndices=3 */
1036 } else {
1037 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -06001038 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001039 *cmds++ = 0; /* viz query info. */
1040 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
1041 *cmds++ = 0x00030088;
1042 }
1043
1044 /* create indirect buffer command for above command sequence */
1045 create_ib1(drawctxt, shadow->gmem_restore, start, cmds);
1046
1047 return cmds;
1048}
1049
Jordan Crousea78c9172011-07-11 13:14:09 -06001050static void build_regrestore_cmds(struct adreno_device *adreno_dev,
1051 struct adreno_context *drawctxt)
1052{
1053 unsigned int *start = tmp_ctx.cmd;
1054 unsigned int *cmd = start;
1055
1056 unsigned int i = 0;
1057 unsigned int reg_array_size = 0;
1058 const unsigned int *ptr_register_ranges;
1059
Jordan Crouse084427d2011-07-28 08:37:58 -06001060 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001061 *cmd++ = 0;
1062
1063 /* H/W Registers */
Jordan Crouse084427d2011-07-28 08:37:58 -06001064 /* deferred cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, ???); */
Jordan Crousea78c9172011-07-11 13:14:09 -06001065 cmd++;
1066#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1067 /* Force mismatch */
1068 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1;
1069#else
1070 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1071#endif
1072
1073 /* Based on chip id choose the registers ranges*/
Jeremy Gebben99105cb2011-08-31 10:23:05 -07001074 if (adreno_is_a220(adreno_dev)) {
1075 ptr_register_ranges = register_ranges_a220;
1076 reg_array_size = ARRAY_SIZE(register_ranges_a220);
1077 } else if (adreno_is_a225(adreno_dev)) {
1078 ptr_register_ranges = register_ranges_a225;
1079 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -06001080 } else {
1081 ptr_register_ranges = register_ranges_a20x;
1082 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
1083 }
1084
1085
1086 for (i = 0; i < (reg_array_size/2); i++) {
1087 cmd = reg_range(cmd, ptr_register_ranges[i*2],
1088 ptr_register_ranges[i*2+1]);
1089 }
1090
1091 /* Now we know how many register blocks we have, we can compute command
1092 * length
1093 */
1094 start[2] =
Jordan Crouse084427d2011-07-28 08:37:58 -06001095 cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, (cmd - start) - 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001096 /* Enable shadowing for the entire register block. */
1097#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1098 start[4] |= (0 << 24) | (4 << 16); /* Disable shadowing. */
1099#else
1100 start[4] |= (1 << 24) | (4 << 16);
1101#endif
1102
1103 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -06001104 *cmd++ = cp_type0_packet(REG_SQ_GPR_MANAGEMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001105 tmp_ctx.reg_values[0] = virt2gpu(cmd, &drawctxt->gpustate);
1106 *cmd++ = 0x00040400;
1107
Jordan Crouse084427d2011-07-28 08:37:58 -06001108 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001109 *cmd++ = 0;
Jordan Crouse084427d2011-07-28 08:37:58 -06001110 *cmd++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001111 tmp_ctx.reg_values[1] = virt2gpu(cmd, &drawctxt->gpustate);
1112 *cmd++ = 0x00000000;
1113
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001114 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001115 unsigned int i;
1116 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001117 for (i = REG_A220_VSC_BIN_SIZE; i <=
1118 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001119 *cmd++ = cp_type0_packet(i, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001120 tmp_ctx.reg_values[j] = virt2gpu(cmd,
1121 &drawctxt->gpustate);
1122 *cmd++ = 0x00000000;
1123 j++;
1124 }
1125 }
1126
1127 /* ALU Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001128 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001129 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
1130#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1131 *cmd++ = (0 << 24) | (0 << 16) | 0; /* Disable shadowing */
1132#else
1133 *cmd++ = (1 << 24) | (0 << 16) | 0;
1134#endif
1135 *cmd++ = ALU_CONSTANTS;
1136
1137 /* Texture Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001138 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001139 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
1140#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1141 /* Disable shadowing */
1142 *cmd++ = (0 << 24) | (1 << 16) | 0;
1143#else
1144 *cmd++ = (1 << 24) | (1 << 16) | 0;
1145#endif
1146 *cmd++ = TEX_CONSTANTS;
1147
1148 /* Boolean Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001149 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + BOOL_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001150 *cmd++ = (2 << 16) | 0;
1151
1152 /* the next BOOL_CONSTANT dwords is the shadow area for
1153 * boolean constants.
1154 */
1155 tmp_ctx.bool_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1156 cmd += BOOL_CONSTANTS;
1157
1158 /* Loop Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001159 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + LOOP_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001160 *cmd++ = (3 << 16) | 0;
1161
1162 /* the next LOOP_CONSTANTS dwords is the shadow area for
1163 * loop constants.
1164 */
1165 tmp_ctx.loop_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1166 cmd += LOOP_CONSTANTS;
1167
1168 /* create indirect buffer command for above command sequence */
1169 create_ib1(drawctxt, drawctxt->reg_restore, start, cmd);
1170
1171 tmp_ctx.cmd = cmd;
1172}
1173
Jordan Crousea78c9172011-07-11 13:14:09 -06001174static void
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001175build_shader_save_restore_cmds(struct adreno_device *adreno_dev,
1176 struct adreno_context *drawctxt)
Jordan Crousea78c9172011-07-11 13:14:09 -06001177{
1178 unsigned int *cmd = tmp_ctx.cmd;
1179 unsigned int *save, *restore, *fixup;
Jordan Crousea78c9172011-07-11 13:14:09 -06001180 unsigned int *startSizeVtx, *startSizePix, *startSizeShared;
Jordan Crousea78c9172011-07-11 13:14:09 -06001181 unsigned int *partition1;
1182 unsigned int *shaderBases, *partition2;
1183
Jordan Crousea78c9172011-07-11 13:14:09 -06001184 /* compute vertex, pixel and shared instruction shadow GPU addresses */
1185 tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001186 tmp_ctx.shader_pixel = tmp_ctx.shader_vertex
1187 + _shader_shadow_size(adreno_dev);
1188 tmp_ctx.shader_shared = tmp_ctx.shader_pixel
1189 + _shader_shadow_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001190
1191 /* restore shader partitioning and instructions */
1192
1193 restore = cmd; /* start address */
1194
1195 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -06001196 *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001197 *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
1198
1199 /* Restore previous shader vertex & pixel instruction bases. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001200 *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001201 shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */
1202
1203 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001204 *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001205 partition1 = cmd++; /* TBD #4a: partition info (from save) */
1206
Jordan Crousea78c9172011-07-11 13:14:09 -06001207 /* load vertex shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001208 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001209 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1210 startSizeVtx = cmd++; /* TBD #1: start/size (from save) */
1211
1212 /* load pixel shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001213 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001214 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1215 startSizePix = cmd++; /* TBD #2: start/size (from save) */
1216
1217 /* load shared shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001218 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001219 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1220 startSizeShared = cmd++; /* TBD #3: start/size (from save) */
Jordan Crousea78c9172011-07-11 13:14:09 -06001221
1222 /* create indirect buffer command for above command sequence */
1223 create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd);
1224
1225 /*
1226 * fixup SET_SHADER_BASES data
1227 *
1228 * since self-modifying PM4 code is being used here, a seperate
1229 * command buffer is used for this fixup operation, to ensure the
1230 * commands are not read by the PM4 engine before the data fields
1231 * have been written.
1232 */
1233
1234 fixup = cmd; /* start address */
1235
1236 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001237 *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001238 partition2 = cmd++; /* TBD #4b: partition info (from save) */
1239
1240 /* mask off unused bits, then OR with shader instruction memory size */
Jordan Crouse084427d2011-07-28 08:37:58 -06001241 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001242 *cmd++ = REG_SCRATCH_REG2;
1243 /* AND off invalid bits. */
1244 *cmd++ = 0x0FFF0FFF;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001245 /* OR in instruction memory size. */
1246 *cmd++ = adreno_encode_istore_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001247
1248 /* write the computed value to the SET_SHADER_BASES data field */
Jordan Crouse084427d2011-07-28 08:37:58 -06001249 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001250 *cmd++ = REG_SCRATCH_REG2;
1251 /* TBD #5: shader bases (to restore) */
1252 *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate);
1253
1254 /* create indirect buffer command for above command sequence */
1255 create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd);
1256
1257 /* save shader partitioning and instructions */
1258
1259 save = cmd; /* start address */
1260
Jordan Crouse084427d2011-07-28 08:37:58 -06001261 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001262 *cmd++ = 0;
1263
1264 /* fetch the SQ_INST_STORE_MANAGMENT register value,
1265 * store the value in the data fields of the SET_CONSTANT commands
1266 * above.
1267 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001268 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001269 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1270 /* TBD #4a: partition info (to restore) */
1271 *cmd++ = virt2gpu(partition1, &drawctxt->gpustate);
Jordan Crouse084427d2011-07-28 08:37:58 -06001272 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001273 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1274 /* TBD #4b: partition info (to fixup) */
1275 *cmd++ = virt2gpu(partition2, &drawctxt->gpustate);
1276
Jordan Crousea78c9172011-07-11 13:14:09 -06001277
1278 /* store the vertex shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001279 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001280 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1281 /* TBD #1: start/size (to restore) */
1282 *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate);
1283
1284 /* store the pixel shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001285 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001286 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1287 /* TBD #2: start/size (to restore) */
1288 *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate);
1289
1290 /* store the shared shader instructions if vertex base is nonzero */
1291
Jordan Crouse084427d2011-07-28 08:37:58 -06001292 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001293 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1294 /* TBD #3: start/size (to restore) */
1295 *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate);
1296
Jordan Crousea78c9172011-07-11 13:14:09 -06001297
Jordan Crouse084427d2011-07-28 08:37:58 -06001298 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001299 *cmd++ = 0;
1300
1301 /* create indirect buffer command for above command sequence */
1302 create_ib1(drawctxt, drawctxt->shader_save, save, cmd);
1303
1304 tmp_ctx.cmd = cmd;
1305}
1306
1307/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001308static int a2xx_create_gpustate_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001309 struct adreno_context *drawctxt)
1310{
Jordan Crousea78c9172011-07-11 13:14:09 -06001311 drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW;
1312
Jordan Crousea78c9172011-07-11 13:14:09 -06001313 /* build indirect command buffers to save & restore regs/constants */
Jordan Crousea78c9172011-07-11 13:14:09 -06001314 build_regrestore_cmds(adreno_dev, drawctxt);
1315 build_regsave_cmds(adreno_dev, drawctxt);
1316
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001317 build_shader_save_restore_cmds(adreno_dev, drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001318
Jordan Crousea78c9172011-07-11 13:14:09 -06001319 return 0;
1320}
1321
1322/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001323static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001324 struct adreno_context *drawctxt)
1325{
1326 int result;
1327
Anoop Kumar Yerukalaa4e88c62012-05-01 14:43:06 +05301328 calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_size);
Jordan Crouse7501d452012-04-19 08:58:44 -06001329 tmp_ctx.gmem_base = adreno_dev->gmem_base;
Jordan Crousea78c9172011-07-11 13:14:09 -06001330
1331 result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
1332 drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
1333
1334 if (result)
1335 return result;
1336
Carter Cooperec549da2012-04-02 15:51:38 -06001337 /* set the gmem shadow flag for the context */
1338 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
Jordan Crousea78c9172011-07-11 13:14:09 -06001339
1340 /* blank out gmem shadow. */
1341 kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
1342 drawctxt->context_gmem_shadow.size);
1343
1344 /* build quad vertex buffer */
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001345 build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
1346 &tmp_ctx.cmd);
Jordan Crousea78c9172011-07-11 13:14:09 -06001347
1348 /* build TP0_CHICKEN register restore command buffer */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001349 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE))
1350 tmp_ctx.cmd = build_chicken_restore_cmds(drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001351
1352 /* build indirect command buffers to save & restore gmem */
Jordan Crousea78c9172011-07-11 13:14:09 -06001353 drawctxt->context_gmem_shadow.gmem_save_commands = tmp_ctx.cmd;
1354 tmp_ctx.cmd =
1355 build_gmem2sys_cmds(adreno_dev, drawctxt,
1356 &drawctxt->context_gmem_shadow);
1357 drawctxt->context_gmem_shadow.gmem_restore_commands = tmp_ctx.cmd;
1358 tmp_ctx.cmd =
1359 build_sys2gmem_cmds(adreno_dev, drawctxt,
1360 &drawctxt->context_gmem_shadow);
1361
1362 kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
1363 KGSL_CACHE_OP_FLUSH);
1364
Sushmita Susheelendraf3896062011-08-12 16:33:10 -06001365 kgsl_cffdump_syncmem(NULL,
1366 &drawctxt->context_gmem_shadow.gmemshadow,
1367 drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
1368 drawctxt->context_gmem_shadow.gmemshadow.size, false);
1369
Jordan Crousea78c9172011-07-11 13:14:09 -06001370 return 0;
1371}
1372
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001373static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
1374 struct adreno_context *drawctxt)
1375{
1376 int ret;
1377
1378 /*
1379 * Allocate memory for the GPU state and the context commands.
1380 * Despite the name, this is much more then just storage for
1381 * the gpustate. This contains command space for gmem save
1382 * and texture and vertex buffer storage too
1383 */
1384
1385 ret = kgsl_allocate(&drawctxt->gpustate,
1386 drawctxt->pagetable, _context_size(adreno_dev));
1387
1388 if (ret)
1389 return ret;
1390
1391 kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0,
1392 _context_size(adreno_dev));
1393
1394 tmp_ctx.cmd = tmp_ctx.start
1395 = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
1396
1397 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
1398 ret = a2xx_create_gpustate_shadow(adreno_dev, drawctxt);
1399 if (ret)
1400 goto done;
1401
1402 drawctxt->flags |= CTXT_FLAGS_SHADER_SAVE;
1403 }
1404
1405 if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) {
1406 ret = a2xx_create_gmem_shadow(adreno_dev, drawctxt);
1407 if (ret)
1408 goto done;
1409 }
1410
1411 /* Flush and sync the gpustate memory */
1412
1413 kgsl_cache_range_op(&drawctxt->gpustate,
1414 KGSL_CACHE_OP_FLUSH);
1415
1416 kgsl_cffdump_syncmem(NULL, &drawctxt->gpustate,
1417 drawctxt->gpustate.gpuaddr,
1418 drawctxt->gpustate.size, false);
1419
1420done:
1421 if (ret)
1422 kgsl_sharedmem_free(&drawctxt->gpustate);
1423
1424 return ret;
1425}
1426
1427static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001428 struct adreno_context *context)
1429{
1430 struct kgsl_device *device = &adreno_dev->dev;
Shubhraprakash Das3598b2e2011-11-22 15:07:16 -07001431 unsigned int cmd[22];
Jordan Crousea78c9172011-07-11 13:14:09 -06001432
1433 if (context == NULL)
1434 return;
1435
1436 if (context->flags & CTXT_FLAGS_GPU_HANG)
1437 KGSL_CTXT_WARN(device,
1438 "Current active context has caused gpu hang\n");
1439
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001440 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001441
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001442 /* save registers and constants. */
Jordan Crousee0ea7622012-01-24 09:32:04 -07001443 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001444 context->reg_save, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001445
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001446 if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
1447 /* save shader partitioning and instructions. */
1448 adreno_ringbuffer_issuecmds(device,
1449 KGSL_CMD_FLAGS_PMODE,
1450 context->shader_save, 3);
1451
1452 /*
1453 * fixup shader partitioning parameter for
1454 * SET_SHADER_BASES.
1455 */
1456 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1457 context->shader_fixup, 3);
1458
1459 context->flags |= CTXT_FLAGS_SHADER_RESTORE;
1460 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001461 }
1462
1463 if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
1464 (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
1465 /* save gmem.
1466 * (note: changes shader. shader must already be saved.)
1467 */
1468 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1469 context->context_gmem_shadow.gmem_save, 3);
1470
1471 /* Restore TP0_CHICKEN */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001472 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
1473 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1474 context->chicken_restore, 3);
1475 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001476
1477 context->flags |= CTXT_FLAGS_GMEM_RESTORE;
Shubhraprakash Das3598b2e2011-11-22 15:07:16 -07001478 } else if (adreno_is_a225(adreno_dev)) {
1479 unsigned int *cmds = &cmd[0];
1480 /*
1481 * Issue an empty draw call to avoid possible hangs due to
1482 * repeated idles without intervening draw calls.
1483 * On adreno 225 the PC block has a cache that is only
1484 * flushed on draw calls and repeated idles can make it
1485 * overflow. The gmem save path contains draw calls so
1486 * this workaround isn't needed there.
1487 */
1488 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1489 *cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
1490 *cmds++ = 0;
1491 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
1492 *cmds++ = 0;
1493 *cmds++ = 1<<14;
1494 *cmds++ = 0;
1495 *cmds++ = device->mmu.setstate_memory.gpuaddr;
1496 *cmds++ = 0;
1497 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
1498 *cmds++ = 0x00000000;
1499
1500 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1501 &cmd[0], 11);
Jordan Crousea78c9172011-07-11 13:14:09 -06001502 }
1503}
1504
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001505static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001506 struct adreno_context *context)
1507{
1508 struct kgsl_device *device = &adreno_dev->dev;
1509 unsigned int cmds[5];
1510
1511 if (context == NULL) {
1512 /* No context - set the default apgetable and thats it */
Shubhraprakash Das79447952012-04-26 18:12:23 -06001513 kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable);
Jordan Crousea78c9172011-07-11 13:14:09 -06001514 return;
1515 }
1516
1517 KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
1518
Jordan Crouse084427d2011-07-28 08:37:58 -06001519 cmds[0] = cp_nop_packet(1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001520 cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
Jordan Crouse084427d2011-07-28 08:37:58 -06001521 cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001522 cmds[3] = device->memstore.gpuaddr +
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001523 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
1524 cmds[4] = context->id;
Jordan Crousee0ea7622012-01-24 09:32:04 -07001525 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
Shubhraprakash Das79447952012-04-26 18:12:23 -06001526 kgsl_mmu_setstate(&device->mmu, context->pagetable);
Jordan Crousea78c9172011-07-11 13:14:09 -06001527
1528#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
1529 kgsl_cffdump_syncmem(NULL, &context->gpustate,
1530 context->gpustate.gpuaddr, LCC_SHADOW_SIZE +
1531 REG_SHADOW_SIZE + CMD_BUFFER_SIZE + TEX_SHADOW_SIZE, false);
1532#endif
1533
1534 /* restore gmem.
1535 * (note: changes shader. shader must not already be restored.)
1536 */
1537 if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
1538 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1539 context->context_gmem_shadow.gmem_restore, 3);
1540
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001541 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
1542 /* Restore TP0_CHICKEN */
1543 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1544 context->chicken_restore, 3);
1545 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001546
1547 context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
1548 }
1549
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001550 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001551
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001552 /* restore registers and constants. */
Jordan Crousee0ea7622012-01-24 09:32:04 -07001553 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001554 context->reg_restore, 3);
1555
1556 /* restore shader instructions & partitioning. */
1557 if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
1558 adreno_ringbuffer_issuecmds(device,
1559 KGSL_CMD_FLAGS_NONE,
1560 context->shader_restore, 3);
1561 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001562 }
1563
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001564 if (adreno_is_a20x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001565 cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001566 cmds[1] = context->bin_base_offset;
Jordan Crousee0ea7622012-01-24 09:32:04 -07001567 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1568 cmds, 2);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001569 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001570}
1571
1572/*
1573 * Interrupt management
1574 *
1575 * a2xx interrupt control is distributed among the various
1576 * hardware components (RB, CP, MMU). The main interrupt
1577 * tells us which component fired the interrupt, but one needs
1578 * to go to the individual component to find out why. The
1579 * following functions provide the broken out support for
1580 * managing the interrupts
1581 */
1582
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001583#define RBBM_INT_MASK RBBM_INT_CNTL__RDERR_INT_MASK
Jordan Crousea78c9172011-07-11 13:14:09 -06001584
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001585#define CP_INT_MASK \
1586 (CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001587 CP_INT_CNTL__OPCODE_ERROR_MASK | \
1588 CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \
1589 CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \
1590 CP_INT_CNTL__IB_ERROR_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001591 CP_INT_CNTL__IB1_INT_MASK | \
1592 CP_INT_CNTL__RB_INT_MASK)
1593
1594#define VALID_STATUS_COUNT_MAX 10
1595
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001596static struct {
1597 unsigned int mask;
1598 const char *message;
1599} kgsl_cp_error_irqs[] = {
1600 { CP_INT_CNTL__T0_PACKET_IN_IB_MASK,
1601 "ringbuffer TO packet in IB interrupt" },
1602 { CP_INT_CNTL__OPCODE_ERROR_MASK,
1603 "ringbuffer opcode error interrupt" },
1604 { CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK,
1605 "ringbuffer protected mode error interrupt" },
1606 { CP_INT_CNTL__RESERVED_BIT_ERROR_MASK,
1607 "ringbuffer reserved bit error interrupt" },
1608 { CP_INT_CNTL__IB_ERROR_MASK,
1609 "ringbuffer IB error interrupt" },
1610};
1611
Jordan Crousea78c9172011-07-11 13:14:09 -06001612static void a2xx_cp_intrcallback(struct kgsl_device *device)
1613{
1614 unsigned int status = 0, num_reads = 0, master_status = 0;
1615 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1616 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001617 int i;
Jordan Crousea78c9172011-07-11 13:14:09 -06001618
1619 adreno_regread(device, REG_MASTER_INT_SIGNAL, &master_status);
1620 while (!status && (num_reads < VALID_STATUS_COUNT_MAX) &&
1621 (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) {
1622 adreno_regread(device, REG_CP_INT_STATUS, &status);
1623 adreno_regread(device, REG_MASTER_INT_SIGNAL,
1624 &master_status);
1625 num_reads++;
1626 }
1627 if (num_reads > 1)
1628 KGSL_DRV_WARN(device,
1629 "Looped %d times to read REG_CP_INT_STATUS\n",
1630 num_reads);
Norman Geed7402ff2011-10-28 08:51:11 -06001631
1632 trace_kgsl_a2xx_irq_status(device, master_status, status);
1633
Jordan Crousea78c9172011-07-11 13:14:09 -06001634 if (!status) {
1635 if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1636 /* This indicates that we could not read CP_INT_STAT.
1637 * As a precaution just wake up processes so
1638 * they can check their timestamps. Since, we
1639 * did not ack any interrupts this interrupt will
1640 * be generated again */
1641 KGSL_DRV_WARN(device, "Unable to read CP_INT_STATUS\n");
1642 wake_up_interruptible_all(&device->wait_queue);
1643 } else
1644 KGSL_DRV_WARN(device, "Spurious interrput detected\n");
1645 return;
1646 }
1647
1648 if (status & CP_INT_CNTL__RB_INT_MASK) {
1649 /* signal intr completion event */
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001650 unsigned int context_id;
1651 kgsl_sharedmem_readl(&device->memstore,
1652 &context_id,
1653 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
1654 current_context));
1655 if (context_id < KGSL_MEMSTORE_MAX) {
1656 kgsl_sharedmem_writel(&rb->device->memstore,
1657 KGSL_MEMSTORE_OFFSET(context_id,
1658 ts_cmp_enable), 0);
1659 device->last_expired_ctxt_id = context_id;
1660 wmb();
1661 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001662 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
1663 }
1664
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001665 for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
1666 if (status & kgsl_cp_error_irqs[i].mask) {
1667 KGSL_CMD_CRIT(rb->device, "%s\n",
1668 kgsl_cp_error_irqs[i].message);
1669 /*
1670 * on fatal errors, turn off the interrupts to
1671 * avoid storming. This has the side effect of
1672 * forcing a PM dump when the timestamp times out
1673 */
Jordan Crousea78c9172011-07-11 13:14:09 -06001674
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001675 kgsl_pwrctrl_irq(rb->device, KGSL_PWRFLAGS_OFF);
1676 }
1677 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001678
1679 /* only ack bits we understand */
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001680 status &= CP_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001681 adreno_regwrite(device, REG_CP_INT_ACK, status);
1682
1683 if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
1684 KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
Jordan Crouse1bf80aa2011-10-12 16:57:47 -06001685 queue_work(device->work_queue, &device->ts_expired_ws);
Jordan Crousea78c9172011-07-11 13:14:09 -06001686 wake_up_interruptible_all(&device->wait_queue);
1687 atomic_notifier_call_chain(&(device->ts_notifier_list),
1688 device->id,
1689 NULL);
1690 }
1691}
1692
1693static void a2xx_rbbm_intrcallback(struct kgsl_device *device)
1694{
1695 unsigned int status = 0;
1696 unsigned int rderr = 0;
1697
1698 adreno_regread(device, REG_RBBM_INT_STATUS, &status);
1699
1700 if (status & RBBM_INT_CNTL__RDERR_INT_MASK) {
1701 union rbbm_read_error_u rerr;
1702 adreno_regread(device, REG_RBBM_READ_ERROR, &rderr);
1703 rerr.val = rderr;
1704 if (rerr.f.read_address == REG_CP_INT_STATUS &&
1705 rerr.f.read_error &&
1706 rerr.f.read_requester)
1707 KGSL_DRV_WARN(device,
1708 "rbbm read error interrupt: %08x\n", rderr);
1709 else
1710 KGSL_DRV_CRIT(device,
1711 "rbbm read error interrupt: %08x\n", rderr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001712 }
1713
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001714 status &= RBBM_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001715 adreno_regwrite(device, REG_RBBM_INT_ACK, status);
1716}
1717
1718irqreturn_t a2xx_irq_handler(struct adreno_device *adreno_dev)
1719{
1720 struct kgsl_device *device = &adreno_dev->dev;
1721 irqreturn_t result = IRQ_NONE;
1722 unsigned int status;
1723
1724 adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
1725
1726 if (status & MASTER_INT_SIGNAL__MH_INT_STAT) {
1727 kgsl_mh_intrcallback(device);
1728 result = IRQ_HANDLED;
1729 }
1730
1731 if (status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1732 a2xx_cp_intrcallback(device);
1733 result = IRQ_HANDLED;
1734 }
1735
1736 if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) {
1737 a2xx_rbbm_intrcallback(device);
1738 result = IRQ_HANDLED;
1739 }
1740
1741 return result;
1742}
1743
1744static void a2xx_irq_control(struct adreno_device *adreno_dev, int state)
1745{
1746 struct kgsl_device *device = &adreno_dev->dev;
1747
1748 if (state) {
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001749 adreno_regwrite(device, REG_RBBM_INT_CNTL, RBBM_INT_MASK);
1750 adreno_regwrite(device, REG_CP_INT_CNTL, CP_INT_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001751 adreno_regwrite(device, MH_INTERRUPT_MASK, KGSL_MMU_INT_MASK);
1752 } else {
1753 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1754 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1755 adreno_regwrite(device, MH_INTERRUPT_MASK, 0);
1756 }
Jordan Crouseb58e61b2011-08-08 13:25:36 -06001757
1758 /* Force the writes to post before touching the IRQ line */
1759 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001760}
1761
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001762static void a2xx_rb_init(struct adreno_device *adreno_dev,
1763 struct adreno_ringbuffer *rb)
1764{
1765 unsigned int *cmds, cmds_gpu;
1766
1767 /* ME_INIT */
1768 cmds = adreno_ringbuffer_allocspace(rb, 19);
1769 cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19);
1770
1771 GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 18));
1772 /* All fields present (bits 9:0) */
1773 GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff);
1774 /* Disable/Enable Real-Time Stream processing (present but ignored) */
1775 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1776 /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
1777 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1778
1779 GSL_RB_WRITE(cmds, cmds_gpu,
1780 SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
1781 GSL_RB_WRITE(cmds, cmds_gpu,
1782 SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
1783 GSL_RB_WRITE(cmds, cmds_gpu,
1784 SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
1785 GSL_RB_WRITE(cmds, cmds_gpu,
1786 SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
1787 GSL_RB_WRITE(cmds, cmds_gpu,
1788 SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
1789 GSL_RB_WRITE(cmds, cmds_gpu,
1790 SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
1791 GSL_RB_WRITE(cmds, cmds_gpu,
1792 SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
1793 GSL_RB_WRITE(cmds, cmds_gpu,
1794 SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
1795
1796 /* Instruction memory size: */
1797 GSL_RB_WRITE(cmds, cmds_gpu,
1798 (adreno_encode_istore_size(adreno_dev)
1799 | adreno_dev->pix_shader_start));
1800 /* Maximum Contexts */
1801 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
1802 /* Write Confirm Interval and The CP will wait the
1803 * wait_interval * 16 clocks between polling */
1804 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1805
1806 /* NQ and External Memory Swap */
1807 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1808 /* Protected mode error checking */
1809 GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL);
1810 /* Disable header dumping and Header dump address */
1811 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1812 /* Header dump size */
1813 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1814
1815 adreno_ringbuffer_submit(rb);
1816}
1817
1818static unsigned int a2xx_busy_cycles(struct adreno_device *adreno_dev)
1819{
1820 struct kgsl_device *device = &adreno_dev->dev;
1821 unsigned int reg, val;
1822
1823 /* Freeze the counter */
1824 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1825 REG_PERF_MODE_CNT | REG_PERF_STATE_FREEZE);
1826
1827 /* Get the value */
1828 adreno_regread(device, REG_RBBM_PERFCOUNTER1_LO, &val);
1829
1830 /* Reset the counter */
1831 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1832 REG_PERF_MODE_CNT | REG_PERF_STATE_RESET);
1833
1834 /* Re-Enable the performance monitors */
1835 adreno_regread(device, REG_RBBM_PM_OVERRIDE2, &reg);
1836 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, (reg | 0x40));
1837 adreno_regwrite(device, REG_RBBM_PERFCOUNTER1_SELECT, 0x1);
1838 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1839 REG_PERF_MODE_CNT | REG_PERF_STATE_ENABLE);
1840
1841 return val;
1842}
1843
1844static void a2xx_gmeminit(struct adreno_device *adreno_dev)
1845{
1846 struct kgsl_device *device = &adreno_dev->dev;
1847 union reg_rb_edram_info rb_edram_info;
1848 unsigned int gmem_size;
1849 unsigned int edram_value = 0;
1850
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001851 /* get edram_size value equivalent */
Jordan Crouse7501d452012-04-19 08:58:44 -06001852 gmem_size = (adreno_dev->gmem_size >> 14);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001853 while (gmem_size >>= 1)
1854 edram_value++;
1855
1856 rb_edram_info.val = 0;
1857
1858 rb_edram_info.f.edram_size = edram_value;
1859 rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */
1860
1861 /* must be aligned to size */
Jordan Crouse7501d452012-04-19 08:58:44 -06001862 rb_edram_info.f.edram_range = (adreno_dev->gmem_base >> 14);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001863
1864 adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
1865}
1866
1867static void a2xx_start(struct adreno_device *adreno_dev)
1868{
1869 struct kgsl_device *device = &adreno_dev->dev;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001870
1871 /*
1872 * We need to make sure all blocks are powered up and clocked
1873 * before issuing a soft reset. The overrides will then be
1874 * turned off (set to 0)
1875 */
1876 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe);
1877 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff);
1878
1879 /*
1880 * Only reset CP block if all blocks have previously been
1881 * reset
1882 */
1883 if (!(device->flags & KGSL_FLAGS_SOFT_RESET) ||
1884 !adreno_is_a22x(adreno_dev)) {
1885 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1886 0xFFFFFFFF);
1887 device->flags |= KGSL_FLAGS_SOFT_RESET;
1888 } else {
1889 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1890 0x00000001);
1891 }
1892 /*
1893 * The core is in an indeterminate state until the reset
1894 * completes after 30ms.
1895 */
1896 msleep(30);
1897
1898 adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000);
1899
1900 if (adreno_is_a225(adreno_dev)) {
1901 /* Enable large instruction store for A225 */
1902 adreno_regwrite(device, REG_SQ_FLOW_CONTROL,
1903 0x18000000);
1904 }
1905
1906 adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
1907
1908 adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
1909 adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
1910
Sudhakara Rao Tentudaebac22012-04-02 14:51:29 -07001911 if (cpu_is_msm8960())
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001912 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
1913 else
1914 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
1915
1916 if (!adreno_is_a22x(adreno_dev))
1917 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0);
1918 else
1919 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
1920
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001921 adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
1922
1923 /* Make sure interrupts are disabled */
1924 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1925 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1926 adreno_regwrite(device, REG_SQ_INT_CNTL, 0);
1927
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001928 a2xx_gmeminit(adreno_dev);
1929}
1930
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001931/* Defined in adreno_a2xx_snapshot.c */
1932void *a2xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
1933 int *remain, int hang);
1934
Jordan Crousea78c9172011-07-11 13:14:09 -06001935struct adreno_gpudev adreno_a2xx_gpudev = {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001936 .reg_rbbm_status = REG_RBBM_STATUS,
1937 .reg_cp_pfp_ucode_addr = REG_CP_PFP_UCODE_ADDR,
1938 .reg_cp_pfp_ucode_data = REG_CP_PFP_UCODE_DATA,
1939
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001940 .ctxt_create = a2xx_drawctxt_create,
1941 .ctxt_save = a2xx_drawctxt_save,
1942 .ctxt_restore = a2xx_drawctxt_restore,
Jordan Crousea78c9172011-07-11 13:14:09 -06001943 .irq_handler = a2xx_irq_handler,
1944 .irq_control = a2xx_irq_control,
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001945 .snapshot = a2xx_snapshot,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001946 .rb_init = a2xx_rb_init,
1947 .busy_cycles = a2xx_busy_cycles,
1948 .start = a2xx_start,
Jordan Crousea78c9172011-07-11 13:14:09 -06001949};