📄 detect.c copy
字号:
/* Copyright (c) 2002, Thomas Kurschel Part of Radeon kernel driver Graphics card detection*/#include "radeon_driver.h"#include <stdio.h>// this table is gathered from different sources// and may even contain some wrong entries#define VENDOR_ID_ATI 0x1002// R100//#define DEVICE_ID_RADEON_QE 0x5145//#define DEVICE_ID_RADEON_QF 0x5146//#define DEVICE_ID_RADEON_QG 0x5147// RV100// M6// RV200// M7 (R200 mobility)// R200// RV250// M9// RV280// r300// r300-4P// rv350// M10// rv360// r350// Mobility Fire GL T2 - any idea about the chip?// r360// rs100// rs200typedef struct { uint16 device_id; radeon_type asic; char *name;} RadeonDevice;// list of supported devicesRadeonDevice radeon_device_list[] = { // original Radeons, now called r100 { 0x5144, rt_r100, "Radeon 7200 / Radeon / ALL-IN-WONDER Radeon" }, // Radeon VE (low-cost, dual CRT, no TCL), now called RV100 { 0x5159, rt_ve, "Radeon 7000" }, { 0x515a, rt_ve, "Radeon 7000" }, // mobility version of original Radeon (based on VE), now called M6 { 0x4c59, rt_m6, "Radeon Mobility" }, { 0x4c5a, rt_m6, "Radeon Mobility M6 LZ" }, // not sure about that: ROM signature is "RADEON" which means r100 { 0x4e54, rt_m6, "Radeon Mobility FireGL T2" }, // rs100 (integrated Radeon, seems to be a Radeon VE) { 0x4336, rt_rs100, "IGP320M" }, // RV200 (dual CRT) { 0x5157, rt_rv200, "Radeon 7500 / ALL-IN-WONDER Radeon 7500" }, { 0x5158, rt_rv200, "Radeon 7500 QX" }, // M7 (based on RV200) { 0x4c57, rt_m7, "Radeon Mobility 7500" }, { 0x4c58, rt_m7, "Radeon Mobility 7500 GL" }, // R200 { 0x5148, rt_r200, "ATI Fire GL E1" }, // chip type: fgl8800 { 0x5149, rt_r200, "Radeon 8500 QI" }, { 0x514a, rt_r200, "Radeon 8500 QJ" }, { 0x514b, rt_r200, "Radeon 8500 QK" }, { 0x514c, rt_r200, "Radeon 8500 / 8500LE / ALL-IN-WONDER Radeon 8500" }, { 0x514d, rt_r200, "Radeon 9100" }, { 0x5168, rt_r200, "Radeon 8500 Qh" }, { 0x5169, rt_r200, "Radeon 8500 Qi" }, { 0x516a, rt_r200, "Radeon 8500 Qj" }, { 0x516b, rt_r200, "Radeon 8500 Qk" }, { 0x4242, rt_r200, "ALL-IN-Wonder Radeon 8500 DV" }, // RV250 (cut-down R200) { 0x4964, rt_rv250, "Radeon 9000 Id" }, { 0x4965, rt_rv250, "Radeon 9000 Ie" }, { 0x4966, rt_rv250, "Radeon 9000" }, { 0x4967, rt_rv250, "Radeon 9000 Ig" }, // M9 (based on rv250) { 0x4c64, rt_m9, "Radeon Mobility 9000 Ld" }, { 0x4c65, rt_m9, "Radeon Mobility 9000 Le" }, { 0x4c66, rt_m9, "Radeon Mobility 9000 Lf" }, { 0x4c67, rt_m9, "Radeon Mobility 9000 Lg" }, // RV280 // this entry violates naming scheme, so it's probably wrong { 0x5960, rt_rv280, "Radeon 9200" }, { 0x5961, rt_rv280, "Radeon 9200" }, { 0x5964, rt_rv280, "Radeon 9200 SE" }, // R300 { 0x4e44, rt_r300, "Radeon 9700 ND" }, { 0x4e45, rt_r300, "Radeon 9700 NE" }, { 0x4e46, rt_r300, "Radeon 9600 XT" }, { 0x4e47, rt_r300, "Radeon 9700 NG" }, { 0x4144, rt_r300, "Radeon 9700 AD" }, { 0x4145, rt_r300, "Radeon 9700 AE" }, { 0x4146, rt_r300, "Radeon 9700 AF" }, { 0x4147, rt_r300, "Radeon 9700 AG" }, // RV350 { 0x4150, rt_rv350, "Radeon 9600 AP" }, { 0x4151, rt_rv350, "Radeon 9600 AQ" }, { 0x4e50, rt_rv350, "Radeon 9600 Pro" }, // RV360 (probably minor revision of rv350) { 0x4152, rt_rv360, "Radeon 9600 AR" }, // R350 { 0x4148, rt_r350, "Radeon 9800 AH" }, { 0x4e48, rt_r350, "Radeon 9800 Pro NH" }, { 0x4e49, rt_r350, "Radeon 9800 NI" }, // R360 (probably minor revision of r350) { 0x4e4a, rt_r360, "Radeon 9800 XT" }, // rs200 (aka IGP) { 0x4337, rt_rs200, "IGP330M/340M/350M (U2) 4337" }, { 0x4137, rt_rs200, "IGP 340" }, { 0, 0, NULL }};// list of supported vendors (there aren't many ;)static struct { uint16 vendor_id; RadeonDevice *devices;} SupportedVendors[] = { { VENDOR_ID_ATI, radeon_device_list }, { 0x0000, NULL }};// check, whether there is *any* supported card plugged inbool Radeon_CardDetect( void ){ long pci_index = 0; pci_info pcii; bool found_one = FALSE; if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci_bus) != B_OK) return B_ERROR; while ((*pci_bus->get_nth_pci_info)(pci_index, &pcii) == B_NO_ERROR) { int vendor = 0; while (SupportedVendors[vendor].vendor_id) { if (SupportedVendors[vendor].vendor_id == pcii.vendor_id) { RadeonDevice *devices = SupportedVendors[vendor].devices; while (devices->device_id) { if (devices->device_id == pcii.device_id ) { rom_info ri; if( Radeon_MapBIOS( &pcii, &ri ) == B_OK ) { Radeon_UnmapBIOS( &ri ); SHOW_INFO( 0, "found supported device pci index %ld, device 0x%04x/0x%04x", pci_index, pcii.vendor_id, pcii.device_id ); found_one = TRUE; goto done; } } devices++; } } vendor++; } pci_index++; } SHOW_INFO0( 0, "no supported devices found" );done: put_module(B_PCI_MODULE_NAME); return (found_one ? B_OK : B_ERROR);}// !extend this array whenever a new ASIC is a added!static struct { const char *name; // name of ASIC tv_chip_type tv_chip; // TV-Out chip (if any) bool has_crtc2; // has second CRTC bool is_mobility; // mobility chip bool has_vip; // has VIP/I2C bool is_igp; // integrated graphics} asic_properties[] ={ { "r100", tc_external_rt1, false, false, true, false }, // only original Radeons have one crtc only { "ve", tc_internal_rt1, true, false, true, false }, { "m6", tc_internal_rt1, true, true, false, false }, { "rs100", tc_internal_rt1, true, true, false, true }, { "rv200", tc_internal_rt2, true, false, true, false }, { "m7", tc_internal_rt1, true, true, false, false }, { "rs200", tc_internal_rt1, true, true, false, true }, { "r200", tc_external_rt1, true, false, true, false }, // r200 has external TV-Out encoder { "rv250", tc_internal_rt2, true, false, true, false }, { "rv280", tc_internal_rt2, true, false, true, false }, { "m9", tc_internal_rt2, true, true, true, false }, { "r300", tc_internal_rt2, true, false, true, false }, { "r300_4p",tc_internal_rt2, true, false, true, false }, { "rv350", tc_internal_rt2, true, false, true, false }, { "rv360", tc_internal_rt2, true, false, true, false }, { "r350", tc_internal_rt2, true, false, true, false }, { "r360", tc_internal_rt2, true, false, true, false }};// get next supported devicestatic bool probeDevice( device_info *di ){ int vendor; /* if we match a supported vendor */ for( vendor = 0; SupportedVendors[vendor].vendor_id; ++vendor ) { RadeonDevice *device; if( SupportedVendors[vendor].vendor_id != di->pcii.vendor_id ) continue; for( device = SupportedVendors[vendor].devices; device->device_id; ++device ) { // avoid double-detection if (device->device_id != di->pcii.device_id ) continue; di->num_heads = asic_properties[device->asic].has_crtc2 ? 2 : 1; di->tv_chip = asic_properties[device->asic].tv_chip; di->asic = device->asic; di->is_mobility = asic_properties[device->asic].is_mobility; di->has_vip = asic_properties[device->asic].has_vip; di->is_igp = asic_properties[device->asic].is_igp; if( Radeon_MapBIOS( &di->pcii, &di->rom ) != B_OK ) // give up checking this device - no BIOS, no fun return false; if( Radeon_ReadBIOSData( di ) != B_OK ) { Radeon_UnmapBIOS( &di->rom ); return false; } // we don't need BIOS any more Radeon_UnmapBIOS( &di->rom ); SHOW_INFO( 0, "found %s; ASIC: %s", device->name, asic_properties[device->asic].name ); sprintf(di->name, "graphics/%04X_%04X_%02X%02X%02X", di->pcii.vendor_id, di->pcii.device_id, di->pcii.bus, di->pcii.device, di->pcii.function); SHOW_FLOW( 3, "making /dev/%s", di->name ); // we always publish it as a video grabber; we should check for Rage // Theater, but the corresponding code (vip.c) needs a fully initialized // driver, and this is too much hazzly, so we leave it to the media add-on // to verify that the card really supports video-in sprintf(di->video_name, "video/radeon/%04X_%04X_%02X%02X%02X", di->pcii.vendor_id, di->pcii.device_id, di->pcii.bus, di->pcii.device, di->pcii.function); di->is_open = 0; di->shared_area = -1; di->si = NULL; return true; } } return false;}// gather list of supported devices// (currently, we rely on proper BIOS detection, which// only works for primary graphics adapter, so multiple// devices won't really work)void Radeon_ProbeDevices( void ) { uint32 pci_index = 0; uint32 count = 0; device_info *di = devices->di; while( count < MAX_DEVICES ) { memset( di, 0, sizeof( *di )); if( (*pci_bus->get_nth_pci_info)(pci_index, &(di->pcii)) != B_NO_ERROR) break; if( probeDevice( di )) { devices->device_names[2*count] = di->name; devices->device_names[2*count+1] = di->video_name; di++; count++; } pci_index++; } devices->count = count; devices->device_names[2*count] = NULL; SHOW_INFO( 0, "%ld supported devices", count );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -