blob: d31c2ce7e22f84692c0e4769ae87b68a74041fb2 [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
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001328 calc_gmemsize(&drawctxt->context_gmem_shadow,
1329 adreno_dev->gmemspace.sizebytes);
Jordan Crousea78c9172011-07-11 13:14:09 -06001330 tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
1331
1332 result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
1333 drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
1334
1335 if (result)
1336 return result;
1337
Carter Cooperec549da2012-04-02 15:51:38 -06001338 /* set the gmem shadow flag for the context */
1339 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
Jordan Crousea78c9172011-07-11 13:14:09 -06001340
1341 /* blank out gmem shadow. */
1342 kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
1343 drawctxt->context_gmem_shadow.size);
1344
1345 /* build quad vertex buffer */
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001346 build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
1347 &tmp_ctx.cmd);
Jordan Crousea78c9172011-07-11 13:14:09 -06001348
1349 /* build TP0_CHICKEN register restore command buffer */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001350 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE))
1351 tmp_ctx.cmd = build_chicken_restore_cmds(drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001352
1353 /* build indirect command buffers to save & restore gmem */
Jordan Crousea78c9172011-07-11 13:14:09 -06001354 drawctxt->context_gmem_shadow.gmem_save_commands = tmp_ctx.cmd;
1355 tmp_ctx.cmd =
1356 build_gmem2sys_cmds(adreno_dev, drawctxt,
1357 &drawctxt->context_gmem_shadow);
1358 drawctxt->context_gmem_shadow.gmem_restore_commands = tmp_ctx.cmd;
1359 tmp_ctx.cmd =
1360 build_sys2gmem_cmds(adreno_dev, drawctxt,
1361 &drawctxt->context_gmem_shadow);
1362
1363 kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
1364 KGSL_CACHE_OP_FLUSH);
1365
Sushmita Susheelendraf3896062011-08-12 16:33:10 -06001366 kgsl_cffdump_syncmem(NULL,
1367 &drawctxt->context_gmem_shadow.gmemshadow,
1368 drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
1369 drawctxt->context_gmem_shadow.gmemshadow.size, false);
1370
Jordan Crousea78c9172011-07-11 13:14:09 -06001371 return 0;
1372}
1373
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001374static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
1375 struct adreno_context *drawctxt)
1376{
1377 int ret;
1378
1379 /*
1380 * Allocate memory for the GPU state and the context commands.
1381 * Despite the name, this is much more then just storage for
1382 * the gpustate. This contains command space for gmem save
1383 * and texture and vertex buffer storage too
1384 */
1385
1386 ret = kgsl_allocate(&drawctxt->gpustate,
1387 drawctxt->pagetable, _context_size(adreno_dev));
1388
1389 if (ret)
1390 return ret;
1391
1392 kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0,
1393 _context_size(adreno_dev));
1394
1395 tmp_ctx.cmd = tmp_ctx.start
1396 = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
1397
1398 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
1399 ret = a2xx_create_gpustate_shadow(adreno_dev, drawctxt);
1400 if (ret)
1401 goto done;
1402
1403 drawctxt->flags |= CTXT_FLAGS_SHADER_SAVE;
1404 }
1405
1406 if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) {
1407 ret = a2xx_create_gmem_shadow(adreno_dev, drawctxt);
1408 if (ret)
1409 goto done;
1410 }
1411
1412 /* Flush and sync the gpustate memory */
1413
1414 kgsl_cache_range_op(&drawctxt->gpustate,
1415 KGSL_CACHE_OP_FLUSH);
1416
1417 kgsl_cffdump_syncmem(NULL, &drawctxt->gpustate,
1418 drawctxt->gpustate.gpuaddr,
1419 drawctxt->gpustate.size, false);
1420
1421done:
1422 if (ret)
1423 kgsl_sharedmem_free(&drawctxt->gpustate);
1424
1425 return ret;
1426}
1427
1428static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001429 struct adreno_context *context)
1430{
1431 struct kgsl_device *device = &adreno_dev->dev;
Shubhraprakash Das3598b2e2011-11-22 15:07:16 -07001432 unsigned int cmd[22];
Jordan Crousea78c9172011-07-11 13:14:09 -06001433
1434 if (context == NULL)
1435 return;
1436
1437 if (context->flags & CTXT_FLAGS_GPU_HANG)
1438 KGSL_CTXT_WARN(device,
1439 "Current active context has caused gpu hang\n");
1440
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001441 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001442
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001443 /* save registers and constants. */
Jordan Crousee0ea7622012-01-24 09:32:04 -07001444 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001445 context->reg_save, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001446
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001447 if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
1448 /* save shader partitioning and instructions. */
1449 adreno_ringbuffer_issuecmds(device,
1450 KGSL_CMD_FLAGS_PMODE,
1451 context->shader_save, 3);
1452
1453 /*
1454 * fixup shader partitioning parameter for
1455 * SET_SHADER_BASES.
1456 */
1457 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1458 context->shader_fixup, 3);
1459
1460 context->flags |= CTXT_FLAGS_SHADER_RESTORE;
1461 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001462 }
1463
1464 if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
1465 (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
1466 /* save gmem.
1467 * (note: changes shader. shader must already be saved.)
1468 */
1469 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1470 context->context_gmem_shadow.gmem_save, 3);
1471
1472 /* Restore TP0_CHICKEN */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001473 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
1474 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1475 context->chicken_restore, 3);
1476 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001477
1478 context->flags |= CTXT_FLAGS_GMEM_RESTORE;
Shubhraprakash Das3598b2e2011-11-22 15:07:16 -07001479 } else if (adreno_is_a225(adreno_dev)) {
1480 unsigned int *cmds = &cmd[0];
1481 /*
1482 * Issue an empty draw call to avoid possible hangs due to
1483 * repeated idles without intervening draw calls.
1484 * On adreno 225 the PC block has a cache that is only
1485 * flushed on draw calls and repeated idles can make it
1486 * overflow. The gmem save path contains draw calls so
1487 * this workaround isn't needed there.
1488 */
1489 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1490 *cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
1491 *cmds++ = 0;
1492 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
1493 *cmds++ = 0;
1494 *cmds++ = 1<<14;
1495 *cmds++ = 0;
1496 *cmds++ = device->mmu.setstate_memory.gpuaddr;
1497 *cmds++ = 0;
1498 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
1499 *cmds++ = 0x00000000;
1500
1501 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1502 &cmd[0], 11);
Jordan Crousea78c9172011-07-11 13:14:09 -06001503 }
1504}
1505
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001506static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001507 struct adreno_context *context)
1508{
1509 struct kgsl_device *device = &adreno_dev->dev;
1510 unsigned int cmds[5];
1511
1512 if (context == NULL) {
1513 /* No context - set the default apgetable and thats it */
1514 kgsl_mmu_setstate(device, device->mmu.defaultpagetable);
1515 return;
1516 }
1517
1518 KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
1519
Jordan Crouse084427d2011-07-28 08:37:58 -06001520 cmds[0] = cp_nop_packet(1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001521 cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
Jordan Crouse084427d2011-07-28 08:37:58 -06001522 cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001523 cmds[3] = device->memstore.gpuaddr +
Wei Zouc8c01632012-03-24 17:27:26 -07001524 KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
1525 cmds[4] = (unsigned int) context;
Jordan Crousee0ea7622012-01-24 09:32:04 -07001526 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
Jordan Crousea78c9172011-07-11 13:14:09 -06001527 kgsl_mmu_setstate(device, context->pagetable);
1528
1529#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
1530 kgsl_cffdump_syncmem(NULL, &context->gpustate,
1531 context->gpustate.gpuaddr, LCC_SHADOW_SIZE +
1532 REG_SHADOW_SIZE + CMD_BUFFER_SIZE + TEX_SHADOW_SIZE, false);
1533#endif
1534
1535 /* restore gmem.
1536 * (note: changes shader. shader must not already be restored.)
1537 */
1538 if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
1539 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
1540 context->context_gmem_shadow.gmem_restore, 3);
1541
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001542 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
1543 /* Restore TP0_CHICKEN */
1544 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1545 context->chicken_restore, 3);
1546 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001547
1548 context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
1549 }
1550
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001551 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001552
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001553 /* restore registers and constants. */
Jordan Crousee0ea7622012-01-24 09:32:04 -07001554 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001555 context->reg_restore, 3);
1556
1557 /* restore shader instructions & partitioning. */
1558 if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
1559 adreno_ringbuffer_issuecmds(device,
1560 KGSL_CMD_FLAGS_NONE,
1561 context->shader_restore, 3);
1562 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001563 }
1564
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001565 if (adreno_is_a20x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001566 cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001567 cmds[1] = context->bin_base_offset;
Jordan Crousee0ea7622012-01-24 09:32:04 -07001568 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
1569 cmds, 2);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001570 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001571}
1572
1573/*
1574 * Interrupt management
1575 *
1576 * a2xx interrupt control is distributed among the various
1577 * hardware components (RB, CP, MMU). The main interrupt
1578 * tells us which component fired the interrupt, but one needs
1579 * to go to the individual component to find out why. The
1580 * following functions provide the broken out support for
1581 * managing the interrupts
1582 */
1583
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001584#define RBBM_INT_MASK RBBM_INT_CNTL__RDERR_INT_MASK
Jordan Crousea78c9172011-07-11 13:14:09 -06001585
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001586#define CP_INT_MASK \
1587 (CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001588 CP_INT_CNTL__OPCODE_ERROR_MASK | \
1589 CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \
1590 CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \
1591 CP_INT_CNTL__IB_ERROR_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001592 CP_INT_CNTL__IB1_INT_MASK | \
1593 CP_INT_CNTL__RB_INT_MASK)
1594
1595#define VALID_STATUS_COUNT_MAX 10
1596
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001597static struct {
1598 unsigned int mask;
1599 const char *message;
1600} kgsl_cp_error_irqs[] = {
1601 { CP_INT_CNTL__T0_PACKET_IN_IB_MASK,
1602 "ringbuffer TO packet in IB interrupt" },
1603 { CP_INT_CNTL__OPCODE_ERROR_MASK,
1604 "ringbuffer opcode error interrupt" },
1605 { CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK,
1606 "ringbuffer protected mode error interrupt" },
1607 { CP_INT_CNTL__RESERVED_BIT_ERROR_MASK,
1608 "ringbuffer reserved bit error interrupt" },
1609 { CP_INT_CNTL__IB_ERROR_MASK,
1610 "ringbuffer IB error interrupt" },
1611};
1612
Jordan Crousea78c9172011-07-11 13:14:09 -06001613static void a2xx_cp_intrcallback(struct kgsl_device *device)
1614{
1615 unsigned int status = 0, num_reads = 0, master_status = 0;
1616 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1617 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001618 int i;
Jordan Crousea78c9172011-07-11 13:14:09 -06001619
1620 adreno_regread(device, REG_MASTER_INT_SIGNAL, &master_status);
1621 while (!status && (num_reads < VALID_STATUS_COUNT_MAX) &&
1622 (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) {
1623 adreno_regread(device, REG_CP_INT_STATUS, &status);
1624 adreno_regread(device, REG_MASTER_INT_SIGNAL,
1625 &master_status);
1626 num_reads++;
1627 }
1628 if (num_reads > 1)
1629 KGSL_DRV_WARN(device,
1630 "Looped %d times to read REG_CP_INT_STATUS\n",
1631 num_reads);
Norman Geed7402ff2011-10-28 08:51:11 -06001632
1633 trace_kgsl_a2xx_irq_status(device, master_status, status);
1634
Jordan Crousea78c9172011-07-11 13:14:09 -06001635 if (!status) {
1636 if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1637 /* This indicates that we could not read CP_INT_STAT.
1638 * As a precaution just wake up processes so
1639 * they can check their timestamps. Since, we
1640 * did not ack any interrupts this interrupt will
1641 * be generated again */
1642 KGSL_DRV_WARN(device, "Unable to read CP_INT_STATUS\n");
1643 wake_up_interruptible_all(&device->wait_queue);
1644 } else
1645 KGSL_DRV_WARN(device, "Spurious interrput detected\n");
1646 return;
1647 }
1648
1649 if (status & CP_INT_CNTL__RB_INT_MASK) {
1650 /* signal intr completion event */
Wei Zouc8c01632012-03-24 17:27:26 -07001651 unsigned int enableflag = 0;
1652 kgsl_sharedmem_writel(&rb->device->memstore,
1653 KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
1654 enableflag);
1655 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001656 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
1657 }
1658
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001659 for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
1660 if (status & kgsl_cp_error_irqs[i].mask) {
1661 KGSL_CMD_CRIT(rb->device, "%s\n",
1662 kgsl_cp_error_irqs[i].message);
1663 /*
1664 * on fatal errors, turn off the interrupts to
1665 * avoid storming. This has the side effect of
1666 * forcing a PM dump when the timestamp times out
1667 */
Jordan Crousea78c9172011-07-11 13:14:09 -06001668
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001669 kgsl_pwrctrl_irq(rb->device, KGSL_PWRFLAGS_OFF);
1670 }
1671 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001672
1673 /* only ack bits we understand */
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001674 status &= CP_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001675 adreno_regwrite(device, REG_CP_INT_ACK, status);
1676
1677 if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
1678 KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
Jordan Crouse1bf80aa2011-10-12 16:57:47 -06001679 queue_work(device->work_queue, &device->ts_expired_ws);
Jordan Crousea78c9172011-07-11 13:14:09 -06001680 wake_up_interruptible_all(&device->wait_queue);
1681 atomic_notifier_call_chain(&(device->ts_notifier_list),
1682 device->id,
1683 NULL);
1684 }
1685}
1686
1687static void a2xx_rbbm_intrcallback(struct kgsl_device *device)
1688{
1689 unsigned int status = 0;
1690 unsigned int rderr = 0;
1691
1692 adreno_regread(device, REG_RBBM_INT_STATUS, &status);
1693
1694 if (status & RBBM_INT_CNTL__RDERR_INT_MASK) {
1695 union rbbm_read_error_u rerr;
1696 adreno_regread(device, REG_RBBM_READ_ERROR, &rderr);
1697 rerr.val = rderr;
1698 if (rerr.f.read_address == REG_CP_INT_STATUS &&
1699 rerr.f.read_error &&
1700 rerr.f.read_requester)
1701 KGSL_DRV_WARN(device,
1702 "rbbm read error interrupt: %08x\n", rderr);
1703 else
1704 KGSL_DRV_CRIT(device,
1705 "rbbm read error interrupt: %08x\n", rderr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001706 }
1707
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001708 status &= RBBM_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001709 adreno_regwrite(device, REG_RBBM_INT_ACK, status);
1710}
1711
1712irqreturn_t a2xx_irq_handler(struct adreno_device *adreno_dev)
1713{
1714 struct kgsl_device *device = &adreno_dev->dev;
1715 irqreturn_t result = IRQ_NONE;
1716 unsigned int status;
1717
1718 adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
1719
1720 if (status & MASTER_INT_SIGNAL__MH_INT_STAT) {
1721 kgsl_mh_intrcallback(device);
1722 result = IRQ_HANDLED;
1723 }
1724
1725 if (status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1726 a2xx_cp_intrcallback(device);
1727 result = IRQ_HANDLED;
1728 }
1729
1730 if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) {
1731 a2xx_rbbm_intrcallback(device);
1732 result = IRQ_HANDLED;
1733 }
1734
1735 return result;
1736}
1737
1738static void a2xx_irq_control(struct adreno_device *adreno_dev, int state)
1739{
1740 struct kgsl_device *device = &adreno_dev->dev;
1741
1742 if (state) {
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001743 adreno_regwrite(device, REG_RBBM_INT_CNTL, RBBM_INT_MASK);
1744 adreno_regwrite(device, REG_CP_INT_CNTL, CP_INT_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001745 adreno_regwrite(device, MH_INTERRUPT_MASK, KGSL_MMU_INT_MASK);
1746 } else {
1747 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1748 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1749 adreno_regwrite(device, MH_INTERRUPT_MASK, 0);
1750 }
Jordan Crouseb58e61b2011-08-08 13:25:36 -06001751
1752 /* Force the writes to post before touching the IRQ line */
1753 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001754}
1755
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001756static void a2xx_rb_init(struct adreno_device *adreno_dev,
1757 struct adreno_ringbuffer *rb)
1758{
1759 unsigned int *cmds, cmds_gpu;
1760
1761 /* ME_INIT */
1762 cmds = adreno_ringbuffer_allocspace(rb, 19);
1763 cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19);
1764
1765 GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 18));
1766 /* All fields present (bits 9:0) */
1767 GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff);
1768 /* Disable/Enable Real-Time Stream processing (present but ignored) */
1769 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1770 /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
1771 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1772
1773 GSL_RB_WRITE(cmds, cmds_gpu,
1774 SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
1775 GSL_RB_WRITE(cmds, cmds_gpu,
1776 SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
1777 GSL_RB_WRITE(cmds, cmds_gpu,
1778 SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
1779 GSL_RB_WRITE(cmds, cmds_gpu,
1780 SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
1781 GSL_RB_WRITE(cmds, cmds_gpu,
1782 SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
1783 GSL_RB_WRITE(cmds, cmds_gpu,
1784 SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
1785 GSL_RB_WRITE(cmds, cmds_gpu,
1786 SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
1787 GSL_RB_WRITE(cmds, cmds_gpu,
1788 SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
1789
1790 /* Instruction memory size: */
1791 GSL_RB_WRITE(cmds, cmds_gpu,
1792 (adreno_encode_istore_size(adreno_dev)
1793 | adreno_dev->pix_shader_start));
1794 /* Maximum Contexts */
1795 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
1796 /* Write Confirm Interval and The CP will wait the
1797 * wait_interval * 16 clocks between polling */
1798 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1799
1800 /* NQ and External Memory Swap */
1801 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1802 /* Protected mode error checking */
1803 GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL);
1804 /* Disable header dumping and Header dump address */
1805 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1806 /* Header dump size */
1807 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1808
1809 adreno_ringbuffer_submit(rb);
1810}
1811
1812static unsigned int a2xx_busy_cycles(struct adreno_device *adreno_dev)
1813{
1814 struct kgsl_device *device = &adreno_dev->dev;
1815 unsigned int reg, val;
1816
1817 /* Freeze the counter */
1818 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1819 REG_PERF_MODE_CNT | REG_PERF_STATE_FREEZE);
1820
1821 /* Get the value */
1822 adreno_regread(device, REG_RBBM_PERFCOUNTER1_LO, &val);
1823
1824 /* Reset the counter */
1825 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1826 REG_PERF_MODE_CNT | REG_PERF_STATE_RESET);
1827
1828 /* Re-Enable the performance monitors */
1829 adreno_regread(device, REG_RBBM_PM_OVERRIDE2, &reg);
1830 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, (reg | 0x40));
1831 adreno_regwrite(device, REG_RBBM_PERFCOUNTER1_SELECT, 0x1);
1832 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1833 REG_PERF_MODE_CNT | REG_PERF_STATE_ENABLE);
1834
1835 return val;
1836}
1837
1838static void a2xx_gmeminit(struct adreno_device *adreno_dev)
1839{
1840 struct kgsl_device *device = &adreno_dev->dev;
1841 union reg_rb_edram_info rb_edram_info;
1842 unsigned int gmem_size;
1843 unsigned int edram_value = 0;
1844
1845 /* make sure edram range is aligned to size */
1846 BUG_ON(adreno_dev->gmemspace.gpu_base &
1847 (adreno_dev->gmemspace.sizebytes - 1));
1848
1849 /* get edram_size value equivalent */
1850 gmem_size = (adreno_dev->gmemspace.sizebytes >> 14);
1851 while (gmem_size >>= 1)
1852 edram_value++;
1853
1854 rb_edram_info.val = 0;
1855
1856 rb_edram_info.f.edram_size = edram_value;
1857 rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */
1858
1859 /* must be aligned to size */
1860 rb_edram_info.f.edram_range = (adreno_dev->gmemspace.gpu_base >> 14);
1861
1862 adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
1863}
1864
1865static void a2xx_start(struct adreno_device *adreno_dev)
1866{
1867 struct kgsl_device *device = &adreno_dev->dev;
Wei Zouc8c01632012-03-24 17:27:26 -07001868 int init_reftimestamp = 0x7fffffff;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001869
1870 /*
1871 * We need to make sure all blocks are powered up and clocked
1872 * before issuing a soft reset. The overrides will then be
1873 * turned off (set to 0)
1874 */
1875 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe);
1876 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff);
1877
1878 /*
1879 * Only reset CP block if all blocks have previously been
1880 * reset
1881 */
1882 if (!(device->flags & KGSL_FLAGS_SOFT_RESET) ||
1883 !adreno_is_a22x(adreno_dev)) {
1884 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1885 0xFFFFFFFF);
1886 device->flags |= KGSL_FLAGS_SOFT_RESET;
1887 } else {
1888 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1889 0x00000001);
1890 }
1891 /*
1892 * The core is in an indeterminate state until the reset
1893 * completes after 30ms.
1894 */
1895 msleep(30);
1896
1897 adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000);
1898
1899 if (adreno_is_a225(adreno_dev)) {
1900 /* Enable large instruction store for A225 */
1901 adreno_regwrite(device, REG_SQ_FLOW_CONTROL,
1902 0x18000000);
1903 }
1904
1905 adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
1906
1907 adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
1908 adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
1909
Sudhakara Rao Tentudaebac22012-04-02 14:51:29 -07001910 if (cpu_is_msm8960())
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001911 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
1912 else
1913 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
1914
1915 if (!adreno_is_a22x(adreno_dev))
1916 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0);
1917 else
1918 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
1919
Wei Zouc8c01632012-03-24 17:27:26 -07001920 kgsl_sharedmem_set(&device->memstore, 0, 0, device->memstore.size);
1921
1922 kgsl_sharedmem_writel(&device->memstore,
1923 KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
1924 init_reftimestamp);
1925
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001926 adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
1927
1928 /* Make sure interrupts are disabled */
1929 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1930 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1931 adreno_regwrite(device, REG_SQ_INT_CNTL, 0);
1932
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001933 a2xx_gmeminit(adreno_dev);
1934}
1935
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001936/* Defined in adreno_a2xx_snapshot.c */
1937void *a2xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
1938 int *remain, int hang);
1939
Jordan Crousea78c9172011-07-11 13:14:09 -06001940struct adreno_gpudev adreno_a2xx_gpudev = {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001941 .reg_rbbm_status = REG_RBBM_STATUS,
1942 .reg_cp_pfp_ucode_addr = REG_CP_PFP_UCODE_ADDR,
1943 .reg_cp_pfp_ucode_data = REG_CP_PFP_UCODE_DATA,
1944
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001945 .ctxt_create = a2xx_drawctxt_create,
1946 .ctxt_save = a2xx_drawctxt_save,
1947 .ctxt_restore = a2xx_drawctxt_restore,
Jordan Crousea78c9172011-07-11 13:14:09 -06001948 .irq_handler = a2xx_irq_handler,
1949 .irq_control = a2xx_irq_control,
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001950 .snapshot = a2xx_snapshot,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001951 .rb_init = a2xx_rb_init,
1952 .busy_cycles = a2xx_busy_cycles,
1953 .start = a2xx_start,
Jordan Crousea78c9172011-07-11 13:14:09 -06001954};