vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / radeon / monitor_detection.c
blobabfd9f42480f1ba74c1dfab4d1467b6d9fd84845
1 /*
2 * Copyright 2002-2004, Thomas Kurschel. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 */
6 /*!
7 Radeon monitor detection
8 */
10 #include <stdlib.h>
11 #include <string.h>
13 #include "radeon_accelerant.h"
14 #include "mmio.h"
15 #include "crtc_regs.h"
16 #include "dac_regs.h"
17 #include "pll_regs.h"
18 #include "tv_out_regs.h"
19 #include "config_regs.h"
20 #include "ddc_regs.h"
21 #include "gpiopad_regs.h"
22 #include "fp_regs.h"
23 #include "pll_access.h"
24 #include "theatre_regs.h"
25 #include "set_mode.h"
26 #include "ddc.h"
29 typedef struct {
30 accelerator_info *ai;
31 uint32 port;
32 } ddc_port_info;
35 //! Get I2C signals
36 static status_t
37 get_signals(void *cookie, int *clk, int *data)
39 ddc_port_info *info = (ddc_port_info *)cookie;
40 vuint8 *regs = info->ai->regs;
41 uint32 value;
43 value = INREG(regs, info->port);
44 *clk = (value >> RADEON_GPIO_Y_SHIFT_1) & 1;
45 *data = (value >> RADEON_GPIO_Y_SHIFT_0) & 1;
47 return B_OK;
51 //! Set I2C signals
52 static status_t
53 set_signals(void *cookie, int clk, int data)
55 ddc_port_info *info = (ddc_port_info *)cookie;
56 vuint8 *regs = info->ai->regs;
57 uint32 value;
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);
66 return B_OK;
70 /*! Read EDID information from monitor
71 ddc_port - register to use for DDC2 communication
73 bool
74 Radeon_ReadEDID(accelerator_info *ai, uint32 ddcPort, edid1_info *edid)
76 i2c_bus bus;
77 ddc_port_info info;
78 void *vdif;
79 size_t vdifLength;
81 info.ai = ai;
82 info.port = ddcPort;
84 ddc2_init_timing(&bus);
85 bus.cookie = &info;
86 bus.set_signals = &set_signals;
87 bus.get_signals = &get_signals;
89 if (ddc2_read_edid1(&bus, edid, &vdif, &vdifLength) != B_OK)
90 return false;
92 SHOW_FLOW(2, "Found DDC-capable monitor @0x%04x", ddcPort);
94 free(vdif);
95 return true;
99 // search for display connect to CRT DAC
100 // colour - true, if only a colour monitor is to be accepted
101 static bool
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;
106 bool found;
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)
134 snooze(2000);
136 // let's see whether there is some
137 found = (INREG(regs, RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) != 0;
138 if (found) {
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);
147 return found;
151 //! Check whethere there is a CRT connected to CRT DAC
152 static bool
153 Radeon_DetectCRT(accelerator_info *ai)
155 vuint32 old_vclk_ecp_cntl, value;
156 bool found;
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,
170 old_vclk_ecp_cntl);
172 return found;
176 //! CRT on TV-DAC detection for rv200 and below checked for rv200
177 static bool
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;
182 bool found;
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);
211 snooze(10000);
213 // let's see what we've got!
214 found = (INREG(regs, RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) != 0;
215 if (found)
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);
223 return found;
227 //! CRT on TV-DAC detection for r300 checked for r300
228 static bool
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;
234 bool found;
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);
256 // enable TV-DAC
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);
272 snooze(10000);
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;
277 // clean up the mess
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);
285 return found;
289 //! Check whether there is a CRT connected to TV-DAC
290 static bool
291 Radeon_DetectTVCRT(accelerator_info *ai)
293 if (ai->si->is_mobility)
294 return dd_none;
296 switch (ai->si->asic) {
297 case rt_r100:
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?
301 return dd_none;
303 case rt_rv100:
304 case rt_rv200:
305 case rt_rv250:
306 case rt_rv280:
307 // IGP is guessed
308 case rt_rs100:
309 case rt_rs200:
310 case rt_rs300:
311 return Radeon_DetectTVCRT_RV200(ai);
313 case rt_r300:
314 case rt_r350:
315 case rt_rv350:
316 case rt_rv380:
317 case rt_r420:
318 return Radeon_DetectTVCRT_R300(ai);
320 case rt_r200:
321 // r200 has no built-in TV-out and thus no TV-DAC to use for
322 // second CRT
323 return dd_none;
326 return dd_none;
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;
337 uint32 config_cntl;
338 display_device_e displays = dd_none;
340 // give up if there is a CRT connected to TV-DAC
341 if (tv_crt_found)
342 return dd_none;
344 // enable TV mode
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);
353 // enable TV output
354 value = old_tv_master_cntl | RADEON_TV_MASTER_CNTL_TV_ON;
355 value &= ~(
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);
361 value |=
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);
370 // unlock TV DAC
371 value =
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
381 value =
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
390 snooze(3000);
392 // now see which wires are connected
393 value = INREG(regs, RADEON_TV_DAC_CNTL);
394 if ((value & RADEON_TV_DAC_CNTL_GDACDET) != 0) {
395 displays |= dd_stv;
396 SHOW_INFO0(2, "S-Video TV-Out is connected");
399 if ((value & RADEON_TV_DAC_CNTL_BDACDET) != 0) {
400 displays |= dd_ctv;
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);
411 return displays;
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);
462 snooze(4000);
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);
473 snooze(6000);
475 // now see which wires are connected
476 tmp = INREG(regs, RADEON_TV_DAC_CNTL);
477 if ((tmp & RADEON_TV_DAC_CNTL_GDACDET) != 0) {
478 displays |= dd_stv;
479 SHOW_INFO0(2, "S-Video TV-Out is connected");
482 if ((tmp & RADEON_TV_DAC_CNTL_BDACDET) != 0) {
483 displays |= dd_ctv;
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);
495 return displays;
499 // save readout of TV detection comparators
500 static bool readTVDetect(accelerator_info *ai)
502 uint32 tmp;
503 int i;
504 bigtime_t start_time;
505 bool detect;
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();
519 do {
520 // wait for stable detect signal
521 for (i = 0; i < 5; ++i) {
522 bool cur_detect;
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)
536 break;
538 detect = cur_detect;
541 if (i == 5) {
542 //SHOW_FLOW(2, "return %d", detect);
543 return detect;
546 // don't wait forever - give up after 1 second
547 } while (system_time() - start_time < 1000000);
549 SHOW_FLOW0(2, "timeout");
550 return false;
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)
564 return dd_none;
566 // save previous values (TV-Out may be running)
567 Radeon_VIPRead(ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
568 &old_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,
580 &old_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));
603 // enable output
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");
619 displays |= dd_ctv;
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");
637 displays |= dd_stv;
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,
645 old_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,
651 old_tv_dac_cntl);
653 return displays;
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) {
665 case rt_r100:
666 case rt_r200:
667 return Radeon_DetectTV_Theatre(ai);
669 case rt_rv100:
670 case rt_rv200:
671 case rt_rv250:
672 case rt_rv280:
673 // IGP method is guessed
674 case rt_rs100:
675 case rt_rs200:
676 case rt_rs300:
677 return Radeon_DetectTV_RV200(ai, tv_crt_found);
679 case rt_r300:
680 case rt_r350:
681 case rt_rv350:
682 case rt_rv380:
683 case rt_r420:
684 return Radeon_DetectTV_R300(ai);
687 return dd_none;
691 //! Get native monitor timing, using Detailed Monitor Description
692 static void
693 Radeon_FindFPTiming_DetailedMonitorDesc(const edid1_info *edid, fp_info *fp,
694 uint32 *max_hsize, uint32 *max_vsize)
696 int i;
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
732 static void
733 Radeon_FindFPTiming_StandardTiming(const edid1_info *edid, fp_info *fp,
734 uint32 *max_hsize, uint32 *max_vsize)
736 int i;
738 for (i = 0; i < EDID1_NUM_STD_TIMING; ++i) {
739 const edid1_std_timing *std_timing = &edid->std_timing[i];
740 int best_fit = -1;
741 int best_refresh_deviation = 10000;
742 int j;
744 if (std_timing->h_size <= 256)
745 continue;
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)
752 continue;
754 // take pixel_clock times 1000 because is is in kHz
755 // further, take it times 1000 again, to get 1/1000 frames
756 // as refresh rate
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) {
773 best_fit = j;
774 best_refresh_deviation = cur_refresh_deviation;
778 if (best_fit < 0) {
779 SHOW_FLOW(2, "Unsupported standard mode %dx%d@%dHz (not VESA)",
780 std_timing->h_size, std_timing->v_size, std_timing->refresh);
781 continue;
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
811 static status_t
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:");
818 //edid_dump(edid);
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");
830 return B_ERROR;
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);
840 return B_OK;
844 static void
845 Radeon_ConnectorInfo(accelerator_info *ai, int port, disp_entity* ptr_entity)
847 const char* mon;
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";
862 const char* con;
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
875 ? "N/A " : "Err ";
876 } else {
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
885 ? "N/A" : "Err";
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"
895 : "Err ?";
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
906 void
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;
914 int i;
916 uint32 edid_regs[] = {
918 RADEON_GPIO_MONID,
919 RADEON_GPIO_DVI_DDC,
920 RADEON_GPIO_VGA_DDC,
921 RADEON_GPIO_CRT2_DDC
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;
957 } else {
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
966 // a monitor
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");
972 // continue;
974 memset(&routes->port_info[i].edid , 0, sizeof(edid1_info));
975 switch (routes->port_info[i].ddc_type) {
976 case ddc_monid:
977 case ddc_dvi:
978 case ddc_vga:
979 case ddc_crt2:
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);
986 } else {
987 routes->port_info[i].mon_type = mt_none;
989 break;
991 default:
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
1003 // desktop card.
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;
1013 } else {
1014 SHOW_ERROR0(2, "Disabled Ext DVI - invalid EDID");
1016 } else {
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;
1022 displays |= dd_dvi;
1023 } else {
1024 SHOW_ERROR0(2, "Disabled DVI - invalid EDID");
1026 } else {
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;
1033 } else {
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;
1042 } else {
1043 SHOW_FLOW0(2, "Seems to be a CRT on VGA port!?");
1044 routes->port_info[i].mon_type = mt_crt;
1045 displays |= dd_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;
1071 } else {
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))
1105 displays |= dd_crt;
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
1123 if (displays == 0)
1124 displays = dd_crt;
1126 Radeon_ConnectorInfo(ai, 0, routes);
1127 Radeon_ConnectorInfo(ai, 1, routes);
1129 ai->vc->connected_displays = displays;
1131 RELEASE_BEN(si->cp.lock);