1 /* 2 Copyright (c) 2002-05, Thomas Kurschel 3 4 5 Part of Radeon accelerant 6 7 Access to VIP 8 9 This code must be in kernel because we need for FIFO to become empty 10 during VIP access (which in turn requires locking the card, and locking 11 is a dangerous thing in user mode as the app can suddenly die, taking 12 the lock with it) 13 */ 14 15 #include "radeon_driver.h" 16 #include "mmio.h" 17 #include "vip_regs.h" 18 #include "bios_regs.h" 19 #include "theatre_regs.h" 20 21 22 // moved to bottom to avoid inlining 23 static bool Radeon_VIPWaitForIdle( device_info *di ); 24 static status_t RADEON_VIPFifoIdle(device_info *di, uint8 channel); 25 26 27 // read data from VIP 28 // CP lock must be hold 29 static bool do_VIPRead( 30 device_info *di, uint channel, uint address, uint32 *data ) 31 { 32 vuint8 *regs = di->regs; 33 34 Radeon_WaitForFifo( di, 2 ); 35 // the 0x2000 is the nameless "register-read" flag 36 OUTREG( regs, RADEON_VIPH_REG_ADDR, (channel << 14) | address | 0x2000 ); 37 38 if( !Radeon_VIPWaitForIdle( di )) 39 return false; 40 41 // enable VIP register cycle reads 42 Radeon_WaitForFifo( di, 2 ); 43 OUTREGP( regs, RADEON_VIPH_TIMEOUT_STAT, 0, 44 ~RADEON_VIPH_TIMEOUT_STAT_AK_MASK & ~RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS ); 45 //Radeon_WaitForIdle( di, false, false ); 46 47 // this read starts a register cycle; the returned value has no meaning 48 INREG( regs, RADEON_VIPH_REG_DATA ); 49 50 if( !Radeon_VIPWaitForIdle( di )) 51 return false; 52 53 //Radeon_WaitForIdle( di, false, false ); 54 55 // register cycle is done, so disable any further cycle 56 Radeon_WaitForFifo( di, 2 ); 57 OUTREGP( regs, RADEON_VIPH_TIMEOUT_STAT, RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS, 58 ~RADEON_VIPH_TIMEOUT_STAT_AK_MASK & ~RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS ); 59 //Radeon_WaitForIdle( di, false, false ); 60 61 // get the data 62 *data = INREG( regs, RADEON_VIPH_REG_DATA ); 63 64 //SHOW_FLOW( 4, "channel=%d, address=%x, data=%lx", channel, address, *data ); 65 66 if( !Radeon_VIPWaitForIdle( di )) 67 return false; 68 69 // disable register cycle again (according to sample code) 70 // IMHO, this is not necessary as it has been done before 71 Radeon_WaitForFifo( di, 2 ); 72 OUTREGP( regs, RADEON_VIPH_TIMEOUT_STAT, RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS, 73 ~RADEON_VIPH_TIMEOUT_STAT_AK_MASK & ~RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS ); 74 75 return true; 76 } 77 78 // public function: read data from VIP 79 bool Radeon_VIPRead( 80 device_info *di, uint channel, uint address, uint32 *data, bool lock ) 81 { 82 bool res; 83 84 if( lock ) 85 ACQUIRE_BEN( di->si->cp.lock ); 86 87 res = do_VIPRead( di, channel, address, data ); 88 89 if( lock ) 90 RELEASE_BEN( di->si->cp.lock ); 91 92 // SHOW_FLOW( 2, "address=%x, data=%lx, lock=%d", address, *data, lock ); 93 94 return res; 95 } 96 97 static bool do_VIPFifoRead(device_info *di, uint8 channel, uint32 address, uint32 count, uint8 *buffer) 98 { 99 vuint8 *regs = di->regs; 100 uint32 status, tmp; 101 102 if(count!=1) 103 { 104 SHOW_FLOW0( 2, "Attempt to access VIP bus with non-stadard transaction length\n"); 105 return false; 106 } 107 108 SHOW_FLOW( 2, "address=%" B_PRIx32 ", count=%" B_PRIu32 " ", 109 address, count ); 110 111 Radeon_WaitForFifo( di, 2); 112 SHOW_FLOW0( 2, "1"); 113 OUTREG( regs, RADEON_VIPH_REG_ADDR, (channel << 14) | address | 0x3000); 114 SHOW_FLOW0( 2, "3"); 115 while(B_BUSY == (status = RADEON_VIPFifoIdle( di , 0xff))); 116 if(B_OK != status) return false; 117 118 // disable VIPH_REGR_DIS to enable VIP cycle. 119 // The LSB of VIPH_TIMEOUT_STAT are set to 0 120 // because 1 would have acknowledged various VIP 121 // interrupts unexpectedly 122 123 SHOW_FLOW0( 2, "4"); 124 Radeon_WaitForFifo( di, 2 ); // Radeon_WaitForIdle( di, false, false ); 125 SHOW_FLOW0( 2, "5"); 126 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, 127 INREG( regs, RADEON_VIPH_TIMEOUT_STAT) & 128 (0xffffff00 & ~RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS) ); 129 130 // the value returned here is garbage. The read merely initiates 131 // a register cycle 132 SHOW_FLOW0( 2, "6"); 133 Radeon_WaitForFifo( di, 2 ); // Radeon_WaitForIdle( di, false, false ); 134 INREG( regs, RADEON_VIPH_REG_DATA); 135 SHOW_FLOW0( 2, "7"); 136 while(B_BUSY == (status = RADEON_VIPFifoIdle( di , 0xff))); 137 if(B_OK != status) return false; 138 139 // set VIPH_REGR_DIS so that the read won't take too long. 140 SHOW_FLOW0( 2, "8"); 141 Radeon_WaitForFifo( di, 2 ); // Radeon_WaitForIdle( di, false, false ); 142 SHOW_FLOW0( 2, "9"); 143 tmp = INREG( regs, RADEON_VIPH_TIMEOUT_STAT); 144 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, (tmp & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS); 145 146 SHOW_FLOW0( 2, "10"); 147 Radeon_WaitForFifo( di, 2 ); // Radeon_WaitForIdle( di, false, false ); 148 switch(count){ 149 case 1: 150 *buffer=(uint8)(INREG( regs, RADEON_VIPH_REG_DATA) & 0xff); 151 break; 152 case 2: 153 *(uint16 *)buffer=(uint16) (INREG( regs, RADEON_VIPH_REG_DATA) & 0xffff); 154 break; 155 case 4: 156 *(uint32 *)buffer=(uint32) ( INREG( regs, RADEON_VIPH_REG_DATA) & 0xffffffff); 157 break; 158 } 159 SHOW_FLOW0( 2, "11"); 160 while(B_BUSY == (status = RADEON_VIPFifoIdle( di , 0xff))); 161 if(B_OK != status) return false; 162 163 // so that reading VIPH_REG_DATA would not trigger unnecessary vip cycles. 164 SHOW_FLOW0( 2, "12"); 165 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, 166 (INREG( regs, RADEON_VIPH_TIMEOUT_STAT) & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS); 167 return true; 168 169 } 170 171 bool Radeon_VIPFifoRead(device_info *di, uint8 channel, uint32 address, uint32 count, uint8 *buffer, bool lock) 172 { 173 bool res; 174 175 if( lock ) 176 ACQUIRE_BEN( di->si->cp.lock ); 177 178 res = do_VIPFifoRead( di, channel, address, count, buffer ); 179 180 if( lock ) 181 RELEASE_BEN( di->si->cp.lock ); 182 183 //SHOW_FLOW( 2, "address=%x, data=%lx, lock=%d", address, *data, lock ); 184 185 return res; 186 } 187 188 // write data to VIP 189 // CP must be hold 190 static bool do_VIPWrite( device_info *di, uint8 channel, uint address, uint32 data ) 191 { 192 vuint8 *regs = di->regs; 193 194 Radeon_WaitForFifo( di, 2 ); 195 OUTREG( regs, RADEON_VIPH_REG_ADDR, (channel << 14) | (address & ~0x2000) ); 196 197 if( !Radeon_VIPWaitForIdle( di )) return false; 198 199 //SHOW_FLOW( 4, "channel=%d, address=%x, data=%lx", channel, address, data ); 200 201 Radeon_WaitForFifo( di, 2 ); 202 OUTREG( regs, RADEON_VIPH_REG_DATA, data ); 203 204 return Radeon_VIPWaitForIdle( di ); 205 206 } 207 208 // public function: write data to VIP 209 bool Radeon_VIPWrite(device_info *di, uint8 channel, uint address, uint32 data, bool lock ) 210 { 211 bool res; 212 213 //SHOW_FLOW( 2, "address=%x, data=%lx, lock=%d", address, data, lock ); 214 215 if( lock ) 216 ACQUIRE_BEN( di->si->cp.lock ); 217 218 res = do_VIPWrite( di, channel, address, data ); 219 220 if( lock ) 221 RELEASE_BEN( di->si->cp.lock ); 222 223 return res; 224 } 225 226 227 static bool do_VIPFifoWrite(device_info *di, uint8 channel, uint32 address, 228 uint32 count, uint8 *buffer) 229 { 230 vuint8 *regs = di->regs; 231 232 uint32 status; 233 uint32 i; 234 235 SHOW_FLOW( 2, "address=%" B_PRIx32 ", count=%" B_PRIu32 ", ", 236 address, count ); 237 238 Radeon_WaitForFifo( di, 2 ); 239 OUTREG( regs, RADEON_VIPH_REG_ADDR, 240 ((channel << 14) | address | 0x1000) & ~0x2000 ); 241 SHOW_FLOW0( 2, "1"); 242 do { 243 status = RADEON_VIPFifoIdle(di, 0x0f); 244 } while (status == B_BUSY); 245 246 if(B_OK != status){ 247 SHOW_FLOW( 2 ,"cannot write %x to VIPH_REG_ADDR\n", 248 (unsigned int)address); 249 return false; 250 } 251 252 SHOW_FLOW0( 2, "2"); 253 for (i = 0; i < count; i+=4) 254 { 255 Radeon_WaitForFifo( di, 2); 256 SHOW_FLOW( 2, "count %" B_PRIu32, count); 257 OUTREG( regs, RADEON_VIPH_REG_DATA, *(uint32*)(buffer + i)); 258 259 do { 260 status = RADEON_VIPFifoIdle(di, 0x0f); 261 } while (status == B_BUSY); 262 263 if(B_OK != status) 264 { 265 SHOW_FLOW0( 2 , "cannot write to VIPH_REG_DATA\n"); 266 return false; 267 } 268 } 269 270 return true; 271 } 272 273 bool Radeon_VIPFifoWrite(device_info *di, uint8 channel, uint32 address, uint32 count, uint8 *buffer, bool lock) 274 { 275 bool res; 276 277 //SHOW_FLOW( 2, "address=%x, data=%lx, lock=%d", address, data, lock ); 278 279 if( lock ) 280 ACQUIRE_BEN( di->si->cp.lock ); 281 282 Radeon_VIPReset( di, false); 283 res = do_VIPFifoWrite( di, channel, address, count, buffer ); 284 285 if( lock ) 286 RELEASE_BEN( di->si->cp.lock ); 287 288 return res; 289 } 290 291 292 // reset VIP 293 void Radeon_VIPReset( 294 device_info *di, bool lock ) 295 { 296 vuint8 *regs = di->regs; 297 298 if( lock ) 299 ACQUIRE_BEN( di->si->cp.lock ); 300 301 Radeon_WaitForFifo( di, 5 ); // Radeon_WaitForIdle( di, false, false ); 302 switch(di->asic){ 303 case rt_r200: 304 case rt_rs200: 305 case rt_rv200: 306 case rt_rs100: 307 case rt_rv100: 308 case rt_r100: 309 OUTREG( regs, RADEON_VIPH_CONTROL, 4 | (15 << RADEON_VIPH_CONTROL_VIPH_MAX_WAIT_SHIFT) | 310 RADEON_VIPH_CONTROL_VIPH_DMA_MODE | RADEON_VIPH_CONTROL_VIPH_EN ); // slowest, timeout in 16 phases 311 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, (INREG( regs, RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | 312 RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS); 313 OUTREG( regs, RADEON_VIPH_DV_LAT, 314 0xff | 315 (4 << RADEON_VIPH_DV_LAT_VIPH_DV0_LAT_SHIFT) | 316 (4 << RADEON_VIPH_DV_LAT_VIPH_DV1_LAT_SHIFT) | 317 (4 << RADEON_VIPH_DV_LAT_VIPH_DV2_LAT_SHIFT) | 318 (4 << RADEON_VIPH_DV_LAT_VIPH_DV3_LAT_SHIFT)); // set timeslice 319 OUTREG( regs, RADEON_VIPH_DMA_CHUNK, 0x151); 320 OUTREG( regs, RADEON_TEST_DEBUG_CNTL, INREG( regs, RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL_OUT_EN)); 321 default: 322 OUTREG( regs, RADEON_VIPH_CONTROL, 9 | (15 << RADEON_VIPH_CONTROL_VIPH_MAX_WAIT_SHIFT) | 323 RADEON_VIPH_CONTROL_VIPH_DMA_MODE | RADEON_VIPH_CONTROL_VIPH_EN ); // slowest, timeout in 16 phases 324 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, (INREG( regs, RADEON_VIPH_TIMEOUT_STAT) & 0xFFFFFF00) | 325 RADEON_VIPH_TIMEOUT_STAT_VIPH_REGR_DIS); 326 OUTREG( regs, RADEON_VIPH_DV_LAT, 327 0xff | 328 (4 << RADEON_VIPH_DV_LAT_VIPH_DV0_LAT_SHIFT) | 329 (4 << RADEON_VIPH_DV_LAT_VIPH_DV1_LAT_SHIFT) | 330 (4 << RADEON_VIPH_DV_LAT_VIPH_DV2_LAT_SHIFT) | 331 (4 << RADEON_VIPH_DV_LAT_VIPH_DV3_LAT_SHIFT)); // set timeslice 332 OUTREG( regs, RADEON_VIPH_DMA_CHUNK, 0x0); 333 OUTREG( regs, RADEON_TEST_DEBUG_CNTL, INREG( regs, RADEON_TEST_DEBUG_CNTL) & (~RADEON_TEST_DEBUG_CNTL_OUT_EN)); 334 break; 335 336 } 337 338 if( lock ) 339 RELEASE_BEN( di->si->cp.lock ); 340 } 341 342 343 // check whether VIP host is idle 344 // lock must be hold 345 static status_t Radeon_VIPIdle( 346 device_info *di ) 347 { 348 vuint8 *regs = di->regs; 349 uint32 timeout; 350 351 //Radeon_WaitForIdle( di, false, false ); 352 353 // if there is a stuck transaction, acknowledge that 354 timeout = INREG( regs, RADEON_VIPH_TIMEOUT_STAT ); 355 if( (timeout & RADEON_VIPH_TIMEOUT_STAT_VIPH_REG_STAT) != 0 ) 356 { 357 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, 358 (timeout & 0xffffff00) | RADEON_VIPH_TIMEOUT_STAT_VIPH_REG_AK); 359 return (INREG( regs, RADEON_VIPH_CONTROL) & 0x2000) ? B_BUSY : B_ERROR; 360 } 361 return (INREG( regs, RADEON_VIPH_CONTROL) & 0x2000) ? B_BUSY : B_OK; 362 } 363 364 static status_t RADEON_VIPFifoIdle(device_info *di, uint8 channel) 365 { 366 vuint8 *regs = di->regs; 367 uint32 timeout; 368 369 timeout = INREG( regs, RADEON_VIPH_TIMEOUT_STAT); 370 if((timeout & 0x0000000f) & channel) /* lockup ?? */ 371 { 372 OUTREG( regs, RADEON_VIPH_TIMEOUT_STAT, (timeout & 0xfffffff0) | channel); 373 return (INREG( regs, RADEON_VIPH_CONTROL) & 0x2000) ? B_BUSY : B_ERROR; 374 } 375 return (INREG( regs, RADEON_VIPH_CONTROL) & 0x2000) ? B_BUSY : B_OK ; 376 } 377 378 379 // wait until VIP host is idle 380 // lock must be hold 381 static bool Radeon_VIPWaitForIdle( 382 device_info *di ) 383 { 384 int i; 385 386 // wait 100x 1ms before giving up 387 for( i = 0; i < 100; ++i ) { 388 status_t res; 389 390 res = Radeon_VIPIdle( di ); 391 if( res != B_BUSY ) { 392 if( res == B_OK ) 393 return true; 394 else 395 return false; 396 } 397 398 snooze( 1000 ); 399 } 400 401 return false; 402 } 403 404 405 // find VIP channel of a device 406 // return: >= 0 channel of device 407 // < 0 no device found 408 int Radeon_FindVIPDevice( 409 device_info *di, uint32 device_id ) 410 { 411 uint channel; 412 uint32 cur_device_id; 413 414 // if card has no VIP port, let hardware detection fail; 415 // in this case, noone will bother us again 416 if( !di->has_vip ) { 417 SHOW_FLOW0( 3, "This Device has no VIP Bus."); 418 return -1; 419 } 420 421 ACQUIRE_BEN( di->si->cp.lock ); 422 423 Radeon_VIPReset( di, false ); 424 425 // there are up to 4 devices, connected to one of 4 channels 426 for( channel = 0; channel < 4; ++channel ) { 427 428 // read device id 429 if( !Radeon_VIPRead( di, channel, RADEON_VIP_VENDOR_DEVICE_ID, &cur_device_id, false )) { 430 SHOW_FLOW( 3, "No device found on channel %d", channel); 431 continue; 432 } 433 434 // compare device id directly 435 if( cur_device_id == device_id ) { 436 SHOW_FLOW( 3, "Device %08" B_PRIx32 " found on channel %d", 437 device_id, channel); 438 RELEASE_BEN( di->si->cp.lock ); 439 return channel; 440 } 441 } 442 443 RELEASE_BEN( di->si->cp.lock ); 444 445 // couldn't find device 446 return -1; 447 } 448