2 Copyright (c) 2002-04, Thomas Kurschel
5 Part of Radeon accelerant
7 CRTC <-> display routing
9 This stuff is highly ASIC dependant and is probably the most ASIC-specific
10 code of the entire project.
13 #include "radeon_accelerant.h"
17 #include "crtc_regs.h"
18 #include "tv_out_regs.h"
20 #include "gpiopad_regs.h"
21 #include "pll_access.h"
25 // read regs needed for display device routing
26 void Radeon_ReadMonitorRoutingRegs(
27 accelerator_info
*ai
, routing_regs
*values
)
29 vuint8
*regs
= ai
->regs
;
31 values
->dac_cntl
= INREG( regs
, RADEON_DAC_CNTL
);
32 values
->dac_cntl2
= INREG( regs
, RADEON_DAC_CNTL2
);
33 values
->crtc_ext_cntl
= INREG( regs
, RADEON_CRTC_EXT_CNTL
);
34 values
->crtc2_gen_cntl
= INREG( regs
, RADEON_CRTC2_GEN_CNTL
);
35 values
->disp_output_cntl
= INREG( regs
, RADEON_DISP_OUTPUT_CNTL
);
36 values
->pixclks_cntl
= Radeon_INPLL( ai
->regs
, ai
->si
->asic
, RADEON_PIXCLKS_CNTL
);
37 values
->vclk_ecp_cntl
= Radeon_INPLL( ai
->regs
, ai
->si
->asic
, RADEON_VCLK_ECP_CNTL
);
39 switch( ai
->si
->asic
) {
47 values
->disp_hw_debug
= INREG( regs
, RADEON_DISP_HW_DEBUG
);
51 values
->disp_tv_out_cntl
= INREG( regs
, RADEON_DISP_TV_OUT_CNTL
);
59 values
->gpiopad_a
= INREG( regs
, RADEON_GPIOPAD_A
);
66 if( ai
->si
->asic
> rt_r100
) {
67 // register introduced after R100
68 values
->tv_dac_cntl
= INREG( regs
, RADEON_TV_DAC_CNTL
);
71 if( IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
))
72 values
->tv_master_cntl
= INREG( regs
, RADEON_TV_MASTER_CNTL
);
74 values
->fp_gen_cntl
= INREG( regs
, RADEON_FP_GEN_CNTL
);
75 values
->fp2_gen_cntl
= INREG( regs
, RADEON_FP2_GEN_CNTL
);
79 // setup register contents to proper CRTC <-> display device mapping
80 void Radeon_CalcMonitorRouting(
81 accelerator_info
*ai
, const impactv_params
*tv_parameters
, routing_regs
*values
)
83 display_device_e display_devices
[2], total_devices
, controlled_devices
;
85 if( ai
->vc
->used_crtc
[0] )
86 display_devices
[0] = ai
->si
->crtc
[0].chosen_displays
;
88 display_devices
[0] = dd_none
;
90 if( ai
->vc
->used_crtc
[1] )
91 display_devices
[1] = ai
->si
->crtc
[1].chosen_displays
;
93 display_devices
[1] = dd_none
;
95 total_devices
= display_devices
[0] | display_devices
[1];
96 controlled_devices
= ai
->vc
->controlled_displays
;
99 // (could be moved to boot initialization)
101 RADEON_DAC_MASK_ALL
| RADEON_DAC_VGA_ADR_EN
| RADEON_DAC_8BIT_EN
;
103 // enable frame buffer access and extended CRTC counter
104 // (again: something for boot init.)
105 values
->crtc_ext_cntl
=
106 RADEON_VGA_ATI_LINEAR
| RADEON_XCRT_CNT_EN
;
108 // set VGA signal style (not sure whether this affects
109 // CRTC1 or CRT-DAC, so we better always set it)
110 values
->dac_cntl
&= ~(RADEON_DAC_RANGE_CNTL_MASK
| RADEON_DAC_BLANKING
);
111 values
->dac_cntl
|= RADEON_DAC_RANGE_CNTL_PS2
;
113 // disable all the magic CRTC shadowing
114 values
->fp_gen_cntl
&=
115 ~(RADEON_FP_RMX_HVSYNC_CONTROL_EN
|
116 RADEON_FP_DFP_SYNC_SEL
|
117 RADEON_FP_CRT_SYNC_SEL
|
118 RADEON_FP_CRTC_LOCK_8DOT
|
119 RADEON_FP_USE_SHADOW_EN
|
120 RADEON_FP_CRTC_USE_SHADOW_VEND
|
121 RADEON_FP_CRT_SYNC_ALT
);
122 values
->fp_gen_cntl
|=
123 RADEON_FP_CRTC_DONT_SHADOW_VPAR
|
124 RADEON_FP_CRTC_DONT_SHADOW_HEND
;
127 if( (total_devices
& dd_crt
) != 0 ) {
128 int crtc_idx
= (display_devices
[1] & dd_crt
) != 0;
130 // the CRT_ON flag seems to directly affect the CRT-DAC, _not_ the CRTC1 signal
131 values
->crtc_ext_cntl
|= RADEON_CRTC_CRT_ON
;
133 switch( ai
->si
->asic
) {
141 values
->dac_cntl2
&= ~RADEON_DAC_CLK_SEL_MASK
;
142 values
->dac_cntl2
|= crtc_idx
== 0 ? 0 : RADEON_DAC_CLK_SEL_CRTC2
;
151 values
->disp_output_cntl
&= ~RADEON_DISP_DAC_SOURCE_MASK
;
152 values
->disp_output_cntl
|=
153 (crtc_idx
== 0 ? 0 : RADEON_DISP_DAC_SOURCE_CRTC2
);
160 } else if( (controlled_devices
& dd_crt
) != 0 ) {
161 values
->crtc_ext_cntl
&= ~RADEON_CRTC_CRT_ON
;
165 if( (total_devices
& (dd_tv_crt
| dd_ctv
| dd_stv
)) != 0 ) {
167 // (but only if TV-Out _and_ TV-CRT is controlled by us)
168 // this will be undone if needed
169 values
->tv_dac_cntl
|=
170 RADEON_TV_DAC_CNTL_RDACPD
|
171 RADEON_TV_DAC_CNTL_GDACPD
|
172 RADEON_TV_DAC_CNTL_BDACPD
;
176 // set CRT mode of TV-DAC if needed
177 // (doesn't work on r200, but there is no TV-DAC used for CRT anyway)
178 if( (total_devices
& dd_tv_crt
) != 0 ) {
179 // enable CRT via TV-DAC (ignored if TV-DAC is in TV-Out mode)
180 values
->crtc2_gen_cntl
|= RADEON_CRTC2_CRT2_ON
;
182 values
->dac_cntl2
&= ~RADEON_DAC2_CLK_SEL_MASK
;
183 values
->dac_cntl2
|= RADEON_DAC2_CLK_SEL_CRT
;
185 // enable TV-DAC and set PS2 signal level
186 values
->tv_dac_cntl
=
187 RADEON_TV_DAC_CNTL_NBLANK
|
188 RADEON_TV_DAC_CNTL_NHOLD
|
189 RADEON_TV_DAC_CNTL_STD_PS2
|
190 (8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT
) |
191 (2 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT
);
193 // at least r300 needs magic bit set to switch between TV-CRT and TV-Out
195 values
->gpiopad_a
|= 1;
197 } else if( (controlled_devices
& dd_tv_crt
) != 0 ) {
198 values
->crtc2_gen_cntl
&= ~RADEON_CRTC2_CRT2_ON
;
201 values
->skip_tv_dac
= false;
204 // disable forwarding data to TV-Out unit
205 // (will be enabled on demand later on)
206 if( (controlled_devices
& (dd_ctv
| dd_stv
)) != 0 )
207 values
->dac_cntl
&= ~RADEON_DAC_TVO_EN
;
210 // set TV mode of TV-DAC if needed
211 if( (total_devices
& (dd_ctv
| dd_stv
)) != 0 ) {
213 values
->dac_cntl2
&= ~RADEON_DAC2_CLK_SEL_MASK
;
214 values
->dac_cntl2
|= RADEON_DAC2_CLK_SEL_TV
;
216 // at least r300 needs magic bit set to switch between TV-CRT and TV-Out
218 values
->gpiopad_a
&= ~1;
221 // the TV-DAC itself is under control of the TV-Out code
222 values
->skip_tv_dac
= true;
224 if( !IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
)) {
225 // tell DAC to forward data to external chip
226 values
->dac_cntl
|= RADEON_DAC_TVO_EN
;
228 // set Output Linear Transform Unit as source
229 // (TODO: is this unit initialized properly?)
230 // disable overlay sync (could be a good idea to enable it)
232 values
->disp_output_cntl
&=
233 ~(RADEON_DISP_TV_SOURCE
|
234 RADEON_DISP_TV_MODE_MASK
|
235 RADEON_DISP_TV_YG_DITH_EN
|
236 RADEON_DISP_TV_CBB_CRR_DITH_EN
|
237 RADEON_DISP_TV_BIT_WIDTH
|
238 RADEON_DISP_TV_SYNC_MODE_MASK
|
239 RADEON_DISP_TV_SYNC_COLOR_MASK
);
242 values
->disp_output_cntl
|=
243 RADEON_DISP_TV_YG_DITH_EN
|
244 RADEON_DISP_TV_CBB_CRR_DITH_EN
;
246 // set output data format
247 values
->disp_output_cntl
|= tv_parameters
->mode888
?
248 RADEON_DISP_TV_MODE_888
: RADEON_DISP_TV_MODE_565
;
250 switch( ai
->si
->asic
) {
252 // disable downfiltering and scaling, set RGB mode,
253 // don't transmit overlay indicator;
254 // I don't really know whether this is a good choice
255 values
->disp_tv_out_cntl
&=
256 (RADEON_DISP_TV_OUT_YG_FILTER_MASK
|
257 RADEON_DISP_TV_OUT_YG_SAMPLE
|
258 RADEON_DISP_TV_OUT_CrR_FILTER_MASK
|
259 RADEON_DISP_TV_OUT_CrR_SAMPLE
|
260 RADEON_DISP_TV_OUT_CbB_FILTER_MASK
|
261 RADEON_DISP_TV_OUT_CbB_SAMPLE
|
262 RADEON_DISP_TV_SUBSAMPLE_CNTL_MASK
|
263 RADEON_DISP_TV_H_DOWNSCALE
|
264 RADEON_DISP_TV_COLOR_SPACE
|
265 RADEON_DISP_TV_DITH_MODE
|
266 RADEON_DISP_TV_DATA_ZERO_SEL
|
267 RADEON_DISP_TV_CLKO_SEL
|
268 RADEON_DISP_TV_CLKO_OUT_EN
|
269 RADEON_DISP_TV_DOWNSCALE_CNTL
);
271 // enable TVOCLKO (is this needed?)
272 values
->disp_tv_out_cntl
|= RADEON_DISP_TV_CLKO_OUT_EN
;
280 } else if( (controlled_devices
& (dd_ctv
| dd_stv
)) != 0 ) {
281 if( IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
)) {
282 // disable clock of TV-out units
283 values
->tv_master_cntl
=
284 RADEON_TV_MASTER_CNTL_TV_ASYNC_RST
|
285 RADEON_TV_MASTER_CNTL_CRT_ASYNC_RST
|
286 RADEON_TV_MASTER_CNTL_TV_FIFO_ASYNC_RST
|
287 RADEON_TV_MASTER_CNTL_TVCLK_ALWAYS_ONb
;
291 // choose CRTC for TV-DAC
292 if( (total_devices
& (dd_tv_crt
| dd_ctv
| dd_stv
)) != 0 ) {
293 int crtc_idx
= (display_devices
[1] & (dd_tv_crt
| dd_ctv
| dd_stv
)) != 0;
295 switch( ai
->si
->asic
) {
303 values
->disp_hw_debug
&= ~RADEON_CRT2_DISP1_SEL
;
304 // warning: meaning is wrong way around - 0 means crtc2, 1 means crtc1
305 values
->disp_hw_debug
|= crtc_idx
== 0 ? RADEON_CRT2_DISP1_SEL
: 0;
309 // TV-Out data comes directly from CRTC (i.e. with Linear Transform Unit)
310 values
->disp_output_cntl
|= RADEON_DISP_TV_SOURCE
;
312 values
->disp_tv_out_cntl
&= ~RADEON_DISP_TV_PATH_SRC
;
313 values
->disp_tv_out_cntl
|= crtc_idx
== 0 ? 0 : RADEON_DISP_TV_PATH_SRC
;
321 values
->disp_output_cntl
&= ~RADEON_DISP_TVDAC_SOURCE_MASK
;
322 values
->disp_output_cntl
|=
323 crtc_idx
== 0 ? 0 : RADEON_DISP_TVDAC_SOURCE_CRTC2
;
331 // choose clock source for (internal) TV-out unit
332 if( (total_devices
& (dd_ctv
| dd_stv
)) != 0 ) {
333 int crtc_idx
= (display_devices
[1] & (dd_ctv
| dd_stv
)) != 0;
335 values
->pixclks_cntl
&= ~RADEON_PIXCLK_TV_SRC_SEL_MASK
;
336 values
->pixclks_cntl
|= crtc_idx
== 0 ?
337 RADEON_PIXCLK_TV_SRC_SEL_PIXCLK
: RADEON_PIXCLK_TV_SRC_SEL_PIX2CLK
;
340 // choose CRTC clock source;
341 // normally, CRTC1 uses PLL1 and CRTC2 uses PLL2, but if an external TV-Out
342 // chip is used, the clock is retrieved from this chip to stay in perfect sync
343 if( (display_devices
[0] & (dd_ctv
| dd_stv
)) != 0
344 && !IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
))
346 // select BYTCLK input pin as pixel src
347 values
->vclk_ecp_cntl
&=
348 ~(RADEON_VCLK_ECP_CNTL_BYTE_CLK_POST_DIV_MASK
| RADEON_VCLK_SRC_SEL_MASK
);
350 values
->vclk_ecp_cntl
|= RADEON_VCLK_SRC_BYTE_CLK
;
351 values
->vclk_ecp_cntl
|= 0 << RADEON_VCLK_ECP_CNTL_BYTE_CLK_POST_DIV_SHIFT
;
353 // disable clock if pixel format in CRTC_GEN_CNTL is zero;
354 // disable (DAC?) during blank
355 values
->vclk_ecp_cntl
|= RADEON_PIXCLK_ALWAYS_ONb
| RADEON_PIXCLK_DAC_ALWAYS_ONb
;
358 // select PLL as pixel clock
359 values
->vclk_ecp_cntl
&= ~RADEON_VCLK_SRC_SEL_MASK
;
360 values
->vclk_ecp_cntl
|= RADEON_VCLK_SRC_PPLL_CLK
;
362 // disable clock if pixel format in CRTC_GEN_CNTL is zero
363 values
->vclk_ecp_cntl
|= RADEON_PIXCLK_ALWAYS_ONb
;
366 values
->pixclks_cntl
&= ~RADEON_PIX2CLK_SRC_SEL_MASK
;
367 if( (display_devices
[1] & (dd_ctv
| dd_stv
)) != 0
368 && !IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
))
370 // r200 spec misses everything regarding second CRTC, so
372 values
->pixclks_cntl
|= 2;
374 values
->pixclks_cntl
|= RADEON_PIX2CLK_SRC_SEL_P2PLL_CLK
;
376 // choose CRTC for flat panel
377 if( (total_devices
& (dd_lvds
| dd_dvi
)) != 0 ) {
378 int crtc_idx
= (display_devices
[1] & (dd_lvds
| dd_dvi
)) != 0;
380 values
->fp_gen_cntl
&= ~RADEON_FP_SEL_CRTC2
;
381 values
->fp_gen_cntl
|= crtc_idx
== 0 ? 0 : RADEON_FP_SEL_CRTC2
;
384 // enable/disable RMX for crtc1 if there is a flat panel
385 // (TODO: this doesn't seem to work)
386 // !!! makes trouble on Radeon 9200 Mobility !??
387 if( (display_devices
[1] & (dd_lvds
| dd_dvi
)) != 0 ) {
388 values
->disp_output_cntl
&= ~RADEON_DISP_DAC_SOURCE_MASK
;
389 values
->disp_output_cntl
|= RADEON_DISP_DAC_SOURCE_RMX
;
393 // choose CRTC for secondary flat panel
394 if( (total_devices
& dd_dvi_ext
) != 0 ) {
395 int crtc_idx
= (display_devices
[1] & (dd_dvi_ext
)) != 0;
397 // TODO: this list looks a bit magic/wrong for me; I reckon ATI moved the
398 // bit starting with ASIC xxx, but I have no specs to verify that
399 switch( ai
->si
->asic
) {
406 values
->fp2_gen_cntl
&= ~RADEON_FP2_SOURCE_SEL_CRTC2
;
407 values
->fp2_gen_cntl
|=
408 crtc_idx
== 0 ? 0 : RADEON_FP2_SOURCE_SEL_CRTC2
;
412 values
->fp2_gen_cntl
&= ~RADEON_FP2_SRC_SEL_CRTC2
;
413 values
->fp2_gen_cntl
|=
414 crtc_idx
== 0 ? 0 : RADEON_FP2_SRC_SEL_CRTC2
;
419 void Radeon_ProgramMonitorRouting(
420 accelerator_info
*ai
, routing_regs
*values
)
422 vuint8
*regs
= ai
->regs
;
424 OUTREG( regs
, RADEON_DAC_CNTL
, values
->dac_cntl
);
425 OUTREG( regs
, RADEON_DAC_CNTL2
, values
->dac_cntl2
);
426 OUTREGP( regs
, RADEON_CRTC2_GEN_CNTL
, values
->crtc2_gen_cntl
,
427 ~RADEON_CRTC2_CRT2_ON
);
428 OUTREG( regs
, RADEON_DISP_OUTPUT_CNTL
, values
->disp_output_cntl
);
430 switch( ai
->si
->asic
) {
438 OUTREG( regs
, RADEON_DISP_HW_DEBUG
, values
->disp_hw_debug
);
442 OUTREG( regs
, RADEON_DISP_TV_OUT_CNTL
, values
->disp_tv_out_cntl
);
450 OUTREGP( regs
, RADEON_GPIOPAD_A
, values
->gpiopad_a
, ~1 );
457 if( ai
->si
->asic
> rt_r100
) {
458 // register introduced after R100;
459 // only set it when necessary (more precisely: if TV-Out is used,
460 // this register is set by the TV-Out code)
461 if( !values
->skip_tv_dac
)
462 OUTREG( regs
, RADEON_TV_DAC_CNTL
, values
->tv_dac_cntl
);
465 if( IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
))
466 OUTREG( regs
, RADEON_TV_MASTER_CNTL
, values
->tv_master_cntl
);
468 OUTREGP( regs
, RADEON_FP_GEN_CNTL
, values
->fp_gen_cntl
, ~(
469 RADEON_FP_SEL_CRTC2
|
470 RADEON_FP_RMX_HVSYNC_CONTROL_EN
|
471 RADEON_FP_DFP_SYNC_SEL
|
472 RADEON_FP_CRT_SYNC_SEL
|
473 RADEON_FP_CRTC_LOCK_8DOT
|
474 RADEON_FP_USE_SHADOW_EN
|
475 RADEON_FP_CRTC_USE_SHADOW_VEND
|
476 RADEON_FP_CRT_SYNC_ALT
|
477 RADEON_FP_CRTC_DONT_SHADOW_VPAR
|
478 RADEON_FP_CRTC_DONT_SHADOW_HEND
));
481 OUTREGP( regs
, RADEON_FP2_GEN_CNTL
, values
->fp2_gen_cntl
,
482 ~(RADEON_FP2_SOURCE_SEL_CRTC2
| RADEON_FP2_SRC_SEL_CRTC2
));
484 if( ai
->vc
->used_crtc
[0] ) {
485 Radeon_OUTPLLP( ai
->regs
, ai
->si
->asic
,
486 RADEON_VCLK_ECP_CNTL
, values
->vclk_ecp_cntl
,
487 ~RADEON_VCLK_SRC_SEL_MASK
);
490 if( ai
->vc
->used_crtc
[1] ) {
491 Radeon_OUTPLLP( ai
->regs
, ai
->si
->asic
,
492 RADEON_PIXCLKS_CNTL
, values
->pixclks_cntl
,
493 ~RADEON_PIX2CLK_SRC_SEL_MASK
);
496 Radeon_OUTPLLP( ai
->regs
, ai
->si
->asic
,
497 RADEON_PIXCLKS_CNTL
, values
->pixclks_cntl
,
498 ~RADEON_PIXCLK_TV_SRC_SEL_MASK
);
500 // enable/disable CRTC1
501 if( ai
->vc
->assigned_crtc
[0] ) {
502 uint32 crtc_gen_cntl
;
504 crtc_gen_cntl
= INREG( regs
, RADEON_CRTC_GEN_CNTL
);
506 if( ai
->vc
->used_crtc
[0] ) {
507 crtc_gen_cntl
|= RADEON_CRTC_EN
;
509 crtc_gen_cntl
&= ~RADEON_CRTC_EN
;
510 crtc_gen_cntl
&= ~RADEON_CRTC_PIX_WIDTH_MASK
;
513 OUTREGP( regs
, RADEON_CRTC_GEN_CNTL
, crtc_gen_cntl
,
514 ~(RADEON_CRTC_PIX_WIDTH_MASK
| RADEON_CRTC_EN
) );
517 // enable/disable CRTC2
518 if( ai
->vc
->assigned_crtc
[1] ) {
519 uint32 crtc2_gen_cntl
;
521 crtc2_gen_cntl
= INREG( regs
, RADEON_CRTC2_GEN_CNTL
);
523 if( ai
->vc
->used_crtc
[1] ) {
524 crtc2_gen_cntl
|= RADEON_CRTC2_EN
;
526 crtc2_gen_cntl
&= ~RADEON_CRTC2_EN
;
527 crtc2_gen_cntl
&= ~RADEON_CRTC2_PIX_WIDTH_MASK
;
530 OUTREGP( regs
, RADEON_CRTC2_GEN_CNTL
, crtc2_gen_cntl
,
531 ~(RADEON_CRTC2_PIX_WIDTH_MASK
| RADEON_CRTC2_EN
) );
534 // XFree says that crtc_ext_cntl must be restored after CRTC2 in dual-screen mode
535 OUTREGP( regs
, RADEON_CRTC_EXT_CNTL
, values
->crtc_ext_cntl
,
536 RADEON_CRTC_VSYNC_DIS
|
537 RADEON_CRTC_HSYNC_DIS
|
538 RADEON_CRTC_DISPLAY_DIS
);
542 // internal version of SetupDefaultMonitorRouting;
543 // input and output are written to local variables
544 static void assignDefaultMonitorRoute(
545 accelerator_info
*ai
,
546 display_device_e display_devices
, int whished_num_heads
, bool use_laptop_panel
,
547 display_device_e
*crtc1
, display_device_e
*crtc2
)
549 virtual_card
*vc
= ai
->vc
;
550 display_device_e crtc1_displays
= 0, crtc2_displays
= 0;
552 SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d",
553 display_devices
, whished_num_heads
);
555 // restrict to allowed devices
556 display_devices
&= ai
->vc
->controlled_displays
;
558 // if CRTC1 is not ours, we cannot use flat panels
559 if( !ai
->vc
->assigned_crtc
[0] ) {
560 display_devices
&= ~(dd_lvds
| dd_dvi
);
563 SHOW_FLOW( 2, "after restriction: %x", display_devices
);
565 // flat panels get always connected to CRTC1 because its RMX unit
566 if( (display_devices
& dd_lvds
) != 0 ) {
567 // if user requests it, laptop panels are always used
568 if( use_laptop_panel
) {
569 crtc1_displays
|= dd_lvds
;
572 // if he doesn't request it, we try to not use it
573 display_device_e tmp_crtc1
, tmp_crtc2
;
574 int effective_num_heads
;
576 // determine routing with laptop panel ignored
577 assignDefaultMonitorRoute( ai
, display_devices
& ~dd_lvds
,
578 whished_num_heads
, use_laptop_panel
, &tmp_crtc1
, &tmp_crtc2
);
580 effective_num_heads
= (tmp_crtc1
!= 0) + (tmp_crtc2
!= 0);
582 // only use laptop panel if we cannot satisfy the requested
583 // number of heads without it
584 if( effective_num_heads
< whished_num_heads
)
585 crtc1_displays
|= dd_lvds
;
588 } else if( (display_devices
& dd_dvi
) != 0 )
589 crtc1_displays
|= dd_dvi
;
591 // TV-Out gets always connected to crtc2...
592 if( (display_devices
& dd_stv
) != 0 )
593 crtc2_displays
|= dd_stv
;
594 else if( (display_devices
& dd_ctv
) != 0 )
595 crtc2_displays
|= dd_ctv
;
597 // ...but if there is no crtc2, they win on crtc1;
598 // if the user connects both a flat panel and a TV, he usually
599 // wants to use the TV
600 if( !vc
->assigned_crtc
[1] && crtc2_displays
!= 0 ) {
601 crtc1_displays
= crtc2_displays
;
602 crtc2_displays
= dd_none
;
605 // if internal TV-Out is used, the DAC cannot drive a CRT at the same time
606 if( IS_INTERNAL_TV_OUT( ai
->si
->tv_chip
) && (display_devices
& (dd_stv
| dd_ctv
)) != 0 )
607 display_devices
&= ~dd_tv_crt
;
609 // CRT on CRT-DAC gets any spare CRTC;
610 // if there is none, it can share CRTC with TV-Out;
611 // this sharing may be dangerous as TV-Out uses strange timings, so
612 // we should perhaps forbid sharing
613 if( (display_devices
& dd_crt
) != 0 ) {
614 if( crtc1_displays
== 0 && vc
->assigned_crtc
[0] )
615 crtc1_displays
|= dd_crt
;
616 else if( ai
->si
->num_crtc
> 1 && crtc2_displays
== 0 && vc
->assigned_crtc
[1] )
617 crtc2_displays
|= dd_crt
;
618 else if( (crtc1_displays
& ~(dd_stv
| dd_ctv
)) == 0 && vc
->assigned_crtc
[0] )
619 crtc1_displays
|= dd_crt
;
620 else if( ai
->si
->num_crtc
> 1 && (crtc2_displays
& ~(dd_stv
| dd_ctv
)) == 0 && vc
->assigned_crtc
[1] )
621 crtc2_displays
|= dd_crt
;
624 // same applies to CRT on TV-DAC;
625 // if we cannot find a CRTC, we could clone the content of the CRT-DAC,
626 // but I doubt that you really want two CRTs showing the same
627 if( (display_devices
& dd_tv_crt
) != 0 ) {
628 if( crtc1_displays
== 0 && vc
->assigned_crtc
[0] )
629 crtc1_displays
|= dd_tv_crt
;
630 else if( ai
->si
->num_crtc
> 1 && crtc2_displays
== 0 && vc
->assigned_crtc
[1] )
631 crtc2_displays
|= dd_tv_crt
;
632 else if( (crtc1_displays
& ~(dd_stv
| dd_ctv
)) == 0 && vc
->assigned_crtc
[0] )
633 crtc1_displays
|= dd_tv_crt
;
634 else if( ai
->si
->num_crtc
> 1 && (crtc2_displays
& ~(dd_stv
| dd_ctv
)) == 0 && vc
->assigned_crtc
[1] )
635 crtc2_displays
|= dd_tv_crt
;
638 if( (display_devices
& dd_dvi_ext
) != 0 )
639 crtc2_displays
|= dd_dvi_ext
;
641 SHOW_FLOW( 2, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays
, crtc2_displays
);
643 *crtc1
= crtc1_displays
;
644 *crtc2
= crtc2_displays
;
647 // Setup sensible default monitor routing
648 // whished_num_heads - number of independant heads current display mode would need
649 // use_laptop_panel - if true, always use laptop panel
650 void Radeon_SetupDefaultMonitorRouting(
651 accelerator_info
*ai
, int whished_num_heads
, bool use_laptop_panel
)
653 virtual_card
*vc
= ai
->vc
;
654 shared_info
*si
= ai
->si
;
655 display_device_e display_devices
= vc
->connected_displays
;
657 if (ai
->si
->settings
.force_lcd
) {
658 use_laptop_panel
= true;
659 SHOW_FLOW0( 2, "LCD Forced Used by Kernel Settings");
662 SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d, use_laptop_panel=%d",
663 display_devices
, whished_num_heads
, use_laptop_panel
);
665 // ignore TV if standard is set to "off"
666 if( vc
->tv_standard
== ts_off
)
667 display_devices
&= ~(dd_ctv
| dd_stv
);
669 assignDefaultMonitorRoute(
670 ai
, display_devices
, whished_num_heads
, use_laptop_panel
,
671 &si
->crtc
[0].chosen_displays
, &si
->crtc
[1].chosen_displays
);
673 /* si->crtc[0].chosen_displays = dd_none;
674 si->crtc[1].chosen_displays = dd_tv_crt;*/
676 /*vc->used_crtc[0] = si->crtc[0].chosen_displays != dd_none;
677 vc->used_crtc[1] = si->crtc[1].chosen_displays != dd_none;*/
679 SHOW_FLOW( 2, "num_crtc: %d, CRTC1 (%s): 0x%x, CRTC2 (%s): 0x%x",
681 vc
->assigned_crtc
[0] ? "assigned" : "not assigned", si
->crtc
[0].chosen_displays
,
682 vc
->assigned_crtc
[0] ? "assigned" : "not assigned", si
->crtc
[1].chosen_displays
);