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