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