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