2 * Copyright 2002-2004, Thomas Kurschel. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
7 Radeon monitor detection
13 #include "radeon_accelerant.h"
15 #include "crtc_regs.h"
18 #include "tv_out_regs.h"
19 #include "config_regs.h"
21 #include "gpiopad_regs.h"
23 #include "pll_access.h"
24 #include "theatre_regs.h"
37 get_signals(void *cookie
, int *clk
, int *data
)
39 ddc_port_info
*info
= (ddc_port_info
*)cookie
;
40 vuint8
*regs
= info
->ai
->regs
;
43 value
= INREG(regs
, info
->port
);
44 *clk
= (value
>> RADEON_GPIO_Y_SHIFT_1
) & 1;
45 *data
= (value
>> RADEON_GPIO_Y_SHIFT_0
) & 1;
53 set_signals(void *cookie
, int clk
, int data
)
55 ddc_port_info
*info
= (ddc_port_info
*)cookie
;
56 vuint8
*regs
= info
->ai
->regs
;
59 value
= INREG(regs
, info
->port
);
60 value
&= ~(RADEON_GPIO_A_1
| RADEON_GPIO_A_0
);
61 value
&= ~(RADEON_GPIO_EN_0
| RADEON_GPIO_EN_1
);
62 value
|= ((1-clk
) << RADEON_GPIO_EN_SHIFT_1
)
63 | ((1-data
) << RADEON_GPIO_EN_SHIFT_0
);
65 OUTREG(regs
, info
->port
, value
);
70 /*! Read EDID information from monitor
71 ddc_port - register to use for DDC2 communication
74 Radeon_ReadEDID(accelerator_info
*ai
, uint32 ddcPort
, edid1_info
*edid
)
84 ddc2_init_timing(&bus
);
86 bus
.set_signals
= &set_signals
;
87 bus
.get_signals
= &get_signals
;
89 if (ddc2_read_edid1(&bus
, edid
, &vdif
, &vdifLength
) != B_OK
)
92 SHOW_FLOW(2, "Found DDC-capable monitor @0x%04x", ddcPort
);
99 // search for display connect to CRT DAC
100 // colour - true, if only a colour monitor is to be accepted
102 Radeon_DetectCRTInt(accelerator_info
*ai
, bool colour
)
104 vuint8
*regs
= ai
->regs
;
105 uint32 old_crtc_ext_cntl
, old_dac_ext_cntl
, old_dac_cntl
, value
;
108 // makes sure there is a signal
109 old_crtc_ext_cntl
= INREG(regs
, RADEON_CRTC_EXT_CNTL
);
111 value
= old_crtc_ext_cntl
| RADEON_CRTC_CRT_ON
;
112 OUTREG(regs
, RADEON_CRTC_EXT_CNTL
, value
);
114 // force DAC to output constant voltage
115 // for colour monitors, RGB is tested, for B/W only G
116 old_dac_ext_cntl
= INREG(regs
, RADEON_DAC_EXT_CNTL
);
118 value
= RADEON_DAC_FORCE_BLANK_OFF_EN
| RADEON_DAC_FORCE_DATA_EN
119 | (colour
? RADEON_DAC_FORCE_DATA_SEL_RGB
: RADEON_DAC_FORCE_DATA_SEL_G
)
120 | (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT
);
121 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, value
);
123 // enable DAC and tell it to use VGA signals
124 old_dac_cntl
= INREG(regs
, RADEON_DAC_CNTL
);
126 value
= old_dac_cntl
& ~(RADEON_DAC_RANGE_CNTL_MASK
| RADEON_DAC_PDWN
);
127 value
|= RADEON_DAC_RANGE_CNTL_PS2
| RADEON_DAC_CMP_EN
;
128 OUTREG(regs
, RADEON_DAC_CNTL
, value
);
130 // specs says that we should wait 1µs before checking but sample
131 // code uses 2 ms; we use long delay to be on safe side
132 // (though we don't want to make it too long as the monitor
133 // gets no sync signal now)
136 // let's see whether there is some
137 found
= (INREG(regs
, RADEON_DAC_CNTL
) & RADEON_DAC_CMP_OUTPUT
) != 0;
139 SHOW_INFO(2, "Found %s CRT connected to CRT-DAC",
140 colour
? "colour" : "b/w");
143 OUTREG(regs
, RADEON_DAC_CNTL
, old_dac_cntl
);
144 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, old_dac_ext_cntl
);
145 OUTREG(regs
, RADEON_CRTC_EXT_CNTL
, old_crtc_ext_cntl
);
151 //! Check whethere there is a CRT connected to CRT DAC
153 Radeon_DetectCRT(accelerator_info
*ai
)
155 vuint32 old_vclk_ecp_cntl
, value
;
158 // enforce clock so the DAC gets activated
159 old_vclk_ecp_cntl
= Radeon_INPLL(ai
->regs
, ai
->si
->asic
,
160 RADEON_VCLK_ECP_CNTL
);
162 value
= old_vclk_ecp_cntl
163 & ~(RADEON_PIXCLK_ALWAYS_ONb
| RADEON_PIXCLK_DAC_ALWAYS_ONb
);
164 Radeon_OUTPLL(ai
->regs
, ai
->si
->asic
, RADEON_VCLK_ECP_CNTL
, value
);
166 // search first for colour, then for B/W monitor
167 found
= Radeon_DetectCRTInt(ai
, true) || Radeon_DetectCRTInt(ai
, false);
169 Radeon_OUTPLL(ai
->regs
, ai
->si
->asic
, RADEON_VCLK_ECP_CNTL
,
176 //! CRT on TV-DAC detection for rv200 and below checked for rv200
178 Radeon_DetectTVCRT_RV200(accelerator_info
*ai
)
180 vuint8
*regs
= ai
->regs
;
181 uint32 old_crtc2_gen_cntl
, old_tv_dac_cntl
, old_dac_cntl2
, value
;
184 // enable CRTC2, setting 8 bpp (we just pick any valid value)
185 old_crtc2_gen_cntl
= INREG(regs
, RADEON_CRTC2_GEN_CNTL
);
187 value
= old_crtc2_gen_cntl
& ~RADEON_CRTC2_PIX_WIDTH_MASK
;
188 value
|= RADEON_CRTC2_CRT2_ON
| (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT
);
189 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, value
);
191 // enable TV-DAC, choosing VGA signal level
192 old_tv_dac_cntl
= INREG(regs
, RADEON_TV_DAC_CNTL
);
194 value
= RADEON_TV_DAC_CNTL_NBLANK
| RADEON_TV_DAC_CNTL_NHOLD
195 | RADEON_TV_DAC_CNTL_DETECT
| RADEON_TV_DAC_CNTL_STD_PS2
;
196 OUTREG(regs
, RADEON_TV_DAC_CNTL
, value
);
198 // enforce constant DAC output voltage on RGB
199 value
= RADEON_DAC2_FORCE_BLANK_OFF_EN
| RADEON_DAC2_FORCE_DATA_EN
200 | RADEON_DAC_FORCE_DATA_SEL_RGB
201 | (0x180 << RADEON_DAC_FORCE_DATA_SHIFT
);
202 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, value
);
204 old_dac_cntl2
= INREG(regs
, RADEON_DAC_CNTL2
);
206 // set DAC in CRT mode and enable detection
207 // TODO: make sure we really use CRTC2 - this is ASIC dependant
208 value
= old_dac_cntl2
| RADEON_DAC2_CLK_SEL_CRT
| RADEON_DAC2_CMP_EN
;
209 OUTREG(regs
, RADEON_DAC_CNTL2
, value
);
213 // let's see what we've got!
214 found
= (INREG(regs
, RADEON_DAC_CNTL2
) & RADEON_DAC2_CMP_OUTPUT
) != 0;
216 SHOW_INFO0(2, "Found CRT connected to TV-DAC, i.e. DVI port");
218 OUTREG(regs
, RADEON_DAC_CNTL2
, old_dac_cntl2
);
219 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, 0);
220 OUTREG(regs
, RADEON_TV_DAC_CNTL
, old_tv_dac_cntl
);
221 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, old_crtc2_gen_cntl
);
227 //! CRT on TV-DAC detection for r300 checked for r300
229 Radeon_DetectTVCRT_R300(accelerator_info
*ai
)
231 vuint8
*regs
= ai
->regs
;
232 uint32 old_crtc2_gen_cntl
, old_tv_dac_cntl
, old_dac_cntl2
, value
;
233 uint32 old_radeon_gpiopad_a
;
236 old_radeon_gpiopad_a
= INREG(regs
, RADEON_GPIOPAD_A
);
238 // whatever these flags mean - let's pray they won't get changed
239 OUTREGP(regs
, RADEON_GPIOPAD_EN
, 1, ~1);
240 OUTREGP(regs
, RADEON_GPIOPAD_MASK
, 1, ~1);
241 OUTREGP(regs
, RADEON_GPIOPAD_A
, 1, ~1);
243 old_crtc2_gen_cntl
= INREG(regs
, RADEON_CRTC2_GEN_CNTL
);
245 // enable DAC, choose valid pixel format and enable DPMS
246 // as usual, the code doesn't take into account whether the TV-DAC
247 // does really use CRTC2
248 value
= old_crtc2_gen_cntl
;
249 value
&= ~RADEON_CRTC2_PIX_WIDTH_MASK
;
250 value
|= (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT
) | RADEON_CRTC2_CRT2_ON
251 | RADEON_CRTC2_VSYNC_TRISTAT
;
252 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, value
);
254 old_tv_dac_cntl
= INREG(regs
, RADEON_TV_DAC_CNTL
);
257 OUTREG(regs
, RADEON_TV_DAC_CNTL
, RADEON_TV_DAC_CNTL_NBLANK
258 | RADEON_TV_DAC_CNTL_NHOLD
| RADEON_TV_DAC_CNTL_DETECT
259 | RADEON_TV_DAC_CNTL_STD_PS2
);
261 // force constant voltage output of DAC for impedance test
262 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, RADEON_DAC2_FORCE_BLANK_OFF_EN
263 | RADEON_DAC2_FORCE_DATA_EN
| RADEON_DAC_FORCE_DATA_SEL_RGB
264 | (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT
));
266 old_dac_cntl2
= INREG(regs
, RADEON_DAC_CNTL2
);
268 // enable CRT mode of TV-DAC and enable comparator
269 OUTREG(regs
, RADEON_DAC_CNTL2
, old_dac_cntl2
| RADEON_DAC2_CLK_SEL_CRT
270 | RADEON_DAC2_CMP_EN
);
274 // check connection of blue data signal to see whether there is a CRT
275 found
= (INREG(regs
, RADEON_DAC_CNTL2
) & RADEON_DAC2_CMP_OUT_B
) != 0;
278 OUTREG(regs
, RADEON_DAC_CNTL2
, old_dac_cntl2
);
279 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, 0);
280 OUTREG(regs
, RADEON_TV_DAC_CNTL
, old_tv_dac_cntl
);
281 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, old_crtc2_gen_cntl
);
283 OUTREGP(regs
, RADEON_GPIOPAD_A
, old_radeon_gpiopad_a
, ~1);
289 //! Check whether there is a CRT connected to TV-DAC
291 Radeon_DetectTVCRT(accelerator_info
*ai
)
293 if (ai
->si
->is_mobility
)
296 switch (ai
->si
->asic
) {
298 // original Radeons have pure DVI only and mobility chips
299 // have no DVI connector
300 // TBD: can they have a docking station for CRT on TV-DAC?
311 return Radeon_DetectTVCRT_RV200(ai
);
318 return Radeon_DetectTVCRT_R300(ai
);
321 // r200 has no built-in TV-out and thus no TV-DAC to use for
330 //! TV detection for rv200 and below should work for M6 and RV200
331 static display_device_e
332 Radeon_DetectTV_RV200(accelerator_info
*ai
, bool tv_crt_found
)
334 vuint8
*regs
= ai
->regs
;
335 uint32 value
, old_dac_cntl2
, old_crtc_ext_cntl
, old_crtc2_gen_cntl
;
336 uint32 old_tv_master_cntl
, old_tv_dac_cntl
, old_pre_dac_mux_cntl
;
338 display_device_e displays
= dd_none
;
340 // give up if there is a CRT connected to TV-DAC
345 old_dac_cntl2
= INREG(regs
, RADEON_DAC_CNTL2
);
346 value
= old_dac_cntl2
& ~RADEON_DAC2_CLK_SEL_CRT
;
347 OUTREG(regs
, RADEON_DAC_CNTL2
, value
);
349 old_crtc_ext_cntl
= INREG(regs
, RADEON_CRTC_EXT_CNTL
);
350 old_crtc2_gen_cntl
= INREG(regs
, RADEON_CRTC2_GEN_CNTL
);
351 old_tv_master_cntl
= INREG(regs
, RADEON_TV_MASTER_CNTL
);
354 value
= old_tv_master_cntl
| RADEON_TV_MASTER_CNTL_TV_ON
;
356 RADEON_TV_MASTER_CNTL_TV_ASYNC_RST
|
357 RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX
|
358 RADEON_TV_MASTER_CNTL_CRT_FIFO_CE_EN
|
359 RADEON_TV_MASTER_CNTL_TV_FIFO_CE_EN
|
360 RADEON_TV_MASTER_CNTL_RE_SYNC_NOW_SEL_MASK
);
362 RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST
|
363 RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST
;
364 OUTREG(regs
, RADEON_TV_MASTER_CNTL
, value
);
366 old_tv_dac_cntl
= INREG(regs
, RADEON_TV_DAC_CNTL
);
368 config_cntl
= INREG(regs
, RADEON_CONFIG_CNTL
);
372 RADEON_TV_DAC_CNTL_NBLANK
| RADEON_TV_DAC_CNTL_NHOLD
|
373 RADEON_TV_DAC_CNTL_DETECT
| RADEON_TV_DAC_CNTL_STD_NTSC
|
374 (8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT
) |
375 ((((config_cntl
& RADEON_CFG_ATI_REV_ID_MASK
) == 0) ? 8 : 4) << RADEON_TV_DAC_CNTL_DACADJ_SHIFT
);
376 OUTREG(regs
, RADEON_TV_DAC_CNTL
, value
);
378 old_pre_dac_mux_cntl
= INREG(regs
, RADEON_TV_PRE_DAC_MUX_CNTL
);
380 // force constant DAC output voltage
382 RADEON_TV_PRE_DAC_MUX_CNTL_C_GRN_EN
| RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN
|
383 (RADEON_TV_MUX_FORCE_DAC_DATA
<< RADEON_TV_PRE_DAC_MUX_CNTL_RED_MX_SHIFT
) |
384 (RADEON_TV_MUX_FORCE_DAC_DATA
<< RADEON_TV_PRE_DAC_MUX_CNTL_GRN_MX_SHIFT
) |
385 (RADEON_TV_MUX_FORCE_DAC_DATA
<< RADEON_TV_PRE_DAC_MUX_CNTL_BLU_MX_SHIFT
) |
386 (0x109 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT
);
387 OUTREG(regs
, RADEON_TV_PRE_DAC_MUX_CNTL
, value
);
389 // let things settle a bit
392 // now see which wires are connected
393 value
= INREG(regs
, RADEON_TV_DAC_CNTL
);
394 if ((value
& RADEON_TV_DAC_CNTL_GDACDET
) != 0) {
396 SHOW_INFO0(2, "S-Video TV-Out is connected");
399 if ((value
& RADEON_TV_DAC_CNTL_BDACDET
) != 0) {
401 SHOW_INFO0(2, "Composite TV-Out is connected");
404 OUTREG(regs
, RADEON_TV_PRE_DAC_MUX_CNTL
, old_pre_dac_mux_cntl
);
405 OUTREG(regs
, RADEON_TV_DAC_CNTL
, old_tv_dac_cntl
);
406 OUTREG(regs
, RADEON_TV_MASTER_CNTL
, old_tv_master_cntl
);
407 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, old_crtc2_gen_cntl
);
408 OUTREG(regs
, RADEON_CRTC_EXT_CNTL
, old_crtc_ext_cntl
);
409 OUTREG(regs
, RADEON_DAC_CNTL2
, old_dac_cntl2
);
415 // TV detection for r300 series
416 // should work for R300
417 static display_device_e
Radeon_DetectTV_R300(accelerator_info
*ai
)
419 vuint8
*regs
= ai
->regs
;
420 display_device_e displays
= dd_none
;
421 uint32 tmp
, old_dac_cntl2
, old_crtc2_gen_cntl
, old_dac_ext_cntl
, old_tv_dac_cntl
;
422 uint32 old_radeon_gpiopad_a
;
424 old_radeon_gpiopad_a
= INREG(regs
, RADEON_GPIOPAD_A
);
426 // whatever these flags mean - let's pray they won't get changed
427 OUTREGP(regs
, RADEON_GPIOPAD_EN
, 1, ~1);
428 OUTREGP(regs
, RADEON_GPIOPAD_MASK
, 1, ~1);
429 OUTREGP(regs
, RADEON_GPIOPAD_A
, 0, ~1);
431 old_dac_cntl2
= INREG(regs
, RADEON_DAC_CNTL2
);
433 // set CRT mode (!) of TV-DAC
434 OUTREG(regs
, RADEON_DAC_CNTL2
, RADEON_DAC2_CLK_SEL_CRT
);
436 old_crtc2_gen_cntl
= INREG(regs
, RADEON_CRTC2_GEN_CNTL
);
438 // enable TV-Out output, but set DPMS mode
439 // (this seems to be not correct if TV-Out is connected to CRTC1,
440 // but it doesn't really hurt having wrong DPMS mode)
441 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
,
442 RADEON_CRTC2_CRT2_ON
| RADEON_CRTC2_VSYNC_TRISTAT
);
444 old_dac_ext_cntl
= INREG(regs
, RADEON_DAC_EXT_CNTL
);
446 // force constant voltage output of DAC for impedance test
447 OUTREG(regs
, RADEON_DAC_EXT_CNTL
,
448 RADEON_DAC2_FORCE_BLANK_OFF_EN
| RADEON_DAC2_FORCE_DATA_EN
|
449 RADEON_DAC_FORCE_DATA_SEL_RGB
|
450 (0xec << RADEON_DAC_FORCE_DATA_SHIFT
));
452 old_tv_dac_cntl
= INREG(regs
, RADEON_TV_DAC_CNTL
);
454 // get TV-DAC running (or something...)
455 OUTREG(regs
, RADEON_TV_DAC_CNTL
,
456 RADEON_TV_DAC_CNTL_STD_NTSC
|
457 (8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT
) |
458 (6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT
));
460 (void)INREG(regs
, RADEON_TV_DAC_CNTL
);
464 OUTREG(regs
, RADEON_TV_DAC_CNTL
,
465 RADEON_TV_DAC_CNTL_NBLANK
| RADEON_TV_DAC_CNTL_NHOLD
|
466 RADEON_TV_DAC_CNTL_DETECT
|
467 RADEON_TV_DAC_CNTL_STD_NTSC
|
468 (8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT
) |
469 (6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT
));
471 (void)INREG(regs
, RADEON_TV_DAC_CNTL
);
475 // now see which wires are connected
476 tmp
= INREG(regs
, RADEON_TV_DAC_CNTL
);
477 if ((tmp
& RADEON_TV_DAC_CNTL_GDACDET
) != 0) {
479 SHOW_INFO0(2, "S-Video TV-Out is connected");
482 if ((tmp
& RADEON_TV_DAC_CNTL_BDACDET
) != 0) {
484 SHOW_INFO0(2, "Composite TV-Out is connected");
487 // clean up the mess we did
488 OUTREG(regs
, RADEON_TV_DAC_CNTL
, old_tv_dac_cntl
);
489 OUTREG(regs
, RADEON_DAC_EXT_CNTL
, old_dac_ext_cntl
);
490 OUTREG(regs
, RADEON_CRTC2_GEN_CNTL
, old_crtc2_gen_cntl
);
491 OUTREG(regs
, RADEON_DAC_CNTL2
, old_dac_cntl2
);
493 OUTREGP(regs
, RADEON_GPIOPAD_A
, old_radeon_gpiopad_a
, ~1);
499 // save readout of TV detection comparators
500 static bool readTVDetect(accelerator_info
*ai
)
504 bigtime_t start_time
;
507 // make output constant
508 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
509 RADEON_TV_DAC_CNTL_STD_NTSC
| RADEON_TV_DAC_CNTL_DETECT
| RADEON_TV_DAC_CNTL_NBLANK
);
511 // check detection result
512 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
, &tmp
);
513 detect
= (tmp
& RADEON_TV_DAC_CNTL_CMPOUT
) != 0;
515 //SHOW_FLOW(2, "detect=%d", detect);
517 start_time
= system_time();
520 // wait for stable detect signal
521 for (i
= 0; i
< 5; ++i
) {
524 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
525 RADEON_TV_DAC_CNTL_STD_NTSC
| RADEON_TV_DAC_CNTL_DETECT
| RADEON_TV_DAC_CNTL_NBLANK
|
526 RADEON_TV_DAC_CNTL_NHOLD
);
527 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
528 RADEON_TV_DAC_CNTL_STD_NTSC
| RADEON_TV_DAC_CNTL_DETECT
| RADEON_TV_DAC_CNTL_NBLANK
);
530 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
, &tmp
);
531 cur_detect
= (tmp
& RADEON_TV_DAC_CNTL_CMPOUT
) != 0;
533 //SHOW_FLOW(2, "cur_detect=%d", cur_detect);
535 if (cur_detect
!= detect
)
542 //SHOW_FLOW(2, "return %d", detect);
546 // don't wait forever - give up after 1 second
547 } while (system_time() - start_time
< 1000000);
549 SHOW_FLOW0(2, "timeout");
554 //! Detect TV connected to external Theatre-Out
555 static display_device_e
556 Radeon_DetectTV_Theatre(accelerator_info
*ai
)
558 uint32 old_tv_dac_cntl
, old_pre_dac_mux_cntl
, old_modulator_cntl1
;
559 uint32 old_master_cntl
;
560 uint32 uv_adr
, old_last_fifo_entry
, old_mid_fifo_entry
, last_fifo_addr
;
561 display_device_e displays
= dd_none
;
563 if (ai
->si
->tv_chip
!= tc_external_rt1
)
566 // save previous values (TV-Out may be running)
567 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
570 // enable DAC and comparators
571 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
572 RADEON_TV_DAC_CNTL_STD_NTSC
| RADEON_TV_DAC_CNTL_DETECT
573 | RADEON_TV_DAC_CNTL_NHOLD
| RADEON_TV_DAC_CNTL_NBLANK
);
575 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_PRE_DAC_MUX_CNTL
,
576 &old_pre_dac_mux_cntl
);
577 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MODULATOR_CNTL1
,
578 &old_modulator_cntl1
);
579 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MASTER_CNTL
,
582 // save output timing
583 Radeon_VIPRead(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_UV_ADR
, &uv_adr
);
585 last_fifo_addr
= (uv_adr
& RADEON_TV_UV_ADR_MAX_UV_ADR_MASK
) * 2 + 1;
587 old_last_fifo_entry
= Radeon_TheatreReadFIFO(ai
, last_fifo_addr
);
588 old_mid_fifo_entry
= Radeon_TheatreReadFIFO(ai
, 0x18f);
590 Radeon_TheatreWriteFIFO(ai
, last_fifo_addr
, 0x20208);
591 Radeon_TheatreWriteFIFO(ai
, 0x18f, 0x3ff2608);
593 // stop TV-Out to savely program it
594 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MASTER_CNTL
,
595 RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST
596 | RADEON_TV_MASTER_CNTL_TV_ASYNC_RST
);
598 // set constant base level
599 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MODULATOR_CNTL1
,
600 (0x2c << RADEON_TV_MODULATOR_CNTL1_SET_UP_LEVEL_SHIFT
)
601 | (0x2c << RADEON_TV_MODULATOR_CNTL1_BLANK_LEVEL_SHIFT
));
604 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MASTER_CNTL
,
605 RADEON_TV_MASTER_CNTL_TV_ASYNC_RST
);
607 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MASTER_CNTL
, 0);
609 // set constant Composite output
610 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_PRE_DAC_MUX_CNTL
,
611 RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN
612 | RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN
613 | (9 << RADEON_TV_PRE_DAC_MUX_CNTL_BLU_MX_SHIFT
)
614 | (0xa8 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT
));
616 // check for S-Video connection
617 if (readTVDetect(ai
)) {
618 SHOW_FLOW0(2, "Composite-Out of Rage Theatre is connected");
622 // enable output changes
623 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
624 RADEON_TV_DAC_CNTL_STD_NTSC
| RADEON_TV_DAC_CNTL_DETECT
625 | RADEON_TV_DAC_CNTL_NBLANK
| RADEON_TV_DAC_CNTL_NHOLD
);
627 // set constant Y-output of S-Video adapter
628 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_PRE_DAC_MUX_CNTL
,
629 RADEON_TV_PRE_DAC_MUX_CNTL_Y_RED_EN
630 | RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN
631 | (9 << RADEON_TV_PRE_DAC_MUX_CNTL_RED_MX_SHIFT
)
632 | (0xa8 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT
));
634 // check for composite connection
635 if (readTVDetect(ai
)) {
636 SHOW_FLOW0(2, "S-Video-Out of Rage Theatre is connected");
640 // restore everything
641 Radeon_TheatreWriteFIFO(ai
, last_fifo_addr
, old_last_fifo_entry
);
642 Radeon_TheatreWriteFIFO(ai
, 0x18f, old_mid_fifo_entry
);
644 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MASTER_CNTL
,
646 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_MODULATOR_CNTL1
,
647 old_modulator_cntl1
);
648 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_PRE_DAC_MUX_CNTL
,
649 old_pre_dac_mux_cntl
);
650 Radeon_VIPWrite(ai
, ai
->si
->theatre_channel
, THEATRE_VIP_TV_DAC_CNTL
,
658 Check whether there is a TV connected to TV-DAC
659 returns bit set, i.e. there can be S-Video or composite or both
661 static display_device_e
662 Radeon_DetectTV(accelerator_info
*ai
, bool tv_crt_found
)
664 switch (ai
->si
->asic
) {
667 return Radeon_DetectTV_Theatre(ai
);
673 // IGP method is guessed
677 return Radeon_DetectTV_RV200(ai
, tv_crt_found
);
684 return Radeon_DetectTV_R300(ai
);
691 //! Get native monitor timing, using Detailed Monitor Description
693 Radeon_FindFPTiming_DetailedMonitorDesc(const edid1_info
*edid
, fp_info
*fp
,
694 uint32
*max_hsize
, uint32
*max_vsize
)
698 for (i
= 0; i
< EDID1_NUM_DETAILED_MONITOR_DESC
; ++i
) {
699 if (edid
->detailed_monitor
[i
].monitor_desc_type
== EDID1_IS_DETAILED_TIMING
) {
700 const edid1_detailed_timing
*timing
= &edid
->detailed_monitor
[i
].data
.detailed_timing
;
702 SHOW_FLOW(2, "Found detailed timing for mode %dx%d in DDC data",
703 (int)timing
->h_active
, (int)timing
->v_active
);
705 if (timing
->h_active
> *max_hsize
&& timing
->v_active
> *max_vsize
) {
706 *max_hsize
= timing
->h_active
;
707 *max_vsize
= timing
->v_active
;
709 // copy it to timing specification
710 fp
->panel_xres
= timing
->h_active
;
711 fp
->h_blank
= timing
->h_blank
;
712 fp
->h_over_plus
= timing
->h_sync_off
;
713 fp
->h_sync_width
= timing
->h_sync_width
;
715 fp
->panel_yres
= timing
->v_active
;
716 fp
->v_blank
= timing
->v_blank
;
717 fp
->v_over_plus
= timing
->v_sync_off
;
718 fp
->v_sync_width
= timing
->v_sync_width
;
720 // BeOS uses kHz, but the timing is in 10 kHz
721 fp
->dot_clock
= timing
->pixel_clock
* 10;
728 /*! Get native monitor timing, using Standard Timing table;
729 this table doesn't contain the actual timing, so we try to find a
730 appropriate VESA modes for the resolutions given in the table
733 Radeon_FindFPTiming_StandardTiming(const edid1_info
*edid
, fp_info
*fp
,
734 uint32
*max_hsize
, uint32
*max_vsize
)
738 for (i
= 0; i
< EDID1_NUM_STD_TIMING
; ++i
) {
739 const edid1_std_timing
*std_timing
= &edid
->std_timing
[i
];
741 int best_refresh_deviation
= 10000;
744 if (std_timing
->h_size
<= 256)
747 for (j
= 0; j
< (int)vesa_mode_list_count
; ++j
) {
748 int refresh_rate
, cur_refresh_deviation
;
750 if (vesa_mode_list
[j
].h_display
!= std_timing
->h_size
751 || vesa_mode_list
[j
].v_display
!= std_timing
->v_size
)
754 // take pixel_clock times 1000 because is is in kHz
755 // further, take it times 1000 again, to get 1/1000 frames
757 refresh_rate
= (int64
)vesa_mode_list
[j
].pixel_clock
* 1000*1000
758 / (vesa_mode_list
[j
].h_total
* vesa_mode_list
[j
].v_total
);
760 // standard timing is in frames, so multiple by it to get 1/1000 frames
761 // result is scaled by 100 to get difference in percentage;
762 cur_refresh_deviation
= (100 * (refresh_rate
- std_timing
->refresh
763 * 1000)) / refresh_rate
;
765 if (cur_refresh_deviation
< 0)
766 cur_refresh_deviation
= -cur_refresh_deviation
;
768 // less then 1 percent difference is (hopefully) OK,
769 // if there are multiple, we take best one
770 // (if the screen is that picky, it should have defined an enhanced timing)
771 if (cur_refresh_deviation
< 1
772 && cur_refresh_deviation
< best_refresh_deviation
) {
774 best_refresh_deviation
= cur_refresh_deviation
;
779 SHOW_FLOW(2, "Unsupported standard mode %dx%d@%dHz (not VESA)",
780 std_timing
->h_size
, std_timing
->v_size
, std_timing
->refresh
);
784 if (std_timing
->h_size
> *max_hsize
&& std_timing
->h_size
> *max_vsize
) {
785 const display_timing
*timing
= &vesa_mode_list
[best_fit
];
787 SHOW_FLOW(2, "Found DDC data for standard mode %dx%d",
788 (int)timing
->h_display
, (int)timing
->v_display
);
790 *max_hsize
= timing
->h_display
;
791 *max_vsize
= timing
->h_display
;
793 // copy it to timing specification
794 fp
->panel_xres
= timing
->h_display
;
795 fp
->h_blank
= timing
->h_total
- timing
->h_display
;
796 fp
->h_over_plus
= timing
->h_sync_start
- timing
->h_display
;
797 fp
->h_sync_width
= timing
->h_sync_end
- timing
->h_sync_start
;
799 fp
->panel_yres
= timing
->v_display
;
800 fp
->v_blank
= timing
->v_total
- timing
->v_display
;
801 fp
->v_over_plus
= timing
->v_sync_start
- timing
->v_display
;
802 fp
->v_sync_width
= timing
->v_sync_end
- timing
->v_sync_start
;
804 fp
->dot_clock
= timing
->pixel_clock
;
810 //! Read edid data of flat panel and setup its timing accordingly
812 Radeon_StoreFPEDID(accelerator_info
*ai
, int port
, const edid1_info
*edid
)
814 fp_info
*fp
= &ai
->si
->flatpanels
[port
];
815 uint32 max_hsize
, max_vsize
;
817 //SHOW_FLOW0(2, "EDID data read from DVI port via DDC2:");
820 // find detailed timing with maximum resolution
821 max_hsize
= max_vsize
= 0;
822 Radeon_FindFPTiming_DetailedMonitorDesc(edid
, fp
, &max_hsize
, &max_vsize
);
824 if (max_hsize
== 0) {
825 SHOW_FLOW0(2, "Timing is not explicitely defined in DDC - checking standard modes");
827 Radeon_FindFPTiming_StandardTiming(edid
, fp
, &max_hsize
, &max_vsize
);
828 if (max_hsize
== 0) {
829 SHOW_FLOW0(2, "Still found no valid native mode, disabling DVI");
834 SHOW_INFO(2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d",
835 fp
->panel_xres
, fp
->h_blank
, fp
->h_over_plus
, fp
->h_sync_width
);
836 SHOW_INFO(2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d",
837 fp
->panel_yres
, fp
->v_blank
, fp
->v_over_plus
, fp
->v_sync_width
);
838 SHOW_INFO(2, "pixel_clock=%d kHz", fp
->dot_clock
);
845 Radeon_ConnectorInfo(accelerator_info
*ai
, int port
, disp_entity
* ptr_entity
)
848 const char* ddc
= ptr_entity
->port_info
[port
].ddc_type
== ddc_none_detected
849 ? "None" : ptr_entity
->port_info
[port
].ddc_type
== ddc_monid
850 ? "Mon ID" : ptr_entity
->port_info
[port
].ddc_type
== ddc_dvi
851 ? "DVI DDC" : ptr_entity
->port_info
[port
].ddc_type
== ddc_vga
852 ? "VGA DDC" : ptr_entity
->port_info
[port
].ddc_type
== ddc_crt2
853 ? "CRT2 DDC" : "Error";
854 const char* tmds
= ptr_entity
->port_info
[port
].tmds_type
== tmds_unknown
855 ? "None" : ptr_entity
->port_info
[port
].tmds_type
== tmds_int
856 ? "Internal" : ptr_entity
->port_info
[port
].tmds_type
== tmds_ext
857 ? "External" : "??? ";
858 const char* dac
= ptr_entity
->port_info
[port
].dac_type
== dac_unknown
859 ? "Unknown" : ptr_entity
->port_info
[port
].dac_type
== dac_primary
860 ? "Primary" : ptr_entity
->port_info
[port
].dac_type
== dac_tvdac
861 ? "TV / External" : "Error";
864 if (ai
->si
->is_atombios
) {
865 con
= ptr_entity
->port_info
[port
].connector_type
== connector_none_atom
866 ? "None" : ptr_entity
->port_info
[port
].connector_type
== connector_vga_atom
867 ? "VGA" : ptr_entity
->port_info
[port
].connector_type
== connector_dvi_i_atom
868 ? "DVI-I" : ptr_entity
->port_info
[port
].connector_type
== connector_dvi_d_atom
869 ? "DVI-D" : ptr_entity
->port_info
[port
].connector_type
== connector_dvi_a_atom
870 ? "DVI-A" : ptr_entity
->port_info
[port
].connector_type
== connector_stv_atom
871 ? "S-Video TV" : ptr_entity
->port_info
[port
].connector_type
== connector_ctv_atom
872 ? "Composite TV" : ptr_entity
->port_info
[port
].connector_type
== connector_lvds_atom
873 ? "LVDS" : ptr_entity
->port_info
[port
].connector_type
== connector_digital_atom
874 ? "Digital" : ptr_entity
->port_info
[port
].connector_type
== connector_unsupported_atom
877 con
= ptr_entity
->port_info
[port
].connector_type
== connector_none
878 ? "None" : ptr_entity
->port_info
[port
].connector_type
== connector_crt
879 ? "VGA" : ptr_entity
->port_info
[port
].connector_type
== connector_dvi_i
880 ? "DVI-I" : ptr_entity
->port_info
[port
].connector_type
== connector_dvi_d
881 ? "DVI-D" : ptr_entity
->port_info
[port
].connector_type
== connector_proprietary
882 ? "Proprietary" : ptr_entity
->port_info
[port
].connector_type
== connector_stv
883 ? "S-Video TV" : ptr_entity
->port_info
[port
].connector_type
== connector_ctv
884 ? "Composite TV" : ptr_entity
->port_info
[port
].connector_type
== connector_unsupported
888 mon
= ptr_entity
->port_info
[port
].mon_type
== mt_unknown
? "???"
889 : ptr_entity
->port_info
[port
].mon_type
== mt_none
? "None"
890 : ptr_entity
->port_info
[port
].mon_type
== mt_crt
? "CRT "
891 : ptr_entity
->port_info
[port
].mon_type
== mt_lcd
? "LCD "
892 : ptr_entity
->port_info
[port
].mon_type
== mt_dfp
? "DVI "
893 : ptr_entity
->port_info
[port
].mon_type
== mt_ctv
? "Composite TV"
894 : ptr_entity
->port_info
[port
].mon_type
== mt_stv
? "S-Video TV"
897 SHOW_INFO(2, "Port %d:- \nMonitor: %s\nConn Type: %s\nDDC Port: %s\nTMDS Type: %s\nDAC Type: %s",
898 port
, mon
, con
, ddc
, tmds
, dac
);
903 Detect connected displays devices
904 whished_num_heads - how many heads the requested display mode needs
907 Radeon_DetectDisplays(accelerator_info
*ai
)
909 shared_info
*si
= ai
->si
;
911 disp_entity
* routes
= &si
->routing
;
912 display_device_e displays
= 0;
913 display_device_e controlled_displays
= ai
->vc
->controlled_displays
;
916 uint32 edid_regs
[] = {
924 // lock hardware so noone bothers us
925 Radeon_WaitForIdle(ai
, true);
927 // alwats make TMDS_INT port first
928 if (routes
->port_info
[1].tmds_type
== tmds_int
) {
929 radeon_connector swap_entity
;
930 swap_entity
= routes
->port_info
[0];
931 routes
->port_info
[0] = routes
->port_info
[1];
932 routes
->port_info
[1] = swap_entity
;
933 SHOW_FLOW0(2, "Swapping TMDS_INT to first port");
934 } else if (routes
->port_info
[0].tmds_type
!= tmds_int
935 && routes
->port_info
[1].tmds_type
!= tmds_int
) {
936 // no TMDS_INT port, make primary DAC port first
937 // On my Inspiron 8600 both internal and external ports are
938 // marked DAC_PRIMARY in BIOS. So be extra careful - only
939 // swap when the first port is not DAC_PRIMARY
940 if (routes
->port_info
[1].dac_type
== dac_primary
941 && routes
->port_info
[0].dac_type
!= dac_primary
) {
942 radeon_connector swap_entity
;
943 swap_entity
= routes
->port_info
[0];
944 routes
->port_info
[0] = routes
->port_info
[1];
945 routes
->port_info
[1] = swap_entity
;
946 SHOW_FLOW0(2, "Swapping Primary Dac to front");
950 if (si
->asic
== rt_rs300
) {
951 // RS300 only has single Dac of TV type
952 // For RS300/RS350/RS400 chips, there is no primary DAC.
953 // Force VGA port to use TVDAC
954 if (routes
->port_info
[0].connector_type
== connector_crt
) {
955 routes
->port_info
[0].dac_type
= dac_tvdac
;
956 routes
->port_info
[1].dac_type
= dac_primary
;
958 routes
->port_info
[1].dac_type
= dac_primary
;
959 routes
->port_info
[0].dac_type
= dac_tvdac
;
961 } else if (si
->num_crtc
== 1) {
962 routes
->port_info
[0].dac_type
= dac_primary
;
965 // use DDC to detect monitors - if we can read DDC, there must be
967 for (i
= 0; i
< 2; i
++) {
968 //TODO could skip edid reading instead if we already have it, but what
969 //if monitors have been hot swapped? Also rely on edid for DVI-D detection
970 //if (routes->port_info[i].mon_type != mt_unknown) {
971 // SHOW_FLOW0(2, "known type, skpping detection");
974 memset(&routes
->port_info
[i
].edid
, 0, sizeof(edid1_info
));
975 switch (routes
->port_info
[i
].ddc_type
) {
980 if (Radeon_ReadEDID(ai
,
981 edid_regs
[routes
->port_info
[i
].ddc_type
],
982 &routes
->port_info
[i
].edid
)) {
983 routes
->port_info
[i
].edid_valid
= true;
984 SHOW_FLOW(2, "Edid Data for CRTC %d on line %d", i
, routes
->port_info
[i
].ddc_type
);
985 edid_dump(&routes
->port_info
[i
].edid
);
987 routes
->port_info
[i
].mon_type
= mt_none
;
992 SHOW_FLOW(2, "No Edid Pin Assigned to CRTC %d ", i
);
993 routes
->port_info
[i
].mon_type
= mt_none
;
996 if (routes
->port_info
[i
].edid_valid
) {
997 if (routes
->port_info
[i
].edid
.display
.input_type
== 1) {
998 SHOW_FLOW0(2, "Must be a DVI monitor");
1000 // Note some laptops have a DVI output that uses internal TMDS,
1001 // when its DVI is enabled by hotkey, LVDS panel is not used.
1002 // In this case, the laptop is configured as DVI+VGA as a normal
1004 // Also for laptop, when X starts with lid closed (no DVI connection)
1005 // both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
1006 if (routes
->port_info
[i
].tmds_type
== tmds_ext
){
1007 // store info about DVI-connected flat-panel
1008 if (Radeon_StoreFPEDID(ai
, i
, &routes
->port_info
[i
].edid
) == B_OK
) {
1009 SHOW_INFO0(2, "Found Ext Laptop DVI");
1010 routes
->port_info
[i
].mon_type
= mt_dfp
;
1011 ai
->si
->flatpanels
[i
].is_fp2
= true;
1012 displays
|= dd_dvi_ext
;
1014 SHOW_ERROR0(2, "Disabled Ext DVI - invalid EDID");
1017 if (INREG(ai
->regs
, RADEON_FP_GEN_CNTL
) & (1 << 7) || (!si
->is_mobility
)) {
1018 // store info about DVI-connected flat-panel
1019 if (Radeon_StoreFPEDID(ai
, i
, &routes
->port_info
[i
].edid
) == B_OK
) {
1020 SHOW_INFO0(2, "Found DVI");
1021 routes
->port_info
[i
].mon_type
= mt_dfp
;
1024 SHOW_ERROR0(2, "Disabled DVI - invalid EDID");
1027 SHOW_INFO0(2, "Laptop Panel Found");
1028 routes
->port_info
[i
].mon_type
= mt_lcd
;
1029 displays
|= dd_lvds
;
1031 ai
->si
->flatpanels
[1].is_fp2
= FALSE
;
1034 // must be the analog portion of DVI
1035 // I'm not sure about Radeons with one CRTC - do they have DVI-I or DVI-D?
1036 // anyway - if there are two CRTC, analog portion must be connected
1037 // to TV-DAC; if there is one CRTC, it must be the normal VGA-DAC
1038 if (si
->num_crtc
> 1) {
1039 SHOW_FLOW0(2, "Must be an analog monitor on DVI port");
1040 routes
->port_info
[i
].mon_type
= mt_crt
;
1041 displays
|= dd_tv_crt
;
1043 SHOW_FLOW0(2, "Seems to be a CRT on VGA port!?");
1044 routes
->port_info
[i
].mon_type
= mt_crt
;
1051 if (!routes
->port_info
[0].edid_valid
) {
1052 SHOW_INFO0(2, "Searching port 0");
1053 if (si
->is_mobility
&& (INREG(ai
->regs
, RADEON_BIOS_4_SCRATCH
) & 4)) {
1054 SHOW_INFO0(2, "Found Laptop Panel");
1055 routes
->port_info
[0].mon_type
= mt_lcd
;
1056 displays
|= dd_lvds
;
1060 if (!routes
->port_info
[1].edid_valid
) {
1061 if (si
->is_mobility
&& (INREG(ai
->regs
, RADEON_FP2_GEN_CNTL
) & RADEON_FP2_FPON
)) {
1062 SHOW_INFO0(2, "Found Ext Laptop DVI");
1063 routes
->port_info
[1].mon_type
= mt_dfp
;
1064 displays
|= dd_dvi_ext
;
1068 if (routes
->port_info
[0].mon_type
== mt_none
) {
1069 if (routes
->port_info
[1].mon_type
== mt_none
) {
1070 routes
->port_info
[0].mon_type
= mt_crt
;
1072 radeon_connector portSwapEntity
;
1073 fp_info panelInfoSwapEntity
;
1075 portSwapEntity
= routes
->port_info
[0];
1076 routes
->port_info
[0] = routes
->port_info
[1];
1077 routes
->port_info
[1] = portSwapEntity
;
1079 panelInfoSwapEntity
= ai
->si
->flatpanels
[0];
1080 ai
->si
->flatpanels
[0] = ai
->si
->flatpanels
[1];
1081 ai
->si
->flatpanels
[1] = panelInfoSwapEntity
;
1083 SHOW_ERROR0(2, "swapping active port 2 to free port 1");
1088 routes
->reversed_DAC
= false;
1089 if (routes
->port_info
[1].dac_type
== dac_tvdac
) {
1090 SHOW_ERROR0(2, "Reversed dac detected (not impl. yet)");
1091 routes
->reversed_DAC
= true;
1094 // we may have overseen monitors if they don't support DDC or
1095 // have broken DDC data (like mine);
1096 // time to do a physical wire test; this test is more reliable, but it
1097 // leads to distortions on screen, which is not very nice to look at
1099 // for DVI, there is no mercy if no DDC data is there - we wouldn't
1100 // even know the native resolution of the panel!
1102 // all versions have a standard VGA port
1103 if ((displays
& dd_crt
) == 0 && (controlled_displays
& dd_crt
) != 0
1104 && Radeon_DetectCRT(ai
))
1107 // check VGA signal routed to DVI port
1108 // (the detection code checks whether there is hardware for that)
1109 if ((displays
& dd_tv_crt
) == 0
1110 && (controlled_displays
& dd_tv_crt
) != 0
1111 && Radeon_DetectTVCRT(ai
))
1112 displays
|= dd_tv_crt
;
1114 // check TV-out connector
1115 if ((controlled_displays
& (dd_ctv
| dd_stv
)) != 0)
1116 displays
|= Radeon_DetectTV(ai
, (displays
& dd_tv_crt
) != 0);
1118 SHOW_INFO(0, "Detected monitors: 0x%x", displays
);
1120 displays
&= controlled_displays
;
1122 // if no monitor found, we define to have a CRT connected to CRT-DAC
1126 Radeon_ConnectorInfo(ai
, 0, routes
);
1127 Radeon_ConnectorInfo(ai
, 1, routes
);
1129 ai
->vc
->connected_displays
= displays
;
1131 RELEASE_BEN(si
->cp
.lock
);