1 /* 2 Copyright (c) 2002, Thomas Kurschel 3 4 5 Part of Radeon accelerant 6 7 Main init/uninit functions 8 */ 9 10 11 #include "GlobalData.h" 12 #include "generic.h" 13 14 #include "string.h" 15 #include "unistd.h" 16 #include "sys/types.h" 17 #include "sys/stat.h" 18 #include "fcntl.h" 19 #include <sys/ioctl.h> 20 #include <malloc.h> 21 #include "CP.h" 22 23 24 // init data used by both primary and cloned accelerant 25 // the_fd - file descriptor of kernel driver 26 // accelerant_is_clone - if true, this is a cloned accelerant 27 static status_t init_common( int the_fd, bool accelerant_is_clone ) 28 { 29 status_t result; 30 radeon_get_private_data gpd; 31 32 SHOW_FLOW0( 3, "" ); 33 34 ai = malloc( sizeof( *ai )); 35 if( ai == NULL ) 36 return B_NO_MEMORY; 37 38 memset( ai, 0, sizeof( *ai )); 39 40 ai->accelerant_is_clone = accelerant_is_clone; 41 ai->fd = the_fd; 42 43 // get basic info from driver 44 gpd.magic = RADEON_PRIVATE_DATA_MAGIC; 45 46 result = ioctl( ai->fd, RADEON_GET_PRIVATE_DATA, &gpd, sizeof(gpd) ); 47 if (result != B_OK) goto err; 48 49 ai->virtual_card_area = clone_area( "Radeon virtual card", (void **)&ai->vc, B_ANY_ADDRESS, 50 B_READ_AREA | B_WRITE_AREA, gpd.virtual_card_area ); 51 if( ai->virtual_card_area < 0 ) { 52 result = ai->virtual_card_area; 53 goto err; 54 } 55 ai->shared_info_area = clone_area( "Radeon shared info", (void **)&ai->si, B_ANY_ADDRESS, 56 B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area ); 57 if( ai->shared_info_area < 0 ) { 58 result = ai->shared_info_area; 59 goto err2; 60 } 61 62 ai->regs_area = clone_area( "Radeon regs area", (void **)&ai->regs, B_ANY_ADDRESS, 63 B_READ_AREA | B_WRITE_AREA, ai->si->regs_area ); 64 if( ai->regs_area < 0 ) { 65 result = ai->regs_area; 66 goto err3; 67 } 68 69 //rud: 70 if( ai->si->memory[mt_PCI].area > 0 ) { 71 ai->mapped_memory[mt_PCI].area = clone_area( "Radeon PCI GART area", 72 (void **)&ai->mapped_memory[mt_PCI].data, B_ANY_ADDRESS, 73 B_READ_AREA | B_WRITE_AREA, ai->si->memory[mt_PCI].area ); 74 if( ai->mapped_memory[mt_PCI].area < 0 ) { 75 result = ai->mapped_memory[mt_PCI].area; 76 goto err4; 77 } 78 } 79 80 if( ai->si->memory[mt_AGP].area > 0 ) { 81 ai->mapped_memory[mt_AGP].area = clone_area( "Radeon AGP GART area", 82 (void **)&ai->mapped_memory[mt_AGP].data, B_ANY_ADDRESS, 83 B_READ_AREA | B_WRITE_AREA, ai->si->memory[mt_PCI].area ); 84 if( ai->mapped_memory[mt_AGP].area < 0 ) { 85 result = ai->mapped_memory[mt_AGP].area; 86 goto err5; 87 } 88 } 89 90 ai->mapped_memory[mt_nonlocal] = ai->mapped_memory[ai->si->nonlocal_type]; 91 ai->mapped_memory[mt_local].data = ai->si->local_mem; 92 93 return B_OK; 94 95 err5: 96 if( ai->mapped_memory[mt_PCI].area > 0 ) 97 delete_area( ai->mapped_memory[mt_PCI].area ); 98 err4: 99 delete_area( ai->regs_area ); 100 err3: 101 delete_area( ai->shared_info_area ); 102 err2: 103 delete_area( ai->virtual_card_area ); 104 err: 105 free( ai ); 106 return result; 107 } 108 109 // clean up data common to both primary and cloned accelerant 110 static void uninit_common( void ) 111 { 112 if( !ai->accelerant_is_clone ) { 113 Radeon_FreeVirtualCardStateBuffer( ai ); 114 115 // the last accelerant should must wait for the card to become quite, 116 // else some nasty command could lunger in some FIFO 117 Radeon_WaitForIdle( ai, false ); 118 } 119 120 if( ai->mapped_memory[mt_AGP].area > 0 ) 121 delete_area( ai->mapped_memory[mt_AGP].area ); 122 if( ai->mapped_memory[mt_PCI].area > 0 ) 123 delete_area( ai->mapped_memory[mt_PCI].area ); 124 delete_area( ai->regs_area ); 125 delete_area( ai->shared_info_area ); 126 delete_area( ai->virtual_card_area ); 127 128 ai->regs_area = ai->shared_info_area = ai->virtual_card_area = 0; 129 130 ai->regs = 0; 131 ai->si = 0; 132 ai->vc = 0; 133 134 // close the file handle ONLY if we're the clone 135 // (this is what Be tells us ;) 136 if( ai->accelerant_is_clone ) 137 close( ai->fd ); 138 139 free( ai ); 140 } 141 142 // public function: init primary accelerant 143 // the_fd - file handle of kernel driver 144 status_t INIT_ACCELERANT( int the_fd ) 145 { 146 shared_info *si; 147 virtual_card *vc; 148 status_t result; 149 150 SHOW_FLOW0( 3, "" ); 151 152 result = init_common( the_fd, 0 ); 153 if (result != B_OK) 154 goto err; 155 156 si = ai->si; 157 vc = ai->vc; 158 159 // init Command Processor 160 /*result = Radeon_InitCP( ai ); 161 if( result != B_OK ) 162 goto err2;*/ 163 164 // this isn't the best place, but has to be done sometime 165 Radeon_ReadSettings( vc ); 166 167 // establish connection to TV-Out unit 168 Radeon_DetectTVOut( ai ); 169 170 // get all possible information about connected display devices 171 Radeon_DetectDisplays( ai ); 172 173 // create list of supported modes 174 result = Radeon_CreateModeList( si ); 175 if (result != B_OK) 176 goto err3; 177 178 /* init the shared semaphore */ 179 (void)INIT_BEN( si->engine.lock, "Radeon engine" ); 180 181 // init engine sync token 182 // (count of issued parameters or commands) 183 si->engine.last_idle = si->engine.count = 0; 184 // set last written count to be very old, so it must be written on first use 185 // (see writeSyncToken) 186 si->engine.written = -1; 187 188 // init overlay 189 si->overlay_mgr.token = 0; 190 si->overlay_mgr.inuse = 0; 191 192 // mark overlay as inactive 193 si->active_overlay.crtc_idx = -1; 194 si->pending_overlay.crtc_idx = -1; 195 196 // reset list of allocated overlays 197 vc->overlay_buffers = NULL; 198 199 // mark engine as having no state 200 //si->cp.active_state_buffer = -1; 201 202 Radeon_AllocateVirtualCardStateBuffer( ai ); 203 204 // everything else is initialized upon set_display_mode 205 return B_OK; 206 207 err3: 208 //err2: 209 uninit_common(); 210 err: 211 return result; 212 } 213 214 215 // public function: return size of clone info 216 ssize_t ACCELERANT_CLONE_INFO_SIZE( void ) 217 { 218 SHOW_FLOW0( 0, "" ); 219 220 // clone info is device name, so return its maximum size 221 return MAX_RADEON_DEVICE_NAME_LENGTH; 222 } 223 224 225 // public function: return clone info 226 // data - buffer to contain info (allocated by caller) 227 void GET_ACCELERANT_CLONE_INFO( void *data ) 228 { 229 radeon_device_name dn; 230 status_t result; 231 232 SHOW_FLOW0( 0, "" ); 233 234 // clone info is device name - ask device driver 235 dn.magic = RADEON_PRIVATE_DATA_MAGIC; 236 dn.name = (char *)data; 237 238 result = ioctl( ai->fd, RADEON_DEVICE_NAME, &dn, sizeof(dn) ); 239 } 240 241 // public function: init cloned accelerant 242 // data - clone info from get_accelerant_clone_info 243 status_t CLONE_ACCELERANT( void *data ) 244 { 245 status_t result; 246 char path[MAXPATHLEN]; 247 int fd; 248 249 SHOW_FLOW0( 0, "" ); 250 251 // create full device name 252 strcpy(path, "/dev/"); 253 strcat(path, (const char *)data); 254 255 // open device; according to Be, permissions aren't important 256 // this will probably change once access right are checked properly 257 fd = open(path, B_READ_WRITE); 258 if( fd < 0 ) 259 return fd; 260 261 result = init_common( fd, 1 ); 262 if( result != B_OK ) 263 goto err1; 264 265 // get (cloned) copy of supported display modes 266 result = ai->mode_list_area = clone_area( 267 "Radeon cloned display_modes", (void **)&ai->mode_list, 268 B_ANY_ADDRESS, B_READ_AREA, ai->si->mode_list_area ); 269 if (result < B_OK) 270 goto err2; 271 272 return B_OK; 273 274 err2: 275 uninit_common(); 276 err1: 277 close( fd ); 278 return result; 279 } 280 281 // public function: uninit primary or cloned accelerant 282 void UNINIT_ACCELERANT( void ) 283 { 284 // TBD: 285 // we should put accelerator into stable state first - 286 // on my Laptop, you never can boot Windows/Linux after shutting 287 // down BeOS; if both ports have been used, even the BIOS screen 288 // is completely messed up 289 290 SHOW_FLOW0( 0, "" ); 291 292 // cloned accelerants have mode_list cloned, so deleting is OK 293 // primary accelerant owns mode list, so deleting is OK as well 294 delete_area( ai->mode_list_area ); 295 ai->mode_list = 0; 296 297 uninit_common(); 298 } 299 300 // public function: get some info about graphics card 301 status_t GET_ACCELERANT_DEVICE_INFO( accelerant_device_info *di ) 302 { 303 SHOW_FLOW0( 0, "" ); 304 305 // is there anyone using it? 306 307 // TBD: everything apart from memsize 308 di->version = B_ACCELERANT_VERSION; 309 strcpy( di->name, "Radeon" ); 310 strcpy( di->chipset, "Radeon" ); 311 strcpy( di->serial_no, "None" ); 312 313 di->memory = ai->si->memory[mt_local].size; 314 315 // TBD: is max PLL speed really equal to max DAC speed? 316 di->dac_speed = ai->si->pll.max_pll_freq; 317 318 return B_OK; 319 } 320