blob: 8a7ab3506b1c88ae98dcfb55cee3e20842d52551 [file] [log] [blame]
Jordan Crousea78c9172011-07-11 13:14:09 -06001/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include "kgsl.h"
15#include "kgsl_sharedmem.h"
16#include "kgsl_cffdump.h"
17#include "adreno.h"
18
19/*
20 *
21 * Memory Map for Register, Constant & Instruction Shadow, and Command Buffers
22 * (34.5KB)
23 *
24 * +---------------------+------------+-------------+---+---------------------+
25 * | ALU Constant Shadow | Reg Shadow | C&V Buffers |Tex| Shader Instr Shadow |
26 * +---------------------+------------+-------------+---+---------------------+
27 * ________________________________/ \____________________
28 * / |
29 * +--------------+-----------+------+-----------+------------------------+
30 * | Restore Regs | Save Regs | Quad | Gmem Save | Gmem Restore | unused |
31 * +--------------+-----------+------+-----------+------------------------+
32 *
33 * 8K - ALU Constant Shadow (8K aligned)
34 * 4K - H/W Register Shadow (8K aligned)
35 * 4K - Command and Vertex Buffers
36 * - Indirect command buffer : Const/Reg restore
37 * - includes Loop & Bool const shadows
38 * - Indirect command buffer : Const/Reg save
39 * - Quad vertices & texture coordinates
40 * - Indirect command buffer : Gmem save
41 * - Indirect command buffer : Gmem restore
42 * - Unused (padding to 8KB boundary)
43 * <1K - Texture Constant Shadow (768 bytes) (8K aligned)
44 * 18K - Shader Instruction Shadow
45 * - 6K vertex (32 byte aligned)
46 * - 6K pixel (32 byte aligned)
47 * - 6K shared (32 byte aligned)
48 *
49 * Note: Reading constants into a shadow, one at a time using REG_TO_MEM, takes
50 * 3 DWORDS per DWORD transfered, plus 1 DWORD for the shadow, for a total of
51 * 16 bytes per constant. If the texture constants were transfered this way,
52 * the Command & Vertex Buffers section would extend past the 16K boundary.
53 * By moving the texture constant shadow area to start at 16KB boundary, we
54 * only require approximately 40 bytes more memory, but are able to use the
55 * LOAD_CONSTANT_CONTEXT shadowing feature for the textures, speeding up
56 * context switching.
57 *
58 * [Using LOAD_CONSTANT_CONTEXT shadowing feature for the Loop and/or Bool
59 * constants would require an additional 8KB each, for alignment.]
60 *
61 */
62
63/* Constants */
64
65#define ALU_CONSTANTS 2048 /* DWORDS */
66#define NUM_REGISTERS 1024 /* DWORDS */
67#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
68#define CMD_BUFFER_LEN 9216 /* DWORDS */
69#else
70#define CMD_BUFFER_LEN 3072 /* DWORDS */
71#endif
72#define TEX_CONSTANTS (32*6) /* DWORDS */
73#define BOOL_CONSTANTS 8 /* DWORDS */
74#define LOOP_CONSTANTS 56 /* DWORDS */
75#define SHADER_INSTRUCT_LOG2 9U /* 2^n == SHADER_INSTRUCTIONS */
76
Jordan Crousea78c9172011-07-11 13:14:09 -060077/* 96-bit instructions */
78#define SHADER_INSTRUCT (1<<SHADER_INSTRUCT_LOG2)
Jordan Crousea78c9172011-07-11 13:14:09 -060079
80/* LOAD_CONSTANT_CONTEXT shadow size */
81#define LCC_SHADOW_SIZE 0x2000 /* 8KB */
82
83#define ALU_SHADOW_SIZE LCC_SHADOW_SIZE /* 8KB */
84#define REG_SHADOW_SIZE 0x1000 /* 4KB */
85#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
86#define CMD_BUFFER_SIZE 0x9000 /* 36KB */
87#else
88#define CMD_BUFFER_SIZE 0x3000 /* 12KB */
89#endif
90#define TEX_SHADOW_SIZE (TEX_CONSTANTS*4) /* 768 bytes */
91#define SHADER_SHADOW_SIZE (SHADER_INSTRUCT*12) /* 6KB */
92
93#define REG_OFFSET LCC_SHADOW_SIZE
94#define CMD_OFFSET (REG_OFFSET + REG_SHADOW_SIZE)
95#define TEX_OFFSET (CMD_OFFSET + CMD_BUFFER_SIZE)
96#define SHADER_OFFSET ((TEX_OFFSET + TEX_SHADOW_SIZE + 32) & ~31)
97
98#define CONTEXT_SIZE (SHADER_OFFSET + 3 * SHADER_SHADOW_SIZE)
99
100/* A scratchpad used to build commands during context create */
101
102static struct tmp_ctx {
103 unsigned int *start; /* Command & Vertex buffer start */
104 unsigned int *cmd; /* Next available dword in C&V buffer */
105
106 /* address of buffers, needed when creating IB1 command buffers. */
107 uint32_t bool_shadow; /* bool constants */
108 uint32_t loop_shadow; /* loop constants */
109
Jordan Crousea78c9172011-07-11 13:14:09 -0600110 uint32_t shader_shared; /* shared shader instruction shadow */
111 uint32_t shader_vertex; /* vertex shader instruction shadow */
112 uint32_t shader_pixel; /* pixel shader instruction shadow */
Jordan Crousea78c9172011-07-11 13:14:09 -0600113
114 /* Addresses in command buffer where separately handled registers
115 * are saved
116 */
117 uint32_t reg_values[33];
118 uint32_t chicken_restore;
119
120 uint32_t gmem_base; /* Base gpu address of GMEM */
121
122} tmp_ctx;
123
124/* context save (gmem -> sys) */
125
126/* pre-compiled vertex shader program
127*
128* attribute vec4 P;
129* void main(void)
130* {
131* gl_Position = P;
132* }
133*/
134#define GMEM2SYS_VTX_PGM_LEN 0x12
135
136static unsigned int gmem2sys_vtx_pgm[GMEM2SYS_VTX_PGM_LEN] = {
137 0x00011003, 0x00001000, 0xc2000000,
138 0x00001004, 0x00001000, 0xc4000000,
139 0x00001005, 0x00002000, 0x00000000,
140 0x1cb81000, 0x00398a88, 0x00000003,
141 0x140f803e, 0x00000000, 0xe2010100,
142 0x14000000, 0x00000000, 0xe2000000
143};
144
145/* pre-compiled fragment shader program
146*
147* precision highp float;
148* uniform vec4 clear_color;
149* void main(void)
150* {
151* gl_FragColor = clear_color;
152* }
153*/
154
155#define GMEM2SYS_FRAG_PGM_LEN 0x0c
156
157static unsigned int gmem2sys_frag_pgm[GMEM2SYS_FRAG_PGM_LEN] = {
158 0x00000000, 0x1002c400, 0x10000000,
159 0x00001003, 0x00002000, 0x00000000,
160 0x140f8000, 0x00000000, 0x22000000,
161 0x14000000, 0x00000000, 0xe2000000
162};
163
164/* context restore (sys -> gmem) */
165/* pre-compiled vertex shader program
166*
167* attribute vec4 position;
168* attribute vec4 texcoord;
169* varying vec4 texcoord0;
170* void main()
171* {
172* gl_Position = position;
173* texcoord0 = texcoord;
174* }
175*/
176
177#define SYS2GMEM_VTX_PGM_LEN 0x18
178
179static unsigned int sys2gmem_vtx_pgm[SYS2GMEM_VTX_PGM_LEN] = {
180 0x00052003, 0x00001000, 0xc2000000, 0x00001005,
181 0x00001000, 0xc4000000, 0x00001006, 0x10071000,
182 0x20000000, 0x18981000, 0x0039ba88, 0x00000003,
183 0x12982000, 0x40257b08, 0x00000002, 0x140f803e,
184 0x00000000, 0xe2010100, 0x140f8000, 0x00000000,
185 0xe2020200, 0x14000000, 0x00000000, 0xe2000000
186};
187
188/* pre-compiled fragment shader program
189*
190* precision mediump float;
191* uniform sampler2D tex0;
192* varying vec4 texcoord0;
193* void main()
194* {
195* gl_FragColor = texture2D(tex0, texcoord0.xy);
196* }
197*/
198
199#define SYS2GMEM_FRAG_PGM_LEN 0x0f
200
201static unsigned int sys2gmem_frag_pgm[SYS2GMEM_FRAG_PGM_LEN] = {
202 0x00011002, 0x00001000, 0xc4000000, 0x00001003,
203 0x10041000, 0x20000000, 0x10000001, 0x1ffff688,
204 0x00000002, 0x140f8000, 0x00000000, 0xe2000000,
205 0x14000000, 0x00000000, 0xe2000000
206};
207
208/* shader texture constants (sysmem -> gmem) */
209#define SYS2GMEM_TEX_CONST_LEN 6
210
211static unsigned int sys2gmem_tex_const[SYS2GMEM_TEX_CONST_LEN] = {
212 /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat,
213 * RFMode=ZeroClamp-1, Dim=1:2d
214 */
215 0x00000002, /* Pitch = TBD */
216
217 /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0,
218 * NearestClamp=1:OGL Mode
219 */
220 0x00000800, /* Address[31:12] = TBD */
221
222 /* Width, Height, EndianSwap=0:None */
223 0, /* Width & Height = TBD */
224
225 /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point,
226 * Mip=2:BaseMap
227 */
228 0 << 1 | 1 << 4 | 2 << 7 | 3 << 10 | 2 << 23,
229
230 /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0,
231 * Dim3d=0
232 */
233 0,
234
235 /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0,
236 * Dim=1:2d, MipPacking=0
237 */
238 1 << 9 /* Mip Address[31:12] = TBD */
239};
240
Jordan Crousea78c9172011-07-11 13:14:09 -0600241#define NUM_COLOR_FORMATS 13
242
243static enum SURFACEFORMAT surface_format_table[NUM_COLOR_FORMATS] = {
244 FMT_4_4_4_4, /* COLORX_4_4_4_4 */
245 FMT_1_5_5_5, /* COLORX_1_5_5_5 */
246 FMT_5_6_5, /* COLORX_5_6_5 */
247 FMT_8, /* COLORX_8 */
248 FMT_8_8, /* COLORX_8_8 */
249 FMT_8_8_8_8, /* COLORX_8_8_8_8 */
250 FMT_8_8_8_8, /* COLORX_S8_8_8_8 */
251 FMT_16_FLOAT, /* COLORX_16_FLOAT */
252 FMT_16_16_FLOAT, /* COLORX_16_16_FLOAT */
253 FMT_16_16_16_16_FLOAT, /* COLORX_16_16_16_16_FLOAT */
254 FMT_32_FLOAT, /* COLORX_32_FLOAT */
255 FMT_32_32_FLOAT, /* COLORX_32_32_FLOAT */
256 FMT_32_32_32_32_FLOAT, /* COLORX_32_32_32_32_FLOAT */
257};
258
259static unsigned int format2bytesperpixel[NUM_COLOR_FORMATS] = {
260 2, /* COLORX_4_4_4_4 */
261 2, /* COLORX_1_5_5_5 */
262 2, /* COLORX_5_6_5 */
263 1, /* COLORX_8 */
264 2, /* COLORX_8_8 8*/
265 4, /* COLORX_8_8_8_8 */
266 4, /* COLORX_S8_8_8_8 */
267 2, /* COLORX_16_FLOAT */
268 4, /* COLORX_16_16_FLOAT */
269 8, /* COLORX_16_16_16_16_FLOAT */
270 4, /* COLORX_32_FLOAT */
271 8, /* COLORX_32_32_FLOAT */
272 16, /* COLORX_32_32_32_32_FLOAT */
273};
274
275/* shader linkage info */
276#define SHADER_CONST_ADDR (11 * 6 + 3)
277
Jordan Crousea78c9172011-07-11 13:14:09 -0600278
279static unsigned int *program_shader(unsigned int *cmds, int vtxfrag,
280 unsigned int *shader_pgm, int dwords)
281{
282 /* load the patched vertex shader stream */
Jordan Crouse084427d2011-07-28 08:37:58 -0600283 *cmds++ = cp_type3_packet(CP_IM_LOAD_IMMEDIATE, 2 + dwords);
Jordan Crousea78c9172011-07-11 13:14:09 -0600284 /* 0=vertex shader, 1=fragment shader */
285 *cmds++ = vtxfrag;
286 /* instruction start & size (in 32-bit words) */
287 *cmds++ = ((0 << 16) | dwords);
288
289 memcpy(cmds, shader_pgm, dwords << 2);
290 cmds += dwords;
291
292 return cmds;
293}
294
295static unsigned int *reg_to_mem(unsigned int *cmds, uint32_t dst,
296 uint32_t src, int dwords)
297{
298 while (dwords-- > 0) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600299 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600300 *cmds++ = src++;
301 *cmds++ = dst;
302 dst += 4;
303 }
304
305 return cmds;
306}
307
308#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
309
310static void build_reg_to_mem_range(unsigned int start, unsigned int end,
311 unsigned int **cmd,
312 struct adreno_context *drawctxt)
313{
314 unsigned int i = start;
315
316 for (i = start; i <= end; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600317 *(*cmd)++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600318 *(*cmd)++ = i;
319 *(*cmd)++ =
320 ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) +
321 (i - 0x2000) * 4;
322 }
323}
324
325#endif
326
327/* chicken restore */
328static unsigned int *build_chicken_restore_cmds(
329 struct adreno_context *drawctxt)
330{
331 unsigned int *start = tmp_ctx.cmd;
332 unsigned int *cmds = start;
333
Jordan Crouse084427d2011-07-28 08:37:58 -0600334 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600335 *cmds++ = 0;
336
Jordan Crouse084427d2011-07-28 08:37:58 -0600337 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600338 tmp_ctx.chicken_restore = virt2gpu(cmds, &drawctxt->gpustate);
339 *cmds++ = 0x00000000;
340
341 /* create indirect buffer command for above command sequence */
342 create_ib1(drawctxt, drawctxt->chicken_restore, start, cmds);
343
344 return cmds;
345}
346
347/****************************************************************************/
348/* context save */
349/****************************************************************************/
350
351static const unsigned int register_ranges_a20x[] = {
352 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
353 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
354 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
355 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
356 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
357 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
358 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
359 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
360 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
361 REG_VGT_MAX_VTX_INDX, REG_RB_FOG_COLOR,
362 REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL,
363 REG_PA_SU_POINT_SIZE, REG_PA_SC_LINE_STIPPLE,
364 REG_PA_SC_VIZ_QUERY, REG_PA_SC_VIZ_QUERY,
365 REG_VGT_VERTEX_REUSE_BLOCK_CNTL, REG_RB_DEPTH_CLEAR
366};
367
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700368static const unsigned int register_ranges_a220[] = {
Jordan Crousea78c9172011-07-11 13:14:09 -0600369 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
370 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
371 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
372 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
373 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
374 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
375 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
376 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
377 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700378 REG_A220_PC_MAX_VTX_INDX, REG_A220_PC_INDX_OFFSET,
Jordan Crousea78c9172011-07-11 13:14:09 -0600379 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
380 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
381 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
382 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
383 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700384 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
385 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
Jordan Crousea78c9172011-07-11 13:14:09 -0600386 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR
387};
388
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700389static const unsigned int register_ranges_a225[] = {
390 REG_RB_SURFACE_INFO, REG_A225_RB_COLOR_INFO3,
391 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
392 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
393 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
394 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
395 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
396 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
397 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
398 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
399 REG_A220_PC_MAX_VTX_INDX, REG_A225_PC_MULTI_PRIM_IB_RESET_INDX,
400 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
401 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
402 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
403 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
404 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
405 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
406 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
407 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR,
408 REG_A225_GRAS_UCP0X, REG_A225_GRAS_UCP_ENABLED
409};
410
Jordan Crousea78c9172011-07-11 13:14:09 -0600411
412/* save h/w regs, alu constants, texture contants, etc. ...
413* requires: bool_shadow_gpuaddr, loop_shadow_gpuaddr
414*/
415static void build_regsave_cmds(struct adreno_device *adreno_dev,
416 struct adreno_context *drawctxt)
417{
418 unsigned int *start = tmp_ctx.cmd;
419 unsigned int *cmd = start;
420
Jordan Crouse084427d2011-07-28 08:37:58 -0600421 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600422 *cmd++ = 0;
423
424#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
425 /* Make sure the HW context has the correct register values
426 * before reading them. */
Jordan Crouse084427d2011-07-28 08:37:58 -0600427 *cmd++ = cp_type3_packet(CP_CONTEXT_UPDATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600428 *cmd++ = 0;
429
430 {
431 unsigned int i = 0;
432 unsigned int reg_array_size = 0;
433 const unsigned int *ptr_register_ranges;
434
435 /* Based on chip id choose the register ranges */
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700436 if (adreno_is_a220(adreno_dev)) {
437 ptr_register_ranges = register_ranges_a220;
438 reg_array_size = ARRAY_SIZE(register_ranges_a220);
439 } else if (adreno_is_a225(adreno_dev)) {
440 ptr_register_ranges = register_ranges_a225;
441 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -0600442 } else {
443 ptr_register_ranges = register_ranges_a20x;
444 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
445 }
446
447
448 /* Write HW registers into shadow */
449 for (i = 0; i < (reg_array_size/2) ; i++) {
450 build_reg_to_mem_range(ptr_register_ranges[i*2],
451 ptr_register_ranges[i*2+1],
452 &cmd, drawctxt);
453 }
454 }
455
456 /* Copy ALU constants */
457 cmd =
458 reg_to_mem(cmd, (drawctxt->gpustate.gpuaddr) & 0xFFFFE000,
459 REG_SQ_CONSTANT_0, ALU_CONSTANTS);
460
461 /* Copy Tex constants */
462 cmd =
463 reg_to_mem(cmd,
464 (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000,
465 REG_SQ_FETCH_0, TEX_CONSTANTS);
466#else
467
468 /* Insert a wait for idle packet before reading the registers.
469 * This is to fix a hang/reset seen during stress testing. In this
470 * hang, CP encountered a timeout reading SQ's boolean constant
471 * register. There is logic in the HW that blocks reading of this
472 * register when the SQ block is not idle, which we believe is
473 * contributing to the hang.*/
Jordan Crouse084427d2011-07-28 08:37:58 -0600474 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600475 *cmd++ = 0;
476
477 /* H/w registers are already shadowed; just need to disable shadowing
478 * to prevent corruption.
479 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600480 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600481 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
482 *cmd++ = 4 << 16; /* regs, start=0 */
483 *cmd++ = 0x0; /* count = 0 */
484
485 /* ALU constants are already shadowed; just need to disable shadowing
486 * to prevent corruption.
487 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600488 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600489 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
490 *cmd++ = 0 << 16; /* ALU, start=0 */
491 *cmd++ = 0x0; /* count = 0 */
492
493 /* Tex constants are already shadowed; just need to disable shadowing
494 * to prevent corruption.
495 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600496 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600497 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
498 *cmd++ = 1 << 16; /* Tex, start=0 */
499 *cmd++ = 0x0; /* count = 0 */
500#endif
501
502 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -0600503 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600504 *cmd++ = REG_SQ_GPR_MANAGEMENT;
505 *cmd++ = tmp_ctx.reg_values[0];
506
Jordan Crouse084427d2011-07-28 08:37:58 -0600507 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600508 *cmd++ = REG_TP0_CHICKEN;
509 *cmd++ = tmp_ctx.reg_values[1];
510
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600511 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600512 unsigned int i;
513 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700514 for (i = REG_A220_VSC_BIN_SIZE; i <=
515 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600516 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600517 *cmd++ = i;
518 *cmd++ = tmp_ctx.reg_values[j];
519 j++;
520 }
521 }
522
523 /* Copy Boolean constants */
524 cmd = reg_to_mem(cmd, tmp_ctx.bool_shadow, REG_SQ_CF_BOOLEANS,
525 BOOL_CONSTANTS);
526
527 /* Copy Loop constants */
528 cmd = reg_to_mem(cmd, tmp_ctx.loop_shadow,
529 REG_SQ_CF_LOOP, LOOP_CONSTANTS);
530
531 /* create indirect buffer command for above command sequence */
532 create_ib1(drawctxt, drawctxt->reg_save, start, cmd);
533
534 tmp_ctx.cmd = cmd;
535}
536
537/*copy colour, depth, & stencil buffers from graphics memory to system memory*/
538static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
539 struct adreno_context *drawctxt,
540 struct gmem_shadow_t *shadow)
541{
542 unsigned int *cmds = shadow->gmem_save_commands;
543 unsigned int *start = cmds;
544 /* Calculate the new offset based on the adjusted base */
545 unsigned int bytesperpixel = format2bytesperpixel[shadow->format];
546 unsigned int addr = shadow->gmemshadow.gpuaddr;
547 unsigned int offset = (addr - (addr & 0xfffff000)) / bytesperpixel;
548
549 /* Store TP0_CHICKEN register */
Jordan Crouse084427d2011-07-28 08:37:58 -0600550 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600551 *cmds++ = REG_TP0_CHICKEN;
552
553 *cmds++ = tmp_ctx.chicken_restore;
554
Jordan Crouse084427d2011-07-28 08:37:58 -0600555 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600556 *cmds++ = 0;
557
558 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600559 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600560 *cmds++ = 0x00000000;
561
562 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600563 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600564 *cmds++ = 0x00000000;
565
566 /* program shader */
567
568 /* load shader vtx constants ... 5 dwords */
Jordan Crouse084427d2011-07-28 08:37:58 -0600569 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crousea78c9172011-07-11 13:14:09 -0600570 *cmds++ = (0x1 << 16) | SHADER_CONST_ADDR;
571 *cmds++ = 0;
572 /* valid(?) vtx constant flag & addr */
573 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
574 /* limit = 12 dwords */
575 *cmds++ = 0x00000030;
576
577 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600578 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600579 *cmds++ = 0x1;
580
Jordan Crouse084427d2011-07-28 08:37:58 -0600581 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600582 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600583 *cmds++ = 0x00ffffff; /* REG_VGT_MAX_VTX_INDX */
584 *cmds++ = 0x0; /* REG_VGT_MIN_VTX_INDX */
585 *cmds++ = 0x00000000; /* REG_VGT_INDX_OFFSET */
586
Jordan Crouse084427d2011-07-28 08:37:58 -0600587 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600588 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600589 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
590
Jordan Crouse084427d2011-07-28 08:37:58 -0600591 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600592 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600593 *cmds++ = 0x00000c20;
594
Tarun Karra16346b02011-07-24 15:04:26 -0700595 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600596 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700597 *cmds++ = 0x180;
598
599 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600600 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700601 *cmds++ = 0x00003F00;
602
Jordan Crouse084427d2011-07-28 08:37:58 -0600603 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700604 *cmds++ = (0x80000000) | 0x180;
605
Jordan Crousea78c9172011-07-11 13:14:09 -0600606 /* load the patched vertex shader stream */
607 cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN);
608
609 /* Load the patched fragment shader stream */
610 cmds =
611 program_shader(cmds, 1, gmem2sys_frag_pgm, GMEM2SYS_FRAG_PGM_LEN);
612
613 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600614 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600615 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600616 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600617 *cmds++ = 0x10018001;
618 else
619 *cmds++ = 0x10010001;
620 *cmds++ = 0x00000008;
621
622 /* resolve */
623
624 /* PA_CL_VTE_CNTL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600625 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600626 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600627 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
628 *cmds++ = 0x00000b00;
629
630 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600631 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600632 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600633 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
634
635 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
636 * Base=gmem_base
637 */
638 /* gmem base assumed 4K aligned. */
639 BUG_ON(tmp_ctx.gmem_base & 0xFFF);
640 *cmds++ =
641 (shadow->
642 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
643
644 /* disable Z */
Jordan Crouse084427d2011-07-28 08:37:58 -0600645 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600646 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600647 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600648 *cmds++ = 0x08;
649 else
650 *cmds++ = 0;
651
652 /* set REG_PA_SU_SC_MODE_CNTL
653 * Front_ptype = draw triangles
654 * Back_ptype = draw triangles
655 * Provoking vertex = last
656 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600657 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600658 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600659 *cmds++ = 0x00080240;
660
661 /* Use maximum scissor values -- quad vertices already have the
662 * correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600663 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600664 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600665 *cmds++ = (0 << 16) | 0;
666 *cmds++ = (0x1fff << 16) | (0x1fff);
Jordan Crouse084427d2011-07-28 08:37:58 -0600667 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600668 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600669 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
670 *cmds++ = (0x1fff << 16) | (0x1fff);
671
672 /* load the viewport so that z scale = clear depth and
673 * z offset = 0.0f
674 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600675 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600676 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600677 *cmds++ = 0xbf800000; /* -1.0f */
678 *cmds++ = 0x0;
679
Jordan Crouse084427d2011-07-28 08:37:58 -0600680 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600681 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600682 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
683
Jordan Crouse084427d2011-07-28 08:37:58 -0600684 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600685 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600686 *cmds++ = 0xffffffff;
687
Jordan Crouse084427d2011-07-28 08:37:58 -0600688 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600689 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -0600690 *cmds++ = 0x00000000;
691 *cmds++ = 0x00000000;
692
693 /* load the stencil ref value
694 * $AAM - do this later
695 */
696
697 /* load the COPY state */
Jordan Crouse084427d2011-07-28 08:37:58 -0600698 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600699 *cmds++ = CP_REG(REG_RB_COPY_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600700 *cmds++ = 0; /* RB_COPY_CONTROL */
701 *cmds++ = addr & 0xfffff000; /* RB_COPY_DEST_BASE */
702 *cmds++ = shadow->pitch >> 5; /* RB_COPY_DEST_PITCH */
703
704 /* Endian=none, Linear, Format=RGBA8888,Swap=0,!Dither,
705 * MaskWrite:R=G=B=A=1
706 */
707 *cmds++ = 0x0003c008 |
708 (shadow->format << RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT);
709 /* Make sure we stay in offsetx field. */
710 BUG_ON(offset & 0xfffff000);
711 *cmds++ = offset;
712
Jordan Crouse084427d2011-07-28 08:37:58 -0600713 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600714 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600715 *cmds++ = 0x6; /* EDRAM copy */
716
Jordan Crouse084427d2011-07-28 08:37:58 -0600717 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600718 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600719 *cmds++ = 0x00010000;
720
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600721 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600722 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600723 *cmds++ = 0;
724
Jordan Crouse084427d2011-07-28 08:37:58 -0600725 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700726 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600727 *cmds++ = 0x0000000;
728
Jordan Crouse084427d2011-07-28 08:37:58 -0600729 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600730 *cmds++ = 0; /* viz query info. */
731 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
732 *cmds++ = 0x00004088;
733 *cmds++ = 3; /* NumIndices=3 */
734 } else {
735 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -0600736 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600737 *cmds++ = 0; /* viz query info. */
738 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
739 *cmds++ = 0x00030088;
740 }
741
742 /* create indirect buffer command for above command sequence */
743 create_ib1(drawctxt, shadow->gmem_save, start, cmds);
744
745 return cmds;
746}
747
748/* context restore */
749
750/*copy colour, depth, & stencil buffers from system memory to graphics memory*/
751static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
752 struct adreno_context *drawctxt,
753 struct gmem_shadow_t *shadow)
754{
755 unsigned int *cmds = shadow->gmem_restore_commands;
756 unsigned int *start = cmds;
757
758 /* Store TP0_CHICKEN register */
Jordan Crouse084427d2011-07-28 08:37:58 -0600759 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600760 *cmds++ = REG_TP0_CHICKEN;
761 *cmds++ = tmp_ctx.chicken_restore;
762
Jordan Crouse084427d2011-07-28 08:37:58 -0600763 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600764 *cmds++ = 0;
765
766 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600767 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600768 *cmds++ = 0x00000000;
769
770 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600771 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600772 *cmds++ = 0x00000000;
773 /* shader constants */
774
775 /* vertex buffer constants */
Jordan Crouse084427d2011-07-28 08:37:58 -0600776 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
Jordan Crousea78c9172011-07-11 13:14:09 -0600777
778 *cmds++ = (0x1 << 16) | (9 * 6);
779 /* valid(?) vtx constant flag & addr */
780 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
781 /* limit = 12 dwords */
782 *cmds++ = 0x00000030;
783 /* valid(?) vtx constant flag & addr */
784 *cmds++ = shadow->quad_texcoords.gpuaddr | 0x3;
785 /* limit = 8 dwords */
786 *cmds++ = 0x00000020;
787 *cmds++ = 0;
788 *cmds++ = 0;
789
790 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600791 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600792 *cmds++ = 0x1;
793
794 cmds = program_shader(cmds, 0, sys2gmem_vtx_pgm, SYS2GMEM_VTX_PGM_LEN);
795
Tarun Karra16346b02011-07-24 15:04:26 -0700796 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600797 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700798 *cmds++ = 0x180;
799
800 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600801 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700802 *cmds++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
803
Jordan Crouse084427d2011-07-28 08:37:58 -0600804 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700805 *cmds++ = (0x80000000) | 0x180;
806
Jordan Crousea78c9172011-07-11 13:14:09 -0600807 /* Load the patched fragment shader stream */
808 cmds =
809 program_shader(cmds, 1, sys2gmem_frag_pgm, SYS2GMEM_FRAG_PGM_LEN);
810
811 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600812 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600813 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600814 *cmds++ = 0x10030002;
815 *cmds++ = 0x00000008;
816
Jordan Crouse084427d2011-07-28 08:37:58 -0600817 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600818 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600819 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
820
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600821 if (!adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600822 /* PA_SC_VIZ_QUERY */
Jordan Crouse084427d2011-07-28 08:37:58 -0600823 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600824 *cmds++ = CP_REG(REG_PA_SC_VIZ_QUERY);
Jordan Crousea78c9172011-07-11 13:14:09 -0600825 *cmds++ = 0x0; /*REG_PA_SC_VIZ_QUERY */
826 }
827
828 /* RB_COLORCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600829 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600830 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600831 *cmds++ = 0x00000c20;
832
Jordan Crouse084427d2011-07-28 08:37:58 -0600833 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600834 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600835 *cmds++ = 0x00ffffff; /* mmVGT_MAX_VTX_INDX */
836 *cmds++ = 0x0; /* mmVGT_MIN_VTX_INDX */
837 *cmds++ = 0x00000000; /* mmVGT_INDX_OFFSET */
838
Jordan Crouse084427d2011-07-28 08:37:58 -0600839 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600840 *cmds++ = CP_REG(REG_VGT_VERTEX_REUSE_BLOCK_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600841 *cmds++ = 0x00000002; /* mmVGT_VERTEX_REUSE_BLOCK_CNTL */
842 *cmds++ = 0x00000002; /* mmVGT_OUT_DEALLOC_CNTL */
843
Jordan Crouse084427d2011-07-28 08:37:58 -0600844 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600845 *cmds++ = CP_REG(REG_SQ_INTERPOLATOR_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600846 *cmds++ = 0xffffffff; /* mmSQ_INTERPOLATOR_CNTL */
847
Jordan Crouse084427d2011-07-28 08:37:58 -0600848 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600849 *cmds++ = CP_REG(REG_PA_SC_AA_CONFIG);
Jordan Crousea78c9172011-07-11 13:14:09 -0600850 *cmds++ = 0x00000000; /* REG_PA_SC_AA_CONFIG */
851
852 /* set REG_PA_SU_SC_MODE_CNTL
853 * Front_ptype = draw triangles
854 * Back_ptype = draw triangles
855 * Provoking vertex = last
856 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600857 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600858 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600859 *cmds++ = 0x00080240;
860
861 /* texture constants */
862 *cmds++ =
Jordan Crouse084427d2011-07-28 08:37:58 -0600863 cp_type3_packet(CP_SET_CONSTANT, (SYS2GMEM_TEX_CONST_LEN + 1));
Jordan Crousea78c9172011-07-11 13:14:09 -0600864 *cmds++ = (0x1 << 16) | (0 * 6);
865 memcpy(cmds, sys2gmem_tex_const, SYS2GMEM_TEX_CONST_LEN << 2);
866 cmds[0] |= (shadow->pitch >> 5) << 22;
867 cmds[1] |=
868 shadow->gmemshadow.gpuaddr | surface_format_table[shadow->format];
869 cmds[2] |= (shadow->width - 1) | (shadow->height - 1) << 13;
870 cmds += SYS2GMEM_TEX_CONST_LEN;
871
872 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600873 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600874 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600875 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
876
877 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
878 * Base=gmem_base
879 */
880 *cmds++ =
881 (shadow->
882 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
883
884 /* RB_DEPTHCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600885 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600886 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600887
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600888 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600889 *cmds++ = 8; /* disable Z */
890 else
891 *cmds++ = 0; /* disable Z */
892
893 /* Use maximum scissor values -- quad vertices already
894 * have the correct bounds */
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_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600897 *cmds++ = (0 << 16) | 0;
898 *cmds++ = ((0x1fff) << 16) | 0x1fff;
Jordan Crouse084427d2011-07-28 08:37:58 -0600899 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600900 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600901 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
902 *cmds++ = ((0x1fff) << 16) | 0x1fff;
903
Jordan Crouse084427d2011-07-28 08:37:58 -0600904 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600905 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600906 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
907 *cmds++ = 0x00000b00;
908
909 /*load the viewport so that z scale = clear depth and z offset = 0.0f */
Jordan Crouse084427d2011-07-28 08:37:58 -0600910 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600911 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600912 *cmds++ = 0xbf800000;
913 *cmds++ = 0x0;
914
Jordan Crouse084427d2011-07-28 08:37:58 -0600915 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600916 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600917 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
918
Jordan Crouse084427d2011-07-28 08:37:58 -0600919 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600920 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600921 *cmds++ = 0xffffffff;
922
Jordan Crouse084427d2011-07-28 08:37:58 -0600923 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600924 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -0600925 *cmds++ = 0x00000000;
926 *cmds++ = 0x00000000;
927
928 /* load the stencil ref value
929 * $AAM - do this later
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_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600933 /* draw pixels with color and depth/stencil component */
934 *cmds++ = 0x4;
935
Jordan Crouse084427d2011-07-28 08:37:58 -0600936 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600937 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600938 *cmds++ = 0x00010000;
939
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600940 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600941 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600942 *cmds++ = 0;
943
Jordan Crouse084427d2011-07-28 08:37:58 -0600944 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700945 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600946 *cmds++ = 0x0000000;
947
Jordan Crouse084427d2011-07-28 08:37:58 -0600948 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600949 *cmds++ = 0; /* viz query info. */
950 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
951 *cmds++ = 0x00004088;
952 *cmds++ = 3; /* NumIndices=3 */
953 } else {
954 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -0600955 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600956 *cmds++ = 0; /* viz query info. */
957 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
958 *cmds++ = 0x00030088;
959 }
960
961 /* create indirect buffer command for above command sequence */
962 create_ib1(drawctxt, shadow->gmem_restore, start, cmds);
963
964 return cmds;
965}
966
Jordan Crousea78c9172011-07-11 13:14:09 -0600967static void build_regrestore_cmds(struct adreno_device *adreno_dev,
968 struct adreno_context *drawctxt)
969{
970 unsigned int *start = tmp_ctx.cmd;
971 unsigned int *cmd = start;
972
973 unsigned int i = 0;
974 unsigned int reg_array_size = 0;
975 const unsigned int *ptr_register_ranges;
976
Jordan Crouse084427d2011-07-28 08:37:58 -0600977 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600978 *cmd++ = 0;
979
980 /* H/W Registers */
Jordan Crouse084427d2011-07-28 08:37:58 -0600981 /* deferred cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, ???); */
Jordan Crousea78c9172011-07-11 13:14:09 -0600982 cmd++;
983#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
984 /* Force mismatch */
985 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1;
986#else
987 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
988#endif
989
990 /* Based on chip id choose the registers ranges*/
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700991 if (adreno_is_a220(adreno_dev)) {
992 ptr_register_ranges = register_ranges_a220;
993 reg_array_size = ARRAY_SIZE(register_ranges_a220);
994 } else if (adreno_is_a225(adreno_dev)) {
995 ptr_register_ranges = register_ranges_a225;
996 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -0600997 } else {
998 ptr_register_ranges = register_ranges_a20x;
999 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
1000 }
1001
1002
1003 for (i = 0; i < (reg_array_size/2); i++) {
1004 cmd = reg_range(cmd, ptr_register_ranges[i*2],
1005 ptr_register_ranges[i*2+1]);
1006 }
1007
1008 /* Now we know how many register blocks we have, we can compute command
1009 * length
1010 */
1011 start[2] =
Jordan Crouse084427d2011-07-28 08:37:58 -06001012 cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, (cmd - start) - 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001013 /* Enable shadowing for the entire register block. */
1014#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1015 start[4] |= (0 << 24) | (4 << 16); /* Disable shadowing. */
1016#else
1017 start[4] |= (1 << 24) | (4 << 16);
1018#endif
1019
1020 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -06001021 *cmd++ = cp_type0_packet(REG_SQ_GPR_MANAGEMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001022 tmp_ctx.reg_values[0] = virt2gpu(cmd, &drawctxt->gpustate);
1023 *cmd++ = 0x00040400;
1024
Jordan Crouse084427d2011-07-28 08:37:58 -06001025 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001026 *cmd++ = 0;
Jordan Crouse084427d2011-07-28 08:37:58 -06001027 *cmd++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001028 tmp_ctx.reg_values[1] = virt2gpu(cmd, &drawctxt->gpustate);
1029 *cmd++ = 0x00000000;
1030
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001031 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001032 unsigned int i;
1033 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001034 for (i = REG_A220_VSC_BIN_SIZE; i <=
1035 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001036 *cmd++ = cp_type0_packet(i, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001037 tmp_ctx.reg_values[j] = virt2gpu(cmd,
1038 &drawctxt->gpustate);
1039 *cmd++ = 0x00000000;
1040 j++;
1041 }
1042 }
1043
1044 /* ALU Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001045 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001046 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
1047#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1048 *cmd++ = (0 << 24) | (0 << 16) | 0; /* Disable shadowing */
1049#else
1050 *cmd++ = (1 << 24) | (0 << 16) | 0;
1051#endif
1052 *cmd++ = ALU_CONSTANTS;
1053
1054 /* Texture Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001055 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001056 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
1057#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1058 /* Disable shadowing */
1059 *cmd++ = (0 << 24) | (1 << 16) | 0;
1060#else
1061 *cmd++ = (1 << 24) | (1 << 16) | 0;
1062#endif
1063 *cmd++ = TEX_CONSTANTS;
1064
1065 /* Boolean Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001066 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + BOOL_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001067 *cmd++ = (2 << 16) | 0;
1068
1069 /* the next BOOL_CONSTANT dwords is the shadow area for
1070 * boolean constants.
1071 */
1072 tmp_ctx.bool_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1073 cmd += BOOL_CONSTANTS;
1074
1075 /* Loop Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001076 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + LOOP_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001077 *cmd++ = (3 << 16) | 0;
1078
1079 /* the next LOOP_CONSTANTS dwords is the shadow area for
1080 * loop constants.
1081 */
1082 tmp_ctx.loop_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1083 cmd += LOOP_CONSTANTS;
1084
1085 /* create indirect buffer command for above command sequence */
1086 create_ib1(drawctxt, drawctxt->reg_restore, start, cmd);
1087
1088 tmp_ctx.cmd = cmd;
1089}
1090
Jordan Crousea78c9172011-07-11 13:14:09 -06001091static void
1092build_shader_save_restore_cmds(struct adreno_context *drawctxt)
1093{
1094 unsigned int *cmd = tmp_ctx.cmd;
1095 unsigned int *save, *restore, *fixup;
Jordan Crousea78c9172011-07-11 13:14:09 -06001096 unsigned int *startSizeVtx, *startSizePix, *startSizeShared;
Jordan Crousea78c9172011-07-11 13:14:09 -06001097 unsigned int *partition1;
1098 unsigned int *shaderBases, *partition2;
1099
Jordan Crousea78c9172011-07-11 13:14:09 -06001100 /* compute vertex, pixel and shared instruction shadow GPU addresses */
1101 tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET;
1102 tmp_ctx.shader_pixel = tmp_ctx.shader_vertex + SHADER_SHADOW_SIZE;
1103 tmp_ctx.shader_shared = tmp_ctx.shader_pixel + SHADER_SHADOW_SIZE;
Jordan Crousea78c9172011-07-11 13:14:09 -06001104
1105 /* restore shader partitioning and instructions */
1106
1107 restore = cmd; /* start address */
1108
1109 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -06001110 *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001111 *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
1112
1113 /* Restore previous shader vertex & pixel instruction bases. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001114 *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001115 shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */
1116
1117 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001118 *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001119 partition1 = cmd++; /* TBD #4a: partition info (from save) */
1120
Jordan Crousea78c9172011-07-11 13:14:09 -06001121 /* load vertex shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001122 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001123 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1124 startSizeVtx = cmd++; /* TBD #1: start/size (from save) */
1125
1126 /* load pixel shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001127 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001128 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1129 startSizePix = cmd++; /* TBD #2: start/size (from save) */
1130
1131 /* load shared shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001132 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001133 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1134 startSizeShared = cmd++; /* TBD #3: start/size (from save) */
Jordan Crousea78c9172011-07-11 13:14:09 -06001135
1136 /* create indirect buffer command for above command sequence */
1137 create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd);
1138
1139 /*
1140 * fixup SET_SHADER_BASES data
1141 *
1142 * since self-modifying PM4 code is being used here, a seperate
1143 * command buffer is used for this fixup operation, to ensure the
1144 * commands are not read by the PM4 engine before the data fields
1145 * have been written.
1146 */
1147
1148 fixup = cmd; /* start address */
1149
1150 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001151 *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001152 partition2 = cmd++; /* TBD #4b: partition info (from save) */
1153
1154 /* mask off unused bits, then OR with shader instruction memory size */
Jordan Crouse084427d2011-07-28 08:37:58 -06001155 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001156 *cmd++ = REG_SCRATCH_REG2;
1157 /* AND off invalid bits. */
1158 *cmd++ = 0x0FFF0FFF;
1159 /* OR in instruction memory size */
1160 *cmd++ = (unsigned int)((SHADER_INSTRUCT_LOG2 - 5U) << 29);
1161
1162 /* write the computed value to the SET_SHADER_BASES data field */
Jordan Crouse084427d2011-07-28 08:37:58 -06001163 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001164 *cmd++ = REG_SCRATCH_REG2;
1165 /* TBD #5: shader bases (to restore) */
1166 *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate);
1167
1168 /* create indirect buffer command for above command sequence */
1169 create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd);
1170
1171 /* save shader partitioning and instructions */
1172
1173 save = cmd; /* start address */
1174
Jordan Crouse084427d2011-07-28 08:37:58 -06001175 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001176 *cmd++ = 0;
1177
1178 /* fetch the SQ_INST_STORE_MANAGMENT register value,
1179 * store the value in the data fields of the SET_CONSTANT commands
1180 * above.
1181 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001182 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001183 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1184 /* TBD #4a: partition info (to restore) */
1185 *cmd++ = virt2gpu(partition1, &drawctxt->gpustate);
Jordan Crouse084427d2011-07-28 08:37:58 -06001186 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001187 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1188 /* TBD #4b: partition info (to fixup) */
1189 *cmd++ = virt2gpu(partition2, &drawctxt->gpustate);
1190
Jordan Crousea78c9172011-07-11 13:14:09 -06001191
1192 /* store the vertex shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001193 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001194 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1195 /* TBD #1: start/size (to restore) */
1196 *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate);
1197
1198 /* store the pixel shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001199 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001200 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1201 /* TBD #2: start/size (to restore) */
1202 *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate);
1203
1204 /* store the shared shader instructions if vertex base is nonzero */
1205
Jordan Crouse084427d2011-07-28 08:37:58 -06001206 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001207 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1208 /* TBD #3: start/size (to restore) */
1209 *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate);
1210
Jordan Crousea78c9172011-07-11 13:14:09 -06001211
Jordan Crouse084427d2011-07-28 08:37:58 -06001212 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001213 *cmd++ = 0;
1214
1215 /* create indirect buffer command for above command sequence */
1216 create_ib1(drawctxt, drawctxt->shader_save, save, cmd);
1217
1218 tmp_ctx.cmd = cmd;
1219}
1220
1221/* create buffers for saving/restoring registers, constants, & GMEM */
1222static int a2xx_ctxt_gpustate_shadow(struct adreno_device *adreno_dev,
1223 struct adreno_context *drawctxt)
1224{
1225 int result;
1226
1227 /* Allocate vmalloc memory to store the gpustate */
1228 result = kgsl_allocate(&drawctxt->gpustate,
1229 drawctxt->pagetable, CONTEXT_SIZE);
1230
1231 if (result)
1232 return result;
1233
1234 drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW;
1235
1236 /* Blank out h/w register, constant, and command buffer shadows. */
1237 kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0, CONTEXT_SIZE);
1238
1239 /* set-up command and vertex buffer pointers */
1240 tmp_ctx.cmd = tmp_ctx.start
1241 = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
1242
1243 /* build indirect command buffers to save & restore regs/constants */
1244 adreno_idle(&adreno_dev->dev, KGSL_TIMEOUT_DEFAULT);
1245 build_regrestore_cmds(adreno_dev, drawctxt);
1246 build_regsave_cmds(adreno_dev, drawctxt);
1247
1248 build_shader_save_restore_cmds(drawctxt);
1249
1250 kgsl_cache_range_op(&drawctxt->gpustate,
1251 KGSL_CACHE_OP_FLUSH);
1252
Sushmita Susheelendraf3896062011-08-12 16:33:10 -06001253 kgsl_cffdump_syncmem(NULL, &drawctxt->gpustate,
1254 drawctxt->gpustate.gpuaddr,
1255 drawctxt->gpustate.size, false);
Jordan Crousea78c9172011-07-11 13:14:09 -06001256 return 0;
1257}
1258
1259/* create buffers for saving/restoring registers, constants, & GMEM */
1260static int a2xx_ctxt_gmem_shadow(struct adreno_device *adreno_dev,
1261 struct adreno_context *drawctxt)
1262{
1263 int result;
1264
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001265 calc_gmemsize(&drawctxt->context_gmem_shadow,
1266 adreno_dev->gmemspace.sizebytes);
Jordan Crousea78c9172011-07-11 13:14:09 -06001267 tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
1268
1269 result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
1270 drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
1271
1272 if (result)
1273 return result;
1274
1275 /* we've allocated the shadow, when swapped out, GMEM must be saved. */
1276 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_GMEM_SAVE;
1277
1278 /* blank out gmem shadow. */
1279 kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
1280 drawctxt->context_gmem_shadow.size);
1281
1282 /* build quad vertex buffer */
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001283 build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
1284 &tmp_ctx.cmd);
Jordan Crousea78c9172011-07-11 13:14:09 -06001285
1286 /* build TP0_CHICKEN register restore command buffer */
1287 tmp_ctx.cmd = build_chicken_restore_cmds(drawctxt);
1288
1289 /* build indirect command buffers to save & restore gmem */
1290 /* Idle because we are reading PM override registers */
1291 adreno_idle(&adreno_dev->dev, KGSL_TIMEOUT_DEFAULT);
1292 drawctxt->context_gmem_shadow.gmem_save_commands = tmp_ctx.cmd;
1293 tmp_ctx.cmd =
1294 build_gmem2sys_cmds(adreno_dev, drawctxt,
1295 &drawctxt->context_gmem_shadow);
1296 drawctxt->context_gmem_shadow.gmem_restore_commands = tmp_ctx.cmd;
1297 tmp_ctx.cmd =
1298 build_sys2gmem_cmds(adreno_dev, drawctxt,
1299 &drawctxt->context_gmem_shadow);
1300
1301 kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
1302 KGSL_CACHE_OP_FLUSH);
1303
Sushmita Susheelendraf3896062011-08-12 16:33:10 -06001304 kgsl_cffdump_syncmem(NULL,
1305 &drawctxt->context_gmem_shadow.gmemshadow,
1306 drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
1307 drawctxt->context_gmem_shadow.gmemshadow.size, false);
1308
Jordan Crousea78c9172011-07-11 13:14:09 -06001309 return 0;
1310}
1311
1312static void a2xx_ctxt_save(struct adreno_device *adreno_dev,
1313 struct adreno_context *context)
1314{
1315 struct kgsl_device *device = &adreno_dev->dev;
1316
1317 if (context == NULL)
1318 return;
1319
1320 if (context->flags & CTXT_FLAGS_GPU_HANG)
1321 KGSL_CTXT_WARN(device,
1322 "Current active context has caused gpu hang\n");
1323
1324 KGSL_CTXT_INFO(device,
1325 "active context flags %08x\n", context->flags);
1326
1327 /* save registers and constants. */
1328 adreno_ringbuffer_issuecmds(device, 0, context->reg_save, 3);
1329
1330 if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
1331 /* save shader partitioning and instructions. */
1332 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1333 context->shader_save, 3);
1334
1335 /* fixup shader partitioning parameter for
1336 * SET_SHADER_BASES.
1337 */
1338 adreno_ringbuffer_issuecmds(device, 0,
1339 context->shader_fixup, 3);
1340
1341 context->flags |= CTXT_FLAGS_SHADER_RESTORE;
1342 }
1343
1344 if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
1345 (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
1346 /* save gmem.
1347 * (note: changes shader. shader must already be saved.)
1348 */
1349 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1350 context->context_gmem_shadow.gmem_save, 3);
1351
1352 /* Restore TP0_CHICKEN */
1353 adreno_ringbuffer_issuecmds(device, 0,
1354 context->chicken_restore, 3);
1355
1356 context->flags |= CTXT_FLAGS_GMEM_RESTORE;
1357 }
1358}
1359
1360static void a2xx_ctxt_restore(struct adreno_device *adreno_dev,
1361 struct adreno_context *context)
1362{
1363 struct kgsl_device *device = &adreno_dev->dev;
1364 unsigned int cmds[5];
1365
1366 if (context == NULL) {
1367 /* No context - set the default apgetable and thats it */
1368 kgsl_mmu_setstate(device, device->mmu.defaultpagetable);
1369 return;
1370 }
1371
1372 KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
1373
Jordan Crouse084427d2011-07-28 08:37:58 -06001374 cmds[0] = cp_nop_packet(1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001375 cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
Jordan Crouse084427d2011-07-28 08:37:58 -06001376 cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001377 cmds[3] = device->memstore.gpuaddr +
1378 KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
1379 cmds[4] = (unsigned int) context;
1380 adreno_ringbuffer_issuecmds(device, 0, cmds, 5);
1381 kgsl_mmu_setstate(device, context->pagetable);
1382
1383#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
1384 kgsl_cffdump_syncmem(NULL, &context->gpustate,
1385 context->gpustate.gpuaddr, LCC_SHADOW_SIZE +
1386 REG_SHADOW_SIZE + CMD_BUFFER_SIZE + TEX_SHADOW_SIZE, false);
1387#endif
1388
1389 /* restore gmem.
1390 * (note: changes shader. shader must not already be restored.)
1391 */
1392 if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
1393 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1394 context->context_gmem_shadow.gmem_restore, 3);
1395
1396 /* Restore TP0_CHICKEN */
1397 adreno_ringbuffer_issuecmds(device, 0,
1398 context->chicken_restore, 3);
1399
1400 context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
1401 }
1402
1403 /* restore registers and constants. */
1404 adreno_ringbuffer_issuecmds(device, 0,
1405 context->reg_restore, 3);
1406
1407 /* restore shader instructions & partitioning. */
1408 if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
1409 adreno_ringbuffer_issuecmds(device, 0,
1410 context->shader_restore, 3);
1411 }
1412
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001413 if (adreno_is_a20x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001414 cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001415 cmds[1] = context->bin_base_offset;
Jordan Crousea78c9172011-07-11 13:14:09 -06001416 adreno_ringbuffer_issuecmds(device, 0, cmds, 2);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001417 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001418}
1419
1420/*
1421 * Interrupt management
1422 *
1423 * a2xx interrupt control is distributed among the various
1424 * hardware components (RB, CP, MMU). The main interrupt
1425 * tells us which component fired the interrupt, but one needs
1426 * to go to the individual component to find out why. The
1427 * following functions provide the broken out support for
1428 * managing the interrupts
1429 */
1430
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001431#define RBBM_INT_MASK RBBM_INT_CNTL__RDERR_INT_MASK
Jordan Crousea78c9172011-07-11 13:14:09 -06001432
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001433#define CP_INT_MASK \
1434 (CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001435 CP_INT_CNTL__OPCODE_ERROR_MASK | \
1436 CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \
1437 CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \
1438 CP_INT_CNTL__IB_ERROR_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001439 CP_INT_CNTL__IB1_INT_MASK | \
1440 CP_INT_CNTL__RB_INT_MASK)
1441
1442#define VALID_STATUS_COUNT_MAX 10
1443
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001444static struct {
1445 unsigned int mask;
1446 const char *message;
1447} kgsl_cp_error_irqs[] = {
1448 { CP_INT_CNTL__T0_PACKET_IN_IB_MASK,
1449 "ringbuffer TO packet in IB interrupt" },
1450 { CP_INT_CNTL__OPCODE_ERROR_MASK,
1451 "ringbuffer opcode error interrupt" },
1452 { CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK,
1453 "ringbuffer protected mode error interrupt" },
1454 { CP_INT_CNTL__RESERVED_BIT_ERROR_MASK,
1455 "ringbuffer reserved bit error interrupt" },
1456 { CP_INT_CNTL__IB_ERROR_MASK,
1457 "ringbuffer IB error interrupt" },
1458};
1459
Jordan Crousea78c9172011-07-11 13:14:09 -06001460static void a2xx_cp_intrcallback(struct kgsl_device *device)
1461{
1462 unsigned int status = 0, num_reads = 0, master_status = 0;
1463 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1464 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001465 int i;
Jordan Crousea78c9172011-07-11 13:14:09 -06001466
1467 adreno_regread(device, REG_MASTER_INT_SIGNAL, &master_status);
1468 while (!status && (num_reads < VALID_STATUS_COUNT_MAX) &&
1469 (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) {
1470 adreno_regread(device, REG_CP_INT_STATUS, &status);
1471 adreno_regread(device, REG_MASTER_INT_SIGNAL,
1472 &master_status);
1473 num_reads++;
1474 }
1475 if (num_reads > 1)
1476 KGSL_DRV_WARN(device,
1477 "Looped %d times to read REG_CP_INT_STATUS\n",
1478 num_reads);
1479 if (!status) {
1480 if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1481 /* This indicates that we could not read CP_INT_STAT.
1482 * As a precaution just wake up processes so
1483 * they can check their timestamps. Since, we
1484 * did not ack any interrupts this interrupt will
1485 * be generated again */
1486 KGSL_DRV_WARN(device, "Unable to read CP_INT_STATUS\n");
1487 wake_up_interruptible_all(&device->wait_queue);
1488 } else
1489 KGSL_DRV_WARN(device, "Spurious interrput detected\n");
1490 return;
1491 }
1492
1493 if (status & CP_INT_CNTL__RB_INT_MASK) {
1494 /* signal intr completion event */
1495 unsigned int enableflag = 0;
1496 kgsl_sharedmem_writel(&rb->device->memstore,
1497 KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
1498 enableflag);
1499 wmb();
1500 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
1501 }
1502
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001503 for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
1504 if (status & kgsl_cp_error_irqs[i].mask) {
1505 KGSL_CMD_CRIT(rb->device, "%s\n",
1506 kgsl_cp_error_irqs[i].message);
1507 /*
1508 * on fatal errors, turn off the interrupts to
1509 * avoid storming. This has the side effect of
1510 * forcing a PM dump when the timestamp times out
1511 */
Jordan Crousea78c9172011-07-11 13:14:09 -06001512
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001513 kgsl_pwrctrl_irq(rb->device, KGSL_PWRFLAGS_OFF);
1514 }
1515 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001516
1517 /* only ack bits we understand */
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001518 status &= CP_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001519 adreno_regwrite(device, REG_CP_INT_ACK, status);
1520
1521 if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
1522 KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
1523 wake_up_interruptible_all(&device->wait_queue);
1524 atomic_notifier_call_chain(&(device->ts_notifier_list),
1525 device->id,
1526 NULL);
1527 }
1528}
1529
1530static void a2xx_rbbm_intrcallback(struct kgsl_device *device)
1531{
1532 unsigned int status = 0;
1533 unsigned int rderr = 0;
1534
1535 adreno_regread(device, REG_RBBM_INT_STATUS, &status);
1536
1537 if (status & RBBM_INT_CNTL__RDERR_INT_MASK) {
1538 union rbbm_read_error_u rerr;
1539 adreno_regread(device, REG_RBBM_READ_ERROR, &rderr);
1540 rerr.val = rderr;
1541 if (rerr.f.read_address == REG_CP_INT_STATUS &&
1542 rerr.f.read_error &&
1543 rerr.f.read_requester)
1544 KGSL_DRV_WARN(device,
1545 "rbbm read error interrupt: %08x\n", rderr);
1546 else
1547 KGSL_DRV_CRIT(device,
1548 "rbbm read error interrupt: %08x\n", rderr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001549 }
1550
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001551 status &= RBBM_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001552 adreno_regwrite(device, REG_RBBM_INT_ACK, status);
1553}
1554
1555irqreturn_t a2xx_irq_handler(struct adreno_device *adreno_dev)
1556{
1557 struct kgsl_device *device = &adreno_dev->dev;
1558 irqreturn_t result = IRQ_NONE;
1559 unsigned int status;
1560
1561 adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
1562
1563 if (status & MASTER_INT_SIGNAL__MH_INT_STAT) {
1564 kgsl_mh_intrcallback(device);
1565 result = IRQ_HANDLED;
1566 }
1567
1568 if (status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1569 a2xx_cp_intrcallback(device);
1570 result = IRQ_HANDLED;
1571 }
1572
1573 if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) {
1574 a2xx_rbbm_intrcallback(device);
1575 result = IRQ_HANDLED;
1576 }
1577
1578 return result;
1579}
1580
1581static void a2xx_irq_control(struct adreno_device *adreno_dev, int state)
1582{
1583 struct kgsl_device *device = &adreno_dev->dev;
1584
1585 if (state) {
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001586 adreno_regwrite(device, REG_RBBM_INT_CNTL, RBBM_INT_MASK);
1587 adreno_regwrite(device, REG_CP_INT_CNTL, CP_INT_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001588 adreno_regwrite(device, MH_INTERRUPT_MASK, KGSL_MMU_INT_MASK);
1589 } else {
1590 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1591 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1592 adreno_regwrite(device, MH_INTERRUPT_MASK, 0);
1593 }
Jordan Crouseb58e61b2011-08-08 13:25:36 -06001594
1595 /* Force the writes to post before touching the IRQ line */
1596 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001597}
1598
1599struct adreno_gpudev adreno_a2xx_gpudev = {
1600 .ctxt_gpustate_shadow = a2xx_ctxt_gpustate_shadow,
1601 .ctxt_gmem_shadow = a2xx_ctxt_gmem_shadow,
1602 .ctxt_save = a2xx_ctxt_save,
1603 .ctxt_restore = a2xx_ctxt_restore,
1604 .irq_handler = a2xx_irq_handler,
1605 .irq_control = a2xx_irq_control,
1606};