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 22 23 // init data used by both primary and cloned accelerant 24 // the_fd - file descriptor of kernel driver 25 // accelerant_is_clone - if true, this is a cloned accelerant 26 static status_t init_common( int the_fd, bool accelerant_is_clone ) 27 { 28 status_t result; 29 radeon_get_private_data gpd; 30 31 SHOW_FLOW0( 3, "" ); 32 33 ai = malloc( sizeof( *ai )); 34 if( ai == NULL ) 35 return B_NO_MEMORY; 36 37 memset( ai, 0, sizeof( *ai )); 38 39 ai->accelerant_is_clone = accelerant_is_clone; 40 ai->fd = the_fd; 41 42 // get basic info from driver 43 gpd.magic = RADEON_PRIVATE_DATA_MAGIC; 44 45 result = ioctl( ai->fd, RADEON_GET_PRIVATE_DATA, &gpd, sizeof(gpd) ); 46 if (result != B_OK) goto err; 47 48 ai->virtual_card_area = clone_area( "Radeon virtual card", (void **)&ai->vc, B_ANY_ADDRESS, 49 B_READ_AREA | B_WRITE_AREA, gpd.virtual_card_area ); 50 if( ai->virtual_card_area < 0 ) { 51 result = ai->virtual_card_area; 52 goto err; 53 } 54 ai->shared_info_area = clone_area("Radeon shared info", (void **)&ai->si, B_ANY_ADDRESS, 55 B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area); 56 if( ai->shared_info_area < 0 ) { 57 result = ai->shared_info_area; 58 goto err2; 59 } 60 61 ai->regs_area = clone_area("Radeon regs area", (void **)&ai->regs, B_ANY_ADDRESS, 62 B_READ_AREA | B_WRITE_AREA, ai->si->regs_area); 63 if( ai->regs_area < 0 ) { 64 result = ai->regs_area; 65 goto err3; 66 } 67 68 return B_OK; 69 70 err3: 71 delete_area( ai->shared_info_area ); 72 err2: 73 delete_area( ai->virtual_card_area ); 74 err: 75 free( ai ); 76 return result; 77 } 78 79 // clean up data common to both primary and cloned accelerant 80 static void uninit_common( void ) 81 { 82 delete_area( ai->regs_area ); 83 delete_area( ai->shared_info_area ); 84 delete_area( ai->virtual_card_area ); 85 86 ai->regs_area = ai->shared_info_area = ai->virtual_card_area = 0; 87 88 ai->regs = 0; 89 ai->si = 0; 90 ai->vc = 0; 91 92 // close the file handle ONLY if we're the clone 93 // (this is what Be tells us ;) 94 if( ai->accelerant_is_clone ) 95 close( ai->fd ); 96 97 free( ai ); 98 } 99 100 // public function: init primary accelerant 101 // the_fd - file handle of kernel driver 102 status_t INIT_ACCELERANT( int the_fd ) 103 { 104 shared_info *si; 105 virtual_card *vc; 106 status_t result; 107 108 SHOW_FLOW0( 3, "" ); 109 110 result = init_common( the_fd, 0 ); 111 if (result != B_OK) 112 goto err; 113 114 si = ai->si; 115 vc = ai->vc; 116 117 // init Command Processor 118 result = Radeon_InitCP( ai ); 119 if( result != B_OK ) 120 goto err2; 121 122 // this isn't the best place, but has to be done sometime 123 Radeon_ReadSettings( vc ); 124 125 // read FP info via DDC 126 // (ignore result - if it fails we fall back to BIOS detection) 127 if( si->fp_port.disp_type == dt_dvi_1 ) 128 Radeon_ReadFPEDID( ai, si ); 129 130 // create list of supported modes 131 result = Radeon_CreateModeList( si ); 132 if (result != B_OK) 133 goto err3; 134 135 /* init the shared semaphore */ 136 INIT_BEN( "Radeon engine", si->engine.lock ); 137 138 // init engine sync token 139 // (count of issued parameters or commands) 140 si->engine.last_idle = si->engine.count = 0; 141 // set last written count to be very old, so it must be written on first use 142 // (see writeSyncToken) 143 si->engine.written = -1; 144 145 // init overlay 146 si->overlay_mgr.token = 0; 147 si->overlay_mgr.inuse = 0; 148 149 // mark overlay as inactive 150 si->active_overlay.port = -1; 151 si->pending_overlay.port = -1; 152 153 // reset list of allocated overlays 154 vc->overlay_buffers = NULL; 155 156 // everything else is initialized upon set_display_mode 157 return B_OK; 158 159 err3: 160 err2: 161 uninit_common(); 162 err: 163 return result; 164 } 165 166 167 // public function: return size of clone info 168 ssize_t ACCELERANT_CLONE_INFO_SIZE( void ) 169 { 170 // clone info is device name, so return its maximum size 171 return MAX_RADEON_DEVICE_NAME_LENGTH; 172 } 173 174 175 // public function: return clone info 176 // data - buffer to contain info (allocated by caller) 177 void GET_ACCELERANT_CLONE_INFO( void *data ) 178 { 179 radeon_device_name dn; 180 status_t result; 181 182 // clone info is device name - ask device driver 183 dn.magic = RADEON_PRIVATE_DATA_MAGIC; 184 dn.name = (char *)data; 185 186 result = ioctl( ai->fd, RADEON_DEVICE_NAME, &dn, sizeof(dn) ); 187 } 188 189 // public function: init cloned accelerant 190 // data - clone info from get_accelerant_clone_info 191 status_t CLONE_ACCELERANT( void *data ) 192 { 193 status_t result; 194 char path[MAXPATHLEN]; 195 int fd; 196 197 // create full device name 198 strcpy(path, "/dev/");//added trailing '/', this fixes cloning accelerant! 199 strcat(path, (const char *)data); 200 201 // open device; according to Be, permissions aren't important 202 // this will probably change once access right are checked properly 203 fd = open(path, B_READ_WRITE); 204 if( fd < 0 ) 205 return fd; 206 207 result = init_common( fd, 1 ); 208 if( result != B_OK ) 209 goto err1; 210 211 // get (cloned) copy of supported display modes 212 result = ai->mode_list_area = clone_area( 213 "Radeon cloned display_modes", (void **)&ai->mode_list, 214 B_ANY_ADDRESS, B_READ_AREA, ai->si->mode_list_area ); 215 if (result < B_OK) 216 goto err2; 217 218 return B_OK; 219 220 err2: 221 uninit_common(); 222 err1: 223 close( fd ); 224 return result; 225 } 226 227 // public function: uninit primary or cloned accelerant 228 void UNINIT_ACCELERANT( void ) 229 { 230 // TBD: 231 // we should put accelerator into stable state first - 232 // on my Laptop, you never can boot Windows/Linux after shutting 233 // down BeOS; if both ports have been used, even the BIOS screen 234 // is completely messed up 235 236 // cloned accelerants have mode_list cloned, so deleting is OK 237 // primary accelerant owns mode list, so deleting is OK as well 238 delete_area( ai->mode_list_area ); 239 ai->mode_list = 0; 240 241 uninit_common(); 242 } 243 244 // public function: get some info about graphics card 245 status_t GET_ACCELERANT_DEVICE_INFO( accelerant_device_info *di ) 246 { 247 // is there anyone using it? 248 249 // TBD: everything apart from memsize 250 di->version = B_ACCELERANT_VERSION; 251 strcpy( di->name, "Radeon" ); 252 strcpy( di->chipset, "Radeon" ); 253 strcpy( di->serial_no, "None" ); 254 255 di->memory = ai->si->local_mem_size; 256 257 // TBD: is max PLL speed really equal to max DAC speed? 258 di->dac_speed = ai->si->pll.max_pll_freq; 259 260 return B_OK; 261 } 262