1 /* 2 * Copyright 2006-2011, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Alexander von Gluck, kallisti5@unixzen.com 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include "gpu.h" 12 13 #include <Debug.h> 14 15 #include "accelerant_protos.h" 16 #include "accelerant.h" 17 #include "bios.h" 18 #include "utility.h" 19 20 21 #undef TRACE 22 23 #define TRACE_GPU 24 #ifdef TRACE_GPU 25 # define TRACE(x...) _sPrintf("radeon_hd: " x) 26 #else 27 # define TRACE(x...) ; 28 #endif 29 30 #define ERROR(x...) _sPrintf("radeon_hd: " x) 31 32 33 status_t 34 radeon_gpu_reset() 35 { 36 radeon_shared_info &info = *gInfo->shared_info; 37 38 // Read GRBM Command Processor status 39 if ((Read32(OUT, GRBM_STATUS) & GUI_ACTIVE) == 0) 40 return B_ERROR; 41 42 TRACE("%s: GPU software reset in progress...\n", __func__); 43 44 // Halt memory controller 45 struct gpu_state gpuState; 46 radeon_gpu_mc_halt(&gpuState); 47 48 if (radeon_gpu_mc_idlewait() != B_OK) 49 ERROR("%s: Couldn't idle memory controller!\n", __func__); 50 51 if (info.chipsetID < RADEON_CEDAR) { 52 Write32(OUT, CP_ME_CNTL, CP_ME_HALT); 53 // Disable Command Processor parsing / prefetching 54 55 // Register busy masks for early Radeon HD cards 56 57 // GRBM Command Processor Status 58 uint32 grbmBusyMask = VC_BUSY; 59 // Vertex Cache Busy 60 grbmBusyMask |= VGT_BUSY_NO_DMA | VGT_BUSY; 61 // Vertex Grouper Tessellator Busy 62 grbmBusyMask |= TA03_BUSY; 63 // unknown 64 grbmBusyMask |= TC_BUSY; 65 // Texture Cache Busy 66 grbmBusyMask |= SX_BUSY; 67 // Shader Export Busy 68 grbmBusyMask |= SH_BUSY; 69 // Sequencer Instruction Cache Busy 70 grbmBusyMask |= SPI_BUSY; 71 // Shader Processor Interpolator Busy 72 grbmBusyMask |= SMX_BUSY; 73 // Shader Memory Exchange 74 grbmBusyMask |= SC_BUSY; 75 // Scan Converter Busy 76 grbmBusyMask |= PA_BUSY; 77 // Primitive Assembler Busy 78 grbmBusyMask |= DB_BUSY; 79 // Depth Block Busy 80 grbmBusyMask |= CR_BUSY; 81 // unknown 82 grbmBusyMask |= CB_BUSY; 83 // Color Block Busy 84 grbmBusyMask |= GUI_ACTIVE; 85 // unknown (graphics pipeline active?) 86 87 // GRBM Command Processor Detailed Status 88 uint32 grbm2BusyMask = SPI0_BUSY | SPI1_BUSY | SPI2_BUSY | SPI3_BUSY; 89 // Shader Processor Interpolator 0 - 3 Busy 90 grbm2BusyMask |= TA0_BUSY | TA1_BUSY | TA2_BUSY | TA3_BUSY; 91 // unknown 0 - 3 Busy 92 grbm2BusyMask |= DB0_BUSY | DB1_BUSY | DB2_BUSY | DB3_BUSY; 93 // Depth Block 0 - 3 Busy 94 grbm2BusyMask |= CB0_BUSY | CB1_BUSY | CB2_BUSY | CB3_BUSY; 95 // Color Block 0 - 3 Busy 96 97 uint32 tmp; 98 /* Check if any of the rendering block is busy and reset it */ 99 if ((Read32(OUT, GRBM_STATUS) & grbmBusyMask) != 0 100 || (Read32(OUT, GRBM_STATUS2) & grbm2BusyMask) != 0) { 101 tmp = SOFT_RESET_CR 102 | SOFT_RESET_DB 103 | SOFT_RESET_CB 104 | SOFT_RESET_PA 105 | SOFT_RESET_SC 106 | SOFT_RESET_SMX 107 | SOFT_RESET_SPI 108 | SOFT_RESET_SX 109 | SOFT_RESET_SH 110 | SOFT_RESET_TC 111 | SOFT_RESET_TA 112 | SOFT_RESET_VC 113 | SOFT_RESET_VGT; 114 Write32(OUT, GRBM_SOFT_RESET, tmp); 115 Read32(OUT, GRBM_SOFT_RESET); 116 snooze(15000); 117 Write32(OUT, GRBM_SOFT_RESET, 0); 118 } 119 120 // Reset CP 121 tmp = SOFT_RESET_CP; 122 Write32(OUT, GRBM_SOFT_RESET, tmp); 123 Read32(OUT, GRBM_SOFT_RESET); 124 snooze(15000); 125 Write32(OUT, GRBM_SOFT_RESET, 0); 126 127 // Let things settle 128 snooze(1000); 129 } else { 130 // Evergreen and higher 131 132 Write32(OUT, CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 133 // Disable Command Processor parsing / prefetching 134 135 // reset the graphics pipeline components 136 uint32 grbmReset = (SOFT_RESET_CP 137 | SOFT_RESET_CB 138 | SOFT_RESET_DB 139 | SOFT_RESET_GDS 140 | SOFT_RESET_PA 141 | SOFT_RESET_SC 142 | SOFT_RESET_SPI 143 | SOFT_RESET_SH 144 | SOFT_RESET_SX 145 | SOFT_RESET_TC 146 | SOFT_RESET_TA 147 | SOFT_RESET_VGT 148 | SOFT_RESET_IA); 149 150 Write32(OUT, GRBM_SOFT_RESET, grbmReset); 151 Read32(OUT, GRBM_SOFT_RESET); 152 153 snooze(50); 154 Write32(OUT, GRBM_SOFT_RESET, 0); 155 Read32(OUT, GRBM_SOFT_RESET); 156 snooze(50); 157 } 158 159 // Resume memory controller 160 radeon_gpu_mc_resume(&gpuState); 161 return B_OK; 162 } 163 164 165 void 166 radeon_gpu_mc_halt(gpu_state* gpuState) 167 { 168 // Backup current memory controller state 169 gpuState->d1vgaControl = Read32(OUT, AVIVO_D1VGA_CONTROL); 170 gpuState->d2vgaControl = Read32(OUT, AVIVO_D2VGA_CONTROL); 171 gpuState->vgaRenderControl = Read32(OUT, AVIVO_VGA_RENDER_CONTROL); 172 gpuState->vgaHdpControl = Read32(OUT, AVIVO_VGA_HDP_CONTROL); 173 gpuState->d1crtcControl = Read32(OUT, AVIVO_D1CRTC_CONTROL); 174 gpuState->d2crtcControl = Read32(OUT, AVIVO_D2CRTC_CONTROL); 175 176 // halt all memory controller actions 177 Write32(OUT, AVIVO_VGA_RENDER_CONTROL, 0); 178 Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 1); 179 Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 1); 180 Write32(OUT, AVIVO_D1CRTC_CONTROL, 0); 181 Write32(OUT, AVIVO_D2CRTC_CONTROL, 0); 182 Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 0); 183 Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 0); 184 Write32(OUT, AVIVO_D1VGA_CONTROL, 0); 185 Write32(OUT, AVIVO_D2VGA_CONTROL, 0); 186 } 187 188 189 void 190 radeon_gpu_mc_resume(gpu_state* gpuState) 191 { 192 Write32(OUT, AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, gInfo->fb.vramStart); 193 Write32(OUT, AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, gInfo->fb.vramStart); 194 Write32(OUT, AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, gInfo->fb.vramStart); 195 Write32(OUT, AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, gInfo->fb.vramStart); 196 // TODO: Evergreen high surface addresses? 197 Write32(OUT, AVIVO_VGA_MEMORY_BASE_ADDRESS, gInfo->fb.vramStart); 198 199 // Unlock host access 200 Write32(OUT, AVIVO_VGA_HDP_CONTROL, gpuState->vgaHdpControl); 201 snooze(1); 202 203 // Restore memory controller state 204 Write32(OUT, AVIVO_D1VGA_CONTROL, gpuState->d1vgaControl); 205 Write32(OUT, AVIVO_D2VGA_CONTROL, gpuState->d2vgaControl); 206 Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 1); 207 Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 1); 208 Write32(OUT, AVIVO_D1CRTC_CONTROL, gpuState->d1crtcControl); 209 Write32(OUT, AVIVO_D2CRTC_CONTROL, gpuState->d2crtcControl); 210 Write32(OUT, AVIVO_D1CRTC_UPDATE_LOCK, 0); 211 Write32(OUT, AVIVO_D2CRTC_UPDATE_LOCK, 0); 212 Write32(OUT, AVIVO_VGA_RENDER_CONTROL, gpuState->vgaRenderControl); 213 } 214 215 216 status_t 217 radeon_gpu_mc_idlewait() 218 { 219 uint32 idleStatus; 220 221 uint32 busyBits 222 = (VMC_BUSY | MCB_BUSY | MCDZ_BUSY | MCDY_BUSY | MCDX_BUSY | MCDW_BUSY); 223 224 uint32 tryCount; 225 // We give the gpu 0.5 seconds to become idle checking once every 500usec 226 for (tryCount = 0; tryCount < 1000; tryCount++) { 227 if (((idleStatus = Read32(MC, SRBM_STATUS)) & busyBits) == 0) 228 return B_OK; 229 snooze(500); 230 } 231 232 ERROR("%s: Couldn't idle SRBM!\n", __func__); 233 234 bool state; 235 state = (idleStatus & VMC_BUSY) != 0; 236 TRACE("%s: VMC is %s\n", __func__, state ? "busy" : "idle"); 237 state = (idleStatus & MCB_BUSY) != 0; 238 TRACE("%s: MCB is %s\n", __func__, state ? "busy" : "idle"); 239 state = (idleStatus & MCDZ_BUSY) != 0; 240 TRACE("%s: MCDZ is %s\n", __func__, state ? "busy" : "idle"); 241 state = (idleStatus & MCDY_BUSY) != 0; 242 TRACE("%s: MCDY is %s\n", __func__, state ? "busy" : "idle"); 243 state = (idleStatus & MCDX_BUSY) != 0; 244 TRACE("%s: MCDX is %s\n", __func__, state ? "busy" : "idle"); 245 state = (idleStatus & MCDW_BUSY) != 0; 246 TRACE("%s: MCDW is %s\n", __func__, state ? "busy" : "idle"); 247 248 return B_TIMED_OUT; 249 } 250 251 252 static status_t 253 radeon_gpu_mc_setup_r600() 254 { 255 // HDP initialization 256 uint32 i; 257 uint32 j; 258 for (i = 0, j = 0; i < 32; i++, j += 0x18) { 259 Write32(OUT, (0x2c14 + j), 0x00000000); 260 Write32(OUT, (0x2c18 + j), 0x00000000); 261 Write32(OUT, (0x2c1c + j), 0x00000000); 262 Write32(OUT, (0x2c20 + j), 0x00000000); 263 Write32(OUT, (0x2c24 + j), 0x00000000); 264 } 265 Write32(OUT, R600_HDP_REG_COHERENCY_FLUSH_CNTL, 0); 266 267 // idle the memory controller 268 struct gpu_state gpuState; 269 radeon_gpu_mc_halt(&gpuState); 270 271 if (radeon_gpu_mc_idlewait() != B_OK) 272 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 273 274 // TODO: Memory Controller AGP 275 Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, 276 gInfo->fb.vramStart >> 12); 277 Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 278 gInfo->fb.vramEnd >> 12); 279 280 Write32(OUT, R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 281 uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16; 282 tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF); 283 284 Write32(OUT, R600_MC_VM_FB_LOCATION, tmp); 285 Write32(OUT, R600_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8)); 286 Write32(OUT, R600_HDP_NONSURFACE_INFO, (2 << 7)); 287 Write32(OUT, R600_HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 288 289 // is AGP? 290 // Write32(OUT, R600_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 22); 291 // Write32(OUT, R600_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 22); 292 // Write32(OUT, R600_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22); 293 // else? 294 Write32(OUT, R600_MC_VM_AGP_BASE, 0); 295 Write32(OUT, R600_MC_VM_AGP_TOP, 0x0FFFFFFF); 296 Write32(OUT, R600_MC_VM_AGP_BOT, 0x0FFFFFFF); 297 298 if (radeon_gpu_mc_idlewait() != B_OK) 299 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 300 301 radeon_gpu_mc_resume(&gpuState); 302 303 // disable render control 304 Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF); 305 306 return B_OK; 307 } 308 309 310 static status_t 311 radeon_gpu_mc_setup_r700() 312 { 313 // HDP initialization 314 uint32 i; 315 uint32 j; 316 for (i = 0, j = 0; i < 32; i++, j += 0x18) { 317 Write32(OUT, (0x2c14 + j), 0x00000000); 318 Write32(OUT, (0x2c18 + j), 0x00000000); 319 Write32(OUT, (0x2c1c + j), 0x00000000); 320 Write32(OUT, (0x2c20 + j), 0x00000000); 321 Write32(OUT, (0x2c24 + j), 0x00000000); 322 } 323 324 // On r7xx read from HDP_DEBUG1 vs write HDP_REG_COHERENCY_FLUSH_CNTL 325 Read32(OUT, R700_HDP_DEBUG1); 326 327 // idle the memory controller 328 struct gpu_state gpuState; 329 radeon_gpu_mc_halt(&gpuState); 330 331 if (radeon_gpu_mc_idlewait() != B_OK) 332 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 333 334 Write32(OUT, AVIVO_VGA_HDP_CONTROL, AVIVO_VGA_MEMORY_DISABLE); 335 336 // TODO: Memory Controller AGP 337 Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, 338 gInfo->fb.vramStart >> 12); 339 Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 340 gInfo->fb.vramEnd >> 12); 341 342 Write32(OUT, R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 343 uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16; 344 tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF); 345 346 Write32(OUT, R700_MC_VM_FB_LOCATION, tmp); 347 Write32(OUT, R700_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8)); 348 Write32(OUT, R700_HDP_NONSURFACE_INFO, (2 << 7)); 349 Write32(OUT, R700_HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 350 351 // is AGP? 352 // Write32(OUT, R700_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 22); 353 // Write32(OUT, R700_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 22); 354 // Write32(OUT, R700_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22); 355 // else? 356 Write32(OUT, R700_MC_VM_AGP_BASE, 0); 357 Write32(OUT, R700_MC_VM_AGP_TOP, 0x0FFFFFFF); 358 Write32(OUT, R700_MC_VM_AGP_BOT, 0x0FFFFFFF); 359 360 if (radeon_gpu_mc_idlewait() != B_OK) 361 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 362 363 radeon_gpu_mc_resume(&gpuState); 364 365 // disable render control 366 Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF); 367 368 return B_OK; 369 } 370 371 372 static status_t 373 radeon_gpu_mc_setup_evergreen() 374 { 375 // HDP initialization 376 uint32 i; 377 uint32 j; 378 for (i = 0, j = 0; i < 32; i++, j += 0x18) { 379 Write32(OUT, (0x2c14 + j), 0x00000000); 380 Write32(OUT, (0x2c18 + j), 0x00000000); 381 Write32(OUT, (0x2c1c + j), 0x00000000); 382 Write32(OUT, (0x2c20 + j), 0x00000000); 383 Write32(OUT, (0x2c24 + j), 0x00000000); 384 } 385 Write32(OUT, EVERGREEN_HDP_REG_COHERENCY_FLUSH_CNTL, 0); 386 387 // idle the memory controller 388 struct gpu_state gpuState; 389 radeon_gpu_mc_halt(&gpuState); 390 391 if (radeon_gpu_mc_idlewait() != B_OK) 392 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 393 394 Write32(OUT, AVIVO_VGA_HDP_CONTROL, AVIVO_VGA_MEMORY_DISABLE); 395 396 // TODO: Memory Controller AGP 397 Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_LOW_ADDR, 398 gInfo->fb.vramStart >> 12); 399 Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 400 gInfo->fb.vramEnd >> 12); 401 402 Write32(OUT, EVERGREEN_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 403 404 radeon_shared_info &info = *gInfo->shared_info; 405 if ((info.chipsetFlags & CHIP_IGP) != 0) { 406 // Evergreen IGP Fusion 407 uint32 tmp = Read32(OUT, EVERGREEN_MC_FUS_VM_FB_OFFSET) 408 & 0x000FFFFF; 409 tmp |= ((gInfo->fb.vramEnd >> 20) & 0xF) << 24; 410 tmp |= ((gInfo->fb.vramStart >> 20) & 0xF) << 20; 411 Write32(OUT, EVERGREEN_MC_FUS_VM_FB_OFFSET, tmp); 412 } 413 414 uint32 tmp = ((gInfo->fb.vramEnd >> 24) & 0xFFFF) << 16; 415 tmp |= ((gInfo->fb.vramStart >> 24) & 0xFFFF); 416 417 Write32(OUT, EVERGREEN_MC_VM_FB_LOCATION, tmp); 418 Write32(OUT, EVERGREEN_HDP_NONSURFACE_BASE, (gInfo->fb.vramStart >> 8)); 419 Write32(OUT, EVERGREEN_HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); 420 Write32(OUT, EVERGREEN_HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 421 422 // is AGP? 423 // Write32(OUT, EVERGREEN_MC_VM_AGP_TOP, gInfo->fb.gartEnd >> 16); 424 // Write32(OUT, EVERGREEN_MC_VM_AGP_BOT, gInfo->fb.gartStart >> 16); 425 // Write32(OUT, EVERGREEN_MC_VM_AGP_BASE, gInfo->fb.agpBase >> 22); 426 // else? 427 Write32(OUT, EVERGREEN_MC_VM_AGP_BASE, 0); 428 Write32(OUT, EVERGREEN_MC_VM_AGP_TOP, 0x0FFFFFFF); 429 Write32(OUT, EVERGREEN_MC_VM_AGP_BOT, 0x0FFFFFFF); 430 431 if (radeon_gpu_mc_idlewait() != B_OK) 432 ERROR("%s: Modifying non-idle memory controller!\n", __func__); 433 434 radeon_gpu_mc_resume(&gpuState); 435 436 // disable render control 437 Write32(OUT, 0x000300, Read32(OUT, 0x000300) & 0xFFFCFFFF); 438 439 return B_OK; 440 } 441 442 443 void 444 radeon_gpu_mc_init() 445 { 446 radeon_shared_info &info = *gInfo->shared_info; 447 448 uint32 fbVMLocationReg; 449 if (info.chipsetID >= RADEON_CEDAR) { 450 fbVMLocationReg = EVERGREEN_MC_VM_FB_LOCATION; 451 } else if (info.chipsetID >= RADEON_RV770) { 452 fbVMLocationReg = R700_MC_VM_FB_LOCATION; 453 } else { 454 fbVMLocationReg = R600_MC_VM_FB_LOCATION; 455 } 456 457 if (gInfo->shared_info->frame_buffer_size > 0) 458 gInfo->fb.valid = true; 459 460 // This is the card internal location. 461 uint64 vramBase = 0; 462 463 if ((info.chipsetFlags & CHIP_IGP) != 0) { 464 vramBase = Read32(OUT, fbVMLocationReg) & 0xFFFF; 465 vramBase <<= 24; 466 } 467 468 gInfo->fb.vramStart = vramBase; 469 gInfo->fb.vramSize = gInfo->shared_info->frame_buffer_size * 1024; 470 gInfo->fb.vramEnd = (vramBase + gInfo->fb.vramSize) - 1; 471 } 472 473 474 status_t 475 radeon_gpu_mc_setup() 476 { 477 radeon_shared_info &info = *gInfo->shared_info; 478 479 radeon_gpu_mc_init(); 480 // init video ram ranges for memory controler 481 482 if (gInfo->fb.valid != true) { 483 ERROR("%s: Memory Controller init failed.\n", __func__); 484 return B_ERROR; 485 } 486 487 TRACE("%s: vramStart: 0x%" B_PRIX64 ", vramEnd: 0x%" B_PRIX64 "\n", 488 __func__, gInfo->fb.vramStart, gInfo->fb.vramEnd); 489 490 if (info.chipsetID >= RADEON_CAYMAN) 491 return radeon_gpu_mc_setup_evergreen(); // also for ni 492 else if (info.chipsetID >= RADEON_CEDAR) 493 return radeon_gpu_mc_setup_evergreen(); 494 else if (info.chipsetID >= RADEON_RV770) 495 return radeon_gpu_mc_setup_r700(); 496 else if (info.chipsetID >= RADEON_R600) 497 return radeon_gpu_mc_setup_r600(); 498 499 return B_ERROR; 500 } 501 502 503 status_t 504 radeon_gpu_ring_setup() 505 { 506 TRACE("%s called\n", __func__); 507 508 // init GFX ring queue 509 gInfo->ringQueue[RADEON_QUEUE_TYPE_GFX_INDEX] 510 = new RingQueue(1024 * 1024, RADEON_QUEUE_TYPE_GFX_INDEX); 511 512 #if 0 513 // init IRQ ring queue (reverse of rendering/cp ring queue) 514 gInfo->irqRingQueue 515 = new IRQRingQueue(64 * 1024) 516 #endif 517 518 519 return B_OK; 520 } 521 522 523 status_t 524 radeon_gpu_ring_boot(uint32 ringType) 525 { 526 TRACE("%s called\n", __func__); 527 528 RingQueue* ring = gInfo->ringQueue[ringType]; 529 if (ring == NULL) { 530 ERROR("%s: Specified ring doesn't exist!\n", __func__); 531 return B_ERROR; 532 } 533 534 // We don't execute this code until it's more complete. 535 ERROR("%s: TODO\n", __func__); 536 return B_OK; 537 538 539 // TODO: Write initial ring PACKET3 STATE 540 541 // *** r600_cp_init_ring_buffer 542 // Reset command processor 543 Write32(OUT, GRBM_SOFT_RESET, RADEON_SOFT_RESET_CP); 544 Read32(OUT, GRBM_SOFT_RESET); 545 snooze(15000); 546 Write32(OUT, GRBM_SOFT_RESET, 0); 547 548 // Set ring buffer size 549 uint32 controlScratch = RB_NO_UPDATE 550 | (compute_order(4096 / 8) << 8) // rptr_update_l2qw 551 | compute_order(ring->GetSize() / 8); // size_l2qw 552 #ifdef __BIG_ENDIAN 553 controlScratch |= BUF_SWAP_32BIT; 554 #endif 555 Write32(OUT, CP_RB_CNTL, controlScratch); 556 557 // Set delays and timeouts 558 Write32(OUT, CP_SEM_WAIT_TIMER, 0); 559 Write32(OUT, CP_RB_WPTR_DELAY, 0); 560 561 // Enable RenderBuffer Reads 562 controlScratch |= RB_RPTR_WR_ENA; 563 Write32(OUT, CP_RB_CNTL, controlScratch); 564 565 // Zero out command processor read and write pointers 566 Write32(OUT, CP_RB_RPTR_WR, 0); 567 Write32(OUT, CP_RB_WPTR, 0); 568 569 #if 0 570 int ringPointer = 0; 571 // TODO: AGP cards 572 /* 573 if (RADEON_IS_AGP) { 574 ringPointer = dev_priv->ring_rptr->offset 575 - dev->agp->base 576 + dev_priv->gart_vm_start; 577 } else { 578 */ 579 ringPointer = dev_priv->ring_rptr->offset 580 - ((unsigned long) dev->sg->virtual) 581 + dev_priv->gart_vm_start; 582 583 Write32(OUT, CP_RB_RPTR_ADDR, (ringPointer & 0xfffffffc)); 584 Write32(OUT, CP_RB_RPTR_ADDR_HI, upper_32_bits(ringPointer)); 585 586 // Drop RPTR_WR_ENA and update CP RB Control 587 controlScratch &= ~R600_RB_RPTR_WR_ENA; 588 Write32(OUT, CP_RB_CNTL, controlScratch); 589 #endif 590 591 #if 0 592 // Update command processor pointer 593 int commandPointer = 0; 594 595 // TODO: AGP cards 596 /* 597 if (RADEON_IS_AGP) { 598 commandPointer = (dev_priv->cp_ring->offset 599 - dev->agp->base 600 + dev_priv->gart_vm_start); 601 } 602 */ 603 commandPointer = (dev_priv->cp_ring->offset 604 - (unsigned long)dev->sg->virtual 605 + dev_priv->gart_vm_start); 606 #endif 607 608 #if 0 609 Write32(OUT, CP_RB_BASE, commandPointer >> 8); 610 Write32(OUT, CP_ME_CNTL, 0xff); 611 Write32(OUT, CP_DEBUG, (1 << 27) | (1 << 28)); 612 #endif 613 614 #if 0 615 // Initialize scratch register pointer. 616 // This wil lcause the scratch register values to be wtitten 617 // to memory whenever they are updated. 618 619 uint64 scratchAddr = Read32(OUT, CP_RB_RPTR_ADDR) & 0xFFFFFFFC; 620 scratchAddr |= ((uint64)Read32(OUT, CP_RB_RPTR_ADDR_HI)) << 32; 621 scratchAddr += R600_SCRATCH_REG_OFFSET; 622 scratchAddr >>= 8; 623 scratchAddr &= 0xffffffff; 624 625 Write32(OUT, R600_SCRATCH_ADDR, (uint32)scratchAddr); 626 627 Write32(OUT, R600_SCRATCH_UMSK, 0x7); 628 #endif 629 630 #if 0 631 // Enable bus mastering 632 radeon_enable_bm(dev_priv); 633 634 radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0); 635 Write32(OUT, R600_LAST_FRAME_REG, 0); 636 637 radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0); 638 Write32(OUT, R600_LAST_DISPATCH_REG, 0); 639 640 radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0); 641 Write32(OUT, R600_LAST_CLEAR_REG, 0); 642 #endif 643 644 // Reset sarea? 645 #if 0 646 master_priv = file_priv->master->driver_priv; 647 if (master_priv->sarea_priv) { 648 master_priv->sarea_priv->last_frame = 0; 649 master_priv->sarea_priv->last_dispatch = 0; 650 master_priv->sarea_priv->last_clear = 0; 651 } 652 653 r600_do_wait_for_idle(dev_priv); 654 #endif 655 656 return B_OK; 657 } 658 659 660 status_t 661 radeon_gpu_ss_disable() 662 { 663 TRACE("%s called\n", __func__); 664 665 radeon_shared_info &info = *gInfo->shared_info; 666 uint32 ssControl; 667 668 if (info.chipsetID >= RADEON_CEDAR) { 669 // PLL1 670 ssControl = Read32(OUT, EVERGREEN_P1PLL_SS_CNTL); 671 ssControl &= ~EVERGREEN_PxPLL_SS_EN; 672 Write32(OUT, EVERGREEN_P1PLL_SS_CNTL, ssControl); 673 // PLL2 674 ssControl = Read32(OUT, EVERGREEN_P2PLL_SS_CNTL); 675 ssControl &= ~EVERGREEN_PxPLL_SS_EN; 676 Write32(OUT, EVERGREEN_P2PLL_SS_CNTL, ssControl); 677 } else if (info.chipsetID >= RADEON_RS600) { 678 // PLL1 679 ssControl = Read32(OUT, AVIVO_P1PLL_INT_SS_CNTL); 680 ssControl &= ~1; 681 Write32(OUT, AVIVO_P1PLL_INT_SS_CNTL, ssControl); 682 // PLL2 683 ssControl = Read32(OUT, AVIVO_P2PLL_INT_SS_CNTL); 684 ssControl &= ~1; 685 Write32(OUT, AVIVO_P2PLL_INT_SS_CNTL, ssControl); 686 } else 687 return B_ERROR; 688 689 return B_OK; 690 } 691