1 /* 2 Copyright (c) 2002, Thomas Kurschel 3 4 5 Part of Radeon kernel driver 6 7 Graphics card detection 8 */ 9 10 11 #include "radeon_driver.h" 12 13 #include <stdio.h> 14 15 16 // this table is gathered from different sources 17 // and may even contain some wrong entries 18 #define VENDOR_ID_ATI 0x1002 19 20 // R100 21 #define DEVICE_ID_RADEON_QD 0x5144 22 #define DEVICE_ID_RADEON_QE 0x5145 23 #define DEVICE_ID_RADEON_QF 0x5146 24 #define DEVICE_ID_RADEON_QG 0x5147 25 26 // RV100 27 #define DEVICE_ID_RADEON_QY 0x5159 28 #define DEVICE_ID_RADEON_QZ 0x515a 29 30 // M6 31 #define DEVICE_ID_RADEON_LY 0x4c59 32 #define DEVICE_ID_RADEON_LZ 0x4c5a 33 34 // RV200 35 #define DEVICE_ID_RADEON_QW 0x5157 36 #define DEVICE_ID_RADEON_QX 0x5158 37 38 // R200 mobility 39 #define DEVICE_ID_RADEON_LW 0x4c57 40 #define DEVICE_ID_RADEON_LX 0x4c58 41 42 // R200 43 #define DEVICE_ID_RADEON_QH 0x5148 44 #define DEVICE_ID_RADEON_QI 0x5149 45 #define DEVICE_ID_RADEON_QJ 0x514a 46 #define DEVICE_ID_RADEON_QK 0x514b 47 #define DEVICE_ID_RADEON_QL 0x514c 48 #define DEVICE_ID_RADEON_QM 0x514d 49 50 #define DEVICE_ID_RADEON_Qh 0x5168 51 #define DEVICE_ID_RADEON_Qi 0x5169 52 #define DEVICE_ID_RADEON_Qj 0x516a 53 #define DEVICE_ID_RADEON_Qk 0x516b 54 55 #define DEVICE_ID_RADEON_BB 0x4242 56 57 // RV250 58 #define DEVICE_ID_RADEON_Id 0x4964 59 #define DEVICE_ID_RADEON_Ie 0x4965 60 #define DEVICE_ID_RADEON_If 0x4966 61 #define DEVICE_ID_RADEON_Ig 0x4967 62 63 // M9 64 #define DEVICE_ID_RADEON_Ld 0x4c64 65 #define DEVICE_ID_RADEON_Le 0x4c65 66 #define DEVICE_ID_RADEON_Lf 0x4c66 67 #define DEVICE_ID_RADEON_Lg 0x4c67 68 69 // RV280 70 #define DEVICE_ID_RADEON_Ya_ 0x5960 71 #define DEVICE_ID_RADEON_Ya 0x5961 72 #define DEVICE_ID_RADEON_Yd 0x5964 73 74 // r300 75 #define DEVICE_ID_RADEON_ND 0x4e44 76 #define DEVICE_ID_RADEON_NE 0x4e45 77 #define DEVICE_ID_RADEON_NF 0x4e46 78 #define DEVICE_ID_RADEON_NG 0x4e47 79 80 // r300-4P 81 #define DEVICE_ID_RADEON_AD 0x4144 82 #define DEVICE_ID_RADEON_AE 0x4145 83 #define DEVICE_ID_RADEON_AF 0x4146 84 #define DEVICE_ID_RADEON_AG 0x4147 85 86 // rv350 87 #define DEVICE_ID_RADEON_AP 0x4150 88 #define DEVICE_ID_RADEON_AQ 0x4151 89 #define DEVICE_ID_RADEON_NO 0x4e50 90 #define DEVICE_ID_RADEON_NS 0x4e54 91 92 // rv360 93 #define DEVICE_ID_RADEON_AR 0x4152 94 95 // r350 96 #define DEVICE_ID_RADEON_AH 0x4148 97 #define DEVICE_ID_RADEON_NH 0x4e48 98 #define DEVICE_ID_RADEON_NI 0x4e49 99 100 // r360 101 #define DEVICE_ID_RADEON_NJ 0x4e4a 102 103 #define DEVICE_ID_IGP320M 0x4336 104 105 typedef struct { 106 uint16 device_id; 107 radeon_type asic; 108 char *name; 109 } RadeonDevice; 110 111 // list of supported devices 112 RadeonDevice radeon_device_list[] = { 113 // original Radeons, now called r100 114 { DEVICE_ID_RADEON_QD, rt_r100, "Radeon 7200 / Radeon / ALL-IN-WONDER Radeon" }, 115 { DEVICE_ID_RADEON_QE, rt_r100, "Radeon QE" }, 116 { DEVICE_ID_RADEON_QF, rt_r100, "Radeon QF" }, 117 { DEVICE_ID_RADEON_QG, rt_r100, "Radeon QG" }, 118 119 // Radeon VE (low-cost, dual CRT, no TCL), now called RV100 120 { DEVICE_ID_RADEON_QY, rt_ve, "Radeon 7000 / Radeon VE" }, 121 { DEVICE_ID_RADEON_QZ, rt_ve, "Radeon QZ VE" }, 122 123 // mobility version of original Radeon (based on VE), now called M6 124 { DEVICE_ID_RADEON_LY, rt_m6, "Radeon Mobility" }, 125 { DEVICE_ID_RADEON_LZ, rt_m6, "Radeon Mobility M6 LZ" }, 126 127 // RV200 (dual CRT) 128 { DEVICE_ID_RADEON_QW, rt_rv200, "Radeon 7500 / ALL-IN-WONDER Radeon 7500" }, 129 { DEVICE_ID_RADEON_QX, rt_rv200, "Radeon 7500 QX" }, 130 131 // R200 mobility (based on RV200) 132 { DEVICE_ID_RADEON_LW, rt_m7, "Radeon Mobility 7500" }, 133 { DEVICE_ID_RADEON_LX, rt_m7, "Radeon Mobility 7500 GL" }, 134 135 // R200 136 { DEVICE_ID_RADEON_QH, rt_r200, "Radeon 8500 QH" }, 137 { DEVICE_ID_RADEON_QI, rt_r200, "Radeon 8500 QI" }, 138 { DEVICE_ID_RADEON_QJ, rt_r200, "Radeon 8500 QJ" }, 139 { DEVICE_ID_RADEON_QK, rt_r200, "Radeon 8500 QK" }, 140 { DEVICE_ID_RADEON_QL, rt_r200, "Radeon 8500 / 8500LE / ALL-IN-WONDER Radeon 8500" }, 141 { DEVICE_ID_RADEON_QM, rt_r200, "Radeon 9100" }, 142 143 { DEVICE_ID_RADEON_Qh, rt_r200, "Radeon 8500 Qh" }, 144 { DEVICE_ID_RADEON_Qi, rt_r200, "Radeon 8500 Qi" }, 145 { DEVICE_ID_RADEON_Qj, rt_r200, "Radeon 8500 Qj" }, 146 { DEVICE_ID_RADEON_Qk, rt_r200, "Radeon 8500 Qk" }, 147 { DEVICE_ID_RADEON_BB, rt_r200, "ALL-IN-Wonder Radeon 8500 DV" }, 148 149 // RV250 (cut-down R200) 150 { DEVICE_ID_RADEON_Id, rt_rv250, "Radeon 9000 Id" }, 151 { DEVICE_ID_RADEON_Ie, rt_rv250, "Radeon 9000 Ie" }, 152 { DEVICE_ID_RADEON_If, rt_rv250, "Radeon 9000" }, 153 { DEVICE_ID_RADEON_Ig, rt_rv250, "Radeon 9000 Ig" }, 154 155 // M9 (based on rv250) 156 { DEVICE_ID_RADEON_Ld, rt_m9, "Radeon Mobility 9000 Ld" }, 157 { DEVICE_ID_RADEON_Le, rt_m9, "Radeon Mobility 9000 Le" }, 158 { DEVICE_ID_RADEON_Lf, rt_m9, "Radeon Mobility 9000 Lf" }, 159 { DEVICE_ID_RADEON_Lg, rt_m9, "Radeon Mobility 9000 Lg" }, 160 161 // RV280 162 // the naming scheme can't properly handle this id 163 { DEVICE_ID_RADEON_Ya_, rt_rv250, "Radeon 9200" }, 164 { DEVICE_ID_RADEON_Ya, rt_rv250, "Radeon 9200" }, 165 { DEVICE_ID_RADEON_Yd, rt_rv250, "Radeon 9200 SE" }, 166 167 // R300 168 { DEVICE_ID_RADEON_ND, rt_r300, "Radeon 9700 ND" }, 169 { DEVICE_ID_RADEON_NE, rt_r300, "Radeon 9700 NE" }, 170 { DEVICE_ID_RADEON_NF, rt_r300, "Radeon 9600 XT" }, 171 { DEVICE_ID_RADEON_NG, rt_r300, "Radeon 9700 NG" }, 172 173 { DEVICE_ID_RADEON_AD, rt_r300, "Radeon 9700 AD" }, 174 { DEVICE_ID_RADEON_AE, rt_r300, "Radeon 9700 AE" }, 175 { DEVICE_ID_RADEON_AF, rt_r300, "Radeon 9700 AF" }, 176 { DEVICE_ID_RADEON_AG, rt_r300, "Radeon 9700 AG" }, 177 178 // RV350 179 { DEVICE_ID_RADEON_AP, rt_rv350, "Radeon 9600 AP" }, 180 { DEVICE_ID_RADEON_AQ, rt_rv350, "Radeon 9600 AQ" }, 181 { DEVICE_ID_RADEON_NO, rt_rv350, "Radeon Mobility 9600 Pro Turbo" }, 182 { DEVICE_ID_RADEON_NS, rt_rv350, "Mobility FireGL T2" }, 183 184 // RV360 (probably minor revision of rv350) 185 { DEVICE_ID_RADEON_AR, rt_rv360, "Radeon 9600 AR" }, 186 187 // R350 188 { DEVICE_ID_RADEON_AH, rt_r350, "Radeon 9800 AH" }, 189 { DEVICE_ID_RADEON_NH, rt_r350, "Radeon 9800 Pro NH" }, 190 { DEVICE_ID_RADEON_NI, rt_r350, "Radeon 9800 NI" }, 191 192 // R360 (probably minor revision of r350) 193 { DEVICE_ID_RADEON_NJ, rt_r360, "Radeon 9800 XT" }, 194 195 { DEVICE_ID_IGP320M, rt_ve, "Radeon IGP 320M" }, 196 197 { 0, 0, NULL } 198 }; 199 200 201 // list of supported vendors (there aren't many ;) 202 static struct { 203 uint16 vendor_id; 204 RadeonDevice *devices; 205 } SupportedVendors[] = { 206 { VENDOR_ID_ATI, radeon_device_list }, 207 { 0x0000, NULL } 208 }; 209 210 // check, whether there is *any* supported card plugged in 211 bool Radeon_CardDetect( void ) 212 { 213 long pci_index = 0; 214 pci_info pcii; 215 bool found_one = FALSE; 216 217 if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) 218 return B_ERROR; 219 220 while ((*pci_bus->get_nth_pci_info)(pci_index, &pcii) == B_NO_ERROR) { 221 int vendor = 0; 222 223 while (SupportedVendors[vendor].vendor_id) { 224 if (SupportedVendors[vendor].vendor_id == pcii.vendor_id) { 225 RadeonDevice *devices = SupportedVendors[vendor].devices; 226 227 while (devices->device_id) { 228 if (devices->device_id == pcii.device_id ) { 229 rom_info ri; 230 231 if( Radeon_MapBIOS( &pcii, &ri ) == B_OK ) { 232 Radeon_UnmapBIOS( &ri ); 233 234 SHOW_INFO( 0, "found supported device pci index %ld, device 0x%04x/0x%04x", 235 pci_index, pcii.vendor_id, pcii.device_id ); 236 found_one = TRUE; 237 goto done; 238 } 239 } 240 devices++; 241 } 242 } 243 vendor++; 244 } 245 246 pci_index++; 247 } 248 SHOW_INFO0( 0, "no supported devices found" ); 249 250 done: 251 put_module(B_PCI_MODULE_NAME); 252 253 return (found_one ? B_OK : B_ERROR); 254 } 255 256 // !extend this array whenever a new ASIC is a added! 257 static bool has_crtc2[] = 258 { 259 false, // only original Radeons have one crtc only 260 false, 261 true, 262 true, 263 true, 264 true, 265 true, 266 true, 267 true, 268 true, 269 true, 270 true, 271 true, 272 true, 273 true 274 }; 275 276 static const char *asic_name[] = 277 { 278 "r100", 279 "ve", 280 "m6", 281 "rv200", 282 "m7", 283 "r200", 284 "rv250", 285 "rv280", 286 "m9", 287 "r300", 288 "r300_4p", 289 "rv350", 290 "rv360", 291 "r350", 292 "r360", 293 }; 294 295 // get next supported device 296 static bool probeDevice( device_info *di ) 297 { 298 int vendor; 299 300 /* if we match a supported vendor */ 301 for( vendor = 0; SupportedVendors[vendor].vendor_id; ++vendor ) { 302 RadeonDevice *device; 303 304 if( SupportedVendors[vendor].vendor_id != di->pcii.vendor_id ) 305 continue; 306 307 for( device = SupportedVendors[vendor].devices; device->device_id; ++device ) { 308 // avoid double-detection 309 if (device->device_id != di->pcii.device_id ) 310 continue; 311 312 di->has_crtc2 = has_crtc2[device->asic]; 313 di->asic = device->asic; 314 315 if( Radeon_MapBIOS( &di->pcii, &di->rom ) != B_OK ) 316 // give up checking this device - no BIOS, no fun 317 return false; 318 319 if( Radeon_ReadBIOSData( di ) != B_OK ) { 320 Radeon_UnmapBIOS( &di->rom ); 321 return false; 322 } 323 324 // we don't need BIOS any more 325 Radeon_UnmapBIOS( &di->rom ); 326 327 SHOW_INFO( 0, "found %s; ASIC: %s", device->name, asic_name[device->asic] ); 328 329 sprintf(di->name, "graphics/%04X_%04X_%02X%02X%02X", 330 di->pcii.vendor_id, di->pcii.device_id, 331 di->pcii.bus, di->pcii.device, di->pcii.function); 332 SHOW_FLOW( 3, "making /dev/%s", di->name ); 333 334 di->is_open = 0; 335 di->shared_area = -1; 336 di->si = NULL; 337 338 return true; 339 } 340 } 341 342 return false; 343 } 344 345 346 // gather list of supported devices 347 // (currently, we rely on proper BIOS detection, which 348 // only works for primary graphics adapter, so multiple 349 // devices won't really work) 350 void Radeon_ProbeDevices( void ) 351 { 352 uint32 pci_index = 0; 353 uint32 count = 0; 354 device_info *di = devices->di; 355 356 while( count < MAX_DEVICES ) { 357 memset( di, 0, sizeof( *di )); 358 359 if( (*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) != B_NO_ERROR) 360 break; 361 362 if( probeDevice( di )) { 363 devices->device_names[count] = di->name; 364 di++; 365 count++; 366 } 367 368 pci_index++; 369 } 370 371 devices->count = count; 372 devices->device_names[count] = NULL; 373 374 SHOW_INFO( 0, "%ld supported devices", count ); 375 } 376