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