1 /* 2 Copyright (c) 2002-04, Thomas Kurschel 3 4 5 Part of Radeon accelerant 6 7 CRTC <-> display routing 8 9 This stuff is highly ASIC dependant and is probably the most ASIC-specific 10 code of the entire project. 11 */ 12 13 #include "radeon_accelerant.h" 14 #include "mmio.h" 15 #include "dac_regs.h" 16 #include "fp_regs.h" 17 #include "crtc_regs.h" 18 #include "tv_out_regs.h" 19 #include "pll_regs.h" 20 #include "gpiopad_regs.h" 21 #include "pll_access.h" 22 #include "set_mode.h" 23 24 25 // read regs needed for display device routing 26 void Radeon_ReadMonitorRoutingRegs( 27 accelerator_info *ai, routing_regs *values ) 28 { 29 vuint8 *regs = ai->regs; 30 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 ); 38 39 switch( ai->si->asic ) { 40 case rt_rv100: 41 case rt_rv200: 42 case rt_rv250: 43 case rt_rv280: 44 case rt_rs100: 45 case rt_rs200: 46 case rt_rs300: 47 values->disp_hw_debug = INREG( regs, RADEON_DISP_HW_DEBUG ); 48 break; 49 50 case rt_r200: 51 values->disp_tv_out_cntl = INREG( regs, RADEON_DISP_TV_OUT_CNTL ); 52 break; 53 54 case rt_r300: 55 case rt_rv350: 56 case rt_r350: 57 case rt_rv380: 58 case rt_r420: 59 values->gpiopad_a = INREG( regs, RADEON_GPIOPAD_A ); 60 break; 61 62 case rt_r100: 63 break; 64 } 65 66 if( ai->si->asic > rt_r100 ) { 67 // register introduced after R100 68 values->tv_dac_cntl = INREG( regs, RADEON_TV_DAC_CNTL ); 69 } 70 71 if( IS_INTERNAL_TV_OUT( ai->si->tv_chip )) 72 values->tv_master_cntl = INREG( regs, RADEON_TV_MASTER_CNTL ); 73 74 values->fp_gen_cntl = INREG( regs, RADEON_FP_GEN_CNTL ); 75 values->fp2_gen_cntl = INREG( regs, RADEON_FP2_GEN_CNTL ); 76 } 77 78 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 ) 82 { 83 display_device_e display_devices[2], total_devices, controlled_devices; 84 85 if( ai->vc->used_crtc[0] ) 86 display_devices[0] = ai->si->crtc[0].chosen_displays; 87 else 88 display_devices[0] = dd_none; 89 90 if( ai->vc->used_crtc[1] ) 91 display_devices[1] = ai->si->crtc[1].chosen_displays; 92 else 93 display_devices[1] = dd_none; 94 95 total_devices = display_devices[0] | display_devices[1]; 96 controlled_devices = ai->vc->controlled_displays; 97 98 // enable 8 bit DAC 99 // (could be moved to boot initialization) 100 values->dac_cntl |= 101 RADEON_DAC_MASK_ALL | RADEON_DAC_VGA_ADR_EN | RADEON_DAC_8BIT_EN; 102 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; 107 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; 112 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; 125 126 // route VGA-DAC 127 if( (total_devices & dd_crt) != 0 ) { 128 int crtc_idx = (display_devices[1] & dd_crt) != 0; 129 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; 132 133 switch( ai->si->asic ) { 134 case rt_rv100: 135 case rt_rv200: 136 case rt_rv250: 137 case rt_rv280: 138 case rt_rs100: 139 case rt_rs200: 140 case rt_rs300: 141 values->dac_cntl2 &= ~RADEON_DAC_CLK_SEL_MASK; 142 values->dac_cntl2 |= crtc_idx == 0 ? 0 : RADEON_DAC_CLK_SEL_CRTC2; 143 break; 144 145 case rt_r200: 146 case rt_r300: 147 case rt_rv350: 148 case rt_r350: 149 case rt_rv380: 150 case rt_r420: 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); 154 break; 155 156 case rt_r100: 157 break; 158 } 159 160 } else if( (controlled_devices & dd_crt) != 0 ) { 161 values->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON; 162 } 163 164 165 if( (total_devices & (dd_tv_crt | dd_ctv | dd_stv)) != 0 ) { 166 // power down TV-DAC 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; 173 } 174 175 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; 181 182 values->dac_cntl2 &= ~RADEON_DAC2_CLK_SEL_MASK; 183 values->dac_cntl2 |= RADEON_DAC2_CLK_SEL_CRT; 184 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); 192 193 // at least r300 needs magic bit set to switch between TV-CRT and TV-Out 194 if (IS_R300_VARIANT) 195 values->gpiopad_a |= 1; 196 197 } else if( (controlled_devices & dd_tv_crt) != 0 ) { 198 values->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON; 199 } 200 201 values->skip_tv_dac = false; 202 203 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; 208 209 210 // set TV mode of TV-DAC if needed 211 if( (total_devices & (dd_ctv | dd_stv)) != 0 ) { 212 // see above 213 values->dac_cntl2 &= ~RADEON_DAC2_CLK_SEL_MASK; 214 values->dac_cntl2 |= RADEON_DAC2_CLK_SEL_TV; 215 216 // at least r300 needs magic bit set to switch between TV-CRT and TV-Out 217 if(IS_R300_VARIANT) 218 values->gpiopad_a &= ~1; 219 220 221 // the TV-DAC itself is under control of the TV-Out code 222 values->skip_tv_dac = true; 223 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; 227 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) 231 // set 8 BPP mode 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); 240 241 // enable dithering 242 values->disp_output_cntl |= 243 RADEON_DISP_TV_YG_DITH_EN | 244 RADEON_DISP_TV_CBB_CRR_DITH_EN; 245 246 // set output data format 247 values->disp_output_cntl |= tv_parameters->mode888 ? 248 RADEON_DISP_TV_MODE_888 : RADEON_DISP_TV_MODE_565; 249 250 switch( ai->si->asic ) { 251 case rt_r200: 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); 270 271 // enable TVOCLKO (is this needed?) 272 values->disp_tv_out_cntl |= RADEON_DISP_TV_CLKO_OUT_EN; 273 break; 274 275 default: 276 ; 277 } 278 } 279 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; 288 } 289 } 290 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; 294 295 switch( ai->si->asic ) { 296 case rt_rv100: 297 case rt_rv200: 298 case rt_rv250: 299 case rt_rv280: 300 case rt_rs100: 301 case rt_rs200: 302 case rt_rs300: 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; 306 break; 307 308 case rt_r200: 309 // TV-Out data comes directly from CRTC (i.e. with Linear Transform Unit) 310 values->disp_output_cntl |= RADEON_DISP_TV_SOURCE; 311 // choose CRTC 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; 314 break; 315 316 case rt_r300: 317 case rt_rv350: 318 case rt_r350: 319 case rt_rv380: 320 case rt_r420: 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; 324 break; 325 326 case rt_r100: 327 break; 328 } 329 } 330 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; 334 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; 338 } 339 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 )) 345 { 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); 349 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; 352 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; 356 357 } else { 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; 361 362 // disable clock if pixel format in CRTC_GEN_CNTL is zero 363 values->vclk_ecp_cntl |= RADEON_PIXCLK_ALWAYS_ONb; 364 } 365 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 )) 369 { 370 // r200 spec misses everything regarding second CRTC, so 371 // this is guessing 372 values->pixclks_cntl |= 2; 373 } else 374 values->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLL_CLK; 375 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; 379 380 values->fp_gen_cntl &= ~RADEON_FP_SEL_CRTC2; 381 values->fp_gen_cntl |= crtc_idx == 0 ? 0 : RADEON_FP_SEL_CRTC2; 382 } 383 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; 390 } 391 392 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; 396 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 ) { 400 case rt_r200: 401 case rt_r300: 402 case rt_r350: 403 case rt_rv350: 404 case rt_rv380: 405 case rt_r420: 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; 409 break; 410 411 default: 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; 415 } 416 } 417 } 418 419 void Radeon_ProgramMonitorRouting( 420 accelerator_info *ai, routing_regs *values ) 421 { 422 vuint8 *regs = ai->regs; 423 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 ); 429 430 switch( ai->si->asic ) { 431 case rt_rv100: 432 case rt_rv200: 433 case rt_rv250: 434 case rt_rv280: 435 case rt_rs100: 436 case rt_rs200: 437 case rt_rs300: 438 OUTREG( regs, RADEON_DISP_HW_DEBUG, values->disp_hw_debug ); 439 break; 440 441 case rt_r200: 442 OUTREG( regs, RADEON_DISP_TV_OUT_CNTL, values->disp_tv_out_cntl ); 443 break; 444 445 case rt_r300: 446 case rt_rv350: 447 case rt_r350: 448 case rt_rv380: 449 case rt_r420: 450 OUTREGP( regs, RADEON_GPIOPAD_A, values->gpiopad_a, ~1 ); 451 break; 452 453 case rt_r100: 454 break; 455 } 456 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 ); 463 } 464 465 if( IS_INTERNAL_TV_OUT( ai->si->tv_chip )) 466 OUTREG( regs, RADEON_TV_MASTER_CNTL, values->tv_master_cntl ); 467 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 )); 479 480 481 OUTREGP( regs, RADEON_FP2_GEN_CNTL, values->fp2_gen_cntl, 482 ~(RADEON_FP2_SOURCE_SEL_CRTC2 | RADEON_FP2_SRC_SEL_CRTC2 )); 483 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 ); 488 } 489 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 ); 494 } 495 496 Radeon_OUTPLLP( ai->regs, ai->si->asic, 497 RADEON_PIXCLKS_CNTL, values->pixclks_cntl, 498 ~RADEON_PIXCLK_TV_SRC_SEL_MASK ); 499 500 // enable/disable CRTC1 501 if( ai->vc->assigned_crtc[0] ) { 502 uint32 crtc_gen_cntl; 503 504 crtc_gen_cntl = INREG( regs, RADEON_CRTC_GEN_CNTL ); 505 506 if( ai->vc->used_crtc[0] ) { 507 crtc_gen_cntl |= RADEON_CRTC_EN; 508 } else { 509 crtc_gen_cntl &= ~RADEON_CRTC_EN; 510 crtc_gen_cntl &= ~RADEON_CRTC_PIX_WIDTH_MASK; 511 } 512 513 OUTREGP( regs, RADEON_CRTC_GEN_CNTL, crtc_gen_cntl, 514 ~(RADEON_CRTC_PIX_WIDTH_MASK | RADEON_CRTC_EN) ); 515 } 516 517 // enable/disable CRTC2 518 if( ai->vc->assigned_crtc[1] ) { 519 uint32 crtc2_gen_cntl; 520 521 crtc2_gen_cntl = INREG( regs, RADEON_CRTC2_GEN_CNTL ); 522 523 if( ai->vc->used_crtc[1] ) { 524 crtc2_gen_cntl |= RADEON_CRTC2_EN; 525 } else { 526 crtc2_gen_cntl &= ~RADEON_CRTC2_EN; 527 crtc2_gen_cntl &= ~RADEON_CRTC2_PIX_WIDTH_MASK; 528 } 529 530 OUTREGP( regs, RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl, 531 ~(RADEON_CRTC2_PIX_WIDTH_MASK | RADEON_CRTC2_EN) ); 532 } 533 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 ); 539 } 540 541 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 ) 548 { 549 virtual_card *vc = ai->vc; 550 display_device_e crtc1_displays = 0, crtc2_displays = 0; 551 552 SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d", 553 display_devices, whished_num_heads ); 554 555 // restrict to allowed devices 556 display_devices &= ai->vc->controlled_displays; 557 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); 561 } 562 563 SHOW_FLOW( 2, "after restriction: %x", display_devices ); 564 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; 570 571 } else { 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; 575 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 ); 579 580 effective_num_heads = (tmp_crtc1 != 0) + (tmp_crtc2 != 0); 581 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; 586 } 587 588 } else if( (display_devices & dd_dvi) != 0 ) 589 crtc1_displays |= dd_dvi; 590 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; 596 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; 603 } 604 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; 608 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; 622 } 623 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; 636 } 637 638 if( (display_devices & dd_dvi_ext) != 0 ) 639 crtc2_displays |= dd_dvi_ext; 640 641 SHOW_FLOW( 2, "CRTC1: 0x%x, CRTC2: 0x%x", crtc1_displays, crtc2_displays ); 642 643 *crtc1 = crtc1_displays; 644 *crtc2 = crtc2_displays; 645 } 646 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 ) 652 { 653 virtual_card *vc = ai->vc; 654 shared_info *si = ai->si; 655 display_device_e display_devices = vc->connected_displays; 656 657 if (ai->si->settings.force_lcd) { 658 use_laptop_panel = true; 659 SHOW_FLOW0( 2, "LCD Forced Used by Kernel Settings"); 660 } 661 662 SHOW_FLOW( 2, "display_devices=%x, whished_num_heads=%d, use_laptop_panel=%d", 663 display_devices, whished_num_heads, use_laptop_panel ); 664 665 // ignore TV if standard is set to "off" 666 if( vc->tv_standard == ts_off ) 667 display_devices &= ~(dd_ctv | dd_stv); 668 669 assignDefaultMonitorRoute( 670 ai, display_devices, whished_num_heads, use_laptop_panel, 671 &si->crtc[0].chosen_displays, &si->crtc[1].chosen_displays ); 672 673 /* si->crtc[0].chosen_displays = dd_none; 674 si->crtc[1].chosen_displays = dd_tv_crt;*/ 675 676 /*vc->used_crtc[0] = si->crtc[0].chosen_displays != dd_none; 677 vc->used_crtc[1] = si->crtc[1].chosen_displays != dd_none;*/ 678 679 SHOW_FLOW( 2, "num_crtc: %d, CRTC1 (%s): 0x%x, CRTC2 (%s): 0x%x", 680 si->num_crtc, 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 ); 683 } 684