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
40static const char ati_rom_sig[] = "761295520";
41
42static 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
72static 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
118static 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/*
192const 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
205static 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
286static 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?)
505static 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)
629static 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
647static 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...
718static 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
822static 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
854static 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.
885static 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
924static 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)
1033status_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
1067void 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)
1076status_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
1125err1:
1126	di->si = NULL;
1127
1128	return result;
1129}
1130