xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon/detect.c (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
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