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