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