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 // M9+ 70 #define DEVICE_ID_RADEON_5c61 0x5c61 71 72 // RV280 73 #define DEVICE_ID_RADEON_Zprea 0x5960 74 #define DEVICE_ID_RADEON_Za 0x5961 75 #define DEVICE_ID_RADEON_Zd 0x5964 76 77 // r300 78 #define DEVICE_ID_RADEON_ND 0x4e44 79 #define DEVICE_ID_RADEON_NE 0x4e45 80 #define DEVICE_ID_RADEON_NF 0x4e46 81 #define DEVICE_ID_RADEON_NG 0x4e47 82 83 // r300-4P 84 #define DEVICE_ID_RADEON_AD 0x4144 85 #define DEVICE_ID_RADEON_AE 0x4145 86 #define DEVICE_ID_RADEON_AF 0x4146 87 #define DEVICE_ID_RADEON_AG 0x4147 88 89 // rv350 90 #define DEVICE_ID_RADEON_AP 0x4150 91 #define DEVICE_ID_RADEON_AQ 0x4151 92 #define DEVICE_ID_RADEON_AS 0x4153 93 94 // m10 95 #define DEVICE_ID_RADEON_NP 0x4e50 96 // Mobility Fire GL T2 - any idea about the chip? 97 #define DEVICE_ID_RADEON_NT 0x4e54 98 99 // rv360 100 #define DEVICE_ID_RADEON_AR 0x4152 101 102 // r350 103 #define DEVICE_ID_RADEON_AH 0x4148 104 #define DEVICE_ID_RADEON_NH 0x4e48 105 #define DEVICE_ID_RADEON_NI 0x4e49 106 107 // r360 108 #define DEVICE_ID_RADEON_NJ 0x4e4a 109 110 // rs100 111 #define DEVICE_ID_IGP320M 0x4336 112 113 // rs200 114 #define DEVICE_ID_RADEON_C7 0x4337 115 #define DEVICE_ID_RADEON_A7 0x4137 116 117 typedef struct { 118 uint16 device_id; 119 radeon_type asic; 120 char *name; 121 } RadeonDevice; 122 123 // list of supported devices 124 RadeonDevice radeon_device_list[] = { 125 // original Radeons, now called r100 126 { DEVICE_ID_RADEON_QD, rt_r100, "Radeon 7200 / Radeon / ALL-IN-WONDER Radeon" }, 127 { DEVICE_ID_RADEON_QE, rt_r100, "Radeon QE" }, 128 { DEVICE_ID_RADEON_QF, rt_r100, "Radeon QF" }, 129 { DEVICE_ID_RADEON_QG, rt_r100, "Radeon QG" }, 130 131 // Radeon VE (low-cost, dual CRT, no TCL), now called RV100 132 { DEVICE_ID_RADEON_QY, rt_ve, "Radeon 7000 / Radeon VE" }, 133 { DEVICE_ID_RADEON_QZ, rt_ve, "Radeon QZ VE" }, 134 135 // mobility version of original Radeon (based on VE), now called M6 136 { DEVICE_ID_RADEON_LY, rt_m6, "Radeon Mobility" }, 137 { DEVICE_ID_RADEON_LZ, rt_m6, "Radeon Mobility M6 LZ" }, 138 139 // rs100 (integrated Radeon, seems to be a Radeon VE) 140 { DEVICE_ID_IGP320M, rt_rs100, "IGP320M" }, 141 142 // RV200 (dual CRT) 143 { DEVICE_ID_RADEON_QW, rt_rv200, "Radeon 7500 / ALL-IN-WONDER Radeon 7500" }, 144 { DEVICE_ID_RADEON_QX, rt_rv200, "Radeon 7500 QX" }, 145 146 // M7 (based on RV200) 147 { DEVICE_ID_RADEON_LW, rt_m7, "Radeon Mobility 7500" }, 148 { DEVICE_ID_RADEON_LX, rt_m7, "Radeon Mobility 7500 GL" }, 149 150 // R200 151 { DEVICE_ID_RADEON_QH, rt_r200, "ATI Fire GL E1" }, // chip type: fgl8800 152 { DEVICE_ID_RADEON_QI, rt_r200, "Radeon 8500 QI" }, 153 { DEVICE_ID_RADEON_QJ, rt_r200, "Radeon 8500 QJ" }, 154 { DEVICE_ID_RADEON_QK, rt_r200, "Radeon 8500 QK" }, 155 { DEVICE_ID_RADEON_QL, rt_r200, "Radeon 8500 / 8500LE / ALL-IN-WONDER Radeon 8500" }, 156 { DEVICE_ID_RADEON_QM, rt_r200, "Radeon 9100" }, 157 158 { DEVICE_ID_RADEON_Qh, rt_r200, "Radeon 8500 Qh" }, 159 { DEVICE_ID_RADEON_Qi, rt_r200, "Radeon 8500 Qi" }, 160 { DEVICE_ID_RADEON_Qj, rt_r200, "Radeon 8500 Qj" }, 161 { DEVICE_ID_RADEON_Qk, rt_r200, "Radeon 8500 Qk" }, 162 { DEVICE_ID_RADEON_BB, rt_r200, "ALL-IN-Wonder Radeon 8500 DV" }, 163 164 // RV250 (cut-down R200 with integrated TV-Out) 165 { DEVICE_ID_RADEON_Id, rt_rv250, "Radeon 9000 Id" }, 166 { DEVICE_ID_RADEON_Ie, rt_rv250, "Radeon 9000 Ie" }, 167 { DEVICE_ID_RADEON_If, rt_rv250, "Radeon 9000" }, 168 { DEVICE_ID_RADEON_Ig, rt_rv250, "Radeon 9000 Ig" }, 169 170 // M9 (based on rv250) 171 { DEVICE_ID_RADEON_Ld, rt_m9, "Radeon Mobility 9000 Ld" }, 172 { DEVICE_ID_RADEON_Le, rt_m9, "Radeon Mobility 9000 Le" }, 173 { DEVICE_ID_RADEON_Lf, rt_m9, "Radeon Mobility 9000 Lf" }, 174 { DEVICE_ID_RADEON_Lg, rt_m9, "Radeon Mobility 9000 Lg" }, 175 176 // RV280 (rv250 with higher frequency) 177 // this entry violates naming scheme, so it's probably wrong 178 { DEVICE_ID_RADEON_Zprea, rt_rv280, "Radeon 9200" }, 179 { DEVICE_ID_RADEON_Za, rt_rv280, "Radeon 9200" }, 180 { DEVICE_ID_RADEON_Zd, rt_rv280, "Radeon 9200 SE" }, 181 182 // M9+ (based on rv280) 183 { DEVICE_ID_RADEON_5c61,rt_m9plus, "Radeon Mobility 9200" }, 184 185 // R300 186 { DEVICE_ID_RADEON_ND, rt_r300, "Radeon 9700 ND" }, 187 { DEVICE_ID_RADEON_NE, rt_r300, "Radeon 9700 NE" }, 188 { DEVICE_ID_RADEON_NF, rt_r300, "Radeon 9600 XT" }, 189 { DEVICE_ID_RADEON_NG, rt_r300, "Radeon 9700 NG" }, 190 191 { DEVICE_ID_RADEON_AD, rt_r300, "Radeon 9700 AD" }, 192 { DEVICE_ID_RADEON_AE, rt_r300, "Radeon 9700 AE" }, 193 { DEVICE_ID_RADEON_AF, rt_r300, "Radeon 9700 AF" }, 194 { DEVICE_ID_RADEON_AG, rt_r300, "Radeon 9700 AG" }, 195 196 // RV350 197 { DEVICE_ID_RADEON_AP, rt_rv350, "Radeon 9600 AP" }, 198 { DEVICE_ID_RADEON_AQ, rt_rv350, "Radeon 9600 AQ" }, 199 { DEVICE_ID_RADEON_AS, rt_rv350, "Radeon 9600 AS" }, 200 201 // M10 (based on rv350) 202 { DEVICE_ID_RADEON_NP, rt_m10, "Radeon Mobility 9600 NP" }, 203 // not sure about that: ROM signature is "RADEON" which means r100 204 { DEVICE_ID_RADEON_NT, rt_m10, "Radeon Mobility FireGL T2" }, 205 206 // RV360 (probably minor revision of rv350) 207 { DEVICE_ID_RADEON_AR, rt_rv360, "Radeon 9600 AR" }, 208 209 // R350 210 { DEVICE_ID_RADEON_AH, rt_r350, "Radeon 9800 AH" }, 211 { DEVICE_ID_RADEON_NH, rt_r350, "Radeon 9800 Pro NH" }, 212 { DEVICE_ID_RADEON_NI, rt_r350, "Radeon 9800 NI" }, 213 214 // R360 (probably minor revision of r350) 215 { DEVICE_ID_RADEON_NJ, rt_r360, "Radeon 9800 XT" }, 216 217 // rs100 (aka IGP 320) 218 { DEVICE_ID_IGP320M, rt_rs100, "Radeon IGP 320M" }, 219 220 // rs200 (aka IGP 340) 221 { DEVICE_ID_RADEON_C7, rt_rs200, "IGP330M/340M/350M (U2) 4337" }, 222 { DEVICE_ID_RADEON_A7, rt_rs200, "IGP 340" }, 223 224 { 0, 0, NULL } 225 }; 226 227 228 // list of supported vendors (there aren't many ;) 229 static struct { 230 uint16 vendor_id; 231 RadeonDevice *devices; 232 } SupportedVendors[] = { 233 { VENDOR_ID_ATI, radeon_device_list }, 234 { 0x0000, NULL } 235 }; 236 237 // check, whether there is *any* supported card plugged in 238 bool Radeon_CardDetect( void ) 239 { 240 long pci_index = 0; 241 pci_info pcii; 242 bool found_one = FALSE; 243 244 if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) 245 return B_ERROR; 246 247 while ((*pci_bus->get_nth_pci_info)(pci_index, &pcii) == B_NO_ERROR) { 248 int vendor = 0; 249 250 while (SupportedVendors[vendor].vendor_id) { 251 if (SupportedVendors[vendor].vendor_id == pcii.vendor_id) { 252 RadeonDevice *devices = SupportedVendors[vendor].devices; 253 254 while (devices->device_id) { 255 if (devices->device_id == pcii.device_id ) { 256 rom_info ri; 257 258 if( Radeon_MapBIOS( &pcii, &ri ) == B_OK ) { 259 Radeon_UnmapBIOS( &ri ); 260 261 SHOW_INFO( 0, "found supported device pci index %ld, device 0x%04x/0x%04x", 262 pci_index, pcii.vendor_id, pcii.device_id ); 263 found_one = TRUE; 264 goto done; 265 } 266 } 267 devices++; 268 } 269 } 270 vendor++; 271 } 272 273 pci_index++; 274 } 275 SHOW_INFO0( 0, "no supported devices found" ); 276 277 done: 278 put_module(B_PCI_MODULE_NAME); 279 280 return (found_one ? B_OK : B_ERROR); 281 } 282 283 // !extend this array whenever a new ASIC is a added! 284 static struct { 285 const char *name; // name of ASIC 286 tv_chip_type tv_chip; // TV-Out chip (if any) 287 bool has_crtc2; // has second CRTC 288 bool is_mobility; // mobility chip 289 bool has_vip; // has VIP/I2C 290 bool new_pll; // reference divider of PPLL moved to other location 291 bool is_igp; // integrated graphics 292 } asic_properties[] = 293 { 294 { "r100", tc_external_rt1, false, false, true, false, false }, // only original Radeons have one crtc only 295 { "ve", tc_internal_rt1, true, false, true, false, false }, 296 { "m6", tc_internal_rt1, true, true, false, false, false }, 297 { "rs100", tc_internal_rt1, true, true, false, false, true }, 298 { "rv200", tc_internal_rt2, true, false, true, false, false }, 299 { "m7", tc_internal_rt1, true, true, false, false, false }, 300 { "rs200", tc_internal_rt1, true, true, false, false, true }, 301 { "r200", tc_external_rt1, true, false, true, false, false }, // r200 has external TV-Out encoder 302 { "rv250", tc_internal_rt2, true, false, true, false, false }, 303 { "m9", tc_internal_rt2, true, true, false, false, false }, 304 { "rv280", tc_internal_rt2, true, false, true, false, false }, 305 { "m9plus", tc_internal_rt2, true, true, false, false, false }, 306 { "r300", tc_internal_rt2, true, false, true, true, false }, 307 { "r300_4p",tc_internal_rt2, true, false, true, true, false }, 308 { "rv350", tc_internal_rt2, true, false, true, true, false }, 309 { "m10", tc_internal_rt2, true, true, false, true, false }, 310 { "rv360", tc_internal_rt2, true, false, true, true, false }, 311 { "r350", tc_internal_rt2, true, false, true, true, false }, 312 { "r360", tc_internal_rt2, true, false, true, true, false } 313 }; 314 315 316 // get next supported device 317 static bool probeDevice( device_info *di ) 318 { 319 int vendor; 320 321 /* if we match a supported vendor */ 322 for( vendor = 0; SupportedVendors[vendor].vendor_id; ++vendor ) { 323 RadeonDevice *device; 324 325 if( SupportedVendors[vendor].vendor_id != di->pcii.vendor_id ) 326 continue; 327 328 for( device = SupportedVendors[vendor].devices; device->device_id; ++device ) { 329 // avoid double-detection 330 if (device->device_id != di->pcii.device_id ) 331 continue; 332 333 di->num_crtc = asic_properties[device->asic].has_crtc2 ? 2 : 1; 334 di->tv_chip = asic_properties[device->asic].tv_chip; 335 di->asic = device->asic; 336 di->is_mobility = asic_properties[device->asic].is_mobility; 337 di->has_vip = asic_properties[device->asic].has_vip; 338 di->new_pll = asic_properties[device->asic].new_pll; 339 di->is_igp = asic_properties[device->asic].is_igp; 340 341 if( Radeon_MapBIOS( &di->pcii, &di->rom ) != B_OK ) 342 // give up checking this device - no BIOS, no fun 343 return false; 344 345 if( Radeon_ReadBIOSData( di ) != B_OK ) { 346 Radeon_UnmapBIOS( &di->rom ); 347 return false; 348 } 349 350 // we don't need BIOS any more 351 Radeon_UnmapBIOS( &di->rom ); 352 353 SHOW_INFO( 0, "found %s; ASIC: %s", device->name, asic_properties[device->asic].name ); 354 355 sprintf(di->name, "graphics/%04X_%04X_%02X%02X%02X", 356 di->pcii.vendor_id, di->pcii.device_id, 357 di->pcii.bus, di->pcii.device, di->pcii.function); 358 SHOW_FLOW( 3, "making /dev/%s", di->name ); 359 360 // we always publish it as a video grabber; we should check for Rage 361 // Theater, but the corresponding code (vip.c) needs a fully initialized 362 // driver, and this is too much hazzly, so we leave it to the media add-on 363 // to verify that the card really supports video-in 364 sprintf(di->video_name, "video/radeon/%04X_%04X_%02X%02X%02X", 365 di->pcii.vendor_id, di->pcii.device_id, 366 di->pcii.bus, di->pcii.device, di->pcii.function); 367 368 di->is_open = 0; 369 di->shared_area = -1; 370 di->si = NULL; 371 372 return true; 373 } 374 } 375 376 return false; 377 } 378 379 380 // gather list of supported devices 381 // (currently, we rely on proper BIOS detection, which 382 // only works for primary graphics adapter, so multiple 383 // devices won't really work) 384 void Radeon_ProbeDevices( void ) 385 { 386 uint32 pci_index = 0; 387 uint32 count = 0; 388 device_info *di = devices->di; 389 390 while( count < MAX_DEVICES ) { 391 memset( di, 0, sizeof( *di )); 392 393 if( (*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) != B_NO_ERROR) 394 break; 395 396 if( probeDevice( di )) { 397 devices->device_names[2*count] = di->name; 398 devices->device_names[2*count+1] = di->video_name; 399 di++; 400 count++; 401 } 402 403 pci_index++; 404 } 405 406 devices->count = count; 407 devices->device_names[2*count] = NULL; 408 409 SHOW_INFO( 0, "%ld supported devices", count ); 410 } 411