blob: 09eae174519ef44bf9af156fa6577f26a566f2da [file] [log] [blame]
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/delay.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070015#include <linux/sched.h>
Sudhakara Rao Tentu5746bde2012-03-15 12:16:32 +053016#include <mach/socinfo.h>
Jordan Crouseb4d31bd2012-02-01 22:11:12 -070017
18#include "kgsl.h"
19#include "adreno.h"
20#include "kgsl_sharedmem.h"
21#include "kgsl_cffdump.h"
22#include "a3xx_reg.h"
Carter Cooperb769c912012-04-13 08:16:35 -060023#include "adreno_a3xx_trace.h"
Jordan Crouseb4d31bd2012-02-01 22:11:12 -070024
Jordan Crouse0c2761a2012-02-01 22:11:12 -070025/*
26 * Set of registers to dump for A3XX on postmortem and snapshot.
27 * Registers in pairs - first value is the start offset, second
28 * is the stop offset (inclusive)
29 */
30
31const unsigned int a3xx_registers[] = {
32 0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027,
33 0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c,
34 0x0060, 0x006c, 0x0080, 0x0082, 0x0084, 0x0088, 0x0090, 0x00e5,
35 0x00ea, 0x00ed, 0x0100, 0x0100, 0x0110, 0x0123, 0x01c0, 0x01c1,
36 0x01c3, 0x01c5, 0x01c7, 0x01c7, 0x01d5, 0x01d9, 0x01dc, 0x01dd,
37 0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
38 0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
39 0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
Jordan Crouse55d98fd2012-02-04 10:23:51 -070040 0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
Jordan Crouse0c2761a2012-02-01 22:11:12 -070041 0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
42 0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
43 0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
44 0x0e0c, 0x0e0c, 0x0e22, 0x0e23, 0x0e41, 0x0e45, 0x0e64, 0x0e65,
45 0x0e80, 0x0e82, 0x0e84, 0x0e89, 0x0ea0, 0x0ea1, 0x0ea4, 0x0ea7,
46 0x0ec4, 0x0ecb, 0x0ee0, 0x0ee0, 0x0f00, 0x0f01, 0x0f03, 0x0f09,
47 0x2040, 0x2040, 0x2044, 0x2044, 0x2048, 0x204d, 0x2068, 0x2069,
48 0x206c, 0x206d, 0x2070, 0x2070, 0x2072, 0x2072, 0x2074, 0x2075,
49 0x2079, 0x207a, 0x20c0, 0x20d3, 0x20e4, 0x20ef, 0x2100, 0x2109,
50 0x210c, 0x210c, 0x210e, 0x210e, 0x2110, 0x2111, 0x2114, 0x2115,
51 0x21e4, 0x21e4, 0x21ea, 0x21ea, 0x21ec, 0x21ed, 0x21f0, 0x21f0,
52 0x2200, 0x2212, 0x2214, 0x2217, 0x221a, 0x221a, 0x2240, 0x227e,
53 0x2280, 0x228b, 0x22c0, 0x22c0, 0x22c4, 0x22ce, 0x22d0, 0x22d8,
54 0x22df, 0x22e6, 0x22e8, 0x22e9, 0x22ec, 0x22ec, 0x22f0, 0x22f7,
55 0x22ff, 0x22ff, 0x2340, 0x2343, 0x2348, 0x2349, 0x2350, 0x2356,
56 0x2360, 0x2360, 0x2440, 0x2440, 0x2444, 0x2444, 0x2448, 0x244d,
57 0x2468, 0x2469, 0x246c, 0x246d, 0x2470, 0x2470, 0x2472, 0x2472,
58 0x2474, 0x2475, 0x2479, 0x247a, 0x24c0, 0x24d3, 0x24e4, 0x24ef,
59 0x2500, 0x2509, 0x250c, 0x250c, 0x250e, 0x250e, 0x2510, 0x2511,
60 0x2514, 0x2515, 0x25e4, 0x25e4, 0x25ea, 0x25ea, 0x25ec, 0x25ed,
61 0x25f0, 0x25f0, 0x2600, 0x2612, 0x2614, 0x2617, 0x261a, 0x261a,
62 0x2640, 0x267e, 0x2680, 0x268b, 0x26c0, 0x26c0, 0x26c4, 0x26ce,
63 0x26d0, 0x26d8, 0x26df, 0x26e6, 0x26e8, 0x26e9, 0x26ec, 0x26ec,
64 0x26f0, 0x26f7, 0x26ff, 0x26ff, 0x2740, 0x2743, 0x2748, 0x2749,
Jordan Crouse1268f9c2012-02-21 08:54:53 -070065 0x2750, 0x2756, 0x2760, 0x2760, 0x300C, 0x300E, 0x301C, 0x301D,
66 0x302A, 0x302A, 0x302C, 0x302D, 0x3030, 0x3031, 0x3034, 0x3036,
67 0x303C, 0x303C, 0x305E, 0x305F,
Jordan Crouse0c2761a2012-02-01 22:11:12 -070068};
69
70const unsigned int a3xx_registers_count = ARRAY_SIZE(a3xx_registers) / 2;
71
Jordan Crouseb4d31bd2012-02-01 22:11:12 -070072/* Simple macro to facilitate bit setting in the gmem2sys and sys2gmem
73 * functions.
74 */
75
76#define _SET(_shift, _val) ((_val) << (_shift))
77
78/*
79 ****************************************************************************
80 *
81 * Context state shadow structure:
82 *
83 * +---------------------+------------+-------------+---------------------+---+
84 * | ALU Constant Shadow | Reg Shadow | C&V Buffers | Shader Instr Shadow |Tex|
85 * +---------------------+------------+-------------+---------------------+---+
86 *
87 * 8K - ALU Constant Shadow (8K aligned)
88 * 4K - H/W Register Shadow (8K aligned)
89 * 5K - Command and Vertex Buffers
90 * 8K - Shader Instruction Shadow
91 * ~6K - Texture Constant Shadow
92 *
93 *
94 ***************************************************************************
95 */
96
97/* Sizes of all sections in state shadow memory */
98#define ALU_SHADOW_SIZE (8*1024) /* 8KB */
99#define REG_SHADOW_SIZE (4*1024) /* 4KB */
100#define CMD_BUFFER_SIZE (5*1024) /* 5KB */
101#define TEX_SIZE_MEM_OBJECTS 896 /* bytes */
102#define TEX_SIZE_MIPMAP 1936 /* bytes */
103#define TEX_SIZE_SAMPLER_OBJ 256 /* bytes */
104#define TEX_SHADOW_SIZE \
105 ((TEX_SIZE_MEM_OBJECTS + TEX_SIZE_MIPMAP + \
106 TEX_SIZE_SAMPLER_OBJ)*2) /* ~6KB */
107#define SHADER_SHADOW_SIZE (8*1024) /* 8KB */
108
109/* Total context size, excluding GMEM shadow */
110#define CONTEXT_SIZE \
111 (ALU_SHADOW_SIZE+REG_SHADOW_SIZE + \
112 CMD_BUFFER_SIZE+SHADER_SHADOW_SIZE + \
113 TEX_SHADOW_SIZE)
114
115/* Offsets to different sections in context shadow memory */
116#define REG_OFFSET ALU_SHADOW_SIZE
117#define CMD_OFFSET (REG_OFFSET+REG_SHADOW_SIZE)
118#define SHADER_OFFSET (CMD_OFFSET+CMD_BUFFER_SIZE)
119#define TEX_OFFSET (SHADER_OFFSET+SHADER_SHADOW_SIZE)
120#define VS_TEX_OFFSET_MEM_OBJECTS TEX_OFFSET
121#define VS_TEX_OFFSET_MIPMAP (VS_TEX_OFFSET_MEM_OBJECTS+TEX_SIZE_MEM_OBJECTS)
122#define VS_TEX_OFFSET_SAMPLER_OBJ (VS_TEX_OFFSET_MIPMAP+TEX_SIZE_MIPMAP)
123#define FS_TEX_OFFSET_MEM_OBJECTS \
124 (VS_TEX_OFFSET_SAMPLER_OBJ+TEX_SIZE_SAMPLER_OBJ)
125#define FS_TEX_OFFSET_MIPMAP (FS_TEX_OFFSET_MEM_OBJECTS+TEX_SIZE_MEM_OBJECTS)
126#define FS_TEX_OFFSET_SAMPLER_OBJ (FS_TEX_OFFSET_MIPMAP+TEX_SIZE_MIPMAP)
127
128/* The offset for fragment shader data in HLSQ context */
129#define SSIZE (16*1024)
130
131#define HLSQ_SAMPLER_OFFSET 0x000
132#define HLSQ_MEMOBJ_OFFSET 0x400
133#define HLSQ_MIPMAP_OFFSET 0x800
134
Jordan Crouseb4d31bd2012-02-01 22:11:12 -0700135/* Use shadow RAM */
136#define HLSQ_SHADOW_BASE (0x10000+SSIZE*2)
Jordan Crouseb4d31bd2012-02-01 22:11:12 -0700137
Jordan Croused0070882012-02-21 08:54:52 -0700138#define REG_TO_MEM_LOOP_COUNT_SHIFT 18
Jordan Crouseb4d31bd2012-02-01 22:11:12 -0700139
140#define BUILD_PC_DRAW_INITIATOR(prim_type, source_select, index_size, \
141 vis_cull_mode) \
142 (((prim_type) << PC_DRAW_INITIATOR_PRIM_TYPE) | \
143 ((source_select) << PC_DRAW_INITIATOR_SOURCE_SELECT) | \
144 ((index_size & 1) << PC_DRAW_INITIATOR_INDEX_SIZE) | \
145 ((index_size >> 1) << PC_DRAW_INITIATOR_SMALL_INDEX) | \
146 ((vis_cull_mode) << PC_DRAW_INITIATOR_VISIBILITY_CULLING_MODE) | \
147 (1 << PC_DRAW_INITIATOR_PRE_DRAW_INITIATOR_ENABLE))
148
149/*
150 * List of context registers (starting from dword offset 0x2000).
151 * Each line contains start and end of a range of registers.
152 */
153static const unsigned int context_register_ranges[] = {
154 A3XX_GRAS_CL_CLIP_CNTL, A3XX_GRAS_CL_CLIP_CNTL,
155 A3XX_GRAS_CL_GB_CLIP_ADJ, A3XX_GRAS_CL_GB_CLIP_ADJ,
156 A3XX_GRAS_CL_VPORT_XOFFSET, A3XX_GRAS_CL_VPORT_ZSCALE,
157 A3XX_GRAS_SU_POINT_MINMAX, A3XX_GRAS_SU_POINT_SIZE,
158 A3XX_GRAS_SU_POLY_OFFSET_SCALE, A3XX_GRAS_SU_POLY_OFFSET_OFFSET,
159 A3XX_GRAS_SU_MODE_CONTROL, A3XX_GRAS_SU_MODE_CONTROL,
160 A3XX_GRAS_SC_CONTROL, A3XX_GRAS_SC_CONTROL,
161 A3XX_GRAS_SC_SCREEN_SCISSOR_TL, A3XX_GRAS_SC_SCREEN_SCISSOR_BR,
162 A3XX_GRAS_SC_WINDOW_SCISSOR_TL, A3XX_GRAS_SC_WINDOW_SCISSOR_BR,
163 A3XX_RB_MODE_CONTROL, A3XX_RB_MRT_BLEND_CONTROL3,
164 A3XX_RB_BLEND_RED, A3XX_RB_COPY_DEST_INFO,
165 A3XX_RB_DEPTH_CONTROL, A3XX_RB_DEPTH_CONTROL,
166 A3XX_PC_VSTREAM_CONTROL, A3XX_PC_VSTREAM_CONTROL,
167 A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, A3XX_PC_VERTEX_REUSE_BLOCK_CNTL,
168 A3XX_PC_PRIM_VTX_CNTL, A3XX_PC_RESTART_INDEX,
169 A3XX_HLSQ_CONTROL_0_REG, A3XX_HLSQ_CONST_FSPRESV_RANGE_REG,
170 A3XX_HLSQ_CL_NDRANGE_0_REG, A3XX_HLSQ_CL_NDRANGE_0_REG,
171 A3XX_HLSQ_CL_NDRANGE_2_REG, A3XX_HLSQ_CL_CONTROL_1_REG,
172 A3XX_HLSQ_CL_KERNEL_CONST_REG, A3XX_HLSQ_CL_KERNEL_GROUP_Z_REG,
173 A3XX_HLSQ_CL_WG_OFFSET_REG, A3XX_HLSQ_CL_WG_OFFSET_REG,
174 A3XX_VFD_CONTROL_0, A3XX_VFD_VS_THREADING_THRESHOLD,
175 A3XX_SP_SP_CTRL_REG, A3XX_SP_SP_CTRL_REG,
176 A3XX_SP_VS_CTRL_REG0, A3XX_SP_VS_OUT_REG_7,
177 A3XX_SP_VS_VPC_DST_REG_0, A3XX_SP_VS_PVT_MEM_SIZE_REG,
178 A3XX_SP_VS_LENGTH_REG, A3XX_SP_FS_PVT_MEM_SIZE_REG,
179 A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, A3XX_SP_FS_FLAT_SHAD_MODE_REG_1,
180 A3XX_SP_FS_OUTPUT_REG, A3XX_SP_FS_OUTPUT_REG,
181 A3XX_SP_FS_MRT_REG_0, A3XX_SP_FS_IMAGE_OUTPUT_REG_3,
182 A3XX_SP_FS_LENGTH_REG, A3XX_SP_FS_LENGTH_REG,
183 A3XX_TPL1_TP_VS_TEX_OFFSET, A3XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR,
184 A3XX_VPC_ATTR, A3XX_VPC_VARY_CYLWRAP_ENABLE_1,
185};
186
187/* Global registers that need to be saved separately */
188static const unsigned int global_registers[] = {
189 A3XX_GRAS_CL_USER_PLANE_X0, A3XX_GRAS_CL_USER_PLANE_Y0,
190 A3XX_GRAS_CL_USER_PLANE_Z0, A3XX_GRAS_CL_USER_PLANE_W0,
191 A3XX_GRAS_CL_USER_PLANE_X1, A3XX_GRAS_CL_USER_PLANE_Y1,
192 A3XX_GRAS_CL_USER_PLANE_Z1, A3XX_GRAS_CL_USER_PLANE_W1,
193 A3XX_GRAS_CL_USER_PLANE_X2, A3XX_GRAS_CL_USER_PLANE_Y2,
194 A3XX_GRAS_CL_USER_PLANE_Z2, A3XX_GRAS_CL_USER_PLANE_W2,
195 A3XX_GRAS_CL_USER_PLANE_X3, A3XX_GRAS_CL_USER_PLANE_Y3,
196 A3XX_GRAS_CL_USER_PLANE_Z3, A3XX_GRAS_CL_USER_PLANE_W3,
197 A3XX_GRAS_CL_USER_PLANE_X4, A3XX_GRAS_CL_USER_PLANE_Y4,
198 A3XX_GRAS_CL_USER_PLANE_Z4, A3XX_GRAS_CL_USER_PLANE_W4,
199 A3XX_GRAS_CL_USER_PLANE_X5, A3XX_GRAS_CL_USER_PLANE_Y5,
200 A3XX_GRAS_CL_USER_PLANE_Z5, A3XX_GRAS_CL_USER_PLANE_W5,
201 A3XX_VSC_BIN_SIZE,
202 A3XX_VSC_PIPE_CONFIG_0, A3XX_VSC_PIPE_CONFIG_1,
203 A3XX_VSC_PIPE_CONFIG_2, A3XX_VSC_PIPE_CONFIG_3,
204 A3XX_VSC_PIPE_CONFIG_4, A3XX_VSC_PIPE_CONFIG_5,
205 A3XX_VSC_PIPE_CONFIG_6, A3XX_VSC_PIPE_CONFIG_7,
206 A3XX_VSC_PIPE_DATA_ADDRESS_0, A3XX_VSC_PIPE_DATA_ADDRESS_1,
207 A3XX_VSC_PIPE_DATA_ADDRESS_2, A3XX_VSC_PIPE_DATA_ADDRESS_3,
208 A3XX_VSC_PIPE_DATA_ADDRESS_4, A3XX_VSC_PIPE_DATA_ADDRESS_5,
209 A3XX_VSC_PIPE_DATA_ADDRESS_6, A3XX_VSC_PIPE_DATA_ADDRESS_7,
210 A3XX_VSC_PIPE_DATA_LENGTH_0, A3XX_VSC_PIPE_DATA_LENGTH_1,
211 A3XX_VSC_PIPE_DATA_LENGTH_2, A3XX_VSC_PIPE_DATA_LENGTH_3,
212 A3XX_VSC_PIPE_DATA_LENGTH_4, A3XX_VSC_PIPE_DATA_LENGTH_5,
213 A3XX_VSC_PIPE_DATA_LENGTH_6, A3XX_VSC_PIPE_DATA_LENGTH_7,
214 A3XX_VSC_SIZE_ADDRESS
215};
216
217#define GLOBAL_REGISTER_COUNT ARRAY_SIZE(global_registers)
218
219/* A scratchpad used to build commands during context create */
220static struct tmp_ctx {
221 unsigned int *cmd; /* Next available dword in C&V buffer */
222
223 /* Addresses in comamnd buffer where registers are saved */
224 uint32_t reg_values[GLOBAL_REGISTER_COUNT];
225 uint32_t gmem_base; /* Base GPU address of GMEM */
226} tmp_ctx;
227
228#ifndef GSL_CONTEXT_SWITCH_CPU_SYNC
229/*
230 * Function for executing dest = ( (reg & and) ROL rol ) | or
231 */
232static unsigned int *rmw_regtomem(unsigned int *cmd,
233 unsigned int reg, unsigned int and,
234 unsigned int rol, unsigned int or,
235 unsigned int dest)
236{
237 /* CP_SCRATCH_REG2 = (CP_SCRATCH_REG2 & 0x00000000) | reg */
238 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
239 *cmd++ = (1 << 30) | A3XX_CP_SCRATCH_REG2;
240 *cmd++ = 0x00000000; /* AND value */
241 *cmd++ = reg; /* OR address */
242
243 /* CP_SCRATCH_REG2 = ( (CP_SCRATCH_REG2 & and) ROL rol ) | or */
244 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
245 *cmd++ = (rol << 24) | A3XX_CP_SCRATCH_REG2;
246 *cmd++ = and; /* AND value */
247 *cmd++ = or; /* OR value */
248
249 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
250 *cmd++ = A3XX_CP_SCRATCH_REG2;
251 *cmd++ = dest;
252
253 return cmd;
254}
255#endif
256
257static void build_regconstantsave_cmds(struct adreno_device *adreno_dev,
258 struct adreno_context *drawctxt)
259{
260 unsigned int *cmd = tmp_ctx.cmd;
Jordan Crousea7ec4212012-02-04 10:23:52 -0700261 unsigned int *start;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -0700262 unsigned int i;
263
264 drawctxt->constant_save_commands[0].hostptr = cmd;
265 drawctxt->constant_save_commands[0].gpuaddr =
266 virt2gpu(cmd, &drawctxt->gpustate);
267 cmd++;
268
Jordan Crousea7ec4212012-02-04 10:23:52 -0700269 start = cmd;
270
Jordan Crouseb4d31bd2012-02-01 22:11:12 -0700271 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
272 *cmd++ = 0;
273
274#ifndef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
275 /*
276 * Context registers are already shadowed; just need to
277 * disable shadowing to prevent corruption.
278 */
279
280 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
281 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
282 *cmd++ = 4 << 16; /* regs, start=0 */
283 *cmd++ = 0x0; /* count = 0 */
284
285#else
286 /*
287 * Make sure the HW context has the correct register values before
288 * reading them.
289 */
290
291 /* Write context registers into shadow */
292 for (i = 0; i < ARRAY_SIZE(context_register_ranges) / 2; i++) {
293 unsigned int start = context_register_ranges[i * 2];
294 unsigned int end = context_register_ranges[i * 2 + 1];
295 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
296 *cmd++ = ((end - start + 1) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
297 start;
298 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET)
299 & 0xFFFFE000) + (start - 0x2000) * 4;
300 }
301#endif
302
303 /* Need to handle some of the global registers separately */
304 for (i = 0; i < ARRAY_SIZE(global_registers); i++) {
305 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
306 *cmd++ = global_registers[i];
307 *cmd++ = tmp_ctx.reg_values[i];
308 }
309
310 /* Save vertex shader constants */
311 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
312 *cmd++ = drawctxt->cond_execs[2].gpuaddr >> 2;
313 *cmd++ = drawctxt->cond_execs[2].gpuaddr >> 2;
314 *cmd++ = 0x0000FFFF;
315 *cmd++ = 3; /* EXEC_COUNT */
316 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
317 drawctxt->constant_save_commands[1].hostptr = cmd;
318 drawctxt->constant_save_commands[1].gpuaddr =
319 virt2gpu(cmd, &drawctxt->gpustate);
320 /*
321 From fixup:
322
323 dwords = SP_VS_CTRL_REG1.VSCONSTLENGTH / 4
324 src = (HLSQ_SHADOW_BASE + 0x2000) / 4
325
326 From register spec:
327 SP_VS_CTRL_REG1.VSCONSTLENGTH [09:00]: 0-512, unit = 128bits.
328 */
329 *cmd++ = 0; /* (dwords << REG_TO_MEM_LOOP_COUNT_SHIFT) | src */
330 /* ALU constant shadow base */
331 *cmd++ = drawctxt->gpustate.gpuaddr & 0xfffffffc;
332
333 /* Save fragment shader constants */
334 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
335 *cmd++ = drawctxt->cond_execs[3].gpuaddr >> 2;
336 *cmd++ = drawctxt->cond_execs[3].gpuaddr >> 2;
337 *cmd++ = 0x0000FFFF;
338 *cmd++ = 3; /* EXEC_COUNT */
339 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
340 drawctxt->constant_save_commands[2].hostptr = cmd;
341 drawctxt->constant_save_commands[2].gpuaddr =
342 virt2gpu(cmd, &drawctxt->gpustate);
343 /*
344 From fixup:
345
346 dwords = SP_FS_CTRL_REG1.FSCONSTLENGTH / 4
347 src = (HLSQ_SHADOW_BASE + 0x2000 + SSIZE) / 4
348
349 From register spec:
350 SP_FS_CTRL_REG1.FSCONSTLENGTH [09:00]: 0-512, unit = 128bits.
351 */
352 *cmd++ = 0; /* (dwords << REG_TO_MEM_LOOP_COUNT_SHIFT) | src */
353
354 /*
355 From fixup:
356
357 base = drawctxt->gpustate.gpuaddr (ALU constant shadow base)
358 offset = SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET
359
360 From register spec:
361 SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
362 start offset in on chip RAM,
363 128bit aligned
364
365 dst = base + offset
366 Because of the base alignment we can use
367 dst = base | offset
368 */
369 *cmd++ = 0; /* dst */
370
371 /* Save VS texture memory objects */
372 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
373 *cmd++ =
374 ((TEX_SIZE_MEM_OBJECTS / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
375 ((HLSQ_SHADOW_BASE + HLSQ_MEMOBJ_OFFSET) / 4);
376 *cmd++ =
377 (drawctxt->gpustate.gpuaddr +
378 VS_TEX_OFFSET_MEM_OBJECTS) & 0xfffffffc;
379
380 /* Save VS texture mipmap pointers */
381 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
382 *cmd++ =
383 ((TEX_SIZE_MIPMAP / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
384 ((HLSQ_SHADOW_BASE + HLSQ_MIPMAP_OFFSET) / 4);
385 *cmd++ =
386 (drawctxt->gpustate.gpuaddr + VS_TEX_OFFSET_MIPMAP) & 0xfffffffc;
387
388 /* Save VS texture sampler objects */
389 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
390 *cmd++ = ((TEX_SIZE_SAMPLER_OBJ / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
391 ((HLSQ_SHADOW_BASE + HLSQ_SAMPLER_OFFSET) / 4);
392 *cmd++ =
393 (drawctxt->gpustate.gpuaddr +
394 VS_TEX_OFFSET_SAMPLER_OBJ) & 0xfffffffc;
395
396 /* Save FS texture memory objects */
397 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
398 *cmd++ =
399 ((TEX_SIZE_MEM_OBJECTS / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
400 ((HLSQ_SHADOW_BASE + HLSQ_MEMOBJ_OFFSET + SSIZE) / 4);
401 *cmd++ =
402 (drawctxt->gpustate.gpuaddr +
403 FS_TEX_OFFSET_MEM_OBJECTS) & 0xfffffffc;
404
405 /* Save FS texture mipmap pointers */
406 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
407 *cmd++ =
408 ((TEX_SIZE_MIPMAP / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
409 ((HLSQ_SHADOW_BASE + HLSQ_MIPMAP_OFFSET + SSIZE) / 4);
410 *cmd++ =
411 (drawctxt->gpustate.gpuaddr + FS_TEX_OFFSET_MIPMAP) & 0xfffffffc;
412
413 /* Save FS texture sampler objects */
414 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
415 *cmd++ =
416 ((TEX_SIZE_SAMPLER_OBJ / 4) << REG_TO_MEM_LOOP_COUNT_SHIFT) |
417 ((HLSQ_SHADOW_BASE + HLSQ_SAMPLER_OFFSET + SSIZE) / 4);
418 *cmd++ =
419 (drawctxt->gpustate.gpuaddr +
420 FS_TEX_OFFSET_SAMPLER_OBJ) & 0xfffffffc;
421
422 /* Create indirect buffer command for above command sequence */
423 create_ib1(drawctxt, drawctxt->regconstant_save, start, cmd);
424
425 tmp_ctx.cmd = cmd;
426}
427
428/* Copy GMEM contents to system memory shadow. */
429static unsigned int *build_gmem2sys_cmds(struct adreno_device *adreno_dev,
430 struct adreno_context *drawctxt,
431 struct gmem_shadow_t *shadow)
432{
433 unsigned int *cmds = tmp_ctx.cmd;
434 unsigned int *start = cmds;
435
436 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
437 *cmds++ = CP_REG(A3XX_RB_MODE_CONTROL);
438
439 /* RB_MODE_CONTROL */
440 *cmds++ = _SET(RB_MODECONTROL_RENDER_MODE, RB_RESOLVE_PASS) |
441 _SET(RB_MODECONTROL_MARB_CACHE_SPLIT_MODE, 1) |
442 _SET(RB_MODECONTROL_PACKER_TIMER_ENABLE, 1);
443 /* RB_RENDER_CONTROL */
444 *cmds++ = _SET(RB_RENDERCONTROL_BIN_WIDTH, shadow->width >> 5) |
445 _SET(RB_RENDERCONTROL_DISABLE_COLOR_PIPE, 1);
446
447 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
448 *cmds++ = CP_REG(A3XX_RB_COPY_CONTROL);
449 /* RB_COPY_CONTROL */
450 *cmds++ = _SET(RB_COPYCONTROL_RESOLVE_CLEAR_MODE,
451 RB_CLEAR_MODE_RESOLVE) |
452 _SET(RB_COPYCONTROL_COPY_GMEM_BASE,
453 tmp_ctx.gmem_base >> 14);
454 /* RB_COPY_DEST_BASE */
455 *cmds++ = _SET(RB_COPYDESTBASE_COPY_DEST_BASE,
456 shadow->gmemshadow.gpuaddr >> 5);
457 /* RB_COPY_DEST_PITCH */
458 *cmds++ = _SET(RB_COPYDESTPITCH_COPY_DEST_PITCH,
459 (shadow->pitch * 4) / 32);
460 /* RB_COPY_DEST_INFO */
461 *cmds++ = _SET(RB_COPYDESTINFO_COPY_DEST_TILE,
462 RB_TILINGMODE_LINEAR) |
463 _SET(RB_COPYDESTINFO_COPY_DEST_FORMAT, RB_R8G8B8A8_UNORM) |
464 _SET(RB_COPYDESTINFO_COPY_COMPONENT_ENABLE, 0X0F) |
465 _SET(RB_COPYDESTINFO_COPY_DEST_ENDIAN, RB_ENDIAN_NONE);
466
467 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
468 *cmds++ = CP_REG(A3XX_GRAS_SC_CONTROL);
469 /* GRAS_SC_CONTROL */
470 *cmds++ = _SET(GRAS_SC_CONTROL_RENDER_MODE, 2);
471
472 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
473 *cmds++ = CP_REG(A3XX_VFD_CONTROL_0);
474 /* VFD_CONTROL_0 */
475 *cmds++ = _SET(VFD_CTRLREG0_TOTALATTRTOVS, 4) |
476 _SET(VFD_CTRLREG0_PACKETSIZE, 2) |
477 _SET(VFD_CTRLREG0_STRMDECINSTRCNT, 1) |
478 _SET(VFD_CTRLREG0_STRMFETCHINSTRCNT, 1);
479 /* VFD_CONTROL_1 */
480 *cmds++ = _SET(VFD_CTRLREG1_MAXSTORAGE, 1) |
481 _SET(VFD_CTRLREG1_REGID4VTX, 252) |
482 _SET(VFD_CTRLREG1_REGID4INST, 252);
483
484 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
485 *cmds++ = CP_REG(A3XX_VFD_FETCH_INSTR_0_0);
486 /* VFD_FETCH_INSTR_0_0 */
487 *cmds++ = _SET(VFD_FETCHINSTRUCTIONS_FETCHSIZE, 11) |
488 _SET(VFD_FETCHINSTRUCTIONS_BUFSTRIDE, 12) |
489 _SET(VFD_FETCHINSTRUCTIONS_STEPRATE, 1);
490 /* VFD_FETCH_INSTR_1_0 */
491 *cmds++ = _SET(VFD_BASEADDR_BASEADDR,
492 shadow->quad_vertices.gpuaddr);
493
494 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
495 *cmds++ = CP_REG(A3XX_VFD_DECODE_INSTR_0);
496 /* VFD_DECODE_INSTR_0 */
497 *cmds++ = _SET(VFD_DECODEINSTRUCTIONS_WRITEMASK, 0x0F) |
498 _SET(VFD_DECODEINSTRUCTIONS_CONSTFILL, 1) |
499 _SET(VFD_DECODEINSTRUCTIONS_FORMAT, 2) |
500 _SET(VFD_DECODEINSTRUCTIONS_REGID, 5) |
501 _SET(VFD_DECODEINSTRUCTIONS_SHIFTCNT, 12) |
502 _SET(VFD_DECODEINSTRUCTIONS_LASTCOMPVALID, 1);
503
504 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
505 *cmds++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG);
506 /* HLSQ_CONTROL_0_REG */
507 *cmds++ = _SET(HLSQ_CTRL0REG_FSTHREADSIZE, HLSQ_TWO_PIX_QUADS) |
508 _SET(HLSQ_CTRL0REG_FSSUPERTHREADENABLE, 1) |
509 _SET(HLSQ_CTRL0REG_SPSHADERRESTART, 1) |
510 _SET(HLSQ_CTRL0REG_RESERVED2, 1) |
511 _SET(HLSQ_CTRL0REG_CHUNKDISABLE, 1) |
512 _SET(HLSQ_CTRL0REG_CONSTSWITCHMODE, 1) |
513 _SET(HLSQ_CTRL0REG_LAZYUPDATEDISABLE, 1) |
514 _SET(HLSQ_CTRL0REG_SPCONSTFULLUPDATE, 1) |
515 _SET(HLSQ_CTRL0REG_TPFULLUPDATE, 1);
516 /* HLSQ_CONTROL_1_REG */
517 *cmds++ = _SET(HLSQ_CTRL1REG_VSTHREADSIZE, HLSQ_TWO_VTX_QUADS) |
518 _SET(HLSQ_CTRL1REG_VSSUPERTHREADENABLE, 1) |
519 _SET(HLSQ_CTRL1REG_RESERVED1, 4);
520 /* HLSQ_CONTROL_2_REG */
521 *cmds++ = _SET(HLSQ_CTRL2REG_PRIMALLOCTHRESHOLD, 31);
522 /* HLSQ_CONTROL_3_REG */
523 *cmds++ = 0x00000000;
524
525 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
526 *cmds++ = CP_REG(A3XX_HLSQ_VS_CONTROL_REG);
527 /* HLSQ_VS_CONTROL_REG */
528 *cmds++ = _SET(HLSQ_VSCTRLREG_VSINSTRLENGTH, 1);
529 /* HLSQ_FS_CONTROL_REG */
530 *cmds++ = _SET(HLSQ_FSCTRLREG_FSCONSTLENGTH, 1) |
531 _SET(HLSQ_FSCTRLREG_FSCONSTSTARTOFFSET, 272) |
532 _SET(HLSQ_FSCTRLREG_FSINSTRLENGTH, 1);
533 /* HLSQ_CONST_VSPRESV_RANGE_REG */
534 *cmds++ = 0x00000000;
535 /* HLSQ_CONST_FSPRESV_RANGE_REQ */
536 *cmds++ = _SET(HLSQ_CONSTFSPRESERVEDRANGEREG_STARTENTRY, 32) |
537 _SET(HLSQ_CONSTFSPRESERVEDRANGEREG_ENDENTRY, 32);
538
539 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
540 *cmds++ = CP_REG(A3XX_SP_FS_LENGTH_REG);
541 /* SP_FS_LENGTH_REG */
542 *cmds++ = _SET(SP_SHADERLENGTH_LEN, 1);
543
544 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
545 *cmds++ = CP_REG(A3XX_SP_SP_CTRL_REG);
546 /* SP_SP_CTRL_REG */
547 *cmds++ = _SET(SP_SPCTRLREG_CONSTMODE, 1) |
548 _SET(SP_SPCTRLREG_SLEEPMODE, 1);
549
550 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 12);
551 *cmds++ = CP_REG(A3XX_SP_VS_CTRL_REG0);
552 /* SP_VS_CTRL_REG0 */
553 *cmds++ = _SET(SP_VSCTRLREG0_VSTHREADMODE, SP_MULTI) |
554 _SET(SP_VSCTRLREG0_VSINSTRBUFFERMODE, SP_BUFFER_MODE) |
555 _SET(SP_VSCTRLREG0_VSICACHEINVALID, 1) |
556 _SET(SP_VSCTRLREG0_VSFULLREGFOOTPRINT, 3) |
557 _SET(SP_VSCTRLREG0_VSTHREADSIZE, SP_TWO_VTX_QUADS) |
558 _SET(SP_VSCTRLREG0_VSSUPERTHREADMODE, 1) |
559 _SET(SP_VSCTRLREG0_VSLENGTH, 1);
560 /* SP_VS_CTRL_REG1 */
561 *cmds++ = _SET(SP_VSCTRLREG1_VSINITIALOUTSTANDING, 4);
562 /* SP_VS_PARAM_REG */
563 *cmds++ = _SET(SP_VSPARAMREG_POSREGID, 1) |
564 _SET(SP_VSPARAMREG_PSIZEREGID, 252);
565 /* SP_VS_OUT_REG_0 */
566 *cmds++ = 0x00000000;
567 /* SP_VS_OUT_REG_1 */
568 *cmds++ = 0x00000000;
569 /* SP_VS_OUT_REG_2 */
570 *cmds++ = 0x00000000;
571 /* SP_VS_OUT_REG_3 */
572 *cmds++ = 0x00000000;
573 /* SP_VS_OUT_REG_4 */
574 *cmds++ = 0x00000000;
575 /* SP_VS_OUT_REG_5 */
576 *cmds++ = 0x00000000;
577 /* SP_VS_OUT_REG_6 */
578 *cmds++ = 0x00000000;
579 /* SP_VS_OUT_REG_7 */
580 *cmds++ = 0x00000000;
581
582 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
583 *cmds++ = CP_REG(A3XX_SP_VS_VPC_DST_REG_0);
584 /* SP_VS_VPC_DST_REG_0 */
585 *cmds++ = 0x00000000;
586 /* SP_VS_VPC_DST_REG_1 */
587 *cmds++ = 0x00000000;
588 /* SP_VS_VPC_DST_REG_2 */
589 *cmds++ = 0x00000000;
590 /* SP_VS_VPC_DST_REG_3 */
591 *cmds++ = 0x00000000;
592 /* SP_VS_OBJ_OFFSET_REG */
593 *cmds++ = 0x00000000;
594 /* SP_VS_OBJ_START_REG */
595 *cmds++ = 0x00000000;
596
597 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
598 *cmds++ = CP_REG(A3XX_SP_VS_LENGTH_REG);
599 /* SP_VS_LENGTH_REG */
600 *cmds++ = _SET(SP_SHADERLENGTH_LEN, 1);
601 /* SP_FS_CTRL_REG0 */
602 *cmds++ = _SET(SP_FSCTRLREG0_FSTHREADMODE, SP_MULTI) |
603 _SET(SP_FSCTRLREG0_FSINSTRBUFFERMODE, SP_BUFFER_MODE) |
604 _SET(SP_FSCTRLREG0_FSICACHEINVALID, 1) |
605 _SET(SP_FSCTRLREG0_FSFULLREGFOOTPRINT, 2) |
606 _SET(SP_FSCTRLREG0_FSINOUTREGOVERLAP, 1) |
607 _SET(SP_FSCTRLREG0_FSTHREADSIZE, SP_TWO_VTX_QUADS) |
608 _SET(SP_FSCTRLREG0_FSSUPERTHREADMODE, 1) |
609 _SET(SP_FSCTRLREG0_FSLENGTH, 1);
610 /* SP_FS_CTRL_REG1 */
611 *cmds++ = _SET(SP_FSCTRLREG1_FSCONSTLENGTH, 1) |
612 _SET(SP_FSCTRLREG1_FSINITIALOUTSTANDING, 2) |
613 _SET(SP_FSCTRLREG1_HALFPRECVAROFFSET, 63);
614 /* SP_FS_OBJ_OFFSET_REG */
615 *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 272) |
616 _SET(SP_OBJOFFSETREG_SHADEROBJOFFSETINIC, 1);
617 /* SP_FS_OBJ_START_REG */
618 *cmds++ = 0x00000000;
619
620 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
621 *cmds++ = CP_REG(A3XX_SP_FS_FLAT_SHAD_MODE_REG_0);
622 /* SP_FS_FLAT_SHAD_MODE_REG_0 */
623 *cmds++ = 0x00000000;
624 /* SP_FS_FLAT_SHAD_MODE_REG_1 */
625 *cmds++ = 0x00000000;
626
627 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
628 *cmds++ = CP_REG(A3XX_SP_FS_OUTPUT_REG);
629 /* SP_FS_OUTPUT_REG */
630 *cmds++ = _SET(SP_IMAGEOUTPUTREG_PAD0, SP_PIXEL_BASED);
631
632 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
633 *cmds++ = CP_REG(A3XX_SP_FS_MRT_REG_0);
634 /* SP_FS_MRT_REG_0 */
635 *cmds++ = _SET(SP_FSMRTREG_REGID, 1);
636 /* SP_FS_MRT_REG_1 */
637 *cmds++ = 0x00000000;
638 /* SP_FS_MRT_REG_2 */
639 *cmds++ = 0x00000000;
640 /* SP_FS_MRT_REG_3 */
641 *cmds++ = 0x00000000;
642
643 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 11);
644 *cmds++ = CP_REG(A3XX_VPC_ATTR);
645 /* VPC_ATTR */
646 *cmds++ = _SET(VPC_VPCATTR_THRHDASSIGN, 1) |
647 _SET(VPC_VPCATTR_LMSIZE, 1);
648 /* VPC_PACK */
649 *cmds++ = 0x00000000;
650 /* VPC_VARRYING_INTERUPT_MODE_0 */
651 *cmds++ = 0x00000000;
652 /* VPC_VARRYING_INTERUPT_MODE_1 */
653 *cmds++ = 0x00000000;
654 /* VPC_VARRYING_INTERUPT_MODE_2 */
655 *cmds++ = 0x00000000;
656 /* VPC_VARRYING_INTERUPT_MODE_3 */
657 *cmds++ = 0x00000000;
658 /* VPC_VARYING_PS_REPL_MODE_0 */
659 *cmds++ = 0x00000000;
660 /* VPC_VARYING_PS_REPL_MODE_1 */
661 *cmds++ = 0x00000000;
662 /* VPC_VARYING_PS_REPL_MODE_2 */
663 *cmds++ = 0x00000000;
664 /* VPC_VARYING_PS_REPL_MODE_3 */
665 *cmds++ = 0x00000000;
666
667 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 10);
668 *cmds++ = (0 << CP_LOADSTATE_DSTOFFSET_SHIFT)
669 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
670 | (HLSQ_BLOCK_ID_SP_VS << CP_LOADSTATE_STATEBLOCKID_SHIFT)
671 | (1 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
672 *cmds++ = (HLSQ_SP_VS_INSTR << CP_LOADSTATE_STATETYPE_SHIFT)
673 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
674
675 /* (sy)(rpt3)mov.f32f32 r0.y, (r)r1.y; */
676 *cmds++ = 0x00000005; *cmds++ = 0x30044b01;
677 /* end; */
678 *cmds++ = 0x00000000; *cmds++ = 0x03000000;
679 /* nop; */
680 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
681 /* nop; */
682 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
683
684 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 10);
685 *cmds++ = (0 << CP_LOADSTATE_DSTOFFSET_SHIFT)
686 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
687 | (HLSQ_BLOCK_ID_SP_FS << CP_LOADSTATE_STATEBLOCKID_SHIFT)
688 | (1 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
689 *cmds++ = (HLSQ_SP_FS_INSTR << CP_LOADSTATE_STATETYPE_SHIFT)
690 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
691
692 /* (sy)(rpt3)mov.f32f32 r0.y, (r)c0.x; */
693 *cmds++ = 0x00000000; *cmds++ = 0x30244b01;
694 /* end; */
695 *cmds++ = 0x00000000; *cmds++ = 0x03000000;
696 /* nop; */
697 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
698 /* nop; */
699 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
700
701 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
702 *cmds++ = CP_REG(A3XX_RB_MSAA_CONTROL);
703 /* RB_MSAA_CONTROL */
704 *cmds++ = _SET(RB_MSAACONTROL_MSAA_DISABLE, 1) |
705 _SET(RB_MSAACONTROL_SAMPLE_MASK, 0xFFFF);
706
707 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
708 *cmds++ = CP_REG(A3XX_RB_DEPTH_CONTROL);
709 /* RB_DEPTH_CONTROL */
710 *cmds++ = _SET(RB_DEPTHCONTROL_Z_TEST_FUNC, RB_FRAG_NEVER);
711
712 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
713 *cmds++ = CP_REG(A3XX_RB_MRT_CONTROL0);
714 /* RB_MRT_CONTROL0 */
715 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
716 _SET(RB_MRTCONTROL_ROP_CODE, 12) |
717 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_ALWAYS) |
718 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
719
720 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
721 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL0);
722 /* RB_MRT_BLEND_CONTROL0 */
723 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
724 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
725 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
726 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
727 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
728 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
729 /* RB_MRT_CONTROL1 */
730 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
731 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
732 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
733
734 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
735 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL1);
736 /* RB_MRT_BLEND_CONTROL1 */
737 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
738 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
739 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
740 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
741 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
742 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
743 /* RB_MRT_CONTROL2 */
744 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
745 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
746 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
747
748 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
749 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL2);
750 /* RB_MRT_BLEND_CONTROL2 */
751 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
752 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
753 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
754 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
755 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
756 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
757 /* RB_MRT_CONTROL3 */
758 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
759 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
760 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
761
762 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
763 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL3);
764 /* RB_MRT_BLEND_CONTROL3 */
765 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
766 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
767 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
768 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
769 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
770 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
771
772 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
773 *cmds++ = CP_REG(A3XX_VFD_INDEX_MIN);
774 /* VFD_INDEX_MIN */
775 *cmds++ = 0x00000000;
776 /* VFD_INDEX_MAX */
777 *cmds++ = 0xFFFFFFFF;
778 /* VFD_INSTANCEID_OFFSET */
779 *cmds++ = 0x00000000;
780 /* VFD_INDEX_OFFSET */
781 *cmds++ = 0x00000000;
782
783 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
784 *cmds++ = CP_REG(A3XX_VFD_VS_THREADING_THRESHOLD);
785 /* VFD_VS_THREADING_THRESHOLD */
786 *cmds++ = _SET(VFD_THREADINGTHRESHOLD_RESERVED6, 12) |
787 _SET(VFD_THREADINGTHRESHOLD_REGID_VTXCNT, 252);
788
789 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
790 *cmds++ = CP_REG(A3XX_TPL1_TP_VS_TEX_OFFSET);
791 /* TPL1_TP_VS_TEX_OFFSET */
792 *cmds++ = 0;
793
794 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
795 *cmds++ = CP_REG(A3XX_TPL1_TP_FS_TEX_OFFSET);
796 /* TPL1_TP_FS_TEX_OFFSET */
797 *cmds++ = _SET(TPL1_TPTEXOFFSETREG_SAMPLEROFFSET, 16) |
798 _SET(TPL1_TPTEXOFFSETREG_MEMOBJOFFSET, 16) |
799 _SET(TPL1_TPTEXOFFSETREG_BASETABLEPTR, 224);
800
801 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
802 *cmds++ = CP_REG(A3XX_PC_PRIM_VTX_CNTL);
803 /* PC_PRIM_VTX_CNTL */
804 *cmds++ = _SET(PC_PRIM_VTX_CONTROL_POLYMODE_FRONT_PTYPE,
805 PC_DRAW_TRIANGLES) |
806 _SET(PC_PRIM_VTX_CONTROL_POLYMODE_BACK_PTYPE,
807 PC_DRAW_TRIANGLES) |
808 _SET(PC_PRIM_VTX_CONTROL_PROVOKING_VTX_LAST, 1);
809
810 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
811 *cmds++ = CP_REG(A3XX_GRAS_SC_WINDOW_SCISSOR_TL);
812 /* GRAS_SC_WINDOW_SCISSOR_TL */
813 *cmds++ = 0x00000000;
814 /* GRAS_SC_WINDOW_SCISSOR_BR */
815 *cmds++ = _SET(GRAS_SC_WINDOW_SCISSOR_BR_BR_X, shadow->width - 1) |
816 _SET(GRAS_SC_WINDOW_SCISSOR_BR_BR_Y, shadow->height - 1);
817
818 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
819 *cmds++ = CP_REG(A3XX_GRAS_SC_SCREEN_SCISSOR_TL);
820 /* GRAS_SC_SCREEN_SCISSOR_TL */
821 *cmds++ = 0x00000000;
822 /* GRAS_SC_SCREEN_SCISSOR_BR */
823 *cmds++ = _SET(GRAS_SC_SCREEN_SCISSOR_BR_BR_X, shadow->width - 1) |
824 _SET(GRAS_SC_SCREEN_SCISSOR_BR_BR_Y, shadow->height - 1);
825
826 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
827 *cmds++ = CP_REG(A3XX_GRAS_CL_VPORT_XOFFSET);
828 /* GRAS_CL_VPORT_XOFFSET */
829 *cmds++ = 0x00000000;
830 /* GRAS_CL_VPORT_XSCALE */
831 *cmds++ = _SET(GRAS_CL_VPORT_XSCALE_VPORT_XSCALE, 0x3f800000);
832 /* GRAS_CL_VPORT_YOFFSET */
833 *cmds++ = 0x00000000;
834 /* GRAS_CL_VPORT_YSCALE */
835 *cmds++ = _SET(GRAS_CL_VPORT_YSCALE_VPORT_YSCALE, 0x3f800000);
836
837 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
838 *cmds++ = CP_REG(A3XX_GRAS_CL_VPORT_ZOFFSET);
839 /* GRAS_CL_VPORT_ZOFFSET */
840 *cmds++ = 0x00000000;
841 /* GRAS_CL_VPORT_ZSCALE */
842 *cmds++ = _SET(GRAS_CL_VPORT_ZSCALE_VPORT_ZSCALE, 0x3f800000);
843
844 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
845 *cmds++ = CP_REG(A3XX_GRAS_CL_CLIP_CNTL);
846 /* GRAS_CL_CLIP_CNTL */
847 *cmds++ = _SET(GRAS_CL_CLIP_CNTL_CLIP_DISABLE, 1) |
848 _SET(GRAS_CL_CLIP_CNTL_ZFAR_CLIP_DISABLE, 1) |
849 _SET(GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE, 1) |
850 _SET(GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE, 1) |
851 _SET(GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE, 1);
852
853 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
854 *cmds++ = CP_REG(A3XX_GRAS_CL_GB_CLIP_ADJ);
855 /* GRAS_CL_GB_CLIP_ADJ */
856 *cmds++ = 0x00000000;
857
858 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
859 *cmds++ = 0x00000000;
860
861 /*
862 * Resolve using two draw calls with a dummy register
863 * write in between. This is a HLM workaround
864 * that should be removed later.
865 */
866 *cmds++ = cp_type3_packet(CP_DRAW_INDX_2, 6);
867 *cmds++ = 0x00000000; /* Viz query info */
868 *cmds++ = BUILD_PC_DRAW_INITIATOR(PC_DI_PT_TRILIST,
869 PC_DI_SRC_SEL_IMMEDIATE,
870 PC_DI_INDEX_SIZE_32_BIT,
871 PC_DI_IGNORE_VISIBILITY);
872 *cmds++ = 0x00000003; /* Num indices */
873 *cmds++ = 0x00000000; /* Index 0 */
874 *cmds++ = 0x00000001; /* Index 1 */
875 *cmds++ = 0x00000002; /* Index 2 */
876
877 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
878 *cmds++ = CP_REG(A3XX_HLSQ_CL_CONTROL_0_REG);
879 *cmds++ = 0x00000000;
880
881 *cmds++ = cp_type3_packet(CP_DRAW_INDX_2, 6);
882 *cmds++ = 0x00000000; /* Viz query info */
883 *cmds++ = BUILD_PC_DRAW_INITIATOR(PC_DI_PT_TRILIST,
884 PC_DI_SRC_SEL_IMMEDIATE,
885 PC_DI_INDEX_SIZE_32_BIT,
886 PC_DI_IGNORE_VISIBILITY);
887 *cmds++ = 0x00000003; /* Num indices */
888 *cmds++ = 0x00000002; /* Index 0 */
889 *cmds++ = 0x00000001; /* Index 1 */
890 *cmds++ = 0x00000003; /* Index 2 */
891
892 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
893 *cmds++ = CP_REG(A3XX_HLSQ_CL_CONTROL_0_REG);
894 *cmds++ = 0x00000000;
895
896 *cmds++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
897 *cmds++ = 0x00000000;
898
899 /* Create indirect buffer command for above command sequence */
900 create_ib1(drawctxt, shadow->gmem_save, start, cmds);
901
902 return cmds;
903}
904
905static void build_shader_save_cmds(struct adreno_device *adreno_dev,
906 struct adreno_context *drawctxt)
907{
908 unsigned int *cmd = tmp_ctx.cmd;
909 unsigned int *start;
910
911 /* Reserve space for boolean values used for COND_EXEC packet */
912 drawctxt->cond_execs[0].hostptr = cmd;
913 drawctxt->cond_execs[0].gpuaddr = virt2gpu(cmd, &drawctxt->gpustate);
914 *cmd++ = 0;
915 drawctxt->cond_execs[1].hostptr = cmd;
916 drawctxt->cond_execs[1].gpuaddr = virt2gpu(cmd, &drawctxt->gpustate);
917 *cmd++ = 0;
918
919 drawctxt->shader_save_commands[0].hostptr = cmd;
920 drawctxt->shader_save_commands[0].gpuaddr =
921 virt2gpu(cmd, &drawctxt->gpustate);
922 *cmd++ = 0;
923 drawctxt->shader_save_commands[1].hostptr = cmd;
924 drawctxt->shader_save_commands[1].gpuaddr =
925 virt2gpu(cmd, &drawctxt->gpustate);
926 *cmd++ = 0;
927
928 start = cmd;
929
930 /* Save vertex shader */
931
932 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
933 *cmd++ = drawctxt->cond_execs[0].gpuaddr >> 2;
934 *cmd++ = drawctxt->cond_execs[0].gpuaddr >> 2;
935 *cmd++ = 0x0000FFFF;
936 *cmd++ = 3; /* EXEC_COUNT */
937
938 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
939 drawctxt->shader_save_commands[2].hostptr = cmd;
940 drawctxt->shader_save_commands[2].gpuaddr =
941 virt2gpu(cmd, &drawctxt->gpustate);
942 /*
943 From fixup:
944
945 dwords = SP_VS_CTRL_REG0.VS_LENGTH * 8
946
947 From regspec:
948 SP_VS_CTRL_REG0.VS_LENGTH [31:24]: VS length, unit = 256bits.
949 If bit31 is 1, it means overflow
950 or any long shader.
951
952 src = (HLSQ_SHADOW_BASE + 0x1000)/4
953 */
954 *cmd++ = 0; /*(dwords << REG_TO_MEM_LOOP_COUNT_SHIFT) | src */
955 *cmd++ = (drawctxt->gpustate.gpuaddr + SHADER_OFFSET) & 0xfffffffc;
956
957 /* Save fragment shader */
958 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
959 *cmd++ = drawctxt->cond_execs[1].gpuaddr >> 2;
960 *cmd++ = drawctxt->cond_execs[1].gpuaddr >> 2;
961 *cmd++ = 0x0000FFFF;
962 *cmd++ = 3; /* EXEC_COUNT */
963
964 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
965 drawctxt->shader_save_commands[3].hostptr = cmd;
966 drawctxt->shader_save_commands[3].gpuaddr =
967 virt2gpu(cmd, &drawctxt->gpustate);
968 /*
969 From fixup:
970
971 dwords = SP_FS_CTRL_REG0.FS_LENGTH * 8
972
973 From regspec:
974 SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
975 If bit31 is 1, it means overflow
976 or any long shader.
977
978 fs_offset = SP_FS_OBJ_OFFSET_REG.SHADEROBJOFFSETINIC * 32
979 From regspec:
980
981 SP_FS_OBJ_OFFSET_REG.SHADEROBJOFFSETINIC [31:25]:
982 First instruction of the whole shader will be stored from
983 the offset in instruction cache, unit = 256bits, a cache line.
984 It can start from 0 if no VS available.
985
986 src = (HLSQ_SHADOW_BASE + 0x1000 + SSIZE + fs_offset)/4
987 */
988 *cmd++ = 0; /*(dwords << REG_TO_MEM_LOOP_COUNT_SHIFT) | src */
989 *cmd++ = (drawctxt->gpustate.gpuaddr + SHADER_OFFSET
990 + (SHADER_SHADOW_SIZE / 2)) & 0xfffffffc;
991
992 /* Create indirect buffer command for above command sequence */
993 create_ib1(drawctxt, drawctxt->shader_save, start, cmd);
994
995 tmp_ctx.cmd = cmd;
996}
997
998/*
999 * Make an IB to modify context save IBs with the correct shader instruction
1000 * and constant sizes and offsets.
1001 */
1002
1003static void build_save_fixup_cmds(struct adreno_device *adreno_dev,
1004 struct adreno_context *drawctxt)
1005{
1006 unsigned int *cmd = tmp_ctx.cmd;
1007 unsigned int *start = cmd;
1008
1009 /* Flush HLSQ lazy updates */
1010 *cmd++ = cp_type3_packet(CP_EVENT_WRITE, 1);
1011 *cmd++ = 0x7; /* HLSQ_FLUSH */
1012 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
1013 *cmd++ = 0;
1014
1015 *cmd++ = cp_type0_packet(A3XX_UCHE_CACHE_INVALIDATE0_REG, 2);
1016 *cmd++ = 0x00000000; /* No start addr for full invalidate */
1017 *cmd++ = (unsigned int)
1018 UCHE_ENTIRE_CACHE << UCHE_INVALIDATE1REG_ALLORPORTION |
1019 UCHE_OP_INVALIDATE << UCHE_INVALIDATE1REG_OPCODE |
1020 0; /* No end addr for full invalidate */
1021
1022 /* Make sure registers are flushed */
1023 *cmd++ = cp_type3_packet(CP_CONTEXT_UPDATE, 1);
1024 *cmd++ = 0;
1025
1026#ifdef GSL_CONTEXT_SWITCH_CPU_SYNC
1027
1028 /* Save shader sizes */
1029 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1030 *cmd++ = A3XX_SP_VS_CTRL_REG0;
1031 *cmd++ = drawctxt->shader_save_commands[2].gpuaddr;
1032
1033 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1034 *cmd++ = A3XX_SP_FS_CTRL_REG0;
1035 *cmd++ = drawctxt->shader_save_commands[3].gpuaddr;
1036
1037 /* Save shader offsets */
1038 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1039 *cmd++ = A3XX_SP_FS_OBJ_OFFSET_REG;
1040 *cmd++ = drawctxt->shader_save_commands[1].gpuaddr;
1041
1042 /* Save constant sizes */
1043 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1044 *cmd++ = A3XX_SP_VS_CTRL_REG1;
1045 *cmd++ = drawctxt->constant_save_commands[1].gpuaddr;
1046 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1047 *cmd++ = A3XX_SP_FS_CTRL_REG1;
1048 *cmd++ = drawctxt->constant_save_commands[2].gpuaddr;
1049
1050 /* Save FS constant offset */
1051 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1052 *cmd++ = A3XX_SP_FS_OBJ_OFFSET_REG;
1053 *cmd++ = drawctxt->constant_save_commands[0].gpuaddr;
1054
1055
1056 /* Save VS instruction store mode */
1057 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1058 *cmd++ = A3XX_SP_VS_CTRL_REG0;
1059 *cmd++ = drawctxt->cond_execs[0].gpuaddr;
1060
1061 /* Save FS instruction store mode */
1062 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1063 *cmd++ = A3XX_SP_FS_CTRL_REG0;
1064 *cmd++ = drawctxt->cond_execs[1].gpuaddr;
1065#else
1066
1067 /* Shader save */
1068 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG0, 0x7f000000,
1069 11+REG_TO_MEM_LOOP_COUNT_SHIFT,
1070 (HLSQ_SHADOW_BASE + 0x1000) / 4,
1071 drawctxt->shader_save_commands[2].gpuaddr);
1072
1073 /* CP_SCRATCH_REG2 = (CP_SCRATCH_REG2 & 0x00000000) | SP_FS_CTRL_REG0 */
1074 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
1075 *cmd++ = (1 << 30) | A3XX_CP_SCRATCH_REG2;
1076 *cmd++ = 0x00000000; /* AND value */
1077 *cmd++ = A3XX_SP_FS_CTRL_REG0; /* OR address */
1078 /* CP_SCRATCH_REG2 = ( (CP_SCRATCH_REG2 & 0x7f000000) >> 21 )
1079 | ((HLSQ_SHADOW_BASE+0x1000+SSIZE)/4) */
1080 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
1081 *cmd++ = ((11 + REG_TO_MEM_LOOP_COUNT_SHIFT) << 24) |
1082 A3XX_CP_SCRATCH_REG2;
1083 *cmd++ = 0x7f000000; /* AND value */
1084 *cmd++ = (HLSQ_SHADOW_BASE + 0x1000 + SSIZE) / 4; /* OR value */
1085
1086 /*
1087 * CP_SCRATCH_REG3 = (CP_SCRATCH_REG3 & 0x00000000) |
1088 * SP_FS_OBJ_OFFSET_REG
1089 */
1090
1091 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
1092 *cmd++ = (1 << 30) | A3XX_CP_SCRATCH_REG3;
1093 *cmd++ = 0x00000000; /* AND value */
1094 *cmd++ = A3XX_SP_FS_OBJ_OFFSET_REG; /* OR address */
1095 /*
1096 * CP_SCRATCH_REG3 = ( (CP_SCRATCH_REG3 & 0xfe000000) >> 25 ) |
1097 * 0x00000000
1098 */
1099 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
1100 *cmd++ = A3XX_CP_SCRATCH_REG3;
1101 *cmd++ = 0xfe000000; /* AND value */
1102 *cmd++ = 0x00000000; /* OR value */
1103 /*
1104 * CP_SCRATCH_REG2 = (CP_SCRATCH_REG2 & 0xffffffff) | CP_SCRATCH_REG3
1105 */
1106 *cmd++ = cp_type3_packet(CP_REG_RMW, 3);
1107 *cmd++ = (1 << 30) | A3XX_CP_SCRATCH_REG2;
1108 *cmd++ = 0xffffffff; /* AND value */
1109 *cmd++ = A3XX_CP_SCRATCH_REG3; /* OR address */
1110
1111 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
1112 *cmd++ = A3XX_CP_SCRATCH_REG2;
1113 *cmd++ = drawctxt->shader_save_commands[3].gpuaddr;
1114
1115 /* Constant save */
1116 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG1, 0x000003ff,
Jordan Croused0070882012-02-21 08:54:52 -07001117 2 + REG_TO_MEM_LOOP_COUNT_SHIFT,
1118 (HLSQ_SHADOW_BASE + 0x2000) / 4,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001119 drawctxt->constant_save_commands[1].gpuaddr);
1120
1121 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG1, 0x000003ff,
Jordan Croused0070882012-02-21 08:54:52 -07001122 2 + REG_TO_MEM_LOOP_COUNT_SHIFT,
1123 (HLSQ_SHADOW_BASE + 0x2000 + SSIZE) / 4,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001124 drawctxt->constant_save_commands[2].gpuaddr);
1125
1126 cmd = rmw_regtomem(cmd, A3XX_SP_FS_OBJ_OFFSET_REG, 0x00ff0000,
1127 18, drawctxt->gpustate.gpuaddr & 0xfffffe00,
1128 drawctxt->constant_save_commands[2].gpuaddr
1129 + sizeof(unsigned int));
1130
1131 /* Modify constant save conditionals */
1132 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG1, 0x000003ff,
1133 0, 0, drawctxt->cond_execs[2].gpuaddr);
1134
1135 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG1, 0x000003ff,
1136 0, 0, drawctxt->cond_execs[3].gpuaddr);
1137
1138 /* Save VS instruction store mode */
1139
1140 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG0, 0x00000002,
1141 31, 0, drawctxt->cond_execs[0].gpuaddr);
1142
1143 /* Save FS instruction store mode */
1144 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG0, 0x00000002,
1145 31, 0, drawctxt->cond_execs[1].gpuaddr);
1146
1147#endif
1148
1149 create_ib1(drawctxt, drawctxt->save_fixup, start, cmd);
1150
1151 tmp_ctx.cmd = cmd;
1152}
1153
1154/****************************************************************************/
1155/* Functions to build context restore IBs */
1156/****************************************************************************/
1157
1158static unsigned int *build_sys2gmem_cmds(struct adreno_device *adreno_dev,
1159 struct adreno_context *drawctxt,
1160 struct gmem_shadow_t *shadow)
1161{
1162 unsigned int *cmds = tmp_ctx.cmd;
1163 unsigned int *start = cmds;
1164
1165 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
1166 *cmds++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG);
1167 /* HLSQ_CONTROL_0_REG */
1168 *cmds++ = _SET(HLSQ_CTRL0REG_FSTHREADSIZE, HLSQ_FOUR_PIX_QUADS) |
1169 _SET(HLSQ_CTRL0REG_SPSHADERRESTART, 1) |
1170 _SET(HLSQ_CTRL0REG_CHUNKDISABLE, 1) |
1171 _SET(HLSQ_CTRL0REG_SPCONSTFULLUPDATE, 1) |
1172 _SET(HLSQ_CTRL0REG_TPFULLUPDATE, 1);
1173 /* HLSQ_CONTROL_1_REG */
1174 *cmds++ = _SET(HLSQ_CTRL1REG_VSTHREADSIZE, HLSQ_TWO_VTX_QUADS);
1175 /* HLSQ_CONTROL_2_REG */
1176 *cmds++ = _SET(HLSQ_CTRL2REG_PRIMALLOCTHRESHOLD, 31);
1177 /* HLSQ_CONTROL3_REG */
1178 *cmds++ = 0x00000000;
1179
1180 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1181 *cmds++ = CP_REG(A3XX_RB_MRT_BUF_INFO0);
1182 /* RB_MRT_BUF_INFO0 */
1183 *cmds++ = _SET(RB_MRTBUFINFO_COLOR_FORMAT, RB_R8G8B8A8_UNORM) |
1184 _SET(RB_MRTBUFINFO_COLOR_TILE_MODE, RB_TILINGMODE_32X32) |
1185 _SET(RB_MRTBUFINFO_COLOR_BUF_PITCH,
1186 (shadow->gmem_pitch * 4 * 8) / 256);
1187 /* RB_MRT_BUF_BASE0 */
1188 *cmds++ = _SET(RB_MRTBUFBASE_COLOR_BUF_BASE, tmp_ctx.gmem_base >> 5);
1189
1190 /* Texture samplers */
1191 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 4);
1192 *cmds++ = (16 << CP_LOADSTATE_DSTOFFSET_SHIFT)
1193 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
1194 | (HLSQ_BLOCK_ID_TP_TEX << CP_LOADSTATE_STATEBLOCKID_SHIFT)
1195 | (1 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
1196 *cmds++ = (HLSQ_TP_TEX_SAMPLERS << CP_LOADSTATE_STATETYPE_SHIFT)
1197 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
1198 *cmds++ = 0x00000240;
1199 *cmds++ = 0x00000000;
1200
1201 /* Texture memobjs */
1202 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 6);
1203 *cmds++ = (16 << CP_LOADSTATE_DSTOFFSET_SHIFT)
1204 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
1205 | (HLSQ_BLOCK_ID_TP_TEX << CP_LOADSTATE_STATEBLOCKID_SHIFT)
1206 | (1 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
1207 *cmds++ = (HLSQ_TP_TEX_MEMOBJ << CP_LOADSTATE_STATETYPE_SHIFT)
1208 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
1209 *cmds++ = 0x4cc06880;
1210 *cmds++ = shadow->height | (shadow->width << 14);
1211 *cmds++ = (shadow->pitch*4*8) << 9;
1212 *cmds++ = 0x00000000;
1213
1214 /* Mipmap bases */
1215 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 16);
1216 *cmds++ = (224 << CP_LOADSTATE_DSTOFFSET_SHIFT)
1217 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
1218 | (HLSQ_BLOCK_ID_TP_MIPMAP << CP_LOADSTATE_STATEBLOCKID_SHIFT)
1219 | (14 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
1220 *cmds++ = (HLSQ_TP_MIPMAP_BASE << CP_LOADSTATE_STATETYPE_SHIFT)
1221 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
1222 *cmds++ = shadow->gmemshadow.gpuaddr;
1223 *cmds++ = 0x00000000;
1224 *cmds++ = 0x00000000;
1225 *cmds++ = 0x00000000;
1226 *cmds++ = 0x00000000;
1227 *cmds++ = 0x00000000;
1228 *cmds++ = 0x00000000;
1229 *cmds++ = 0x00000000;
1230 *cmds++ = 0x00000000;
1231 *cmds++ = 0x00000000;
1232 *cmds++ = 0x00000000;
1233 *cmds++ = 0x00000000;
1234 *cmds++ = 0x00000000;
1235 *cmds++ = 0x00000000;
1236
1237 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
1238 *cmds++ = CP_REG(A3XX_HLSQ_VS_CONTROL_REG);
1239 /* HLSQ_VS_CONTROL_REG */
1240 *cmds++ = _SET(HLSQ_VSCTRLREG_VSINSTRLENGTH, 1);
1241 /* HLSQ_FS_CONTROL_REG */
1242 *cmds++ = _SET(HLSQ_FSCTRLREG_FSCONSTLENGTH, 1) |
1243 _SET(HLSQ_FSCTRLREG_FSCONSTSTARTOFFSET, 128) |
1244 _SET(HLSQ_FSCTRLREG_FSINSTRLENGTH, 2);
1245 /* HLSQ_CONST_VSPRESV_RANGE_REG */
1246 *cmds++ = 0x00000000;
1247 /* HLSQ_CONST_FSPRESV_RANGE_REG */
1248 *cmds++ = 0x00000000;
1249
1250 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1251 *cmds++ = CP_REG(A3XX_SP_FS_LENGTH_REG);
1252 /* SP_FS_LENGTH_REG */
1253 *cmds++ = _SET(SP_SHADERLENGTH_LEN, 2);
1254
1255 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 12);
1256 *cmds++ = CP_REG(A3XX_SP_VS_CTRL_REG0);
1257 /* SP_VS_CTRL_REG0 */
1258 *cmds++ = _SET(SP_VSCTRLREG0_VSTHREADMODE, SP_MULTI) |
1259 _SET(SP_VSCTRLREG0_VSINSTRBUFFERMODE, SP_BUFFER_MODE) |
1260 _SET(SP_VSCTRLREG0_VSICACHEINVALID, 1) |
1261 _SET(SP_VSCTRLREG0_VSFULLREGFOOTPRINT, 2) |
1262 _SET(SP_VSCTRLREG0_VSTHREADSIZE, SP_TWO_VTX_QUADS) |
1263 _SET(SP_VSCTRLREG0_VSLENGTH, 1);
1264 /* SP_VS_CTRL_REG1 */
1265 *cmds++ = _SET(SP_VSCTRLREG1_VSINITIALOUTSTANDING, 8);
1266 /* SP_VS_PARAM_REG */
1267 *cmds++ = _SET(SP_VSPARAMREG_POSREGID, 4) |
1268 _SET(SP_VSPARAMREG_PSIZEREGID, 252) |
1269 _SET(SP_VSPARAMREG_TOTALVSOUTVAR, 1);
1270 /* SP_VS_OUT_REG0 */
1271 *cmds++ = _SET(SP_VSOUTREG_COMPMASK0, 3);
1272 /* SP_VS_OUT_REG1 */
1273 *cmds++ = 0x00000000;
1274 /* SP_VS_OUT_REG2 */
1275 *cmds++ = 0x00000000;
1276 /* SP_VS_OUT_REG3 */
1277 *cmds++ = 0x00000000;
1278 /* SP_VS_OUT_REG4 */
1279 *cmds++ = 0x00000000;
1280 /* SP_VS_OUT_REG5 */
1281 *cmds++ = 0x00000000;
1282 /* SP_VS_OUT_REG6 */
1283 *cmds++ = 0x00000000;
1284 /* SP_VS_OUT_REG7 */
1285 *cmds++ = 0x00000000;
1286
1287 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 7);
1288 *cmds++ = CP_REG(A3XX_SP_VS_VPC_DST_REG_0);
1289 /* SP_VS_VPC_DST_REG0 */
1290 *cmds++ = _SET(SP_VSVPCDSTREG_OUTLOC0, 8);
1291 /* SP_VS_VPC_DST_REG1 */
1292 *cmds++ = 0x00000000;
1293 /* SP_VS_VPC_DST_REG2 */
1294 *cmds++ = 0x00000000;
1295 /* SP_VS_VPC_DST_REG3 */
1296 *cmds++ = 0x00000000;
1297 /* SP_VS_OBJ_OFFSET_REG */
1298 *cmds++ = 0x00000000;
1299 /* SP_VS_OBJ_START_REG */
1300 *cmds++ = 0x00000000;
1301
1302 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 6);
1303 *cmds++ = CP_REG(A3XX_SP_VS_LENGTH_REG);
1304 /* SP_VS_LENGTH_REG */
1305 *cmds++ = _SET(SP_SHADERLENGTH_LEN, 1);
1306 /* SP_FS_CTRL_REG0 */
1307 *cmds++ = _SET(SP_FSCTRLREG0_FSTHREADMODE, SP_MULTI) |
1308 _SET(SP_FSCTRLREG0_FSINSTRBUFFERMODE, SP_BUFFER_MODE) |
1309 _SET(SP_FSCTRLREG0_FSICACHEINVALID, 1) |
1310 _SET(SP_FSCTRLREG0_FSFULLREGFOOTPRINT, 2) |
1311 _SET(SP_FSCTRLREG0_FSINOUTREGOVERLAP, 1) |
1312 _SET(SP_FSCTRLREG0_FSTHREADSIZE, SP_FOUR_PIX_QUADS) |
1313 _SET(SP_FSCTRLREG0_PIXLODENABLE, 1) |
1314 _SET(SP_FSCTRLREG0_FSLENGTH, 2);
1315 /* SP_FS_CTRL_REG1 */
1316 *cmds++ = _SET(SP_FSCTRLREG1_FSCONSTLENGTH, 1) |
1317 _SET(SP_FSCTRLREG1_FSINITIALOUTSTANDING, 2) |
1318 _SET(SP_FSCTRLREG1_HALFPRECVAROFFSET, 63);
1319 /* SP_FS_OBJ_OFFSET_REG */
Tarun Karra7e8e1cf2012-02-06 18:23:19 -08001320 *cmds++ = _SET(SP_OBJOFFSETREG_CONSTOBJECTSTARTOFFSET, 128) |
1321 _SET(SP_OBJOFFSETREG_SHADEROBJOFFSETINIC, 1);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001322 /* SP_FS_OBJ_START_REG */
1323 *cmds++ = 0x00000000;
1324
1325 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1326 *cmds++ = CP_REG(A3XX_SP_FS_FLAT_SHAD_MODE_REG_0);
1327 /* SP_FS_FLAT_SHAD_MODE_REG0 */
1328 *cmds++ = 0x00000000;
1329 /* SP_FS_FLAT_SHAD_MODE_REG1 */
1330 *cmds++ = 0x00000000;
1331
1332 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1333 *cmds++ = CP_REG(A3XX_SP_FS_OUTPUT_REG);
1334 /* SP_FS_OUT_REG */
1335 *cmds++ = _SET(SP_FSOUTREG_PAD0, SP_PIXEL_BASED);
1336
Jordan Crousea7ec4212012-02-04 10:23:52 -07001337 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001338 *cmds++ = CP_REG(A3XX_SP_FS_MRT_REG_0);
1339 /* SP_FS_MRT_REG0 */
1340 *cmds++ = _SET(SP_FSMRTREG_REGID, 4);
1341 /* SP_FS_MRT_REG1 */
1342 *cmds++ = 0;
1343 /* SP_FS_MRT_REG2 */
1344 *cmds++ = 0;
1345 /* SP_FS_MRT_REG3 */
1346 *cmds++ = 0;
1347
1348 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 11);
1349 *cmds++ = CP_REG(A3XX_VPC_ATTR);
1350 /* VPC_ATTR */
1351 *cmds++ = _SET(VPC_VPCATTR_TOTALATTR, 2) |
1352 _SET(VPC_VPCATTR_THRHDASSIGN, 1) |
1353 _SET(VPC_VPCATTR_LMSIZE, 1);
1354 /* VPC_PACK */
1355 *cmds++ = _SET(VPC_VPCPACK_NUMFPNONPOSVAR, 2) |
1356 _SET(VPC_VPCPACK_NUMNONPOSVSVAR, 2);
1357 /* VPC_VARYING_INTERP_MODE_0 */
1358 *cmds++ = 0x00000000;
1359 /* VPC_VARYING_INTERP_MODE1 */
1360 *cmds++ = 0x00000000;
1361 /* VPC_VARYING_INTERP_MODE2 */
1362 *cmds++ = 0x00000000;
1363 /* VPC_VARYING_IINTERP_MODE3 */
1364 *cmds++ = 0x00000000;
1365 /* VPC_VARRYING_PS_REPL_MODE_0 */
1366 *cmds++ = _SET(VPC_VPCVARPSREPLMODE_COMPONENT08, 1) |
1367 _SET(VPC_VPCVARPSREPLMODE_COMPONENT09, 2) |
1368 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0A, 1) |
1369 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0B, 2) |
1370 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0C, 1) |
1371 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0D, 2) |
1372 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0E, 1) |
1373 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0F, 2) |
1374 _SET(VPC_VPCVARPSREPLMODE_COMPONENT10, 1) |
1375 _SET(VPC_VPCVARPSREPLMODE_COMPONENT11, 2) |
1376 _SET(VPC_VPCVARPSREPLMODE_COMPONENT12, 1) |
1377 _SET(VPC_VPCVARPSREPLMODE_COMPONENT13, 2) |
1378 _SET(VPC_VPCVARPSREPLMODE_COMPONENT14, 1) |
1379 _SET(VPC_VPCVARPSREPLMODE_COMPONENT15, 2) |
1380 _SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
1381 _SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
1382 /* VPC_VARRYING_PS_REPL_MODE_1 */
1383 *cmds++ = _SET(VPC_VPCVARPSREPLMODE_COMPONENT08, 1) |
1384 _SET(VPC_VPCVARPSREPLMODE_COMPONENT09, 2) |
1385 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0A, 1) |
1386 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0B, 2) |
1387 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0C, 1) |
1388 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0D, 2) |
1389 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0E, 1) |
1390 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0F, 2) |
1391 _SET(VPC_VPCVARPSREPLMODE_COMPONENT10, 1) |
1392 _SET(VPC_VPCVARPSREPLMODE_COMPONENT11, 2) |
1393 _SET(VPC_VPCVARPSREPLMODE_COMPONENT12, 1) |
1394 _SET(VPC_VPCVARPSREPLMODE_COMPONENT13, 2) |
1395 _SET(VPC_VPCVARPSREPLMODE_COMPONENT14, 1) |
1396 _SET(VPC_VPCVARPSREPLMODE_COMPONENT15, 2) |
1397 _SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
1398 _SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
1399 /* VPC_VARRYING_PS_REPL_MODE_2 */
1400 *cmds++ = _SET(VPC_VPCVARPSREPLMODE_COMPONENT08, 1) |
1401 _SET(VPC_VPCVARPSREPLMODE_COMPONENT09, 2) |
1402 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0A, 1) |
1403 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0B, 2) |
1404 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0C, 1) |
1405 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0D, 2) |
1406 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0E, 1) |
1407 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0F, 2) |
1408 _SET(VPC_VPCVARPSREPLMODE_COMPONENT10, 1) |
1409 _SET(VPC_VPCVARPSREPLMODE_COMPONENT11, 2) |
1410 _SET(VPC_VPCVARPSREPLMODE_COMPONENT12, 1) |
1411 _SET(VPC_VPCVARPSREPLMODE_COMPONENT13, 2) |
1412 _SET(VPC_VPCVARPSREPLMODE_COMPONENT14, 1) |
1413 _SET(VPC_VPCVARPSREPLMODE_COMPONENT15, 2) |
1414 _SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
1415 _SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
1416 /* VPC_VARRYING_PS_REPL_MODE_3 */
1417 *cmds++ = _SET(VPC_VPCVARPSREPLMODE_COMPONENT08, 1) |
1418 _SET(VPC_VPCVARPSREPLMODE_COMPONENT09, 2) |
1419 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0A, 1) |
1420 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0B, 2) |
1421 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0C, 1) |
1422 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0D, 2) |
1423 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0E, 1) |
1424 _SET(VPC_VPCVARPSREPLMODE_COMPONENT0F, 2) |
1425 _SET(VPC_VPCVARPSREPLMODE_COMPONENT10, 1) |
1426 _SET(VPC_VPCVARPSREPLMODE_COMPONENT11, 2) |
1427 _SET(VPC_VPCVARPSREPLMODE_COMPONENT12, 1) |
1428 _SET(VPC_VPCVARPSREPLMODE_COMPONENT13, 2) |
1429 _SET(VPC_VPCVARPSREPLMODE_COMPONENT14, 1) |
1430 _SET(VPC_VPCVARPSREPLMODE_COMPONENT15, 2) |
1431 _SET(VPC_VPCVARPSREPLMODE_COMPONENT16, 1) |
1432 _SET(VPC_VPCVARPSREPLMODE_COMPONENT17, 2);
1433
Jordan Crousea7ec4212012-02-04 10:23:52 -07001434 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001435 *cmds++ = CP_REG(A3XX_SP_SP_CTRL_REG);
1436 /* SP_SP_CTRL_REG */
1437 *cmds++ = _SET(SP_SPCTRLREG_SLEEPMODE, 1);
1438
1439 /* Load vertex shader */
1440 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 10);
1441 *cmds++ = (0 << CP_LOADSTATE_DSTOFFSET_SHIFT)
1442 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
1443 | (HLSQ_BLOCK_ID_SP_VS << CP_LOADSTATE_STATEBLOCKID_SHIFT)
1444 | (1 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
1445 *cmds++ = (HLSQ_SP_VS_INSTR << CP_LOADSTATE_STATETYPE_SHIFT)
1446 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
1447 /* (sy)end; */
1448 *cmds++ = 0x00000000; *cmds++ = 0x13000000;
1449 /* nop; */
1450 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
1451 /* nop; */
1452 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
1453 /* nop; */
1454 *cmds++ = 0x00000000; *cmds++ = 0x00000000;
1455
1456 /* Load fragment shader */
1457 *cmds++ = cp_type3_packet(CP_LOAD_STATE, 18);
1458 *cmds++ = (0 << CP_LOADSTATE_DSTOFFSET_SHIFT)
1459 | (HLSQ_DIRECT << CP_LOADSTATE_STATESRC_SHIFT)
1460 | (HLSQ_BLOCK_ID_SP_FS << CP_LOADSTATE_STATEBLOCKID_SHIFT)
1461 | (2 << CP_LOADSTATE_NUMOFUNITS_SHIFT);
1462 *cmds++ = (HLSQ_SP_FS_INSTR << CP_LOADSTATE_STATETYPE_SHIFT)
1463 | (0 << CP_LOADSTATE_EXTSRCADDR_SHIFT);
1464 /* (sy)(rpt1)bary.f (ei)r0.z, (r)0, r0.x; */
1465 *cmds++ = 0x00002000; *cmds++ = 0x57368902;
1466 /* (rpt5)nop; */
1467 *cmds++ = 0x00000000; *cmds++ = 0x00000500;
1468 /* sam (f32)r0.xyzw, r0.z, s#0, t#0; */
1469 *cmds++ = 0x00000005; *cmds++ = 0xa0c01f00;
1470 /* (sy)mov.f32f32 r1.x, r0.x; */
1471 *cmds++ = 0x00000000; *cmds++ = 0x30044004;
1472 /* mov.f32f32 r1.y, r0.y; */
1473 *cmds++ = 0x00000001; *cmds++ = 0x20044005;
1474 /* mov.f32f32 r1.z, r0.z; */
1475 *cmds++ = 0x00000002; *cmds++ = 0x20044006;
1476 /* mov.f32f32 r1.w, r0.w; */
1477 *cmds++ = 0x00000003; *cmds++ = 0x20044007;
1478 /* end; */
1479 *cmds++ = 0x00000000; *cmds++ = 0x03000000;
1480
1481 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1482 *cmds++ = CP_REG(A3XX_VFD_CONTROL_0);
1483 /* VFD_CONTROL_0 */
1484 *cmds++ = _SET(VFD_CTRLREG0_TOTALATTRTOVS, 8) |
1485 _SET(VFD_CTRLREG0_PACKETSIZE, 2) |
1486 _SET(VFD_CTRLREG0_STRMDECINSTRCNT, 2) |
1487 _SET(VFD_CTRLREG0_STRMFETCHINSTRCNT, 2);
1488 /* VFD_CONTROL_1 */
1489 *cmds++ = _SET(VFD_CTRLREG1_MAXSTORAGE, 2) |
1490 _SET(VFD_CTRLREG1_REGID4VTX, 252) |
1491 _SET(VFD_CTRLREG1_REGID4INST, 252);
1492
1493 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
1494 *cmds++ = CP_REG(A3XX_VFD_FETCH_INSTR_0_0);
1495 /* VFD_FETCH_INSTR_0_0 */
1496 *cmds++ = _SET(VFD_FETCHINSTRUCTIONS_FETCHSIZE, 7) |
1497 _SET(VFD_FETCHINSTRUCTIONS_BUFSTRIDE, 8) |
1498 _SET(VFD_FETCHINSTRUCTIONS_SWITCHNEXT, 1) |
1499 _SET(VFD_FETCHINSTRUCTIONS_STEPRATE, 1);
1500 /* VFD_FETCH_INSTR_1_0 */
1501 *cmds++ = _SET(VFD_BASEADDR_BASEADDR,
1502 shadow->quad_vertices_restore.gpuaddr);
1503 /* VFD_FETCH_INSTR_0_1 */
1504 *cmds++ = _SET(VFD_FETCHINSTRUCTIONS_FETCHSIZE, 11) |
1505 _SET(VFD_FETCHINSTRUCTIONS_BUFSTRIDE, 12) |
1506 _SET(VFD_FETCHINSTRUCTIONS_INDEXDECODE, 1) |
1507 _SET(VFD_FETCHINSTRUCTIONS_STEPRATE, 1);
1508 /* VFD_FETCH_INSTR_1_1 */
1509 *cmds++ = _SET(VFD_BASEADDR_BASEADDR,
1510 shadow->quad_vertices_restore.gpuaddr + 16);
1511
1512 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1513 *cmds++ = CP_REG(A3XX_VFD_DECODE_INSTR_0);
1514 /* VFD_DECODE_INSTR_0 */
1515 *cmds++ = _SET(VFD_DECODEINSTRUCTIONS_WRITEMASK, 0x0F) |
1516 _SET(VFD_DECODEINSTRUCTIONS_CONSTFILL, 1) |
1517 _SET(VFD_DECODEINSTRUCTIONS_FORMAT, 1) |
1518 _SET(VFD_DECODEINSTRUCTIONS_SHIFTCNT, 8) |
1519 _SET(VFD_DECODEINSTRUCTIONS_LASTCOMPVALID, 1) |
1520 _SET(VFD_DECODEINSTRUCTIONS_SWITCHNEXT, 1);
1521 /* VFD_DECODE_INSTR_1 */
1522 *cmds++ = _SET(VFD_DECODEINSTRUCTIONS_WRITEMASK, 0x0F) |
1523 _SET(VFD_DECODEINSTRUCTIONS_CONSTFILL, 1) |
1524 _SET(VFD_DECODEINSTRUCTIONS_FORMAT, 2) |
1525 _SET(VFD_DECODEINSTRUCTIONS_REGID, 4) |
1526 _SET(VFD_DECODEINSTRUCTIONS_SHIFTCNT, 12) |
1527 _SET(VFD_DECODEINSTRUCTIONS_LASTCOMPVALID, 1);
1528
1529 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1530 *cmds++ = CP_REG(A3XX_RB_DEPTH_CONTROL);
1531 /* RB_DEPTH_CONTROL */
1532 *cmds++ = _SET(RB_DEPTHCONTROL_Z_TEST_FUNC, RB_FRAG_NEVER);
1533
1534 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1535 *cmds++ = CP_REG(A3XX_RB_STENCIL_CONTROL);
1536 /* RB_STENCIL_CONTROL */
1537 *cmds++ = _SET(RB_STENCILCONTROL_STENCIL_FUNC, RB_REF_NEVER) |
1538 _SET(RB_STENCILCONTROL_STENCIL_FAIL, RB_STENCIL_KEEP) |
1539 _SET(RB_STENCILCONTROL_STENCIL_ZPASS, RB_STENCIL_KEEP) |
1540 _SET(RB_STENCILCONTROL_STENCIL_ZFAIL, RB_STENCIL_KEEP) |
1541 _SET(RB_STENCILCONTROL_STENCIL_FUNC_BF, RB_REF_NEVER) |
1542 _SET(RB_STENCILCONTROL_STENCIL_FAIL_BF, RB_STENCIL_KEEP) |
1543 _SET(RB_STENCILCONTROL_STENCIL_ZPASS_BF, RB_STENCIL_KEEP) |
1544 _SET(RB_STENCILCONTROL_STENCIL_ZFAIL_BF, RB_STENCIL_KEEP);
1545
1546 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1547 *cmds++ = CP_REG(A3XX_RB_MODE_CONTROL);
1548 /* RB_MODE_CONTROL */
1549 *cmds++ = _SET(RB_MODECONTROL_RENDER_MODE, RB_RENDERING_PASS) |
1550 _SET(RB_MODECONTROL_MARB_CACHE_SPLIT_MODE, 1);
1551
1552 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1553 *cmds++ = CP_REG(A3XX_RB_RENDER_CONTROL);
1554 /* RB_RENDER_CONTROL */
1555 *cmds++ = _SET(RB_RENDERCONTROL_BIN_WIDTH, shadow->width >> 5) |
1556 _SET(RB_RENDERCONTROL_ALPHA_TEST_FUNC, 7);
1557
1558 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1559 *cmds++ = CP_REG(A3XX_RB_MSAA_CONTROL);
1560 /* RB_MSAA_CONTROL */
1561 *cmds++ = _SET(RB_MSAACONTROL_MSAA_DISABLE, 1) |
1562 _SET(RB_MSAACONTROL_SAMPLE_MASK, 0xFFFF);
1563
1564 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1565 *cmds++ = CP_REG(A3XX_RB_MRT_CONTROL0);
1566 /* RB_MRT_CONTROL0 */
1567 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
1568 _SET(RB_MRTCONTROL_ROP_CODE, 12) |
1569 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_ALWAYS) |
1570 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
1571
1572 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1573 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL0);
1574 /* RB_MRT_BLENDCONTROL0 */
1575 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
1576 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1577 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
1578 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
1579 _SET(RB_MRTBLENDCONTROL_ALPHA_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1580 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
1581 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
1582 /* RB_MRT_CONTROL1 */
1583 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
1584 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
1585 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
1586
1587 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1588 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL1);
1589 /* RB_MRT_BLENDCONTROL1 */
1590 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
1591 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1592 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
1593 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
1594 _SET(RB_MRTBLENDCONTROL_ALPHA_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1595 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
1596 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
1597 /* RB_MRT_CONTROL2 */
1598 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
1599 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
1600 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
1601
1602 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1603 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL2);
1604 /* RB_MRT_BLENDCONTROL2 */
1605 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
1606 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1607 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
1608 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
1609 _SET(RB_MRTBLENDCONTROL_ALPHA_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1610 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
1611 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
1612 /* RB_MRT_CONTROL3 */
1613 *cmds++ = _SET(RB_MRTCONTROL_READ_DEST_ENABLE, 1) |
1614 _SET(RB_MRTCONTROL_DITHER_MODE, RB_DITHER_DISABLE) |
1615 _SET(RB_MRTCONTROL_COMPONENT_ENABLE, 0xF);
1616
1617 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1618 *cmds++ = CP_REG(A3XX_RB_MRT_BLEND_CONTROL3);
1619 /* RB_MRT_BLENDCONTROL3 */
1620 *cmds++ = _SET(RB_MRTBLENDCONTROL_RGB_SRC_FACTOR, RB_FACTOR_ONE) |
1621 _SET(RB_MRTBLENDCONTROL_RGB_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1622 _SET(RB_MRTBLENDCONTROL_RGB_DEST_FACTOR, RB_FACTOR_ZERO) |
1623 _SET(RB_MRTBLENDCONTROL_ALPHA_SRC_FACTOR, RB_FACTOR_ONE) |
1624 _SET(RB_MRTBLENDCONTROL_ALPHA_BLEND_OPCODE, RB_BLEND_OP_ADD) |
1625 _SET(RB_MRTBLENDCONTROL_ALPHA_DEST_FACTOR, RB_FACTOR_ZERO) |
1626 _SET(RB_MRTBLENDCONTROL_CLAMP_ENABLE, 1);
1627
1628 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
1629 *cmds++ = CP_REG(A3XX_VFD_INDEX_MIN);
1630 /* VFD_INDEX_MIN */
1631 *cmds++ = 0x00000000;
1632 /* VFD_INDEX_MAX */
1633 *cmds++ = 0xFFFFFFFF;
1634 /* VFD_INDEX_OFFSET */
1635 *cmds++ = 0x00000000;
1636 /* TPL1_TP_VS_TEX_OFFSET */
1637 *cmds++ = 0x00000000;
1638
1639 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1640 *cmds++ = CP_REG(A3XX_VFD_VS_THREADING_THRESHOLD);
1641 /* VFD_VS_THREADING_THRESHOLD */
1642 *cmds++ = _SET(VFD_THREADINGTHRESHOLD_RESERVED6, 12) |
1643 _SET(VFD_THREADINGTHRESHOLD_REGID_VTXCNT, 252);
1644
1645 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1646 *cmds++ = CP_REG(A3XX_TPL1_TP_VS_TEX_OFFSET);
1647 /* TPL1_TP_VS_TEX_OFFSET */
1648 *cmds++ = 0x00000000;
1649
1650 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1651 *cmds++ = CP_REG(A3XX_TPL1_TP_FS_TEX_OFFSET);
1652 /* TPL1_TP_FS_TEX_OFFSET */
1653 *cmds++ = _SET(TPL1_TPTEXOFFSETREG_SAMPLEROFFSET, 16) |
1654 _SET(TPL1_TPTEXOFFSETREG_MEMOBJOFFSET, 16) |
1655 _SET(TPL1_TPTEXOFFSETREG_BASETABLEPTR, 224);
1656
1657 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1658 *cmds++ = CP_REG(A3XX_GRAS_SC_CONTROL);
1659 /* GRAS_SC_CONTROL */
Tarun Karra7e8e1cf2012-02-06 18:23:19 -08001660 /*cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1);
1661 *cmds++ = _SET(GRAS_SC_CONTROL_RASTER_MODE, 1) |*/
1662 *cmds++ = 0x04001000;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07001663
1664 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1665 *cmds++ = CP_REG(A3XX_GRAS_SU_MODE_CONTROL);
1666 /* GRAS_SU_MODE_CONTROL */
1667 *cmds++ = 0x00000000;
1668
1669 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1670 *cmds++ = CP_REG(A3XX_GRAS_SC_WINDOW_SCISSOR_TL);
1671 /* GRAS_SC_WINDOW_SCISSOR_TL */
1672 *cmds++ = 0x00000000;
1673 /* GRAS_SC_WINDOW_SCISSOR_BR */
1674 *cmds++ = _SET(GRAS_SC_WINDOW_SCISSOR_BR_BR_X, shadow->width - 1) |
1675 _SET(GRAS_SC_WINDOW_SCISSOR_BR_BR_Y, shadow->height - 1);
1676
1677 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1678 *cmds++ = CP_REG(A3XX_GRAS_SC_SCREEN_SCISSOR_TL);
1679 /* GRAS_SC_SCREEN_SCISSOR_TL */
1680 *cmds++ = 0x00000000;
1681 /* GRAS_SC_SCREEN_SCISSOR_BR */
1682 *cmds++ = _SET(GRAS_SC_SCREEN_SCISSOR_BR_BR_X, shadow->width - 1) |
1683 _SET(GRAS_SC_SCREEN_SCISSOR_BR_BR_Y, shadow->height - 1);
1684
1685 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 5);
1686 *cmds++ = CP_REG(A3XX_GRAS_CL_VPORT_XOFFSET);
1687 /* GRAS_CL_VPORT_XOFFSET */
1688 *cmds++ = 0x00000000;
1689 /* GRAS_CL_VPORT_XSCALE */
1690 *cmds++ = _SET(GRAS_CL_VPORT_XSCALE_VPORT_XSCALE, 0x3F800000);
1691 /* GRAS_CL_VPORT_YOFFSET */
1692 *cmds++ = 0x00000000;
1693 /* GRAS_CL_VPORT_YSCALE */
1694 *cmds++ = _SET(GRAS_CL_VPORT_YSCALE_VPORT_YSCALE, 0x3F800000);
1695
1696 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 3);
1697 *cmds++ = CP_REG(A3XX_GRAS_CL_VPORT_ZOFFSET);
1698 /* GRAS_CL_VPORT_ZOFFSET */
1699 *cmds++ = 0x00000000;
1700 /* GRAS_CL_VPORT_ZSCALE */
1701 *cmds++ = _SET(GRAS_CL_VPORT_ZSCALE_VPORT_ZSCALE, 0x3F800000);
1702
1703 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1704 *cmds++ = CP_REG(A3XX_GRAS_CL_CLIP_CNTL);
1705 /* GRAS_CL_CLIP_CNTL */
1706 *cmds++ = _SET(GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER, 1);
1707
1708 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1709 *cmds++ = CP_REG(A3XX_SP_FS_IMAGE_OUTPUT_REG_0);
1710 /* SP_FS_IMAGE_OUTPUT_REG_0 */
1711 *cmds++ = _SET(SP_IMAGEOUTPUTREG_MRTFORMAT, SP_R8G8B8A8_UNORM);
1712
1713 *cmds++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1714 *cmds++ = CP_REG(A3XX_PC_PRIM_VTX_CNTL);
1715 /* PC_PRIM_VTX_CONTROL */
1716 *cmds++ = _SET(PC_PRIM_VTX_CONTROL_STRIDE_IN_VPC, 2) |
1717 _SET(PC_PRIM_VTX_CONTROL_POLYMODE_FRONT_PTYPE,
1718 PC_DRAW_TRIANGLES) |
1719 _SET(PC_PRIM_VTX_CONTROL_POLYMODE_BACK_PTYPE,
1720 PC_DRAW_TRIANGLES) |
1721 _SET(PC_PRIM_VTX_CONTROL_PROVOKING_VTX_LAST, 1);
1722
1723 *cmds++ = cp_type3_packet(CP_DRAW_INDX, 3);
1724 *cmds++ = 0x00000000; /* Viz query info */
1725 *cmds++ = BUILD_PC_DRAW_INITIATOR(PC_DI_PT_RECTLIST,
1726 PC_DI_SRC_SEL_AUTO_INDEX,
1727 PC_DI_INDEX_SIZE_16_BIT,
1728 PC_DI_IGNORE_VISIBILITY);
1729 *cmds++ = 0x00000002; /* Num indices */
1730
1731 /* Create indirect buffer command for above command sequence */
1732 create_ib1(drawctxt, shadow->gmem_restore, start, cmds);
1733
1734 return cmds;
1735}
1736
1737static void build_regrestore_cmds(struct adreno_device *adreno_dev,
1738 struct adreno_context *drawctxt)
1739{
1740 unsigned int *start = tmp_ctx.cmd;
1741 unsigned int *cmd = start;
1742 unsigned int *lcc_start;
1743
1744 int i;
1745
1746 /* Flush HLSQ lazy updates */
1747 *cmd++ = cp_type3_packet(CP_EVENT_WRITE, 1);
1748 *cmd++ = 0x7; /* HLSQ_FLUSH */
1749 *cmd++ = cp_type3_packet(CP_WAIT_FOR_IDLE, 1);
1750 *cmd++ = 0;
1751
1752 *cmd++ = cp_type0_packet(A3XX_UCHE_CACHE_INVALIDATE0_REG, 2);
1753 *cmd++ = 0x00000000; /* No start addr for full invalidate */
1754 *cmd++ = (unsigned int)
1755 UCHE_ENTIRE_CACHE << UCHE_INVALIDATE1REG_ALLORPORTION |
1756 UCHE_OP_INVALIDATE << UCHE_INVALIDATE1REG_OPCODE |
1757 0; /* No end addr for full invalidate */
1758
1759 lcc_start = cmd;
1760
1761 /* deferred cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, ???); */
1762 cmd++;
1763
1764#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1765 /* Force mismatch */
1766 *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1;
1767#else
1768 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1769#endif
1770
1771 for (i = 0; i < ARRAY_SIZE(context_register_ranges) / 2; i++) {
1772 cmd = reg_range(cmd, context_register_ranges[i * 2],
1773 context_register_ranges[i * 2 + 1]);
1774 }
1775
1776 lcc_start[0] = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT,
1777 (cmd - lcc_start) - 1);
1778
1779#ifdef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1780 lcc_start[2] |= (0 << 24) | (4 << 16); /* Disable shadowing. */
1781#else
1782 lcc_start[2] |= (1 << 24) | (4 << 16);
1783#endif
1784
1785 for (i = 0; i < ARRAY_SIZE(global_registers); i++) {
1786 *cmd++ = cp_type0_packet(global_registers[i], 1);
1787 tmp_ctx.reg_values[i] = virt2gpu(cmd, &drawctxt->gpustate);
1788 *cmd++ = 0x00000000;
1789 }
1790
1791 create_ib1(drawctxt, drawctxt->reg_restore, start, cmd);
1792 tmp_ctx.cmd = cmd;
1793}
1794
1795static void build_constantrestore_cmds(struct adreno_device *adreno_dev,
1796 struct adreno_context *drawctxt)
1797{
1798 unsigned int *cmd = tmp_ctx.cmd;
1799 unsigned int *start = cmd;
1800 unsigned int mode = 4; /* Indirect mode */
1801 unsigned int stateblock;
1802 unsigned int numunits;
1803 unsigned int statetype;
1804
1805 drawctxt->cond_execs[2].hostptr = cmd;
1806 drawctxt->cond_execs[2].gpuaddr = virt2gpu(cmd, &drawctxt->gpustate);
1807 *cmd++ = 0;
1808 drawctxt->cond_execs[3].hostptr = cmd;
1809 drawctxt->cond_execs[3].gpuaddr = virt2gpu(cmd, &drawctxt->gpustate);
1810 *cmd++ = 0;
1811
1812#ifndef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1813 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
1814 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1815 *cmd++ = 4 << 16;
1816 *cmd++ = 0x0;
1817#endif
1818 /* HLSQ full update */
1819 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 2);
1820 *cmd++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG);
1821 *cmd++ = 0x68000240; /* A3XX_HLSQ_CONTROL_0_REG */
1822
1823#ifndef CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES
1824 /* Re-enable shadowing */
1825 *cmd++ = cp_type3_packet(CP_LOAD_CONSTANT_CONTEXT, 3);
1826 *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000;
1827 *cmd++ = (4 << 16) | (1 << 24);
1828 *cmd++ = 0x0;
1829#endif
1830
1831 /* Load vertex shader constants */
1832 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
1833 *cmd++ = drawctxt->cond_execs[2].gpuaddr >> 2;
1834 *cmd++ = drawctxt->cond_execs[2].gpuaddr >> 2;
1835 *cmd++ = 0x0000ffff;
1836 *cmd++ = 3; /* EXEC_COUNT */
1837 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1838 drawctxt->constant_load_commands[0].hostptr = cmd;
1839 drawctxt->constant_load_commands[0].gpuaddr = virt2gpu(cmd,
1840 &drawctxt->gpustate);
1841
1842 /*
1843 From fixup:
1844
1845 mode = 4 (indirect)
1846 stateblock = 4 (Vertex constants)
1847 numunits = SP_VS_CTRL_REG1.VSCONSTLENGTH * 2; (256bit units)
1848
1849 From register spec:
1850 SP_VS_CTRL_REG1.VSCONSTLENGTH [09:00]: 0-512, unit = 128bits.
1851
1852 ord1 = (numunits<<22) | (stateblock<<19) | (mode<<16);
1853 */
1854
1855 *cmd++ = 0; /* ord1 */
1856 *cmd++ = ((drawctxt->gpustate.gpuaddr) & 0xfffffffc) | 1;
1857
1858 /* Load fragment shader constants */
1859 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
1860 *cmd++ = drawctxt->cond_execs[3].gpuaddr >> 2;
1861 *cmd++ = drawctxt->cond_execs[3].gpuaddr >> 2;
1862 *cmd++ = 0x0000ffff;
1863 *cmd++ = 3; /* EXEC_COUNT */
1864 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1865 drawctxt->constant_load_commands[1].hostptr = cmd;
1866 drawctxt->constant_load_commands[1].gpuaddr =
1867 virt2gpu(cmd, &drawctxt->gpustate);
1868 /*
1869 From fixup:
1870
1871 mode = 4 (indirect)
1872 stateblock = 6 (Fragment constants)
1873 numunits = SP_FS_CTRL_REG1.FSCONSTLENGTH * 2; (256bit units)
1874
1875 From register spec:
1876 SP_FS_CTRL_REG1.FSCONSTLENGTH [09:00]: 0-512, unit = 128bits.
1877
1878 ord1 = (numunits<<22) | (stateblock<<19) | (mode<<16);
1879 */
1880
1881 *cmd++ = 0; /* ord1 */
1882 drawctxt->constant_load_commands[2].hostptr = cmd;
1883 drawctxt->constant_load_commands[2].gpuaddr =
1884 virt2gpu(cmd, &drawctxt->gpustate);
1885 /*
1886 From fixup:
1887 base = drawctxt->gpustate.gpuaddr (ALU constant shadow base)
1888 offset = SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET
1889
1890 From register spec:
1891 SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
1892 start offset in on chip RAM,
1893 128bit aligned
1894
1895 ord2 = base + offset | 1
1896 Because of the base alignment we can use
1897 ord2 = base | offset | 1
1898 */
1899 *cmd++ = 0; /* ord2 */
1900
1901 /* Restore VS texture memory objects */
1902 stateblock = 0;
1903 statetype = 1;
1904 numunits = (TEX_SIZE_MEM_OBJECTS / 7) / 4;
1905
1906 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1907 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1908 *cmd++ = ((drawctxt->gpustate.gpuaddr + VS_TEX_OFFSET_MEM_OBJECTS)
1909 & 0xfffffffc) | statetype;
1910
1911 /* Restore VS texture mipmap addresses */
1912 stateblock = 1;
1913 statetype = 1;
1914 numunits = TEX_SIZE_MIPMAP / 4;
1915 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1916 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1917 *cmd++ = ((drawctxt->gpustate.gpuaddr + VS_TEX_OFFSET_MIPMAP)
1918 & 0xfffffffc) | statetype;
1919
1920 /* Restore VS texture sampler objects */
1921 stateblock = 0;
1922 statetype = 0;
1923 numunits = (TEX_SIZE_SAMPLER_OBJ / 2) / 4;
1924 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1925 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1926 *cmd++ = ((drawctxt->gpustate.gpuaddr + VS_TEX_OFFSET_SAMPLER_OBJ)
1927 & 0xfffffffc) | statetype;
1928
1929 /* Restore FS texture memory objects */
1930 stateblock = 2;
1931 statetype = 1;
1932 numunits = (TEX_SIZE_MEM_OBJECTS / 7) / 4;
1933 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1934 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1935 *cmd++ = ((drawctxt->gpustate.gpuaddr + FS_TEX_OFFSET_MEM_OBJECTS)
1936 & 0xfffffffc) | statetype;
1937
1938 /* Restore FS texture mipmap addresses */
1939 stateblock = 3;
1940 statetype = 1;
1941 numunits = TEX_SIZE_MIPMAP / 4;
1942 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1943 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1944 *cmd++ = ((drawctxt->gpustate.gpuaddr + FS_TEX_OFFSET_MIPMAP)
1945 & 0xfffffffc) | statetype;
1946
1947 /* Restore FS texture sampler objects */
1948 stateblock = 2;
1949 statetype = 0;
1950 numunits = (TEX_SIZE_SAMPLER_OBJ / 2) / 4;
1951 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1952 *cmd++ = (numunits << 22) | (stateblock << 19) | (mode << 16);
1953 *cmd++ = ((drawctxt->gpustate.gpuaddr + FS_TEX_OFFSET_SAMPLER_OBJ)
1954 & 0xfffffffc) | statetype;
1955
1956 create_ib1(drawctxt, drawctxt->constant_restore, start, cmd);
1957 tmp_ctx.cmd = cmd;
1958}
1959
1960static void build_shader_restore_cmds(struct adreno_device *adreno_dev,
1961 struct adreno_context *drawctxt)
1962{
1963 unsigned int *cmd = tmp_ctx.cmd;
1964 unsigned int *start = cmd;
1965
1966 /* Vertex shader */
1967 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
1968 *cmd++ = drawctxt->cond_execs[0].gpuaddr >> 2;
1969 *cmd++ = drawctxt->cond_execs[0].gpuaddr >> 2;
1970 *cmd++ = 1;
1971 *cmd++ = 3; /* EXEC_COUNT */
1972
1973 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
1974 drawctxt->shader_load_commands[0].hostptr = cmd;
1975 drawctxt->shader_load_commands[0].gpuaddr =
1976 virt2gpu(cmd, &drawctxt->gpustate);
1977 /*
1978 From fixup:
1979
1980 mode = 4 (indirect)
1981 stateblock = 4 (Vertex shader)
1982 numunits = SP_VS_CTRL_REG0.VS_LENGTH
1983
1984 From regspec:
1985 SP_VS_CTRL_REG0.VS_LENGTH [31:24]: VS length, unit = 256bits.
1986 If bit31 is 1, it means overflow
1987 or any long shader.
1988
1989 ord1 = (numunits<<22) | (stateblock<<19) | (mode<<11)
1990 */
1991 *cmd++ = 0; /*ord1 */
1992 *cmd++ = (drawctxt->gpustate.gpuaddr + SHADER_OFFSET) & 0xfffffffc;
1993
1994 /* Fragment shader */
1995 *cmd++ = cp_type3_packet(CP_COND_EXEC, 4);
1996 *cmd++ = drawctxt->cond_execs[1].gpuaddr >> 2;
1997 *cmd++ = drawctxt->cond_execs[1].gpuaddr >> 2;
1998 *cmd++ = 1;
1999 *cmd++ = 3; /* EXEC_COUNT */
2000
2001 *cmd++ = cp_type3_packet(CP_LOAD_STATE, 2);
2002 drawctxt->shader_load_commands[1].hostptr = cmd;
2003 drawctxt->shader_load_commands[1].gpuaddr =
2004 virt2gpu(cmd, &drawctxt->gpustate);
2005 /*
2006 From fixup:
2007
2008 mode = 4 (indirect)
2009 stateblock = 6 (Fragment shader)
2010 numunits = SP_FS_CTRL_REG0.FS_LENGTH
2011
2012 From regspec:
2013 SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
2014 If bit31 is 1, it means overflow
2015 or any long shader.
2016
2017 ord1 = (numunits<<22) | (stateblock<<19) | (mode<<11)
2018 */
2019 *cmd++ = 0; /*ord1 */
2020 *cmd++ = (drawctxt->gpustate.gpuaddr + SHADER_OFFSET
2021 + (SHADER_SHADOW_SIZE / 2)) & 0xfffffffc;
2022
2023 create_ib1(drawctxt, drawctxt->shader_restore, start, cmd);
2024 tmp_ctx.cmd = cmd;
2025}
2026
2027static void build_hlsqcontrol_restore_cmds(struct adreno_device *adreno_dev,
2028 struct adreno_context *drawctxt)
2029{
2030 unsigned int *cmd = tmp_ctx.cmd;
2031 unsigned int *start = cmd;
2032
2033 *cmd++ = cp_type3_packet(CP_SET_CONSTANT, 2);
2034 *cmd++ = CP_REG(A3XX_HLSQ_CONTROL_0_REG);
2035 drawctxt->hlsqcontrol_restore_commands[0].hostptr = cmd;
2036 drawctxt->hlsqcontrol_restore_commands[0].gpuaddr
2037 = virt2gpu(cmd, &drawctxt->gpustate);
2038 *cmd++ = 0;
2039
2040 /* Create indirect buffer command for above command sequence */
2041 create_ib1(drawctxt, drawctxt->hlsqcontrol_restore, start, cmd);
2042
2043 tmp_ctx.cmd = cmd;
2044}
2045
2046/* IB that modifies the shader and constant sizes and offsets in restore IBs. */
2047static void build_restore_fixup_cmds(struct adreno_device *adreno_dev,
2048 struct adreno_context *drawctxt)
2049{
2050 unsigned int *cmd = tmp_ctx.cmd;
2051 unsigned int *start = cmd;
2052
2053#ifdef GSL_CONTEXT_SWITCH_CPU_SYNC
2054 /* Save shader sizes */
2055 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
2056 *cmd++ = A3XX_SP_VS_CTRL_REG0;
2057 *cmd++ = drawctxt->shader_load_commands[0].gpuaddr;
2058
2059 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
2060 *cmd++ = A3XX_SP_FS_CTRL_REG0;
2061 *cmd++ = drawctxt->shader_load_commands[1].gpuaddr;
2062
2063 /* Save constant sizes */
2064 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
2065 *cmd++ = A3XX_SP_VS_CTRL_REG1;
2066 *cmd++ = drawctxt->constant_load_commands[0].gpuaddr;
2067
2068 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
2069 *cmd++ = A3XX_SP_FS_CTRL_REG1;
2070 *cmd++ = drawctxt->constant_load_commands[1].gpuaddr;
2071
2072 /* Save constant offsets */
2073 *cmd++ = cp_type3_packet(CP_REG_TO_MEM, 2);
2074 *cmd++ = A3XX_SP_FS_OBJ_OFFSET_REG;
2075 *cmd++ = drawctxt->constant_load_commands[2].gpuaddr;
2076#else
2077 /* Save shader sizes */
2078 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG0, 0x7f000000,
2079 30, (4 << 19) | (4 << 16),
2080 drawctxt->shader_load_commands[0].gpuaddr);
2081
2082 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG0, 0x7f000000,
2083 30, (6 << 19) | (4 << 16),
2084 drawctxt->shader_load_commands[1].gpuaddr);
2085
2086 /* Save constant sizes */
2087 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG1, 0x000003ff,
2088 23, (4 << 19) | (4 << 16),
2089 drawctxt->constant_load_commands[0].gpuaddr);
2090
2091 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG1, 0x000003ff,
2092 23, (6 << 19) | (4 << 16),
2093 drawctxt->constant_load_commands[1].gpuaddr);
2094
2095 /* Modify constant restore conditionals */
2096 cmd = rmw_regtomem(cmd, A3XX_SP_VS_CTRL_REG1, 0x000003ff,
2097 0, 0, drawctxt->cond_execs[2].gpuaddr);
2098
2099 cmd = rmw_regtomem(cmd, A3XX_SP_FS_CTRL_REG1, 0x000003ff,
2100 0, 0, drawctxt->cond_execs[3].gpuaddr);
2101
2102 /* Save fragment constant shadow offset */
2103 cmd = rmw_regtomem(cmd, A3XX_SP_FS_OBJ_OFFSET_REG, 0x00ff0000,
2104 18, (drawctxt->gpustate.gpuaddr & 0xfffffe00) | 1,
2105 drawctxt->constant_load_commands[2].gpuaddr);
2106#endif
2107
2108 /* Use mask value to avoid flushing HLSQ which would cause the HW to
2109 discard all the shader data */
2110
2111 cmd = rmw_regtomem(cmd, A3XX_HLSQ_CONTROL_0_REG, 0x9ffffdff,
2112 0, 0, drawctxt->hlsqcontrol_restore_commands[0].gpuaddr);
2113
2114 create_ib1(drawctxt, drawctxt->restore_fixup, start, cmd);
2115
2116 tmp_ctx.cmd = cmd;
2117}
2118
2119static int a3xx_create_gpustate_shadow(struct adreno_device *adreno_dev,
2120 struct adreno_context *drawctxt)
2121{
2122 drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW;
2123
2124 build_regrestore_cmds(adreno_dev, drawctxt);
2125 build_constantrestore_cmds(adreno_dev, drawctxt);
2126 build_hlsqcontrol_restore_cmds(adreno_dev, drawctxt);
2127 build_regconstantsave_cmds(adreno_dev, drawctxt);
2128 build_shader_save_cmds(adreno_dev, drawctxt);
2129 build_shader_restore_cmds(adreno_dev, drawctxt);
2130 build_restore_fixup_cmds(adreno_dev, drawctxt);
2131 build_save_fixup_cmds(adreno_dev, drawctxt);
2132
2133 return 0;
2134}
2135
2136/* create buffers for saving/restoring registers, constants, & GMEM */
2137static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev,
2138 struct adreno_context *drawctxt)
2139{
Jordan Crousea7ec4212012-02-04 10:23:52 -07002140 int result;
2141
Jordan Crouse7501d452012-04-19 08:58:44 -06002142 calc_gmemsize(&drawctxt->context_gmem_shadow, adreno_dev->gmem_size);
2143 tmp_ctx.gmem_base = adreno_dev->gmem_base;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002144
Jordan Crousea7ec4212012-02-04 10:23:52 -07002145 result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
2146 drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002147
Jordan Crousea7ec4212012-02-04 10:23:52 -07002148 if (result)
2149 return result;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002150
2151 build_quad_vtxbuff(drawctxt, &drawctxt->context_gmem_shadow,
2152 &tmp_ctx.cmd);
2153
2154 /* Dow we need to idle? */
2155 /* adreno_idle(&adreno_dev->dev, KGSL_TIMEOUT_DEFAULT); */
2156
2157 tmp_ctx.cmd = build_gmem2sys_cmds(adreno_dev, drawctxt,
2158 &drawctxt->context_gmem_shadow);
2159 tmp_ctx.cmd = build_sys2gmem_cmds(adreno_dev, drawctxt,
2160 &drawctxt->context_gmem_shadow);
2161
2162 kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
2163 KGSL_CACHE_OP_FLUSH);
2164
Jordan Crousea7ec4212012-02-04 10:23:52 -07002165 drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
2166
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002167 return 0;
2168}
2169
2170static int a3xx_drawctxt_create(struct adreno_device *adreno_dev,
2171 struct adreno_context *drawctxt)
2172{
2173 int ret;
2174
2175 /*
2176 * Allocate memory for the GPU state and the context commands.
2177 * Despite the name, this is much more then just storage for
2178 * the gpustate. This contains command space for gmem save
2179 * and texture and vertex buffer storage too
2180 */
2181
2182 ret = kgsl_allocate(&drawctxt->gpustate,
2183 drawctxt->pagetable, CONTEXT_SIZE);
2184
2185 if (ret)
2186 return ret;
2187
2188 kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0, CONTEXT_SIZE);
2189 tmp_ctx.cmd = drawctxt->gpustate.hostptr + CMD_OFFSET;
2190
2191 if (!(drawctxt->flags & CTXT_FLAGS_PREAMBLE)) {
2192 ret = a3xx_create_gpustate_shadow(adreno_dev, drawctxt);
2193 if (ret)
2194 goto done;
2195
2196 drawctxt->flags |= CTXT_FLAGS_SHADER_SAVE;
2197 }
2198
2199 if (!(drawctxt->flags & CTXT_FLAGS_NOGMEMALLOC))
2200 ret = a3xx_create_gmem_shadow(adreno_dev, drawctxt);
2201
2202done:
2203 if (ret)
2204 kgsl_sharedmem_free(&drawctxt->gpustate);
2205
2206 return ret;
2207}
2208
2209static void a3xx_drawctxt_save(struct adreno_device *adreno_dev,
2210 struct adreno_context *context)
2211{
2212 struct kgsl_device *device = &adreno_dev->dev;
2213
2214 if (context == NULL)
2215 return;
2216
2217 if (context->flags & CTXT_FLAGS_GPU_HANG)
2218 KGSL_CTXT_WARN(device,
2219 "Current active context has caused gpu hang\n");
2220
2221 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
2222 /* Fixup self modifying IBs for save operations */
2223 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2224 context->save_fixup, 3);
2225
2226 /* save registers and constants. */
2227 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2228 context->regconstant_save, 3);
2229
2230 if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
2231 /* Save shader instructions */
2232 adreno_ringbuffer_issuecmds(device,
2233 KGSL_CMD_FLAGS_PMODE, context->shader_save, 3);
2234
2235 context->flags |= CTXT_FLAGS_SHADER_RESTORE;
2236 }
2237 }
2238
2239 if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
2240 (context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
2241 /*
2242 * Save GMEM (note: changes shader. shader must
2243 * already be saved.)
2244 */
2245
2246 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
2247 context->context_gmem_shadow.
2248 gmem_save, 3);
2249 context->flags |= CTXT_FLAGS_GMEM_RESTORE;
2250 }
2251}
2252
2253static void a3xx_drawctxt_restore(struct adreno_device *adreno_dev,
2254 struct adreno_context *context)
2255{
2256 struct kgsl_device *device = &adreno_dev->dev;
2257 unsigned int cmds[5];
2258
2259 if (context == NULL) {
2260 /* No context - set the default pagetable and thats it */
Shubhraprakash Das79447952012-04-26 18:12:23 -06002261 kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002262 return;
2263 }
2264
2265 KGSL_CTXT_INFO(device, "context flags %08x\n", context->flags);
2266
2267 cmds[0] = cp_nop_packet(1);
2268 cmds[1] = KGSL_CONTEXT_TO_MEM_IDENTIFIER;
2269 cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
2270 cmds[3] = device->memstore.gpuaddr +
Carter Cooper7e7f02e2012-02-15 09:36:31 -07002271 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
2272 cmds[4] = context->id;
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002273 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE, cmds, 5);
Shubhraprakash Das79447952012-04-26 18:12:23 -06002274 kgsl_mmu_setstate(&device->mmu, context->pagetable);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002275
2276 /*
2277 * Restore GMEM. (note: changes shader.
2278 * Shader must not already be restored.)
2279 */
2280
2281 if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
2282 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE,
2283 context->context_gmem_shadow.
2284 gmem_restore, 3);
2285 context->flags &= ~CTXT_FLAGS_GMEM_RESTORE;
2286 }
2287
2288 if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
2289 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2290 context->reg_restore, 3);
2291
2292 /* Fixup self modifying IBs for restore operations */
2293 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2294 context->restore_fixup, 3);
2295
2296 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2297 context->constant_restore, 3);
2298
2299 if (context->flags & CTXT_FLAGS_SHADER_RESTORE)
2300 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2301 context->shader_restore, 3);
2302
2303 /* Restore HLSQ_CONTROL_0 register */
2304 adreno_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NONE,
2305 context->hlsqcontrol_restore, 3);
2306 }
2307}
2308
2309static void a3xx_rb_init(struct adreno_device *adreno_dev,
2310 struct adreno_ringbuffer *rb)
2311{
2312 unsigned int *cmds, cmds_gpu;
2313 cmds = adreno_ringbuffer_allocspace(rb, 18);
2314 cmds_gpu = rb->buffer_desc.gpuaddr + sizeof(uint) * (rb->wptr - 18);
2315
2316 GSL_RB_WRITE(cmds, cmds_gpu, cp_type3_packet(CP_ME_INIT, 17));
2317 GSL_RB_WRITE(cmds, cmds_gpu, 0x000003f7);
2318 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2319 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2320 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2321 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000080);
2322 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000100);
2323 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000180);
2324 GSL_RB_WRITE(cmds, cmds_gpu, 0x00006600);
2325 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000150);
2326 GSL_RB_WRITE(cmds, cmds_gpu, 0x0000014e);
2327 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000154);
2328 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000001);
2329 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2330 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2331 /* Protected mode control - turned off for A3XX */
2332 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2333 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2334 GSL_RB_WRITE(cmds, cmds_gpu, 0x00000000);
2335
2336 adreno_ringbuffer_submit(rb);
2337}
2338
Jordan Crousedc932302012-05-23 11:16:18 -06002339#define VBIF_MAX_CLIENTS 6
2340
2341static void a3xx_vbif_callback(struct adreno_device *adreno_dev,
2342 unsigned int status)
2343{
2344 struct kgsl_device *device = &adreno_dev->dev;
2345 int i;
2346 char str[80], *ptr = str;
2347 int slen = sizeof(str) - 1;
2348
2349 KGSL_DRV_INFO(device, "VBIF error | status=%X\n",
2350 status);
2351
2352 for (i = 0; i < VBIF_MAX_CLIENTS; i++) {
2353 if (status & (1 << i)) {
2354 unsigned int err;
2355 int ret;
2356
2357 adreno_regwrite(device, A3XX_VBIF_ERR_INFO, i);
2358 adreno_regread(device, A3XX_VBIF_ERR_INFO, &err);
2359
2360 ret = snprintf(ptr, slen, "%d:%8.8X ", i, err);
2361 ptr += ret;
2362 slen -= ret;
2363 }
2364 }
2365
2366 KGSL_DRV_INFO(device, "%s\n", str);
2367
2368 /* Clear the errors */
2369 adreno_regwrite(device, A3XX_VBIF_ERR_CLEAR, status);
2370}
2371
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002372static void a3xx_err_callback(struct adreno_device *adreno_dev, int bit)
2373{
2374 struct kgsl_device *device = &adreno_dev->dev;
2375 const char *err = "";
2376
2377 switch (bit) {
2378 case A3XX_INT_RBBM_AHB_ERROR: {
2379 unsigned int reg;
2380
2381 adreno_regread(device, A3XX_RBBM_AHB_ERROR_STATUS, &reg);
2382
2383 /*
2384 * Return the word address of the erroring register so that it
2385 * matches the register specification
2386 */
2387
2388 KGSL_DRV_CRIT(device,
2389 "RBBM | AHB bus error | %s | addr=%x | ports=%x:%x\n",
2390 reg & (1 << 28) ? "WRITE" : "READ",
2391 (reg & 0xFFFFF) >> 2, (reg >> 20) & 0x3,
2392 (reg >> 24) & 0x3);
2393
2394 /* Clear the error */
2395 adreno_regwrite(device, A3XX_RBBM_AHB_CMD, (1 << 3));
2396 return;
2397 }
2398 case A3XX_INT_RBBM_REG_TIMEOUT:
2399 err = "RBBM: AHB register timeout";
2400 break;
2401 case A3XX_INT_RBBM_ME_MS_TIMEOUT:
2402 err = "RBBM: ME master split timeout";
2403 break;
2404 case A3XX_INT_RBBM_PFP_MS_TIMEOUT:
2405 err = "RBBM: PFP master split timeout";
2406 break;
2407 case A3XX_INT_RBBM_ATB_BUS_OVERFLOW:
2408 err = "RBBM: ATB bus oveflow";
2409 break;
2410 case A3XX_INT_VFD_ERROR:
2411 err = "VFD: Out of bounds access";
2412 break;
2413 case A3XX_INT_CP_T0_PACKET_IN_IB:
2414 err = "ringbuffer TO packet in IB interrupt";
2415 break;
2416 case A3XX_INT_CP_OPCODE_ERROR:
2417 err = "ringbuffer opcode error interrupt";
2418 break;
2419 case A3XX_INT_CP_RESERVED_BIT_ERROR:
2420 err = "ringbuffer reserved bit error interrupt";
2421 break;
2422 case A3XX_INT_CP_HW_FAULT:
2423 err = "ringbuffer hardware fault";
2424 break;
2425 case A3XX_INT_CP_REG_PROTECT_FAULT:
2426 err = "ringbuffer protected mode error interrupt";
2427 break;
2428 case A3XX_INT_CP_AHB_ERROR_HALT:
2429 err = "ringbuffer AHB error interrupt";
2430 break;
2431 case A3XX_INT_MISC_HANG_DETECT:
2432 err = "MISC: GPU hang detected";
2433 break;
2434 case A3XX_INT_UCHE_OOB_ACCESS:
2435 err = "UCHE: Out of bounds access";
2436 break;
2437 }
2438
2439 KGSL_DRV_CRIT(device, "%s\n", err);
2440 kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
2441}
2442
2443static void a3xx_cp_callback(struct adreno_device *adreno_dev, int irq)
2444{
2445 struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
2446
2447 if (irq == A3XX_INT_CP_RB_INT) {
Carter Cooper7e7f02e2012-02-15 09:36:31 -07002448 unsigned int context_id;
2449 kgsl_sharedmem_readl(&adreno_dev->dev.memstore,
2450 &context_id,
2451 KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
2452 current_context));
2453 if (context_id < KGSL_MEMSTORE_MAX) {
2454 kgsl_sharedmem_writel(&rb->device->memstore,
2455 KGSL_MEMSTORE_OFFSET(context_id,
2456 ts_cmp_enable), 0);
2457 wmb();
2458 }
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002459 KGSL_CMD_WARN(rb->device, "ringbuffer rb interrupt\n");
2460 }
2461
2462 wake_up_interruptible_all(&rb->device->wait_queue);
2463
2464 /* Schedule work to free mem and issue ibs */
2465 queue_work(rb->device->work_queue, &rb->device->ts_expired_ws);
2466
2467 atomic_notifier_call_chain(&rb->device->ts_notifier_list,
2468 rb->device->id, NULL);
2469}
2470
2471#define A3XX_IRQ_CALLBACK(_c) { .func = _c }
2472
2473#define A3XX_INT_MASK \
2474 ((1 << A3XX_INT_RBBM_AHB_ERROR) | \
2475 (1 << A3XX_INT_RBBM_REG_TIMEOUT) | \
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002476 (1 << A3XX_INT_RBBM_ATB_BUS_OVERFLOW) | \
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002477 (1 << A3XX_INT_CP_T0_PACKET_IN_IB) | \
2478 (1 << A3XX_INT_CP_OPCODE_ERROR) | \
2479 (1 << A3XX_INT_CP_RESERVED_BIT_ERROR) | \
2480 (1 << A3XX_INT_CP_HW_FAULT) | \
2481 (1 << A3XX_INT_CP_IB1_INT) | \
2482 (1 << A3XX_INT_CP_IB2_INT) | \
2483 (1 << A3XX_INT_CP_RB_INT) | \
2484 (1 << A3XX_INT_CP_REG_PROTECT_FAULT) | \
2485 (1 << A3XX_INT_CP_AHB_ERROR_HALT) | \
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002486 (1 << A3XX_INT_UCHE_OOB_ACCESS))
2487
2488static struct {
2489 void (*func)(struct adreno_device *, int);
2490} a3xx_irq_funcs[] = {
2491 A3XX_IRQ_CALLBACK(NULL), /* 0 - RBBM_GPU_IDLE */
2492 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 1 - RBBM_AHB_ERROR */
2493 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 2 - RBBM_REG_TIMEOUT */
2494 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 3 - RBBM_ME_MS_TIMEOUT */
2495 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 4 - RBBM_PFP_MS_TIMEOUT */
2496 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 5 - RBBM_ATB_BUS_OVERFLOW */
2497 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 6 - RBBM_VFD_ERROR */
2498 A3XX_IRQ_CALLBACK(NULL), /* 7 - CP_SW */
2499 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 8 - CP_T0_PACKET_IN_IB */
2500 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 9 - CP_OPCODE_ERROR */
2501 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 10 - CP_RESERVED_BIT_ERROR */
2502 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 11 - CP_HW_FAULT */
2503 A3XX_IRQ_CALLBACK(NULL), /* 12 - CP_DMA */
2504 A3XX_IRQ_CALLBACK(a3xx_cp_callback), /* 13 - CP_IB2_INT */
2505 A3XX_IRQ_CALLBACK(a3xx_cp_callback), /* 14 - CP_IB1_INT */
2506 A3XX_IRQ_CALLBACK(a3xx_cp_callback), /* 15 - CP_RB_INT */
2507 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 16 - CP_REG_PROTECT_FAULT */
2508 A3XX_IRQ_CALLBACK(NULL), /* 17 - CP_RB_DONE_TS */
2509 A3XX_IRQ_CALLBACK(NULL), /* 18 - CP_VS_DONE_TS */
2510 A3XX_IRQ_CALLBACK(NULL), /* 19 - CP_PS_DONE_TS */
2511 A3XX_IRQ_CALLBACK(NULL), /* 20 - CP_CACHE_FLUSH_TS */
2512 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 21 - CP_AHB_ERROR_FAULT */
2513 A3XX_IRQ_CALLBACK(NULL), /* 22 - Unused */
2514 A3XX_IRQ_CALLBACK(NULL), /* 23 - Unused */
Jordan Crouseb6ebffe2012-02-04 10:23:53 -07002515 A3XX_IRQ_CALLBACK(NULL), /* 24 - MISC_HANG_DETECT */
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002516 A3XX_IRQ_CALLBACK(a3xx_err_callback), /* 25 - UCHE_OOB_ACCESS */
2517 /* 26 to 31 - Unused */
2518};
2519
2520static irqreturn_t a3xx_irq_handler(struct adreno_device *adreno_dev)
2521{
2522 struct kgsl_device *device = &adreno_dev->dev;
2523 irqreturn_t ret = IRQ_NONE;
2524 unsigned int status, tmp;
2525 int i;
2526
2527 adreno_regread(&adreno_dev->dev, A3XX_RBBM_INT_0_STATUS, &status);
2528
2529 for (tmp = status, i = 0; tmp && i < ARRAY_SIZE(a3xx_irq_funcs); i++) {
2530 if (tmp & 1) {
2531 if (a3xx_irq_funcs[i].func != NULL) {
2532 a3xx_irq_funcs[i].func(adreno_dev, i);
2533 ret = IRQ_HANDLED;
2534 } else {
2535 KGSL_DRV_CRIT(device,
2536 "Unhandled interrupt bit %x\n", i);
2537 }
2538 }
2539
2540 tmp >>= 1;
2541 }
2542
Carter Cooperb769c912012-04-13 08:16:35 -06002543 trace_kgsl_a3xx_irq_status(device, status);
2544
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002545 if (status)
2546 adreno_regwrite(&adreno_dev->dev, A3XX_RBBM_INT_CLEAR_CMD,
2547 status);
Jordan Crousedc932302012-05-23 11:16:18 -06002548
2549 /* Check for VBIF errors */
2550 adreno_regread(&adreno_dev->dev, A3XX_VBIF_ERR_PENDING, &status);
2551
2552 if (status) {
2553 a3xx_vbif_callback(adreno_dev, status);
2554 ret = IRQ_HANDLED;
2555 }
2556
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002557 return ret;
2558}
2559
2560static void a3xx_irq_control(struct adreno_device *adreno_dev, int state)
2561{
2562 struct kgsl_device *device = &adreno_dev->dev;
2563
Jordan Crousedc932302012-05-23 11:16:18 -06002564 if (state) {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002565 adreno_regwrite(device, A3XX_RBBM_INT_0_MASK, A3XX_INT_MASK);
Jordan Crousedc932302012-05-23 11:16:18 -06002566
2567 /* Enable VBIF interrupts - write 0 to enable them all */
2568 adreno_regwrite(device, A3XX_VBIF_ERR_MASK, 0);
2569 /* Clear outstanding VBIF errors */
2570 adreno_regwrite(device, A3XX_VBIF_ERR_CLEAR, 0x3F);
2571 } else {
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002572 adreno_regwrite(device, A3XX_RBBM_INT_0_MASK, 0);
Jordan Crousedc932302012-05-23 11:16:18 -06002573 adreno_regwrite(device, A3XX_VBIF_ERR_MASK, 0xFFFFFFFF);
2574 }
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002575}
2576
2577static unsigned int a3xx_busy_cycles(struct adreno_device *adreno_dev)
2578{
2579 struct kgsl_device *device = &adreno_dev->dev;
2580 unsigned int reg, val;
2581
2582 /* Freeze the counter */
2583 adreno_regread(device, A3XX_RBBM_RBBM_CTL, &reg);
2584 reg &= ~RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
2585 adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
2586
2587 /* Read the value */
2588 adreno_regread(device, A3XX_RBBM_PERFCTR_PWR_1_LO, &val);
2589
2590 /* Reset the counter */
2591 reg |= RBBM_RBBM_CTL_RESET_PWR_CTR1;
2592 adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
2593
2594 /* Re-enable the counter */
2595 reg &= ~RBBM_RBBM_CTL_RESET_PWR_CTR1;
2596 reg |= RBBM_RBBM_CTL_ENABLE_PWR_CTR1;
2597 adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, reg);
2598
2599 return val;
2600}
2601
2602static void a3xx_start(struct adreno_device *adreno_dev)
2603{
2604 struct kgsl_device *device = &adreno_dev->dev;
2605
2606 /* Reset the core */
2607 adreno_regwrite(device, A3XX_RBBM_SW_RESET_CMD,
2608 0x00000001);
2609 msleep(20);
2610
Jordan Crouse563cf0f2012-02-21 08:54:53 -07002611 /* Set up 16 deep read/write request queues */
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002612
Jordan Crouse563cf0f2012-02-21 08:54:53 -07002613 adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
2614 adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
2615 adreno_regwrite(device, A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010);
2616 adreno_regwrite(device, A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010);
2617 adreno_regwrite(device, A3XX_VBIF_DDR_OUT_MAX_BURST, 0x00000303);
2618 adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010);
2619 adreno_regwrite(device, A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010);
2620
2621 /* Enable WR-REQ */
2622 adreno_regwrite(device, A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x000000FF);
2623
2624 /* Set up round robin arbitration between both AXI ports */
2625 adreno_regwrite(device, A3XX_VBIF_ARB_CTL, 0x00000030);
2626
2627 /* Set up AOOO */
2628 adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003C);
2629 adreno_regwrite(device, A3XX_VBIF_OUT_AXI_AOOO, 0x003C003C);
2630
Sudhakara Rao Tentu5746bde2012-03-15 12:16:32 +05302631 if (cpu_is_apq8064()) {
2632 /* Enable 1K sort */
2633 adreno_regwrite(device, A3XX_VBIF_ABIT_SORT, 0x000000FF);
2634 adreno_regwrite(device, A3XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
2635 }
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002636 /* Make all blocks contribute to the GPU BUSY perf counter */
2637 adreno_regwrite(device, A3XX_RBBM_GPU_BUSY_MASKED, 0xFFFFFFFF);
2638
Jordan Crousea1d43ff2012-04-09 09:37:50 -06002639 /* Tune the hystersis counters for SP and CP idle detection */
2640 adreno_regwrite(device, A3XX_RBBM_SP_HYST_CNT, 0x10);
2641 adreno_regwrite(device, A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
2642
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002643 /* Enable the RBBM error reporting bits. This lets us get
2644 useful information on failure */
2645
2646 adreno_regwrite(device, A3XX_RBBM_AHB_CTL0, 0x00000001);
2647
2648 /* Enable AHB error reporting */
Wei Zou8e6dfcc2012-03-16 14:53:39 -06002649 adreno_regwrite(device, A3XX_RBBM_AHB_CTL1, 0xA6FFFFFF);
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002650
2651 /* Turn on the power counters */
Tarun Karra4b6bd982012-04-23 17:55:36 -07002652 adreno_regwrite(device, A3XX_RBBM_RBBM_CTL, 0x00030000);
Jordan Crouseb6ebffe2012-02-04 10:23:53 -07002653
2654 /* Turn on hang detection - this spews a lot of useful information
2655 * into the RBBM registers on a hang */
2656
2657 adreno_regwrite(device, A3XX_RBBM_INTERFACE_HANG_INT_CTL,
2658 (1 << 16) | 0xFFF);
2659
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002660}
2661
Jordan Crouse0c2761a2012-02-01 22:11:12 -07002662/* Defined in adreno_a3xx_snapshot.c */
2663void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
2664 int *remain, int hang);
2665
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002666struct adreno_gpudev adreno_a3xx_gpudev = {
2667 .reg_rbbm_status = A3XX_RBBM_STATUS,
2668 .reg_cp_pfp_ucode_addr = A3XX_CP_PFP_UCODE_ADDR,
2669 .reg_cp_pfp_ucode_data = A3XX_CP_PFP_UCODE_DATA,
2670
2671 .ctxt_create = a3xx_drawctxt_create,
2672 .ctxt_save = a3xx_drawctxt_save,
2673 .ctxt_restore = a3xx_drawctxt_restore,
2674 .rb_init = a3xx_rb_init,
2675 .irq_control = a3xx_irq_control,
2676 .irq_handler = a3xx_irq_handler,
2677 .busy_cycles = a3xx_busy_cycles,
2678 .start = a3xx_start,
Jordan Crouse0c2761a2012-02-01 22:11:12 -07002679 .snapshot = a3xx_snapshot,
Jordan Crouseb4d31bd2012-02-01 22:11:12 -07002680};