radeon_commonfuncs.c revision 209ff23f
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->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
62
63    if (IS_R300_3D || IS_R500_3D) {
64
65	BEGIN_ACCEL(3);
66	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
67	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
68	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
69	FINISH_ACCEL();
70
71	gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
72
73	switch(info->num_gb_pipes) {
74	case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
75	case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
76	case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
77	default:
78	case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
79	}
80
81	BEGIN_ACCEL(5);
82	OUT_ACCEL_REG(R300_GB_TILE_CONFIG, gb_tile_config);
83	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
84	OUT_ACCEL_REG(R300_DST_PIPE_CONFIG, R300_PIPE_AUTO_CONFIG);
85	OUT_ACCEL_REG(R300_GB_SELECT, 0);
86	OUT_ACCEL_REG(R300_GB_ENABLE, 0);
87	FINISH_ACCEL();
88
89	if (IS_R500_3D) {
90	    su_reg_dest = ((1 << info->num_gb_pipes) - 1);
91	    BEGIN_ACCEL(2);
92	    OUT_ACCEL_REG(R500_SU_REG_DEST, su_reg_dest);
93	    OUT_ACCEL_REG(R500_VAP_INDEX_OFFSET, 0);
94	    FINISH_ACCEL();
95	}
96
97	BEGIN_ACCEL(3);
98	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
99	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
100	OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
101	FINISH_ACCEL();
102
103	BEGIN_ACCEL(5);
104	OUT_ACCEL_REG(R300_GB_AA_CONFIG, 0);
105	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
106	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
107	OUT_ACCEL_REG(R300_GB_MSPOS0, ((8 << R300_MS_X0_SHIFT) |
108				       (8 << R300_MS_Y0_SHIFT) |
109				       (8 << R300_MS_X1_SHIFT) |
110				       (8 << R300_MS_Y1_SHIFT) |
111				       (8 << R300_MS_X2_SHIFT) |
112				       (8 << R300_MS_Y2_SHIFT) |
113				       (8 << R300_MSBD0_Y_SHIFT) |
114				       (7 << R300_MSBD0_X_SHIFT)));
115	OUT_ACCEL_REG(R300_GB_MSPOS1, ((8 << R300_MS_X3_SHIFT) |
116				       (8 << R300_MS_Y3_SHIFT) |
117				       (8 << R300_MS_X4_SHIFT) |
118				       (8 << R300_MS_Y4_SHIFT) |
119				       (8 << R300_MS_X5_SHIFT) |
120				       (8 << R300_MS_Y5_SHIFT) |
121				       (8 << R300_MSBD1_SHIFT)));
122	FINISH_ACCEL();
123
124	BEGIN_ACCEL(5);
125	OUT_ACCEL_REG(R300_GA_ENHANCE, R300_GA_DEADLOCK_CNTL | R300_GA_FASTSYNC_CNTL);
126	OUT_ACCEL_REG(R300_GA_POLY_MODE, R300_FRONT_PTYPE_TRIANGE | R300_BACK_PTYPE_TRIANGE);
127	OUT_ACCEL_REG(R300_GA_ROUND_MODE, (R300_GEOMETRY_ROUND_NEAREST |
128					   R300_COLOR_ROUND_NEAREST));
129	OUT_ACCEL_REG(R300_GA_COLOR_CONTROL, (R300_RGB0_SHADING_GOURAUD |
130					      R300_ALPHA0_SHADING_GOURAUD |
131					      R300_RGB1_SHADING_GOURAUD |
132					      R300_ALPHA1_SHADING_GOURAUD |
133					      R300_RGB2_SHADING_GOURAUD |
134					      R300_ALPHA2_SHADING_GOURAUD |
135					      R300_RGB3_SHADING_GOURAUD |
136					      R300_ALPHA3_SHADING_GOURAUD));
137	OUT_ACCEL_REG(R300_GA_OFFSET, 0);
138	FINISH_ACCEL();
139
140	BEGIN_ACCEL(5);
141	OUT_ACCEL_REG(R300_SU_TEX_WRAP, 0);
142	OUT_ACCEL_REG(R300_SU_POLY_OFFSET_ENABLE, 0);
143	OUT_ACCEL_REG(R300_SU_CULL_MODE, R300_FACE_NEG);
144	OUT_ACCEL_REG(R300_SU_DEPTH_SCALE, 0x4b7fffff);
145	OUT_ACCEL_REG(R300_SU_DEPTH_OFFSET, 0);
146	FINISH_ACCEL();
147
148	/* setup the VAP */
149	if (info->has_tcl)
150	    vap_cntl = ((5 << R300_PVS_NUM_SLOTS_SHIFT) |
151			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
152			(9 << R300_VF_MAX_VTX_NUM_SHIFT));
153	else
154	    vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) |
155			(5 << R300_PVS_NUM_CNTLRS_SHIFT) |
156			(5 << R300_VF_MAX_VTX_NUM_SHIFT));
157
158	if (info->ChipFamily == CHIP_FAMILY_RV515)
159	    vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT);
160	else if ((info->ChipFamily == CHIP_FAMILY_RV530) ||
161		 (info->ChipFamily == CHIP_FAMILY_RV560))
162	    vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT);
163	else if (info->ChipFamily == CHIP_FAMILY_R420)
164	    vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT);
165	else if ((info->ChipFamily == CHIP_FAMILY_R520) ||
166		 (info->ChipFamily == CHIP_FAMILY_R580) ||
167		 (info->ChipFamily == CHIP_FAMILY_RV570))
168	    vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT);
169	else
170	    vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT);
171
172	if (info->has_tcl)
173	    BEGIN_ACCEL(15);
174	else
175	    BEGIN_ACCEL(9);
176	OUT_ACCEL_REG(R300_VAP_VTX_STATE_CNTL, 0);
177	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
178
179	if (info->has_tcl)
180	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, 0);
181	else
182	    OUT_ACCEL_REG(R300_VAP_CNTL_STATUS, R300_PVS_BYPASS);
183	OUT_ACCEL_REG(R300_VAP_CNTL, vap_cntl);
184	OUT_ACCEL_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
185	OUT_ACCEL_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
186	OUT_ACCEL_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0);
187
188	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0,
189		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_0_SHIFT) |
190		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_0_SHIFT) |
191		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_0_SHIFT) |
192		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_0_SHIFT) |
193		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
194			<< R300_WRITE_ENA_0_SHIFT) |
195		       (R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_1_SHIFT) |
196		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_1_SHIFT) |
197		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_1_SHIFT) |
198		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_1_SHIFT) |
199		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
200			<< R300_WRITE_ENA_1_SHIFT)));
201	OUT_ACCEL_REG(R300_VAP_PROG_STREAM_CNTL_EXT_1,
202		      ((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_2_SHIFT) |
203		       (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_2_SHIFT) |
204		       (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_2_SHIFT) |
205		       (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_2_SHIFT) |
206		       ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W)
207			<< R300_WRITE_ENA_2_SHIFT)));
208
209	if (info->has_tcl) {
210	    OUT_ACCEL_REG(R300_VAP_PVS_FLOW_CNTL_OPC, 0);
211	    OUT_ACCEL_REG(R300_VAP_GB_VERT_CLIP_ADJ, 0x3f800000);
212	    OUT_ACCEL_REG(R300_VAP_GB_VERT_DISC_ADJ, 0x3f800000);
213	    OUT_ACCEL_REG(R300_VAP_GB_HORZ_CLIP_ADJ, 0x3f800000);
214	    OUT_ACCEL_REG(R300_VAP_GB_HORZ_DISC_ADJ, 0x3f800000);
215	    OUT_ACCEL_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
216	}
217	FINISH_ACCEL();
218
219	/* pre-load the vertex shaders */
220	if (info->has_tcl) {
221	    /* exa mask shader program */
222	    BEGIN_ACCEL(13);
223	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
224	    /* PVS inst 0 */
225	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
226			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
227			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
228			   R300_PVS_DST_OFFSET(0) |
229			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
230			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
231	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
232			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
233			   R300_PVS_SRC_OFFSET(0) |
234			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
235			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
236			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
237			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
238	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
239			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
240			   R300_PVS_SRC_OFFSET(0) |
241			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
242			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
243			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
244			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
245	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
246			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
247			   R300_PVS_SRC_OFFSET(0) |
248			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
249			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
250			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
251			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
252
253	    /* PVS inst 1 */
254	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
255			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
256			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
257			   R300_PVS_DST_OFFSET(1) |
258			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
259			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
260	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
261			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
262			   R300_PVS_SRC_OFFSET(6) |
263			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
264			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
265			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
266			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
267	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
268			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
269			   R300_PVS_SRC_OFFSET(6) |
270			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
271			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
272			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
273			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
274	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
275			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
276			   R300_PVS_SRC_OFFSET(6) |
277			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
278			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
279			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
280			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
281
282	    /* PVS inst 2 */
283	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
284			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
285			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
286			   R300_PVS_DST_OFFSET(2) |
287			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
288			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
289	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
290			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
291			   R300_PVS_SRC_OFFSET(7) |
292			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
293			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
294			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
295			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
296	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
297			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
298			   R300_PVS_SRC_OFFSET(7) |
299			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
300			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
301			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
302			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
303	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
304			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
305			   R300_PVS_SRC_OFFSET(7) |
306			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
307			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
308			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
309			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
310	    FINISH_ACCEL();
311
312	    BEGIN_ACCEL(9);
313	    /* exa no mask instruction */
314	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 3);
315	    /* PVS inst 0 */
316	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
317			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
318			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
319			   R300_PVS_DST_OFFSET(0) |
320			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
321			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
322	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
323			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
324			   R300_PVS_SRC_OFFSET(0) |
325			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
326			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
327			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
328			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
329	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
330			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
331			   R300_PVS_SRC_OFFSET(0) |
332			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
333			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
334			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
335			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
336	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
337			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
338			   R300_PVS_SRC_OFFSET(0) |
339			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
340			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
341			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
342			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
343
344	    /* PVS inst 1 */
345	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
346			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
347			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
348			   R300_PVS_DST_OFFSET(1) |
349			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
350			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
351	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
352			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
353			   R300_PVS_SRC_OFFSET(6) |
354			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
355			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
356			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
357			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
358	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
359			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
360			   R300_PVS_SRC_OFFSET(6) |
361			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
362			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
363			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
364			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
365	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
366			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
367			   R300_PVS_SRC_OFFSET(6) |
368			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
369			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
370			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
371			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
372	    FINISH_ACCEL();
373
374	    /* Xv shader program */
375	    BEGIN_ACCEL(9);
376	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_INDX_REG, 5);
377
378	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
379			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
380			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
381			   R300_PVS_DST_OFFSET(0) |
382			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
383			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
384	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
385			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
386			   R300_PVS_SRC_OFFSET(0) |
387			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
388			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
389			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
390			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
391	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
392			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
393			   R300_PVS_SRC_OFFSET(0) |
394			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
395			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
396			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
397			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
398	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
399			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
400			   R300_PVS_SRC_OFFSET(0) |
401			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
402			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
403			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
404			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
405
406	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
407			  (R300_PVS_DST_OPCODE(R300_VE_ADD) |
408			   R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
409			   R300_PVS_DST_OFFSET(1) |
410			   R300_PVS_DST_WE_X | R300_PVS_DST_WE_Y |
411			   R300_PVS_DST_WE_Z | R300_PVS_DST_WE_W));
412	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
413			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
414			   R300_PVS_SRC_OFFSET(6) |
415			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_X) |
416			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_Y) |
417			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_Z) |
418			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_W)));
419	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
420			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
421			   R300_PVS_SRC_OFFSET(6) |
422			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
423			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
424			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
425			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
426	    OUT_ACCEL_REG(R300_VAP_PVS_VECTOR_DATA_REG,
427			  (R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
428			   R300_PVS_SRC_OFFSET(6) |
429			   R300_PVS_SRC_SWIZZLE_X(R300_PVS_SRC_SELECT_FORCE_0) |
430			   R300_PVS_SRC_SWIZZLE_Y(R300_PVS_SRC_SELECT_FORCE_0) |
431			   R300_PVS_SRC_SWIZZLE_Z(R300_PVS_SRC_SELECT_FORCE_0) |
432			   R300_PVS_SRC_SWIZZLE_W(R300_PVS_SRC_SELECT_FORCE_0)));
433	    FINISH_ACCEL();
434	}
435
436	/* pre-load the RS instructions */
437	BEGIN_ACCEL(4);
438	if (IS_R300_3D) {
439	    /* rasterizer source table
440	     * R300_RS_TEX_PTR is the offset into the input RS stream
441	     * 0,1 are tex0
442	     * 2,3 are tex1
443	     */
444	    OUT_ACCEL_REG(R300_RS_IP_0,
445			  (R300_RS_TEX_PTR(0) |
446			   R300_RS_SEL_S(R300_RS_SEL_C0) |
447			   R300_RS_SEL_T(R300_RS_SEL_C1) |
448			   R300_RS_SEL_R(R300_RS_SEL_K0) |
449			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
450	    OUT_ACCEL_REG(R300_RS_IP_1,
451			  (R300_RS_TEX_PTR(2) |
452			   R300_RS_SEL_S(R300_RS_SEL_C0) |
453			   R300_RS_SEL_T(R300_RS_SEL_C1) |
454			   R300_RS_SEL_R(R300_RS_SEL_K0) |
455			   R300_RS_SEL_Q(R300_RS_SEL_K1)));
456	    /* src tex */
457	    /* R300_INST_TEX_ID - select the RS source table entry
458	     * R300_INST_TEX_ADDR - the FS temp register for the texture data
459	     */
460	    OUT_ACCEL_REG(R300_RS_INST_0, (R300_INST_TEX_ID(0) |
461					   R300_RS_INST_TEX_CN_WRITE |
462					   R300_INST_TEX_ADDR(0)));
463	    /* mask tex */
464	    OUT_ACCEL_REG(R300_RS_INST_1, (R300_INST_TEX_ID(1) |
465					   R300_RS_INST_TEX_CN_WRITE |
466					   R300_INST_TEX_ADDR(1)));
467
468	} else {
469	    /* rasterizer source table
470	     * R300_RS_TEX_PTR is the offset into the input RS stream
471	     * 0,1 are tex0
472	     * 2,3 are tex1
473	     */
474	    OUT_ACCEL_REG(R500_RS_IP_0, ((0 << R500_RS_IP_TEX_PTR_S_SHIFT) |
475					 (1 << R500_RS_IP_TEX_PTR_T_SHIFT) |
476					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
477					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
478
479	    OUT_ACCEL_REG(R500_RS_IP_1, ((2 << R500_RS_IP_TEX_PTR_S_SHIFT) |
480					 (3 << R500_RS_IP_TEX_PTR_T_SHIFT) |
481					 (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) |
482					 (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)));
483	    /* src tex */
484	    /* R500_RS_INST_TEX_ID_SHIFT - select the RS source table entry
485	     * R500_RS_INST_TEX_ADDR_SHIFT - the FS temp register for the texture data
486	     */
487	    OUT_ACCEL_REG(R500_RS_INST_0, ((0 << R500_RS_INST_TEX_ID_SHIFT) |
488					   R500_RS_INST_TEX_CN_WRITE |
489					   (0 << R500_RS_INST_TEX_ADDR_SHIFT)));
490	    /* mask tex */
491	    OUT_ACCEL_REG(R500_RS_INST_1, ((1 << R500_RS_INST_TEX_ID_SHIFT) |
492					   R500_RS_INST_TEX_CN_WRITE |
493					   (1 << R500_RS_INST_TEX_ADDR_SHIFT)));
494	}
495	FINISH_ACCEL();
496
497	/* pre-load FS tex instructions */
498	if (IS_R300_3D) {
499	    BEGIN_ACCEL(2);
500	    /* tex inst for src texture */
501	    OUT_ACCEL_REG(R300_US_TEX_INST_0,
502			  (R300_TEX_SRC_ADDR(0) |
503			   R300_TEX_DST_ADDR(0) |
504			   R300_TEX_ID(0) |
505			   R300_TEX_INST(R300_TEX_INST_LD)));
506
507	    /* tex inst for mask texture */
508	    OUT_ACCEL_REG(R300_US_TEX_INST_1,
509			  (R300_TEX_SRC_ADDR(1) |
510			   R300_TEX_DST_ADDR(1) |
511			   R300_TEX_ID(1) |
512			   R300_TEX_INST(R300_TEX_INST_LD)));
513	    FINISH_ACCEL();
514	}
515
516	if (IS_R300_3D) {
517	    BEGIN_ACCEL(9);
518	    OUT_ACCEL_REG(R300_US_CONFIG, (0 << R300_NLEVEL_SHIFT) | R300_FIRST_TEX);
519	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
520	    OUT_ACCEL_REG(R300_US_CODE_ADDR_0,
521			  (R300_ALU_START(0) |
522			   R300_ALU_SIZE(0) |
523			   R300_TEX_START(0) |
524			   R300_TEX_SIZE(0)));
525	    OUT_ACCEL_REG(R300_US_CODE_ADDR_1,
526			  (R300_ALU_START(0) |
527			   R300_ALU_SIZE(0) |
528			   R300_TEX_START(0) |
529			   R300_TEX_SIZE(0)));
530	    OUT_ACCEL_REG(R300_US_CODE_ADDR_2,
531			  (R300_ALU_START(0) |
532			   R300_ALU_SIZE(0) |
533			   R300_TEX_START(0) |
534			   R300_TEX_SIZE(0)));
535	} else {
536	    BEGIN_ACCEL(7);
537	    OUT_ACCEL_REG(R300_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
538	    OUT_ACCEL_REG(R300_US_PIXSIZE, 1); /* highest temp used */
539	    OUT_ACCEL_REG(R500_US_FC_CTRL, 0);
540	}
541	OUT_ACCEL_REG(R300_US_W_FMT, 0);
542	OUT_ACCEL_REG(R300_US_OUT_FMT_1, (R300_OUT_FMT_UNUSED |
543					  R300_OUT_FMT_C0_SEL_BLUE |
544					  R300_OUT_FMT_C1_SEL_GREEN |
545					  R300_OUT_FMT_C2_SEL_RED |
546					  R300_OUT_FMT_C3_SEL_ALPHA));
547	OUT_ACCEL_REG(R300_US_OUT_FMT_2, (R300_OUT_FMT_UNUSED |
548					  R300_OUT_FMT_C0_SEL_BLUE |
549					  R300_OUT_FMT_C1_SEL_GREEN |
550					  R300_OUT_FMT_C2_SEL_RED |
551					  R300_OUT_FMT_C3_SEL_ALPHA));
552	OUT_ACCEL_REG(R300_US_OUT_FMT_3, (R300_OUT_FMT_UNUSED |
553					  R300_OUT_FMT_C0_SEL_BLUE |
554					  R300_OUT_FMT_C1_SEL_GREEN |
555					  R300_OUT_FMT_C2_SEL_RED |
556					  R300_OUT_FMT_C3_SEL_ALPHA));
557	FINISH_ACCEL();
558
559
560	BEGIN_ACCEL(3);
561	OUT_ACCEL_REG(R300_FG_DEPTH_SRC, 0);
562	OUT_ACCEL_REG(R300_FG_FOG_BLEND, 0);
563	OUT_ACCEL_REG(R300_FG_ALPHA_FUNC, 0);
564	FINISH_ACCEL();
565
566	BEGIN_ACCEL(13);
567	OUT_ACCEL_REG(R300_RB3D_ABLENDCNTL, 0);
568	OUT_ACCEL_REG(R300_RB3D_ZSTENCILCNTL, 0);
569	OUT_ACCEL_REG(R300_RB3D_ZCACHE_CTLSTAT, R300_ZC_FLUSH | R300_ZC_FREE);
570	OUT_ACCEL_REG(R300_RB3D_BW_CNTL, 0);
571	OUT_ACCEL_REG(R300_RB3D_ZCNTL, 0);
572	OUT_ACCEL_REG(R300_RB3D_ZTOP, 0);
573	OUT_ACCEL_REG(R300_RB3D_ROPCNTL, 0);
574
575	OUT_ACCEL_REG(R300_RB3D_AARESOLVE_CTL, 0);
576	OUT_ACCEL_REG(R300_RB3D_COLOR_CHANNEL_MASK, (R300_BLUE_MASK_EN |
577						     R300_GREEN_MASK_EN |
578						     R300_RED_MASK_EN |
579						     R300_ALPHA_MASK_EN));
580	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
581	OUT_ACCEL_REG(R300_RB3D_CCTL, 0);
582	OUT_ACCEL_REG(R300_RB3D_DITHER_CTL, 0);
583	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
584	FINISH_ACCEL();
585
586	BEGIN_ACCEL(7);
587	OUT_ACCEL_REG(R300_SC_EDGERULE, 0xA5294A5);
588	OUT_ACCEL_REG(R300_SC_SCISSOR0, ((0 << R300_SCISSOR_X_SHIFT) |
589					 (0 << R300_SCISSOR_Y_SHIFT)));
590	OUT_ACCEL_REG(R300_SC_SCISSOR1, ((8191 << R300_SCISSOR_X_SHIFT) |
591					 (8191 << R300_SCISSOR_Y_SHIFT)));
592
593	if (IS_R300_3D) {
594	    /* clip has offset 1440 */
595	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
596					     (1088 << R300_CLIP_Y_SHIFT)));
597	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, (((1080 + 2920) << R300_CLIP_X_SHIFT) |
598					     ((1080 + 2920) << R300_CLIP_Y_SHIFT)));
599	} else {
600	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((0 << R300_CLIP_X_SHIFT) |
601					     (0 << R300_CLIP_Y_SHIFT)));
602	    OUT_ACCEL_REG(R300_SC_CLIP_0_B, ((4080 << R300_CLIP_X_SHIFT) |
603					     (4080 << R300_CLIP_Y_SHIFT)));
604	}
605	OUT_ACCEL_REG(R300_SC_CLIP_RULE, 0xAAAA);
606	OUT_ACCEL_REG(R300_SC_SCREENDOOR, 0xffffff);
607	FINISH_ACCEL();
608    } else if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
609	       (info->ChipFamily == CHIP_FAMILY_RV280) ||
610	       (info->ChipFamily == CHIP_FAMILY_RS300) ||
611	       (info->ChipFamily == CHIP_FAMILY_R200)) {
612
613	BEGIN_ACCEL(7);
614	if (info->ChipFamily == CHIP_FAMILY_RS300) {
615	    OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, RADEON_TCL_BYPASS);
616	} else {
617	    OUT_ACCEL_REG(R200_SE_VAP_CNTL_STATUS, 0);
618	}
619	OUT_ACCEL_REG(R200_PP_CNTL_X, 0);
620	OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0);
621	OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0);
622	OUT_ACCEL_REG(R200_RE_CNTL, 0x0);
623	OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0);
624	OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE |
625	    R200_VAP_VF_MAX_VTX_NUM);
626	FINISH_ACCEL();
627
628	BEGIN_ACCEL(5);
629	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
630	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
631	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
632	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
633	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
634				       RADEON_BFACE_SOLID |
635				       RADEON_FFACE_SOLID |
636				       RADEON_VTX_PIX_CENTER_OGL |
637				       RADEON_ROUND_MODE_ROUND |
638				       RADEON_ROUND_PREC_4TH_PIX));
639	FINISH_ACCEL();
640    } else {
641	BEGIN_ACCEL(2);
642	if ((info->ChipFamily == CHIP_FAMILY_RADEON) ||
643	    (info->ChipFamily == CHIP_FAMILY_RV200))
644	    OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, 0);
645	else
646	    OUT_ACCEL_REG(RADEON_SE_CNTL_STATUS, RADEON_TCL_BYPASS);
647	OUT_ACCEL_REG(RADEON_SE_COORD_FMT,
648	    RADEON_VTX_XY_PRE_MULT_1_OVER_W0 |
649	    RADEON_VTX_ST0_NONPARAMETRIC |
650	    RADEON_VTX_ST1_NONPARAMETRIC |
651	    RADEON_TEX1_W_ROUTING_USE_W0);
652	FINISH_ACCEL();
653
654	BEGIN_ACCEL(5);
655	OUT_ACCEL_REG(RADEON_RE_TOP_LEFT, 0);
656	OUT_ACCEL_REG(RADEON_RE_WIDTH_HEIGHT, 0x07ff07ff);
657	OUT_ACCEL_REG(RADEON_AUX_SC_CNTL, 0);
658	OUT_ACCEL_REG(RADEON_RB3D_PLANEMASK, 0xffffffff);
659	OUT_ACCEL_REG(RADEON_SE_CNTL, (RADEON_DIFFUSE_SHADE_GOURAUD |
660				       RADEON_BFACE_SOLID |
661				       RADEON_FFACE_SOLID |
662				       RADEON_VTX_PIX_CENTER_OGL |
663				       RADEON_ROUND_MODE_ROUND |
664				       RADEON_ROUND_PREC_4TH_PIX));
665	FINISH_ACCEL();
666    }
667
668}
669
670
671/* MMIO:
672 *
673 * Wait for the graphics engine to be completely idle: the FIFO has
674 * drained, the Pixel Cache is flushed, and the engine is idle.  This is
675 * a standard "sync" function that will make the hardware "quiescent".
676 *
677 * CP:
678 *
679 * Wait until the CP is completely idle: the FIFO has drained and the CP
680 * is idle.
681 */
682void FUNC_NAME(RADEONWaitForIdle)(ScrnInfoPtr pScrn)
683{
684    RADEONInfoPtr  info = RADEONPTR(pScrn);
685    unsigned char *RADEONMMIO = info->MMIO;
686    int            i    = 0;
687
688#ifdef ACCEL_CP
689    /* Make sure the CP is idle first */
690    if (info->CPStarted) {
691	int  ret;
692
693	FLUSH_RING();
694
695	for (;;) {
696	    do {
697		ret = drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE);
698		if (ret && ret != -EBUSY) {
699		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
700			       "%s: CP idle %d\n", __FUNCTION__, ret);
701		}
702	    } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT));
703
704	    if (ret == 0) return;
705
706	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
707		       "Idle timed out, resetting engine...\n");
708	    RADEONEngineReset(pScrn);
709	    RADEONEngineRestore(pScrn);
710
711	    /* Always restart the engine when doing CP 2D acceleration */
712	    RADEONCP_RESET(pScrn, info);
713	    RADEONCP_START(pScrn, info);
714	}
715    }
716#endif
717
718#if 0
719    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
720		   "WaitForIdle (entering): %d entries, stat=0x%08x\n",
721		   INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
722		   INREG(RADEON_RBBM_STATUS));
723#endif
724
725    /* Wait for the engine to go idle */
726    RADEONWaitForFifoFunction(pScrn, 64);
727
728    for (;;) {
729	for (i = 0; i < RADEON_TIMEOUT; i++) {
730	    if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) {
731		RADEONEngineFlush(pScrn);
732		return;
733	    }
734	}
735	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
736		       "Idle timed out: %u entries, stat=0x%08x\n",
737		       (unsigned int)INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
738		       (unsigned int)INREG(RADEON_RBBM_STATUS));
739	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
740		   "Idle timed out, resetting engine...\n");
741	RADEONEngineReset(pScrn);
742	RADEONEngineRestore(pScrn);
743#ifdef XF86DRI
744	if (info->directRenderingEnabled) {
745	    RADEONCP_RESET(pScrn, info);
746	    RADEONCP_START(pScrn, info);
747	}
748#endif
749    }
750}
751