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