1 /* 2 * Copyright (c) 2002-2004, Thomas Kurschel 3 * Copyright (c) 2006-2007, Euan Kirkhope 4 * 5 * Distributed under the terms of the MIT license. 6 */ 7 8 /* 9 Init and clean-up of devices 10 11 TODO: support for multiple virtual card per device is 12 not implemented yet - there is only one per device; 13 apart from additional device names, we need proper 14 management of graphics mem to not interfere. 15 */ 16 17 #include "dac_regs.h" 18 #include "tv_out_regs.h" 19 #include "fp_regs.h" 20 #include "mmio.h" 21 #include "radeon_driver.h" 22 23 #include <PCI.h> 24 25 #include <stdio.h> 26 #include <string.h> 27 28 // helper macros for easier PCI access 29 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s)) 30 #define set_pci(o, s, v) (*pci_bus->write_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s), (v)) 31 32 extern radeon_settings current_settings; 33 34 // map frame buffer and registers 35 // mmio_only - true = map registers only (used during detection) 36 status_t Radeon_MapDevice( device_info *di, bool mmio_only ) 37 { 38 // framebuffer is stored in PCI range 0, 39 // register map in PCI range 2 40 int regs = 2; 41 int fb = 0; 42 char buffer[100]; 43 shared_info *si = di->si; 44 uint32 tmp; 45 pci_info *pcii = &(di->pcii); 46 status_t result; 47 48 SHOW_FLOW( 3, "device: %02X%02X%02X", 49 di->pcii.bus, di->pcii.device, di->pcii.function ); 50 51 si->ROM_area = si->regs_area = si->memory[mt_local].area = 0; 52 53 // enable memory mapped IO and frame buffer 54 // also, enable bus mastering (some BIOSes seem to 55 // disable that, like mine) 56 tmp = get_pci( PCI_command, 2 ); 57 SHOW_FLOW( 3, "old PCI command state: 0x%08" B_PRIx32, tmp ); 58 tmp |= PCI_command_io | PCI_command_memory | PCI_command_master; 59 set_pci( PCI_command, 2, tmp ); 60 61 // registers cannot be accessed directly by user apps, 62 // they need to clone area for safety reasons 63 SHOW_INFO( 1, 64 "physical address of memory-mapped I/O: 0x%8" B_PRIx32 "-0x%8" B_PRIx32, 65 di->pcii.u.h0.base_registers[regs], 66 di->pcii.u.h0.base_registers[regs] + di->pcii.u.h0.base_register_sizes[regs] - 1 ); 67 68 sprintf( buffer, "%04X_%04X_%02X%02X%02X regs", 69 di->pcii.vendor_id, di->pcii.device_id, 70 di->pcii.bus, di->pcii.device, di->pcii.function ); 71 72 si->regs_area = map_physical_memory( 73 buffer, 74 di->pcii.u.h0.base_registers[regs], 75 di->pcii.u.h0.base_register_sizes[regs], 76 B_ANY_KERNEL_ADDRESS, 77 /*// for "poke" debugging 78 B_READ_AREA + B_WRITE_AREA*/ 79 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA, 80 (void **)&(di->regs)); 81 if( si->regs_area < 0 ) 82 return si->regs_area; 83 84 // that's all during detection as we have no clue about ROM or 85 // frame buffer at this point 86 if( mmio_only ) 87 return B_OK; 88 89 // ROM must be explicetely mapped by applications too 90 sprintf( buffer, "%04X_%04X_%02X%02X%02X ROM", 91 di->pcii.vendor_id, di->pcii.device_id, 92 di->pcii.bus, di->pcii.device, di->pcii.function ); 93 94 si->ROM_area = map_physical_memory( 95 buffer, 96 di->rom.phys_address, 97 di->rom.size, 98 B_ANY_KERNEL_ADDRESS, 99 0, 100 (void **)&(di->rom.rom_ptr)); 101 if( si->ROM_area < 0 ) { 102 result = si->ROM_area; 103 goto err2; 104 } 105 106 if( di->pcii.u.h0.base_register_sizes[fb] > di->local_mem_size ) { 107 // Radeons allocate more address range then really needed -> 108 // only map the area that contains physical memory 109 SHOW_INFO( 1, 110 "restrict frame buffer from 0x%8" B_PRIx32 111 " to 0x%8" B_PRIx32 " bytes", 112 di->pcii.u.h0.base_register_sizes[fb], 113 di->local_mem_size 114 ); 115 di->pcii.u.h0.base_register_sizes[fb] = di->local_mem_size; 116 } 117 118 // framebuffer can be accessed by everyone 119 // this is not a perfect solution; preferably, only 120 // those areas owned by an application are mapped into 121 // its address space 122 // (this hack is needed by BeOS to write something onto screen in KDL) 123 SHOW_INFO( 1, 124 "physical address of framebuffer: 0x%8" B_PRIx32 "-0x%8" B_PRIx32, 125 di->pcii.u.h0.base_registers[fb], 126 di->pcii.u.h0.base_registers[fb] + di->pcii.u.h0.base_register_sizes[fb] - 1 ); 127 128 sprintf(buffer, "%04X_%04X_%02X%02X%02X framebuffer", 129 di->pcii.vendor_id, di->pcii.device_id, 130 di->pcii.bus, di->pcii.device, di->pcii.function); 131 132 si->memory[mt_local].area = map_physical_memory( 133 buffer, 134 di->pcii.u.h0.base_registers[fb], 135 di->pcii.u.h0.base_register_sizes[fb], 136 B_ANY_KERNEL_BLOCK_ADDRESS | B_WRITE_COMBINING_MEMORY, 137 B_READ_AREA | B_WRITE_AREA | B_CLONEABLE_AREA, 138 (void **)&(si->local_mem)); 139 140 if( si->memory[mt_local].area < 0 ) { 141 SHOW_FLOW0( 3, "couldn't enable WC for frame buffer" ); 142 si->memory[mt_local].area = map_physical_memory( 143 buffer, 144 di->pcii.u.h0.base_registers[fb], 145 di->pcii.u.h0.base_register_sizes[fb], 146 B_ANY_KERNEL_BLOCK_ADDRESS, 147 B_READ_AREA | B_WRITE_AREA | B_CLONEABLE_AREA, 148 (void **)&(si->local_mem)); 149 } 150 151 SHOW_FLOW( 3, "mapped frame buffer @%p", si->local_mem ); 152 153 if( si->memory[mt_local].area < 0 ) { 154 result = si->memory[mt_local].area; 155 goto err; 156 } 157 158 // save physical address though noone can probably make 159 // any use of it 160 si->framebuffer_pci = (void *) di->pcii.u.h0.base_registers_pci[fb]; 161 162 return B_OK; 163 164 err: 165 delete_area( si->ROM_area ); 166 err2: 167 delete_area( si->regs_area ); 168 return result; 169 } 170 171 172 // unmap PCI ranges 173 void Radeon_UnmapDevice(device_info *di) 174 { 175 shared_info *si = di->si; 176 pci_info *pcii = &(di->pcii); 177 uint32 tmp; 178 179 SHOW_FLOW0( 3, "" ); 180 181 // disable PCI ranges (though it probably won't 182 // hurt leaving them enabled) 183 tmp = get_pci( PCI_command, 2 ); 184 tmp &= ~PCI_command_io | PCI_command_memory | PCI_command_master; 185 set_pci( PCI_command, 2, tmp ); 186 187 if( si->regs_area > 0 ) 188 delete_area( si->regs_area ); 189 190 if( si->ROM_area > 0 ) 191 delete_area( si->ROM_area ); 192 193 if( si->memory[mt_local].area > 0 ) 194 delete_area( si->memory[mt_local].area ); 195 196 si->regs_area = si->ROM_area = si->memory[mt_local].area = 0; 197 } 198 199 200 // initialize shared infos on first open 201 status_t Radeon_FirstOpen( device_info *di ) 202 { 203 status_t result; 204 char buffer[100]; // B_OS_NAME_LENGTH is too short 205 shared_info *si; 206 //uint32 /*dma_block, */dma_offset; 207 208 // create shared info; don't allow access by apps - 209 // they'll clone it 210 sprintf( buffer, "%04X_%04X_%02X%02X%02X shared", 211 di->pcii.vendor_id, di->pcii.device_id, 212 di->pcii.bus, di->pcii.device, di->pcii.function ); 213 214 di->shared_area = create_area( 215 buffer, 216 (void **)&(di->si), 217 B_ANY_KERNEL_ADDRESS, 218 (sizeof(shared_info) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1), 219 B_FULL_LOCK, 220 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA); 221 if (di->shared_area < 0) { 222 result = di->shared_area; 223 goto err8; 224 } 225 226 memset( di->si, 0, sizeof( *di->si )); 227 228 si = di->si; 229 230 si->settings = di->settings = current_settings; 231 232 if (di->settings.force_acc_dma) 233 di->acc_dma = true; 234 if (di->settings.force_acc_mmio) // force mmio will override dma... a tristate fuzzylogic, grey bool would be nice... 235 di->acc_dma = false; 236 237 #ifdef ENABLE_LOGGING 238 #ifdef LOG_INCLUDE_STARTUP 239 si->log = log_init( 1000000 ); 240 #endif 241 #endif 242 243 // copy all info into shared info 244 si->vendor_id = di->pcii.vendor_id; 245 si->device_id = di->pcii.device_id; 246 si->revision = di->pcii.revision; 247 248 si->asic = di->asic; 249 si->is_mobility = di->is_mobility; 250 si->tv_chip = di->tv_chip; 251 si->new_pll = di->new_pll; 252 si->is_igp = di->is_igp; 253 si->has_no_i2c = di->has_no_i2c; 254 si->is_atombios = di->is_atombios; 255 si->is_mobility = di->is_mobility; 256 si->panel_pwr_delay = di->si->panel_pwr_delay; 257 si->acc_dma = di->acc_dma; 258 259 memcpy(&si->routing, &di->routing, sizeof(disp_entity)); 260 261 // detecting theatre channel in kernel would lead to code duplication, 262 // so we let the first accelerant take care of it 263 si->theatre_channel = -1; 264 265 si->crtc[0].crtc_idx = 0; 266 si->crtc[0].flatpanel_port = 0; 267 si->crtc[1].crtc_idx = 1; 268 si->crtc[1].flatpanel_port = 1; 269 si->num_crtc = di->num_crtc; 270 271 if (di->is_mobility) 272 si->flatpanels[0] = di->fp_info; 273 274 si->pll = di->pll; 275 276 // create virtual card info; don't allow access by apps - 277 // they'll clone it 278 sprintf( buffer, "%04X_%04X_%02X%02X%02X virtual card 0", 279 di->pcii.vendor_id, di->pcii.device_id, 280 di->pcii.bus, di->pcii.device, di->pcii.function ); 281 di->virtual_card_area = create_area( 282 buffer, 283 (void **)&(di->vc), 284 B_ANY_KERNEL_ADDRESS, 285 (sizeof(virtual_card) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1), 286 B_FULL_LOCK, 287 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_CLONEABLE_AREA); 288 if (di->virtual_card_area < 0) { 289 result = di->virtual_card_area; 290 goto err7; 291 } 292 293 // currently, we assign fixed ports to this virtual card 294 di->vc->assigned_crtc[0] = true; 295 di->vc->assigned_crtc[1] = si->num_crtc > 1; 296 di->vc->controlled_displays = 297 dd_tv_crt | dd_crt | dd_lvds | dd_dvi | dd_dvi_ext | dd_ctv | dd_stv; 298 299 di->vc->fb_mem_handle = 0; 300 di->vc->cursor.mem_handle = 0; 301 302 // create unique id 303 di->vc->id = di->virtual_card_area; 304 305 result = Radeon_MapDevice( di, false ); 306 if (result < 0) 307 goto err6; 308 309 // save dac2_cntl register 310 // on M6, we need to restore that during uninit, else you only get 311 // garbage on screen on reboot if both CRTCs are used 312 if( di->asic == rt_rv100 && di->is_mobility) 313 di->dac2_cntl = INREG( di->regs, RADEON_DAC_CNTL2 ); 314 315 memcpy(&si->tmds_pll, &di->tmds_pll, sizeof(di->tmds_pll)); 316 si->tmds_pll_cntl = INREG( di->regs, RADEON_TMDS_PLL_CNTL); 317 si->tmds_transmitter_cntl = INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL); 318 319 // print these out to capture bios status... 320 // if ( di->is_mobility ) { 321 SHOW_INFO0( 2, "Copy of Laptop Display Regs for Reference:"); 322 SHOW_INFO( 2, "LVDS GEN = %8" B_PRIx32, 323 INREG( di->regs, RADEON_LVDS_GEN_CNTL )); 324 SHOW_INFO( 2, "LVDS PLL = %8" B_PRIx32, 325 INREG( di->regs, RADEON_LVDS_PLL_CNTL )); 326 SHOW_INFO( 2, "TMDS PLL = %8" B_PRIx32, 327 INREG( di->regs, RADEON_TMDS_PLL_CNTL )); 328 SHOW_INFO( 2, "TMDS TRANS = %8" B_PRIx32, 329 INREG( di->regs, RADEON_TMDS_TRANSMITTER_CNTL )); 330 SHOW_INFO( 2, "FP1 GEN = %8" B_PRIx32, 331 INREG( di->regs, RADEON_FP_GEN_CNTL )); 332 SHOW_INFO( 2, "FP2 GEN = %8" B_PRIx32 , 333 INREG( di->regs, RADEON_FP2_GEN_CNTL )); 334 SHOW_INFO( 2, "TV DAC = %8" B_PRIx32 , 335 INREG( di->regs, RADEON_TV_DAC_CNTL )); //not setup right when ext dvi 336 // } 337 338 result = Radeon_InitPCIGART( di ); 339 if( result < 0 ) 340 goto err5; 341 342 si->memory[mt_local].size = di->local_mem_size; 343 344 si->memory[mt_PCI].area = di->pci_gart.buffer.area; 345 si->memory[mt_PCI].size = di->pci_gart.buffer.size; 346 347 // currently, defaultnon-local memory is PCI memory 348 si->nonlocal_type = mt_PCI; 349 350 Radeon_InitMemController( di ); 351 352 // currently, we don't support VBI - something is broken there 353 // (it doesn't change a thing apart from crashing) 354 result = Radeon_SetupIRQ( di, buffer ); 355 if( result < 0 ) 356 goto err4; 357 358 // resolution of 2D register is 1K, resolution of CRTC etc. is higher, 359 // so 1K is the minimum block size; 360 // (CP cannot use local mem) 361 di->memmgr[mt_local] = mem_init("radeon local memory", 0, di->local_mem_size, 1024, 362 di->local_mem_size / 1024); 363 if (di->memmgr[mt_local] == NULL) { 364 result = B_NO_MEMORY; 365 goto err3; 366 } 367 368 // CP requires 4K alignment, which is the most restrictive I found 369 di->memmgr[mt_PCI] = mem_init("radeon PCI GART memory", 0, di->pci_gart.buffer.size, 4096, 370 di->pci_gart.buffer.size / 4096); 371 if (di->memmgr[mt_PCI] == NULL) { 372 result = B_NO_MEMORY; 373 goto err2; 374 } 375 376 // no AGP support 377 di->memmgr[mt_AGP] = NULL; 378 379 // fix AGP settings for IGP chipset 380 Radeon_Set_AGP( di, !di->settings.force_pci ); // disable AGP 381 382 383 // time to init Command Processor 384 result = Radeon_InitCP( di ); 385 if( result != B_OK ) 386 goto err; 387 388 if ( di->acc_dma ) 389 { 390 result = Radeon_InitDMA( di ); 391 if( result != B_OK ) 392 goto err0; 393 } 394 else 395 { 396 SHOW_INFO0( 0, "DMA is diabled using PIO mode"); 397 } 398 399 // mem_alloc( di->local_memmgr, 0x100000, (void *)-1, &dma_block, &dma_offset ); 400 /* dma_offset = 15 * 1024 * 1024; 401 402 si->nonlocal_mem = (uint32 *)((uint32)si->framebuffer + dma_offset); 403 si->nonlocal_vm_start = (uint32)si->framebuffer_pci + dma_offset;*/ 404 405 // set dynamic clocks for Mobilty chips 406 if (di->is_mobility && di->settings.dynamic_clocks) 407 Radeon_SetDynamicClock( di, 1); 408 409 return B_OK; 410 411 err0: 412 Radeon_UninitCP( di ); 413 err: 414 mem_destroy( di->memmgr[mt_PCI] ); 415 err2: 416 mem_destroy( di->memmgr[mt_local] ); 417 err3: 418 Radeon_CleanupIRQ( di ); 419 err4: 420 Radeon_CleanupPCIGART( di ); 421 err5: 422 Radeon_UnmapDevice( di ); 423 err6: 424 delete_area( di->virtual_card_area ); 425 err7: 426 delete_area( di->shared_area ); 427 err8: 428 return result; 429 } 430 431 // clean up shared info on last close 432 // (we could for device destruction, but this makes 433 // testing easier as everythings gets cleaned up 434 // during tests) 435 void Radeon_LastClose( device_info *di ) 436 { 437 if ( di->acc_dma ) 438 Radeon_UninitCP( di ); 439 440 // M6 fix - unfortunately, the device is never closed by app_server, 441 // not even before reboot 442 if( di->asic == rt_rv100 && di->is_mobility) 443 OUTREG( di->regs, RADEON_DAC_CNTL2, di->dac2_cntl ); 444 445 446 mem_destroy( di->memmgr[mt_local] ); 447 448 if( di->memmgr[mt_PCI] ) 449 mem_destroy( di->memmgr[mt_PCI] ); 450 451 if( di->memmgr[mt_AGP] ) 452 mem_destroy( di->memmgr[mt_AGP] ); 453 454 Radeon_CleanupIRQ( di ); 455 Radeon_CleanupPCIGART( di ); 456 Radeon_UnmapDevice(di); 457 458 #ifdef ENABLE_LOGGING 459 #ifdef LOG_INCLUDE_STARTUP 460 log_exit( di->si->log ); 461 #endif 462 #endif 463 464 delete_area( di->virtual_card_area ); 465 delete_area( di->shared_area ); 466 } 467