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