radeon_commonfuncs.c revision c503f109
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); 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, ((6 << R300_MS_X0_SHIFT) | 109 (6 << R300_MS_Y0_SHIFT) | 110 (6 << R300_MS_X1_SHIFT) | 111 (6 << R300_MS_Y1_SHIFT) | 112 (6 << R300_MS_X2_SHIFT) | 113 (6 << R300_MS_Y2_SHIFT) | 114 (6 << R300_MSBD0_Y_SHIFT) | 115 (6 << R300_MSBD0_X_SHIFT))); 116 OUT_ACCEL_REG(R300_GB_MSPOS1, ((6 << R300_MS_X3_SHIFT) | 117 (6 << R300_MS_Y3_SHIFT) | 118 (6 << R300_MS_X4_SHIFT) | 119 (6 << R300_MS_Y4_SHIFT) | 120 (6 << R300_MS_X5_SHIFT) | 121 (6 << R300_MS_Y5_SHIFT) | 122 (6 << 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, ((1440 << R300_CLIP_X_SHIFT) | 556 (1440 << R300_CLIP_Y_SHIFT))); 557 OUT_ACCEL_REG(R300_SC_CLIP_0_B, ((4080 << R300_CLIP_X_SHIFT) | 558 (4080 << 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