xref: /haiku/src/add-ons/kernel/drivers/graphics/radeon/bios.c (revision cc7e844c12cbb4d60c80edac08a503d5cf872929)
1 /*
2 	Copyright (c) 2002, Thomas Kurschel
3 
4 
5 	Part of Radeon kernel driver
6 
7 	BIOS detection and retrieval of vital data
8 
9 	Most of this data should be gathered directly,
10 	especially monitor detection should be done on
11 	demand so not all monitors need to be connected
12 	during boot
13 */
14 
15 #include "radeon_driver.h"
16 #include "mmio.h"
17 #include "bios_regs.h"
18 #include "config_regs.h"
19 #include "memcntrl_regs.h"
20 #include "buscntrl_regs.h"
21 #include "fp_regs.h"
22 #include "crtc_regs.h"
23 #include "ddc_regs.h"
24 #include "radeon_bios.h"
25 #include "utils.h"
26 
27 #include <stdio.h>
28 #include <string.h>
29 
30 #define get_pci(o, s) (*pci_bus->read_pci_config)(pcii->bus, pcii->device, pcii->function, (o), (s))
31 
32 #define RADEON_BIOS8(v) 	 (di->rom.rom_ptr[v])
33 #define RADEON_BIOS16(v) 	((di->rom.rom_ptr[v]) | \
34 				(di->rom.rom_ptr[(v) + 1] << 8))
35 #define RADEON_BIOS32(v) 	((di->rom.rom_ptr[v]) | \
36 				(di->rom.rom_ptr[(v) + 1] << 8) | \
37 				(di->rom.rom_ptr[(v) + 2] << 16) | \
38 				(di->rom.rom_ptr[(v) + 3] << 24))
39 
40 static const char ati_rom_sig[] = "761295520";
41 
42 static const tmds_pll_info default_tmds_pll[14][4] =
43 {
44     {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},			// r100
45     {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},			// rv100
46     {{0, 0}, {0, 0}, {0, 0}, {0, 0}},						// rs100
47     {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},			// rv200
48     {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},			// rs200
49     {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},			// r200
50     {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},			// rv250
51     {{0, 0}, {0, 0}, {0, 0}, {0, 0}},						// rs300
52     {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, 	// rv280
53     {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},				// r300
54     {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},				// r350
55     {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},			// rv350
56     {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},			// rv380
57     {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},				// r420
58 };
59 
60 
61 // find address of ROM;
62 // this code is really nasty as maintaining the radeon signatures
63 // is almost impossible (the signatures provided by ATI are always out-dated);
64 // further, if there is more then one card built into the computer, we
65 // may detect the wrong BIOS!
66 // we have two possible solutions:
67 // 1. use the PCI location as stored in BIOS
68 // 2. verify the IO-base address as stored in BIOS
69 // I have no clue how these values are _written_ into the BIOS, and
70 // unfortunately, every BIOS does the detection in a different way,
71 // so I'm not sure which is the _right_ way of doing it
Radeon_FindRom(rom_info * ri)72 static char *Radeon_FindRom( rom_info *ri )
73 {
74 	uint32 segstart;
75 	uint8 *rom_base;
76 	char *rom;
77 	int i;
78 
79 	for( segstart = 0x000c0000; segstart < 0x000f0000; segstart += 0x00001000 ) {
80 		bool found = false;
81 
82 		// find ROM
83 		rom_base = ri->bios_ptr + segstart - 0xc0000;
84 
85 		if( rom_base[0] != 0x55 || rom_base[1] != 0xaa )
86 			continue;
87 
88 		// find signature of ATI
89 		rom = rom_base;
90 
91 		found = false;
92 
93 		for( i = 0; i < 128 - strlen( ati_rom_sig ); i++ ) {
94 			if( ati_rom_sig[0] == rom_base[i] ) {
95 				if( strncmp(ati_rom_sig, rom_base + i, strlen( ati_rom_sig )) == 0 ) {
96 					found = true;
97 					break;
98 				}
99 			}
100 		}
101 
102 		if( !found )
103 			continue;
104 
105 		// EK don't bother looking for signiture now, due to lack of consistancy.
106 
107 		SHOW_INFO( 2, "found ROM @0x%" B_PRIx32, segstart );
108 		return rom_base;
109 	}
110 
111 	SHOW_INFO0( 2, "no ROM found" );
112 	return NULL;
113 }
114 
115 
116 // PLL info is stored in ROM, probably it's too easy to replace it
117 // and thus they produce cards with different timings
Radeon_GetPLLInfo(device_info * di)118 static void Radeon_GetPLLInfo( device_info *di )
119 {
120 	uint8 *bios_header;
121 	uint8 *tmp;
122 	PLL_BLOCK pll, *pll_info;
123 
124 	bios_header = di->rom.rom_ptr + *(uint16 *)(di->rom.rom_ptr + 0x48);
125 	pll_info = (PLL_BLOCK *)(di->rom.rom_ptr + *(uint16 *)(bios_header + 0x30));
126 
127 	// determine type of ROM
128 
129 	tmp = bios_header + 4;
130 
131     if ((	*tmp 	== 'A'
132    		&& *(tmp+1) == 'T'
133    		&& *(tmp+2) == 'O'
134    		&& *(tmp+3) == 'M'
135    		)
136    		||
137    		(	*tmp	== 'M'
138    		&& *(tmp+1) == 'O'
139    		&& *(tmp+2) == 'T'
140    		&& *(tmp+3) == 'A'
141    		))
142 	{
143 		int bios_header, master_data_start, pll_start;
144 		di->is_atombios = true;
145 
146 		bios_header 	  	 = RADEON_BIOS16(0x48);
147 		master_data_start 	 = RADEON_BIOS16(bios_header + 32);
148 		pll_start 		  	 = RADEON_BIOS16(master_data_start + 12);
149 
150 		di->pll.ref_div 	 = 0;
151 		di->pll.max_pll_freq = RADEON_BIOS16(pll_start + 32);
152 		di->pll.xclk 		 = RADEON_BIOS16(pll_start + 72);
153 		di->pll.min_pll_freq = RADEON_BIOS16(pll_start + 78);
154 		di->pll.ref_freq 	 = RADEON_BIOS16(pll_start + 82);
155 
156 		SHOW_INFO( 2, "TESTING "
157 			"ref_clk=%" B_PRIu32 ", ref_div=%" B_PRIu32 ", xclk=%" B_PRIu32 ", "
158 			"min_freq=%" B_PRIu32 ", max_freq=%" B_PRIu32 " from ATOM Bios",
159 			di->pll.ref_freq, di->pll.ref_div, di->pll.xclk,
160 			di->pll.min_pll_freq, di->pll.max_pll_freq );
161 
162 		// Unused by beos driver so it appears...
163 		// info->sclk = RADEON_BIOS32(pll_info_block + 8) / 100.0;
164 		// info->mclk = RADEON_BIOS32(pll_info_block + 12) / 100.0;
165 		// if (info->sclk == 0) info->sclk = 200;
166 		// if (info->mclk == 0) info->mclk = 200;
167 
168 	}
169     else
170 	{
171 		di->is_atombios = false;
172 
173 		memcpy( &pll, pll_info, sizeof( pll ));
174 
175 		di->pll.xclk 		 = (uint32)pll.XCLK;
176 		di->pll.ref_freq 	 = (uint32)pll.PCLK_ref_freq;
177 		di->pll.ref_div 	 = (uint32)pll.PCLK_ref_divider;
178 		di->pll.min_pll_freq = pll.PCLK_min_freq;
179 		di->pll.max_pll_freq = pll.PCLK_max_freq;
180 
181 		SHOW_INFO( 2,
182 			"ref_clk=%" B_PRIu32 ", ref_div=%" B_PRIu32 ", xclk=%" B_PRIu32 ", "
183 			"min_freq=%" B_PRIu32 ", max_freq=%" B_PRIu32 " from Legacy BIOS",
184 			di->pll.ref_freq, di->pll.ref_div, di->pll.xclk,
185 			di->pll.min_pll_freq, di->pll.max_pll_freq );
186 
187 	}
188 
189 }
190 
191 /*
192 const char *Mon2Str[] = {
193 	"N/C",
194 	"CRT",
195 	"CRT",
196 	"Laptop flatpanel",
197 	"DVI (flatpanel)",
198 	"secondary DVI (flatpanel) - unsupported",
199 	"Composite TV",
200 	"S-Video out"
201 };*/
202 
203 /*
204 // ask BIOS what kind of monitor is connected to each port
205 static void Radeon_GetMonType( device_info *di )
206 {
207 	unsigned int tmp;
208 
209 	SHOW_FLOW0( 3, "" );
210 
211 	di->disp_type[0] = di->disp_type[1] = dt_none;
212 
213 	if (di->has_crtc2) {
214 		tmp = INREG( di->regs, RADEON_BIOS_4_SCRATCH );
215 
216 		// ordering of "if"s is important as multiple
217 		// devices can be concurrently connected to one port
218 		// (like both a CRT and a TV)
219 
220 		// primary port
221 		// having flat-panel support is most important
222 		if (tmp & 0x08)
223 			di->disp_type[0] = dt_dvi;
224 		else if (tmp & 0x4)
225 			di->disp_type[0] = dt_lvds;
226 		else if (tmp & 0x200)
227 			di->disp_type[0] = dt_tv_crt;
228 		else if (tmp & 0x10)
229 			di->disp_type[0] = dt_ctv;
230 		else if (tmp & 0x20)
231 			di->disp_type[0] = dt_stv;
232 
233 		// secondary port
234 		// having TV-Out support is more important then CRT support
235 		// (CRT gets signal anyway)
236 		if (tmp & 0x1000)
237 			di->disp_type[1] = dt_ctv;
238 		else if (tmp & 0x2000)
239 			di->disp_type[1] = dt_stv;
240 		else if (tmp & 0x2)
241 			di->disp_type[1] = dt_crt;
242 		else if (tmp & 0x800)
243 			di->disp_type[1] = dt_dvi_ext;
244 		else if (tmp & 0x400)
245 			// this is unlikely - I only know about one LVDS unit
246 			di->disp_type[1] = dt_lvds;
247 	} else {
248 		// regular Radeon
249 		// TBD: no TV-Out detection
250 		di->disp_type[0] = dt_none;
251 
252 		tmp = INREG( di->regs, RADEON_FP_GEN_CNTL);
253 
254 		if( tmp & RADEON_FP_EN_TMDS )
255 			di->disp_type[0] = dt_dvi;
256 		else
257 			di->disp_type[0] = dt_crt;
258 	}
259 
260 	SHOW_INFO( 1, "BIOS reports %s on primary and %s on secondary port",
261 		Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]);
262 
263 	// remove unsupported devices
264 	if( di->disp_type[0] >= dt_dvi_ext )
265 		di->disp_type[0] = dt_none;
266 	if( di->disp_type[1] >= dt_dvi_ext )
267 		di->disp_type[1] = dt_none;
268 
269 	// HACK: overlays can only be shown on first CRTC;
270 	// if there's nothing on first port, connect
271 	// second port to first CRTC (proper signal routing
272 	// is hopefully done by BIOS)
273 	if( di->has_crtc2 ) {
274 		if( di->disp_type[0] == dt_none && di->disp_type[1] == dt_crt ) {
275 			di->disp_type[0] = dt_crt;
276 			di->disp_type[1] = dt_none;
277 		}
278 	}
279 
280 	SHOW_INFO( 1, "Effective routing: %s on primary and %s on secondary port",
281 		Mon2Str[di->disp_type[0]], Mon2Str[di->disp_type[1]]);
282 }
283 */
284 
285 
Radeon_GetConnectorInfoFromBIOS(device_info * di)286 static bool Radeon_GetConnectorInfoFromBIOS ( device_info* di )
287 {
288 
289 	ptr_disp_entity ptr_entity = &di->routing;
290 	int i = 0, j, tmp, tmp0=0, tmp1=0;
291 
292 	int bios_header, master_data_start;
293 
294 	bios_header = RADEON_BIOS16(0x48);
295 
296 	if (di->is_atombios)
297 	{
298 		master_data_start = RADEON_BIOS16( bios_header + 32 );
299 		tmp = RADEON_BIOS16( master_data_start + 22);
300 		if (tmp) {
301 			int crtc = 0, id[2];
302 			tmp1 = RADEON_BIOS16( tmp + 4 );
303 			for (i=0; i<8; i++) {
304 				if(tmp1 & (1<<i)) {
305 					uint16 portinfo = RADEON_BIOS16( tmp + 6 + i * 2 );
306 					if (crtc < 2) {
307 						if ((i == 2) || (i == 6)) continue; /* ignore TV here */
308 
309 						if ( crtc == 1 ) {
310 							/* sharing same port with id[0] */
311 							if ((( portinfo >> 8) & 0xf) == id[0] ) {
312 								if (i == 3)
313 									ptr_entity->port_info[0].tmds_type = tmds_int;
314 								else if (i == 7)
315 									ptr_entity->port_info[0].tmds_type = tmds_ext;
316 
317 								if (ptr_entity->port_info[0].dac_type == dac_unknown)
318 									ptr_entity->port_info[0].dac_type = (portinfo & 0xf) - 1;
319 								continue;
320 							}
321 						}
322 
323 						id[crtc] = (portinfo>>8) & 0xf;
324 						ptr_entity->port_info[crtc].dac_type = (portinfo & 0xf) - 1;
325 						ptr_entity->port_info[crtc].connector_type = (portinfo>>4) & 0xf;
326 						if (i == 3)
327 							ptr_entity->port_info[crtc].tmds_type = tmds_int;
328 						else if (i == 7)
329 							ptr_entity->port_info[crtc].tmds_type = tmds_ext;
330 
331 						tmp0 = RADEON_BIOS16( master_data_start + 24);
332 						if( tmp0 && id[crtc] ) {
333 							switch (RADEON_BIOS16(tmp0 + 4 + 27 * id[crtc]) * 4)
334 							{
335 								case RADEON_GPIO_MONID:
336 									ptr_entity->port_info[crtc].ddc_type = ddc_monid;
337 									break;
338 								case RADEON_GPIO_DVI_DDC:
339 									ptr_entity->port_info[crtc].ddc_type = ddc_dvi;
340 									break;
341 								case RADEON_GPIO_VGA_DDC:
342 									ptr_entity->port_info[crtc].ddc_type = ddc_vga;
343 									break;
344 								case RADEON_GPIO_CRT2_DDC:
345 									ptr_entity->port_info[crtc].ddc_type = ddc_crt2;
346 									break;
347 								default:
348 									ptr_entity->port_info[crtc].ddc_type = ddc_none_detected;
349 									break;
350 							}
351 
352 						} else {
353 							ptr_entity->port_info[crtc].ddc_type = ddc_none_detected;
354 						}
355 						crtc++;
356 					} else {
357 						/* we have already had two CRTCs assigned. the rest may share the same
358 						* port with the existing connector, fill in them accordingly.
359 						*/
360 						for ( j = 0; j < 2; j++ ) {
361 							if ((( portinfo >> 8 ) & 0xf ) == id[j] ) {
362 								if ( i == 3 )
363 								ptr_entity->port_info[j].tmds_type = tmds_int;
364 								else if (i == 7)
365 								ptr_entity->port_info[j].tmds_type = tmds_ext;
366 
367 								if ( ptr_entity->port_info[j].dac_type == dac_unknown )
368 									ptr_entity->port_info[j].dac_type = ( portinfo & 0xf ) - 1;
369 							}
370 						}
371 					}
372 				}
373 			}
374 
375 			for (i=0; i<2; i++) {
376 				SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d",
377 					i, ptr_entity->port_info[i].ddc_type, ptr_entity->port_info[i].dac_type,
378 					ptr_entity->port_info[i].tmds_type, ptr_entity->port_info[i].connector_type);
379 		    }
380 		} else {
381 			SHOW_INFO0( 4 , "No Device Info Table found!");
382 			return FALSE;
383 		}
384 	} else {
385 		/* Some laptops only have one connector (VGA) listed in the connector table,
386 		* we need to add LVDS in as a non-DDC display.
387 		* Note, we can't assume the listed VGA will be filled in PortInfo[0],
388 		* when walking through connector table. connector_found has following meaning:
389 		* 0 -- nothing found,
390 		* 1 -- only PortInfo[0] filled,
391 		* 2 -- only PortInfo[1] filled,
392 		* 3 -- both are filled.
393 		*/
394 		int connector_found = 0;
395 
396 		if ((tmp = RADEON_BIOS16( bios_header + 0x50 ))) {
397 			for ( i = 1; i < 4; i++ ) {
398 
399 				if (!(RADEON_BIOS16( tmp + i * 2 )))
400 					break; /* end of table */
401 
402 				tmp0 = RADEON_BIOS16( tmp + i * 2 );
403 				if ((( tmp0 >> 12 ) & 0x0f ) == 0 )
404 					continue;     /* no connector */
405 				if (connector_found > 0) {
406 					if (ptr_entity->port_info[tmp1].ddc_type == (( tmp0 >> 8 ) & 0x0f ))
407 						continue;	/* same connector */
408 				}
409 
410 				/* internal ddc_dvi port will get assigned to portinfo[0], or if there is no ddc_dvi (like in some igps). */
411 				tmp1 = (((( tmp0 >> 8 ) & 0xf ) == ddc_dvi ) || ( tmp1 == 1 )) ? 0 : 1; /* determine port info index */
412 
413 				ptr_entity->port_info[tmp1].ddc_type = (tmp0 >> 8) & 0x0f;
414 				if (ptr_entity->port_info[tmp1].ddc_type > ddc_crt2)
415 					ptr_entity->port_info[tmp1].ddc_type = ddc_none_detected;
416 				ptr_entity->port_info[tmp1].dac_type = (tmp0 & 0x01) ? dac_tvdac : dac_primary;
417 				ptr_entity->port_info[tmp1].connector_type = (tmp0 >> 12) & 0x0f;
418 				if (ptr_entity->port_info[tmp1].connector_type > connector_unsupported)
419 					ptr_entity->port_info[tmp1].connector_type = connector_unsupported;
420 				ptr_entity->port_info[tmp1].tmds_type = ((tmp0 >> 4) & 0x01) ? tmds_ext : tmds_int;
421 
422 				/* some sanity checks */
423 				if (((ptr_entity->port_info[tmp1].connector_type != connector_dvi_d) &&
424 				(ptr_entity->port_info[tmp1].connector_type != connector_dvi_i)) &&
425 				ptr_entity->port_info[tmp1].tmds_type == tmds_int)
426 				ptr_entity->port_info[tmp1].tmds_type = tmds_unknown;
427 
428 				connector_found += (tmp1 + 1);
429 			}
430 		} else {
431 			SHOW_INFO0(4, "No Connector Info Table found!");
432 			return FALSE;
433 		}
434 
435 		if (di->is_mobility)
436 		{
437 			/* For the cases where only one VGA connector is found,
438 			we assume LVDS is not listed in the connector table,
439 			add it in here as the first port.
440 			*/
441 			if ((connector_found < 3) && (ptr_entity->port_info[tmp1].connector_type == connector_crt)) {
442 				if (connector_found == 1) {
443 					memcpy (&ptr_entity->port_info[1],
444 						&ptr_entity->port_info[0],
445 							sizeof (ptr_entity->port_info[0]));
446 				}
447 				ptr_entity->port_info[0].dac_type = dac_tvdac;
448 				ptr_entity->port_info[0].tmds_type = tmds_unknown;
449 				ptr_entity->port_info[0].ddc_type = ddc_none_detected;
450 				ptr_entity->port_info[0].connector_type = connector_proprietary;
451 
452 				SHOW_INFO0( 4 , "lvds port is not in connector table, added in.");
453 				if (connector_found == 0)
454 					connector_found = 1;
455 				else
456 					connector_found = 3;
457 			}
458 
459 			if ((tmp = RADEON_BIOS16( bios_header + 0x42 ))) {
460 				if ((tmp0 = RADEON_BIOS16( tmp + 0x15 ))) {
461 					if ((tmp1 = RADEON_BIOS16( tmp0 + 2 ) & 0x07)) {
462 						ptr_entity->port_info[0].ddc_type	= tmp1;
463 						if (ptr_entity->port_info[0].ddc_type > ddc_crt2) {
464 							SHOW_INFO( 4, "unknown ddctype %d found",
465 								ptr_entity->port_info[0].ddc_type);
466 							ptr_entity->port_info[0].ddc_type = ddc_none_detected;
467 						}
468 						SHOW_INFO0( 4, "lcd ddc info table found!");
469 					}
470 				}
471 			}
472 		} else if (connector_found == 2) {
473 			memcpy (&ptr_entity->port_info[0],
474 				&ptr_entity->port_info[1],
475 					sizeof (ptr_entity->port_info[0]));
476 			ptr_entity->port_info[1].dac_type = dac_unknown;
477 			ptr_entity->port_info[1].tmds_type = tmds_unknown;
478 			ptr_entity->port_info[1].ddc_type = ddc_none_detected;
479 			ptr_entity->port_info[1].connector_type = connector_none;
480 			connector_found = 1;
481 		}
482 
483 		if (connector_found == 0) {
484 			SHOW_INFO0( 4, "no connector found in connector info table.");
485 		} else {
486 			SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d",
487 				0, ptr_entity->port_info[0].ddc_type, ptr_entity->port_info[0].dac_type,
488 				ptr_entity->port_info[0].tmds_type, ptr_entity->port_info[0].connector_type);
489 
490 		}
491 		if (connector_found == 3) {
492 			SHOW_INFO( 2, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d",
493 				1, ptr_entity->port_info[1].ddc_type, ptr_entity->port_info[1].dac_type,
494 				ptr_entity->port_info[1].tmds_type, ptr_entity->port_info[1].connector_type);
495 		}
496 
497 	}
498 	return TRUE;
499 }
500 
501 
502 // get flat panel info (does only make sense for Laptops
503 // with integrated display, but looking for it doesn't hurt,
504 // who knows which strange kind of combination is out there?)
Radeon_GetBIOSDFPInfo(device_info * di)505 static bool Radeon_GetBIOSDFPInfo( device_info *di )
506 {
507 	uint16 bios_header;
508 	uint16 fpi_offset;
509 	FPI_BLOCK fpi;
510 	char panel_name[30];
511 	int i;
512 
513 	uint16 tmp;
514 
515 	bios_header = RADEON_BIOS16( 0x48 );
516 
517 	if (di->is_atombios)
518 	{
519 		int master_data_start;
520 		master_data_start = RADEON_BIOS16( bios_header + 32 );
521 
522 		tmp = RADEON_BIOS16( master_data_start + 16 );
523 		if( tmp )
524 		{
525 
526 		    di->fp_info.panel_xres		= RADEON_BIOS16( tmp +  6 );
527 		    di->fp_info.panel_yres		= RADEON_BIOS16( tmp + 10 );
528 		    di->fp_info.dot_clock		= RADEON_BIOS16( tmp +  4 ) * 10;
529 		    di->fp_info.h_blank			= RADEON_BIOS16( tmp +  8 );
530 		    di->fp_info.h_over_plus		= RADEON_BIOS16( tmp + 14 );
531 		    di->fp_info.h_sync_width	= RADEON_BIOS16( tmp + 16 );
532 		    di->fp_info.v_blank      	= RADEON_BIOS16( tmp + 12 );
533 			di->fp_info.v_over_plus		= RADEON_BIOS16( tmp + 18 );
534 		    di->fp_info.h_sync_width	= RADEON_BIOS16( tmp + 20 );
535 		    di->fp_info.panel_pwr_delay	= RADEON_BIOS16( tmp + 40 );
536 
537 		    SHOW_INFO( 2, "Panel Info from ATOMBIOS:\n"
538 					"XRes: %d, YRes: %d, DotClock: %d\n"
539 					"HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
540 					"VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n"
541 					"PanelPowerDelay: %d\n",
542 					di->fp_info.panel_xres,	di->fp_info.panel_yres,	di->fp_info.dot_clock,
543 					di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width,
544 					di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.h_sync_width,
545 					di->fp_info.panel_pwr_delay	);
546 
547 		}
548 		else
549 		{
550 		    di->fp_info.panel_pwr_delay = 200;
551 			SHOW_ERROR0( 2, "No Panel Info Table found in BIOS" );
552 			return false;
553 		}
554 	} // is_atombios
555 	else
556 	{
557 
558 		fpi_offset = RADEON_BIOS16(bios_header + 0x40);
559 
560 		if( !fpi_offset ) {
561 			di->fp_info.panel_pwr_delay = 200;
562 			SHOW_ERROR0( 2, "No Panel Info Table found in BIOS" );
563 			return false;
564 		}
565 
566 		memcpy( &fpi, di->rom.rom_ptr + fpi_offset, sizeof( fpi ));
567 
568 		memcpy( panel_name, &fpi.name, sizeof( fpi.name ) );
569 		panel_name[sizeof( fpi.name )] = 0;
570 
571 		SHOW_INFO( 2, "Panel ID string: %s", panel_name );
572 
573 		di->fp_info.panel_xres = fpi.panel_xres;
574 		di->fp_info.panel_yres = fpi.panel_yres;
575 
576 		SHOW_INFO( 2, "Panel Size from BIOS: %dx%d",
577 			di->fp_info.panel_xres, di->fp_info.panel_yres);
578 
579 		di->fp_info.panel_pwr_delay = fpi.panel_pwr_delay;
580 		if( di->fp_info.panel_pwr_delay > 2000 || di->fp_info.panel_pwr_delay < 0 )
581 			di->fp_info.panel_pwr_delay = 2000;
582 
583 		di->fp_info.ref_div = fpi.ref_div;
584 		di->fp_info.post_div = fpi.post_div;
585 		di->fp_info.feedback_div = fpi.feedback_div;
586 
587 		di->fp_info.fixed_dividers =
588 			di->fp_info.ref_div != 0 && di->fp_info.feedback_div > 3;
589 
590 
591 		// there might be multiple supported resolutions stored;
592 		// we are looking for native resolution
593 		for( i = 0; i < 20; ++i ) {
594 			uint16 fpi_timing_ofs;
595 			FPI_TIMING_BLOCK fpi_timing;
596 
597 			fpi_timing_ofs = fpi.fpi_timing_ofs[i];
598 
599 			if( fpi_timing_ofs == 0 )
600 				break;
601 
602 			memcpy( &fpi_timing, di->rom.rom_ptr + fpi_timing_ofs, sizeof( fpi_timing ));
603 
604 			if( fpi_timing.panel_xres != di->fp_info.panel_xres ||
605 				fpi_timing.panel_yres != di->fp_info.panel_yres )
606 				continue;
607 
608 			di->fp_info.h_blank			= (fpi_timing.h_total - fpi_timing.h_display) * 8;
609 			// TBD: seems like upper four bits of hsync_start contain garbage
610 			di->fp_info.h_over_plus 	= ((fpi_timing.h_sync_start & 0xfff) - fpi_timing.h_display - 1) * 8;
611 			di->fp_info.h_sync_width 	= fpi_timing.h_sync_width * 8;
612 			di->fp_info.v_blank			= fpi_timing.v_total - fpi_timing.v_display;
613 			di->fp_info.v_over_plus 	= (fpi_timing.v_sync & 0x7ff) - fpi_timing.v_display;
614 			di->fp_info.v_sync_width 	= (fpi_timing.v_sync & 0xf800) >> 11;
615 			di->fp_info.dot_clock 		= fpi_timing.dot_clock * 10;
616 			return true;
617 		}
618 	} // not is_atombios
619 
620 	SHOW_ERROR0( 2, "Radeon: couldn't get Panel Timing from BIOS" );
621 	return false;
622 }
623 
624 
625 // try to reverse engineer DFP specification from
626 // timing currently set up in graphics cards registers
627 // (effectively, we hope that BIOS has set it up correctly
628 //  and noone has messed registers up yet; let's pray)
Radeon_RevEnvDFPSize(device_info * di)629 static void Radeon_RevEnvDFPSize( device_info *di )
630 {
631 	vuint8 *regs = di->regs;
632 
633 	di->fp_info.panel_yres =
634 		((INREG( regs, RADEON_FP_VERT_STRETCH ) & RADEON_VERT_PANEL_SIZE)
635 		>> RADEON_VERT_PANEL_SIZE_SHIFT) + 1;
636 
637 	di->fp_info.panel_xres =
638 		(((INREG( regs, RADEON_FP_HORZ_STRETCH ) & RADEON_HORZ_PANEL_SIZE)
639 		>> RADEON_HORZ_PANEL_SIZE_SHIFT) + 1) * 8;
640 
641 	SHOW_INFO( 2, "detected panel size from registers: %dx%d",
642 		di->fp_info.panel_xres, di->fp_info.panel_yres);
643 }
644 
645 
646 // once more for getting precise timing
Radeon_RevEnvDFPTiming(device_info * di)647 static void Radeon_RevEnvDFPTiming( device_info *di )
648 {
649 	vuint8 *regs = di->regs;
650 	uint32 r;
651 	uint16 a, b;
652 
653 
654 	r = INREG( regs, RADEON_FP_CRTC_H_TOTAL_DISP );
655 	// the magic "4" was found by trial and error and probably stems from fudge (see crtc.c)
656 	a = (r & RADEON_FP_CRTC_H_TOTAL_MASK)/* + 4*/;
657 	b = (r & RADEON_FP_CRTC_H_DISP_MASK) >> RADEON_FP_CRTC_H_DISP_SHIFT;
658 	di->fp_info.h_blank = (a - b) * 8;
659 
660 	SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 );
661 
662 	r = INREG( regs, RADEON_FP_H_SYNC_STRT_WID );
663 	di->fp_info.h_over_plus =
664 		((r & RADEON_FP_H_SYNC_STRT_CHAR_MASK)
665 			  	>> RADEON_FP_H_SYNC_STRT_CHAR_SHIFT) - b/* - 1*/;
666 	di->fp_info.h_over_plus *= 8;
667 	di->fp_info.h_sync_width =
668 		((r & RADEON_FP_H_SYNC_WID_MASK)
669 				>> RADEON_FP_H_SYNC_WID_SHIFT);
670 	// TBD: this seems to be wrong
671 	// (my BIOS tells 112, this calculation leads to 24!)
672 	di->fp_info.h_sync_width *= 8;
673 
674 	r = INREG( regs, RADEON_FP_CRTC_V_TOTAL_DISP );
675 	a = (r & RADEON_FP_CRTC_V_TOTAL_MASK)/* + 1*/;
676 	b = (r & RADEON_FP_CRTC_V_DISP_MASK) >> RADEON_FP_CRTC_V_DISP_SHIFT;
677 	di->fp_info.v_blank = a - b;
678 
679 	SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b );
680 
681 	r = INREG( regs, RADEON_FP_V_SYNC_STRT_WID );
682 	di->fp_info.v_over_plus = (r & RADEON_FP_V_SYNC_STRT_MASK) - b;
683 	di->fp_info.v_sync_width = ((r & RADEON_FP_V_SYNC_WID_MASK)
684 		>> RADEON_FP_V_SYNC_WID_SHIFT)/* + 1*/;
685 
686 	// standard CRTC
687 	r = INREG( regs, RADEON_CRTC_H_TOTAL_DISP );
688 	a = (r & RADEON_CRTC_H_TOTAL);
689 	b = (r & RADEON_CRTC_H_DISP) >> RADEON_CRTC_H_DISP_SHIFT;
690 	di->fp_info.h_blank = (a - b) * 8;
691 
692 	SHOW_FLOW( 2, "h_total=%d, h_disp=%d", a * 8, b * 8 );
693 
694 	r = INREG( regs, RADEON_CRTC_H_SYNC_STRT_WID );
695 	di->fp_info.h_over_plus =
696 		((r & RADEON_CRTC_H_SYNC_STRT_CHAR)
697 			  	>> RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) - b;
698 	di->fp_info.h_over_plus *= 8;
699 	di->fp_info.h_sync_width =
700 		((r & RADEON_CRTC_H_SYNC_WID)
701 				>> RADEON_CRTC_H_SYNC_WID_SHIFT);
702 	di->fp_info.h_sync_width *= 8;
703 
704 	r = INREG( regs, RADEON_CRTC_V_TOTAL_DISP );
705 	a = (r & RADEON_CRTC_V_TOTAL);
706 	b = (r & RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT;
707 	di->fp_info.v_blank = a - b;
708 
709 	SHOW_FLOW( 2, "v_total=%d, v_disp=%d", a, b );
710 
711 	r = INREG( regs, RADEON_CRTC_V_SYNC_STRT_WID );
712 	di->fp_info.v_over_plus = (r & RADEON_CRTC_V_SYNC_STRT) - b;
713 	di->fp_info.v_sync_width = ((r & RADEON_CRTC_V_SYNC_WID)
714 		>> RADEON_CRTC_V_SYNC_WID_SHIFT);
715 }
716 
717 //snaffled from X.org hope it works...
Radeon_GetTMDSInfoFromBios(device_info * di)718 static void Radeon_GetTMDSInfoFromBios( device_info *di )
719 {
720     uint32 tmp, maxfreq;
721     uint32 found = FALSE;
722     int i, n;
723     uint16 bios_header;
724 
725     bios_header = RADEON_BIOS16( 0x48 );
726 
727 	for (i = 0; i < 4; i++) {
728         di->tmds_pll[i].value = 0;
729         di->tmds_pll[i].freq = 0;
730     }
731 
732 	if (di->is_atombios)
733 	{
734 		int master_data_start;
735 		master_data_start = RADEON_BIOS16( bios_header + 32 );
736 
737 		if((tmp = RADEON_BIOS16 (master_data_start + 18))) {
738 
739 		    maxfreq = RADEON_BIOS16(tmp + 4);
740 
741 		    for (i = 0; i < 4; i++) {
742 				di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 6 + 6);
743 				// This assumes each field in TMDS_PLL has 6 bit as in R300/R420
744 				di->tmds_pll[i].value = ((RADEON_BIOS8(tmp + i * 6 + 8) & 0x3f) |
745 				   ((RADEON_BIOS8(tmp + i * 6 + 10) & 0x3f) << 6) |
746 				   ((RADEON_BIOS8(tmp + i * 6 +  9) & 0xf) << 12) |
747 				   ((RADEON_BIOS8(tmp + i * 6 + 11) & 0xf) << 16));
748 				SHOW_ERROR( 2, "TMDS PLL from BIOS: %" B_PRIu32 " %" B_PRIx32,
749 				   di->tmds_pll[i].freq, di->tmds_pll[i].value);
750 
751 				if (maxfreq == di->tmds_pll[i].freq) {
752 				    di->tmds_pll[i].freq = 0xffffffff;
753 				    break;
754 				}
755 		    }
756 		    found = TRUE;
757 		}
758     } else {
759 
760 		tmp = RADEON_BIOS16(bios_header + 0x34);
761 		if (tmp) {
762 		    SHOW_ERROR( 2, "DFP table revision: %d", RADEON_BIOS8(tmp));
763 		    if (RADEON_BIOS8(tmp) == 3) {
764 				n = RADEON_BIOS8(tmp + 5) + 1;
765 				if (n > 4)
766 					n = 4;
767 				for (i = 0; i < n; i++) {
768 					di->tmds_pll[i].value = RADEON_BIOS32(tmp + i * 10 + 0x08);
769 					di->tmds_pll[i].freq = RADEON_BIOS16(tmp + i * 10 + 0x10);
770 				}
771 				found = TRUE;
772 		    } else if (RADEON_BIOS8(tmp) == 4) {
773 		        int stride = 0;
774 				n = RADEON_BIOS8(tmp + 5) + 1;
775 				if (n > 4)
776 					n = 4;
777 				for (i = 0; i < n; i++) {
778 				    di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08);
779 				    di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10);
780 				    if (i == 0)
781 				    	stride += 10;
782 				    else
783 				    	stride += 6;
784 				}
785 				found = TRUE;
786 		    }
787 
788 		    // revision 4 has some problem as it appears in RV280,
789 		    // comment it off for now, use default instead
790 			/*
791 				else if (RADEON_BIOS8(tmp) == 4) {
792 				int stride = 0;
793 				n = RADEON_BIOS8(tmp + 5) + 1;
794 				if (n > 4) n = 4;
795 				for (i = 0; i < n; i++) {
796 					di->tmds_pll[i].value = RADEON_BIOS32(tmp + stride + 0x08);
797 					di->tmds_pll[i].freq = RADEON_BIOS16(tmp + stride + 0x10);
798 					if (i == 0)
799 						stride += 10;
800 					else
801 						stride += 6;
802 				}
803 				found = TRUE;
804 			}
805 			*/
806 
807 		}
808     }
809 
810     if (found == FALSE) {
811     	for (i = 0; i < 4; i++) {
812 	        di->tmds_pll[i].value = default_tmds_pll[di->asic][i].value;
813 	        di->tmds_pll[i].freq = default_tmds_pll[di->asic][i].freq;
814 	        SHOW_ERROR( 2, "TMDS PLL from DEFAULTS: %" B_PRIu32 " %" B_PRIx32,
815 				di->tmds_pll[i].freq, di->tmds_pll[i].value);
816     	}
817     }
818 }
819 
820 /*
821 // get everything in terms of monitors connected to the card
822 static void Radeon_GetBIOSMon( device_info *di )
823 {
824 	Radeon_GetMonType( di );
825 
826     // reset all Flat Panel Info;
827     // it gets filled out step by step, and this way we know what's still missing
828     memset( &di->fp_info, 0, sizeof( di->fp_info ));
829 
830     // we assume that the only fp port is combined with standard port 0
831 	di->fp_info.disp_type = di->disp_type[0];
832 
833 	if( di->is_mobility ) {
834 		// there is a flat panel - get info about it
835 		Radeon_GetBIOSDFPInfo( di );
836 
837 		// if BIOS doesn't know, ask the registers
838 		if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0)
839 			Radeon_RevEnvDFPSize( di );
840 
841 		if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0)
842 			Radeon_RevEnvDFPTiming( di );
843 
844 		SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d",
845 			di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width );
846 		SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d",
847 			di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width );
848 		SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock );
849 	}
850 }
851 */
852 
853 // get info about Laptop flat panel
Radeon_GetFPData(device_info * di)854 static void Radeon_GetFPData( device_info *di )
855 {
856     // reset all Flat Panel Info;
857     // it gets filled out step by step, and this way we know what's still missing
858     memset( &di->fp_info, 0, sizeof( di->fp_info ));
859 
860 	// we only use BIOS for Laptop flat panels
861 	if( !di->is_mobility )
862 		return;
863 
864 	// ask BIOS about flat panel spec
865 	Radeon_GetBIOSDFPInfo( di );
866 
867 	// if BIOS doesn't know, ask the registers
868 	if( di->fp_info.panel_xres == 0 || di->fp_info.panel_yres == 0)
869 		Radeon_RevEnvDFPSize( di );
870 
871 	if( di->fp_info.h_blank == 0 || di->fp_info.v_blank == 0)
872 		Radeon_RevEnvDFPTiming( di );
873 
874 	SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d",
875 		di->fp_info.panel_xres, di->fp_info.h_blank, di->fp_info.h_over_plus, di->fp_info.h_sync_width );
876 	SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d",
877 		di->fp_info.panel_yres, di->fp_info.v_blank, di->fp_info.v_over_plus, di->fp_info.v_sync_width );
878 	SHOW_INFO( 2, "pixel_clock=%d", di->fp_info.dot_clock );
879 }
880 
881 
882 // Depending on card genertation, chipset bugs, etc... the amount of vram
883 // accessible to the CPU can vary. This function is our best shot at figuring
884 // it out. Returns a value in KB.
RADEON_GetAccessibleVRAM(device_info * di)885 static uint32 RADEON_GetAccessibleVRAM( device_info *di )
886 {
887 	vuint8 *regs = di->regs;
888 	pci_info *pcii = &(di->pcii);
889 
890     uint32 aper_size = INREG( regs, RADEON_CONFIG_APER_SIZE );
891 
892     // Set HDP_APER_CNTL only on cards that are known not to be broken,
893     // that is has the 2nd generation multifunction PCI interface
894     if (di->asic == rt_rv280 ||
895 		di->asic == rt_rv350 ||
896 		di->asic == rt_rv380 ||
897 		di->asic == rt_r420  ) {
898 			OUTREGP( regs, RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL,
899 		     ~RADEON_HDP_APER_CNTL);
900 	    SHOW_INFO0( 0, "Generation 2 PCI interface, using max accessible memory");
901 	    return aper_size * 2;
902     }
903 
904     // Older cards have all sorts of funny issues to deal with. First
905     // check if it's a multifunction card by reading the PCI config
906     // header type... Limit those to one aperture size
907     if (get_pci(PCI_header_type, 1) & 0x80) {
908 		SHOW_INFO0( 0, "Generation 1 PCI interface in multifunction mode"
909 				", accessible memory limited to one aperture\n");
910 		return aper_size;
911     }
912 
913     // Single function older card. We read HDP_APER_CNTL to see how the BIOS
914     // have set it up. We don't write this as it's broken on some ASICs but
915     // we expect the BIOS to have done the right thing (might be too optimistic...)
916     if (INREG( regs, RADEON_HOST_PATH_CNTL ) & RADEON_HDP_APER_CNTL )
917         return aper_size * 2;
918 
919     return aper_size;
920 }
921 
922 
923 // detect amount of graphics memory
Radeon_DetectRAM(device_info * di)924 static void Radeon_DetectRAM( device_info *di )
925 {
926 	vuint8 *regs = di->regs;
927 	uint32 accessible, bar_size, tmp = 0;
928 
929 	if( di->is_igp	) {
930 		uint32 tom;
931 
932 		tom = INREG( regs, RADEON_NB_TOM );
933 		di->local_mem_size = ((tom >> 16) + 1 - (tom & 0xffff)) << 16;
934 		OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size * 1024);
935 	} else {
936 		di->local_mem_size = INREG( regs, RADEON_CONFIG_MEMSIZE ) & RADEON_CONFIG_MEMSIZE_MASK;
937 	}
938 
939 	// some production boards of m6 will return 0 if it's 8 MB
940 	if( di->local_mem_size == 0 ) {
941 		di->local_mem_size = 8 * 1024 *1024;
942 		OUTREG( regs, RADEON_CONFIG_MEMSIZE, di->local_mem_size);
943 	}
944 
945 
946 	// Get usable Vram, after asic bugs, configuration screw ups etc
947 	accessible = RADEON_GetAccessibleVRAM( di );
948 
949 	// Crop it to the size of the PCI BAR
950 	bar_size = di->pcii.u.h0.base_register_sizes[0];
951 	if (bar_size == 0)
952 	    bar_size = 0x200000;
953 	if (accessible > bar_size)
954 	    accessible = bar_size;
955 
956 	SHOW_INFO( 0,
957 		"Detected total video RAM=%" B_PRIu32 "K, "
958 		"accessible=%" B_PRIu32 "K "
959 		"(PCI BAR=%" B_PRIu32 "K)",
960 		di->local_mem_size / 1024,
961 		accessible / 1024,
962 		bar_size / 1024);
963 	if (di->local_mem_size > accessible)
964 	    di->local_mem_size = accessible;
965 
966 	// detect ram bus width only used by dynamic clocks for now.
967 	tmp = INREG( regs, RADEON_MEM_CNTL );
968 	if (IS_DI_R300_VARIANT) {
969 		tmp &=  R300_MEM_NUM_CHANNELS_MASK;
970 		switch (tmp) {
971 			case 0: di->ram.width = 64; break;
972 			case 1: di->ram.width = 128; break;
973 			case 2: di->ram.width = 256; break;
974 			default: di->ram.width = 128; break;
975 		}
976 	} else if ( (di->asic >= rt_rv100) ||
977 				(di->asic >= rt_rs100) ||
978 				(di->asic >= rt_rs200)) {
979 		if (tmp & RV100_HALF_MODE)
980 			di->ram.width = 32;
981 		else
982 			di->ram.width = 64;
983 	} else {
984 		if (tmp & RADEON_MEM_NUM_CHANNELS_MASK)
985 			di->ram.width = 128;
986 		else
987 			di->ram.width = 64;
988 	}
989 
990 	if (di->is_igp || (di->asic >= rt_r300))
991 	{
992 		uint32 mem_type = INREG( regs, RADEON_MEM_SDRAM_MODE_REG ) & RADEON_MEM_CFG_TYPE_MASK;
993 		if ( mem_type == RADEON_MEM_CFG_SDR) {
994 				// SDR SGRAM (2:1)
995 				strcpy(di->ram_type, "SDR SGRAM");
996 				di->ram.ml = 4;
997 				di->ram.MB = 4;
998 				di->ram.Trcd = 1;
999 				di->ram.Trp = 2;
1000 				di->ram.Twr = 1;
1001 				di->ram.CL = 2;
1002 				di->ram.loop_latency = 16;
1003 				di->ram.Rloop = 16;
1004 				di->ram.Tr2w = 0;
1005 		} else {  // RADEON_MEM_CFG_DDR
1006 				// DDR SGRAM
1007 				strcpy(di->ram_type, "DDR SGRAM");
1008 				di->ram.ml = 4;
1009 				di->ram.MB = 4;
1010 				di->ram.Trcd = 3;
1011 				di->ram.Trp = 3;
1012 				di->ram.Twr = 2;
1013 				di->ram.CL = 3;
1014 				di->ram.Tr2w = 1;
1015 				di->ram.loop_latency = 16;
1016 				di->ram.Rloop = 16;
1017 		}
1018 	}
1019 
1020 	SHOW_INFO( 1, "%" B_PRIu32 " MB %s found on %d wide bus",
1021 		di->local_mem_size / 1024 / 1024, di->ram_type, di->ram.width);
1022 
1023 /*	if( di->local_mem_size > 64 * 1024 * 1024 ) {
1024 		di->local_mem_size = 64 * 1024 * 1024;
1025 
1026 		SHOW_INFO0( 1, "restricted to 64 MB" );
1027 	}*/
1028 }
1029 
1030 
1031 // map and verify card's BIOS to see whether this really is a Radeon
1032 // (as we need BIOS for further info we have to make sure we use the right one)
Radeon_MapBIOS(pci_info * pcii,rom_info * ri)1033 status_t Radeon_MapBIOS( pci_info *pcii, rom_info *ri )
1034 {
1035 	char buffer[100];
1036 
1037 	sprintf(buffer, "%04X_%04X_%02X%02X%02X bios",
1038 		pcii->vendor_id, pcii->device_id,
1039 		pcii->bus, pcii->device, pcii->function);
1040 
1041 	// we only scan BIOS at legacy location in first MB;
1042 	// using the PCI location would improve detection, especially
1043 	// if multiple graphics cards are installed
1044 	// BUT: BeOS uses the first graphics card it finds (sorted by
1045 	// device name), thus you couldn't choose in BIOS which card
1046 	// to use; checking the legacy location ensures that the card is
1047 	// only detected if it's the primary card
1048 	ri->phys_address = 0xc0000;
1049 	ri->size = 0x40000;
1050 
1051 	ri->bios_area = map_physical_memory( buffer, ri->phys_address,
1052 		ri->size, B_ANY_KERNEL_ADDRESS, B_READ_AREA, (void **)&ri->bios_ptr );
1053 	if( ri->bios_area < 0 )
1054 		return ri->bios_area;
1055 
1056 	ri->rom_ptr = Radeon_FindRom( ri );
1057 
1058 	// on success, adjust physical address to found ROM
1059 	if( ri->rom_ptr != NULL )
1060 		ri->phys_address += ri->rom_ptr - ri->bios_ptr;
1061 
1062 	return ri->rom_ptr != NULL ? B_OK : B_ERROR;
1063 }
1064 
1065 
1066 // unmap card's BIOS
Radeon_UnmapBIOS(rom_info * ri)1067 void Radeon_UnmapBIOS( rom_info *ri )
1068 {
1069 	delete_area( ri->bios_area );
1070 
1071 	ri->bios_ptr = ri->rom_ptr = NULL;
1072 }
1073 
1074 
1075 // get everything valuable from BIOS (BIOS must be mapped)
Radeon_ReadBIOSData(device_info * di)1076 status_t Radeon_ReadBIOSData( device_info *di )
1077 {
1078 	shared_info dummy_si;
1079 	status_t result = B_OK;
1080 
1081 	// give Radeon_MapDevice something to play with
1082 	di->si = &dummy_si;
1083 
1084 	// don't map frame buffer - we don't know its proper size yet!
1085 	result = Radeon_MapDevice( di, true );
1086 	if( result < 0 )
1087 		goto err1;
1088 
1089 	Radeon_GetPLLInfo( di );
1090 
1091 	// setup defaults
1092 	di->routing.port_info[0].mon_type = mt_unknown;
1093 	di->routing.port_info[0].ddc_type = ddc_none_detected;
1094 	di->routing.port_info[0].dac_type = dac_unknown;
1095 	di->routing.port_info[0].tmds_type = tmds_unknown;
1096 	di->routing.port_info[0].connector_type = connector_none;
1097 
1098 	di->routing.port_info[1].mon_type = mt_unknown;
1099 	di->routing.port_info[1].ddc_type = ddc_none_detected;
1100 	di->routing.port_info[1].dac_type = dac_unknown;
1101 	di->routing.port_info[1].tmds_type = tmds_unknown;
1102 	di->routing.port_info[1].connector_type = connector_none;
1103 
1104 	if ( !Radeon_GetConnectorInfoFromBIOS( di ) )
1105 	{
1106 		di->routing.port_info[0].mon_type = mt_unknown;
1107 		di->routing.port_info[0].ddc_type = ddc_none_detected;
1108 		di->routing.port_info[0].dac_type = dac_tvdac;
1109 		di->routing.port_info[0].tmds_type = tmds_unknown;
1110 		di->routing.port_info[0].connector_type = connector_proprietary;
1111 
1112 		di->routing.port_info[1].mon_type = mt_unknown;
1113 		di->routing.port_info[1].ddc_type = ddc_none_detected;
1114 		di->routing.port_info[1].dac_type = dac_primary;
1115 		di->routing.port_info[1].tmds_type = tmds_ext;
1116 		di->routing.port_info[1].connector_type = connector_crt;
1117 
1118 	}
1119 	Radeon_GetFPData( di );
1120 	Radeon_GetTMDSInfoFromBios( di );
1121 	Radeon_DetectRAM( di );
1122 
1123 	Radeon_UnmapDevice( di );
1124 
1125 err1:
1126 	di->si = NULL;
1127 
1128 	return result;
1129 }
1130