radeon_output.c revision c503f109
1/* 2 * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and 3 * VA Linux Systems Inc., Fremont, California. 4 * 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining 8 * a copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation on the rights to use, copy, modify, merge, 11 * publish, distribute, sublicense, and/or sell copies of the Software, 12 * and to permit persons to whom the Software is furnished to do so, 13 * subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial 17 * portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR 23 * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <string.h> 34#include <stdio.h> 35 36/* X and server generic header files */ 37#include "xf86.h" 38#include "xf86_OSproc.h" 39#include "vgaHW.h" 40#include "xf86Modes.h" 41 42/* Driver data structures */ 43#include "radeon.h" 44#include "radeon_reg.h" 45#include "radeon_macros.h" 46#include "radeon_probe.h" 47#include "radeon_version.h" 48#include "radeon_tv.h" 49#include "radeon_atombios.h" 50 51const char *encoder_name[34] = { 52 "NONE", 53 "INTERNAL_LVDS", 54 "INTERNAL_TMDS1", 55 "INTERNAL_TMDS2", 56 "INTERNAL_DAC1", 57 "INTERNAL_DAC2", 58 "INTERNAL_SDVOA", 59 "INTERNAL_SDVOB", 60 "SI170B", 61 "CH7303", 62 "CH7301", 63 "INTERNAL_DVO1", 64 "EXTERNAL_SDVOA", 65 "EXTERNAL_SDVOB", 66 "TITFP513", 67 "INTERNAL_LVTM1", 68 "VT1623", 69 "HDMI_SI1930", 70 "HDMI_INTERNAL", 71 "INTERNAL_KLDSCP_TMDS1", 72 "INTERNAL_KLDSCP_DVO1", 73 "INTERNAL_KLDSCP_DAC1", 74 "INTERNAL_KLDSCP_DAC2", 75 "SI178", 76 "MVPU_FPGA", 77 "INTERNAL_DDI", 78 "VT1625", 79 "HDMI_SI1932", 80 "DP_AN9801", 81 "DP_DP501", 82 "INTERNAL_UNIPHY", 83 "INTERNAL_KLDSCP_LVTMA", 84 "INTERNAL_UNIPHY1", 85 "INTERNAL_UNIPHY2", 86}; 87 88const char *ConnectorTypeName[17] = { 89 "None", 90 "VGA", 91 "DVI-I", 92 "DVI-D", 93 "DVI-A", 94 "S-video", 95 "Composite", 96 "LVDS", 97 "Digital", 98 "SCART", 99 "HDMI-A", 100 "HDMI-B", 101 "Unsupported", 102 "Unsupported", 103 "DIN", 104 "DisplayPort", 105 "Unsupported" 106}; 107 108extern void atombios_output_mode_set(xf86OutputPtr output, 109 DisplayModePtr mode, 110 DisplayModePtr adjusted_mode); 111extern void atombios_output_dpms(xf86OutputPtr output, int mode); 112extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output); 113extern AtomBiosResult 114atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock); 115static void 116radeon_bios_output_dpms(xf86OutputPtr output, int mode); 117static void 118radeon_bios_output_crtc(xf86OutputPtr output); 119static void 120radeon_bios_output_lock(xf86OutputPtr output, Bool lock); 121 122void RADEONPrintPortMap(ScrnInfoPtr pScrn) 123{ 124 RADEONInfoPtr info = RADEONPTR(pScrn); 125 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 126 RADEONOutputPrivatePtr radeon_output; 127 xf86OutputPtr output; 128 int o; 129 130 for (o = 0; o < xf86_config->num_output; o++) { 131 output = xf86_config->output[o]; 132 radeon_output = output->driver_private; 133 134 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o); 135 ErrorF(" XRANDR name: %s\n", output->name); 136 ErrorF(" Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]); 137 if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) 138 ErrorF(" CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]); 139 if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) 140 ErrorF(" CRT2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id]); 141 if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) 142 ErrorF(" LCD1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_LCD1_INDEX]->encoder_id]); 143 if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) 144 ErrorF(" DFP1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP1_INDEX]->encoder_id]); 145 if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) 146 ErrorF(" DFP2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP2_INDEX]->encoder_id]); 147 if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) 148 ErrorF(" DFP3: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP3_INDEX]->encoder_id]); 149 if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) 150 ErrorF(" DFP4: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP4_INDEX]->encoder_id]); 151 if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) 152 ErrorF(" DFP5: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP5_INDEX]->encoder_id]); 153 if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) 154 ErrorF(" TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]); 155 if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) 156 ErrorF(" CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]); 157 ErrorF(" DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg); 158 } 159 160} 161 162static void 163radeon_set_active_device(xf86OutputPtr output) 164{ 165 RADEONOutputPrivatePtr radeon_output = output->driver_private; 166 167 radeon_output->active_device = 0; 168 169 switch (radeon_output->MonType) { 170 case MT_DP: 171 case MT_DFP: 172 if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) 173 radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT; 174 else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) 175 radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT; 176 else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) 177 radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT; 178 else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) 179 radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT; 180 else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) 181 radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT; 182 break; 183 case MT_CRT: 184 if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) 185 radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT; 186 else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) 187 radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT; 188 break; 189 case MT_LCD: 190 if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) 191 radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT; 192 else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT) 193 radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT; 194 break; 195 case MT_STV: 196 case MT_CTV: 197 if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) 198 radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT; 199 else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT) 200 radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT; 201 break; 202 case MT_CV: 203 if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) 204 radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT; 205 break; 206 default: 207 ErrorF("Unhandled monitor type %d\n", radeon_output->MonType); 208 radeon_output->active_device = 0; 209 } 210} 211 212static RADEONMonitorType 213radeon_ddc_connected(xf86OutputPtr output) 214{ 215 ScrnInfoPtr pScrn = output->scrn; 216 RADEONInfoPtr info = RADEONPTR(pScrn); 217 RADEONMonitorType MonType = MT_NONE; 218 xf86MonPtr MonInfo = NULL; 219 RADEONOutputPrivatePtr radeon_output = output->driver_private; 220 221 if (radeon_output->pI2CBus) { 222 if (info->get_hardcoded_edid_from_bios) 223 MonInfo = RADEONGetHardCodedEDIDFromBIOS(output); 224 if (MonInfo == NULL) { 225 RADEONI2CDoLock(output, radeon_output->pI2CBus, TRUE); 226 MonInfo = xf86OutputGetEDID(output, radeon_output->pI2CBus); 227 RADEONI2CDoLock(output, radeon_output->pI2CBus, FALSE); 228 } 229 } 230 if (MonInfo) { 231 switch (radeon_output->ConnectorType) { 232 case CONNECTOR_LVDS: 233 MonType = MT_LCD; 234 break; 235 case CONNECTOR_DVI_D: 236 case CONNECTOR_HDMI_TYPE_A: 237 case CONNECTOR_HDMI_TYPE_B: 238 if (radeon_output->shared_ddc) { 239 if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI/HDMI/etc. */ 240 MonType = MT_DFP; 241 else 242 MonType = MT_NONE; 243 } else 244 MonType = MT_DFP; 245 break; 246 case CONNECTOR_DISPLAY_PORT: 247 /* 248 * XXX wrong. need to infer based on whether we got DDC from I2C 249 * or AUXCH. 250 */ 251 MonType = MT_DFP; 252 case CONNECTOR_DVI_I: 253 if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI */ 254 MonType = MT_DFP; 255 else 256 MonType = MT_CRT; 257 break; 258 case CONNECTOR_VGA: 259 case CONNECTOR_DVI_A: 260 default: 261 if (radeon_output->shared_ddc) { 262 if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */ 263 MonType = MT_NONE; 264 else 265 MonType = MT_CRT; 266 } else 267 MonType = MT_CRT; 268 break; 269 } 270 271 if (MonType != MT_NONE) 272 if (!xf86ReturnOptValBool(info->Options, OPTION_IGNORE_EDID, FALSE)) 273 xf86OutputSetEDID(output, MonInfo); 274 } else 275 MonType = MT_NONE; 276 277 return MonType; 278} 279 280#ifndef __powerpc__ 281 282static RADEONMonitorType 283RADEONDetectLidStatus(ScrnInfoPtr pScrn) 284{ 285 RADEONInfoPtr info = RADEONPTR(pScrn); 286 RADEONMonitorType MonType = MT_NONE; 287#ifdef __linux__ 288 char lidline[50]; /* 50 should be sufficient for our purposes */ 289 FILE *f = fopen ("/proc/acpi/button/lid/LID/state", "r"); 290 291 if (f != NULL) { 292 while (fgets(lidline, sizeof lidline, f)) { 293 if (!strncmp(lidline, "state:", strlen ("state:"))) { 294 if (strstr(lidline, "open")) { 295 fclose(f); 296 ErrorF("proc lid open\n"); 297 return MT_LCD; 298 } 299 else if (strstr(lidline, "closed")) { 300 fclose(f); 301 ErrorF("proc lid closed\n"); 302 return MT_NONE; 303 } 304 } 305 } 306 fclose(f); 307 } 308#endif 309 310 if (!info->IsAtomBios) { 311 unsigned char *RADEONMMIO = info->MMIO; 312 313 /* see if the lid is closed -- only works at boot */ 314 if (INREG(RADEON_BIOS_6_SCRATCH) & 0x10) 315 MonType = MT_NONE; 316 else 317 MonType = MT_LCD; 318 } else 319 MonType = MT_LCD; 320 321 return MonType; 322} 323 324#endif /* __powerpc__ */ 325 326static void 327radeon_dpms(xf86OutputPtr output, int mode) 328{ 329 RADEONInfoPtr info = RADEONPTR(output->scrn); 330 RADEONOutputPrivatePtr radeon_output = output->driver_private; 331 332 if ((mode == DPMSModeOn) && radeon_output->enabled) 333 return; 334 335 if (IS_AVIVO_VARIANT || info->r4xx_atom) { 336 atombios_output_dpms(output, mode); 337 } else { 338 legacy_output_dpms(output, mode); 339 } 340 radeon_bios_output_dpms(output, mode); 341 342 if (mode == DPMSModeOn) 343 radeon_output->enabled = TRUE; 344 else 345 radeon_output->enabled = FALSE; 346 347} 348 349static void 350radeon_save(xf86OutputPtr output) 351{ 352 353} 354 355static void 356radeon_restore(xf86OutputPtr restore) 357{ 358 359} 360 361static int 362radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) 363{ 364 RADEONOutputPrivatePtr radeon_output = output->driver_private; 365 radeon_native_mode_ptr native_mode = &radeon_output->native_mode; 366 ScrnInfoPtr pScrn = output->scrn; 367 RADEONInfoPtr info = RADEONPTR(pScrn); 368 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 369 370 /* 371 * RN50 has effective maximum mode bandwidth of about 300MiB/s. 372 * XXX should really do this for all chips by properly computing 373 * memory bandwidth and an overhead factor. 374 */ 375 if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) { 376 if (xf86ModeBandwidth(pMode, pScrn->bitsPerPixel) > 300) 377 return MODE_BANDWIDTH; 378 } 379 380 if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) { 381 if (IS_AVIVO_VARIANT) 382 return MODE_OK; 383 else { 384 /* FIXME: Update when more modes are added */ 385 if (pMode->HDisplay == 800 && pMode->VDisplay == 600) 386 return MODE_OK; 387 else 388 return MODE_CLOCK_RANGE; 389 } 390 } 391 392 /* single link DVI check */ 393 if (pMode->Clock > 165000 && radeon_output->MonType == MT_DFP) { 394 /* DP->DVI converter */ 395 if (radeon_output->ConnectorType == CONNECTOR_DISPLAY_PORT) 396 return MODE_CLOCK_HIGH; 397 398 /* XXX some HDMI can do better than 165MHz on a link */ 399 if (radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) 400 return MODE_CLOCK_HIGH; 401 402 /* XXX some R300 and R400 can actually do this */ 403 if (!IS_AVIVO_VARIANT) 404 return MODE_CLOCK_HIGH; 405 406 /* XXX and some AVIVO can't */ 407 } 408 409 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) { 410 if (radeon_output->rmx_type == RMX_OFF) { 411 if (pMode->HDisplay != native_mode->PanelXRes || 412 pMode->VDisplay != native_mode->PanelYRes) 413 return MODE_PANEL; 414 } 415 if (pMode->HDisplay > native_mode->PanelXRes || 416 pMode->VDisplay > native_mode->PanelYRes) 417 return MODE_PANEL; 418 } 419 420 return MODE_OK; 421} 422 423static Bool 424radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, 425 DisplayModePtr adjusted_mode) 426{ 427 RADEONInfoPtr info = RADEONPTR(output->scrn); 428 RADEONOutputPrivatePtr radeon_output = output->driver_private; 429 radeon_native_mode_ptr native_mode = &radeon_output->native_mode; 430 431 radeon_output->Flags &= ~RADEON_USE_RMX; 432 433 /* 434 * Refresh the Crtc values without INTERLACE_HALVE_V 435 * Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does? 436 */ 437 xf86SetModeCrtc(adjusted_mode, 0); 438 439 /* decide if we are using RMX */ 440 if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) 441 && radeon_output->rmx_type != RMX_OFF) { 442 xf86CrtcPtr crtc = output->crtc; 443 RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 444 445 if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) { 446 if (mode->HDisplay < native_mode->PanelXRes || 447 mode->VDisplay < native_mode->PanelYRes) { 448 radeon_output->Flags |= RADEON_USE_RMX; 449 if (IS_AVIVO_VARIANT) { 450 /* set to the panel's native mode */ 451 adjusted_mode->HDisplay = native_mode->PanelXRes; 452 adjusted_mode->VDisplay = native_mode->PanelYRes; 453 adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; 454 adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; 455 adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; 456 adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; 457 adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; 458 adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; 459 /* update crtc values */ 460 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); 461 /* adjust crtc values */ 462 adjusted_mode->CrtcHDisplay = native_mode->PanelXRes; 463 adjusted_mode->CrtcVDisplay = native_mode->PanelYRes; 464 adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; 465 adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; 466 adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; 467 adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; 468 adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; 469 adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; 470 } else { 471 /* set to the panel's native mode */ 472 adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank; 473 adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus; 474 adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth; 475 adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank; 476 adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus; 477 adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth; 478 adjusted_mode->Clock = native_mode->DotClock; 479 /* update crtc values */ 480 xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); 481 /* adjust crtc values */ 482 adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank; 483 adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus; 484 adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth; 485 adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank; 486 adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus; 487 adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth; 488 } 489 adjusted_mode->Clock = native_mode->DotClock; 490 adjusted_mode->Flags = native_mode->Flags; 491 } 492 } 493 } 494 495 if (IS_AVIVO_VARIANT) { 496 /* hw bug */ 497 if ((mode->Flags & V_INTERLACE) 498 && (adjusted_mode->CrtcVSyncStart < (adjusted_mode->CrtcVDisplay + 2))) 499 adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + 2; 500 } 501 502 return TRUE; 503} 504 505static void 506radeon_mode_prepare(xf86OutputPtr output) 507{ 508 RADEONInfoPtr info = RADEONPTR(output->scrn); 509 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 510 int o; 511 512 for (o = 0; o < config->num_output; o++) { 513 xf86OutputPtr loop_output = config->output[o]; 514 if (loop_output == output) 515 continue; 516 else if (loop_output->crtc) { 517 xf86CrtcPtr other_crtc = loop_output->crtc; 518 RADEONCrtcPrivatePtr other_radeon_crtc = other_crtc->driver_private; 519 if (other_crtc->enabled) { 520 if (other_radeon_crtc->initialized) { 521 radeon_crtc_dpms(other_crtc, DPMSModeOff); 522 if (IS_AVIVO_VARIANT || info->r4xx_atom) 523 atombios_lock_crtc(info->atomBIOS, other_radeon_crtc->crtc_id, 1); 524 radeon_dpms(loop_output, DPMSModeOff); 525 } 526 } 527 } 528 } 529 530 radeon_bios_output_lock(output, TRUE); 531 radeon_dpms(output, DPMSModeOff); 532 radeon_crtc_dpms(output->crtc, DPMSModeOff); 533 534} 535 536static void 537radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, 538 DisplayModePtr adjusted_mode) 539{ 540 RADEONInfoPtr info = RADEONPTR(output->scrn); 541 542 if (IS_AVIVO_VARIANT || info->r4xx_atom) 543 atombios_output_mode_set(output, mode, adjusted_mode); 544 else 545 legacy_output_mode_set(output, mode, adjusted_mode); 546 radeon_bios_output_crtc(output); 547 548} 549 550static void 551radeon_mode_commit(xf86OutputPtr output) 552{ 553 RADEONInfoPtr info = RADEONPTR(output->scrn); 554 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (output->scrn); 555 int o; 556 557 for (o = 0; o < config->num_output; o++) { 558 xf86OutputPtr loop_output = config->output[o]; 559 if (loop_output == output) 560 continue; 561 else if (loop_output->crtc) { 562 xf86CrtcPtr other_crtc = loop_output->crtc; 563 RADEONCrtcPrivatePtr other_radeon_crtc = other_crtc->driver_private; 564 if (other_crtc->enabled) { 565 if (other_radeon_crtc->initialized) { 566 radeon_crtc_dpms(other_crtc, DPMSModeOn); 567 if (IS_AVIVO_VARIANT || info->r4xx_atom) 568 atombios_lock_crtc(info->atomBIOS, other_radeon_crtc->crtc_id, 0); 569 radeon_dpms(loop_output, DPMSModeOn); 570 } 571 } 572 } 573 } 574 575 radeon_dpms(output, DPMSModeOn); 576 radeon_crtc_dpms(output->crtc, DPMSModeOn); 577 radeon_bios_output_lock(output, FALSE); 578} 579 580static void 581radeon_bios_output_lock(xf86OutputPtr output, Bool lock) 582{ 583 ScrnInfoPtr pScrn = output->scrn; 584 RADEONInfoPtr info = RADEONPTR(pScrn); 585 unsigned char *RADEONMMIO = info->MMIO; 586 RADEONSavePtr save = info->ModeReg; 587 588 if (info->IsAtomBios) { 589 if (lock) { 590 save->bios_6_scratch |= ATOM_S6_CRITICAL_STATE; 591 } else { 592 save->bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; 593 } 594 } else { 595 if (lock) { 596 save->bios_6_scratch |= RADEON_DRIVER_CRITICAL; 597 } else { 598 save->bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; 599 } 600 } 601 if (info->ChipFamily >= CHIP_FAMILY_R600) 602 OUTREG(R600_BIOS_6_SCRATCH, save->bios_6_scratch); 603 else 604 OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch); 605} 606 607static void 608radeon_bios_output_dpms(xf86OutputPtr output, int mode) 609{ 610 ScrnInfoPtr pScrn = output->scrn; 611 RADEONInfoPtr info = RADEONPTR(pScrn); 612 RADEONOutputPrivatePtr radeon_output = output->driver_private; 613 unsigned char *RADEONMMIO = info->MMIO; 614 RADEONSavePtr save = info->ModeReg; 615 616 if (info->IsAtomBios) { 617 if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 618 if (mode == DPMSModeOn) 619 save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; 620 else 621 save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; 622 } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { 623 if (mode == DPMSModeOn) 624 save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; 625 else 626 save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; 627 } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 628 if (mode == DPMSModeOn) 629 save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; 630 else 631 save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; 632 } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 633 if (mode == DPMSModeOn) 634 save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; 635 else 636 save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; 637 } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 638 if (mode == DPMSModeOn) 639 save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; 640 else 641 save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; 642 } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 643 if (mode == DPMSModeOn) 644 save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; 645 else 646 save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; 647 } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 648 if (mode == DPMSModeOn) 649 save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; 650 else 651 save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; 652 } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { 653 if (mode == DPMSModeOn) 654 save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; 655 else 656 save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; 657 } else if (radeon_output->active_device & ATOM_DEVICE_DFP4_SUPPORT) { 658 if (mode == DPMSModeOn) 659 save->bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE; 660 else 661 save->bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE; 662 } else if (radeon_output->active_device & ATOM_DEVICE_DFP5_SUPPORT) { 663 if (mode == DPMSModeOn) 664 save->bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE; 665 else 666 save->bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE; 667 } 668 if (info->ChipFamily >= CHIP_FAMILY_R600) 669 OUTREG(R600_BIOS_2_SCRATCH, save->bios_2_scratch); 670 else 671 OUTREG(RADEON_BIOS_2_SCRATCH, save->bios_2_scratch); 672 } else { 673 if (mode == DPMSModeOn) { 674 save->bios_6_scratch &= ~(RADEON_DPMS_MASK | RADEON_SCREEN_BLANKING); 675 save->bios_6_scratch |= RADEON_DPMS_ON; 676 } else { 677 save->bios_6_scratch &= ~RADEON_DPMS_MASK; 678 save->bios_6_scratch |= (RADEON_DPMS_OFF | RADEON_SCREEN_BLANKING); 679 } 680 if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 681 if (mode == DPMSModeOn) 682 save->bios_6_scratch |= RADEON_TV_DPMS_ON; 683 else 684 save->bios_6_scratch &= ~RADEON_TV_DPMS_ON; 685 } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 686 if (mode == DPMSModeOn) 687 save->bios_6_scratch |= RADEON_CRT_DPMS_ON; 688 else 689 save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; 690 } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 691 if (mode == DPMSModeOn) 692 save->bios_6_scratch |= RADEON_CRT_DPMS_ON; 693 else 694 save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON; 695 } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 696 if (mode == DPMSModeOn) 697 save->bios_6_scratch |= RADEON_LCD_DPMS_ON; 698 else 699 save->bios_6_scratch &= ~RADEON_LCD_DPMS_ON; 700 } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 701 if (mode == DPMSModeOn) 702 save->bios_6_scratch |= RADEON_DFP_DPMS_ON; 703 else 704 save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; 705 } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 706 if (mode == DPMSModeOn) 707 save->bios_6_scratch |= RADEON_DFP_DPMS_ON; 708 else 709 save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON; 710 } 711 OUTREG(RADEON_BIOS_6_SCRATCH, save->bios_6_scratch); 712 } 713} 714 715static void 716radeon_bios_output_crtc(xf86OutputPtr output) 717{ 718 ScrnInfoPtr pScrn = output->scrn; 719 RADEONInfoPtr info = RADEONPTR(pScrn); 720 RADEONOutputPrivatePtr radeon_output = output->driver_private; 721 unsigned char *RADEONMMIO = info->MMIO; 722 RADEONSavePtr save = info->ModeReg; 723 xf86CrtcPtr crtc = output->crtc; 724 RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; 725 726 if (info->IsAtomBios) { 727 if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 728 save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; 729 save->bios_3_scratch |= (radeon_crtc->crtc_id << 18); 730 } else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) { 731 save->bios_3_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; 732 save->bios_3_scratch |= (radeon_crtc->crtc_id << 24); 733 } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 734 save->bios_3_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; 735 save->bios_3_scratch |= (radeon_crtc->crtc_id << 16); 736 } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 737 save->bios_3_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; 738 save->bios_3_scratch |= (radeon_crtc->crtc_id << 20); 739 } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 740 save->bios_3_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; 741 save->bios_3_scratch |= (radeon_crtc->crtc_id << 17); 742 } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 743 save->bios_3_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; 744 save->bios_3_scratch |= (radeon_crtc->crtc_id << 19); 745 } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 746 save->bios_3_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; 747 save->bios_3_scratch |= (radeon_crtc->crtc_id << 23); 748 } else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) { 749 save->bios_3_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; 750 save->bios_3_scratch |= (radeon_crtc->crtc_id << 25); 751 } 752 if (info->ChipFamily >= CHIP_FAMILY_R600) 753 OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch); 754 else 755 OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch); 756 } else { 757 if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) { 758 save->bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; 759 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT); 760 } else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) { 761 save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; 762 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT); 763 } else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) { 764 save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; 765 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT); 766 } else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) { 767 save->bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; 768 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT); 769 } else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) { 770 save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; 771 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT); 772 } else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) { 773 save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; 774 save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT); 775 } 776 OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch); 777 } 778} 779 780static void 781radeon_bios_output_connected(xf86OutputPtr output, Bool connected) 782{ 783 ScrnInfoPtr pScrn = output->scrn; 784 RADEONInfoPtr info = RADEONPTR(pScrn); 785 RADEONOutputPrivatePtr radeon_output = output->driver_private; 786 unsigned char *RADEONMMIO = info->MMIO; 787 RADEONSavePtr save = info->ModeReg; 788 789 if (info->IsAtomBios) { 790 switch (radeon_output->active_device) { 791 case ATOM_DEVICE_TV1_SUPPORT: 792 if (connected) 793 save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE; 794 else { 795 save->bios_0_scratch &= ~ATOM_S0_TV1_MASK; 796 save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; 797 } 798 break; 799 case ATOM_DEVICE_CV_SUPPORT: 800 if (connected) 801 save->bios_3_scratch |= ATOM_S3_CV_ACTIVE; 802 else { 803 save->bios_0_scratch &= ~ATOM_S0_CV_MASK; 804 save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; 805 } 806 break; 807 case ATOM_DEVICE_LCD1_SUPPORT: 808 if (connected) { 809 save->bios_0_scratch |= ATOM_S0_LCD1; 810 save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; 811 } else { 812 save->bios_0_scratch &= ~ATOM_S0_LCD1; 813 save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; 814 } 815 break; 816 case ATOM_DEVICE_CRT1_SUPPORT: 817 if (connected) { 818 save->bios_0_scratch |= ATOM_S0_CRT1_COLOR; 819 save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; 820 } else { 821 save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK; 822 save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; 823 } 824 break; 825 case ATOM_DEVICE_CRT2_SUPPORT: 826 if (connected) { 827 save->bios_0_scratch |= ATOM_S0_CRT2_COLOR; 828 save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; 829 } else { 830 save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK; 831 save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; 832 } 833 break; 834 case ATOM_DEVICE_DFP1_SUPPORT: 835 if (connected) { 836 save->bios_0_scratch |= ATOM_S0_DFP1; 837 save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; 838 } else { 839 save->bios_0_scratch &= ~ATOM_S0_DFP1; 840 save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; 841 } 842 break; 843 case ATOM_DEVICE_DFP2_SUPPORT: 844 if (connected) { 845 save->bios_0_scratch |= ATOM_S0_DFP2; 846 save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; 847 } else { 848 save->bios_0_scratch &= ~ATOM_S0_DFP2; 849 save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; 850 } 851 break; 852 case ATOM_DEVICE_DFP3_SUPPORT: 853 if (connected) { 854 save->bios_0_scratch |= ATOM_S0_DFP3; 855 save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; 856 } else { 857 save->bios_0_scratch &= ~ATOM_S0_DFP3; 858 save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; 859 } 860 break; 861 case ATOM_DEVICE_DFP4_SUPPORT: 862 if (connected) { 863 save->bios_0_scratch |= ATOM_S0_DFP4; 864 save->bios_3_scratch |= ATOM_S3_DFP4_ACTIVE; 865 } else { 866 save->bios_0_scratch &= ~ATOM_S0_DFP4; 867 save->bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE; 868 } 869 break; 870 case ATOM_DEVICE_DFP5_SUPPORT: 871 if (connected) { 872 save->bios_0_scratch |= ATOM_S0_DFP5; 873 save->bios_3_scratch |= ATOM_S3_DFP5_ACTIVE; 874 } else { 875 save->bios_0_scratch &= ~ATOM_S0_DFP5; 876 save->bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE; 877 } 878 break; 879 } 880 if (info->ChipFamily >= CHIP_FAMILY_R600) { 881 OUTREG(R600_BIOS_0_SCRATCH, save->bios_0_scratch); 882 OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch); 883 } else { 884 OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch); 885 OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch); 886 } 887 } else { 888 switch (radeon_output->active_device) { 889 case ATOM_DEVICE_TV1_SUPPORT: 890 if (connected) { 891 if (radeon_output->MonType == MT_STV) 892 save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO; 893 else if (radeon_output->MonType == MT_CTV) 894 save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP; 895 save->bios_5_scratch |= RADEON_TV1_ON; 896 } else { 897 save->bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK; 898 save->bios_5_scratch &= ~RADEON_TV1_ON; 899 } 900 break; 901 case ATOM_DEVICE_LCD1_SUPPORT: 902 if (connected) { 903 save->bios_4_scratch |= RADEON_LCD1_ATTACHED; 904 save->bios_5_scratch |= RADEON_LCD1_ON; 905 } else { 906 save->bios_4_scratch &= ~RADEON_LCD1_ATTACHED; 907 save->bios_5_scratch &= ~RADEON_LCD1_ON; 908 } 909 break; 910 case ATOM_DEVICE_CRT1_SUPPORT: 911 if (connected) { 912 save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR; 913 save->bios_5_scratch |= RADEON_CRT1_ON; 914 } else { 915 save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK; 916 save->bios_5_scratch &= ~RADEON_CRT1_ON; 917 } 918 break; 919 case ATOM_DEVICE_CRT2_SUPPORT: 920 if (connected) { 921 save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR; 922 save->bios_5_scratch |= RADEON_CRT2_ON; 923 } else { 924 save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK; 925 save->bios_5_scratch &= ~RADEON_CRT2_ON; 926 } 927 break; 928 case ATOM_DEVICE_DFP1_SUPPORT: 929 if (connected) { 930 save->bios_4_scratch |= RADEON_DFP1_ATTACHED; 931 save->bios_5_scratch |= RADEON_DFP1_ON; 932 } else { 933 save->bios_4_scratch &= ~RADEON_DFP1_ATTACHED; 934 save->bios_5_scratch &= ~RADEON_DFP1_ON; 935 } 936 break; 937 case ATOM_DEVICE_DFP2_SUPPORT: 938 if (connected) { 939 save->bios_4_scratch |= RADEON_DFP2_ATTACHED; 940 save->bios_5_scratch |= RADEON_DFP2_ON; 941 } else { 942 save->bios_4_scratch &= ~RADEON_DFP2_ATTACHED; 943 save->bios_5_scratch &= ~RADEON_DFP2_ON; 944 } 945 break; 946 } 947 OUTREG(RADEON_BIOS_4_SCRATCH, save->bios_4_scratch); 948 OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch); 949 } 950 951} 952 953static xf86OutputStatus 954radeon_detect(xf86OutputPtr output) 955{ 956 ScrnInfoPtr pScrn = output->scrn; 957 RADEONInfoPtr info = RADEONPTR(pScrn); 958 RADEONOutputPrivatePtr radeon_output = output->driver_private; 959 Bool connected = TRUE; 960 961 radeon_output->MonType = MT_UNKNOWN; 962 radeon_bios_output_connected(output, FALSE); 963 radeon_output->MonType = radeon_ddc_connected(output); 964 if (!radeon_output->MonType) { 965 if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 966 if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE)) 967 radeon_output->MonType = MT_LCD; 968 else 969#if defined(__powerpc__) 970 radeon_output->MonType = MT_LCD; 971#else 972 radeon_output->MonType = RADEONDetectLidStatus(pScrn); 973#endif 974 } else { 975 if (info->IsAtomBios) 976 radeon_output->MonType = atombios_dac_detect(output); 977 else 978 radeon_output->MonType = legacy_dac_detect(output); 979 } 980 } 981 982 // if size is zero panel probably broken or not connected 983 if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 984 radeon_encoder_ptr radeon_encoder = info->encoders[ATOM_DEVICE_LCD1_INDEX]; 985 if (radeon_encoder) { 986 radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv; 987 if (lvds) { 988 if ((lvds->native_mode.PanelXRes == 0) || (lvds->native_mode.PanelYRes == 0)) 989 radeon_output->MonType = MT_NONE; 990 } 991 } 992 } 993 994 995 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 996 "Output: %s, Detected Monitor Type: %d\n", output->name, radeon_output->MonType); 997 if (output->MonInfo) { 998 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n", 999 output->name); 1000 xf86PrintEDID( output->MonInfo ); 1001 } 1002 1003 /* nothing connected, light up some defaults so the server comes up */ 1004 if (radeon_output->MonType == MT_NONE && 1005 info->first_load_no_devices) { 1006 if (info->IsMobility) { 1007 if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) { 1008 radeon_output->MonType = MT_LCD; 1009 info->first_load_no_devices = FALSE; 1010 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LCD default\n"); 1011 } 1012 } else { 1013 if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) { 1014 radeon_output->MonType = MT_CRT; 1015 info->first_load_no_devices = FALSE; 1016 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using CRT default\n"); 1017 } else if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 1018 radeon_output->MonType = MT_DFP; 1019 info->first_load_no_devices = FALSE; 1020 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DFP default\n"); 1021 } 1022 } 1023 } 1024 1025 radeon_bios_output_connected(output, TRUE); 1026 1027 /* set montype so users can force outputs on even if detection fails */ 1028 if (radeon_output->MonType == MT_NONE) { 1029 connected = FALSE; 1030 switch (radeon_output->ConnectorType) { 1031 case CONNECTOR_LVDS: 1032 radeon_output->MonType = MT_LCD; 1033 break; 1034 case CONNECTOR_DVI_D: 1035 case CONNECTOR_HDMI_TYPE_A: 1036 case CONNECTOR_HDMI_TYPE_B: 1037 radeon_output->MonType = MT_DFP; 1038 break; 1039 case CONNECTOR_VGA: 1040 case CONNECTOR_DVI_A: 1041 default: 1042 radeon_output->MonType = MT_CRT; 1043 break; 1044 case CONNECTOR_DVI_I: 1045 if (radeon_output->DVIType == DVI_ANALOG) 1046 radeon_output->MonType = MT_CRT; 1047 else if (radeon_output->DVIType == DVI_DIGITAL) 1048 radeon_output->MonType = MT_DFP; 1049 break; 1050 case CONNECTOR_STV: 1051 radeon_output->MonType = MT_STV; 1052 break; 1053 case CONNECTOR_CTV: 1054 radeon_output->MonType = MT_CTV; 1055 break; 1056 case CONNECTOR_DIN: 1057 radeon_output->MonType = MT_CV; 1058 break; 1059 case CONNECTOR_DISPLAY_PORT: 1060 radeon_output->MonType = MT_DP; 1061 break; 1062 } 1063 } 1064 1065 radeon_set_active_device(output); 1066 1067 if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) 1068 output->subpixel_order = SubPixelHorizontalRGB; 1069 else 1070 output->subpixel_order = SubPixelNone; 1071 1072 if (connected) 1073 return XF86OutputStatusConnected; 1074 else 1075 return XF86OutputStatusDisconnected; 1076} 1077 1078static DisplayModePtr 1079radeon_get_modes(xf86OutputPtr output) 1080{ 1081 DisplayModePtr modes; 1082 modes = RADEONProbeOutputModes(output); 1083 return modes; 1084} 1085 1086static void 1087radeon_destroy (xf86OutputPtr output) 1088{ 1089 if (output->driver_private) 1090 xfree(output->driver_private); 1091} 1092 1093static void 1094radeon_set_backlight_level(xf86OutputPtr output, int level) 1095{ 1096#if 0 1097 ScrnInfoPtr pScrn = output->scrn; 1098 RADEONInfoPtr info = RADEONPTR(pScrn); 1099 unsigned char * RADEONMMIO = info->MMIO; 1100 uint32_t lvds_gen_cntl; 1101 1102 lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); 1103 lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN; 1104 lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK; 1105 lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK; 1106 //usleep (radeon_output->PanelPwrDly * 1000); 1107 OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 1108 lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN; 1109 //usleep (radeon_output->PanelPwrDly * 1000); 1110 OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); 1111#endif 1112} 1113 1114static Atom backlight_atom; 1115static Atom tmds_pll_atom; 1116static Atom rmx_atom; 1117static Atom monitor_type_atom; 1118static Atom load_detection_atom; 1119static Atom coherent_mode_atom; 1120static Atom tv_hsize_atom; 1121static Atom tv_hpos_atom; 1122static Atom tv_vpos_atom; 1123static Atom tv_std_atom; 1124#define RADEON_MAX_BACKLIGHT_LEVEL 255 1125 1126static void 1127radeon_create_resources(xf86OutputPtr output) 1128{ 1129 ScrnInfoPtr pScrn = output->scrn; 1130 RADEONInfoPtr info = RADEONPTR(pScrn); 1131 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1132 INT32 range[2]; 1133 int data, err; 1134 const char *s; 1135 1136#if 0 1137 /* backlight control */ 1138 if (radeon_output->type == OUTPUT_LVDS) { 1139 backlight_atom = MAKE_ATOM("backlight"); 1140 1141 range[0] = 0; 1142 range[1] = RADEON_MAX_BACKLIGHT_LEVEL; 1143 err = RRConfigureOutputProperty(output->randr_output, backlight_atom, 1144 FALSE, TRUE, FALSE, 2, range); 1145 if (err != 0) { 1146 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1147 "RRConfigureOutputProperty error, %d\n", err); 1148 } 1149 /* Set the current value of the backlight property */ 1150 //data = (info->SavedReg->lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT; 1151 data = RADEON_MAX_BACKLIGHT_LEVEL; 1152 err = RRChangeOutputProperty(output->randr_output, backlight_atom, 1153 XA_INTEGER, 32, PropModeReplace, 1, &data, 1154 FALSE, TRUE); 1155 if (err != 0) { 1156 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1157 "RRChangeOutputProperty error, %d\n", err); 1158 } 1159 } 1160#endif 1161 1162 if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT | ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) { 1163 load_detection_atom = MAKE_ATOM("load_detection"); 1164 1165 range[0] = 0; /* off */ 1166 range[1] = 1; /* on */ 1167 err = RRConfigureOutputProperty(output->randr_output, load_detection_atom, 1168 FALSE, TRUE, FALSE, 2, range); 1169 if (err != 0) { 1170 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1171 "RRConfigureOutputProperty error, %d\n", err); 1172 } 1173 1174 if (radeon_output->load_detection) 1175 data = 1; 1176 else 1177 data = 0; 1178 1179 err = RRChangeOutputProperty(output->randr_output, load_detection_atom, 1180 XA_INTEGER, 32, PropModeReplace, 1, &data, 1181 FALSE, TRUE); 1182 if (err != 0) { 1183 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1184 "RRChangeOutputProperty error, %d\n", err); 1185 } 1186 } 1187 1188 if (IS_AVIVO_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) { 1189 coherent_mode_atom = MAKE_ATOM("coherent_mode"); 1190 1191 range[0] = 0; /* off */ 1192 range[1] = 1; /* on */ 1193 err = RRConfigureOutputProperty(output->randr_output, coherent_mode_atom, 1194 FALSE, TRUE, FALSE, 2, range); 1195 if (err != 0) { 1196 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1197 "RRConfigureOutputProperty error, %d\n", err); 1198 } 1199 1200 data = 1; /* coherent mode on by default */ 1201 1202 err = RRChangeOutputProperty(output->randr_output, coherent_mode_atom, 1203 XA_INTEGER, 32, PropModeReplace, 1, &data, 1204 FALSE, TRUE); 1205 if (err != 0) { 1206 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1207 "RRChangeOutputProperty error, %d\n", err); 1208 } 1209 } 1210 1211 if ((!IS_AVIVO_VARIANT) && (radeon_output->devices & (ATOM_DEVICE_DFP1_SUPPORT))) { 1212 tmds_pll_atom = MAKE_ATOM("tmds_pll"); 1213 1214 err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom, 1215 FALSE, FALSE, FALSE, 0, NULL); 1216 if (err != 0) { 1217 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1218 "RRConfigureOutputProperty error, %d\n", err); 1219 } 1220 /* Set the current value of the property */ 1221#if defined(__powerpc__) 1222 s = "driver"; 1223#else 1224 s = "bios"; 1225#endif 1226 if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_TMDS_PLL, FALSE)) { 1227 s = "driver"; 1228 } 1229 1230 err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom, 1231 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1232 FALSE, FALSE); 1233 if (err != 0) { 1234 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1235 "RRChangeOutputProperty error, %d\n", err); 1236 } 1237 1238 } 1239 1240 /* RMX control - fullscreen, centered, keep ratio, off */ 1241 /* actually more of a crtc property as only crtc1 has rmx */ 1242 if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) { 1243 rmx_atom = MAKE_ATOM("scaler"); 1244 1245 err = RRConfigureOutputProperty(output->randr_output, rmx_atom, 1246 FALSE, FALSE, FALSE, 0, NULL); 1247 if (err != 0) { 1248 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1249 "RRConfigureOutputProperty error, %d\n", err); 1250 } 1251 /* Set the current value of the property */ 1252 switch (radeon_output->rmx_type) { 1253 case RMX_OFF: 1254 default: 1255 s = "off"; 1256 break; 1257 case RMX_FULL: 1258 s = "full"; 1259 break; 1260 case RMX_CENTER: 1261 s = "center"; 1262 break; 1263 case RMX_ASPECT: 1264 s = "aspect"; 1265 break; 1266 } 1267 err = RRChangeOutputProperty(output->randr_output, rmx_atom, 1268 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1269 FALSE, FALSE); 1270 if (err != 0) { 1271 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1272 "RRChangeOutputProperty error, %d\n", err); 1273 } 1274 } 1275 1276 /* force auto/analog/digital for DVI-I ports */ 1277 if ((radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) && 1278 (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))){ 1279 monitor_type_atom = MAKE_ATOM("dvi_monitor_type"); 1280 1281 err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom, 1282 FALSE, FALSE, FALSE, 0, NULL); 1283 if (err != 0) { 1284 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1285 "RRConfigureOutputProperty error, %d\n", err); 1286 } 1287 /* Set the current value of the backlight property */ 1288 s = "auto"; 1289 err = RRChangeOutputProperty(output->randr_output, monitor_type_atom, 1290 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1291 FALSE, FALSE); 1292 if (err != 0) { 1293 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1294 "RRChangeOutputProperty error, %d\n", err); 1295 } 1296 } 1297 1298 if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) { 1299 radeon_tvout_ptr tvout = &radeon_output->tvout; 1300 if (!IS_AVIVO_VARIANT) { 1301 tv_hsize_atom = MAKE_ATOM("tv_horizontal_size"); 1302 1303 range[0] = -MAX_H_SIZE; 1304 range[1] = MAX_H_SIZE; 1305 err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom, 1306 FALSE, TRUE, FALSE, 2, range); 1307 if (err != 0) { 1308 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1309 "RRConfigureOutputProperty error, %d\n", err); 1310 } 1311 data = 0; 1312 err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom, 1313 XA_INTEGER, 32, PropModeReplace, 1, &data, 1314 FALSE, TRUE); 1315 if (err != 0) { 1316 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1317 "RRChangeOutputProperty error, %d\n", err); 1318 } 1319 1320 tv_hpos_atom = MAKE_ATOM("tv_horizontal_position"); 1321 1322 range[0] = -MAX_H_POSITION; 1323 range[1] = MAX_H_POSITION; 1324 err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom, 1325 FALSE, TRUE, FALSE, 2, range); 1326 if (err != 0) { 1327 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1328 "RRConfigureOutputProperty error, %d\n", err); 1329 } 1330 data = 0; 1331 err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom, 1332 XA_INTEGER, 32, PropModeReplace, 1, &data, 1333 FALSE, TRUE); 1334 if (err != 0) { 1335 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1336 "RRChangeOutputProperty error, %d\n", err); 1337 } 1338 1339 tv_vpos_atom = MAKE_ATOM("tv_vertical_position"); 1340 1341 range[0] = -MAX_V_POSITION; 1342 range[1] = MAX_V_POSITION; 1343 err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom, 1344 FALSE, TRUE, FALSE, 2, range); 1345 if (err != 0) { 1346 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1347 "RRConfigureOutputProperty error, %d\n", err); 1348 } 1349 data = 0; 1350 err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom, 1351 XA_INTEGER, 32, PropModeReplace, 1, &data, 1352 FALSE, TRUE); 1353 if (err != 0) { 1354 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1355 "RRChangeOutputProperty error, %d\n", err); 1356 } 1357 } 1358 1359 tv_std_atom = MAKE_ATOM("tv_standard"); 1360 1361 err = RRConfigureOutputProperty(output->randr_output, tv_std_atom, 1362 FALSE, FALSE, FALSE, 0, NULL); 1363 if (err != 0) { 1364 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1365 "RRConfigureOutputProperty error, %d\n", err); 1366 } 1367 1368 /* Set the current value of the property */ 1369 switch (tvout->tvStd) { 1370 case TV_STD_PAL: 1371 s = "pal"; 1372 break; 1373 case TV_STD_PAL_M: 1374 s = "pal-m"; 1375 break; 1376 case TV_STD_PAL_60: 1377 s = "pal-60"; 1378 break; 1379 case TV_STD_NTSC_J: 1380 s = "ntsc-j"; 1381 break; 1382 case TV_STD_SCART_PAL: 1383 s = "scart-pal"; 1384 break; 1385 case TV_STD_NTSC: 1386 default: 1387 s = "ntsc"; 1388 break; 1389 } 1390 1391 err = RRChangeOutputProperty(output->randr_output, tv_std_atom, 1392 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, 1393 FALSE, FALSE); 1394 if (err != 0) { 1395 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1396 "RRChangeOutputProperty error, %d\n", err); 1397 } 1398 } 1399} 1400 1401static Bool 1402radeon_set_mode_for_property(xf86OutputPtr output) 1403{ 1404 ScrnInfoPtr pScrn = output->scrn; 1405 1406 if (output->crtc) { 1407 xf86CrtcPtr crtc = output->crtc; 1408 1409 if (crtc->enabled) { 1410 if (!xf86CrtcSetMode(crtc, &crtc->desiredMode, crtc->desiredRotation, 1411 crtc->desiredX, crtc->desiredY)) { 1412 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1413 "Failed to set mode after propery change!\n"); 1414 return FALSE; 1415 } 1416 } 1417 } 1418 return TRUE; 1419} 1420 1421static Bool 1422radeon_set_property(xf86OutputPtr output, Atom property, 1423 RRPropertyValuePtr value) 1424{ 1425 RADEONInfoPtr info = RADEONPTR(output->scrn); 1426 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1427 INT32 val; 1428 1429 1430 if (property == backlight_atom) { 1431 if (value->type != XA_INTEGER || 1432 value->format != 32 || 1433 value->size != 1) { 1434 return FALSE; 1435 } 1436 1437 val = *(INT32 *)value->data; 1438 if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL) 1439 return FALSE; 1440 1441#if defined(__powerpc__) 1442 val = RADEON_MAX_BACKLIGHT_LEVEL - val; 1443#endif 1444 1445 radeon_set_backlight_level(output, val); 1446 1447 } else if (property == load_detection_atom) { 1448 if (value->type != XA_INTEGER || 1449 value->format != 32 || 1450 value->size != 1) { 1451 return FALSE; 1452 } 1453 1454 val = *(INT32 *)value->data; 1455 if (val < 0 || val > 1) 1456 return FALSE; 1457 1458 radeon_output->load_detection = val; 1459 1460 } else if (property == coherent_mode_atom) { 1461 Bool coherent_mode = radeon_output->coherent_mode; 1462 1463 if (value->type != XA_INTEGER || 1464 value->format != 32 || 1465 value->size != 1) { 1466 return FALSE; 1467 } 1468 1469 val = *(INT32 *)value->data; 1470 if (val < 0 || val > 1) 1471 return FALSE; 1472 1473 radeon_output->coherent_mode = val; 1474 if (!radeon_set_mode_for_property(output)) { 1475 radeon_output->coherent_mode = coherent_mode; 1476 (void)radeon_set_mode_for_property(output); 1477 return FALSE; 1478 } 1479 1480 } else if (property == rmx_atom) { 1481 const char *s; 1482 RADEONRMXType rmx = radeon_output->rmx_type; 1483 1484 if (value->type != XA_STRING || value->format != 8) 1485 return FALSE; 1486 s = (char*)value->data; 1487 if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) { 1488 radeon_output->rmx_type = RMX_FULL; 1489 } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) { 1490 radeon_output->rmx_type = RMX_CENTER; 1491 } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) { 1492 if (IS_AVIVO_VARIANT) 1493 radeon_output->rmx_type = RMX_ASPECT; 1494 else 1495 return FALSE; 1496 } else if (value->size == strlen("off") && !strncmp("off", s, strlen("off"))) { 1497 radeon_output->rmx_type = RMX_OFF; 1498 } else 1499 return FALSE; 1500 1501 if (!radeon_set_mode_for_property(output)) { 1502 radeon_output->rmx_type = rmx; 1503 (void)radeon_set_mode_for_property(output); 1504 return FALSE; 1505 } 1506 } else if (property == tmds_pll_atom) { 1507 radeon_tmds_ptr tmds = NULL; 1508 const char *s; 1509 1510 if (info->encoders[ATOM_DEVICE_DFP1_INDEX] && info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv) 1511 tmds = (radeon_tmds_ptr)info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv; 1512 else 1513 return FALSE; 1514 1515 if (value->type != XA_STRING || value->format != 8) 1516 return FALSE; 1517 s = (char*)value->data; 1518 if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) { 1519 if (!RADEONGetTMDSInfoFromBIOS(output->scrn, tmds)) 1520 RADEONGetTMDSInfoFromTable(output->scrn, tmds); 1521 } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) 1522 RADEONGetTMDSInfoFromTable(output->scrn, tmds); 1523 else 1524 return FALSE; 1525 1526 return radeon_set_mode_for_property(output); 1527 } else if (property == monitor_type_atom) { 1528 const char *s; 1529 if (value->type != XA_STRING || value->format != 8) 1530 return FALSE; 1531 s = (char*)value->data; 1532 if (value->size == strlen("auto") && !strncmp("auto", s, strlen("auto"))) { 1533 radeon_output->DVIType = DVI_AUTO; 1534 return TRUE; 1535 } else if (value->size == strlen("analog") && !strncmp("analog", s, strlen("analog"))) { 1536 radeon_output->DVIType = DVI_ANALOG; 1537 return TRUE; 1538 } else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) { 1539 radeon_output->DVIType = DVI_DIGITAL; 1540 return TRUE; 1541 } else 1542 return FALSE; 1543 } else if (property == tv_hsize_atom) { 1544 radeon_tvout_ptr tvout = &radeon_output->tvout; 1545 if (value->type != XA_INTEGER || 1546 value->format != 32 || 1547 value->size != 1) { 1548 return FALSE; 1549 } 1550 1551 val = *(INT32 *)value->data; 1552 if (val < -MAX_H_SIZE || val > MAX_H_SIZE) 1553 return FALSE; 1554 1555 tvout->hSize = val; 1556 if (tvout->tv_on && !IS_AVIVO_VARIANT) 1557 RADEONUpdateHVPosition(output, &output->crtc->mode); 1558 1559 } else if (property == tv_hpos_atom) { 1560 radeon_tvout_ptr tvout = &radeon_output->tvout; 1561 if (value->type != XA_INTEGER || 1562 value->format != 32 || 1563 value->size != 1) { 1564 return FALSE; 1565 } 1566 1567 val = *(INT32 *)value->data; 1568 if (val < -MAX_H_POSITION || val > MAX_H_POSITION) 1569 return FALSE; 1570 1571 tvout->hPos = val; 1572 if (tvout->tv_on && !IS_AVIVO_VARIANT) 1573 RADEONUpdateHVPosition(output, &output->crtc->mode); 1574 1575 } else if (property == tv_vpos_atom) { 1576 radeon_tvout_ptr tvout = &radeon_output->tvout; 1577 if (value->type != XA_INTEGER || 1578 value->format != 32 || 1579 value->size != 1) { 1580 return FALSE; 1581 } 1582 1583 val = *(INT32 *)value->data; 1584 if (val < -MAX_H_POSITION || val > MAX_H_POSITION) 1585 return FALSE; 1586 1587 tvout->vPos = val; 1588 if (tvout->tv_on && !IS_AVIVO_VARIANT) 1589 RADEONUpdateHVPosition(output, &output->crtc->mode); 1590 1591 } else if (property == tv_std_atom) { 1592 const char *s; 1593 radeon_tvout_ptr tvout = &radeon_output->tvout; 1594 TVStd std = tvout->tvStd; 1595 1596 if (value->type != XA_STRING || value->format != 8) 1597 return FALSE; 1598 s = (char*)value->data; 1599 if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) { 1600 tvout->tvStd = TV_STD_NTSC; 1601 } else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) { 1602 tvout->tvStd = TV_STD_PAL; 1603 } else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) { 1604 tvout->tvStd = TV_STD_PAL_M; 1605 } else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) { 1606 tvout->tvStd = TV_STD_PAL_60; 1607 } else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) { 1608 tvout->tvStd = TV_STD_NTSC_J; 1609 } else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) { 1610 tvout->tvStd = TV_STD_SCART_PAL; 1611 } else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) { 1612 tvout->tvStd = TV_STD_PAL_CN; 1613 } else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) { 1614 tvout->tvStd = TV_STD_SECAM; 1615 } else 1616 return FALSE; 1617 1618 if (!radeon_set_mode_for_property(output)) { 1619 tvout->tvStd = std; 1620 (void)radeon_set_mode_for_property(output); 1621 return FALSE; 1622 } 1623 } 1624 1625 return TRUE; 1626} 1627 1628static const xf86OutputFuncsRec radeon_output_funcs = { 1629 .create_resources = radeon_create_resources, 1630 .dpms = radeon_dpms, 1631 .save = radeon_save, 1632 .restore = radeon_restore, 1633 .mode_valid = radeon_mode_valid, 1634 .mode_fixup = radeon_mode_fixup, 1635 .prepare = radeon_mode_prepare, 1636 .mode_set = radeon_mode_set, 1637 .commit = radeon_mode_commit, 1638 .detect = radeon_detect, 1639 .get_modes = radeon_get_modes, 1640 .set_property = radeon_set_property, 1641 .destroy = radeon_destroy 1642}; 1643 1644Bool 1645RADEONI2CDoLock(xf86OutputPtr output, I2CBusPtr b, int lock_state) 1646{ 1647 ScrnInfoPtr pScrn = output->scrn; 1648 RADEONInfoPtr info = RADEONPTR(pScrn); 1649 RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1650 unsigned char *RADEONMMIO = info->MMIO; 1651 uint32_t temp; 1652 1653 if (lock_state) { 1654 /* RV410 appears to have a bug where the hw i2c in reset 1655 * holds the i2c port in a bad state - switch hw i2c away before 1656 * doing DDC - do this for all r200s/r300s for safety sakes */ 1657 if ((info->ChipFamily >= CHIP_FAMILY_R200) && (!IS_AVIVO_VARIANT)) { 1658 if (pRADEONI2CBus->mask_clk_reg == RADEON_GPIO_MONID) 1659 OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 1660 R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); 1661 else 1662 OUTREG(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | 1663 R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); 1664 } 1665 1666 temp = INREG(pRADEONI2CBus->a_clk_reg); 1667 temp &= ~(pRADEONI2CBus->a_clk_mask); 1668 OUTREG(pRADEONI2CBus->a_clk_reg, temp); 1669 1670 temp = INREG(pRADEONI2CBus->a_data_reg); 1671 temp &= ~(pRADEONI2CBus->a_data_mask); 1672 OUTREG(pRADEONI2CBus->a_data_reg, temp); 1673 } 1674 1675 temp = INREG(pRADEONI2CBus->mask_clk_reg); 1676 if (lock_state) 1677 temp |= (pRADEONI2CBus->mask_clk_mask); 1678 else 1679 temp &= ~(pRADEONI2CBus->mask_clk_mask); 1680 OUTREG(pRADEONI2CBus->mask_clk_reg, temp); 1681 temp = INREG(pRADEONI2CBus->mask_clk_reg); 1682 1683 temp = INREG(pRADEONI2CBus->mask_data_reg); 1684 if (lock_state) 1685 temp |= (pRADEONI2CBus->mask_data_mask); 1686 else 1687 temp &= ~(pRADEONI2CBus->mask_data_mask); 1688 OUTREG(pRADEONI2CBus->mask_data_reg, temp); 1689 temp = INREG(pRADEONI2CBus->mask_data_reg); 1690 1691 return TRUE; 1692} 1693 1694static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data) 1695{ 1696 ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 1697 RADEONInfoPtr info = RADEONPTR(pScrn); 1698 unsigned long val; 1699 unsigned char *RADEONMMIO = info->MMIO; 1700 RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1701 1702 /* Get the result */ 1703 val = INREG(pRADEONI2CBus->get_clk_reg); 1704 *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0; 1705 val = INREG(pRADEONI2CBus->get_data_reg); 1706 *data = (val & pRADEONI2CBus->get_data_mask) != 0; 1707 1708} 1709 1710static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data) 1711{ 1712 ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; 1713 RADEONInfoPtr info = RADEONPTR(pScrn); 1714 unsigned long val; 1715 unsigned char *RADEONMMIO = info->MMIO; 1716 RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr; 1717 1718 val = INREG(pRADEONI2CBus->put_clk_reg) & (uint32_t)~(pRADEONI2CBus->put_clk_mask); 1719 val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask); 1720 OUTREG(pRADEONI2CBus->put_clk_reg, val); 1721 /* read back to improve reliability on some cards. */ 1722 val = INREG(pRADEONI2CBus->put_clk_reg); 1723 1724 val = INREG(pRADEONI2CBus->put_data_reg) & (uint32_t)~(pRADEONI2CBus->put_data_mask); 1725 val |= (data ? 0:pRADEONI2CBus->put_data_mask); 1726 OUTREG(pRADEONI2CBus->put_data_reg, val); 1727 /* read back to improve reliability on some cards. */ 1728 val = INREG(pRADEONI2CBus->put_data_reg); 1729 1730} 1731 1732Bool 1733RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus) 1734{ 1735 I2CBusPtr pI2CBus; 1736 1737 pI2CBus = xf86CreateI2CBusRec(); 1738 if (!pI2CBus) return FALSE; 1739 1740 pI2CBus->BusName = name; 1741 pI2CBus->scrnIndex = pScrn->scrnIndex; 1742 pI2CBus->I2CPutBits = RADEONI2CPutBits; 1743 pI2CBus->I2CGetBits = RADEONI2CGetBits; 1744 pI2CBus->AcknTimeout = 5; 1745 1746 pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus; 1747 1748 if (!xf86I2CBusInit(pI2CBus)) 1749 return FALSE; 1750 1751 *bus_ptr = pI2CBus; 1752 return TRUE; 1753} 1754 1755RADEONI2CBusRec 1756legacy_setup_i2c_bus(int ddc_line) 1757{ 1758 RADEONI2CBusRec i2c; 1759 1760 i2c.hw_line = 0; 1761 i2c.hw_capable = FALSE; 1762 i2c.mask_clk_mask = RADEON_GPIO_EN_1; 1763 i2c.mask_data_mask = RADEON_GPIO_EN_0; 1764 i2c.a_clk_mask = RADEON_GPIO_A_1; 1765 i2c.a_data_mask = RADEON_GPIO_A_0; 1766 i2c.put_clk_mask = RADEON_GPIO_EN_1; 1767 i2c.put_data_mask = RADEON_GPIO_EN_0; 1768 i2c.get_clk_mask = RADEON_GPIO_Y_1; 1769 i2c.get_data_mask = RADEON_GPIO_Y_0; 1770 if ((ddc_line == RADEON_LCD_GPIO_MASK) || 1771 (ddc_line == RADEON_MDGPIO_EN_REG)) { 1772 i2c.mask_clk_reg = ddc_line; 1773 i2c.mask_data_reg = ddc_line; 1774 i2c.a_clk_reg = ddc_line; 1775 i2c.a_data_reg = ddc_line; 1776 i2c.put_clk_reg = ddc_line; 1777 i2c.put_data_reg = ddc_line; 1778 i2c.get_clk_reg = ddc_line + 4; 1779 i2c.get_data_reg = ddc_line + 4; 1780 } else { 1781 i2c.mask_clk_reg = ddc_line; 1782 i2c.mask_data_reg = ddc_line; 1783 i2c.a_clk_reg = ddc_line; 1784 i2c.a_data_reg = ddc_line; 1785 i2c.put_clk_reg = ddc_line; 1786 i2c.put_data_reg = ddc_line; 1787 i2c.get_clk_reg = ddc_line; 1788 i2c.get_data_reg = ddc_line; 1789 } 1790 1791 if (ddc_line) 1792 i2c.valid = TRUE; 1793 else 1794 i2c.valid = FALSE; 1795 1796 return i2c; 1797} 1798 1799RADEONI2CBusRec 1800atom_setup_i2c_bus(int ddc_line) 1801{ 1802 RADEONI2CBusRec i2c; 1803 1804 i2c.hw_line = 0; 1805 i2c.hw_capable = FALSE; 1806 if (ddc_line == AVIVO_GPIO_0) { 1807 i2c.put_clk_mask = (1 << 19); 1808 i2c.put_data_mask = (1 << 18); 1809 i2c.get_clk_mask = (1 << 19); 1810 i2c.get_data_mask = (1 << 18); 1811 i2c.mask_clk_mask = (1 << 19); 1812 i2c.mask_data_mask = (1 << 18); 1813 i2c.a_clk_mask = (1 << 19); 1814 i2c.a_data_mask = (1 << 18); 1815 } else { 1816 i2c.put_clk_mask = (1 << 0); 1817 i2c.put_data_mask = (1 << 8); 1818 i2c.get_clk_mask = (1 << 0); 1819 i2c.get_data_mask = (1 << 8); 1820 i2c.mask_clk_mask = (1 << 0); 1821 i2c.mask_data_mask = (1 << 8); 1822 i2c.a_clk_mask = (1 << 0); 1823 i2c.a_data_mask = (1 << 8); 1824 } 1825 i2c.mask_clk_reg = ddc_line; 1826 i2c.mask_data_reg = ddc_line; 1827 i2c.a_clk_reg = ddc_line + 0x4; 1828 i2c.a_data_reg = ddc_line + 0x4; 1829 i2c.put_clk_reg = ddc_line + 0x8; 1830 i2c.put_data_reg = ddc_line + 0x8; 1831 i2c.get_clk_reg = ddc_line + 0xc; 1832 i2c.get_data_reg = ddc_line + 0xc; 1833 if (ddc_line) 1834 i2c.valid = TRUE; 1835 else 1836 i2c.valid = FALSE; 1837 1838 return i2c; 1839} 1840 1841static void 1842RADEONGetTVInfo(xf86OutputPtr output) 1843{ 1844 ScrnInfoPtr pScrn = output->scrn; 1845 RADEONInfoPtr info = RADEONPTR(pScrn); 1846 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1847 radeon_tvout_ptr tvout = &radeon_output->tvout; 1848 char *optstr; 1849 1850 tvout->hPos = 0; 1851 tvout->vPos = 0; 1852 tvout->hSize = 0; 1853 tvout->tv_on = FALSE; 1854 1855 if (!RADEONGetTVInfoFromBIOS(output)) { 1856 /* set some reasonable defaults */ 1857 tvout->default_tvStd = TV_STD_NTSC; 1858 tvout->tvStd = TV_STD_NTSC; 1859 tvout->TVRefClk = 27.000000000; 1860 tvout->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL; 1861 } 1862 1863 optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD); 1864 if (optstr) { 1865 if (!strncmp("ntsc", optstr, strlen("ntsc"))) 1866 tvout->tvStd = TV_STD_NTSC; 1867 else if (!strncmp("pal", optstr, strlen("pal"))) 1868 tvout->tvStd = TV_STD_PAL; 1869 else if (!strncmp("pal-m", optstr, strlen("pal-m"))) 1870 tvout->tvStd = TV_STD_PAL_M; 1871 else if (!strncmp("pal-60", optstr, strlen("pal-60"))) 1872 tvout->tvStd = TV_STD_PAL_60; 1873 else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j"))) 1874 tvout->tvStd = TV_STD_NTSC_J; 1875 else if (!strncmp("scart-pal", optstr, strlen("scart-pal"))) 1876 tvout->tvStd = TV_STD_SCART_PAL; 1877 else { 1878 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr); 1879 } 1880 } 1881 1882} 1883 1884void RADEONInitConnector(xf86OutputPtr output) 1885{ 1886 ScrnInfoPtr pScrn = output->scrn; 1887 RADEONInfoPtr info = RADEONPTR(pScrn); 1888 RADEONOutputPrivatePtr radeon_output = output->driver_private; 1889 1890 if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) 1891 radeon_output->rmx_type = RMX_FULL; 1892 else 1893 radeon_output->rmx_type = RMX_OFF; 1894 1895 /* dce 3.2 chips have problems with low dot clocks, so use the scaler */ 1896 if (IS_DCE32_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) 1897 radeon_output->rmx_type = RMX_FULL; 1898 1899 if (!IS_AVIVO_VARIANT) { 1900 if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) { 1901 if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE)) 1902 radeon_output->load_detection = 1; 1903 } 1904 } 1905 1906 if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) 1907 RADEONGetTVInfo(output); 1908 1909 if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) 1910 radeon_output->coherent_mode = TRUE; 1911 1912 if (radeon_output->ddc_i2c.valid) 1913 RADEONI2CInit(pScrn, &radeon_output->pI2CBus, output->name, &radeon_output->ddc_i2c); 1914 1915} 1916 1917#if defined(__powerpc__) 1918static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn) 1919{ 1920 RADEONInfoPtr info = RADEONPTR(pScrn); 1921 1922 1923 switch (info->MacModel) { 1924 case RADEON_MAC_IBOOK: 1925 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 1926 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 1927 info->BiosConnector[0].valid = TRUE; 1928 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 1929 if (!radeon_add_encoder(pScrn, 1930 radeon_get_encoder_id_from_supported_device(pScrn, 1931 ATOM_DEVICE_LCD1_SUPPORT, 1932 0), 1933 ATOM_DEVICE_LCD1_SUPPORT)) 1934 return FALSE; 1935 1936 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 1937 info->BiosConnector[1].load_detection = FALSE; 1938 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 1939 info->BiosConnector[1].valid = TRUE; 1940 info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 1941 if (!radeon_add_encoder(pScrn, 1942 radeon_get_encoder_id_from_supported_device(pScrn, 1943 ATOM_DEVICE_CRT2_SUPPORT, 1944 2), 1945 ATOM_DEVICE_CRT2_SUPPORT)) 1946 return FALSE; 1947 1948 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 1949 info->BiosConnector[2].load_detection = FALSE; 1950 info->BiosConnector[2].ddc_i2c.valid = FALSE; 1951 info->BiosConnector[2].valid = TRUE; 1952 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 1953 if (!radeon_add_encoder(pScrn, 1954 radeon_get_encoder_id_from_supported_device(pScrn, 1955 ATOM_DEVICE_TV1_SUPPORT, 1956 2), 1957 ATOM_DEVICE_TV1_SUPPORT)) 1958 return FALSE; 1959 return TRUE; 1960 case RADEON_MAC_POWERBOOK_EXTERNAL: 1961 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 1962 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 1963 info->BiosConnector[0].valid = TRUE; 1964 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 1965 if (!radeon_add_encoder(pScrn, 1966 radeon_get_encoder_id_from_supported_device(pScrn, 1967 ATOM_DEVICE_LCD1_SUPPORT, 1968 0), 1969 ATOM_DEVICE_LCD1_SUPPORT)) 1970 return FALSE; 1971 1972 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 1973 info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 1974 info->BiosConnector[1].valid = TRUE; 1975 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 1976 if (!radeon_add_encoder(pScrn, 1977 radeon_get_encoder_id_from_supported_device(pScrn, 1978 ATOM_DEVICE_CRT1_SUPPORT, 1979 1), 1980 ATOM_DEVICE_CRT1_SUPPORT)) 1981 return FALSE; 1982 if (!radeon_add_encoder(pScrn, 1983 radeon_get_encoder_id_from_supported_device(pScrn, 1984 ATOM_DEVICE_DFP2_SUPPORT, 1985 0), 1986 ATOM_DEVICE_DFP2_SUPPORT)) 1987 return FALSE; 1988 1989 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 1990 info->BiosConnector[2].load_detection = FALSE; 1991 info->BiosConnector[2].ddc_i2c.valid = FALSE; 1992 info->BiosConnector[2].valid = TRUE; 1993 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 1994 if (!radeon_add_encoder(pScrn, 1995 radeon_get_encoder_id_from_supported_device(pScrn, 1996 ATOM_DEVICE_TV1_SUPPORT, 1997 2), 1998 ATOM_DEVICE_TV1_SUPPORT)) 1999 return FALSE; 2000 return TRUE; 2001 case RADEON_MAC_POWERBOOK_INTERNAL: 2002 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2003 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2004 info->BiosConnector[0].valid = TRUE; 2005 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2006 if (!radeon_add_encoder(pScrn, 2007 radeon_get_encoder_id_from_supported_device(pScrn, 2008 ATOM_DEVICE_LCD1_SUPPORT, 2009 0), 2010 ATOM_DEVICE_LCD1_SUPPORT)) 2011 return FALSE; 2012 2013 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2014 info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 2015 info->BiosConnector[1].valid = TRUE; 2016 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2017 if (!radeon_add_encoder(pScrn, 2018 radeon_get_encoder_id_from_supported_device(pScrn, 2019 ATOM_DEVICE_CRT1_SUPPORT, 2020 1), 2021 ATOM_DEVICE_CRT1_SUPPORT)) 2022 return FALSE; 2023 if (!radeon_add_encoder(pScrn, 2024 radeon_get_encoder_id_from_supported_device(pScrn, 2025 ATOM_DEVICE_DFP1_SUPPORT, 2026 0), 2027 ATOM_DEVICE_DFP1_SUPPORT)) 2028 return FALSE; 2029 2030 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2031 info->BiosConnector[2].load_detection = FALSE; 2032 info->BiosConnector[2].ddc_i2c.valid = FALSE; 2033 info->BiosConnector[2].valid = TRUE; 2034 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2035 if (!radeon_add_encoder(pScrn, 2036 radeon_get_encoder_id_from_supported_device(pScrn, 2037 ATOM_DEVICE_TV1_SUPPORT, 2038 2), 2039 ATOM_DEVICE_TV1_SUPPORT)) 2040 return FALSE; 2041 return TRUE; 2042 case RADEON_MAC_POWERBOOK_VGA: 2043 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2044 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2045 info->BiosConnector[0].valid = TRUE; 2046 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2047 if (!radeon_add_encoder(pScrn, 2048 radeon_get_encoder_id_from_supported_device(pScrn, 2049 ATOM_DEVICE_LCD1_SUPPORT, 2050 0), 2051 ATOM_DEVICE_LCD1_SUPPORT)) 2052 return FALSE; 2053 2054 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2055 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2056 info->BiosConnector[1].valid = TRUE; 2057 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2058 if (!radeon_add_encoder(pScrn, 2059 radeon_get_encoder_id_from_supported_device(pScrn, 2060 ATOM_DEVICE_CRT1_SUPPORT, 2061 1), 2062 ATOM_DEVICE_CRT1_SUPPORT)) 2063 return FALSE; 2064 2065 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2066 info->BiosConnector[2].load_detection = FALSE; 2067 info->BiosConnector[2].ddc_i2c.valid = FALSE; 2068 info->BiosConnector[2].valid = TRUE; 2069 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2070 if (!radeon_add_encoder(pScrn, 2071 radeon_get_encoder_id_from_supported_device(pScrn, 2072 ATOM_DEVICE_TV1_SUPPORT, 2073 2), 2074 ATOM_DEVICE_TV1_SUPPORT)) 2075 return FALSE; 2076 return TRUE; 2077 case RADEON_MAC_MINI_EXTERNAL: 2078 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2079 info->BiosConnector[0].load_detection = FALSE; 2080 info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2081 info->BiosConnector[0].valid = TRUE; 2082 info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 2083 if (!radeon_add_encoder(pScrn, 2084 radeon_get_encoder_id_from_supported_device(pScrn, 2085 ATOM_DEVICE_CRT2_SUPPORT, 2086 2), 2087 ATOM_DEVICE_CRT2_SUPPORT)) 2088 return FALSE; 2089 if (!radeon_add_encoder(pScrn, 2090 radeon_get_encoder_id_from_supported_device(pScrn, 2091 ATOM_DEVICE_DFP2_SUPPORT, 2092 0), 2093 ATOM_DEVICE_DFP2_SUPPORT)) 2094 return FALSE; 2095 2096 info->BiosConnector[1].ConnectorType = CONNECTOR_STV; 2097 info->BiosConnector[1].load_detection = FALSE; 2098 info->BiosConnector[1].ddc_i2c.valid = FALSE; 2099 info->BiosConnector[1].valid = TRUE; 2100 info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; 2101 if (!radeon_add_encoder(pScrn, 2102 radeon_get_encoder_id_from_supported_device(pScrn, 2103 ATOM_DEVICE_TV1_SUPPORT, 2104 2), 2105 ATOM_DEVICE_TV1_SUPPORT)) 2106 return FALSE; 2107 return TRUE; 2108 case RADEON_MAC_MINI_INTERNAL: 2109 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2110 info->BiosConnector[0].load_detection = FALSE; 2111 info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2112 info->BiosConnector[0].valid = TRUE; 2113 info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2114 if (!radeon_add_encoder(pScrn, 2115 radeon_get_encoder_id_from_supported_device(pScrn, 2116 ATOM_DEVICE_CRT2_SUPPORT, 2117 2), 2118 ATOM_DEVICE_CRT2_SUPPORT)) 2119 return FALSE; 2120 if (!radeon_add_encoder(pScrn, 2121 radeon_get_encoder_id_from_supported_device(pScrn, 2122 ATOM_DEVICE_DFP1_SUPPORT, 2123 0), 2124 ATOM_DEVICE_DFP1_SUPPORT)) 2125 return FALSE; 2126 2127 info->BiosConnector[1].ConnectorType = CONNECTOR_STV; 2128 info->BiosConnector[1].load_detection = FALSE; 2129 info->BiosConnector[1].ddc_i2c.valid = FALSE; 2130 info->BiosConnector[1].valid = TRUE; 2131 info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT; 2132 if (!radeon_add_encoder(pScrn, 2133 radeon_get_encoder_id_from_supported_device(pScrn, 2134 ATOM_DEVICE_TV1_SUPPORT, 2135 2), 2136 ATOM_DEVICE_TV1_SUPPORT)) 2137 return FALSE; 2138 return TRUE; 2139 case RADEON_MAC_IMAC_G5_ISIGHT: 2140 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); 2141 info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D; 2142 info->BiosConnector[0].valid = TRUE; 2143 info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT; 2144 if (!radeon_add_encoder(pScrn, 2145 radeon_get_encoder_id_from_supported_device(pScrn, 2146 ATOM_DEVICE_DFP1_SUPPORT, 2147 0), 2148 ATOM_DEVICE_DFP1_SUPPORT)) 2149 return FALSE; 2150 2151 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2152 info->BiosConnector[1].load_detection = FALSE; 2153 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2154 info->BiosConnector[1].valid = TRUE; 2155 info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 2156 if (!radeon_add_encoder(pScrn, 2157 radeon_get_encoder_id_from_supported_device(pScrn, 2158 ATOM_DEVICE_CRT2_SUPPORT, 2159 2), 2160 ATOM_DEVICE_CRT2_SUPPORT)) 2161 return FALSE; 2162 2163 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2164 info->BiosConnector[2].load_detection = FALSE; 2165 info->BiosConnector[2].ddc_i2c.valid = FALSE; 2166 info->BiosConnector[2].valid = TRUE; 2167 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2168 if (!radeon_add_encoder(pScrn, 2169 radeon_get_encoder_id_from_supported_device(pScrn, 2170 ATOM_DEVICE_TV1_SUPPORT, 2171 2), 2172 ATOM_DEVICE_TV1_SUPPORT)) 2173 return FALSE; 2174 return TRUE; 2175 case RADEON_MAC_EMAC: 2176 /* eMac G4 800/1.0 with radeon 7500, no EDID on internal monitor 2177 * later eMac's (G4 1.25/1.42) with radeon 9200 and 9600 may have 2178 * different ddc setups. need to verify 2179 */ 2180 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2181 info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2182 info->BiosConnector[0].valid = TRUE; 2183 info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2184 if (!radeon_add_encoder(pScrn, 2185 radeon_get_encoder_id_from_supported_device(pScrn, 2186 ATOM_DEVICE_CRT1_SUPPORT, 2187 1), 2188 ATOM_DEVICE_CRT1_SUPPORT)) 2189 return FALSE; 2190 2191 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2192 info->BiosConnector[1].load_detection = FALSE; 2193 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2194 info->BiosConnector[1].valid = TRUE; 2195 info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT; 2196 if (!radeon_add_encoder(pScrn, 2197 radeon_get_encoder_id_from_supported_device(pScrn, 2198 ATOM_DEVICE_CRT2_SUPPORT, 2199 2), 2200 ATOM_DEVICE_CRT2_SUPPORT)) 2201 return FALSE; 2202 2203 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2204 info->BiosConnector[2].load_detection = FALSE; 2205 info->BiosConnector[2].ddc_i2c.valid = FALSE; 2206 info->BiosConnector[2].valid = TRUE; 2207 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2208 if (!radeon_add_encoder(pScrn, 2209 radeon_get_encoder_id_from_supported_device(pScrn, 2210 ATOM_DEVICE_TV1_SUPPORT, 2211 2), 2212 ATOM_DEVICE_TV1_SUPPORT)) 2213 return FALSE; 2214 return TRUE; 2215 default: 2216 return FALSE; 2217 } 2218 2219 return FALSE; 2220} 2221#endif 2222 2223static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn) 2224{ 2225 RADEONInfoPtr info = RADEONPTR(pScrn); 2226 RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); 2227 2228 if (IS_AVIVO_VARIANT) 2229 return; 2230 2231 if (!pRADEONEnt->HasCRTC2) { 2232 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2233 info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2234 info->BiosConnector[0].valid = TRUE; 2235 info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2236 radeon_add_encoder(pScrn, 2237 radeon_get_encoder_id_from_supported_device(pScrn, 2238 ATOM_DEVICE_CRT1_SUPPORT, 2239 1), 2240 ATOM_DEVICE_CRT1_SUPPORT); 2241 return; 2242 } 2243 2244 if (info->IsMobility) { 2245 /* Below is the most common setting, but may not be true */ 2246 if (info->IsIGP) { 2247 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); 2248 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2249 info->BiosConnector[0].valid = TRUE; 2250 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2251 radeon_add_encoder(pScrn, 2252 radeon_get_encoder_id_from_supported_device(pScrn, 2253 ATOM_DEVICE_LCD1_SUPPORT, 2254 0), 2255 ATOM_DEVICE_LCD1_SUPPORT); 2256 2257 /* IGP only has TVDAC */ 2258 if ((info->ChipFamily == CHIP_FAMILY_RS400) || 2259 (info->ChipFamily == CHIP_FAMILY_RS480)) 2260 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2261 else 2262 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2263 info->BiosConnector[1].load_detection = FALSE; 2264 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2265 info->BiosConnector[1].valid = TRUE; 2266 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2267 radeon_add_encoder(pScrn, 2268 radeon_get_encoder_id_from_supported_device(pScrn, 2269 ATOM_DEVICE_CRT1_SUPPORT, 2270 2), 2271 ATOM_DEVICE_CRT1_SUPPORT); 2272 } else { 2273#if defined(__powerpc__) 2274 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2275#else 2276 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK); 2277#endif 2278 info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS; 2279 info->BiosConnector[0].valid = TRUE; 2280 info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT; 2281 radeon_add_encoder(pScrn, 2282 radeon_get_encoder_id_from_supported_device(pScrn, 2283 ATOM_DEVICE_LCD1_SUPPORT, 2284 0), 2285 ATOM_DEVICE_LCD1_SUPPORT); 2286 2287 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2288 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2289 info->BiosConnector[1].valid = TRUE; 2290 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2291 radeon_add_encoder(pScrn, 2292 radeon_get_encoder_id_from_supported_device(pScrn, 2293 ATOM_DEVICE_CRT1_SUPPORT, 2294 1), 2295 ATOM_DEVICE_CRT1_SUPPORT); 2296 } 2297 } else { 2298 /* Below is the most common setting, but may not be true */ 2299 if (info->IsIGP) { 2300 if ((info->ChipFamily == CHIP_FAMILY_RS400) || 2301 (info->ChipFamily == CHIP_FAMILY_RS480)) 2302 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC); 2303 else 2304 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2305 info->BiosConnector[0].load_detection = FALSE; 2306 info->BiosConnector[0].ConnectorType = CONNECTOR_VGA; 2307 info->BiosConnector[0].valid = TRUE; 2308 info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT; 2309 radeon_add_encoder(pScrn, 2310 radeon_get_encoder_id_from_supported_device(pScrn, 2311 ATOM_DEVICE_CRT1_SUPPORT, 2312 1), 2313 ATOM_DEVICE_CRT1_SUPPORT); 2314 2315 /* not sure what a good default DDCType for DVI on 2316 * IGP desktop chips is 2317 */ 2318 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */ 2319 info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D; 2320 info->BiosConnector[1].valid = TRUE; 2321 info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT; 2322 radeon_add_encoder(pScrn, 2323 radeon_get_encoder_id_from_supported_device(pScrn, 2324 ATOM_DEVICE_DFP1_SUPPORT, 2325 0), 2326 ATOM_DEVICE_DFP1_SUPPORT); 2327 } else { 2328 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2329 info->BiosConnector[0].load_detection = FALSE; 2330 info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I; 2331 info->BiosConnector[0].valid = TRUE; 2332 info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT; 2333 radeon_add_encoder(pScrn, 2334 radeon_get_encoder_id_from_supported_device(pScrn, 2335 ATOM_DEVICE_CRT2_SUPPORT, 2336 2), 2337 ATOM_DEVICE_CRT2_SUPPORT); 2338 radeon_add_encoder(pScrn, 2339 radeon_get_encoder_id_from_supported_device(pScrn, 2340 ATOM_DEVICE_DFP1_SUPPORT, 2341 0), 2342 ATOM_DEVICE_DFP1_SUPPORT); 2343 2344#if defined(__powerpc__) 2345 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2346 info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I; 2347 info->BiosConnector[1].valid = TRUE; 2348 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT; 2349 radeon_add_encoder(pScrn, 2350 radeon_get_encoder_id_from_supported_device(pScrn, 2351 ATOM_DEVICE_CRT1_SUPPORT, 2352 1), 2353 ATOM_DEVICE_CRT1_SUPPORT); 2354 radeon_add_encoder(pScrn, 2355 radeon_get_encoder_id_from_supported_device(pScrn, 2356 ATOM_DEVICE_DFP2_SUPPORT, 2357 0), 2358 ATOM_DEVICE_DFP2_SUPPORT); 2359#else 2360 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2361 info->BiosConnector[1].ConnectorType = CONNECTOR_VGA; 2362 info->BiosConnector[1].valid = TRUE; 2363 info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT; 2364 radeon_add_encoder(pScrn, 2365 radeon_get_encoder_id_from_supported_device(pScrn, 2366 ATOM_DEVICE_CRT1_SUPPORT, 2367 1), 2368 ATOM_DEVICE_CRT1_SUPPORT); 2369#endif 2370 } 2371 } 2372 2373 if (info->InternalTVOut) { 2374 info->BiosConnector[2].ConnectorType = CONNECTOR_STV; 2375 info->BiosConnector[2].load_detection = FALSE; 2376 info->BiosConnector[2].ddc_i2c.valid = FALSE; 2377 info->BiosConnector[2].valid = TRUE; 2378 info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT; 2379 radeon_add_encoder(pScrn, 2380 radeon_get_encoder_id_from_supported_device(pScrn, 2381 ATOM_DEVICE_TV1_SUPPORT, 2382 2), 2383 ATOM_DEVICE_TV1_SUPPORT); 2384 } 2385 2386 /* Some cards have the DDC lines swapped and we have no way to 2387 * detect it yet (Mac cards) 2388 */ 2389 if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) { 2390 info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC); 2391 info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC); 2392 } 2393} 2394 2395#if defined(__powerpc__) 2396 2397/* 2398 * Returns RADEONMacModel or 0 based on lines 'detected as' and 'machine' 2399 * in /proc/cpuinfo (on Linux) */ 2400static RADEONMacModel RADEONDetectMacModel(ScrnInfoPtr pScrn) 2401{ 2402 RADEONInfoPtr info = RADEONPTR(pScrn); 2403 RADEONMacModel ret = 0; 2404#ifdef __linux__ 2405 char cpuline[50]; /* 50 should be sufficient for our purposes */ 2406 FILE *f = fopen ("/proc/cpuinfo", "r"); 2407 2408 /* Some macs (minis and powerbooks) use internal tmds, others use external tmds 2409 * and not just for dual-link TMDS, it shows up with single-link as well. 2410 * Unforunately, there doesn't seem to be any good way to figure it out. 2411 */ 2412 2413 /* 2414 * PowerBook5,[1-5]: external tmds, single-link 2415 * PowerBook5,[789]: external tmds, dual-link 2416 * PowerBook5,6: external tmds, single-link or dual-link 2417 * need to add another option to specify the external tmds chip 2418 * or find out what's used and add it. 2419 */ 2420 2421 2422 if (f != NULL) { 2423 while (fgets(cpuline, sizeof cpuline, f)) { 2424 if (!strncmp(cpuline, "machine", strlen ("machine"))) { 2425 if (strstr(cpuline, "PowerBook5,1") || 2426 strstr(cpuline, "PowerBook5,2") || 2427 strstr(cpuline, "PowerBook5,3") || 2428 strstr(cpuline, "PowerBook5,4") || 2429 strstr(cpuline, "PowerBook5,5")) { 2430 ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* single link */ 2431 info->ext_tmds_chip = RADEON_SIL_164; /* works on 5,2 */ 2432 break; 2433 } 2434 2435 if (strstr(cpuline, "PowerBook5,6")) { 2436 ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual or single link */ 2437 break; 2438 } 2439 2440 if (strstr(cpuline, "PowerBook5,7") || 2441 strstr(cpuline, "PowerBook5,8") || 2442 strstr(cpuline, "PowerBook5,9")) { 2443 ret = RADEON_MAC_POWERBOOK_EXTERNAL; /* dual link */ 2444 info->ext_tmds_chip = RADEON_SIL_1178; /* guess */ 2445 break; 2446 } 2447 2448 if (strstr(cpuline, "PowerBook3,3")) { 2449 ret = RADEON_MAC_POWERBOOK_VGA; /* vga rather than dvi */ 2450 break; 2451 } 2452 2453 if (strstr(cpuline, "PowerMac10,1")) { 2454 ret = RADEON_MAC_MINI_INTERNAL; /* internal tmds */ 2455 break; 2456 } 2457 if (strstr(cpuline, "PowerMac10,2")) { 2458 ret = RADEON_MAC_MINI_EXTERNAL; /* external tmds */ 2459 break; 2460 } 2461 } else if (!strncmp(cpuline, "detected as", strlen("detected as"))) { 2462 if (strstr(cpuline, "iBook")) { 2463 ret = RADEON_MAC_IBOOK; 2464 break; 2465 } else if (strstr(cpuline, "PowerBook")) { 2466 ret = RADEON_MAC_POWERBOOK_INTERNAL; /* internal tmds */ 2467 break; 2468 } else if (strstr(cpuline, "iMac G5 (iSight)")) { 2469 ret = RADEON_MAC_IMAC_G5_ISIGHT; 2470 break; 2471 } else if (strstr(cpuline, "eMac")) { 2472 ret = RADEON_MAC_EMAC; 2473 break; 2474 } 2475 2476 /* No known PowerMac model detected */ 2477 break; 2478 } 2479 } 2480 2481 fclose (f); 2482 } else 2483 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 2484 "Cannot detect PowerMac model because /proc/cpuinfo not " 2485 "readable.\n"); 2486 2487#endif /* __linux */ 2488 2489 if (ret) { 2490 xf86DrvMsg(pScrn->scrnIndex, X_DEFAULT, "Detected %s.\n", 2491 ret == RADEON_MAC_POWERBOOK_EXTERNAL ? "PowerBook with external DVI" : 2492 ret == RADEON_MAC_POWERBOOK_INTERNAL ? "PowerBook with integrated DVI" : 2493 ret == RADEON_MAC_POWERBOOK_VGA ? "PowerBook with VGA" : 2494 ret == RADEON_MAC_IBOOK ? "iBook" : 2495 ret == RADEON_MAC_MINI_EXTERNAL ? "Mac Mini with external DVI" : 2496 ret == RADEON_MAC_MINI_INTERNAL ? "Mac Mini with integrated DVI" : 2497 "iMac G5 iSight"); 2498 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2499 "If this is not correct, try Option \"MacModel\" and " 2500 "consider reporting to the\n"); 2501 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2502 "xorg-driver-ati@lists.x.org mailing list" 2503#ifdef __linux__ 2504 " with the contents of /proc/cpuinfo" 2505#endif 2506 ".\n"); 2507 } 2508 2509 return ret; 2510} 2511 2512#endif /* __powerpc__ */ 2513 2514static int 2515radeon_output_clones (ScrnInfoPtr pScrn, xf86OutputPtr output) 2516{ 2517 RADEONInfoPtr info = RADEONPTR(pScrn); 2518 RADEONOutputPrivatePtr radeon_output = output->driver_private; 2519 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); 2520 int o; 2521 int index_mask = 0; 2522 2523 /* DIG routing gets problematic */ 2524 if (IS_DCE32_VARIANT) 2525 return index_mask; 2526 2527 /* LVDS is too wacky */ 2528 if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) 2529 return index_mask; 2530 2531 if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) 2532 return index_mask; 2533 2534 for (o = 0; o < config->num_output; o++) { 2535 xf86OutputPtr clone = config->output[o]; 2536 RADEONOutputPrivatePtr radeon_clone = clone->driver_private; 2537 2538 if (output == clone) /* don't clone yourself */ 2539 continue; 2540 else if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) /* LVDS */ 2541 continue; 2542 else if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) /* TV */ 2543 continue; 2544 else 2545 index_mask |= (1 << o); 2546 } 2547 2548 return index_mask; 2549} 2550 2551static xf86OutputPtr 2552RADEONOutputCreate(ScrnInfoPtr pScrn, const char *name, int i) 2553{ 2554 char buf[32]; 2555 sprintf(buf, name, i); 2556 return xf86OutputCreate(pScrn, &radeon_output_funcs, buf); 2557} 2558 2559/* 2560 * initialise the static data sos we don't have to re-do at randr change */ 2561Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) 2562{ 2563 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2564 RADEONInfoPtr info = RADEONPTR(pScrn); 2565 xf86OutputPtr output; 2566 char *optstr; 2567 int i; 2568 int num_vga = 0; 2569 int num_dvi = 0; 2570 int num_hdmi = 0; 2571 int num_dp = 0; 2572 2573 /* We first get the information about all connectors from BIOS. 2574 * This is how the card is phyiscally wired up. 2575 * The information should be correct even on a OEM card. 2576 */ 2577 for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 2578 info->encoders[i] = NULL; 2579 info->BiosConnector[i].valid = FALSE; 2580 info->BiosConnector[i].load_detection = TRUE; 2581 info->BiosConnector[i].shared_ddc = FALSE; 2582 info->BiosConnector[i].ddc_i2c.valid = FALSE; 2583 info->BiosConnector[i].ConnectorType = CONNECTOR_NONE; 2584 info->BiosConnector[i].devices = 0; 2585 } 2586 2587#if defined(__powerpc__) 2588 info->MacModel = 0; 2589 optstr = (char *)xf86GetOptValString(info->Options, OPTION_MAC_MODEL); 2590 if (optstr) { 2591 if (!strncmp("ibook", optstr, strlen("ibook"))) 2592 info->MacModel = RADEON_MAC_IBOOK; 2593 else if (!strncmp("powerbook-duallink", optstr, strlen("powerbook-duallink"))) /* alias */ 2594 info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL; 2595 else if (!strncmp("powerbook-external", optstr, strlen("powerbook-external"))) 2596 info->MacModel = RADEON_MAC_POWERBOOK_EXTERNAL; 2597 else if (!strncmp("powerbook-internal", optstr, strlen("powerbook-internal"))) 2598 info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL; 2599 else if (!strncmp("powerbook-vga", optstr, strlen("powerbook-vga"))) 2600 info->MacModel = RADEON_MAC_POWERBOOK_VGA; 2601 else if (!strncmp("powerbook", optstr, strlen("powerbook"))) /* alias */ 2602 info->MacModel = RADEON_MAC_POWERBOOK_INTERNAL; 2603 else if (!strncmp("mini-internal", optstr, strlen("mini-internal"))) 2604 info->MacModel = RADEON_MAC_MINI_INTERNAL; 2605 else if (!strncmp("mini-external", optstr, strlen("mini-external"))) 2606 info->MacModel = RADEON_MAC_MINI_EXTERNAL; 2607 else if (!strncmp("mini", optstr, strlen("mini"))) /* alias */ 2608 info->MacModel = RADEON_MAC_MINI_EXTERNAL; 2609 else if (!strncmp("imac-g5-isight", optstr, strlen("imac-g5-isight"))) 2610 info->MacModel = RADEON_MAC_IMAC_G5_ISIGHT; 2611 else if (!strncmp("emac", optstr, strlen("emac"))) 2612 info->MacModel = RADEON_MAC_EMAC; 2613 else { 2614 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid Mac Model: %s\n", optstr); 2615 } 2616 } 2617 2618 if (!info->MacModel) { 2619 info->MacModel = RADEONDetectMacModel(pScrn); 2620 } 2621 2622 if (info->MacModel){ 2623 if (!RADEONSetupAppleConnectors(pScrn)) 2624 RADEONSetupGenericConnectors(pScrn); 2625 } else 2626#endif 2627 if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) { 2628 RADEONSetupGenericConnectors(pScrn); 2629 } else { 2630 if (!RADEONGetConnectorInfoFromBIOS(pScrn)) 2631 RADEONSetupGenericConnectors(pScrn); 2632 } 2633 2634 /* parse connector table option */ 2635 optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE); 2636 2637 if (optstr) { 2638 unsigned int ddc_line[2]; 2639 int DACType[2], TMDSType[2]; 2640 2641 for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 2642 info->BiosConnector[i].valid = FALSE; 2643 } 2644 2645 if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u", 2646 &ddc_line[0], 2647 &DACType[0], 2648 &TMDSType[0], 2649 &info->BiosConnector[0].ConnectorType, 2650 &ddc_line[1], 2651 &DACType[1], 2652 &TMDSType[1], 2653 &info->BiosConnector[1].ConnectorType) != 8) { 2654 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr); 2655 return FALSE; 2656 } 2657 2658 for (i = 0; i < 2; i++) { 2659 info->BiosConnector[i].valid = TRUE; 2660 info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(ddc_line[i]); 2661 switch (DACType[i]) { 2662 case 1: 2663 info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT; 2664 if (!radeon_add_encoder(pScrn, 2665 radeon_get_encoder_id_from_supported_device(pScrn, 2666 ATOM_DEVICE_CRT1_SUPPORT, 2667 1), 2668 ATOM_DEVICE_CRT1_SUPPORT)) 2669 return FALSE; 2670 info->BiosConnector[i].load_detection = TRUE; 2671 break; 2672 case 2: 2673 info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT; 2674 if (!radeon_add_encoder(pScrn, 2675 radeon_get_encoder_id_from_supported_device(pScrn, 2676 ATOM_DEVICE_CRT1_SUPPORT, 2677 2), 2678 ATOM_DEVICE_CRT1_SUPPORT)) 2679 return FALSE; 2680 info->BiosConnector[i].load_detection = FALSE; 2681 break; 2682 } 2683 switch (TMDSType[i]) { 2684 case 1: 2685 info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT; 2686 if (!radeon_add_encoder(pScrn, 2687 radeon_get_encoder_id_from_supported_device(pScrn, 2688 ATOM_DEVICE_DFP1_SUPPORT, 2689 0), 2690 ATOM_DEVICE_DFP1_SUPPORT)) 2691 return FALSE; 2692 break; 2693 case 2: 2694 info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT; 2695 if (!radeon_add_encoder(pScrn, 2696 radeon_get_encoder_id_from_supported_device(pScrn, 2697 ATOM_DEVICE_DFP2_SUPPORT, 2698 0), 2699 ATOM_DEVICE_DFP2_SUPPORT)) 2700 return FALSE; 2701 break; 2702 } 2703 } 2704 } 2705 2706 for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 2707 if (info->BiosConnector[i].valid) { 2708 RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType; 2709 if ((conntype == CONNECTOR_DVI_D) || 2710 (conntype == CONNECTOR_DVI_I) || 2711 (conntype == CONNECTOR_DVI_A)) { 2712 num_dvi++; 2713 } else if (conntype == CONNECTOR_VGA) { 2714 num_vga++; 2715 } else if ((conntype == CONNECTOR_HDMI_TYPE_A) || 2716 (conntype == CONNECTOR_HDMI_TYPE_B)) { 2717 num_hdmi++; 2718 } else if (conntype == CONNECTOR_DISPLAY_PORT) { 2719 num_dp++; 2720 } 2721 } 2722 } 2723 2724 for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) { 2725 if (info->BiosConnector[i].valid) { 2726 RADEONOutputPrivatePtr radeon_output; 2727 RADEONConnectorType conntype = info->BiosConnector[i].ConnectorType; 2728 2729 if (conntype == CONNECTOR_NONE) 2730 continue; 2731 2732 radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1); 2733 if (!radeon_output) { 2734 return FALSE; 2735 } 2736 radeon_output->MonType = MT_UNKNOWN; 2737 radeon_output->ConnectorType = conntype; 2738 radeon_output->devices = info->BiosConnector[i].devices; 2739 radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c; 2740 radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info; 2741 radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc; 2742 radeon_output->load_detection = info->BiosConnector[i].load_detection; 2743 radeon_output->linkb = info->BiosConnector[i].linkb; 2744 radeon_output->connector_id = info->BiosConnector[i].connector_object; 2745 2746 if ((conntype == CONNECTOR_DVI_D) || 2747 (conntype == CONNECTOR_DVI_I) || 2748 (conntype == CONNECTOR_DVI_A)) { 2749 output = RADEONOutputCreate(pScrn, "DVI-%d", --num_dvi); 2750 } else if (conntype == CONNECTOR_VGA) { 2751 output = RADEONOutputCreate(pScrn, "VGA-%d", --num_vga); 2752 } else if ((conntype == CONNECTOR_HDMI_TYPE_A) || 2753 (conntype == CONNECTOR_HDMI_TYPE_B)) { 2754 output = RADEONOutputCreate(pScrn, "HDMI-%d", --num_hdmi); 2755 } else if (conntype == CONNECTOR_DISPLAY_PORT) { 2756 output = RADEONOutputCreate(pScrn, "DisplayPort-%d", --num_dp); 2757 } else { 2758 output = RADEONOutputCreate(pScrn, 2759 ConnectorTypeName[conntype], 0); 2760 } 2761 2762 if (!output) { 2763 return FALSE; 2764 } 2765 output->driver_private = radeon_output; 2766 output->possible_crtcs = 1; 2767 /* crtc2 can drive LVDS, it just doesn't have RMX */ 2768 if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))) 2769 output->possible_crtcs |= 2; 2770 2771 /* we can clone the DACs, and probably TV-out, 2772 but I'm not sure it's worth the trouble */ 2773 output->possible_clones = 0; 2774 2775 RADEONInitConnector(output); 2776 } 2777 } 2778 2779 for (i = 0; i < xf86_config->num_output; i++) { 2780 xf86OutputPtr output = xf86_config->output[i]; 2781 2782 output->possible_clones = radeon_output_clones(pScrn, output); 2783 } 2784 2785 return TRUE; 2786} 2787 2788