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 if ( ai->si->acc_dma ) 115 Radeon_FreeVirtualCardStateBuffer( ai ); 116 117 // the last accelerant should must wait for the card to become quite, 118 // else some nasty command could lunger in some FIFO 119 Radeon_WaitForIdle( ai, false ); 120 } 121 122 if( ai->mapped_memory[mt_AGP].area > 0 ) 123 delete_area( ai->mapped_memory[mt_AGP].area ); 124 if( ai->mapped_memory[mt_PCI].area > 0 ) 125 delete_area( ai->mapped_memory[mt_PCI].area ); 126 delete_area( ai->regs_area ); 127 delete_area( ai->shared_info_area ); 128 delete_area( ai->virtual_card_area ); 129 130 ai->regs_area = ai->shared_info_area = ai->virtual_card_area = 0; 131 132 ai->regs = 0; 133 ai->si = 0; 134 ai->vc = 0; 135 136 // close the file handle ONLY if we're the clone 137 // (this is what Be tells us ;) 138 if( ai->accelerant_is_clone ) 139 close( ai->fd ); 140 141 free( ai ); 142 } 143 144 // public function: init primary accelerant 145 // the_fd - file handle of kernel driver 146 status_t INIT_ACCELERANT( int the_fd ) 147 { 148 shared_info *si; 149 virtual_card *vc; 150 status_t result; 151 152 SHOW_FLOW0( 3, "" ); 153 154 result = init_common( the_fd, 0 ); 155 if (result != B_OK) 156 goto err; 157 158 si = ai->si; 159 vc = ai->vc; 160 161 // init Command Processor 162 /*result = Radeon_InitCP( ai ); 163 if( result != B_OK ) 164 goto err2;*/ 165 166 // this isn't the best place, but has to be done sometime 167 Radeon_ReadSettings( vc ); 168 169 // establish connection to TV-Out unit 170 Radeon_DetectTVOut( ai ); 171 172 // get all possible information about connected display devices 173 Radeon_DetectDisplays( ai ); 174 175 // create list of supported modes 176 result = Radeon_CreateModeList( si ); 177 if (result != B_OK) 178 goto err3; 179 180 /* init the shared semaphore */ 181 (void)INIT_BEN( si->engine.lock, "Radeon engine" ); 182 183 // init engine sync token 184 // (count of issued parameters or commands) 185 si->engine.last_idle = si->engine.count = 0; 186 // set last written count to be very old, so it must be written on first use 187 // (see writeSyncToken) 188 si->engine.written = -1; 189 190 // init overlay 191 si->overlay_mgr.token = 0; 192 si->overlay_mgr.inuse = 0; 193 194 // mark overlay as inactive 195 si->active_overlay.crtc_idx = -1; 196 si->pending_overlay.crtc_idx = -1; 197 198 // reset list of allocated overlays 199 vc->overlay_buffers = NULL; 200 201 // mark engine as having no state 202 //si->cp.active_state_buffer = -1; 203 204 if ( ai->si->acc_dma ) 205 Radeon_AllocateVirtualCardStateBuffer( ai ); 206 207 // everything else is initialized upon set_display_mode 208 return B_OK; 209 210 err3: 211 //err2: 212 uninit_common(); 213 err: 214 return result; 215 } 216 217 218 // public function: return size of clone info 219 ssize_t ACCELERANT_CLONE_INFO_SIZE( void ) 220 { 221 SHOW_FLOW0( 0, "" ); 222 223 // clone info is device name, so return its maximum size 224 return MAX_RADEON_DEVICE_NAME_LENGTH; 225 } 226 227 228 // public function: return clone info 229 // data - buffer to contain info (allocated by caller) 230 void GET_ACCELERANT_CLONE_INFO( void *data ) 231 { 232 radeon_device_name dn; 233 status_t result; 234 235 SHOW_FLOW0( 0, "" ); 236 237 // clone info is device name - ask device driver 238 dn.magic = RADEON_PRIVATE_DATA_MAGIC; 239 dn.name = (char *)data; 240 241 result = ioctl( ai->fd, RADEON_DEVICE_NAME, &dn, sizeof(dn) ); 242 } 243 244 // public function: init cloned accelerant 245 // data - clone info from get_accelerant_clone_info 246 status_t CLONE_ACCELERANT( void *data ) 247 { 248 status_t result; 249 char path[MAXPATHLEN]; 250 int fd; 251 252 SHOW_FLOW0( 0, "" ); 253 254 // create full device name 255 strcpy(path, "/dev/"); 256 strcat(path, (const char *)data); 257 258 // open device; according to Be, permissions aren't important 259 // this will probably change once access right are checked properly 260 fd = open(path, B_READ_WRITE); 261 if( fd < 0 ) 262 return errno; 263 264 result = init_common( fd, 1 ); 265 if( result != B_OK ) 266 goto err1; 267 268 // get (cloned) copy of supported display modes 269 result = ai->mode_list_area = clone_area( 270 "Radeon cloned display_modes", (void **)&ai->mode_list, 271 B_ANY_ADDRESS, B_READ_AREA, ai->si->mode_list_area ); 272 if (result < B_OK) 273 goto err2; 274 275 return B_OK; 276 277 err2: 278 uninit_common(); 279 err1: 280 close( fd ); 281 return result; 282 } 283 284 // public function: uninit primary or cloned accelerant 285 void UNINIT_ACCELERANT( void ) 286 { 287 // TBD: 288 // we should put accelerator into stable state first - 289 // on my Laptop, you never can boot Windows/Linux after shutting 290 // down BeOS; if both ports have been used, even the BIOS screen 291 // is completely messed up 292 293 SHOW_FLOW0( 0, "" ); 294 295 // cloned accelerants have mode_list cloned, so deleting is OK 296 // primary accelerant owns mode list, so deleting is OK as well 297 delete_area( ai->mode_list_area ); 298 ai->mode_list = 0; 299 300 uninit_common(); 301 } 302 303 // public function: get some info about graphics card 304 status_t GET_ACCELERANT_DEVICE_INFO( accelerant_device_info *di ) 305 { 306 SHOW_FLOW0( 0, "" ); 307 308 // is there anyone using it? 309 310 // TBD: everything apart from memsize 311 di->version = B_ACCELERANT_VERSION; 312 strcpy( di->name, "Radeon" ); 313 strcpy( di->chipset, "Radeon" ); 314 strcpy( di->serial_no, "None" ); 315 316 di->memory = ai->si->memory[mt_local].size; 317 318 // TBD: is max PLL speed really equal to max DAC speed? 319 di->dac_speed = ai->si->pll.max_pll_freq; 320 321 return B_OK; 322 } 323