blob: c633991999acd29bed430b8d2f11bb9b7e1774dd [file] [log] [blame]
Duy Truonge833aca2013-02-12 13:35:08 -08001/* Copyright (c) 2002,2007-2012, The Linux Foundation. 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>
Steve Mucklef132c6c2012-06-06 18:30:57 -070015#include <linux/sched.h>
Jordan Crouseb4d31bd2012-02-01 22:11:12 -070016#include <mach/socinfo.h>
17
Jordan Crousea78c9172011-07-11 13:14:09 -060018#include "kgsl.h"
19#include "kgsl_sharedmem.h"
20#include "kgsl_cffdump.h"
21#include "adreno.h"
Norman Geed7402ff2011-10-28 08:51:11 -060022#include "adreno_a2xx_trace.h"
Jordan Crousea78c9172011-07-11 13:14:09 -060023
24/*
Jordan Crousef7597bf2012-01-03 08:43:34 -070025 * These are the registers that are dumped with GPU snapshot
26 * and postmortem. The lists are dword offset pairs in the
27 * form of {start offset, end offset} inclusive.
28 */
29
30/* A200, A205 */
31const unsigned int a200_registers[] = {
32 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
33 0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
34 0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
35 0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
36 0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
37 0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
38 0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
39 0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
40 0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A43, 0x0A45, 0x0A45,
41 0x0A4E, 0x0A4F, 0x0C2C, 0x0C2C, 0x0C30, 0x0C30, 0x0C38, 0x0C3C,
42 0x0C40, 0x0C40, 0x0C44, 0x0C44, 0x0C80, 0x0C86, 0x0C88, 0x0C94,
43 0x0C99, 0x0C9A, 0x0CA4, 0x0CA5, 0x0D00, 0x0D03, 0x0D06, 0x0D06,
44 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
45 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
46 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
47 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x0F0C, 0x0F0C, 0x0F0E, 0x0F12,
48 0x0F26, 0x0F2A, 0x0F2C, 0x0F2C, 0x2000, 0x2002, 0x2006, 0x200F,
49 0x2080, 0x2082, 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184,
50 0x21F5, 0x21F7, 0x2200, 0x2208, 0x2280, 0x2283, 0x2293, 0x2294,
51 0x2300, 0x2308, 0x2312, 0x2312, 0x2316, 0x231D, 0x2324, 0x2326,
52 0x2380, 0x2383, 0x2400, 0x2402, 0x2406, 0x240F, 0x2480, 0x2482,
53 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7,
54 0x2600, 0x2608, 0x2680, 0x2683, 0x2693, 0x2694, 0x2700, 0x2708,
55 0x2712, 0x2712, 0x2716, 0x271D, 0x2724, 0x2726, 0x2780, 0x2783,
56 0x4000, 0x4003, 0x4800, 0x4805, 0x4900, 0x4900, 0x4908, 0x4908,
57};
58
Jordan Crousef7597bf2012-01-03 08:43:34 -070059const 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
Jeremy Gebben6be78d12012-03-07 16:02:47 -070088const unsigned int a225_registers[] = {
89 0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
90 0x0046, 0x0047, 0x013C, 0x013C, 0x0140, 0x014F, 0x01C0, 0x01C1,
91 0x01C3, 0x01C8, 0x01D5, 0x01D9, 0x01DC, 0x01DD, 0x01EA, 0x01EA,
92 0x01EE, 0x01F3, 0x01F6, 0x01F7, 0x01FC, 0x01FF, 0x0391, 0x0392,
93 0x039B, 0x039E, 0x03B2, 0x03B5, 0x03B7, 0x03B7, 0x03F8, 0x03FB,
94 0x0440, 0x0440, 0x0443, 0x0444, 0x044B, 0x044B, 0x044D, 0x044F,
95 0x0452, 0x0452, 0x0454, 0x045B, 0x047F, 0x047F, 0x0578, 0x0587,
96 0x05C9, 0x05C9, 0x05D0, 0x05D0, 0x0601, 0x0604, 0x0606, 0x0609,
97 0x060B, 0x060E, 0x0613, 0x0614, 0x0A29, 0x0A2B, 0x0A2F, 0x0A31,
98 0x0A40, 0x0A40, 0x0A42, 0x0A43, 0x0A45, 0x0A45, 0x0A4E, 0x0A4F,
99 0x0C01, 0x0C1D, 0x0C30, 0x0C30, 0x0C38, 0x0C39, 0x0C3C, 0x0C3C,
100 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03, 0x0D05, 0x0D06,
101 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
102 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
103 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
104 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x200F, 0x2080, 0x2082,
105 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7,
106 0x2200, 0x2202, 0x2204, 0x2206, 0x2208, 0x2210, 0x2220, 0x2222,
107 0x2280, 0x2282, 0x2294, 0x2294, 0x2297, 0x2297, 0x2300, 0x230A,
108 0x2312, 0x2312, 0x2315, 0x2316, 0x2318, 0x231D, 0x2324, 0x2326,
109 0x2340, 0x2357, 0x2360, 0x2360, 0x2380, 0x2383, 0x2400, 0x240F,
110 0x2480, 0x2482, 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584,
111 0x25F5, 0x25F7, 0x2600, 0x2602, 0x2604, 0x2606, 0x2608, 0x2610,
112 0x2620, 0x2622, 0x2680, 0x2682, 0x2694, 0x2694, 0x2697, 0x2697,
113 0x2700, 0x270A, 0x2712, 0x2712, 0x2715, 0x2716, 0x2718, 0x271D,
114 0x2724, 0x2726, 0x2740, 0x2757, 0x2760, 0x2760, 0x2780, 0x2783,
115 0x4000, 0x4003, 0x4800, 0x4806, 0x4808, 0x4808, 0x4900, 0x4900,
116 0x4908, 0x4908,
117};
118
Jordan Crousef7597bf2012-01-03 08:43:34 -0700119const unsigned int a200_registers_count = ARRAY_SIZE(a200_registers) / 2;
120const unsigned int a220_registers_count = ARRAY_SIZE(a220_registers) / 2;
Jeremy Gebben6be78d12012-03-07 16:02:47 -0700121const unsigned int a225_registers_count = ARRAY_SIZE(a225_registers) / 2;
Jordan Crousef7597bf2012-01-03 08:43:34 -0700122
123/*
Jordan Crousea78c9172011-07-11 13:14:09 -0600124 *
125 * Memory Map for Register, Constant & Instruction Shadow, and Command Buffers
126 * (34.5KB)
127 *
128 * +---------------------+------------+-------------+---+---------------------+
129 * | ALU Constant Shadow | Reg Shadow | C&V Buffers |Tex| Shader Instr Shadow |
130 * +---------------------+------------+-------------+---+---------------------+
131 * ________________________________/ \____________________
132 * / |
133 * +--------------+-----------+------+-----------+------------------------+
134 * | Restore Regs | Save Regs | Quad | Gmem Save | Gmem Restore | unused |
135 * +--------------+-----------+------+-----------+------------------------+
136 *
137 * 8K - ALU Constant Shadow (8K aligned)
138 * 4K - H/W Register Shadow (8K aligned)
139 * 4K - Command and Vertex Buffers
140 * - Indirect command buffer : Const/Reg restore
141 * - includes Loop & Bool const shadows
142 * - Indirect command buffer : Const/Reg save
143 * - Quad vertices & texture coordinates
144 * - Indirect command buffer : Gmem save
145 * - Indirect command buffer : Gmem restore
146 * - Unused (padding to 8KB boundary)
147 * <1K - Texture Constant Shadow (768 bytes) (8K aligned)
148 * 18K - Shader Instruction Shadow
149 * - 6K vertex (32 byte aligned)
150 * - 6K pixel (32 byte aligned)
151 * - 6K shared (32 byte aligned)
152 *
153 * Note: Reading constants into a shadow, one at a time using REG_TO_MEM, takes
154 * 3 DWORDS per DWORD transfered, plus 1 DWORD for the shadow, for a total of
155 * 16 bytes per constant. If the texture constants were transfered this way,
156 * the Command & Vertex Buffers section would extend past the 16K boundary.
157 * By moving the texture constant shadow area to start at 16KB boundary, we
158 * only require approximately 40 bytes more memory, but are able to use the
159 * LOAD_CONSTANT_CONTEXT shadowing feature for the textures, speeding up
160 * context switching.
161 *
162 * [Using LOAD_CONSTANT_CONTEXT shadowing feature for the Loop and/or Bool
163 * constants would require an additional 8KB each, for alignment.]
164 *
165 */
166
167/* Constants */
168
169#define ALU_CONSTANTS 2048 /* DWORDS */
170#define NUM_REGISTERS 1024 /* DWORDS */
171#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
172#define CMD_BUFFER_LEN 9216 /* DWORDS */
173#else
174#define CMD_BUFFER_LEN 3072 /* DWORDS */
175#endif
176#define TEX_CONSTANTS (32*6) /* DWORDS */
177#define BOOL_CONSTANTS 8 /* DWORDS */
178#define LOOP_CONSTANTS 56 /* DWORDS */
Jordan Crousea78c9172011-07-11 13:14:09 -0600179
180/* LOAD_CONSTANT_CONTEXT shadow size */
181#define LCC_SHADOW_SIZE 0x2000 /* 8KB */
182
183#define ALU_SHADOW_SIZE LCC_SHADOW_SIZE /* 8KB */
184#define REG_SHADOW_SIZE 0x1000 /* 4KB */
185#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
186#define CMD_BUFFER_SIZE 0x9000 /* 36KB */
187#else
188#define CMD_BUFFER_SIZE 0x3000 /* 12KB */
189#endif
190#define TEX_SHADOW_SIZE (TEX_CONSTANTS*4) /* 768 bytes */
Jordan Crousea78c9172011-07-11 13:14:09 -0600191
192#define REG_OFFSET LCC_SHADOW_SIZE
193#define CMD_OFFSET (REG_OFFSET + REG_SHADOW_SIZE)
194#define TEX_OFFSET (CMD_OFFSET + CMD_BUFFER_SIZE)
195#define SHADER_OFFSET ((TEX_OFFSET + TEX_SHADOW_SIZE + 32) & ~31)
196
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700197static inline int _shader_shadow_size(struct adreno_device *adreno_dev)
198{
Jordan Crousec6b3a992012-02-04 10:23:51 -0700199 return adreno_dev->istore_size *
200 (adreno_dev->instruction_size * sizeof(unsigned int));
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700201}
202
203static inline int _context_size(struct adreno_device *adreno_dev)
204{
205 return SHADER_OFFSET + 3*_shader_shadow_size(adreno_dev);
206}
Jordan Crousea78c9172011-07-11 13:14:09 -0600207
208/* A scratchpad used to build commands during context create */
209
210static struct tmp_ctx {
211 unsigned int *start; /* Command & Vertex buffer start */
212 unsigned int *cmd; /* Next available dword in C&V buffer */
213
214 /* address of buffers, needed when creating IB1 command buffers. */
215 uint32_t bool_shadow; /* bool constants */
216 uint32_t loop_shadow; /* loop constants */
217
Jordan Crousea78c9172011-07-11 13:14:09 -0600218 uint32_t shader_shared; /* shared shader instruction shadow */
219 uint32_t shader_vertex; /* vertex shader instruction shadow */
220 uint32_t shader_pixel; /* pixel shader instruction shadow */
Jordan Crousea78c9172011-07-11 13:14:09 -0600221
222 /* Addresses in command buffer where separately handled registers
223 * are saved
224 */
225 uint32_t reg_values[33];
226 uint32_t chicken_restore;
227
228 uint32_t gmem_base; /* Base gpu address of GMEM */
229
230} tmp_ctx;
231
232/* context save (gmem -> sys) */
233
234/* pre-compiled vertex shader program
235*
236* attribute vec4 P;
237* void main(void)
238* {
239* gl_Position = P;
240* }
241*/
242#define GMEM2SYS_VTX_PGM_LEN 0x12
243
244static unsigned int gmem2sys_vtx_pgm[GMEM2SYS_VTX_PGM_LEN] = {
245 0x00011003, 0x00001000, 0xc2000000,
246 0x00001004, 0x00001000, 0xc4000000,
247 0x00001005, 0x00002000, 0x00000000,
248 0x1cb81000, 0x00398a88, 0x00000003,
249 0x140f803e, 0x00000000, 0xe2010100,
250 0x14000000, 0x00000000, 0xe2000000
251};
252
253/* pre-compiled fragment shader program
254*
255* precision highp float;
256* uniform vec4 clear_color;
257* void main(void)
258* {
259* gl_FragColor = clear_color;
260* }
261*/
262
263#define GMEM2SYS_FRAG_PGM_LEN 0x0c
264
265static unsigned int gmem2sys_frag_pgm[GMEM2SYS_FRAG_PGM_LEN] = {
266 0x00000000, 0x1002c400, 0x10000000,
267 0x00001003, 0x00002000, 0x00000000,
268 0x140f8000, 0x00000000, 0x22000000,
269 0x14000000, 0x00000000, 0xe2000000
270};
271
272/* context restore (sys -> gmem) */
273/* pre-compiled vertex shader program
274*
275* attribute vec4 position;
276* attribute vec4 texcoord;
277* varying vec4 texcoord0;
278* void main()
279* {
280* gl_Position = position;
281* texcoord0 = texcoord;
282* }
283*/
284
285#define SYS2GMEM_VTX_PGM_LEN 0x18
286
287static unsigned int sys2gmem_vtx_pgm[SYS2GMEM_VTX_PGM_LEN] = {
288 0x00052003, 0x00001000, 0xc2000000, 0x00001005,
289 0x00001000, 0xc4000000, 0x00001006, 0x10071000,
290 0x20000000, 0x18981000, 0x0039ba88, 0x00000003,
291 0x12982000, 0x40257b08, 0x00000002, 0x140f803e,
292 0x00000000, 0xe2010100, 0x140f8000, 0x00000000,
293 0xe2020200, 0x14000000, 0x00000000, 0xe2000000
294};
295
296/* pre-compiled fragment shader program
297*
298* precision mediump float;
299* uniform sampler2D tex0;
300* varying vec4 texcoord0;
301* void main()
302* {
303* gl_FragColor = texture2D(tex0, texcoord0.xy);
304* }
305*/
306
307#define SYS2GMEM_FRAG_PGM_LEN 0x0f
308
309static unsigned int sys2gmem_frag_pgm[SYS2GMEM_FRAG_PGM_LEN] = {
310 0x00011002, 0x00001000, 0xc4000000, 0x00001003,
311 0x10041000, 0x20000000, 0x10000001, 0x1ffff688,
312 0x00000002, 0x140f8000, 0x00000000, 0xe2000000,
313 0x14000000, 0x00000000, 0xe2000000
314};
315
316/* shader texture constants (sysmem -> gmem) */
317#define SYS2GMEM_TEX_CONST_LEN 6
318
319static unsigned int sys2gmem_tex_const[SYS2GMEM_TEX_CONST_LEN] = {
320 /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat,
321 * RFMode=ZeroClamp-1, Dim=1:2d
322 */
323 0x00000002, /* Pitch = TBD */
324
325 /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0,
326 * NearestClamp=1:OGL Mode
327 */
328 0x00000800, /* Address[31:12] = TBD */
329
330 /* Width, Height, EndianSwap=0:None */
331 0, /* Width & Height = TBD */
332
333 /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point,
334 * Mip=2:BaseMap
335 */
336 0 << 1 | 1 << 4 | 2 << 7 | 3 << 10 | 2 << 23,
337
338 /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0,
339 * Dim3d=0
340 */
341 0,
342
343 /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0,
344 * Dim=1:2d, MipPacking=0
345 */
346 1 << 9 /* Mip Address[31:12] = TBD */
347};
348
Jordan Crousea78c9172011-07-11 13:14:09 -0600349#define NUM_COLOR_FORMATS 13
350
351static enum SURFACEFORMAT surface_format_table[NUM_COLOR_FORMATS] = {
352 FMT_4_4_4_4, /* COLORX_4_4_4_4 */
353 FMT_1_5_5_5, /* COLORX_1_5_5_5 */
354 FMT_5_6_5, /* COLORX_5_6_5 */
355 FMT_8, /* COLORX_8 */
356 FMT_8_8, /* COLORX_8_8 */
357 FMT_8_8_8_8, /* COLORX_8_8_8_8 */
358 FMT_8_8_8_8, /* COLORX_S8_8_8_8 */
359 FMT_16_FLOAT, /* COLORX_16_FLOAT */
360 FMT_16_16_FLOAT, /* COLORX_16_16_FLOAT */
361 FMT_16_16_16_16_FLOAT, /* COLORX_16_16_16_16_FLOAT */
362 FMT_32_FLOAT, /* COLORX_32_FLOAT */
363 FMT_32_32_FLOAT, /* COLORX_32_32_FLOAT */
364 FMT_32_32_32_32_FLOAT, /* COLORX_32_32_32_32_FLOAT */
365};
366
367static unsigned int format2bytesperpixel[NUM_COLOR_FORMATS] = {
368 2, /* COLORX_4_4_4_4 */
369 2, /* COLORX_1_5_5_5 */
370 2, /* COLORX_5_6_5 */
371 1, /* COLORX_8 */
372 2, /* COLORX_8_8 8*/
373 4, /* COLORX_8_8_8_8 */
374 4, /* COLORX_S8_8_8_8 */
375 2, /* COLORX_16_FLOAT */
376 4, /* COLORX_16_16_FLOAT */
377 8, /* COLORX_16_16_16_16_FLOAT */
378 4, /* COLORX_32_FLOAT */
379 8, /* COLORX_32_32_FLOAT */
380 16, /* COLORX_32_32_32_32_FLOAT */
381};
382
383/* shader linkage info */
384#define SHADER_CONST_ADDR (11 * 6 + 3)
385
Jordan Crousea78c9172011-07-11 13:14:09 -0600386
387static unsigned int *program_shader(unsigned int *cmds, int vtxfrag,
388 unsigned int *shader_pgm, int dwords)
389{
390 /* load the patched vertex shader stream */
Jordan Crouse084427d2011-07-28 08:37:58 -0600391 *cmds++ = cp_type3_packet(CP_IM_LOAD_IMMEDIATE, 2 + dwords);
Jordan Crousea78c9172011-07-11 13:14:09 -0600392 /* 0=vertex shader, 1=fragment shader */
393 *cmds++ = vtxfrag;
394 /* instruction start & size (in 32-bit words) */
395 *cmds++ = ((0 << 16) | dwords);
396
397 memcpy(cmds, shader_pgm, dwords << 2);
398 cmds += dwords;
399
400 return cmds;
401}
402
403static unsigned int *reg_to_mem(unsigned int *cmds, uint32_t dst,
404 uint32_t src, int dwords)
405{
406 while (dwords-- > 0) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600407 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600408 *cmds++ = src++;
409 *cmds++ = dst;
410 dst += 4;
411 }
412
413 return cmds;
414}
415
416#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
417
418static void build_reg_to_mem_range(unsigned int start, unsigned int end,
419 unsigned int **cmd,
420 struct adreno_context *drawctxt)
421{
422 unsigned int i = start;
423
424 for (i = start; i <= end; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600425 *(*cmd)++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600426 *(*cmd)++ = i;
427 *(*cmd)++ =
428 ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) +
429 (i - 0x2000) * 4;
430 }
431}
432
433#endif
434
435/* chicken restore */
436static unsigned int *build_chicken_restore_cmds(
437 struct adreno_context *drawctxt)
438{
439 unsigned int *start = tmp_ctx.cmd;
440 unsigned int *cmds = start;
441
Jordan Crouse084427d2011-07-28 08:37:58 -0600442 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600443 *cmds++ = 0;
444
Jordan Crouse084427d2011-07-28 08:37:58 -0600445 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600446 tmp_ctx.chicken_restore = virt2gpu(cmds, &drawctxt->gpustate);
447 *cmds++ = 0x00000000;
448
449 /* create indirect buffer command for above command sequence */
450 create_ib1(drawctxt, drawctxt->chicken_restore, start, cmds);
451
452 return cmds;
453}
454
455/****************************************************************************/
456/* context save */
457/****************************************************************************/
458
459static const unsigned int register_ranges_a20x[] = {
460 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
461 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
462 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
463 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
464 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
465 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
466 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
467 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
468 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
469 REG_VGT_MAX_VTX_INDX, REG_RB_FOG_COLOR,
470 REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL,
471 REG_PA_SU_POINT_SIZE, REG_PA_SC_LINE_STIPPLE,
472 REG_PA_SC_VIZ_QUERY, REG_PA_SC_VIZ_QUERY,
473 REG_VGT_VERTEX_REUSE_BLOCK_CNTL, REG_RB_DEPTH_CLEAR
474};
475
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700476static const unsigned int register_ranges_a220[] = {
Jordan Crousea78c9172011-07-11 13:14:09 -0600477 REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO,
478 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
479 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
480 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
481 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
482 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
483 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
484 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
485 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700486 REG_A220_PC_MAX_VTX_INDX, REG_A220_PC_INDX_OFFSET,
Jordan Crousea78c9172011-07-11 13:14:09 -0600487 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
488 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
489 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
490 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
491 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700492 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
493 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
Jordan Crousea78c9172011-07-11 13:14:09 -0600494 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR
495};
496
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700497static const unsigned int register_ranges_a225[] = {
498 REG_RB_SURFACE_INFO, REG_A225_RB_COLOR_INFO3,
499 REG_COHER_DEST_BASE_0, REG_PA_SC_SCREEN_SCISSOR_BR,
500 REG_PA_SC_WINDOW_OFFSET, REG_PA_SC_WINDOW_SCISSOR_BR,
501 REG_RB_STENCILREFMASK_BF, REG_PA_CL_VPORT_ZOFFSET,
502 REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1,
503 REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST,
504 REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK,
505 REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK,
506 REG_PA_SU_POLY_OFFSET_FRONT_SCALE, REG_PA_SU_POLY_OFFSET_BACK_OFFSET,
507 REG_A220_PC_MAX_VTX_INDX, REG_A225_PC_MULTI_PRIM_IB_RESET_INDX,
508 REG_RB_COLOR_MASK, REG_RB_FOG_COLOR,
509 REG_RB_DEPTHCONTROL, REG_RB_COLORCONTROL,
510 REG_PA_CL_CLIP_CNTL, REG_PA_CL_VTE_CNTL,
511 REG_RB_MODECONTROL, REG_RB_SAMPLE_POS,
512 REG_PA_SU_POINT_SIZE, REG_PA_SU_LINE_CNTL,
513 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
514 REG_A220_PC_VERTEX_REUSE_BLOCK_CNTL,
515 REG_RB_COPY_CONTROL, REG_RB_DEPTH_CLEAR,
Jeremy Gebbene139a042011-11-17 16:20:41 -0700516 REG_A225_GRAS_UCP0X, REG_A225_GRAS_UCP5W,
517 REG_A225_GRAS_UCP_ENABLED, REG_A225_GRAS_UCP_ENABLED
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700518};
519
Jordan Crousea78c9172011-07-11 13:14:09 -0600520
521/* save h/w regs, alu constants, texture contants, etc. ...
522* requires: bool_shadow_gpuaddr, loop_shadow_gpuaddr
523*/
524static void build_regsave_cmds(struct adreno_device *adreno_dev,
525 struct adreno_context *drawctxt)
526{
527 unsigned int *start = tmp_ctx.cmd;
528 unsigned int *cmd = start;
529
Jordan Crouse084427d2011-07-28 08:37:58 -0600530 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600531 *cmd++ = 0;
532
533#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
534 /* Make sure the HW context has the correct register values
535 * before reading them. */
Jordan Crouse084427d2011-07-28 08:37:58 -0600536 *cmd++ = cp_type3_packet(CP_CONTEXT_UPDATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600537 *cmd++ = 0;
538
539 {
540 unsigned int i = 0;
541 unsigned int reg_array_size = 0;
542 const unsigned int *ptr_register_ranges;
543
544 /* Based on chip id choose the register ranges */
Jeremy Gebben99105cb2011-08-31 10:23:05 -0700545 if (adreno_is_a220(adreno_dev)) {
546 ptr_register_ranges = register_ranges_a220;
547 reg_array_size = ARRAY_SIZE(register_ranges_a220);
548 } else if (adreno_is_a225(adreno_dev)) {
549 ptr_register_ranges = register_ranges_a225;
550 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -0600551 } else {
552 ptr_register_ranges = register_ranges_a20x;
553 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
554 }
555
556
557 /* Write HW registers into shadow */
558 for (i = 0; i < (reg_array_size/2) ; i++) {
559 build_reg_to_mem_range(ptr_register_ranges[i*2],
560 ptr_register_ranges[i*2+1],
561 &cmd, drawctxt);
562 }
563 }
564
565 /* Copy ALU constants */
566 cmd =
567 reg_to_mem(cmd, (drawctxt->gpustate.gpuaddr) & 0xFFFFE000,
568 REG_SQ_CONSTANT_0, ALU_CONSTANTS);
569
570 /* Copy Tex constants */
571 cmd =
572 reg_to_mem(cmd,
573 (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000,
574 REG_SQ_FETCH_0, TEX_CONSTANTS);
575#else
576
577 /* Insert a wait for idle packet before reading the registers.
578 * This is to fix a hang/reset seen during stress testing. In this
579 * hang, CP encountered a timeout reading SQ's boolean constant
580 * register. There is logic in the HW that blocks reading of this
581 * register when the SQ block is not idle, which we believe is
582 * contributing to the hang.*/
Jordan Crouse084427d2011-07-28 08:37:58 -0600583 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600584 *cmd++ = 0;
585
586 /* H/w registers are already shadowed; just need to disable shadowing
587 * to prevent corruption.
588 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600589 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600590 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
591 *cmd++ = 4 << 16; /* regs, start=0 */
592 *cmd++ = 0x0; /* count = 0 */
593
594 /* ALU constants are already shadowed; just need to disable shadowing
595 * to prevent corruption.
596 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600597 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600598 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
599 *cmd++ = 0 << 16; /* ALU, start=0 */
600 *cmd++ = 0x0; /* count = 0 */
601
602 /* Tex constants are already shadowed; just need to disable shadowing
603 * to prevent corruption.
604 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600605 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600606 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
607 *cmd++ = 1 << 16; /* Tex, start=0 */
608 *cmd++ = 0x0; /* count = 0 */
609#endif
610
611 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -0600612 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600613 *cmd++ = REG_SQ_GPR_MANAGEMENT;
614 *cmd++ = tmp_ctx.reg_values[0];
615
Jordan Crouse084427d2011-07-28 08:37:58 -0600616 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600617 *cmd++ = REG_TP0_CHICKEN;
618 *cmd++ = tmp_ctx.reg_values[1];
619
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600620 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600621 unsigned int i;
622 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700623 for (i = REG_A220_VSC_BIN_SIZE; i <=
624 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600625 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600626 *cmd++ = i;
627 *cmd++ = tmp_ctx.reg_values[j];
628 j++;
629 }
630 }
631
632 /* Copy Boolean constants */
633 cmd = reg_to_mem(cmd, tmp_ctx.bool_shadow, REG_SQ_CF_BOOLEANS,
634 BOOL_CONSTANTS);
635
636 /* Copy Loop constants */
637 cmd = reg_to_mem(cmd, tmp_ctx.loop_shadow,
638 REG_SQ_CF_LOOP, LOOP_CONSTANTS);
639
640 /* create indirect buffer command for above command sequence */
641 create_ib1(drawctxt, drawctxt->reg_save, start, cmd);
642
643 tmp_ctx.cmd = cmd;
644}
645
646/*copy colour, depth, & stencil buffers from graphics memory to system memory*/
647static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
648 struct adreno_context *drawctxt,
649 struct gmem_shadow_t *shadow)
650{
651 unsigned int *cmds = shadow->gmem_save_commands;
652 unsigned int *start = cmds;
653 /* Calculate the new offset based on the adjusted base */
654 unsigned int bytesperpixel = format2bytesperpixel[shadow->format];
655 unsigned int addr = shadow->gmemshadow.gpuaddr;
656 unsigned int offset = (addr - (addr & 0xfffff000)) / bytesperpixel;
657
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700658 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
659 /* Store TP0_CHICKEN register */
660 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
661 *cmds++ = REG_TP0_CHICKEN;
Jordan Crousea78c9172011-07-11 13:14:09 -0600662
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700663 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600664
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700665 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
666 *cmds++ = 0;
667 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600668
669 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600670 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600671 *cmds++ = 0x00000000;
672
673 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600674 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600675 *cmds++ = 0x00000000;
676
677 /* program shader */
678
679 /* load shader vtx constants ... 5 dwords */
Jordan Crouse084427d2011-07-28 08:37:58 -0600680 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crousea78c9172011-07-11 13:14:09 -0600681 *cmds++ = (0x1 << 16) | SHADER_CONST_ADDR;
682 *cmds++ = 0;
683 /* valid(?) vtx constant flag & addr */
684 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
685 /* limit = 12 dwords */
686 *cmds++ = 0x00000030;
687
688 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600689 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600690 *cmds++ = 0x1;
691
Jordan Crouse084427d2011-07-28 08:37:58 -0600692 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600693 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600694 *cmds++ = 0x00ffffff; /* REG_VGT_MAX_VTX_INDX */
695 *cmds++ = 0x0; /* REG_VGT_MIN_VTX_INDX */
696 *cmds++ = 0x00000000; /* REG_VGT_INDX_OFFSET */
697
Jordan Crouse084427d2011-07-28 08:37:58 -0600698 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600699 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600700 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
701
Jordan Crouse084427d2011-07-28 08:37:58 -0600702 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600703 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600704 *cmds++ = 0x00000c20;
705
Tarun Karra16346b02011-07-24 15:04:26 -0700706 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600707 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700708 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700709
710 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600711 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700712 *cmds++ = 0x00003F00;
713
Jordan Crouse084427d2011-07-28 08:37:58 -0600714 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700715 *cmds++ = adreno_encode_istore_size(adreno_dev)
716 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700717
Jordan Crousea78c9172011-07-11 13:14:09 -0600718 /* load the patched vertex shader stream */
719 cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN);
720
721 /* Load the patched fragment shader stream */
722 cmds =
723 program_shader(cmds, 1, gmem2sys_frag_pgm, GMEM2SYS_FRAG_PGM_LEN);
724
725 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600726 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600727 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600728 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600729 *cmds++ = 0x10018001;
730 else
731 *cmds++ = 0x10010001;
732 *cmds++ = 0x00000008;
733
734 /* resolve */
735
736 /* PA_CL_VTE_CNTL */
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_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600739 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
740 *cmds++ = 0x00000b00;
741
742 /* program surface info */
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_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600745 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
746
747 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
748 * Base=gmem_base
749 */
750 /* gmem base assumed 4K aligned. */
751 BUG_ON(tmp_ctx.gmem_base & 0xFFF);
752 *cmds++ =
753 (shadow->
754 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
755
756 /* disable Z */
Jordan Crouse084427d2011-07-28 08:37:58 -0600757 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600758 *cmds++ = CP_REG(REG_RB_DEPTHCONTROL);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600759 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -0600760 *cmds++ = 0x08;
761 else
762 *cmds++ = 0;
763
764 /* set REG_PA_SU_SC_MODE_CNTL
765 * Front_ptype = draw triangles
766 * Back_ptype = draw triangles
767 * Provoking vertex = last
768 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600769 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600770 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600771 *cmds++ = 0x00080240;
772
773 /* Use maximum scissor values -- quad vertices already have the
774 * correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -0600775 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600776 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600777 *cmds++ = (0 << 16) | 0;
778 *cmds++ = (0x1fff << 16) | (0x1fff);
Jordan Crouse084427d2011-07-28 08:37:58 -0600779 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600780 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600781 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
782 *cmds++ = (0x1fff << 16) | (0x1fff);
783
784 /* load the viewport so that z scale = clear depth and
785 * z offset = 0.0f
786 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600787 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600788 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -0600789 *cmds++ = 0xbf800000; /* -1.0f */
790 *cmds++ = 0x0;
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_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600794 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
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_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600798 *cmds++ = 0xffffffff;
799
Jordan Crouse084427d2011-07-28 08:37:58 -0600800 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600801 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -0600802 *cmds++ = 0x00000000;
803 *cmds++ = 0x00000000;
804
805 /* load the stencil ref value
806 * $AAM - do this later
807 */
808
809 /* load the COPY state */
Jordan Crouse084427d2011-07-28 08:37:58 -0600810 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600811 *cmds++ = CP_REG(REG_RB_COPY_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600812 *cmds++ = 0; /* RB_COPY_CONTROL */
813 *cmds++ = addr & 0xfffff000; /* RB_COPY_DEST_BASE */
814 *cmds++ = shadow->pitch >> 5; /* RB_COPY_DEST_PITCH */
815
816 /* Endian=none, Linear, Format=RGBA8888,Swap=0,!Dither,
817 * MaskWrite:R=G=B=A=1
818 */
819 *cmds++ = 0x0003c008 |
820 (shadow->format << RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT);
821 /* Make sure we stay in offsetx field. */
822 BUG_ON(offset & 0xfffff000);
823 *cmds++ = offset;
824
Jordan Crouse084427d2011-07-28 08:37:58 -0600825 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600826 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600827 *cmds++ = 0x6; /* EDRAM copy */
828
Jordan Crouse084427d2011-07-28 08:37:58 -0600829 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600830 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600831 *cmds++ = 0x00010000;
832
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600833 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -0600834 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -0700835 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600836 *cmds++ = 0x0000000;
837
Jordan Crouse084427d2011-07-28 08:37:58 -0600838 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -0600839 *cmds++ = 0; /* viz query info. */
840 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
841 *cmds++ = 0x00004088;
842 *cmds++ = 3; /* NumIndices=3 */
843 } else {
844 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -0600845 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -0600846 *cmds++ = 0; /* viz query info. */
847 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
848 *cmds++ = 0x00030088;
849 }
850
851 /* create indirect buffer command for above command sequence */
852 create_ib1(drawctxt, shadow->gmem_save, start, cmds);
853
854 return cmds;
855}
856
857/* context restore */
858
859/*copy colour, depth, & stencil buffers from system memory to graphics memory*/
860static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
861 struct adreno_context *drawctxt,
862 struct gmem_shadow_t *shadow)
863{
864 unsigned int *cmds = shadow->gmem_restore_commands;
865 unsigned int *start = cmds;
866
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700867 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
868 /* Store TP0_CHICKEN register */
869 *cmds++ = cp_type3_packet(CP_REG_TO_MEM, 2);
870 *cmds++ = REG_TP0_CHICKEN;
871 *cmds++ = tmp_ctx.chicken_restore;
Jordan Crousea78c9172011-07-11 13:14:09 -0600872
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -0700873 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
874 *cmds++ = 0;
875 }
Jordan Crousea78c9172011-07-11 13:14:09 -0600876
877 /* Set TP0_CHICKEN to zero */
Jordan Crouse084427d2011-07-28 08:37:58 -0600878 *cmds++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600879 *cmds++ = 0x00000000;
880
881 /* Set PA_SC_AA_CONFIG to 0 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600882 *cmds++ = cp_type0_packet(REG_PA_SC_AA_CONFIG, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600883 *cmds++ = 0x00000000;
884 /* shader constants */
885
886 /* vertex buffer constants */
Jordan Crouse084427d2011-07-28 08:37:58 -0600887 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
Jordan Crousea78c9172011-07-11 13:14:09 -0600888
889 *cmds++ = (0x1 << 16) | (9 * 6);
890 /* valid(?) vtx constant flag & addr */
891 *cmds++ = shadow->quad_vertices.gpuaddr | 0x3;
892 /* limit = 12 dwords */
893 *cmds++ = 0x00000030;
894 /* valid(?) vtx constant flag & addr */
895 *cmds++ = shadow->quad_texcoords.gpuaddr | 0x3;
896 /* limit = 8 dwords */
897 *cmds++ = 0x00000020;
898 *cmds++ = 0;
899 *cmds++ = 0;
900
901 /* Invalidate L2 cache to make sure vertices are updated */
Jordan Crouse084427d2011-07-28 08:37:58 -0600902 *cmds++ = cp_type0_packet(REG_TC_CNTL_STATUS, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -0600903 *cmds++ = 0x1;
904
905 cmds = program_shader(cmds, 0, sys2gmem_vtx_pgm, SYS2GMEM_VTX_PGM_LEN);
906
Tarun Karra16346b02011-07-24 15:04:26 -0700907 /* Repartition shaders */
Jordan Crouse084427d2011-07-28 08:37:58 -0600908 *cmds++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jeremy Gebben72aadf42011-12-02 11:00:49 -0700909 *cmds++ = adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700910
911 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -0600912 *cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Tarun Karra16346b02011-07-24 15:04:26 -0700913 *cmds++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
914
Jordan Crouse084427d2011-07-28 08:37:58 -0600915 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jeremy Gebbenddf6b572011-09-09 13:39:49 -0700916 *cmds++ = adreno_encode_istore_size(adreno_dev)
917 | adreno_dev->pix_shader_start;
Tarun Karra16346b02011-07-24 15:04:26 -0700918
Jordan Crousea78c9172011-07-11 13:14:09 -0600919 /* Load the patched fragment shader stream */
920 cmds =
921 program_shader(cmds, 1, sys2gmem_frag_pgm, SYS2GMEM_FRAG_PGM_LEN);
922
923 /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */
Jordan Crouse084427d2011-07-28 08:37:58 -0600924 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600925 *cmds++ = CP_REG(REG_SQ_PROGRAM_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600926 *cmds++ = 0x10030002;
927 *cmds++ = 0x00000008;
928
Jordan Crouse084427d2011-07-28 08:37:58 -0600929 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600930 *cmds++ = CP_REG(REG_PA_SC_AA_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -0600931 *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */
932
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -0600933 if (!adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -0600934 /* PA_SC_VIZ_QUERY */
Jordan Crouse084427d2011-07-28 08:37:58 -0600935 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600936 *cmds++ = CP_REG(REG_PA_SC_VIZ_QUERY);
Jordan Crousea78c9172011-07-11 13:14:09 -0600937 *cmds++ = 0x0; /*REG_PA_SC_VIZ_QUERY */
938 }
939
940 /* RB_COLORCONTROL */
Jordan Crouse084427d2011-07-28 08:37:58 -0600941 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600942 *cmds++ = CP_REG(REG_RB_COLORCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600943 *cmds++ = 0x00000c20;
944
Jordan Crouse084427d2011-07-28 08:37:58 -0600945 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 4);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600946 *cmds++ = CP_REG(REG_VGT_MAX_VTX_INDX);
Jordan Crousea78c9172011-07-11 13:14:09 -0600947 *cmds++ = 0x00ffffff; /* mmVGT_MAX_VTX_INDX */
948 *cmds++ = 0x0; /* mmVGT_MIN_VTX_INDX */
949 *cmds++ = 0x00000000; /* mmVGT_INDX_OFFSET */
950
Jordan Crouse084427d2011-07-28 08:37:58 -0600951 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600952 *cmds++ = CP_REG(REG_VGT_VERTEX_REUSE_BLOCK_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600953 *cmds++ = 0x00000002; /* mmVGT_VERTEX_REUSE_BLOCK_CNTL */
954 *cmds++ = 0x00000002; /* mmVGT_OUT_DEALLOC_CNTL */
955
Jordan Crouse084427d2011-07-28 08:37:58 -0600956 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600957 *cmds++ = CP_REG(REG_SQ_INTERPOLATOR_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600958 *cmds++ = 0xffffffff; /* mmSQ_INTERPOLATOR_CNTL */
959
Jordan Crouse084427d2011-07-28 08:37:58 -0600960 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600961 *cmds++ = CP_REG(REG_PA_SC_AA_CONFIG);
Jordan Crousea78c9172011-07-11 13:14:09 -0600962 *cmds++ = 0x00000000; /* REG_PA_SC_AA_CONFIG */
963
964 /* set REG_PA_SU_SC_MODE_CNTL
965 * Front_ptype = draw triangles
966 * Back_ptype = draw triangles
967 * Provoking vertex = last
968 */
Jordan Crouse084427d2011-07-28 08:37:58 -0600969 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600970 *cmds++ = CP_REG(REG_PA_SU_SC_MODE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600971 *cmds++ = 0x00080240;
972
973 /* texture constants */
974 *cmds++ =
Jordan Crouse084427d2011-07-28 08:37:58 -0600975 cp_type3_packet(CP_SET_CONSTANT, (SYS2GMEM_TEX_CONST_LEN + 1));
Jordan Crousea78c9172011-07-11 13:14:09 -0600976 *cmds++ = (0x1 << 16) | (0 * 6);
977 memcpy(cmds, sys2gmem_tex_const, SYS2GMEM_TEX_CONST_LEN << 2);
978 cmds[0] |= (shadow->pitch >> 5) << 22;
979 cmds[1] |=
980 shadow->gmemshadow.gpuaddr | surface_format_table[shadow->format];
981 cmds[2] |= (shadow->width - 1) | (shadow->height - 1) << 13;
982 cmds += SYS2GMEM_TEX_CONST_LEN;
983
984 /* program surface info */
Jordan Crouse084427d2011-07-28 08:37:58 -0600985 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -0600986 *cmds++ = CP_REG(REG_RB_SURFACE_INFO);
Jordan Crousea78c9172011-07-11 13:14:09 -0600987 *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */
988
989 /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0,
990 * Base=gmem_base
991 */
992 *cmds++ =
993 (shadow->
994 format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | tmp_ctx.gmem_base;
995
996 /* RB_DEPTHCONTROL */
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_DEPTHCONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -0600999
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001000 if (adreno_is_a22x(adreno_dev))
Jordan Crousea78c9172011-07-11 13:14:09 -06001001 *cmds++ = 8; /* disable Z */
1002 else
1003 *cmds++ = 0; /* disable Z */
1004
1005 /* Use maximum scissor values -- quad vertices already
1006 * have the correct bounds */
Jordan Crouse084427d2011-07-28 08:37:58 -06001007 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001008 *cmds++ = CP_REG(REG_PA_SC_SCREEN_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001009 *cmds++ = (0 << 16) | 0;
1010 *cmds++ = ((0x1fff) << 16) | 0x1fff;
Jordan Crouse084427d2011-07-28 08:37:58 -06001011 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001012 *cmds++ = CP_REG(REG_PA_SC_WINDOW_SCISSOR_TL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001013 *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0);
1014 *cmds++ = ((0x1fff) << 16) | 0x1fff;
1015
Jordan Crouse084427d2011-07-28 08:37:58 -06001016 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001017 *cmds++ = CP_REG(REG_PA_CL_VTE_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001018 /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */
1019 *cmds++ = 0x00000b00;
1020
1021 /*load the viewport so that z scale = clear depth and z offset = 0.0f */
Jordan Crouse084427d2011-07-28 08:37:58 -06001022 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001023 *cmds++ = CP_REG(REG_PA_CL_VPORT_ZSCALE);
Jordan Crousea78c9172011-07-11 13:14:09 -06001024 *cmds++ = 0xbf800000;
1025 *cmds++ = 0x0;
1026
Jordan Crouse084427d2011-07-28 08:37:58 -06001027 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001028 *cmds++ = CP_REG(REG_RB_COLOR_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001029 *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */
1030
Jordan Crouse084427d2011-07-28 08:37:58 -06001031 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001032 *cmds++ = CP_REG(REG_RB_COLOR_DEST_MASK);
Jordan Crousea78c9172011-07-11 13:14:09 -06001033 *cmds++ = 0xffffffff;
1034
Jordan Crouse084427d2011-07-28 08:37:58 -06001035 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001036 *cmds++ = CP_REG(REG_SQ_WRAPPING_0);
Jordan Crousea78c9172011-07-11 13:14:09 -06001037 *cmds++ = 0x00000000;
1038 *cmds++ = 0x00000000;
1039
1040 /* load the stencil ref value
1041 * $AAM - do this later
1042 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001043 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001044 *cmds++ = CP_REG(REG_RB_MODECONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001045 /* draw pixels with color and depth/stencil component */
1046 *cmds++ = 0x4;
1047
Jordan Crouse084427d2011-07-28 08:37:58 -06001048 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001049 *cmds++ = CP_REG(REG_PA_CL_CLIP_CNTL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001050 *cmds++ = 0x00010000;
1051
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001052 if (adreno_is_a22x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001053 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001054 *cmds++ = CP_REG(REG_A220_RB_LRZ_VSC_CONTROL);
Jordan Crousea78c9172011-07-11 13:14:09 -06001055 *cmds++ = 0x0000000;
1056
Jordan Crouse084427d2011-07-28 08:37:58 -06001057 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001058 *cmds++ = 0; /* viz query info. */
1059 /* PrimType=RectList, SrcSel=AutoIndex, VisCullMode=Ignore*/
1060 *cmds++ = 0x00004088;
1061 *cmds++ = 3; /* NumIndices=3 */
1062 } else {
1063 /* queue the draw packet */
Jordan Crouse084427d2011-07-28 08:37:58 -06001064 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001065 *cmds++ = 0; /* viz query info. */
1066 /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */
1067 *cmds++ = 0x00030088;
1068 }
1069
1070 /* create indirect buffer command for above command sequence */
1071 create_ib1(drawctxt, shadow->gmem_restore, start, cmds);
1072
1073 return cmds;
1074}
1075
Jordan Crousea78c9172011-07-11 13:14:09 -06001076static void build_regrestore_cmds(struct adreno_device *adreno_dev,
1077 struct adreno_context *drawctxt)
1078{
1079 unsigned int *start = tmp_ctx.cmd;
1080 unsigned int *cmd = start;
1081
1082 unsigned int i = 0;
1083 unsigned int reg_array_size = 0;
1084 const unsigned int *ptr_register_ranges;
1085
Jordan Crouse084427d2011-07-28 08:37:58 -06001086 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001087 *cmd++ = 0;
1088
1089 /* H/W Registers */
Jordan Crouse084427d2011-07-28 08:37:58 -06001090 /* deferred cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, ???); */
Jordan Crousea78c9172011-07-11 13:14:09 -06001091 cmd++;
1092#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1093 /* Force mismatch */
1094 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1;
1095#else
1096 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1097#endif
1098
1099 /* Based on chip id choose the registers ranges*/
Jeremy Gebben99105cb2011-08-31 10:23:05 -07001100 if (adreno_is_a220(adreno_dev)) {
1101 ptr_register_ranges = register_ranges_a220;
1102 reg_array_size = ARRAY_SIZE(register_ranges_a220);
1103 } else if (adreno_is_a225(adreno_dev)) {
1104 ptr_register_ranges = register_ranges_a225;
1105 reg_array_size = ARRAY_SIZE(register_ranges_a225);
Jordan Crousea78c9172011-07-11 13:14:09 -06001106 } else {
1107 ptr_register_ranges = register_ranges_a20x;
1108 reg_array_size = ARRAY_SIZE(register_ranges_a20x);
1109 }
1110
1111
1112 for (i = 0; i < (reg_array_size/2); i++) {
1113 cmd = reg_range(cmd, ptr_register_ranges[i*2],
1114 ptr_register_ranges[i*2+1]);
1115 }
1116
1117 /* Now we know how many register blocks we have, we can compute command
1118 * length
1119 */
1120 start[2] =
Jordan Crouse084427d2011-07-28 08:37:58 -06001121 cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, (cmd - start) - 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001122 /* Enable shadowing for the entire register block. */
1123#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1124 start[4] |= (0 << 24) | (4 << 16); /* Disable shadowing. */
1125#else
1126 start[4] |= (1 << 24) | (4 << 16);
1127#endif
1128
1129 /* Need to handle some of the registers separately */
Jordan Crouse084427d2011-07-28 08:37:58 -06001130 *cmd++ = cp_type0_packet(REG_SQ_GPR_MANAGEMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001131 tmp_ctx.reg_values[0] = virt2gpu(cmd, &drawctxt->gpustate);
1132 *cmd++ = 0x00040400;
1133
Jordan Crouse084427d2011-07-28 08:37:58 -06001134 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001135 *cmd++ = 0;
Jordan Crouse084427d2011-07-28 08:37:58 -06001136 *cmd++ = cp_type0_packet(REG_TP0_CHICKEN, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001137 tmp_ctx.reg_values[1] = virt2gpu(cmd, &drawctxt->gpustate);
1138 *cmd++ = 0x00000000;
1139
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001140 if (adreno_is_a22x(adreno_dev)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001141 unsigned int i;
1142 unsigned int j = 2;
Jeremy Gebbeneebc4612011-08-31 10:15:21 -07001143 for (i = REG_A220_VSC_BIN_SIZE; i <=
1144 REG_A220_VSC_PIPE_DATA_LENGTH_7; i++) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001145 *cmd++ = cp_type0_packet(i, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001146 tmp_ctx.reg_values[j] = virt2gpu(cmd,
1147 &drawctxt->gpustate);
1148 *cmd++ = 0x00000000;
1149 j++;
1150 }
1151 }
1152
1153 /* ALU Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001154 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001155 *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000;
1156#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1157 *cmd++ = (0 << 24) | (0 << 16) | 0; /* Disable shadowing */
1158#else
1159 *cmd++ = (1 << 24) | (0 << 16) | 0;
1160#endif
1161 *cmd++ = ALU_CONSTANTS;
1162
1163 /* Texture Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001164 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001165 *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000;
1166#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1167 /* Disable shadowing */
1168 *cmd++ = (0 << 24) | (1 << 16) | 0;
1169#else
1170 *cmd++ = (1 << 24) | (1 << 16) | 0;
1171#endif
1172 *cmd++ = TEX_CONSTANTS;
1173
1174 /* Boolean Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001175 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + BOOL_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001176 *cmd++ = (2 << 16) | 0;
1177
1178 /* the next BOOL_CONSTANT dwords is the shadow area for
1179 * boolean constants.
1180 */
1181 tmp_ctx.bool_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1182 cmd += BOOL_CONSTANTS;
1183
1184 /* Loop Constants */
Jordan Crouse084427d2011-07-28 08:37:58 -06001185 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 1 + LOOP_CONSTANTS);
Jordan Crousea78c9172011-07-11 13:14:09 -06001186 *cmd++ = (3 << 16) | 0;
1187
1188 /* the next LOOP_CONSTANTS dwords is the shadow area for
1189 * loop constants.
1190 */
1191 tmp_ctx.loop_shadow = virt2gpu(cmd, &drawctxt->gpustate);
1192 cmd += LOOP_CONSTANTS;
1193
1194 /* create indirect buffer command for above command sequence */
1195 create_ib1(drawctxt, drawctxt->reg_restore, start, cmd);
1196
1197 tmp_ctx.cmd = cmd;
1198}
1199
Jordan Crousea78c9172011-07-11 13:14:09 -06001200static void
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001201build_shader_save_restore_cmds(struct adreno_device *adreno_dev,
1202 struct adreno_context *drawctxt)
Jordan Crousea78c9172011-07-11 13:14:09 -06001203{
1204 unsigned int *cmd = tmp_ctx.cmd;
1205 unsigned int *save, *restore, *fixup;
Jordan Crousea78c9172011-07-11 13:14:09 -06001206 unsigned int *startSizeVtx, *startSizePix, *startSizeShared;
Jordan Crousea78c9172011-07-11 13:14:09 -06001207 unsigned int *partition1;
1208 unsigned int *shaderBases, *partition2;
1209
Jordan Crousea78c9172011-07-11 13:14:09 -06001210 /* compute vertex, pixel and shared instruction shadow GPU addresses */
1211 tmp_ctx.shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001212 tmp_ctx.shader_pixel = tmp_ctx.shader_vertex
1213 + _shader_shadow_size(adreno_dev);
1214 tmp_ctx.shader_shared = tmp_ctx.shader_pixel
1215 + _shader_shadow_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001216
1217 /* restore shader partitioning and instructions */
1218
1219 restore = cmd; /* start address */
1220
1221 /* Invalidate Vertex & Pixel instruction code address and sizes */
Jordan Crouse084427d2011-07-28 08:37:58 -06001222 *cmd++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001223 *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */
1224
1225 /* Restore previous shader vertex & pixel instruction bases. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001226 *cmd++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001227 shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */
1228
1229 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001230 *cmd++ = cp_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001231 partition1 = cmd++; /* TBD #4a: partition info (from save) */
1232
Jordan Crousea78c9172011-07-11 13:14:09 -06001233 /* load vertex shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001234 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001235 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1236 startSizeVtx = cmd++; /* TBD #1: start/size (from save) */
1237
1238 /* load pixel shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001239 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001240 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1241 startSizePix = cmd++; /* TBD #2: start/size (from save) */
1242
1243 /* load shared shader instructions from the shadow. */
Jordan Crouse084427d2011-07-28 08:37:58 -06001244 *cmd++ = cp_type3_packet(CP_IM_LOAD, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001245 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1246 startSizeShared = cmd++; /* TBD #3: start/size (from save) */
Jordan Crousea78c9172011-07-11 13:14:09 -06001247
1248 /* create indirect buffer command for above command sequence */
1249 create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd);
1250
1251 /*
1252 * fixup SET_SHADER_BASES data
1253 *
1254 * since self-modifying PM4 code is being used here, a seperate
1255 * command buffer is used for this fixup operation, to ensure the
1256 * commands are not read by the PM4 engine before the data fields
1257 * have been written.
1258 */
1259
1260 fixup = cmd; /* start address */
1261
1262 /* write the shader partition information to a scratch register */
Jordan Crouse084427d2011-07-28 08:37:58 -06001263 *cmd++ = cp_type0_packet(REG_SCRATCH_REG2, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001264 partition2 = cmd++; /* TBD #4b: partition info (from save) */
1265
1266 /* mask off unused bits, then OR with shader instruction memory size */
Jordan Crouse084427d2011-07-28 08:37:58 -06001267 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001268 *cmd++ = REG_SCRATCH_REG2;
1269 /* AND off invalid bits. */
1270 *cmd++ = 0x0FFF0FFF;
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001271 /* OR in instruction memory size. */
1272 *cmd++ = adreno_encode_istore_size(adreno_dev);
Jordan Crousea78c9172011-07-11 13:14:09 -06001273
1274 /* write the computed value to the SET_SHADER_BASES data field */
Jordan Crouse084427d2011-07-28 08:37:58 -06001275 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001276 *cmd++ = REG_SCRATCH_REG2;
1277 /* TBD #5: shader bases (to restore) */
1278 *cmd++ = virt2gpu(shaderBases, &drawctxt->gpustate);
1279
1280 /* create indirect buffer command for above command sequence */
1281 create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd);
1282
1283 /* save shader partitioning and instructions */
1284
1285 save = cmd; /* start address */
1286
Jordan Crouse084427d2011-07-28 08:37:58 -06001287 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001288 *cmd++ = 0;
1289
1290 /* fetch the SQ_INST_STORE_MANAGMENT register value,
1291 * store the value in the data fields of the SET_CONSTANT commands
1292 * above.
1293 */
Jordan Crouse084427d2011-07-28 08:37:58 -06001294 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001295 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1296 /* TBD #4a: partition info (to restore) */
1297 *cmd++ = virt2gpu(partition1, &drawctxt->gpustate);
Jordan Crouse084427d2011-07-28 08:37:58 -06001298 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001299 *cmd++ = REG_SQ_INST_STORE_MANAGMENT;
1300 /* TBD #4b: partition info (to fixup) */
1301 *cmd++ = virt2gpu(partition2, &drawctxt->gpustate);
1302
Jordan Crousea78c9172011-07-11 13:14:09 -06001303
1304 /* store the vertex shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001305 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001306 *cmd++ = tmp_ctx.shader_vertex + 0x0; /* 0x0 = Vertex */
1307 /* TBD #1: start/size (to restore) */
1308 *cmd++ = virt2gpu(startSizeVtx, &drawctxt->gpustate);
1309
1310 /* store the pixel shader instructions */
Jordan Crouse084427d2011-07-28 08:37:58 -06001311 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001312 *cmd++ = tmp_ctx.shader_pixel + 0x1; /* 0x1 = Pixel */
1313 /* TBD #2: start/size (to restore) */
1314 *cmd++ = virt2gpu(startSizePix, &drawctxt->gpustate);
1315
1316 /* store the shared shader instructions if vertex base is nonzero */
1317
Jordan Crouse084427d2011-07-28 08:37:58 -06001318 *cmd++ = cp_type3_packet(CP_IM_STORE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001319 *cmd++ = tmp_ctx.shader_shared + 0x2; /* 0x2 = Shared */
1320 /* TBD #3: start/size (to restore) */
1321 *cmd++ = virt2gpu(startSizeShared, &drawctxt->gpustate);
1322
Jordan Crousea78c9172011-07-11 13:14:09 -06001323
Jordan Crouse084427d2011-07-28 08:37:58 -06001324 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001325 *cmd++ = 0;
1326
1327 /* create indirect buffer command for above command sequence */
1328 create_ib1(drawctxt, drawctxt->shader_save, save, cmd);
1329
1330 tmp_ctx.cmd = cmd;
1331}
1332
1333/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001334static int a2xx_create_gpustate_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001335 struct adreno_context *drawctxt)
1336{
Jordan Crousea78c9172011-07-11 13:14:09 -06001337 drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW;
1338
Jordan Crousea78c9172011-07-11 13:14:09 -06001339 /* build indirect command buffers to save & restore regs/constants */
Jordan Crousea78c9172011-07-11 13:14:09 -06001340 build_regrestore_cmds(adreno_dev, drawctxt);
1341 build_regsave_cmds(adreno_dev, drawctxt);
1342
Jeremy Gebbenddf6b572011-09-09 13:39:49 -07001343 build_shader_save_restore_cmds(adreno_dev, drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001344
Jordan Crousea78c9172011-07-11 13:14:09 -06001345 return 0;
1346}
1347
1348/* create buffers for saving/restoring registers, constants, & GMEM */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001349static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001350 struct adreno_context *drawctxt)
1351{
1352 int result;
1353
Anoop Kumar Yerukalaa4e88c62012-05-01 14:43:06 +05301354 calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_size);
Jordan Crouse7501d452012-04-19 08:58:44 -06001355 tmp_ctx.gmem_base = adreno_dev->gmem_base;
Jordan Crousea78c9172011-07-11 13:14:09 -06001356
1357 result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
1358 drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
1359
1360 if (result)
1361 return result;
1362
Carter Cooperec549da2012-04-02 15:51:38 -06001363 /* set the gmem shadow flag for the context */
1364 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
Jordan Crousea78c9172011-07-11 13:14:09 -06001365
1366 /* blank out gmem shadow. */
1367 kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
1368 drawctxt->context_gmem_shadow.size);
1369
1370 /* build quad vertex buffer */
Jordan Crouse0e0486f2011-07-28 08:37:58 -06001371 build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
1372 &tmp_ctx.cmd);
Jordan Crousea78c9172011-07-11 13:14:09 -06001373
1374 /* build TP0_CHICKEN register restore command buffer */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001375 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE))
1376 tmp_ctx.cmd = build_chicken_restore_cmds(drawctxt);
Jordan Crousea78c9172011-07-11 13:14:09 -06001377
1378 /* build indirect command buffers to save & restore gmem */
Jordan Crousea78c9172011-07-11 13:14:09 -06001379 drawctxt->context_gmem_shadow.gmem_save_commands = tmp_ctx.cmd;
1380 tmp_ctx.cmd =
1381 build_gmem2sys_cmds(adreno_dev, drawctxt,
1382 &drawctxt->context_gmem_shadow);
1383 drawctxt->context_gmem_shadow.gmem_restore_commands = tmp_ctx.cmd;
1384 tmp_ctx.cmd =
1385 build_sys2gmem_cmds(adreno_dev, drawctxt,
1386 &drawctxt->context_gmem_shadow);
1387
1388 kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
1389 KGSL_CACHE_OP_FLUSH);
1390
Sushmita Susheelendraf3896062011-08-12 16:33:10 -06001391 kgsl_cffdump_syncmem(NULL,
1392 &drawctxt->context_gmem_shadow.gmemshadow,
1393 drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
1394 drawctxt->context_gmem_shadow.gmemshadow.size, false);
1395
Jordan Crousea78c9172011-07-11 13:14:09 -06001396 return 0;
1397}
1398
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001399static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
1400 struct adreno_context *drawctxt)
1401{
1402 int ret;
1403
1404 /*
1405 * Allocate memory for the GPU state and the context commands.
1406 * Despite the name, this is much more then just storage for
1407 * the gpustate. This contains command space for gmem save
1408 * and texture and vertex buffer storage too
1409 */
1410
1411 ret = kgsl_allocate(&drawctxt->gpustate,
1412 drawctxt->pagetable, _context_size(adreno_dev));
1413
1414 if (ret)
1415 return ret;
1416
1417 kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0,
1418 _context_size(adreno_dev));
1419
1420 tmp_ctx.cmd = tmp_ctx.start
1421 = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
1422
1423 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
1424 ret = a2xx_create_gpustate_shadow(adreno_dev, drawctxt);
1425 if (ret)
1426 goto done;
1427
1428 drawctxt->flags |= CTXT_FLAGS_SHADER_SAVE;
1429 }
1430
1431 if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC)) {
1432 ret = a2xx_create_gmem_shadow(adreno_dev, drawctxt);
1433 if (ret)
1434 goto done;
1435 }
1436
1437 /* Flush and sync the gpustate memory */
1438
1439 kgsl_cache_range_op(&drawctxt->gpustate,
1440 KGSL_CACHE_OP_FLUSH);
1441
1442 kgsl_cffdump_syncmem(NULL, &drawctxt->gpustate,
1443 drawctxt->gpustate.gpuaddr,
1444 drawctxt->gpustate.size, false);
1445
1446done:
1447 if (ret)
1448 kgsl_sharedmem_free(&drawctxt->gpustate);
1449
1450 return ret;
1451}
1452
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001453static void a2xx_drawctxt_draw_workaround(struct adreno_device *adreno_dev,
1454 struct adreno_context *context)
Shubhraprakash Das4624b552012-06-01 14:08:03 -06001455{
1456 struct kgsl_device *device = &adreno_dev->dev;
1457 unsigned int cmd[11];
1458 unsigned int *cmds = &cmd[0];
1459
Ranjhith Kalisamyd71cfd62012-06-22 19:37:51 +05301460 if (adreno_is_a225(adreno_dev)) {
1461 adreno_dev->gpudev->ctx_switches_since_last_draw++;
1462 /* If there have been > than
1463 * ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW calls to context
1464 * switches w/o gmem being saved then we need to execute
1465 * this workaround */
1466 if (adreno_dev->gpudev->ctx_switches_since_last_draw >
1467 ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW)
1468 adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
1469 else
1470 return;
1471 /*
1472 * Issue an empty draw call to avoid possible hangs due to
1473 * repeated idles without intervening draw calls.
1474 * On adreno 225 the PC block has a cache that is only
1475 * flushed on draw calls and repeated idles can make it
1476 * overflow. The gmem save path contains draw calls so
1477 * this workaround isn't needed there.
1478 */
1479 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1480 *cmds++ = (0x4 << 16) | (REG_PA_SU_SC_MODE_CNTL - 0x2000);
1481 *cmds++ = 0;
1482 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 5);
1483 *cmds++ = 0;
1484 *cmds++ = 1<<14;
1485 *cmds++ = 0;
1486 *cmds++ = device->mmu.setstate_memory.gpuaddr;
1487 *cmds++ = 0;
1488 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
1489 *cmds++ = 0x00000000;
1490 } else {
1491 /* On Adreno 20x/220, if the events for shader space reuse
1492 * gets dropped, the CP block would wait indefinitely.
1493 * Sending CP_SET_SHADER_BASES packet unblocks the CP from
1494 * this wait.
1495 */
1496 *cmds++ = cp_type3_packet(CP_SET_SHADER_BASES, 1);
1497 *cmds++ = adreno_encode_istore_size(adreno_dev)
1498 | adreno_dev->pix_shader_start;
1499 }
Shubhraprakash Das4624b552012-06-01 14:08:03 -06001500
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001501 adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_PMODE,
Ranjhith Kalisamyd71cfd62012-06-22 19:37:51 +05301502 &cmd[0], cmds - cmd);
Shubhraprakash Das4624b552012-06-01 14:08:03 -06001503}
1504
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001505static void a2xx_drawctxt_save(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
Shubhraprakash Dasc9ec2662012-11-20 11:10:41 -07001510 if (context == NULL || (context->flags & CTXT_FLAGS_BEING_DESTROYED))
Jordan Crousea78c9172011-07-11 13:14:09 -06001511 return;
1512
1513 if (context->flags & CTXT_FLAGS_GPU_HANG)
1514 KGSL_CTXT_WARN(device,
1515 "Current active context has caused gpu hang\n");
1516
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001517 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001518
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001519 /* save registers and constants. */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001520 adreno_ringbuffer_issuecmds(device, context,
1521 KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001522 context->reg_save, 3);
Jordan Crousea78c9172011-07-11 13:14:09 -06001523
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001524 if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
1525 /* save shader partitioning and instructions. */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001526 adreno_ringbuffer_issuecmds(device, context,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001527 KGSL_CMD_FLAGS_PMODE,
1528 context->shader_save, 3);
1529
1530 /*
1531 * fixup shader partitioning parameter for
1532 * SET_SHADER_BASES.
1533 */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001534 adreno_ringbuffer_issuecmds(device, context,
1535 KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001536 context->shader_fixup, 3);
1537
1538 context->flags |= CTXT_FLAGS_SHADER_RESTORE;
1539 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001540 }
1541
1542 if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
1543 (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
1544 /* save gmem.
1545 * (note: changes shader. shader must already be saved.)
1546 */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001547 adreno_ringbuffer_issuecmds(device, context,
1548 KGSL_CMD_FLAGS_PMODE,
Jordan Crousea78c9172011-07-11 13:14:09 -06001549 context->context_gmem_shadow.gmem_save, 3);
1550
1551 /* Restore TP0_CHICKEN */
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001552 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001553 adreno_ringbuffer_issuecmds(device, context,
1554 KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001555 context->chicken_restore, 3);
1556 }
Shubhraprakash Das4624b552012-06-01 14:08:03 -06001557 adreno_dev->gpudev->ctx_switches_since_last_draw = 0;
Jordan Crousea78c9172011-07-11 13:14:09 -06001558
1559 context->flags |= CTXT_FLAGS_GMEM_RESTORE;
Ranjhith Kalisamyd71cfd62012-06-22 19:37:51 +05301560 } else if (adreno_is_a2xx(adreno_dev))
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001561 a2xx_drawctxt_draw_workaround(adreno_dev, context);
Jordan Crousea78c9172011-07-11 13:14:09 -06001562}
1563
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001564static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
Jordan Crousea78c9172011-07-11 13:14:09 -06001565 struct adreno_context *context)
1566{
1567 struct kgsl_device *device = &adreno_dev->dev;
1568 unsigned int cmds[5];
1569
1570 if (context == NULL) {
1571 /* No context - set the default apgetable and thats it */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001572 kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable,
1573 adreno_dev->drawctxt_active->id);
Jordan Crousea78c9172011-07-11 13:14:09 -06001574 return;
1575 }
1576
1577 KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
1578
Jordan Crouse084427d2011-07-28 08:37:58 -06001579 cmds[0] = cp_nop_packet(1);
Jordan Crousea78c9172011-07-11 13:14:09 -06001580 cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
Jordan Crouse084427d2011-07-28 08:37:58 -06001581 cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
Jordan Crousea78c9172011-07-11 13:14:09 -06001582 cmds[3] = device->memstore.gpuaddr +
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001583 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
1584 cmds[4] = context->id;
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001585 adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
1586 cmds, 5);
1587 kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
Jordan Crousea78c9172011-07-11 13:14:09 -06001588
1589#ifndef CONFIG_MSM_KGSL_CFF_DUMP_NO_CONTEXT_MEM_DUMP
1590 kgsl_cffdump_syncmem(NULL, &context->gpustate,
1591 context->gpustate.gpuaddr, LCC_SHADOW_SIZE +
1592 REG_SHADOW_SIZE + CMD_BUFFER_SIZE + TEX_SHADOW_SIZE, false);
1593#endif
1594
1595 /* restore gmem.
1596 * (note: changes shader. shader must not already be restored.)
1597 */
1598 if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001599 adreno_ringbuffer_issuecmds(device, context,
1600 KGSL_CMD_FLAGS_PMODE,
Jordan Crousea78c9172011-07-11 13:14:09 -06001601 context->context_gmem_shadow.gmem_restore, 3);
1602
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001603 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
1604 /* Restore TP0_CHICKEN */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001605 adreno_ringbuffer_issuecmds(device, context,
1606 KGSL_CMD_FLAGS_NONE,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001607 context->chicken_restore, 3);
1608 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001609
1610 context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
1611 }
1612
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001613 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001614
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001615 /* restore registers and constants. */
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001616 adreno_ringbuffer_issuecmds(device, context,
1617 KGSL_CMD_FLAGS_NONE, context->reg_restore, 3);
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001618
1619 /* restore shader instructions & partitioning. */
1620 if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001621 adreno_ringbuffer_issuecmds(device, context,
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07001622 KGSL_CMD_FLAGS_NONE,
1623 context->shader_restore, 3);
1624 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001625 }
1626
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001627 if (adreno_is_a20x(adreno_dev)) {
Jordan Crouse084427d2011-07-28 08:37:58 -06001628 cmds[0] = cp_type3_packet(CP_SET_BIN_BASE_OFFSET, 1);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001629 cmds[1] = context->bin_base_offset;
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06001630 adreno_ringbuffer_issuecmds(device, context,
1631 KGSL_CMD_FLAGS_NONE, cmds, 2);
Jeremy Gebben5bb7ece2011-08-02 11:04:48 -06001632 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001633}
1634
1635/*
1636 * Interrupt management
1637 *
1638 * a2xx interrupt control is distributed among the various
1639 * hardware components (RB, CP, MMU). The main interrupt
1640 * tells us which component fired the interrupt, but one needs
1641 * to go to the individual component to find out why. The
1642 * following functions provide the broken out support for
1643 * managing the interrupts
1644 */
1645
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001646#define RBBM_INT_MASK RBBM_INT_CNTL__RDERR_INT_MASK
Jordan Crousea78c9172011-07-11 13:14:09 -06001647
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001648#define CP_INT_MASK \
1649 (CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001650 CP_INT_CNTL__OPCODE_ERROR_MASK | \
1651 CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \
1652 CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \
1653 CP_INT_CNTL__IB_ERROR_MASK | \
Jordan Crousea78c9172011-07-11 13:14:09 -06001654 CP_INT_CNTL__IB1_INT_MASK | \
1655 CP_INT_CNTL__RB_INT_MASK)
1656
1657#define VALID_STATUS_COUNT_MAX 10
1658
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001659static struct {
1660 unsigned int mask;
1661 const char *message;
1662} kgsl_cp_error_irqs[] = {
1663 { CP_INT_CNTL__T0_PACKET_IN_IB_MASK,
1664 "ringbuffer TO packet in IB interrupt" },
1665 { CP_INT_CNTL__OPCODE_ERROR_MASK,
1666 "ringbuffer opcode error interrupt" },
1667 { CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK,
1668 "ringbuffer protected mode error interrupt" },
1669 { CP_INT_CNTL__RESERVED_BIT_ERROR_MASK,
1670 "ringbuffer reserved bit error interrupt" },
1671 { CP_INT_CNTL__IB_ERROR_MASK,
1672 "ringbuffer IB error interrupt" },
1673};
1674
Jordan Crousea78c9172011-07-11 13:14:09 -06001675static void a2xx_cp_intrcallback(struct kgsl_device *device)
1676{
1677 unsigned int status = 0, num_reads = 0, master_status = 0;
1678 struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
1679 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001680 int i;
Jordan Crousea78c9172011-07-11 13:14:09 -06001681
1682 adreno_regread(device, REG_MASTER_INT_SIGNAL, &master_status);
1683 while (!status && (num_reads < VALID_STATUS_COUNT_MAX) &&
1684 (master_status & MASTER_INT_SIGNAL__CP_INT_STAT)) {
1685 adreno_regread(device, REG_CP_INT_STATUS, &status);
1686 adreno_regread(device, REG_MASTER_INT_SIGNAL,
1687 &master_status);
1688 num_reads++;
1689 }
1690 if (num_reads > 1)
1691 KGSL_DRV_WARN(device,
1692 "Looped %d times to read REG_CP_INT_STATUS\n",
1693 num_reads);
Norman Geed7402ff2011-10-28 08:51:11 -06001694
1695 trace_kgsl_a2xx_irq_status(device, master_status, status);
1696
Jordan Crousea78c9172011-07-11 13:14:09 -06001697 if (!status) {
1698 if (master_status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1699 /* This indicates that we could not read CP_INT_STAT.
1700 * As a precaution just wake up processes so
1701 * they can check their timestamps. Since, we
1702 * did not ack any interrupts this interrupt will
1703 * be generated again */
1704 KGSL_DRV_WARN(device, "Unable to read CP_INT_STATUS\n");
1705 wake_up_interruptible_all(&device->wait_queue);
1706 } else
1707 KGSL_DRV_WARN(device, "Spurious interrput detected\n");
1708 return;
1709 }
1710
1711 if (status & CP_INT_CNTL__RB_INT_MASK) {
1712 /* signal intr completion event */
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001713 unsigned int context_id;
1714 kgsl_sharedmem_readl(&device->memstore,
1715 &context_id,
1716 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
1717 current_context));
1718 if (context_id < KGSL_MEMSTORE_MAX) {
Carter Cooperbedd2282012-11-05 11:53:54 -07001719 /* reset per context ts_cmp_enable */
1720 kgsl_sharedmem_writel(&device->memstore,
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001721 KGSL_MEMSTORE_OFFSET(context_id,
1722 ts_cmp_enable), 0);
Carter Cooperbedd2282012-11-05 11:53:54 -07001723 /* Always reset global timestamp ts_cmp_enable */
1724 kgsl_sharedmem_writel(&device->memstore,
1725 KGSL_MEMSTORE_OFFSET(
1726 KGSL_MEMSTORE_GLOBAL,
1727 ts_cmp_enable), 0);
Carter Cooper7e7f02e2012-02-15 09:36:31 -07001728 wmb();
1729 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001730 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
1731 }
1732
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001733 for (i = 0; i < ARRAY_SIZE(kgsl_cp_error_irqs); i++) {
1734 if (status & kgsl_cp_error_irqs[i].mask) {
1735 KGSL_CMD_CRIT(rb->device, "%s\n",
1736 kgsl_cp_error_irqs[i].message);
1737 /*
1738 * on fatal errors, turn off the interrupts to
1739 * avoid storming. This has the side effect of
1740 * forcing a PM dump when the timestamp times out
1741 */
Jordan Crousea78c9172011-07-11 13:14:09 -06001742
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001743 kgsl_pwrctrl_irq(rb->device, KGSL_PWRFLAGS_OFF);
1744 }
1745 }
Jordan Crousea78c9172011-07-11 13:14:09 -06001746
1747 /* only ack bits we understand */
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001748 status &= CP_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001749 adreno_regwrite(device, REG_CP_INT_ACK, status);
1750
1751 if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
1752 KGSL_CMD_WARN(rb->device, "ringbuffer ib1/rb interrupt\n");
Jordan Crouse1bf80aa2011-10-12 16:57:47 -06001753 queue_work(device->work_queue, &device->ts_expired_ws);
Jordan Crousea78c9172011-07-11 13:14:09 -06001754 wake_up_interruptible_all(&device->wait_queue);
1755 atomic_notifier_call_chain(&(device->ts_notifier_list),
1756 device->id,
1757 NULL);
1758 }
1759}
1760
1761static void a2xx_rbbm_intrcallback(struct kgsl_device *device)
1762{
1763 unsigned int status = 0;
1764 unsigned int rderr = 0;
Jeremy Gebben22784c22012-03-07 16:02:08 -07001765 unsigned int addr = 0;
1766 const char *source;
Jordan Crousea78c9172011-07-11 13:14:09 -06001767
1768 adreno_regread(device, REG_RBBM_INT_STATUS, &status);
1769
1770 if (status & RBBM_INT_CNTL__RDERR_INT_MASK) {
Jordan Crousea78c9172011-07-11 13:14:09 -06001771 adreno_regread(device, REG_RBBM_READ_ERROR, &rderr);
Jeremy Gebben22784c22012-03-07 16:02:08 -07001772 source = (rderr & RBBM_READ_ERROR_REQUESTER)
1773 ? "host" : "cp";
1774 /* convert to dword address */
1775 addr = (rderr & RBBM_READ_ERROR_ADDRESS_MASK) >> 2;
1776
1777 /*
1778 * Log CP_INT_STATUS interrupts from the CP at a
1779 * lower level because they can happen frequently
1780 * and are worked around in a2xx_irq_handler.
1781 */
1782 if (addr == REG_CP_INT_STATUS &&
1783 rderr & RBBM_READ_ERROR_ERROR &&
1784 rderr & RBBM_READ_ERROR_REQUESTER)
Jordan Crousea78c9172011-07-11 13:14:09 -06001785 KGSL_DRV_WARN(device,
Jeremy Gebben22784c22012-03-07 16:02:08 -07001786 "rbbm read error interrupt: %s reg: %04X\n",
1787 source, addr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001788 else
1789 KGSL_DRV_CRIT(device,
Jeremy Gebben22784c22012-03-07 16:02:08 -07001790 "rbbm read error interrupt: %s reg: %04X\n",
1791 source, addr);
Jordan Crousea78c9172011-07-11 13:14:09 -06001792 }
1793
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001794 status &= RBBM_INT_MASK;
Jordan Crousea78c9172011-07-11 13:14:09 -06001795 adreno_regwrite(device, REG_RBBM_INT_ACK, status);
1796}
1797
1798irqreturn_t a2xx_irq_handler(struct adreno_device *adreno_dev)
1799{
1800 struct kgsl_device *device = &adreno_dev->dev;
1801 irqreturn_t result = IRQ_NONE;
1802 unsigned int status;
1803
1804 adreno_regread(device, REG_MASTER_INT_SIGNAL, &status);
1805
1806 if (status & MASTER_INT_SIGNAL__MH_INT_STAT) {
1807 kgsl_mh_intrcallback(device);
1808 result = IRQ_HANDLED;
1809 }
1810
1811 if (status & MASTER_INT_SIGNAL__CP_INT_STAT) {
1812 a2xx_cp_intrcallback(device);
1813 result = IRQ_HANDLED;
1814 }
1815
1816 if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) {
1817 a2xx_rbbm_intrcallback(device);
1818 result = IRQ_HANDLED;
1819 }
1820
1821 return result;
1822}
1823
1824static void a2xx_irq_control(struct adreno_device *adreno_dev, int state)
1825{
1826 struct kgsl_device *device = &adreno_dev->dev;
1827
1828 if (state) {
Jordan Crousec8c9fcd2011-07-28 08:37:58 -06001829 adreno_regwrite(device, REG_RBBM_INT_CNTL, RBBM_INT_MASK);
1830 adreno_regwrite(device, REG_CP_INT_CNTL, CP_INT_MASK);
Anoop Kumar Yerukala5479c9c2012-07-08 14:53:06 +05301831 adreno_regwrite(device, MH_INTERRUPT_MASK,
1832 kgsl_mmu_get_int_mask());
Jordan Crousea78c9172011-07-11 13:14:09 -06001833 } else {
1834 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
1835 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
1836 adreno_regwrite(device, MH_INTERRUPT_MASK, 0);
1837 }
Jordan Crouseb58e61b2011-08-08 13:25:36 -06001838
1839 /* Force the writes to post before touching the IRQ line */
1840 wmb();
Jordan Crousea78c9172011-07-11 13:14:09 -06001841}
1842
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001843static void a2xx_rb_init(struct adreno_device *adreno_dev,
1844 struct adreno_ringbuffer *rb)
1845{
1846 unsigned int *cmds, cmds_gpu;
1847
1848 /* ME_INIT */
Shubhraprakash Dasd316ff82012-08-02 12:43:48 -07001849 cmds = adreno_ringbuffer_allocspace(rb, NULL, 19);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001850 cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint)*(rb->wptr-19);
1851
1852 GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 18));
1853 /* All fields present (bits 9:0) */
1854 GSL_RB_WRITE(cmds, cmds_gpu, 0x000003ff);
1855 /* Disable/Enable Real-Time Stream processing (present but ignored) */
1856 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1857 /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
1858 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1859
1860 GSL_RB_WRITE(cmds, cmds_gpu,
1861 SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
1862 GSL_RB_WRITE(cmds, cmds_gpu,
1863 SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
1864 GSL_RB_WRITE(cmds, cmds_gpu,
1865 SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
1866 GSL_RB_WRITE(cmds, cmds_gpu,
1867 SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
1868 GSL_RB_WRITE(cmds, cmds_gpu,
1869 SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
1870 GSL_RB_WRITE(cmds, cmds_gpu,
1871 SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
1872 GSL_RB_WRITE(cmds, cmds_gpu,
1873 SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
1874 GSL_RB_WRITE(cmds, cmds_gpu,
1875 SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
1876
1877 /* Instruction memory size: */
1878 GSL_RB_WRITE(cmds, cmds_gpu,
1879 (adreno_encode_istore_size(adreno_dev)
1880 | adreno_dev->pix_shader_start));
1881 /* Maximum Contexts */
1882 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
1883 /* Write Confirm Interval and The CP will wait the
1884 * wait_interval * 16 clocks between polling */
1885 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1886
1887 /* NQ and External Memory Swap */
1888 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
Shubhraprakash Dasc6e21012012-05-11 17:24:51 -06001889 /* Protected mode error checking
1890 * If iommu is used then protection needs to be turned off
1891 * to enable context bank switching */
1892 if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_get_mmutype())
1893 GSL_RB_WRITE(cmds, cmds_gpu, 0);
1894 else
1895 GSL_RB_WRITE(cmds, cmds_gpu, GSL_RB_PROTECTED_MODE_CONTROL);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001896 /* Disable header dumping and Header dump address */
1897 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1898 /* Header dump size */
1899 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
1900
1901 adreno_ringbuffer_submit(rb);
1902}
1903
1904static unsigned int a2xx_busy_cycles(struct adreno_device *adreno_dev)
1905{
1906 struct kgsl_device *device = &adreno_dev->dev;
1907 unsigned int reg, val;
1908
1909 /* Freeze the counter */
1910 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1911 REG_PERF_MODE_CNT | REG_PERF_STATE_FREEZE);
1912
1913 /* Get the value */
1914 adreno_regread(device, REG_RBBM_PERFCOUNTER1_LO, &val);
1915
1916 /* Reset the counter */
1917 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1918 REG_PERF_MODE_CNT | REG_PERF_STATE_RESET);
1919
1920 /* Re-Enable the performance monitors */
1921 adreno_regread(device, REG_RBBM_PM_OVERRIDE2, &reg);
1922 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, (reg | 0x40));
1923 adreno_regwrite(device, REG_RBBM_PERFCOUNTER1_SELECT, 0x1);
1924 adreno_regwrite(device, REG_CP_PERFMON_CNTL,
1925 REG_PERF_MODE_CNT | REG_PERF_STATE_ENABLE);
1926
1927 return val;
1928}
1929
1930static void a2xx_gmeminit(struct adreno_device *adreno_dev)
1931{
1932 struct kgsl_device *device = &adreno_dev->dev;
1933 union reg_rb_edram_info rb_edram_info;
1934 unsigned int gmem_size;
1935 unsigned int edram_value = 0;
1936
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001937 /* get edram_size value equivalent */
Jordan Crouse7501d452012-04-19 08:58:44 -06001938 gmem_size = (adreno_dev->gmem_size >> 14);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001939 while (gmem_size >>= 1)
1940 edram_value++;
1941
1942 rb_edram_info.val = 0;
1943
1944 rb_edram_info.f.edram_size = edram_value;
1945 rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */
1946
1947 /* must be aligned to size */
Jordan Crouse7501d452012-04-19 08:58:44 -06001948 rb_edram_info.f.edram_range = (adreno_dev->gmem_base >> 14);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001949
1950 adreno_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val);
1951}
1952
1953static void a2xx_start(struct adreno_device *adreno_dev)
1954{
1955 struct kgsl_device *device = &adreno_dev->dev;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001956
1957 /*
1958 * We need to make sure all blocks are powered up and clocked
1959 * before issuing a soft reset. The overrides will then be
1960 * turned off (set to 0)
1961 */
1962 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe);
1963 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff);
1964
1965 /*
1966 * Only reset CP block if all blocks have previously been
1967 * reset
1968 */
1969 if (!(device->flags & KGSL_FLAGS_SOFT_RESET) ||
1970 !adreno_is_a22x(adreno_dev)) {
1971 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1972 0xFFFFFFFF);
1973 device->flags |= KGSL_FLAGS_SOFT_RESET;
1974 } else {
1975 adreno_regwrite(device, REG_RBBM_SOFT_RESET,
1976 0x00000001);
1977 }
1978 /*
1979 * The core is in an indeterminate state until the reset
1980 * completes after 30ms.
1981 */
1982 msleep(30);
1983
1984 adreno_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000);
1985
1986 if (adreno_is_a225(adreno_dev)) {
1987 /* Enable large instruction store for A225 */
1988 adreno_regwrite(device, REG_SQ_FLOW_CONTROL,
1989 0x18000000);
1990 }
1991
Rammohan Basavarajucf3252d2012-08-28 16:30:25 +05301992 if (adreno_is_a20x(adreno_dev))
1993 /* For A20X based targets increase number of clocks
1994 * that RBBM will wait before de-asserting Register
1995 * Clock Active signal */
Rajesh Kemisetti7a5d18c2012-08-02 14:48:06 +05301996 adreno_regwrite(device, REG_RBBM_CNTL, 0x0000FFFF);
1997 else
1998 adreno_regwrite(device, REG_RBBM_CNTL, 0x00004442);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001999
2000 adreno_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000);
2001 adreno_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000);
2002
Sudhakara Rao Tentudaebac22012-04-02 14:51:29 -07002003 if (cpu_is_msm8960())
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002004 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0x200);
2005 else
2006 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0);
2007
2008 if (!adreno_is_a22x(adreno_dev))
2009 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0);
2010 else
2011 adreno_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0x80);
2012
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002013 adreno_regwrite(device, REG_RBBM_DEBUG, 0x00080000);
2014
2015 /* Make sure interrupts are disabled */
2016 adreno_regwrite(device, REG_RBBM_INT_CNTL, 0);
2017 adreno_regwrite(device, REG_CP_INT_CNTL, 0);
2018 adreno_regwrite(device, REG_SQ_INT_CNTL, 0);
2019
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002020 a2xx_gmeminit(adreno_dev);
2021}
2022
Jordan Crouse156cfbc2012-01-24 09:32:04 -07002023/* Defined in adreno_a2xx_snapshot.c */
2024void *a2xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
2025 int *remain, int hang);
2026
Jordan Crousea78c9172011-07-11 13:14:09 -06002027struct adreno_gpudev adreno_a2xx_gpudev = {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002028 .reg_rbbm_status = REG_RBBM_STATUS,
2029 .reg_cp_pfp_ucode_addr = REG_CP_PFP_UCODE_ADDR,
2030 .reg_cp_pfp_ucode_data = REG_CP_PFP_UCODE_DATA,
2031
Vijay Krishnamoorthybef66932012-01-24 09:32:05 -07002032 .ctxt_create = a2xx_drawctxt_create,
2033 .ctxt_save = a2xx_drawctxt_save,
2034 .ctxt_restore = a2xx_drawctxt_restore,
Shubhraprakash Dasb2abc452012-06-08 16:33:03 -06002035 .ctxt_draw_workaround = a2xx_drawctxt_draw_workaround,
Jordan Crousea78c9172011-07-11 13:14:09 -06002036 .irq_handler = a2xx_irq_handler,
2037 .irq_control = a2xx_irq_control,
Jordan Crouse156cfbc2012-01-24 09:32:04 -07002038 .snapshot = a2xx_snapshot,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002039 .rb_init = a2xx_rb_init,
2040 .busy_cycles = a2xx_busy_cycles,
2041 .start = a2xx_start,
Jordan Crousea78c9172011-07-11 13:14:09 -06002042};