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