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