xref: /haiku/src/add-ons/accelerants/radeon/monitor_detection.c (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
1 /*
2 	Copyright (c) 2002-2004 Thomas Kurschel
3 
4 
5 	Part of Radeon accelerant
6 
7 	Monitor detection
8 */
9 
10 #include "radeon_accelerant.h"
11 #include "mmio.h"
12 #include "crtc_regs.h"
13 #include "dac_regs.h"
14 #include "pll_regs.h"
15 #include "tv_out_regs.h"
16 #include "config_regs.h"
17 #include "ddc_regs.h"
18 #include "gpiopad_regs.h"
19 #include "fp_regs.h"
20 #include "pll_access.h"
21 #include "theatre_regs.h"
22 #include "set_mode.h"
23 #include "ddc.h"
24 #include <malloc.h>
25 #include "string.h"
26 
27 typedef struct {
28 	accelerator_info *ai;
29 	uint32 port;
30 } ddc_port_info;
31 
32 
33 // get I2C signals
34 static status_t get_signals( void *cookie, int *clk, int *data )
35 {
36 	ddc_port_info *info = (ddc_port_info *)cookie;
37 	vuint8 *regs = info->ai->regs;
38 	uint32 value;
39 
40 	value = INREG( regs, info->port );
41 
42 	*clk = (value >> RADEON_GPIO_Y_SHIFT_1) & 1;
43 	*data = (value >> RADEON_GPIO_Y_SHIFT_0) & 1;
44 
45 	return B_OK;
46 }
47 
48 
49 // set I2C signals
50 static status_t set_signals( void *cookie, int clk, int data )
51 {
52 	ddc_port_info *info = (ddc_port_info *)cookie;
53 	vuint8 *regs = info->ai->regs;
54 	uint32 value;
55 
56 	value = INREG( regs, info->port );
57 	value &= ~(RADEON_GPIO_A_1 | RADEON_GPIO_A_0);
58 	value &= ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
59 	value |= ((1-clk) << RADEON_GPIO_EN_SHIFT_1) | ((1-data) << RADEON_GPIO_EN_SHIFT_0);
60 
61 	OUTREG( regs, info->port, value );
62 
63 	return B_OK;
64 }
65 
66 
67 // read EDID information from monitor
68 // ddc_port - register to use for DDC2 communication
69 bool Radeon_ReadEDID( accelerator_info *ai, uint32 ddc_port, edid1_info *edid )
70 {
71 	i2c_bus bus;
72 	ddc_port_info info;
73 	void *vdif;
74 	size_t vdif_len;
75 	status_t res;
76 
77 	info.ai = ai;
78 	info.port = ddc_port;
79 
80 	bus.cookie = &info;
81 	bus.set_signals = &set_signals;
82 	bus.get_signals = &get_signals;
83 
84 	res = ddc2_read_edid1( &bus, edid, &vdif, &vdif_len );
85 	if( res != B_OK )
86 		return false;
87 
88 	SHOW_FLOW( 2, "Found DDC-capable monitor @0x%04x", ddc_port );
89 
90 	if( vdif != NULL )
91 		free( vdif );
92 
93 	return true;
94 }
95 
96 
97 // search for display connect to CRT DAC
98 // colour - true, if only a colour monitor is to be accepted
99 static bool Radeon_DetectCRTInt( accelerator_info *ai, bool colour )
100 {
101 	vuint8 *regs = ai->regs;
102 	uint32 old_crtc_ext_cntl, old_dac_ext_cntl, old_dac_cntl, tmp;
103 	bool found;
104 
105 	// makes sure there is a signal
106 	old_crtc_ext_cntl = INREG( regs, RADEON_CRTC_EXT_CNTL );
107 
108 	tmp = old_crtc_ext_cntl | RADEON_CRTC_CRT_ON;
109 	OUTREG( regs, RADEON_CRTC_EXT_CNTL, tmp );
110 
111 	// force DAC to output constant voltage
112 	// for colour monitors, RGB is tested, for B/W only G
113 	old_dac_ext_cntl = INREG( regs, RADEON_DAC_EXT_CNTL );
114 
115 	tmp =
116 		RADEON_DAC_FORCE_BLANK_OFF_EN |
117 		RADEON_DAC_FORCE_DATA_EN |
118 		(colour ? RADEON_DAC_FORCE_DATA_SEL_RGB : RADEON_DAC_FORCE_DATA_SEL_G) |
119 		(0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
120 	OUTREG( regs, RADEON_DAC_EXT_CNTL, tmp );
121 
122 	// enable DAC and tell is to use VGA signals
123 	old_dac_cntl = INREG( regs, RADEON_DAC_CNTL );
124 
125 	tmp = old_dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
126 	tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
127 	OUTREG( regs, RADEON_DAC_CNTL, tmp );
128 
129 	// specs says that we should wait 1µs before checking but sample
130 	// code uses 2 ms; we use long delay to be on safe side
131 	// (though we don't want to make it too long as the monitor
132 	// gets no sync signal now)
133 	snooze( 2000 );
134 
135 	// let's see whether there is some
136 	found = (INREG( regs, RADEON_DAC_CNTL ) & RADEON_DAC_CMP_OUTPUT) != 0;
137 
138 	if( found )
139 		SHOW_INFO( 2, "Found %s CRT connected to CRT-DAC", colour ? "colour" : "b/w" );
140 
141 	OUTREG( regs, RADEON_DAC_CNTL, old_dac_cntl );
142 	OUTREG( regs, RADEON_DAC_EXT_CNTL, old_dac_ext_cntl );
143 	OUTREG( regs, RADEON_CRTC_EXT_CNTL, old_crtc_ext_cntl );
144 
145 	return found;
146 }
147 
148 
149 // check whethere there is a CRT connected to CRT DAC
150 static bool Radeon_DetectCRT( accelerator_info *ai )
151 {
152 	vuint32 old_vclk_ecp_cntl, tmp;
153 	bool found;
154 
155 	// enforce clock so the DAC gets activated
156 	old_vclk_ecp_cntl = Radeon_INPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL );
157 
158 	tmp = old_vclk_ecp_cntl &
159 		~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
160 	Radeon_OUTPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL, tmp );
161 
162 	// search first for colour, then for B/W monitor
163 	found = Radeon_DetectCRTInt( ai, true ) || Radeon_DetectCRTInt( ai, false );
164 
165 	Radeon_OUTPLL( ai->regs, ai->si->asic, RADEON_VCLK_ECP_CNTL, old_vclk_ecp_cntl );
166 
167 	return found;
168 }
169 
170 
171 // CRT on TV-DAC detection for rv200 and below
172 // checked for rv200
173 static bool Radeon_DetectTVCRT_RV200( accelerator_info *ai )
174 {
175 	vuint8 *regs = ai->regs;
176 	uint32 old_crtc2_gen_cntl, old_tv_dac_cntl, old_dac_cntl2, tmp;
177 	bool found;
178 
179 	// enable CRTC2, setting 8 bpp (we just pick any valid value)
180 	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );
181 
182 	tmp = old_crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
183 	tmp |=
184 		RADEON_CRTC2_CRT2_ON |
185 		(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
186 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, tmp );
187 
188 	// enable TV-DAC, choosing VGA signal level
189 	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );
190 
191 	tmp =
192 		RADEON_TV_DAC_CNTL_NBLANK |
193 		RADEON_TV_DAC_CNTL_NHOLD |
194 		RADEON_TV_DAC_CNTL_DETECT |
195 		RADEON_TV_DAC_CNTL_STD_PS2;
196 	OUTREG( regs, RADEON_TV_DAC_CNTL, tmp );
197 
198 	// enforce constant DAC output voltage on RGB
199 	tmp =
200 		RADEON_DAC2_FORCE_BLANK_OFF_EN |
201 		RADEON_DAC2_FORCE_DATA_EN |
202 		RADEON_DAC_FORCE_DATA_SEL_RGB |
203 		(0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
204 	OUTREG( regs, RADEON_DAC_EXT_CNTL, tmp );
205 
206 	old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );
207 
208 	// set DAC in CRT mode and enable detection
209 	// TODO: make sure we really use CRTC2 - this is ASIC dependant
210 	tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN;
211 	OUTREG( regs, RADEON_DAC_CNTL2, tmp );
212 
213 	snooze( 10000 );
214 
215 	// let's see what we've got!
216 	found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUTPUT) != 0;
217 
218 	if( found )
219 		SHOW_INFO0( 2, "Found CRT connected to TV-DAC, i.e. DVI port" );
220 
221 	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );
222 	OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 );
223 	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );
224 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );
225 
226 	return found;
227 }
228 
229 // CRT on TV-DAC detection for r300
230 // checked for r300
231 static bool Radeon_DetectTVCRT_R300( accelerator_info *ai )
232 {
233 	vuint8 *regs = ai->regs;
234 	uint32 old_crtc2_gen_cntl, old_tv_dac_cntl, old_dac_cntl2, tmp;
235 	uint32 old_radeon_gpiopad_a;
236 	bool found;
237 
238 	old_radeon_gpiopad_a = INREG( regs, RADEON_GPIOPAD_A );
239 
240 	// whatever these flags mean - let's pray they won't get changed
241 	OUTREGP( regs, RADEON_GPIOPAD_EN, 1, ~1 );
242 	OUTREGP( regs, RADEON_GPIOPAD_MASK, 1, ~1 );
243 	OUTREGP( regs, RADEON_GPIOPAD_A, 1, ~1 );
244 
245 	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );
246 
247 	// enable DAC, choose valid pixel format and enable DPMS
248 	// as usual, the code doesn't take into account whether the TV-DAC
249 	// does really use CRTC2
250 	tmp = old_crtc2_gen_cntl;
251 	tmp &= ~RADEON_CRTC2_PIX_WIDTH_MASK;
252 	tmp |=
253 		(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT) |
254 		RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT;
255 
256 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, tmp );
257 
258 	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );
259 
260 	// enable TV-DAC
261 	OUTREG( regs, RADEON_TV_DAC_CNTL,
262 		RADEON_TV_DAC_CNTL_NBLANK | RADEON_TV_DAC_CNTL_NHOLD |
263 		RADEON_TV_DAC_CNTL_DETECT |
264 		RADEON_TV_DAC_CNTL_STD_PS2 );
265 
266 	// force constant voltage output of DAC for impedance test
267 	OUTREG( regs, RADEON_DAC_EXT_CNTL,
268 		RADEON_DAC2_FORCE_BLANK_OFF_EN | RADEON_DAC2_FORCE_DATA_EN |
269     	RADEON_DAC_FORCE_DATA_SEL_RGB |
270     	(0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT ));
271 
272     old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );
273 
274 	// enable CRT mode of TV-DAC and enable comparator
275     tmp = old_dac_cntl2 | RADEON_DAC2_CLK_SEL_CRT | RADEON_DAC2_CMP_EN;
276 
277     OUTREG( regs, RADEON_DAC_CNTL2, tmp );
278 
279     snooze( 10000 );
280 
281     // check connection of blue data signal to see whether there is a CRT
282 	found = (INREG( regs, RADEON_DAC_CNTL2 ) & RADEON_DAC2_CMP_OUT_B) != 0;
283 
284     // clean up the mess
285 	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );
286 	OUTREG( regs, RADEON_DAC_EXT_CNTL, 0 );
287 	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );
288 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );
289 
290 	OUTREGP( regs, RADEON_GPIOPAD_A, old_radeon_gpiopad_a, ~1 );
291 
292     return found;
293 }
294 
295 
296 // check whether there is a CRT connected to TV-DAC
297 static bool Radeon_DetectTVCRT( accelerator_info *ai )
298 {
299 	if (ai->si->is_mobility)
300 		return dd_none;
301 
302 	switch( ai->si->asic ) {
303 	case rt_r100:
304 		// original Radeons have pure DVI only and mobility chips
305 		// have no DVI connector
306 		// TBD: can they have a docking station for CRT on TV-DAC?
307 		return dd_none;
308 
309 	case rt_rv100:
310 	case rt_rv200:
311 	case rt_rv250:
312 	case rt_rv280:
313 	// IGP is guessed
314 	case rt_rs100:
315 	case rt_rs200:
316 	case rt_rs300:
317 		return Radeon_DetectTVCRT_RV200( ai );
318 
319 	case rt_r300:
320 	case rt_r350:
321 	case rt_rv350:
322 	case rt_rv380:
323 	case rt_r420:
324 		return Radeon_DetectTVCRT_R300( ai );
325 
326 	case rt_r200:
327 		// r200 has no built-in TV-out and thus no TV-DAC to use for
328 		// second CRT
329 		return dd_none;
330 	}
331 
332 	return dd_none;
333 }
334 
335 
336 // TV detection for rv200 and below
337 // should work for M6 and RV200
338 static display_device_e Radeon_DetectTV_RV200( accelerator_info *ai, bool tv_crt_found )
339 {
340 	vuint8 *regs = ai->regs;
341 	uint32
342 		tmp, old_dac_cntl2, old_crtc_ext_cntl, old_crtc2_gen_cntl, old_tv_master_cntl,
343 		old_tv_dac_cntl, old_pre_dac_mux_cntl, config_cntl;
344 	display_device_e displays = dd_none;
345 
346 	// give up if there is a CRT connected to TV-DAC
347 	if( tv_crt_found )
348 		return dd_none;
349 
350 	// enable TV mode
351 	old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );
352 	tmp = old_dac_cntl2 & ~RADEON_DAC2_CLK_SEL_CRT;
353 	OUTREG( regs, RADEON_DAC_CNTL2, tmp );
354 
355 	old_crtc_ext_cntl = INREG( regs, RADEON_CRTC_EXT_CNTL );
356 	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );
357 	old_tv_master_cntl = INREG( regs, RADEON_TV_MASTER_CNTL );
358 
359 	// enable TV output
360 	tmp = old_tv_master_cntl | RADEON_TV_MASTER_CNTL_TV_ON;
361 	tmp &= ~(
362 		RADEON_TV_MASTER_CNTL_TV_ASYNC_RST |
363 		RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX |
364 		RADEON_TV_MASTER_CNTL_CRT_FIFO_CE_EN |
365 		RADEON_TV_MASTER_CNTL_TV_FIFO_CE_EN |
366 		RADEON_TV_MASTER_CNTL_RE_SYNC_NOW_SEL_MASK);
367 	tmp |=
368 		RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST |
369 		RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST;
370 	OUTREG( regs, RADEON_TV_MASTER_CNTL, tmp );
371 
372 	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );
373 
374 	config_cntl = INREG( regs, RADEON_CONFIG_CNTL );
375 
376 	// unlock TV DAC
377 	tmp =
378 		RADEON_TV_DAC_CNTL_NBLANK | RADEON_TV_DAC_CNTL_NHOLD |
379 		RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_STD_NTSC |
380 		(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) |
381 		((((config_cntl & RADEON_CFG_ATI_REV_ID_MASK) == 0) ? 8 : 4) << RADEON_TV_DAC_CNTL_DACADJ_SHIFT);
382 	OUTREG( regs, RADEON_TV_DAC_CNTL, tmp );
383 
384 	old_pre_dac_mux_cntl = INREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL );
385 
386 	// force constant DAC output voltage
387 	tmp =
388 		RADEON_TV_PRE_DAC_MUX_CNTL_C_GRN_EN | RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN |
389 		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_RED_MX_SHIFT) |
390 		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_GRN_MX_SHIFT) |
391 		(RADEON_TV_MUX_FORCE_DAC_DATA << RADEON_TV_PRE_DAC_MUX_CNTL_BLU_MX_SHIFT) |
392 		(0x109 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT);
393 	OUTREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL, tmp );
394 
395 	// let things settle a bit
396 	snooze( 3000 );
397 
398 	// now see which wires are connected
399 	tmp = INREG( regs, RADEON_TV_DAC_CNTL );
400 	if( (tmp & RADEON_TV_DAC_CNTL_GDACDET) != 0 ) {
401 		displays |= dd_stv;
402 		SHOW_INFO0( 2, "S-Video TV-Out is connected" );
403 	}
404 
405 	if( (tmp & RADEON_TV_DAC_CNTL_BDACDET) != 0 ) {
406 		displays |= dd_ctv;
407 		SHOW_INFO0( 2, "Composite TV-Out is connected" );
408 	}
409 
410 	OUTREG( regs, RADEON_TV_PRE_DAC_MUX_CNTL, old_pre_dac_mux_cntl );
411 	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );
412 	OUTREG( regs, RADEON_TV_MASTER_CNTL, old_tv_master_cntl );
413 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );
414 	OUTREG( regs, RADEON_CRTC_EXT_CNTL, old_crtc_ext_cntl );
415 	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );
416 
417 	return displays;
418 }
419 
420 
421 // TV detection for r300 series
422 // should work for R300
423 static display_device_e Radeon_DetectTV_R300( accelerator_info *ai )
424 {
425 	vuint8 *regs = ai->regs;
426 	display_device_e displays = dd_none;
427 	uint32 tmp, old_dac_cntl2, old_crtc2_gen_cntl, old_dac_ext_cntl, old_tv_dac_cntl;
428 	uint32 old_radeon_gpiopad_a;
429 
430 	old_radeon_gpiopad_a = INREG( regs, RADEON_GPIOPAD_A );
431 
432 	// whatever these flags mean - let's pray they won't get changed
433 	OUTREGP( regs, RADEON_GPIOPAD_EN, 1, ~1 );
434 	OUTREGP( regs, RADEON_GPIOPAD_MASK, 1, ~1 );
435 	OUTREGP( regs, RADEON_GPIOPAD_A, 0, ~1 );
436 
437 	old_dac_cntl2 = INREG( regs, RADEON_DAC_CNTL2 );
438 
439 	// set CRT mode (!) of TV-DAC
440 	OUTREG( regs, RADEON_DAC_CNTL2, RADEON_DAC2_CLK_SEL_CRT );
441 
442 	old_crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL );
443 
444 	// enable TV-Out output, but set DPMS mode
445 	// (this seems to be not correct if TV-Out is connected to CRTC1,
446 	//  but it doesn't really hurt having wrong DPMS mode)
447 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL,
448 		RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
449 
450 	old_dac_ext_cntl = INREG( regs, RADEON_DAC_EXT_CNTL );
451 
452 	// force constant voltage output of DAC for impedance test
453 	OUTREG( regs, RADEON_DAC_EXT_CNTL,
454 		RADEON_DAC2_FORCE_BLANK_OFF_EN | RADEON_DAC2_FORCE_DATA_EN |
455     	RADEON_DAC_FORCE_DATA_SEL_RGB |
456     	(0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
457 
458 	old_tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL );
459 
460 	// get TV-DAC running (or something...)
461 	OUTREG( regs, RADEON_TV_DAC_CNTL,
462 		RADEON_TV_DAC_CNTL_STD_NTSC |
463 		(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) |
464 		(6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT ));
465 
466 	(void)INREG( regs, RADEON_TV_DAC_CNTL );
467 
468 	snooze( 4000 );
469 
470 	OUTREG( regs, RADEON_TV_DAC_CNTL,
471 		RADEON_TV_DAC_CNTL_NBLANK | RADEON_TV_DAC_CNTL_NHOLD |
472 		RADEON_TV_DAC_CNTL_DETECT |
473 		RADEON_TV_DAC_CNTL_STD_NTSC |
474 		(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) |
475 		(6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT ));
476 
477 	(void)INREG( regs, RADEON_TV_DAC_CNTL );
478 
479 	snooze( 6000 );
480 
481 	// now see which wires are connected
482 	tmp = INREG( regs, RADEON_TV_DAC_CNTL );
483 	if( (tmp & RADEON_TV_DAC_CNTL_GDACDET) != 0 ) {
484 		displays |= dd_stv;
485 		SHOW_INFO0( 2, "S-Video TV-Out is connected" );
486 	}
487 
488 	if( (tmp & RADEON_TV_DAC_CNTL_BDACDET) != 0 ) {
489 		displays |= dd_ctv;
490 		SHOW_INFO0( 2, "Composite TV-Out is connected" );
491 	}
492 
493 	// clean up the mess we did
494 	OUTREG( regs, RADEON_TV_DAC_CNTL, old_tv_dac_cntl );
495 	OUTREG( regs, RADEON_DAC_EXT_CNTL, old_dac_ext_cntl );
496 	OUTREG( regs, RADEON_CRTC2_GEN_CNTL, old_crtc2_gen_cntl );
497 	OUTREG( regs, RADEON_DAC_CNTL2, old_dac_cntl2 );
498 
499 	OUTREGP( regs, RADEON_GPIOPAD_A, old_radeon_gpiopad_a, ~1 );
500 
501 	return displays;
502 }
503 
504 
505 // save readout of TV detection comparators
506 static bool readTVDetect( accelerator_info *ai )
507 {
508 	uint32 tmp;
509 	int i;
510 	bigtime_t start_time;
511 	bool detect;
512 
513 	// make output constant
514 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
515 		RADEON_TV_DAC_CNTL_STD_NTSC | RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_NBLANK );
516 
517 	// check detection result
518 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL, &tmp );
519 	detect = (tmp & RADEON_TV_DAC_CNTL_CMPOUT) != 0;
520 
521 	//SHOW_FLOW( 2, "detect=%d", detect );
522 
523 	start_time = system_time();
524 
525 	do {
526 		// wait for stable detect signal
527 		for( i = 0; i < 5; ++i ) {
528 			bool cur_detect;
529 
530 			Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
531 				RADEON_TV_DAC_CNTL_STD_NTSC | RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_NBLANK |
532 				RADEON_TV_DAC_CNTL_NHOLD );
533 			Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
534 				RADEON_TV_DAC_CNTL_STD_NTSC | RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_NBLANK );
535 
536 			Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL, &tmp );
537 			cur_detect = (tmp & RADEON_TV_DAC_CNTL_CMPOUT) != 0;
538 
539 			//SHOW_FLOW( 2, "cur_detect=%d", cur_detect );
540 
541 			if( cur_detect != detect )
542 				break;
543 
544 			detect = cur_detect;
545 		}
546 
547 		if( i == 5 ) {
548 			//SHOW_FLOW( 2, "return %d", detect );
549 			return detect;
550 		}
551 
552 		// don't wait forever - give up after 1 second
553 	} while( system_time() - start_time < 1000000 );
554 
555 	SHOW_FLOW0( 2, "timeout" );
556 
557 	return false;
558 }
559 
560 
561 // detect TV connected to external Theatre-Out
562 static display_device_e Radeon_DetectTV_Theatre( accelerator_info *ai )
563 {
564 	uint32
565 		old_tv_dac_cntl, old_pre_dac_mux_cntl, old_modulator_cntl1, old_master_cntl;
566 	uint32
567 		uv_adr, old_last_fifo_entry, old_mid_fifo_entry, last_fifo_addr;
568 	display_device_e displays = dd_none;
569 
570 	if( ai->si->tv_chip != tc_external_rt1 )
571 		return dd_none;
572 
573 	// save previous values (TV-Out may be running)
574 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL, &old_tv_dac_cntl );
575 
576 	// enable DAC and comparators
577 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
578 		RADEON_TV_DAC_CNTL_STD_NTSC | RADEON_TV_DAC_CNTL_DETECT |
579 		RADEON_TV_DAC_CNTL_NHOLD | RADEON_TV_DAC_CNTL_NBLANK );
580 
581 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_PRE_DAC_MUX_CNTL, &old_pre_dac_mux_cntl );
582 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_MODULATOR_CNTL1, &old_modulator_cntl1 );
583 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_MASTER_CNTL, &old_master_cntl );
584 
585 	// save output timing
586 	Radeon_VIPRead( ai, ai->si->theatre_channel, THEATRE_VIP_UV_ADR, &uv_adr );
587 
588 	last_fifo_addr = (uv_adr & RADEON_TV_UV_ADR_MAX_UV_ADR_MASK) * 2 + 1;
589 
590 	old_last_fifo_entry = Radeon_TheatreReadFIFO( ai, last_fifo_addr );
591 	old_mid_fifo_entry = Radeon_TheatreReadFIFO( ai, 0x18f );
592 
593 	Radeon_TheatreWriteFIFO( ai, last_fifo_addr, 0x20208 );
594 	Radeon_TheatreWriteFIFO( ai, 0x18f, 0x3ff2608 );
595 
596 	// stop TV-Out to savely program it
597 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MASTER_CNTL,
598 		RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST | RADEON_TV_MASTER_CNTL_TV_ASYNC_RST );
599 
600 	// set constant base level
601 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MODULATOR_CNTL1,
602 		(0x2c << RADEON_TV_MODULATOR_CNTL1_SET_UP_LEVEL_SHIFT) |
603 		(0x2c << RADEON_TV_MODULATOR_CNTL1_BLANK_LEVEL_SHIFT) );
604 
605 	// enable output
606 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MASTER_CNTL,
607 		RADEON_TV_MASTER_CNTL_TV_ASYNC_RST );
608 
609 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MASTER_CNTL,
610 		0 );
611 
612 	// set constant Composite output
613 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_PRE_DAC_MUX_CNTL,
614 		RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN |
615 		RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN |
616 		(9 << RADEON_TV_PRE_DAC_MUX_CNTL_BLU_MX_SHIFT) |
617 		(0xa8 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT) );
618 
619 	// check for S-Video connection
620 	if( readTVDetect( ai )) {
621 		SHOW_FLOW0( 2, "Composite-Out of Rage Theatre is connected" );
622 		displays |= dd_ctv;
623 	}
624 
625 	// enable output changes
626 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL,
627 		RADEON_TV_DAC_CNTL_STD_NTSC | RADEON_TV_DAC_CNTL_DETECT | RADEON_TV_DAC_CNTL_NBLANK |
628 		RADEON_TV_DAC_CNTL_NHOLD );
629 
630 	// set constant Y-output of S-Video adapter
631 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_PRE_DAC_MUX_CNTL,
632 		RADEON_TV_PRE_DAC_MUX_CNTL_Y_RED_EN |
633 		RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN |
634 		(9 << RADEON_TV_PRE_DAC_MUX_CNTL_RED_MX_SHIFT) |
635 		(0xa8 << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT) );
636 
637 	// check for composite connection
638 	if( readTVDetect( ai )) {
639 		SHOW_FLOW0( 2, "S-Video-Out of Rage Theatre is connected" );
640 		displays |= dd_stv;
641 	}
642 
643 	// restore everything
644 	Radeon_TheatreWriteFIFO( ai, last_fifo_addr, old_last_fifo_entry );
645 	Radeon_TheatreWriteFIFO( ai, 0x18f, old_mid_fifo_entry );
646 
647 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MASTER_CNTL, old_master_cntl );
648 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_MODULATOR_CNTL1, old_modulator_cntl1 );
649 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_PRE_DAC_MUX_CNTL, old_pre_dac_mux_cntl );
650 	Radeon_VIPWrite( ai, ai->si->theatre_channel, THEATRE_VIP_TV_DAC_CNTL, old_tv_dac_cntl );
651 
652 	return displays;
653 }
654 
655 // check whether there is a TV connected to TV-DAC
656 // returns bit set, i.e. there can be S-Video or composite or both
657 static display_device_e Radeon_DetectTV( accelerator_info *ai, bool tv_crt_found )
658 {
659 	switch( ai->si->asic ) {
660 	case rt_r100:
661 	case rt_r200:
662 		return Radeon_DetectTV_Theatre( ai );
663 
664 	case rt_rv100:
665 	case rt_rv200:
666 	case rt_rv250:
667 	case rt_rv280:
668 	// IGP method is guessed
669 	case rt_rs100:
670 	case rt_rs200:
671 	case rt_rs300:
672 		return Radeon_DetectTV_RV200( ai, tv_crt_found );
673 
674 	case rt_r300:
675 	case rt_r350:
676 	case rt_rv350:
677 	case rt_rv380:
678 	case rt_r420:
679 		return Radeon_DetectTV_R300( ai );
680 	}
681 
682 	return dd_none;
683 }
684 
685 
686 // get native monitor timing, using Detailed Monitor Description
687 static void Radeon_FindFPTiming_DetailedMonitorDesc(
688 	const edid1_info *edid, fp_info *fp, uint32 *max_hsize, uint32 *max_vsize )
689 {
690 	int i;
691 
692 	for( i = 0; i < EDID1_NUM_DETAILED_MONITOR_DESC; ++i ) {
693 		if( edid->detailed_monitor[i].monitor_desc_type == edid1_is_detailed_timing ) {
694 			const edid1_detailed_timing *timing = &edid->detailed_monitor[i].data.detailed_timing;
695 
696 			SHOW_FLOW( 2, "Found detailed timing for mode %dx%d in DDC data",
697 				(int)timing->h_active, (int)timing->v_active );
698 
699 			if( timing->h_active > *max_hsize && timing->v_active > *max_vsize ) {
700 				*max_hsize = timing->h_active;
701 				*max_vsize = timing->v_active;
702 
703 				// copy it to timing specification
704 				fp->panel_xres = timing->h_active;
705 				fp->h_blank = timing->h_blank;
706 				fp->h_over_plus = timing->h_sync_off;
707 				fp->h_sync_width = timing->h_sync_width;
708 
709 				fp->panel_yres = timing->v_active;
710 				fp->v_blank = timing->v_blank;
711 				fp->v_over_plus = timing->v_sync_off;
712 				fp->v_sync_width = timing->v_sync_width;
713 
714 				// BeOS uses kHz, but the timing is in 10 kHz
715 				fp->dot_clock = timing->pixel_clock * 10;
716 			}
717 		}
718 	}
719 }
720 
721 // get native monitor timing, using Standard Timing table;
722 // this table doesn't contain the actual timing, so we try to find a
723 // appropriate VESA modes for the resolutions given in the table
724 static void Radeon_FindFPTiming_StandardTiming(
725 	const edid1_info *edid, fp_info *fp, uint32 *max_hsize, uint32 *max_vsize )
726 {
727 	int i;
728 
729 	for( i = 0; i < EDID1_NUM_STD_TIMING; ++i ) {
730 		const edid1_std_timing *std_timing = &edid->std_timing[i];
731 
732 		int best_fit = -1;
733 		int best_refresh_deviation = 10000;
734 		int j;
735 
736 		if( std_timing->h_size <= 256 )
737 			continue;
738 
739 		for( j = 0; j < (int)vesa_mode_list_count; ++j ) {
740 			int refresh_rate, cur_refresh_deviation;
741 
742 			if( vesa_mode_list[j].h_display != std_timing->h_size ||
743 				vesa_mode_list[j].v_display != std_timing->v_size )
744 				continue;
745 
746 			// take pixel_clock times 1000 because is is in kHz
747 			// further, take it times 1000 again, to get 1/1000 frames
748 			// as refresh rate
749 			refresh_rate = (int64)vesa_mode_list[j].pixel_clock * 1000*1000 /
750 				(vesa_mode_list[j].h_total * vesa_mode_list[j].v_total);
751 
752 			// standard timing is in frames, so multiple by it to get 1/1000 frames
753 			// result is scaled by 100 to get difference in percentage;
754 			cur_refresh_deviation =
755 				(100 * (refresh_rate - std_timing->refresh * 1000)) / refresh_rate;
756 
757 			if( cur_refresh_deviation < 0 )
758 				cur_refresh_deviation = -cur_refresh_deviation;
759 
760 			// less then 1 percent difference is (hopefully) OK,
761 			// if there are multiple, we take best one
762 			// (if the screen is that picky, it should have defined an enhanced timing)
763 			if( cur_refresh_deviation < 1 &&
764 				cur_refresh_deviation < best_refresh_deviation )
765 			{
766 				best_fit = j;
767 				best_refresh_deviation = cur_refresh_deviation;
768 			}
769 		}
770 
771 		if( best_fit < 0 ) {
772 			SHOW_FLOW( 2, "Unsupported standard mode %dx%d@%dHz (not VESA)",
773 				std_timing->h_size, std_timing->v_size, std_timing->refresh );
774 			continue;
775 		}
776 
777 		if( std_timing->h_size > *max_hsize && std_timing->h_size > *max_vsize ) {
778 			const display_timing *timing = &vesa_mode_list[best_fit];
779 
780 			SHOW_FLOW( 2, "Found DDC data for standard mode %dx%d",
781 				(int)timing->h_display, (int)timing->v_display );
782 
783 			*max_hsize = timing->h_display;
784 			*max_vsize = timing->h_display;
785 
786 			// copy it to timing specification
787 			fp->panel_xres = timing->h_display;
788 			fp->h_blank = timing->h_total - timing->h_display;
789 			fp->h_over_plus = timing->h_sync_start - timing->h_display;
790 			fp->h_sync_width = timing->h_sync_end - timing->h_sync_start;
791 
792 			fp->panel_yres = timing->v_display;
793 			fp->v_blank = timing->v_total - timing->v_display;
794 			fp->v_over_plus = timing->v_sync_start - timing->v_display;
795 			fp->v_sync_width = timing->v_sync_end - timing->v_sync_start;
796 
797 			fp->dot_clock = timing->pixel_clock;
798 		}
799 	}
800 }
801 
802 // read edid data of flat panel and setup its timing accordingly
803 static status_t Radeon_StoreFPEDID( accelerator_info *ai, const edid1_info *edid )
804 {
805 	fp_info *fp = &ai->si->flatpanels[0];
806 	uint32 max_hsize, max_vsize;
807 
808 	//SHOW_FLOW0( 2, "EDID data read from DVI port via DDC2:" );
809 	//edid_dump( edid );
810 
811 	// find detailed timing with maximum resolution
812 	max_hsize = max_vsize = 0;
813 
814 	Radeon_FindFPTiming_DetailedMonitorDesc( edid, fp, &max_hsize, &max_vsize );
815 
816 	if( max_hsize == 0 ) {
817 		SHOW_FLOW0( 2, "Timing is not explicitely defined in DDC - checking standard modes" );
818 
819 		Radeon_FindFPTiming_StandardTiming(
820 			edid, fp, &max_hsize, &max_vsize );
821 
822 		if( max_hsize == 0 ) {
823 			SHOW_FLOW0( 2, "Still found no valid native mode, disabling DVI" );
824 			return B_ERROR;
825 		}
826 	}
827 
828 	SHOW_INFO( 2, "h_disp=%d, h_blank=%d, h_over_plus=%d, h_sync_width=%d",
829 		fp->panel_xres, fp->h_blank, fp->h_over_plus, fp->h_sync_width );
830 	SHOW_INFO( 2, "v_disp=%d, v_blank=%d, v_over_plus=%d, v_sync_width=%d",
831 		fp->panel_yres, fp->v_blank, fp->v_over_plus, fp->v_sync_width );
832 	SHOW_INFO( 2, "pixel_clock=%d kHz", fp->dot_clock );
833 
834 	return B_OK;
835 }
836 
837 static void Radeon_ConnectorInfo( accelerator_info *ai, int port, disp_entity* ptr_entity )
838 {
839 	const char* mon;
840 	const char* ddc =	ptr_entity->port_info[port].ddc_type == ddc_none_detected	? "None" :
841 						ptr_entity->port_info[port].ddc_type == ddc_monid			? "Mon ID" :
842 						ptr_entity->port_info[port].ddc_type == ddc_dvi				? "DVI DDC" :
843 						ptr_entity->port_info[port].ddc_type == ddc_vga				? "VGA DDC" :
844 						ptr_entity->port_info[port].ddc_type == ddc_crt2			? "CRT2 DDC" : "Error";
845 
846 	const char* tmds =	ptr_entity->port_info[port].tmds_type == tmds_unknown		? "None" :
847 						ptr_entity->port_info[port].tmds_type == tmds_int			? "Internal" :
848 						ptr_entity->port_info[port].tmds_type == tmds_ext			? "External" : "??? ";
849 
850 	const char* dac =	ptr_entity->port_info[port].dac_type == dac_unknown			? "Unknown" :
851 						ptr_entity->port_info[port].dac_type == dac_primary			? "Primary" :
852 						ptr_entity->port_info[port].dac_type == dac_tvdac			? "TV / External" : "Error";
853 
854 	const char* con;
855 	if (ai->si->is_atombios) {
856 				con =	ptr_entity->port_info[port].connector_type == connector_none_atom			? "None" :
857 						ptr_entity->port_info[port].connector_type == connector_vga_atom			? "VGA" :
858 						ptr_entity->port_info[port].connector_type == connector_dvi_i_atom			? "DVI-I" :
859 						ptr_entity->port_info[port].connector_type == connector_dvi_d_atom			? "DVI-D" :
860 						ptr_entity->port_info[port].connector_type == connector_dvi_a_atom			? "DVI-A" :
861 						ptr_entity->port_info[port].connector_type == connector_stv_atom			? "S-Video TV" :
862 						ptr_entity->port_info[port].connector_type == connector_ctv_atom			? "Composite TV" :
863 						ptr_entity->port_info[port].connector_type == connector_lvds_atom			? "LVDS" :
864 						ptr_entity->port_info[port].connector_type == connector_digital_atom		? "Digital" :
865 						ptr_entity->port_info[port].connector_type == connector_unsupported_atom	? "N/A  " : "Err  ";
866 	} else {
867 				con =	ptr_entity->port_info[port].connector_type == connector_none		? "None" :
868 						ptr_entity->port_info[port].connector_type == connector_crt			? "VGA" :
869 						ptr_entity->port_info[port].connector_type == connector_dvi_i		? "DVI-I" :
870 						ptr_entity->port_info[port].connector_type == connector_dvi_d		? "DVI-D" :
871 						ptr_entity->port_info[port].connector_type == connector_proprietary ? "Proprietary" :
872 						ptr_entity->port_info[port].connector_type == connector_stv			? "S-Video TV" :
873 						ptr_entity->port_info[port].connector_type == connector_ctv			? "Composite TV" :
874 						ptr_entity->port_info[port].connector_type == connector_unsupported ? "N/A" : "Err";
875 	}
876 
877 				mon = 	ptr_entity->port_info[port].mon_type == mt_unknown ? "???" :
878 						ptr_entity->port_info[port].mon_type == mt_none    ? "None" :
879 						ptr_entity->port_info[port].mon_type == mt_crt     ? "CRT " :
880 						ptr_entity->port_info[port].mon_type == mt_lcd     ? "LCD " :
881 						ptr_entity->port_info[port].mon_type == mt_dfp     ? "DVI " :
882 						ptr_entity->port_info[port].mon_type == mt_ctv     ? "Composite TV" :
883 						ptr_entity->port_info[port].mon_type == mt_stv     ? "S-Video TV" : "Err ?";
884 
885 	SHOW_INFO( 2 , "Port %d:- \nMonitor:    %s\nConn Type:  %s\nDDC Port:   %s\nTMDS Type:  %s\nDAC Type:   %s",
886 					port, mon, con, ddc, tmds, dac);
887 }
888 
889 
890 // detect connected displays devices
891 // whished_num_heads - how many heads the requested display mode needs
892 void Radeon_DetectDisplays( accelerator_info *ai )
893 {
894 	shared_info *si = ai->si;
895 
896 	disp_entity* routes = &si->routing;
897 	display_device_e displays = 0;
898 	display_device_e controlled_displays = ai->vc->controlled_displays;
899 	int i;
900 
901 	uint32 edid_regs[] = {
902 		0,
903 		RADEON_GPIO_MONID,
904 		RADEON_GPIO_DVI_DDC,
905 		RADEON_GPIO_VGA_DDC,
906 		RADEON_GPIO_CRT2_DDC
907 	};
908 
909 	// lock hardware so noone bothers us
910 	Radeon_WaitForIdle( ai, true );
911 
912 	// alwats make TMDS_INT port first
913 	if (routes->port_info[1].tmds_type == tmds_int) {
914 
915 		radeon_connector swap_entity;
916 		swap_entity = routes->port_info[0];
917 		routes->port_info[0] = routes->port_info[1];
918 		routes->port_info[1] = swap_entity;
919 		SHOW_FLOW0( 2, "Swapping TMDS_INT to first port");
920 	}
921 	else if ( routes->port_info[0].tmds_type != tmds_int &&
922 			  routes->port_info[1].tmds_type != tmds_int ) {
923 
924 		// no TMDS_INT port, make primary DAC port first
925 		// On my Inspiron 8600 both internal and external ports are
926 		// marked DAC_PRIMARY in BIOS. So be extra careful - only
927 		// swap when the first port is not DAC_PRIMARY
928 		if ( routes->port_info[1].dac_type == dac_primary &&
929 			 routes->port_info[0].dac_type != dac_primary ) {
930 
931 			radeon_connector swap_entity;
932 			swap_entity = routes->port_info[0];
933 			routes->port_info[0] = routes->port_info[1];
934 			routes->port_info[1] = swap_entity;
935 			SHOW_FLOW0( 2, "Swapping Primary Dac to front");
936 		}
937 	}
938 
939 	if ( si->asic == rt_rs300 )  // RS300 only has single Dac of TV type
940 	{
941 		// For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC
942 		if ( routes->port_info[0].connector_type == connector_crt ) {
943 			routes->port_info[0].dac_type = dac_tvdac;
944 			routes->port_info[1].dac_type = dac_primary;
945 		} else {
946 			routes->port_info[1].dac_type = dac_primary;
947 			routes->port_info[0].dac_type = dac_tvdac;
948 		}
949 	} else if ( si->num_crtc == 1 )	{
950 
951 		routes->port_info[0].dac_type = dac_primary;
952 	}
953 
954 	// use DDC to detect monitors - if we can read DDC, there must be a monitor
955 	for ( i = 0; i < 2; i++ )
956 	{
957 		if (routes->port_info[i].mon_type != mt_unknown ) {
958 			SHOW_FLOW0( 2, "known type, skpping detection" );
959 			continue;
960 		}
961 
962 		memset( &routes->port_info[i].edid , 0, sizeof(edid1_info) );
963 		switch ( routes->port_info[i].ddc_type ) {
964 			case ddc_monid:
965 			case ddc_dvi:
966 			case ddc_vga:
967 			case ddc_crt2:
968 				if ( Radeon_ReadEDID( ai, edid_regs[routes->port_info[i].ddc_type], &routes->port_info[i].edid ))
969 				{
970 					routes->port_info[i].edid_valid = true;
971 					SHOW_FLOW( 2, "Edid Data for CRTC %d on line %d", i, routes->port_info[i].ddc_type );
972 					edid_dump ( &routes->port_info[i].edid );
973 				} else {
974 					routes->port_info[i].mon_type = mt_none;
975 				}
976 
977 				break;
978 			default:
979 				SHOW_FLOW( 2, "No Edid Pin Assigned to CRTC %d ", i );
980 				routes->port_info[i].mon_type = mt_none;
981 		}
982 
983 		if ( routes->port_info[i].edid_valid ) {
984 
985 			if( routes->port_info[i].edid.display.input_type == 1 ) {
986 				SHOW_FLOW0( 2, "Must be a DVI monitor" );
987 
988 				// Note some laptops have a DVI output that uses internal TMDS,
989 				// when its DVI is enabled by hotkey, LVDS panel is not used.
990 				// In this case, the laptop is configured as DVI+VGA as a normal
991 				// desktop card.
992 				// Also for laptop, when X starts with lid closed (no DVI connection)
993 				// both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
994 				if ( routes->port_info[i].tmds_type == tmds_ext ){
995 					// store info about DVI-connected flat-panel
996 					if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {
997 						SHOW_INFO0( 2, "Found Ext Laptop DVI" );
998 						routes->port_info[i].mon_type = mt_dfp;
999 						displays |= dd_dvi_ext;
1000 					} else {
1001 						SHOW_ERROR0( 2, "Disabled Ext DVI - invalid EDID" );
1002 					}
1003 				} else {
1004 					if( INREG( ai->regs, RADEON_FP_GEN_CNTL) & (1 << 7) || ( !si->is_mobility ) ) {
1005 						// store info about DVI-connected flat-panel
1006 						if( Radeon_StoreFPEDID( ai, &routes->port_info[i].edid ) == B_OK ) {
1007 							SHOW_INFO0( 2, "Found DVI" );
1008 							routes->port_info[i].mon_type = mt_dfp;
1009 							displays |= dd_dvi;
1010 						} else {
1011 							SHOW_ERROR0( 2, "Disabled DVI - invalid EDID" );
1012 						}
1013 					} else {
1014 						SHOW_INFO0( 2, "Laptop Panel Found" );
1015 						routes->port_info[i].mon_type = mt_lcd;
1016 						displays |= dd_lvds;
1017 					}
1018 				}
1019 			} else {
1020 				// must be the analog portion of DVI
1021 				// I'm not sure about Radeons with one CRTC - do they have DVI-I or DVI-D?
1022 				// anyway - if there are two CRTC, analog portion must be connected
1023 				// to TV-DAC; if there is one CRTC, it must be the normal VGA-DAC
1024 				if( si->num_crtc > 1 ) {
1025 					SHOW_FLOW0( 2, "Must be an analog monitor on DVI port" );
1026 					routes->port_info[i].mon_type = mt_crt;
1027 					displays |= dd_tv_crt;
1028 				} else {
1029 					SHOW_FLOW0( 2, "Seems to be a CRT on VGA port!?" );
1030 					routes->port_info[i].mon_type = mt_crt;
1031 					displays |= dd_crt;
1032 				}
1033 			}
1034 		}
1035 	}
1036 
1037 
1038 	if ( !routes->port_info[0].edid_valid ) {
1039 		SHOW_INFO0( 2, "Searching port 0" );
1040 		if ( si->is_mobility && (INREG( ai->regs, RADEON_BIOS_4_SCRATCH) & 4)) {
1041 			SHOW_INFO0( 2, "Found Laptop Panel" );
1042 			routes->port_info[0].mon_type = mt_lcd;
1043 			displays |= dd_lvds;
1044 		}
1045 	}
1046 
1047 	if ( !routes->port_info[1].edid_valid ) {
1048 
1049 		if ( si->is_mobility && (INREG( ai->regs, RADEON_FP2_GEN_CNTL) & RADEON_FP2_FPON)) {
1050 			SHOW_INFO0( 2, "Found Ext Laptop DVI" );
1051 			routes->port_info[1].mon_type = mt_dfp;
1052 			displays |= dd_dvi;
1053 		}
1054 	}
1055 
1056 	if ( routes->port_info[0].mon_type == mt_none )
1057 	{
1058 		if ( routes->port_info[1].mon_type == mt_none ) {
1059 			routes->port_info[0].mon_type = mt_crt;
1060 		} else {
1061 			radeon_connector swap_entity;
1062 			swap_entity = routes->port_info[0];
1063 			routes->port_info[0] = routes->port_info[1];
1064 			routes->port_info[1] = swap_entity;
1065 			SHOW_ERROR0( 2, "swapping active port 2 to free port 1" );
1066 		}
1067 
1068 	}
1069 
1070 	routes->reversed_DAC = false;
1071 	if ( routes->port_info[1].dac_type == dac_tvdac ) {
1072 		SHOW_ERROR0( 2, "Reversed dac detected (not impl. yet)" );
1073 		routes->reversed_DAC = true;
1074 	}
1075 
1076 
1077 
1078 	// we may have overseen monitors if they don't support DDC or
1079 	// have broken DDC data (like mine);
1080 	// time to do a physical wire test; this test is more reliable, but it
1081 	// leads to distortions on screen, which is not very nice to look at
1082 
1083 	// for DVI, there is no mercy if no DDC data is there - we wouldn't
1084 	// even know the native resolution of the panel!
1085 
1086 	// all versions have a standard VGA port
1087 	if( (displays & dd_crt) == 0 &&
1088 		(controlled_displays & dd_crt) != 0 &&
1089 		Radeon_DetectCRT( ai ))
1090 		displays |= dd_crt;
1091 
1092 	// check VGA signal routed to DVI port
1093 	// (the detection code checks whether there is hardware for that)
1094 	if( (displays & dd_tv_crt) == 0 &&
1095 		(controlled_displays & dd_tv_crt) != 0 &&
1096 		Radeon_DetectTVCRT( ai ))
1097 		displays |= dd_tv_crt;
1098 
1099 	// check TV-out connector
1100 	if( (controlled_displays && (dd_ctv | dd_stv)) != 0 )
1101 		displays |= Radeon_DetectTV( ai, (displays & dd_tv_crt) != 0 );
1102 
1103 	SHOW_INFO( 0, "Detected monitors: 0x%x", displays );
1104 
1105 	displays &= controlled_displays;
1106 
1107 	// if no monitor found, we define to have a CRT connected to CRT-DAC
1108 	if( displays == 0 )
1109 		displays = dd_crt;
1110 
1111 	Radeon_ConnectorInfo( ai, 0, routes);
1112 	Radeon_ConnectorInfo( ai, 1, routes);
1113 
1114 	ai->vc->connected_displays = displays;
1115 
1116 	RELEASE_BEN( si->cp.lock );
1117 }
1118