radeon_commonfuncs.c revision b7e1c893
1/*
2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
3 *                VA Linux Systems Inc., Fremont, California.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "ati_pciids_gen.h"
34
35#if defined(ACCEL_MMIO) && defined(ACCEL_CP)
36#error Cannot define both MMIO and CP acceleration!
37#endif
38
39#if !defined(UNIXCPP) || defined(ANSICPP)
40#define FUNC_NAME_CAT(prefix,suffix) prefix##suffix
41#else
42#define FUNC_NAME_CAT(prefix,suffix) prefix/**/suffix
43#endif
44
45#ifdef ACCEL_MMIO
46#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,MMIO)
47#else
48#ifdef ACCEL_CP
49#define FUNC_NAME(prefix) FUNC_NAME_CAT(prefix,CP)
50#else
51#error No accel type defined!
52#endif
53#endif
54
55static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
56{
57    RADEONInfoPtr  info       = RADEONPTR(pScrn);
58    uint32_t gb_tile_config, su_reg_dest, vap_cntl;
59    ACCEL_PREAMBLE();
60
61    info->accel_state->texW[0] = info->accel_state->texH[0] =
62	info->accel_state->texW[1] = info->accel_state->texH[1] = 1;
63
64    if (IS_R300_3D || IS_R500_3D) {
65
66	BEGIN_ACCEL(3);
67	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
68	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
69	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
70	FINISH_ACCEL();
71
72	gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
73
74	switch(info->accel_state->num_gb_pipes) {
75	case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
76	case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
77	case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
78	default:
79	case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
80	}
81
82	BEGIN_ACCEL(5);
83	OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config);
84	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
85	OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
86	OUT_ACCEL_REG(R300_GB_SELECT, 0);
87	OUT_ACCEL_REG(R300_GB_ENABLE, 0);
88	FINISH_ACCEL();
89
90	if (IS_R500_3D) {
91	    su_reg_dest = ((1 << info->accel_state->num_gb_pipes) - 1);
92	    BEGIN_ACCEL(2);
93	    OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
94	    OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
95	    FINISH_ACCEL();
96	}
97
98	BEGIN_ACCEL(3);
99	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
100	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
101	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
102	FINISH_ACCEL();
103
104	BEGIN_ACCEL(5);
105	OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0);
106	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
107	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
108	OUT_ACCEL_REG(R300_GB_MSPOS0, ((8 << R300_MS_X0_SHIFT) |
109				       (8 << R300_MS_Y0_SHIFT) |
110				       (8 << R300_MS_X1_SHIFT) |
111				       (8 << R300_MS_Y1_SHIFT) |
112				       (8 << R300_MS_X2_SHIFT) |
113				       (8 << R300_MS_Y2_SHIFT) |
114				       (8 << R300_MSBD0_Y_SHIFT) |
115				       (7 << R300_MSBD0_X_SHIFT)));
116	OUT_ACCEL_REG(R300_GB_MSPOS1, ((8 << R300_MS_X3_SHIFT) |
117				       (8 << R300_MS_Y3_SHIFT) |
118				       (8 << R300_MS_X4_SHIFT) |
119				       (8 << R300_MS_Y4_SHIFT) |
120				       (8 << R300_MS_X5_SHIFT) |
121				       (8 << R300_MS_Y5_SHIFT) |
122				       (8 << R300_MSBD1_SHIFT)));
123	FINISH_ACCEL();
124
125	BEGIN_ACCEL(5);
126	OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL);
127	OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE);
128	OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST |
129					   R300_COLOR_ROUND_NEAREST));
130	OUT_ACCEL_REG(R300_GA_COLOR_CONTROL, (R300_RGB0_SHADING_GOURAUD |
131					      R300_ALPHA0_SHADING_GOURAUD |
132					      R300_RGB1_SHADING_GOURAUD |
133					      R300_ALPHA1_SHADING_GOURAUD |
134					      R300_RGB2_SHADING_GOURAUD |
135					      R300_ALPHA2_SHADING_GOURAUD |
136					      R300_RGB3_SHADING_GOURAUD |
137					      R300_ALPHA3_SHADING_GOURAUD));
138	OUT_ACCEL_REG(R300_GA_OFFSET, 0);
139	FINISH_ACCEL();
140
141	BEGIN_ACCEL(5);
142	OUT_ACCEL_REG(R300_SU_TEX_WRAP, 0);
143	OUT_ACCEL_REG(R300_SU_POLY_OFFSET_ENABLE, 0);
144	OUT_ACCEL_REG(R300_SU_CULL_MODE, R300_FACE_NEG);
145	OUT_ACCEL_REG(R300_SU_DEPTH_SCALE, 0x4b7fffff);
146	OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
147	FINISH_ACCEL();
148
149	/* setup the VAP */
150	if (info->accel_state->has_tcl)
151	    vap_cntl = ((5 << R300_PVS_NUM_SLOTS_SHIFT) |
152			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
153			(9 << R300_VF_MAX_VTX_NUM_SHIFT));
154	else
155	    vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
156			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
157			(5 << R300_VF_MAX_VTX_NUM_SHIFT));
158
159	if (info->ChipFamily == CHIP_FAMILY_RV515)
160	    vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
161	else if ((info->ChipFamily == CHIP_FAMILY_RV530) ||
162		 (info->ChipFamily == CHIP_FAMILY_RV560) ||
163		 (info->ChipFamily == CHIP_FAMILY_RV570))
164	    vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
165	else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
166		 (info->ChipFamily == CHIP_FAMILY_R420))
167	    vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
168	else if ((info->ChipFamily == CHIP_FAMILY_R520) ||
169		 (info->ChipFamily == CHIP_FAMILY_R580))
170	    vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
171	else
172	    vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
173
174	if (info->accel_state->has_tcl)
175	    BEGIN_ACCEL(15);
176	else
177	    BEGIN_ACCEL(9);
178	OUT_ACCEL_REG(R300_VAP_VTX_STATE_CNTL, 0);
179	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
180
181	if (info->accel_state->has_tcl)
182	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
183	else
184	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
185	OUT_ACCEL_REG(R300_VAP_CNTL, vap_cntl);
186	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
187	OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
188	OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
189
190	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
191		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
192		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
193		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
194		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
195		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
196			<< R300_WRITE_ENA_0_SHIFT) |
197		       (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
198		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
199		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
200		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
201		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
202			<< R300_WRITE_ENA_1_SHIFT)));
203	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
204		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
205		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
206		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
207		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_2_SHIFT) |
208		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
209			<< R300_WRITE_ENA_2_SHIFT)));
210
211	if (info->accel_state->has_tcl) {
212	    OUT_ACCEL_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0);
213	    OUT_ACCEL_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
214	    OUT_ACCEL_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
215	    OUT_ACCEL_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
216	    OUT_ACCEL_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
217	    OUT_ACCEL_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
218	}
219	FINISH_ACCEL();
220
221	/* pre-load the vertex shaders */
222	if (info->accel_state->has_tcl) {
223	    /* exa mask/Xv bicubic shader program */
224	    BEGIN_ACCEL(13);
225	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
226	    /* PVS inst 0 */
227	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
228			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
229			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
230			   R300_PVS_DST_OFFSET(0) |
231			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
232			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
233	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
234			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
235			   R300_PVS_SRC_OFFSET(0) |
236			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
237			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
238			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
239			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
240	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
241			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
242			   R300_PVS_SRC_OFFSET(0) |
243			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
244			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
245			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
246			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
247	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
248			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
249			   R300_PVS_SRC_OFFSET(0) |
250			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
251			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
252			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
253			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
254
255	    /* PVS inst 1 */
256	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
257			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
258			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
259			   R300_PVS_DST_OFFSET(1) |
260			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
261			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
262	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
263			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
264			   R300_PVS_SRC_OFFSET(6) |
265			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
266			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
267			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
268			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
269	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
270			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
271			   R300_PVS_SRC_OFFSET(6) |
272			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
273			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
274			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
275			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
276	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
277			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
278			   R300_PVS_SRC_OFFSET(6) |
279			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
280			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
281			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
282			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
283
284	    /* PVS inst 2 */
285	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
286			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
287			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
288			   R300_PVS_DST_OFFSET(2) |
289			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
290			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
291	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
292			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
293			   R300_PVS_SRC_OFFSET(7) |
294			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
295			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
296			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
297			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
298	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
299			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
300			   R300_PVS_SRC_OFFSET(7) |
301			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
302			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
303			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
304			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
305	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
306			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
307			   R300_PVS_SRC_OFFSET(7) |
308			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
309			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
310			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
311			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
312	    FINISH_ACCEL();
313
314	    BEGIN_ACCEL(9);
315	    /* exa no mask instruction */
316	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 3);
317	    /* PVS inst 0 */
318	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
319			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
320			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
321			   R300_PVS_DST_OFFSET(0) |
322			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
323			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
324	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
325			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
326			   R300_PVS_SRC_OFFSET(0) |
327			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
328			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
329			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
330			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
331	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
332			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
333			   R300_PVS_SRC_OFFSET(0) |
334			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
335			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
336			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
337			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
338	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
339			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
340			   R300_PVS_SRC_OFFSET(0) |
341			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
342			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
343			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
344			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
345
346	    /* PVS inst 1 */
347	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
348			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
349			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
350			   R300_PVS_DST_OFFSET(1) |
351			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
352			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
353	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
354			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
355			   R300_PVS_SRC_OFFSET(6) |
356			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
357			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
358			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
359			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
360	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
361			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
362			   R300_PVS_SRC_OFFSET(6) |
363			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
364			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
365			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
366			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
367	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
368			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
369			   R300_PVS_SRC_OFFSET(6) |
370			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
371			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
372			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
373			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
374	    FINISH_ACCEL();
375
376	    /* Xv shader program */
377	    BEGIN_ACCEL(9);
378	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 5);
379
380	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
381			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
382			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
383			   R300_PVS_DST_OFFSET(0) |
384			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
385			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
386	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
387			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
388			   R300_PVS_SRC_OFFSET(0) |
389			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
390			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
391			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
392			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
393	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
394			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
395			   R300_PVS_SRC_OFFSET(0) |
396			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
397			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
398			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
399			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
400	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
401			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
402			   R300_PVS_SRC_OFFSET(0) |
403			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
404			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
405			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
406			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
407
408	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
409			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
410			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
411			   R300_PVS_DST_OFFSET(1) |
412			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
413			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
414	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
415			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
416			   R300_PVS_SRC_OFFSET(6) |
417			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
418			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
419			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
420			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
421	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
422			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
423			   R300_PVS_SRC_OFFSET(6) |
424			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
425			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
426			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
427			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
428	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
429			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
430			   R300_PVS_SRC_OFFSET(6) |
431			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
432			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
433			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
434			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
435	    FINISH_ACCEL();
436	}
437
438	/* pre-load the RS instructions */
439	BEGIN_ACCEL(4);
440	if (IS_R300_3D) {
441	    /* rasterizer source table
442	     * R300_RS_TEX_PTR is the offset into the input RS stream
443	     * 0,1 are tex0
444	     * 2,3 are tex1
445	     */
446	    OUT_ACCEL_REG(R300_RS_IP_0,
447			  (R300_RS_TEX_PTR(0) |
448			   R300_RS_SEL_S(R300_RS_SEL_C0) |
449			   R300_RS_SEL_T(R300_RS_SEL_C1) |
450			   R300_RS_SEL_R(R300_RS_SEL_K0) |
451			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
452	    OUT_ACCEL_REG(R300_RS_IP_1,
453			  (R300_RS_TEX_PTR(2) |
454			   R300_RS_SEL_S(R300_RS_SEL_C0) |
455			   R300_RS_SEL_T(R300_RS_SEL_C1) |
456			   R300_RS_SEL_R(R300_RS_SEL_K0) |
457			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
458	    /* src tex */
459	    /* R300_INST_TEX_ID - select the RS source table entry
460	     * R300_INST_TEX_ADDR - the FS temp register for the texture data
461	     */
462	    OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
463					   R300_RS_INST_TEX_CN_WRITE |
464					   R300_INST_TEX_ADDR(0)));
465	    /* mask tex */
466	    OUT_ACCEL_REG(R300_RS_INST_1, (R300_INST_TEX_ID(1) |
467					   R300_RS_INST_TEX_CN_WRITE |
468					   R300_INST_TEX_ADDR(1)));
469
470	} else {
471	    /* rasterizer source table
472	     * R300_RS_TEX_PTR is the offset into the input RS stream
473	     * 0,1 are tex0
474	     * 2,3 are tex1
475	     */
476	    OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
477					 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
478					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
479					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
480
481	    OUT_ACCEL_REG(R500_RS_IP_1, ((2 << R500_RS_IP_TEX_PTR_S_SHIFT) |
482					 (3 << R500_RS_IP_TEX_PTR_T_SHIFT) |
483					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
484					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
485	    /* src tex */
486	    /* R500_RS_INST_TEX_ID_SHIFT - select the RS source table entry
487	     * R500_RS_INST_TEX_ADDR_SHIFT - the FS temp register for the texture data
488	     */
489	    OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
490					   R500_RS_INST_TEX_CN_WRITE |
491					   (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
492	    /* mask tex */
493	    OUT_ACCEL_REG(R500_RS_INST_1, ((1 << R500_RS_INST_TEX_ID_SHIFT) |
494					   R500_RS_INST_TEX_CN_WRITE |
495					   (1 << R500_RS_INST_TEX_ADDR_SHIFT)));
496	}
497	FINISH_ACCEL();
498
499	if (IS_R300_3D)
500	    BEGIN_ACCEL(4);
501	else {
502	    BEGIN_ACCEL(6);
503	    OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
504	    OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
505	}
506	OUT_ACCEL_REG(R300_US_W_FMT, 0);
507	OUT_ACCEL_REG(R300_US_OUT_FMT_1, (R300_OUT_FMT_UNUSED |
508					  R300_OUT_FMT_C0_SEL_BLUE |
509					  R300_OUT_FMT_C1_SEL_GREEN |
510					  R300_OUT_FMT_C2_SEL_RED |
511					  R300_OUT_FMT_C3_SEL_ALPHA));
512	OUT_ACCEL_REG(R300_US_OUT_FMT_2, (R300_OUT_FMT_UNUSED |
513					  R300_OUT_FMT_C0_SEL_BLUE |
514					  R300_OUT_FMT_C1_SEL_GREEN |
515					  R300_OUT_FMT_C2_SEL_RED |
516					  R300_OUT_FMT_C3_SEL_ALPHA));
517	OUT_ACCEL_REG(R300_US_OUT_FMT_3, (R300_OUT_FMT_UNUSED |
518					  R300_OUT_FMT_C0_SEL_BLUE |
519					  R300_OUT_FMT_C1_SEL_GREEN |
520					  R300_OUT_FMT_C2_SEL_RED |
521					  R300_OUT_FMT_C3_SEL_ALPHA));
522	FINISH_ACCEL();
523
524
525	BEGIN_ACCEL(3);
526	OUT_ACCEL_REG(R300_FG_DEPTH_SRC, 0);
527	OUT_ACCEL_REG(R300_FG_FOG_BLEND, 0);
528	OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0);
529	FINISH_ACCEL();
530
531	BEGIN_ACCEL(13);
532	OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
533	OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0);
534	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
535	OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0);
536	OUT_ACCEL_REG(R300_RB3D_ZCNTL, 0);
537	OUT_ACCEL_REG(R300_RB3D_ZTOP, 0);
538	OUT_ACCEL_REG(R300_RB3D_ROPCNTL, 0);
539
540	OUT_ACCEL_REG(R300_RB3D_AARESOLVE_CTL, 0);
541	OUT_ACCEL_REG(R300_RB3D_COLOR_CHANNEL_MASK, (R300_BLUE_MASK_EN |
542						     R300_GREEN_MASK_EN |
543						     R300_RED_MASK_EN |
544						     R300_ALPHA_MASK_EN));
545	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
546	OUT_ACCEL_REG(R300_RB3D_CCTL, 0);
547	OUT_ACCEL_REG(R300_RB3D_DITHER_CTL, 0);
548	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
549	FINISH_ACCEL();
550
551	BEGIN_ACCEL(5);
552	OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5);
553	if (IS_R300_3D) {
554	    /* clip has offset 1440 */
555	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
556					     (1088 << R300_CLIP_Y_SHIFT)));
557	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2920) << R300_CLIP_X_SHIFT) |
558					     ((1080 + 2920) << R300_CLIP_Y_SHIFT)));
559	} else {
560	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((0 << R300_CLIP_X_SHIFT) |
561					     (0 << R300_CLIP_Y_SHIFT)));
562	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, ((4080 << R300_CLIP_X_SHIFT) |
563					     (4080 << R300_CLIP_Y_SHIFT)));
564	}
565	OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
566	OUT_ACCEL_REG(R300_SC_SCREENDOOR, 0xffffff);
567	FINISH_ACCEL();
568    } else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
569	       (info->ChipFamily == CHIP_FAMILY_RV280) ||
570	       (info->ChipFamily == CHIP_FAMILY_RS300) ||
571	       (info->ChipFamily == CHIP_FAMILY_R200)) {
572
573	BEGIN_ACCEL(6);
574	if (info->ChipFamily == CHIP_FAMILY_RS300) {
575	    OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
576	} else {
577	    OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0);
578	}
579	OUT_ACCEL_REG(R200_PP_CNTL_X, 0);
580	OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0);
581	OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0);
582	OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0);
583	OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE |
584	    R200_VAP_VF_MAX_VTX_NUM);
585	FINISH_ACCEL();
586
587	BEGIN_ACCEL(5);
588	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
589	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
590	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
591	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
592	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
593				       RADEON_BFACE_SOLID |
594				       RADEON_FFACE_SOLID |
595				       RADEON_VTX_PIX_CENTER_OGL |
596				       RADEON_ROUND_MODE_ROUND |
597				       RADEON_ROUND_PREC_4TH_PIX));
598	FINISH_ACCEL();
599    } else {
600	BEGIN_ACCEL(2);
601	if ((info->ChipFamily == CHIP_FAMILY_RADEON) ||
602	    (info->ChipFamily == CHIP_FAMILY_RV200))
603	    OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0);
604	else
605	    OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
606	OUT_ACCEL_REG(RADEON_SE_COORD_FMT,
607	    RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
608	    RADEON_VTX_ST0_NONPARAMETRIC |
609	    RADEON_VTX_ST1_NONPARAMETRIC |
610	    RADEON_TEX1_W_ROUTING_USE_W0);
611	FINISH_ACCEL();
612
613	BEGIN_ACCEL(5);
614	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
615	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
616	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
617	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
618	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
619				       RADEON_BFACE_SOLID |
620				       RADEON_FFACE_SOLID |
621				       RADEON_VTX_PIX_CENTER_OGL |
622				       RADEON_ROUND_MODE_ROUND |
623				       RADEON_ROUND_PREC_4TH_PIX));
624	FINISH_ACCEL();
625    }
626
627}
628
629/* inserts a wait for vline in the command stream */
630void FUNC_NAME(RADEONWaitForVLine)(ScrnInfoPtr pScrn, PixmapPtr pPix,
631	int crtc, int start, int stop)
632{
633    RADEONInfoPtr  info = RADEONPTR(pScrn);
634    xf86CrtcConfigPtr  xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
635    uint32_t offset;
636    ACCEL_PREAMBLE();
637
638    if ((crtc < 0) || (crtc > 1))
639	return;
640
641    if (stop < start)
642	return;
643
644    if (!xf86_config->crtc[crtc]->enabled)
645	return;
646
647#ifdef USE_EXA
648    if (info->useEXA)
649	offset = exaGetPixmapOffset(pPix);
650    else
651#endif
652	offset = pPix->devPrivate.ptr - info->FB;
653
654    /* if drawing to front buffer */
655    if (offset != 0)
656	return;
657
658    start = max(start, 0);
659    stop = min(stop, xf86_config->crtc[crtc]->mode.VDisplay);
660
661    if (start > xf86_config->crtc[crtc]->mode.VDisplay)
662	return;
663
664    BEGIN_ACCEL(2);
665
666    if (IS_AVIVO_VARIANT) {
667	RADEONCrtcPrivatePtr radeon_crtc = xf86_config->crtc[crtc]->driver_private;
668
669	OUT_ACCEL_REG(AVIVO_D1MODE_VLINE_START_END + radeon_crtc->crtc_offset,
670		      ((start << AVIVO_D1MODE_VLINE_START_SHIFT) |
671		       (stop << AVIVO_D1MODE_VLINE_END_SHIFT) |
672		       AVIVO_D1MODE_VLINE_INV));
673    } else {
674	if (crtc == 0)
675	    OUT_ACCEL_REG(RADEON_CRTC_GUI_TRIG_VLINE,
676			  ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) |
677			   (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) |
678			   RADEON_CRTC_GUI_TRIG_VLINE_INV));
679	else
680	    OUT_ACCEL_REG(RADEON_CRTC2_GUI_TRIG_VLINE,
681			  ((start << RADEON_CRTC_GUI_TRIG_VLINE_START_SHIFT) |
682			   (stop << RADEON_CRTC_GUI_TRIG_VLINE_END_SHIFT) |
683			   RADEON_CRTC_GUI_TRIG_VLINE_INV));
684    }
685
686    if (crtc == 0)
687	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE |
688					  RADEON_ENG_DISPLAY_SELECT_CRTC0));
689    else
690	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, (RADEON_WAIT_CRTC_VLINE |
691					  RADEON_ENG_DISPLAY_SELECT_CRTC1));
692
693    FINISH_ACCEL();
694}
695
696/* MMIO:
697 *
698 * Wait for the graphics engine to be completely idle: the FIFO has
699 * drained, the Pixel Cache is flushed, and the engine is idle.  This is
700 * a standard "sync" function that will make the hardware "quiescent".
701 *
702 * CP:
703 *
704 * Wait until the CP is completely idle: the FIFO has drained and the CP
705 * is idle.
706 */
707void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
708{
709    RADEONInfoPtr  info = RADEONPTR(pScrn);
710    unsigned char *RADEONMMIO = info->MMIO;
711    int            i    = 0;
712
713#ifdef ACCEL_CP
714    /* Make sure the CP is idle first */
715    if (info->cp->CPStarted) {
716	int  ret;
717
718	FLUSH_RING();
719
720	for (;;) {
721	    do {
722		ret = drmCommandNone(info->dri->drmFD, DRM_RADEON_CP_IDLE);
723		if (ret && ret != -EBUSY) {
724		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
725			       "%s: CP idle %d\n", __FUNCTION__, ret);
726		}
727	    } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));
728
729	    if (ret == 0) return;
730
731	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
732		       "Idle timed out, resetting engine...\n");
733	    if (info->ChipFamily < CHIP_FAMILY_R600) {
734		RADEONEngineReset(pScrn);
735		RADEONEngineRestore(pScrn);
736	    } else
737		R600EngineReset(pScrn);
738
739	    /* Always restart the engine when doing CP 2D acceleration */
740	    RADEONCP_RESET(pScrn, info);
741	    RADEONCP_START(pScrn, info);
742	}
743    }
744#endif
745
746    if (info->ChipFamily >= CHIP_FAMILY_R600) {
747	if (!info->accelOn)
748	    return;
749
750	/* Wait for the engine to go idle */
751	if (info->ChipFamily >= CHIP_FAMILY_RV770)
752	    R600WaitForFifoFunction(pScrn, 8);
753	else
754	    R600WaitForFifoFunction(pScrn, 16);
755
756	for (;;) {
757	    for (i = 0; i < RADEON_TIMEOUT; i++) {
758		if (!(INREG(R600_GRBM_STATUS) & R600_GUI_ACTIVE))
759		    return;
760	    }
761	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
762			   "Idle timed out: stat=0x%08x\n",
763			   (unsigned int)INREG(R600_GRBM_STATUS));
764	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
765		       "Idle timed out, resetting engine...\n");
766	    R600EngineReset(pScrn);
767#ifdef XF86DRI
768	    if (info->directRenderingEnabled) {
769		RADEONCP_RESET(pScrn, info);
770		RADEONCP_START(pScrn, info);
771	    }
772#endif
773	}
774    } else {
775	/* Wait for the engine to go idle */
776	RADEONWaitForFifoFunction(pScrn, 64);
777
778	for (;;) {
779	    for (i = 0; i < RADEON_TIMEOUT; i++) {
780		if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
781		    RADEONEngineFlush(pScrn);
782		    return;
783		}
784	    }
785	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
786			   "Idle timed out: %u entries, stat=0x%08x\n",
787			   (unsigned int)INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
788			   (unsigned int)INREG(RADEON_RBBM_STATUS));
789	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
790		       "Idle timed out, resetting engine...\n");
791	    RADEONEngineReset(pScrn);
792	    RADEONEngineRestore(pScrn);
793#ifdef XF86DRI
794	    if (info->directRenderingEnabled) {
795		RADEONCP_RESET(pScrn, info);
796		RADEONCP_START(pScrn, info);
797	    }
798#endif
799	}
800    }
801}
802