blob: e31b76b0175eb79704cf254aeead5ab8593e73fb [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{
167 return adreno_dev->istore_size*ADRENO_ISTORE_BYTES;
168}
169
170static inline int _context_size(struct adreno_device *adreno_dev)
171{
172 return SHADER_OFFSET + 3*_shader_shadow_size(adreno_dev);
173}
Jordan Crousea78c9172011-07-11 13:14:09 -0600174
175/* A scratchpad used to build commands during context create */
176
177static struct tmp_ctx {
178 unsigned int *start; /* Command & Vertex buffer start */
179 unsigned int *cmd; /* Next available dword in C&V buffer */
180
181 /* address of buffers, needed when creating IB1 command buffers. */
182 uint32_t bool_shadow; /* bool constants */
183 uint32_t loop_shadow; /* loop constants */
184
Jordan Crousea78c9172011-07-11 13:14:09 -0600185 uint32_t shader_shared; /* shared shader instruction shadow */
186 uint32_t shader_vertex; /* vertex shader instruction shadow */
187 uint32_t shader_pixel; /* pixel shader instruction shadow */
Jordan Crousea78c9172011-07-11 13:14:09 -0600188
189 /* Addresses in command buffer where separately handled registers
190 * are saved
191 */
192 uint32_t reg_values[33];
193 uint32_t chicken_restore;
194
195 uint32_t gmem_base; /* Base gpu address of GMEM */
196
197} tmp_ctx;
198
199/* context save (gmem -> sys) */
200
201/* pre-compiled vertex shader program
202*
203* attribute vec4 P;
204* void main(void)
205* {
206* gl_Position = P;
207* }
208*/
209#define GMEM2SYS_VTX_PGM_LEN 0x12
210
211static unsigned int gmem2sys_vtx_pgm[GMEM2SYS_VTX_PGM_LEN] = {
212 0x00011003, 0x00001000, 0xc2000000,
213 0x00001004, 0x00001000, 0xc4000000,
214 0x00001005, 0x00002000, 0x00000000,
215 0x1cb81000, 0x00398a88, 0x00000003,
216 0x140f803e, 0x00000000, 0xe2010100,
217 0x14000000, 0x00000000, 0xe2000000
218};
219
220/* pre-compiled fragment shader program
221*
222* precision highp float;
223* uniform vec4 clear_color;
224* void main(void)
225* {
226* gl_FragColor = clear_color;
227* }
228*/
229
230#define GMEM2SYS_FRAG_PGM_LEN 0x0c
231
232static unsigned int gmem2sys_frag_pgm[GMEM2SYS_FRAG_PGM_LEN] = {
233 0x00000000, 0x1002c400, 0x10000000,
234 0x00001003, 0x00002000, 0x00000000,
235 0x140f8000, 0x00000000, 0x22000000,
236 0x14000000, 0x00000000, 0xe2000000
237};
238
239/* context restore (sys -> gmem) */
240/* pre-compiled vertex shader program
241*
242* attribute vec4 position;
243* attribute vec4 texcoord;
244* varying vec4 texcoord0;
245* void main()
246* {
247* gl_Position = position;
248* texcoord0 = texcoord;
249* }
250*/
251
252#define SYS2GMEM_VTX_PGM_LEN 0x18
253
254static unsigned int sys2gmem_vtx_pgm[SYS2GMEM_VTX_PGM_LEN] = {
255 0x00052003, 0x00001000, 0xc2000000, 0x00001005,
256 0x00001000, 0xc4000000, 0x00001006, 0x10071000,
257 0x20000000, 0x18981000, 0x0039ba88, 0x00000003,
258 0x12982000, 0x40257b08, 0x00000002, 0x140f803e,
259 0x00000000, 0xe2010100, 0x140f8000, 0x00000000,
260 0xe2020200, 0x14000000, 0x00000000, 0xe2000000
261};
262
263/* pre-compiled fragment shader program
264*
265* precision mediump float;
266* uniform sampler2D tex0;
267* varying vec4 texcoord0;
268* void main()
269* {
270* gl_FragColor = texture2D(tex0, texcoord0.xy);
271* }
272*/
273
274#define SYS2GMEM_FRAG_PGM_LEN 0x0f
275
276static unsigned int sys2gmem_frag_pgm[SYS2GMEM_FRAG_PGM_LEN] = {
277 0x00011002, 0x00001000, 0xc4000000, 0x00001003,
278 0x10041000, 0x20000000, 0x10000001, 0x1ffff688,
279 0x00000002, 0x140f8000, 0x00000000, 0xe2000000,
280 0x14000000, 0x00000000, 0xe2000000
281};
282
283/* shader texture constants (sysmem -> gmem) */
284#define SYS2GMEM_TEX_CONST_LEN 6
285
286static unsigned int sys2gmem_tex_const[SYS2GMEM_TEX_CONST_LEN] = {
287 /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat,
288 * RFMode=ZeroClamp-1, Dim=1:2d
289 */
290 0x00000002, /* Pitch = TBD */
291
292 /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0,
293 * NearestClamp=1:OGL Mode
294 */
295 0x00000800, /* Address[31:12] = TBD */
296
297 /* Width, Height, EndianSwap=0:None */
298 0, /* Width & Height = TBD */
299
300 /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point,
301 * Mip=2:BaseMap
302 */
303 0 << 1 | 1 << 4 | 2 << 7 | 3 << 10 | 2 << 23,
304
305 /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0,
306 * Dim3d=0
307 */
308 0,
309
310 /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0,
311 * Dim=1:2d, MipPacking=0
312 */
313 1 << 9 /* Mip Address[31:12] = TBD */
314};
315
Jordan Crousea78c9172011-07-11 13:14:09 -0600316#define NUM_COLOR_FORMATS 13
317
318static enum SURFACEFORMAT surface_format_table[NUM_COLOR_FORMATS] = {
319 FMT_4_4_4_4, /* COLORX_4_4_4_4 */
320 FMT_1_5_5_5, /* COLORX_1_5_5_5 */
321 FMT_5_6_5, /* COLORX_5_6_5 */
322 FMT_8, /* COLORX_8 */
323 FMT_8_8, /* COLORX_8_8 */
324 FMT_8_8_8_8, /* COLORX_8_8_8_8 */
325 FMT_8_8_8_8, /* COLORX_S8_8_8_8 */
326 FMT_16_FLOAT, /* COLORX_16_FLOAT */
327 FMT_16_16_FLOAT, /* COLORX_16_16_FLOAT */
328 FMT_16_16_16_16_FLOAT, /* COLORX_16_16_16_16_FLOAT */
329 FMT_32_FLOAT, /* COLORX_32_FLOAT */
330 FMT_32_32_FLOAT, /* COLORX_32_32_FLOAT */
331 FMT_32_32_32_32_FLOAT, /* COLORX_32_32_32_32_FLOAT */
332};
333
334static unsigned int format2bytesperpixel[NUM_COLOR_FORMATS] = {
335 2, /* COLORX_4_4_4_4 */
336 2, /* COLORX_1_5_5_5 */
337 2, /* COLORX_5_6_5 */
338 1, /* COLORX_8 */
339 2, /* COLORX_8_8 8*/
340 4, /* COLORX_8_8_8_8 */
341 4, /* COLORX_S8_8_8_8 */
342 2, /* COLORX_16_FLOAT */
343 4, /* COLORX_16_16_FLOAT */
344 8, /* COLORX_16_16_16_16_FLOAT */
345 4, /* COLORX_32_FLOAT */
346 8, /* COLORX_32_32_FLOAT */
347 16, /* COLORX_32_32_32_32_FLOAT */
348};
349
350/* shader linkage info */
351#define SHADER_CONST_ADDR (11 * 6 + 3)
352
Jordan Crousea78c9172011-07-11 13:14:09 -0600353
354static unsigned int *program_shader(unsigned int *cmds, int vtxfrag,
355 unsigned int *shader_pgm, int dwords)
356{
357 /* load the patched vertex shader stream */
Jordan Crouse084427d2011-07-28 08:37:58 -0600358 *cmds++ = cp_type3_packet(CP_IM_LOAD_IMMEDIATE, 2 + dwords);
Jordan Crousea78c9172011-07-11 13:14:09 -0600359 /* 0=vertex shader, 1=fragment shader */
360 *cmds++ = vtxfrag;
361 /* instruction start & size (in 32-bit words) */
362 *cmds++ = ((0 << 16) | dwords);
363
364 memcpy(cmds, shader_pgm, dwords << 2);
365 cmds += dwords;
366
367 return cmds;
368}
369
370static unsigned int *reg_to_mem(unsigned int *cmds, uint32_t dst,
371 uint32_t src, int dwords)
372{
373 while (dwords-- > 0) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600374 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600375 *cmds++ = src++;
376 *cmds++ = dst;
377 dst += 4;
378 }
379
380 return cmds;
381}
382
383#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
384
385static void build_reg_to_mem_range(unsigned int start, unsigned int end,
386 unsigned int **cmd,
387 struct adreno_context *drawctxt)
388{
389 unsigned int i = start;
390
391 for (i = start; i <= end; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600392 *(*cmd)++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600393 *(*cmd)++ = i;
394 *(*cmd)++ =
395 ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) +
396 (i - 0x2000) * 4;
397 }
398}
399
400#endif
401
402/* chicken restore */
403static unsigned int *build_chicken_restore_cmds(
404 struct adreno_context *drawctxt)
405{
406 unsigned int *start = tmp_ctx.cmd;
407 unsigned int *cmds = start;
408
Jordan Crouse084427d2011-07-28 08:37:58 -0600409 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600410 *cmds++ = 0;
411
Jordan Crouse084427d2011-07-28 08:37:58 -0600412 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600413 tmp_ctx.chicken_restore = virt2gpu(cmds, &drawctxt->gpustate);
414 *cmds++ = 0x00000000;
415
416 /* create indirect buffer command for above command sequence */
417 create_ib1(drawctxt, drawctxt->chicken_restore, start, cmds);
418
419 return cmds;
420}
421
422/****************************************************************************/
423/* context save */
424/****************************************************************************/
425
426static const unsigned int register_ranges_a20x[] = {
427 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
428 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
429 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
430 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
431 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
432 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
433 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
434 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
435 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
436 REG_VGT_MAX_VTX_INDX, REG_RB_FOG_COLOR,
437 REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL,
438 REG_PA_SU_POINT_SIZE, REG_PA_SC_LINE_STIPPLE,
439 REG_PA_SC_VIZ_QUERY, REG_PA_SC_VIZ_QUERY,
440 REG_VGT_VERTEX_REUSE_BLOCK_CNTL, REG_RB_DEPTH_CLEAR
441};
442
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700443static const unsigned int register_ranges_a220[] = {
Jordan Crousea78c9172011-07-11 13:14:09 -0600444 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
445 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
446 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
447 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
448 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
449 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
450 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
451 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
452 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700453 REG_A220_PC_MAX_VTX_INDX, REG_A220_PC_INDX_OFFSET,
Jordan Crousea78c9172011-07-11 13:14:09 -0600454 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
455 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
456 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
457 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
458 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700459 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
460 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
Jordan Crousea78c9172011-07-11 13:14:09 -0600461 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR
462};
463
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700464static const unsigned int register_ranges_a225[] = {
465 REG_RB_SURFACE_INFO, REG_A225_RB_COLOR_INFO3,
466 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
467 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
468 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
469 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
470 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
471 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
472 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
473 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
474 REG_A220_PC_MAX_VTX_INDX, REG_A225_PC_MULTI_PRIM_IB_RESET_INDX,
475 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
476 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
477 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
478 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
479 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
480 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
481 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
482 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR,
Jeremy Gebbene139a042011-11-17 16:20:41 -0700483 REG_A225_GRAS_UCP0X, REG_A225_GRAS_UCP5W,
484 REG_A225_GRAS_UCP_ENABLED, REG_A225_GRAS_UCP_ENABLED
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700485};
486
Jordan Crousea78c9172011-07-11 13:14:09 -0600487
488/* save h/w regs, alu constants, texture contants, etc. ...
489* requires: bool_shadow_gpuaddr, loop_shadow_gpuaddr
490*/
491static void build_regsave_cmds(struct adreno_device *adreno_dev,
492 struct adreno_context *drawctxt)
493{
494 unsigned int *start = tmp_ctx.cmd;
495 unsigned int *cmd = start;
496
Jordan Crouse084427d2011-07-28 08:37:58 -0600497 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600498 *cmd++ = 0;
499
500#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
501 /* Make sure the HW context has the correct register values
502 * before reading them. */
Jordan Crouse084427d2011-07-28 08:37:58 -0600503 *cmd++ = cp_type3_packet(CP_CONTEXT_UPDATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600504 *cmd++ = 0;
505
506 {
507 unsigned int i = 0;
508 unsigned int reg_array_size = 0;
509 const unsigned int *ptr_register_ranges;
510
511 /* Based on chip id choose the register ranges */
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700512 if (adreno_is_a220(adreno_dev)) {
513 ptr_register_ranges = register_ranges_a220;
514 reg_array_size = ARRAY_SIZE(register_ranges_a220);
515 } else if (adreno_is_a225(adreno_dev)) {
516 ptr_register_ranges = register_ranges_a225;
517 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -0600518 } else {
519 ptr_register_ranges = register_ranges_a20x;
520 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
521 }
522
523
524 /* Write HW registers into shadow */
525 for (i = 0; i < (reg_array_size/2) ; i++) {
526 build_reg_to_mem_range(ptr_register_ranges[i*2],
527 ptr_register_ranges[i*2+1],
528 &cmd, drawctxt);
529 }
530 }
531
532 /* Copy ALU constants */
533 cmd =
534 reg_to_mem(cmd, (drawctxt->gpustate.gpuaddr) & 0xFFFFE000,
535 REG_SQ_CONSTANT_0, ALU_CONSTANTS);
536
537 /* Copy Tex constants */
538 cmd =
539 reg_to_mem(cmd,
540 (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000,
541 REG_SQ_FETCH_0, TEX_CONSTANTS);
542#else
543
544 /* Insert a wait for idle packet before reading the registers.
545 * This is to fix a hang/reset seen during stress testing. In this
546 * hang, CP encountered a timeout reading SQ's boolean constant
547 * register. There is logic in the HW that blocks reading of this
548 * register when the SQ block is not idle, which we believe is
549 * contributing to the hang.*/
Jordan Crouse084427d2011-07-28 08:37:58 -0600550 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600551 *cmd++ = 0;
552
553 /* H/w registers are already shadowed; just need to disable shadowing
554 * to prevent corruption.
555 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600556 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600557 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
558 *cmd++ = 4 << 16; /* regs, start=0 */
559 *cmd++ = 0x0; /* count = 0 */
560
561 /* ALU constants are already shadowed; just need to disable shadowing
562 * to prevent corruption.
563 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600564 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600565 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
566 *cmd++ = 0 << 16; /* ALU, start=0 */
567 *cmd++ = 0x0; /* count = 0 */
568
569 /* Tex constants are already shadowed; just need to disable shadowing
570 * to prevent corruption.
571 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600572 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600573 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
574 *cmd++ = 1 << 16; /* Tex, start=0 */
575 *cmd++ = 0x0; /* count = 0 */
576#endif
577
578 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -0600579 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600580 *cmd++ = REG_SQ_GPR_MANAGEMENT;
581 *cmd++ = tmp_ctx.reg_values[0];
582
Jordan Crouse084427d2011-07-28 08:37:58 -0600583 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600584 *cmd++ = REG_TP0_CHICKEN;
585 *cmd++ = tmp_ctx.reg_values[1];
586
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600587 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600588 unsigned int i;
589 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700590 for (i = REG_A220_VSC_BIN_SIZE; i <=
591 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600592 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600593 *cmd++ = i;
594 *cmd++ = tmp_ctx.reg_values[j];
595 j++;
596 }
597 }
598
599 /* Copy Boolean constants */
600 cmd = reg_to_mem(cmd, tmp_ctx.bool_shadow, REG_SQ_CF_BOOLEANS,
601 BOOL_CONSTANTS);
602
603 /* Copy Loop constants */
604 cmd = reg_to_mem(cmd, tmp_ctx.loop_shadow,
605 REG_SQ_CF_LOOP, LOOP_CONSTANTS);
606
607 /* create indirect buffer command for above command sequence */
608 create_ib1(drawctxt, drawctxt->reg_save, start, cmd);
609
610 tmp_ctx.cmd = cmd;
611}
612
613/*copy colour, depth, & stencil buffers from graphics memory to system memory*/
614static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
615 struct adreno_context *drawctxt,
616 struct gmem_shadow_t *shadow)
617{
618 unsigned int *cmds = shadow->gmem_save_commands;
619 unsigned int *start = cmds;
620 /* Calculate the new offset based on the adjusted base */
621 unsigned int bytesperpixel = format2bytesperpixel[shadow->format];
622 unsigned int addr = shadow->gmemshadow.gpuaddr;
623 unsigned int offset = (addr - (addr & 0xfffff000)) / bytesperpixel;
624
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700625 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
626 /* Store TP0_CHICKEN register */
627 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
628 *cmds++ = REG_TP0_CHICKEN;
Jordan Crousea78c9172011-07-11 13:14:09 -0600629
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700630 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600631
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700632 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
633 *cmds++ = 0;
634 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600635
636 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600637 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600638 *cmds++ = 0x00000000;
639
640 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600641 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600642 *cmds++ = 0x00000000;
643
644 /* program shader */
645
646 /* load shader vtx constants ... 5 dwords */
Jordan Crouse084427d2011-07-28 08:37:58 -0600647 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crousea78c9172011-07-11 13:14:09 -0600648 *cmds++ = (0x1 << 16) | SHADER_CONST_ADDR;
649 *cmds++ = 0;
650 /* valid(?) vtx constant flag & addr */
651 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
652 /* limit = 12 dwords */
653 *cmds++ = 0x00000030;
654
655 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600656 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600657 *cmds++ = 0x1;
658
Jordan Crouse084427d2011-07-28 08:37:58 -0600659 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600660 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600661 *cmds++ = 0x00ffffff; /* REG_VGT_MAX_VTX_INDX */
662 *cmds++ = 0x0; /* REG_VGT_MIN_VTX_INDX */
663 *cmds++ = 0x00000000; /* REG_VGT_INDX_OFFSET */
664
Jordan Crouse084427d2011-07-28 08:37:58 -0600665 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600666 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600667 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
668
Jordan Crouse084427d2011-07-28 08:37:58 -0600669 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600670 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600671 *cmds++ = 0x00000c20;
672
Tarun Karra16346b02011-07-24 15:04:26 -0700673 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600674 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700675 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700676
677 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600678 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700679 *cmds++ = 0x00003F00;
680
Jordan Crouse084427d2011-07-28 08:37:58 -0600681 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700682 *cmds++ = adreno_encode_istore_size(adreno_dev)
683 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700684
Jordan Crousea78c9172011-07-11 13:14:09 -0600685 /* load the patched vertex shader stream */
686 cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN);
687
688 /* Load the patched fragment shader stream */
689 cmds =
690 program_shader(cmds, 1, gmem2sys_frag_pgm, GMEM2SYS_FRAG_PGM_LEN);
691
692 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600693 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600694 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600695 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600696 *cmds++ = 0x10018001;
697 else
698 *cmds++ = 0x10010001;
699 *cmds++ = 0x00000008;
700
701 /* resolve */
702
703 /* PA_CL_VTE_CNTL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600704 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600705 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600706 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
707 *cmds++ = 0x00000b00;
708
709 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600710 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600711 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600712 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
713
714 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
715 * Base=gmem_base
716 */
717 /* gmem base assumed 4K aligned. */
718 BUG_ON(tmp_ctx.gmem_base & 0xFFF);
719 *cmds++ =
720 (shadow->
721 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
722
723 /* disable Z */
Jordan Crouse084427d2011-07-28 08:37:58 -0600724 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600725 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600726 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600727 *cmds++ = 0x08;
728 else
729 *cmds++ = 0;
730
731 /* set REG_PA_SU_SC_MODE_CNTL
732 * Front_ptype = draw triangles
733 * Back_ptype = draw triangles
734 * Provoking vertex = last
735 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600736 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600737 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600738 *cmds++ = 0x00080240;
739
740 /* Use maximum scissor values -- quad vertices already have the
741 * correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600742 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600743 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600744 *cmds++ = (0 << 16) | 0;
745 *cmds++ = (0x1fff << 16) | (0x1fff);
Jordan Crouse084427d2011-07-28 08:37:58 -0600746 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600747 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600748 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
749 *cmds++ = (0x1fff << 16) | (0x1fff);
750
751 /* load the viewport so that z scale = clear depth and
752 * z offset = 0.0f
753 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600754 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600755 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600756 *cmds++ = 0xbf800000; /* -1.0f */
757 *cmds++ = 0x0;
758
Jordan Crouse084427d2011-07-28 08:37:58 -0600759 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600760 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600761 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
762
Jordan Crouse084427d2011-07-28 08:37:58 -0600763 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600764 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600765 *cmds++ = 0xffffffff;
766
Jordan Crouse084427d2011-07-28 08:37:58 -0600767 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600768 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -0600769 *cmds++ = 0x00000000;
770 *cmds++ = 0x00000000;
771
772 /* load the stencil ref value
773 * $AAM - do this later
774 */
775
776 /* load the COPY state */
Jordan Crouse084427d2011-07-28 08:37:58 -0600777 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600778 *cmds++ = CP_REG(REG_RB_COPY_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600779 *cmds++ = 0; /* RB_COPY_CONTROL */
780 *cmds++ = addr & 0xfffff000; /* RB_COPY_DEST_BASE */
781 *cmds++ = shadow->pitch >> 5; /* RB_COPY_DEST_PITCH */
782
783 /* Endian=none, Linear, Format=RGBA8888,Swap=0,!Dither,
784 * MaskWrite:R=G=B=A=1
785 */
786 *cmds++ = 0x0003c008 |
787 (shadow->format << RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT);
788 /* Make sure we stay in offsetx field. */
789 BUG_ON(offset & 0xfffff000);
790 *cmds++ = offset;
791
Jordan Crouse084427d2011-07-28 08:37:58 -0600792 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600793 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600794 *cmds++ = 0x6; /* EDRAM copy */
795
Jordan Crouse084427d2011-07-28 08:37:58 -0600796 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600797 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600798 *cmds++ = 0x00010000;
799
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600800 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600801 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600802 *cmds++ = 0;
803
Jordan Crouse084427d2011-07-28 08:37:58 -0600804 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700805 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600806 *cmds++ = 0x0000000;
807
Jordan Crouse084427d2011-07-28 08:37:58 -0600808 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600809 *cmds++ = 0; /* viz query info. */
810 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
811 *cmds++ = 0x00004088;
812 *cmds++ = 3; /* NumIndices=3 */
813 } else {
814 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -0600815 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600816 *cmds++ = 0; /* viz query info. */
817 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
818 *cmds++ = 0x00030088;
819 }
820
821 /* create indirect buffer command for above command sequence */
822 create_ib1(drawctxt, shadow->gmem_save, start, cmds);
823
824 return cmds;
825}
826
827/* context restore */
828
829/*copy colour, depth, & stencil buffers from system memory to graphics memory*/
830static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
831 struct adreno_context *drawctxt,
832 struct gmem_shadow_t *shadow)
833{
834 unsigned int *cmds = shadow->gmem_restore_commands;
835 unsigned int *start = cmds;
836
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700837 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
838 /* Store TP0_CHICKEN register */
839 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
840 *cmds++ = REG_TP0_CHICKEN;
841 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600842
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700843 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
844 *cmds++ = 0;
845 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600846
847 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600848 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600849 *cmds++ = 0x00000000;
850
851 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600852 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600853 *cmds++ = 0x00000000;
854 /* shader constants */
855
856 /* vertex buffer constants */
Jordan Crouse084427d2011-07-28 08:37:58 -0600857 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
Jordan Crousea78c9172011-07-11 13:14:09 -0600858
859 *cmds++ = (0x1 << 16) | (9 * 6);
860 /* valid(?) vtx constant flag & addr */
861 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
862 /* limit = 12 dwords */
863 *cmds++ = 0x00000030;
864 /* valid(?) vtx constant flag & addr */
865 *cmds++ = shadow->quad_texcoords.gpuaddr | 0x3;
866 /* limit = 8 dwords */
867 *cmds++ = 0x00000020;
868 *cmds++ = 0;
869 *cmds++ = 0;
870
871 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600872 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600873 *cmds++ = 0x1;
874
875 cmds = program_shader(cmds, 0, sys2gmem_vtx_pgm, SYS2GMEM_VTX_PGM_LEN);
876
Tarun Karra16346b02011-07-24 15:04:26 -0700877 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600878 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700879 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700880
881 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600882 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700883 *cmds++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
884
Jordan Crouse084427d2011-07-28 08:37:58 -0600885 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700886 *cmds++ = adreno_encode_istore_size(adreno_dev)
887 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700888
Jordan Crousea78c9172011-07-11 13:14:09 -0600889 /* Load the patched fragment shader stream */
890 cmds =
891 program_shader(cmds, 1, sys2gmem_frag_pgm, SYS2GMEM_FRAG_PGM_LEN);
892
893 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600894 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600895 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600896 *cmds++ = 0x10030002;
897 *cmds++ = 0x00000008;
898
Jordan Crouse084427d2011-07-28 08:37:58 -0600899 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600900 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600901 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
902
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600903 if (!adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600904 /* PA_SC_VIZ_QUERY */
Jordan Crouse084427d2011-07-28 08:37:58 -0600905 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600906 *cmds++ = CP_REG(REG_PA_SC_VIZ_QUERY);
Jordan Crousea78c9172011-07-11 13:14:09 -0600907 *cmds++ = 0x0; /*REG_PA_SC_VIZ_QUERY */
908 }
909
910 /* RB_COLORCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600911 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600912 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600913 *cmds++ = 0x00000c20;
914
Jordan Crouse084427d2011-07-28 08:37:58 -0600915 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600916 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600917 *cmds++ = 0x00ffffff; /* mmVGT_MAX_VTX_INDX */
918 *cmds++ = 0x0; /* mmVGT_MIN_VTX_INDX */
919 *cmds++ = 0x00000000; /* mmVGT_INDX_OFFSET */
920
Jordan Crouse084427d2011-07-28 08:37:58 -0600921 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600922 *cmds++ = CP_REG(REG_VGT_VERTEX_REUSE_BLOCK_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600923 *cmds++ = 0x00000002; /* mmVGT_VERTEX_REUSE_BLOCK_CNTL */
924 *cmds++ = 0x00000002; /* mmVGT_OUT_DEALLOC_CNTL */
925
Jordan Crouse084427d2011-07-28 08:37:58 -0600926 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600927 *cmds++ = CP_REG(REG_SQ_INTERPOLATOR_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600928 *cmds++ = 0xffffffff; /* mmSQ_INTERPOLATOR_CNTL */
929
Jordan Crouse084427d2011-07-28 08:37:58 -0600930 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600931 *cmds++ = CP_REG(REG_PA_SC_AA_CONFIG);
Jordan Crousea78c9172011-07-11 13:14:09 -0600932 *cmds++ = 0x00000000; /* REG_PA_SC_AA_CONFIG */
933
934 /* set REG_PA_SU_SC_MODE_CNTL
935 * Front_ptype = draw triangles
936 * Back_ptype = draw triangles
937 * Provoking vertex = last
938 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600939 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600940 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600941 *cmds++ = 0x00080240;
942
943 /* texture constants */
944 *cmds++ =
Jordan Crouse084427d2011-07-28 08:37:58 -0600945 cp_type3_packet(CP_SET_CONSTANT, (SYS2GMEM_TEX_CONST_LEN + 1));
Jordan Crousea78c9172011-07-11 13:14:09 -0600946 *cmds++ = (0x1 << 16) | (0 * 6);
947 memcpy(cmds, sys2gmem_tex_const, SYS2GMEM_TEX_CONST_LEN << 2);
948 cmds[0] |= (shadow->pitch >> 5) << 22;
949 cmds[1] |=
950 shadow->gmemshadow.gpuaddr | surface_format_table[shadow->format];
951 cmds[2] |= (shadow->width - 1) | (shadow->height - 1) << 13;
952 cmds += SYS2GMEM_TEX_CONST_LEN;
953
954 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600955 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600956 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600957 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
958
959 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
960 * Base=gmem_base
961 */
962 *cmds++ =
963 (shadow->
964 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
965
966 /* RB_DEPTHCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600967 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600968 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600969
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600970 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600971 *cmds++ = 8; /* disable Z */
972 else
973 *cmds++ = 0; /* disable Z */
974
975 /* Use maximum scissor values -- quad vertices already
976 * have the correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600977 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600978 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600979 *cmds++ = (0 << 16) | 0;
980 *cmds++ = ((0x1fff) << 16) | 0x1fff;
Jordan Crouse084427d2011-07-28 08:37:58 -0600981 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600982 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600983 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
984 *cmds++ = ((0x1fff) << 16) | 0x1fff;
985
Jordan Crouse084427d2011-07-28 08:37:58 -0600986 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600987 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600988 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
989 *cmds++ = 0x00000b00;
990
991 /*load the viewport so that z scale = clear depth and z offset = 0.0f */
Jordan Crouse084427d2011-07-28 08:37:58 -0600992 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600993 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600994 *cmds++ = 0xbf800000;
995 *cmds++ = 0x0;
996
Jordan Crouse084427d2011-07-28 08:37:58 -0600997 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600998 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600999 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
1000
Jordan Crouse084427d2011-07-28 08:37:58 -06001001 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001002 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001003 *cmds++ = 0xffffffff;
1004
Jordan Crouse084427d2011-07-28 08:37:58 -06001005 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001006 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -06001007 *cmds++ = 0x00000000;
1008 *cmds++ = 0x00000000;
1009
1010 /* load the stencil ref value
1011 * $AAM - do this later
1012 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001013 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001014 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001015 /* draw pixels with color and depth/stencil component */
1016 *cmds++ = 0x4;
1017
Jordan Crouse084427d2011-07-28 08:37:58 -06001018 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001019 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001020 *cmds++ = 0x00010000;
1021
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001022 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001023 *cmds++ = cp_type3_packet(CP_SET_DRAW_INIT_FLAGS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001024 *cmds++ = 0;
1025
Jordan Crouse084427d2011-07-28 08:37:58 -06001026 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001027 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001028 *cmds++ = 0x0000000;
1029
Jordan Crouse084427d2011-07-28 08:37:58 -06001030 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001031 *cmds++ = 0; /* viz query info. */
1032 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
1033 *cmds++ = 0x00004088;
1034 *cmds++ = 3; /* NumIndices=3 */
1035 } else {
1036 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -06001037 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001038 *cmds++ = 0; /* viz query info. */
1039 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
1040 *cmds++ = 0x00030088;
1041 }
1042
1043 /* create indirect buffer command for above command sequence */
1044 create_ib1(drawctxt, shadow->gmem_restore, start, cmds);
1045
1046 return cmds;
1047}
1048
Jordan Crousea78c9172011-07-11 13:14:09 -06001049static void build_regrestore_cmds(struct adreno_device *adreno_dev,
1050 struct adreno_context *drawctxt)
1051{
1052 unsigned int *start = tmp_ctx.cmd;
1053 unsigned int *cmd = start;
1054
1055 unsigned int i = 0;
1056 unsigned int reg_array_size = 0;
1057 const unsigned int *ptr_register_ranges;
1058
Jordan Crouse084427d2011-07-28 08:37:58 -06001059 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001060 *cmd++ = 0;
1061
1062 /* H/W Registers */
Jordan Crouse084427d2011-07-28 08:37:58 -06001063 /* deferred cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, ???); */
Jordan Crousea78c9172011-07-11 13:14:09 -06001064 cmd++;
1065#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1066 /* Force mismatch */
1067 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1;
1068#else
1069 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1070#endif
1071
1072 /* Based on chip id choose the registers ranges*/
Jeremy Gebben99105cb2011-08-31 10:23:05 -07001073 if (adreno_is_a220(adreno_dev)) {
1074 ptr_register_ranges = register_ranges_a220;
1075 reg_array_size = ARRAY_SIZE(register_ranges_a220);
1076 } else if (adreno_is_a225(adreno_dev)) {
1077 ptr_register_ranges = register_ranges_a225;
1078 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -06001079 } else {
1080 ptr_register_ranges = register_ranges_a20x;
1081 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
1082 }
1083
1084
1085 for (i = 0; i < (reg_array_size/2); i++) {
1086 cmd = reg_range(cmd, ptr_register_ranges[i*2],
1087 ptr_register_ranges[i*2+1]);
1088 }
1089
1090 /* Now we know how many register blocks we have, we can compute command
1091 * length
1092 */
1093 start[2] =
Jordan Crouse084427d2011-07-28 08:37:58 -06001094 cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, (cmd - start) - 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001095 /* Enable shadowing for the entire register block. */
1096#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1097 start[4] |= (0 << 24) | (4 << 16); /* Disable shadowing. */
1098#else
1099 start[4] |= (1 << 24) | (4 << 16);
1100#endif
1101
1102 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -06001103 *cmd++ = cp_type0_packet(REG_SQ_GPR_MANAGEMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001104 tmp_ctx.reg_values[0] = virt2gpu(cmd, &drawctxt->gpustate);
1105 *cmd++ = 0x00040400;
1106
Jordan Crouse084427d2011-07-28 08:37:58 -06001107 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001108 *cmd++ = 0;
Jordan Crouse084427d2011-07-28 08:37:58 -06001109 *cmd++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001110 tmp_ctx.reg_values[1] = virt2gpu(cmd, &drawctxt->gpustate);
1111 *cmd++ = 0x00000000;
1112
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001113 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001114 unsigned int i;
1115 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001116 for (i = REG_A220_VSC_BIN_SIZE; i <=
1117 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001118 *cmd++ = cp_type0_packet(i, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001119 tmp_ctx.reg_values[j] = virt2gpu(cmd,
1120 &drawctxt->gpustate);
1121 *cmd++ = 0x00000000;
1122 j++;
1123 }
1124 }
1125
1126 /* ALU Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001127 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001128 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
1129#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1130 *cmd++ = (0 << 24) | (0 << 16) | 0; /* Disable shadowing */
1131#else
1132 *cmd++ = (1 << 24) | (0 << 16) | 0;
1133#endif
1134 *cmd++ = ALU_CONSTANTS;
1135
1136 /* Texture Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001137 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001138 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
1139#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1140 /* Disable shadowing */
1141 *cmd++ = (0 << 24) | (1 << 16) | 0;
1142#else
1143 *cmd++ = (1 << 24) | (1 << 16) | 0;
1144#endif
1145 *cmd++ = TEX_CONSTANTS;
1146
1147 /* Boolean Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001148 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + BOOL_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001149 *cmd++ = (2 << 16) | 0;
1150
1151 /* the next BOOL_CONSTANT dwords is the shadow area for
1152 * boolean constants.
1153 */
1154 tmp_ctx.bool_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1155 cmd += BOOL_CONSTANTS;
1156
1157 /* Loop Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001158 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + LOOP_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001159 *cmd++ = (3 << 16) | 0;
1160
1161 /* the next LOOP_CONSTANTS dwords is the shadow area for
1162 * loop constants.
1163 */
1164 tmp_ctx.loop_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1165 cmd += LOOP_CONSTANTS;
1166
1167 /* create indirect buffer command for above command sequence */
1168 create_ib1(drawctxt, drawctxt->reg_restore, start, cmd);
1169
1170 tmp_ctx.cmd = cmd;
1171}
1172
Jordan Crousea78c9172011-07-11 13:14:09 -06001173static void
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001174build_shader_save_restore_cmds(struct adreno_device *adreno_dev,
1175 struct adreno_context *drawctxt)
Jordan Crousea78c9172011-07-11 13:14:09 -06001176{
1177 unsigned int *cmd = tmp_ctx.cmd;
1178 unsigned int *save, *restore, *fixup;
Jordan Crousea78c9172011-07-11 13:14:09 -06001179 unsigned int *startSizeVtx, *startSizePix, *startSizeShared;
Jordan Crousea78c9172011-07-11 13:14:09 -06001180 unsigned int *partition1;
1181 unsigned int *shaderBases, *partition2;
1182
Jordan Crousea78c9172011-07-11 13:14:09 -06001183 /* compute vertex, pixel and shared instruction shadow GPU addresses */
1184 tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001185 tmp_ctx.shader_pixel = tmp_ctx.shader_vertex
1186 + _shader_shadow_size(adreno_dev);
1187 tmp_ctx.shader_shared = tmp_ctx.shader_pixel
1188 + _shader_shadow_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001189
1190 /* restore shader partitioning and instructions */
1191
1192 restore = cmd; /* start address */
1193
1194 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -06001195 *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001196 *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
1197
1198 /* Restore previous shader vertex & pixel instruction bases. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001199 *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001200 shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */
1201
1202 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001203 *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001204 partition1 = cmd++; /* TBD #4a: partition info (from save) */
1205
Jordan Crousea78c9172011-07-11 13:14:09 -06001206 /* load vertex shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001207 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001208 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1209 startSizeVtx = cmd++; /* TBD #1: start/size (from save) */
1210
1211 /* load pixel shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001212 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001213 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1214 startSizePix = cmd++; /* TBD #2: start/size (from save) */
1215
1216 /* load shared shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001217 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001218 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1219 startSizeShared = cmd++; /* TBD #3: start/size (from save) */
Jordan Crousea78c9172011-07-11 13:14:09 -06001220
1221 /* create indirect buffer command for above command sequence */
1222 create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd);
1223
1224 /*
1225 * fixup SET_SHADER_BASES data
1226 *
1227 * since self-modifying PM4 code is being used here, a seperate
1228 * command buffer is used for this fixup operation, to ensure the
1229 * commands are not read by the PM4 engine before the data fields
1230 * have been written.
1231 */
1232
1233 fixup = cmd; /* start address */
1234
1235 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001236 *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001237 partition2 = cmd++; /* TBD #4b: partition info (from save) */
1238
1239 /* mask off unused bits, then OR with shader instruction memory size */
Jordan Crouse084427d2011-07-28 08:37:58 -06001240 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001241 *cmd++ = REG_SCRATCH_REG2;
1242 /* AND off invalid bits. */
1243 *cmd++ = 0x0FFF0FFF;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001244 /* OR in instruction memory size. */
1245 *cmd++ = adreno_encode_istore_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001246
1247 /* write the computed value to the SET_SHADER_BASES data field */
Jordan Crouse084427d2011-07-28 08:37:58 -06001248 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001249 *cmd++ = REG_SCRATCH_REG2;
1250 /* TBD #5: shader bases (to restore) */
1251 *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate);
1252
1253 /* create indirect buffer command for above command sequence */
1254 create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd);
1255
1256 /* save shader partitioning and instructions */
1257
1258 save = cmd; /* start address */
1259
Jordan Crouse084427d2011-07-28 08:37:58 -06001260 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001261 *cmd++ = 0;
1262
1263 /* fetch the SQ_INST_STORE_MANAGMENT register value,
1264 * store the value in the data fields of the SET_CONSTANT commands
1265 * above.
1266 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001267 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001268 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1269 /* TBD #4a: partition info (to restore) */
1270 *cmd++ = virt2gpu(partition1, &drawctxt->gpustate);
Jordan Crouse084427d2011-07-28 08:37:58 -06001271 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001272 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1273 /* TBD #4b: partition info (to fixup) */
1274 *cmd++ = virt2gpu(partition2, &drawctxt->gpustate);
1275
Jordan Crousea78c9172011-07-11 13:14:09 -06001276
1277 /* store the vertex shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001278 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001279 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1280 /* TBD #1: start/size (to restore) */
1281 *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate);
1282
1283 /* store the pixel shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001284 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001285 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1286 /* TBD #2: start/size (to restore) */
1287 *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate);
1288
1289 /* store the shared shader instructions if vertex base is nonzero */
1290
Jordan Crouse084427d2011-07-28 08:37:58 -06001291 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001292 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1293 /* TBD #3: start/size (to restore) */
1294 *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate);
1295
Jordan Crousea78c9172011-07-11 13:14:09 -06001296
Jordan Crouse084427d2011-07-28 08:37:58 -06001297 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001298 *cmd++ = 0;
1299
1300 /* create indirect buffer command for above command sequence */
1301 create_ib1(drawctxt, drawctxt->shader_save, save, cmd);
1302
1303 tmp_ctx.cmd = cmd;
1304}
1305
1306/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001307static int a2xx_create_gpustate_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001308 struct adreno_context *drawctxt)
1309{
Jordan Crousea78c9172011-07-11 13:14:09 -06001310 drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW;
1311
Jordan Crousea78c9172011-07-11 13:14:09 -06001312 /* build indirect command buffers to save & restore regs/constants */
Jordan Crousea78c9172011-07-11 13:14:09 -06001313 build_regrestore_cmds(adreno_dev, drawctxt);
1314 build_regsave_cmds(adreno_dev, drawctxt);
1315
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001316 build_shader_save_restore_cmds(adreno_dev, drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001317
Jordan Crousea78c9172011-07-11 13:14:09 -06001318 return 0;
1319}
1320
1321/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001322static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001323 struct adreno_context *drawctxt)
1324{
1325 int result;
1326
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001327 calc_gmemsize(&drawctxt->context_gmem_shadow,
1328 adreno_dev->gmemspace.sizebytes);
Jordan Crousea78c9172011-07-11 13:14:09 -06001329 tmp_ctx.gmem_base = adreno_dev->gmemspace.gpu_base;
1330
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
1337 /* we've allocated the shadow, when swapped out, GMEM must be saved. */
1338 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_GMEM_SAVE;
1339
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 */
1513 kgsl_mmu_setstate(device, device->mmu.defaultpagetable);
1514 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 +
1523 KGSL_DEVICE_MEMSTORE_OFFSET(current_context);
1524 cmds[4] = (unsigned int) context;
Jordan Crousee0ea7622012-01-24 09:32:04 -07001525 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
Jordan Crousea78c9172011-07-11 13:14:09 -06001526 kgsl_mmu_setstate(device, context->pagetable);
1527
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 */
1650 unsigned int enableflag = 0;
1651 kgsl_sharedmem_writel(&rb->device->memstore,
1652 KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
1653 enableflag);
1654 wmb();
1655 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
1656 }
1657
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001658 for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
1659 if (status & kgsl_cp_error_irqs[i].mask) {
1660 KGSL_CMD_CRIT(rb->device, "%s\n",
1661 kgsl_cp_error_irqs[i].message);
1662 /*
1663 * on fatal errors, turn off the interrupts to
1664 * avoid storming. This has the side effect of
1665 * forcing a PM dump when the timestamp times out
1666 */
Jordan Crousea78c9172011-07-11 13:14:09 -06001667
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001668 kgsl_pwrctrl_irq(rb->device, KGSL_PWRFLAGS_OFF);
1669 }
1670 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001671
1672 /* only ack bits we understand */
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001673 status &= CP_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001674 adreno_regwrite(device, REG_CP_INT_ACK, status);
1675
1676 if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
1677 KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
Jordan Crouse1bf80aa2011-10-12 16:57:47 -06001678 queue_work(device->work_queue, &device->ts_expired_ws);
Jordan Crousea78c9172011-07-11 13:14:09 -06001679 wake_up_interruptible_all(&device->wait_queue);
1680 atomic_notifier_call_chain(&(device->ts_notifier_list),
1681 device->id,
1682 NULL);
1683 }
1684}
1685
1686static void a2xx_rbbm_intrcallback(struct kgsl_device *device)
1687{
1688 unsigned int status = 0;
1689 unsigned int rderr = 0;
1690
1691 adreno_regread(device, REG_RBBM_INT_STATUS, &status);
1692
1693 if (status & RBBM_INT_CNTL__RDERR_INT_MASK) {
1694 union rbbm_read_error_u rerr;
1695 adreno_regread(device, REG_RBBM_READ_ERROR, &rderr);
1696 rerr.val = rderr;
1697 if (rerr.f.read_address == REG_CP_INT_STATUS &&
1698 rerr.f.read_error &&
1699 rerr.f.read_requester)
1700 KGSL_DRV_WARN(device,
1701 "rbbm read error interrupt: %08x\n", rderr);
1702 else
1703 KGSL_DRV_CRIT(device,
1704 "rbbm read error interrupt: %08x\n", rderr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001705 }
1706
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001707 status &= RBBM_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001708 adreno_regwrite(device, REG_RBBM_INT_ACK, status);
1709}
1710
1711irqreturn_t a2xx_irq_handler(struct adreno_device *adreno_dev)
1712{
1713 struct kgsl_device *device = &adreno_dev->dev;
1714 irqreturn_t result = IRQ_NONE;
1715 unsigned int status;
1716
1717 adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
1718
1719 if (status & MASTER_INT_SIGNAL__MH_INT_STAT) {
1720 kgsl_mh_intrcallback(device);
1721 result = IRQ_HANDLED;
1722 }
1723
1724 if (status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1725 a2xx_cp_intrcallback(device);
1726 result = IRQ_HANDLED;
1727 }
1728
1729 if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) {
1730 a2xx_rbbm_intrcallback(device);
1731 result = IRQ_HANDLED;
1732 }
1733
1734 return result;
1735}
1736
1737static void a2xx_irq_control(struct adreno_device *adreno_dev, int state)
1738{
1739 struct kgsl_device *device = &adreno_dev->dev;
1740
1741 if (state) {
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001742 adreno_regwrite(device, REG_RBBM_INT_CNTL, RBBM_INT_MASK);
1743 adreno_regwrite(device, REG_CP_INT_CNTL, CP_INT_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001744 adreno_regwrite(device, MH_INTERRUPT_MASK, KGSL_MMU_INT_MASK);
1745 } else {
1746 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1747 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1748 adreno_regwrite(device, MH_INTERRUPT_MASK, 0);
1749 }
Jordan Crouseb58e61b2011-08-08 13:25:36 -06001750
1751 /* Force the writes to post before touching the IRQ line */
1752 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001753}
1754
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001755static void a2xx_rb_init(struct adreno_device *adreno_dev,
1756 struct adreno_ringbuffer *rb)
1757{
1758 unsigned int *cmds, cmds_gpu;
1759
1760 /* ME_INIT */
1761 cmds = adreno_ringbuffer_allocspace(rb, 19);
1762 cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19);
1763
1764 GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 18));
1765 /* All fields present (bits 9:0) */
1766 GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff);
1767 /* Disable/Enable Real-Time Stream processing (present but ignored) */
1768 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1769 /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
1770 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1771
1772 GSL_RB_WRITE(cmds, cmds_gpu,
1773 SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
1774 GSL_RB_WRITE(cmds, cmds_gpu,
1775 SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
1776 GSL_RB_WRITE(cmds, cmds_gpu,
1777 SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
1778 GSL_RB_WRITE(cmds, cmds_gpu,
1779 SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
1780 GSL_RB_WRITE(cmds, cmds_gpu,
1781 SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
1782 GSL_RB_WRITE(cmds, cmds_gpu,
1783 SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
1784 GSL_RB_WRITE(cmds, cmds_gpu,
1785 SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
1786 GSL_RB_WRITE(cmds, cmds_gpu,
1787 SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
1788
1789 /* Instruction memory size: */
1790 GSL_RB_WRITE(cmds, cmds_gpu,
1791 (adreno_encode_istore_size(adreno_dev)
1792 | adreno_dev->pix_shader_start));
1793 /* Maximum Contexts */
1794 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
1795 /* Write Confirm Interval and The CP will wait the
1796 * wait_interval * 16 clocks between polling */
1797 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1798
1799 /* NQ and External Memory Swap */
1800 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1801 /* Protected mode error checking */
1802 GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL);
1803 /* Disable header dumping and Header dump address */
1804 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1805 /* Header dump size */
1806 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1807
1808 adreno_ringbuffer_submit(rb);
1809}
1810
1811static unsigned int a2xx_busy_cycles(struct adreno_device *adreno_dev)
1812{
1813 struct kgsl_device *device = &adreno_dev->dev;
1814 unsigned int reg, val;
1815
1816 /* Freeze the counter */
1817 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1818 REG_PERF_MODE_CNT | REG_PERF_STATE_FREEZE);
1819
1820 /* Get the value */
1821 adreno_regread(device, REG_RBBM_PERFCOUNTER1_LO, &val);
1822
1823 /* Reset the counter */
1824 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1825 REG_PERF_MODE_CNT | REG_PERF_STATE_RESET);
1826
1827 /* Re-Enable the performance monitors */
1828 adreno_regread(device, REG_RBBM_PM_OVERRIDE2, &reg);
1829 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, (reg | 0x40));
1830 adreno_regwrite(device, REG_RBBM_PERFCOUNTER1_SELECT, 0x1);
1831 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1832 REG_PERF_MODE_CNT | REG_PERF_STATE_ENABLE);
1833
1834 return val;
1835}
1836
1837static void a2xx_gmeminit(struct adreno_device *adreno_dev)
1838{
1839 struct kgsl_device *device = &adreno_dev->dev;
1840 union reg_rb_edram_info rb_edram_info;
1841 unsigned int gmem_size;
1842 unsigned int edram_value = 0;
1843
1844 /* make sure edram range is aligned to size */
1845 BUG_ON(adreno_dev->gmemspace.gpu_base &
1846 (adreno_dev->gmemspace.sizebytes - 1));
1847
1848 /* get edram_size value equivalent */
1849 gmem_size = (adreno_dev->gmemspace.sizebytes >> 14);
1850 while (gmem_size >>= 1)
1851 edram_value++;
1852
1853 rb_edram_info.val = 0;
1854
1855 rb_edram_info.f.edram_size = edram_value;
1856 rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */
1857
1858 /* must be aligned to size */
1859 rb_edram_info.f.edram_range = (adreno_dev->gmemspace.gpu_base >> 14);
1860
1861 adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
1862}
1863
1864static void a2xx_start(struct adreno_device *adreno_dev)
1865{
1866 struct kgsl_device *device = &adreno_dev->dev;
1867 int init_reftimestamp = 0x7fffffff;
1868
1869 /*
1870 * We need to make sure all blocks are powered up and clocked
1871 * before issuing a soft reset. The overrides will then be
1872 * turned off (set to 0)
1873 */
1874 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe);
1875 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff);
1876
1877 /*
1878 * Only reset CP block if all blocks have previously been
1879 * reset
1880 */
1881 if (!(device->flags & KGSL_FLAGS_SOFT_RESET) ||
1882 !adreno_is_a22x(adreno_dev)) {
1883 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1884 0xFFFFFFFF);
1885 device->flags |= KGSL_FLAGS_SOFT_RESET;
1886 } else {
1887 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1888 0x00000001);
1889 }
1890 /*
1891 * The core is in an indeterminate state until the reset
1892 * completes after 30ms.
1893 */
1894 msleep(30);
1895
1896 adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000);
1897
1898 if (adreno_is_a225(adreno_dev)) {
1899 /* Enable large instruction store for A225 */
1900 adreno_regwrite(device, REG_SQ_FLOW_CONTROL,
1901 0x18000000);
1902 }
1903
1904 adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
1905
1906 adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
1907 adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
1908
1909 if (cpu_is_msm8960() || cpu_is_msm8930())
1910 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
1911 else
1912 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
1913
1914 if (!adreno_is_a22x(adreno_dev))
1915 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0);
1916 else
1917 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
1918
1919 kgsl_sharedmem_set(&device->memstore, 0, 0, device->memstore.size);
1920
1921 kgsl_sharedmem_writel(&device->memstore,
1922 KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
1923 init_reftimestamp);
1924
1925 adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
1926
1927 /* Make sure interrupts are disabled */
1928 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1929 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1930 adreno_regwrite(device, REG_SQ_INT_CNTL, 0);
1931
1932 if (adreno_is_a22x(adreno_dev))
1933 adreno_dev->gmemspace.sizebytes = SZ_512K;
1934 else
1935 adreno_dev->gmemspace.sizebytes = SZ_256K;
1936
1937 a2xx_gmeminit(adreno_dev);
1938}
1939
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001940/* Defined in adreno_a2xx_snapshot.c */
1941void *a2xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
1942 int *remain, int hang);
1943
Jordan Crousea78c9172011-07-11 13:14:09 -06001944struct adreno_gpudev adreno_a2xx_gpudev = {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001945 .reg_rbbm_status = REG_RBBM_STATUS,
1946 .reg_cp_pfp_ucode_addr = REG_CP_PFP_UCODE_ADDR,
1947 .reg_cp_pfp_ucode_data = REG_CP_PFP_UCODE_DATA,
1948
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001949 .ctxt_create = a2xx_drawctxt_create,
1950 .ctxt_save = a2xx_drawctxt_save,
1951 .ctxt_restore = a2xx_drawctxt_restore,
Jordan Crousea78c9172011-07-11 13:14:09 -06001952 .irq_handler = a2xx_irq_handler,
1953 .irq_control = a2xx_irq_control,
Jordan Crouse156cfbc2012-01-24 09:32:04 -07001954 .snapshot = a2xx_snapshot,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001955 .rb_init = a2xx_rb_init,
1956 .busy_cycles = a2xx_busy_cycles,
1957 .start = a2xx_start,
Jordan Crousea78c9172011-07-11 13:14:09 -06001958};