xf86-video-ati: Branch 'master' - 35 commits

Alex Deucher agd5f at kemper.freedesktop.org
Wed Jan 28 11:41:15 PST 2009


 src/atombios_crtc.c   |   58 -
 src/atombios_output.c |  970 ++++++++++++----------
 src/legacy_crtc.c     |    8 
 src/legacy_output.c   |  885 ++++++++++++--------
 src/radeon.h          |   32 
 src/radeon_atombios.c |  631 +++++++++-----
 src/radeon_atombios.h |   12 
 src/radeon_bios.c     |  409 ++++++---
 src/radeon_modes.c    |  164 +++
 src/radeon_output.c   | 2116 ++++++++++++++++++++++----------------------------
 src/radeon_probe.h    |  186 ++--
 src/radeon_tv.c       |  163 ++-
 src/radeon_video.c    |    2 
 13 files changed, 3038 insertions(+), 2598 deletions(-)

New commits:
commit bd8021d46e9066e4cd116c03a7b7adcfe2557aff
Merge: 4f88dd8... 20d5dd3...
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 28 14:33:14 2009 -0500

    Merge branch 'atom-rework' and fix conflicts

diff --cc src/atombios_output.c
index 796aaed,2aa9ba5..0827d74
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@@ -610,290 -711,6 +711,289 @@@ atombios_output_dig_transmitter_setup(x
  
  }
  
 +static void atom_rv515_force_tv_scaler(ScrnInfoPtr pScrn)
 +{
 +    RADEONInfoPtr info       = RADEONPTR(pScrn);
 +    unsigned char *RADEONMMIO = info->MMIO;
 +
 +    OUTREG(0x659C,0x0);
 +    OUTREG(0x6594,0x705);
 +    OUTREG(0x65A4,0x10001);
 +    OUTREG(0x65D8,0x0);
 +    OUTREG(0x65B0,0x0);
 +    OUTREG(0x65C0,0x0);
 +    OUTREG(0x65D4,0x0);
 +    OUTREG(0x6578,0x0);
 +    OUTREG(0x657C,0x841880A8);
 +    OUTREG(0x6578,0x1);
 +    OUTREG(0x657C,0x84208680);
 +    OUTREG(0x6578,0x2);
 +    OUTREG(0x657C,0xBFF880B0);
 +    OUTREG(0x6578,0x100);
 +    OUTREG(0x657C,0x83D88088);
 +    OUTREG(0x6578,0x101);
 +    OUTREG(0x657C,0x84608680);
 +    OUTREG(0x6578,0x102);
 +    OUTREG(0x657C,0xBFF080D0);
 +    OUTREG(0x6578,0x200);
 +    OUTREG(0x657C,0x83988068);
 +    OUTREG(0x6578,0x201);
 +    OUTREG(0x657C,0x84A08680);
 +    OUTREG(0x6578,0x202);
 +    OUTREG(0x657C,0xBFF080F8);
 +    OUTREG(0x6578,0x300);
 +    OUTREG(0x657C,0x83588058);
 +    OUTREG(0x6578,0x301);
 +    OUTREG(0x657C,0x84E08660);
 +    OUTREG(0x6578,0x302);
 +    OUTREG(0x657C,0xBFF88120);
 +    OUTREG(0x6578,0x400);
 +    OUTREG(0x657C,0x83188040);
 +    OUTREG(0x6578,0x401);
 +    OUTREG(0x657C,0x85008660);
 +    OUTREG(0x6578,0x402);
 +    OUTREG(0x657C,0xBFF88150);
 +    OUTREG(0x6578,0x500);
 +    OUTREG(0x657C,0x82D88030);
 +    OUTREG(0x6578,0x501);
 +    OUTREG(0x657C,0x85408640);
 +    OUTREG(0x6578,0x502);
 +    OUTREG(0x657C,0xBFF88180);
 +    OUTREG(0x6578,0x600);
 +    OUTREG(0x657C,0x82A08018);
 +    OUTREG(0x6578,0x601);
 +    OUTREG(0x657C,0x85808620);
 +    OUTREG(0x6578,0x602);
 +    OUTREG(0x657C,0xBFF081B8);
 +    OUTREG(0x6578,0x700);
 +    OUTREG(0x657C,0x82608010);
 +    OUTREG(0x6578,0x701);
 +    OUTREG(0x657C,0x85A08600);
 +    OUTREG(0x6578,0x702);
 +    OUTREG(0x657C,0x800081F0);
 +    OUTREG(0x6578,0x800);
 +    OUTREG(0x657C,0x8228BFF8);
 +    OUTREG(0x6578,0x801);
 +    OUTREG(0x657C,0x85E085E0);
 +    OUTREG(0x6578,0x802);
 +    OUTREG(0x657C,0xBFF88228);
 +    OUTREG(0x6578,0x10000);
 +    OUTREG(0x657C,0x82A8BF00);
 +    OUTREG(0x6578,0x10001);
 +    OUTREG(0x657C,0x82A08CC0);
 +    OUTREG(0x6578,0x10002);
 +    OUTREG(0x657C,0x8008BEF8);
 +    OUTREG(0x6578,0x10100);
 +    OUTREG(0x657C,0x81F0BF28);
 +    OUTREG(0x6578,0x10101);
 +    OUTREG(0x657C,0x83608CA0);
 +    OUTREG(0x6578,0x10102);
 +    OUTREG(0x657C,0x8018BED0);
 +    OUTREG(0x6578,0x10200);
 +    OUTREG(0x657C,0x8148BF38);
 +    OUTREG(0x6578,0x10201);
 +    OUTREG(0x657C,0x84408C80);
 +    OUTREG(0x6578,0x10202);
 +    OUTREG(0x657C,0x8008BEB8);
 +    OUTREG(0x6578,0x10300);
 +    OUTREG(0x657C,0x80B0BF78);
 +    OUTREG(0x6578,0x10301);
 +    OUTREG(0x657C,0x85008C20);
 +    OUTREG(0x6578,0x10302);
 +    OUTREG(0x657C,0x8020BEA0);
 +    OUTREG(0x6578,0x10400);
 +    OUTREG(0x657C,0x8028BF90);
 +    OUTREG(0x6578,0x10401);
 +    OUTREG(0x657C,0x85E08BC0);
 +    OUTREG(0x6578,0x10402);
 +    OUTREG(0x657C,0x8018BE90);
 +    OUTREG(0x6578,0x10500);
 +    OUTREG(0x657C,0xBFB8BFB0);
 +    OUTREG(0x6578,0x10501);
 +    OUTREG(0x657C,0x86C08B40);
 +    OUTREG(0x6578,0x10502);
 +    OUTREG(0x657C,0x8010BE90);
 +    OUTREG(0x6578,0x10600);
 +    OUTREG(0x657C,0xBF58BFC8);
 +    OUTREG(0x6578,0x10601);
 +    OUTREG(0x657C,0x87A08AA0);
 +    OUTREG(0x6578,0x10602);
 +    OUTREG(0x657C,0x8010BE98);
 +    OUTREG(0x6578,0x10700);
 +    OUTREG(0x657C,0xBF10BFF0);
 +    OUTREG(0x6578,0x10701);
 +    OUTREG(0x657C,0x886089E0);
 +    OUTREG(0x6578,0x10702);
 +    OUTREG(0x657C,0x8018BEB0);
 +    OUTREG(0x6578,0x10800);
 +    OUTREG(0x657C,0xBED8BFE8);
 +    OUTREG(0x6578,0x10801);
 +    OUTREG(0x657C,0x89408940);
 +    OUTREG(0x6578,0x10802);
 +    OUTREG(0x657C,0xBFE8BED8);
 +    OUTREG(0x6578,0x20000);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20001);
 +    OUTREG(0x657C,0x90008000);
 +    OUTREG(0x6578,0x20002);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20003);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20100);
 +    OUTREG(0x657C,0x80108000);
 +    OUTREG(0x6578,0x20101);
 +    OUTREG(0x657C,0x8FE0BF70);
 +    OUTREG(0x6578,0x20102);
 +    OUTREG(0x657C,0xBFE880C0);
 +    OUTREG(0x6578,0x20103);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20200);
 +    OUTREG(0x657C,0x8018BFF8);
 +    OUTREG(0x6578,0x20201);
 +    OUTREG(0x657C,0x8F80BF08);
 +    OUTREG(0x6578,0x20202);
 +    OUTREG(0x657C,0xBFD081A0);
 +    OUTREG(0x6578,0x20203);
 +    OUTREG(0x657C,0xBFF88000);
 +    OUTREG(0x6578,0x20300);
 +    OUTREG(0x657C,0x80188000);
 +    OUTREG(0x6578,0x20301);
 +    OUTREG(0x657C,0x8EE0BEC0);
 +    OUTREG(0x6578,0x20302);
 +    OUTREG(0x657C,0xBFB082A0);
 +    OUTREG(0x6578,0x20303);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20400);
 +    OUTREG(0x657C,0x80188000);
 +    OUTREG(0x6578,0x20401);
 +    OUTREG(0x657C,0x8E00BEA0);
 +    OUTREG(0x6578,0x20402);
 +    OUTREG(0x657C,0xBF8883C0);
 +    OUTREG(0x6578,0x20403);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x20500);
 +    OUTREG(0x657C,0x80188000);
 +    OUTREG(0x6578,0x20501);
 +    OUTREG(0x657C,0x8D00BE90);
 +    OUTREG(0x6578,0x20502);
 +    OUTREG(0x657C,0xBF588500);
 +    OUTREG(0x6578,0x20503);
 +    OUTREG(0x657C,0x80008008);
 +    OUTREG(0x6578,0x20600);
 +    OUTREG(0x657C,0x80188000);
 +    OUTREG(0x6578,0x20601);
 +    OUTREG(0x657C,0x8BC0BE98);
 +    OUTREG(0x6578,0x20602);
 +    OUTREG(0x657C,0xBF308660);
 +    OUTREG(0x6578,0x20603);
 +    OUTREG(0x657C,0x80008008);
 +    OUTREG(0x6578,0x20700);
 +    OUTREG(0x657C,0x80108000);
 +    OUTREG(0x6578,0x20701);
 +    OUTREG(0x657C,0x8A80BEB0);
 +    OUTREG(0x6578,0x20702);
 +    OUTREG(0x657C,0xBF0087C0);
 +    OUTREG(0x6578,0x20703);
 +    OUTREG(0x657C,0x80008008);
 +    OUTREG(0x6578,0x20800);
 +    OUTREG(0x657C,0x80108000);
 +    OUTREG(0x6578,0x20801);
 +    OUTREG(0x657C,0x8920BED0);
 +    OUTREG(0x6578,0x20802);
 +    OUTREG(0x657C,0xBED08920);
 +    OUTREG(0x6578,0x20803);
 +    OUTREG(0x657C,0x80008010);
 +    OUTREG(0x6578,0x30000);
 +    OUTREG(0x657C,0x90008000);
 +    OUTREG(0x6578,0x30001);
 +    OUTREG(0x657C,0x80008000);
 +    OUTREG(0x6578,0x30100);
 +    OUTREG(0x657C,0x8FE0BF90);
 +    OUTREG(0x6578,0x30101);
 +    OUTREG(0x657C,0xBFF880A0);
 +    OUTREG(0x6578,0x30200);
 +    OUTREG(0x657C,0x8F60BF40);
 +    OUTREG(0x6578,0x30201);
 +    OUTREG(0x657C,0xBFE88180);
 +    OUTREG(0x6578,0x30300);
 +    OUTREG(0x657C,0x8EC0BF00);
 +    OUTREG(0x6578,0x30301);
 +    OUTREG(0x657C,0xBFC88280);
 +    OUTREG(0x6578,0x30400);
 +    OUTREG(0x657C,0x8DE0BEE0);
 +    OUTREG(0x6578,0x30401);
 +    OUTREG(0x657C,0xBFA083A0);
 +    OUTREG(0x6578,0x30500);
 +    OUTREG(0x657C,0x8CE0BED0);
 +    OUTREG(0x6578,0x30501);
 +    OUTREG(0x657C,0xBF7884E0);
 +    OUTREG(0x6578,0x30600);
 +    OUTREG(0x657C,0x8BA0BED8);
 +    OUTREG(0x6578,0x30601);
 +    OUTREG(0x657C,0xBF508640);
 +    OUTREG(0x6578,0x30700);
 +    OUTREG(0x657C,0x8A60BEE8);
 +    OUTREG(0x6578,0x30701);
 +    OUTREG(0x657C,0xBF2087A0);
 +    OUTREG(0x6578,0x30800);
 +    OUTREG(0x657C,0x8900BF00);
 +    OUTREG(0x6578,0x30801);
 +    OUTREG(0x657C,0xBF008900);
 +}
 +
 +static int
 +atombios_output_yuv_setup(xf86OutputPtr output, Bool enable)
 +{
 +    RADEONOutputPrivatePtr radeon_output = output->driver_private;
 +    RADEONInfoPtr info       = RADEONPTR(output->scrn);
 +    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
 +    ENABLE_YUV_PS_ALLOCATION disp_data;
 +    AtomBiosArgRec data;
 +    unsigned char *space;
 +    unsigned char *RADEONMMIO = info->MMIO;
 +    uint32_t temp, reg;
 +
 +    if (info->ChipFamily >= CHIP_FAMILY_R600)
 +	reg = R600_BIOS_3_SCRATCH;
 +    else
 +	reg = RADEON_BIOS_3_SCRATCH;
 +
 +    //fix up scratch reg handling
 +    temp = INREG(reg);
-     if ((radeon_output->MonType == MT_CTV) ||
- 	(radeon_output->MonType == MT_STV))
++    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
 +	OUTREG(reg, (ATOM_S3_TV1_ACTIVE |
 +		     (radeon_crtc->crtc_id << 18)));
-     else if (radeon_output->MonType == MT_CV)
++    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 +	OUTREG(reg, (ATOM_S3_CV_ACTIVE |
 +		     (radeon_crtc->crtc_id << 24)));
 +    else
 +	OUTREG(reg, 0);
 +
 +    memset(&disp_data, 0, sizeof(disp_data));
 +
 +    if (enable)
 +	disp_data.ucEnable = ATOM_ENABLE;
 +    disp_data.ucCRTC = radeon_crtc->crtc_id;
 +
 +    data.exec.index = GetIndexIntoMasterTable(COMMAND, EnableYUV);
 +    data.exec.dataSpace = (void *)&space;
 +    data.exec.pspace = &disp_data;
 +
 +    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
 +
 +	OUTREG(reg, temp);
 +
 +	ErrorF("crtc %d YUV %s setup success\n", radeon_crtc->crtc_id, enable ? "enable" : "disable");
 +	return ATOM_SUCCESS;
 +    }
 +
 +    OUTREG(reg, temp);
 +
 +    ErrorF("crtc %d YUV %s setup failed\n", radeon_crtc->crtc_id, enable ? "enable" : "disable");
 +    return ATOM_NOT_IMPLEMENTED;
 +
 +}
 +
  static int
  atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
  {
@@@ -957,11 -778,6 +1061,11 @@@
      data.exec.pspace = &disp_data;
  
      if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- 	if (OUTPUT_IS_TV && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) {
++	if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)
++	    && info->ChipFamily >= CHIP_FAMILY_RV515 && info->ChipFamily <= CHIP_FAMILY_RV570) {
 +	    ErrorF("forcing TV scaler\n");
 +	    atom_rv515_force_tv_scaler(output->scrn);
 +	}
-       
  	ErrorF("scaler %d setup success\n", radeon_crtc->crtc_id);
  	return ATOM_SUCCESS;
      }
@@@ -1306,71 -1102,38 +1390,42 @@@ atombios_output_mode_set(xf86OutputPtr 
  
      atombios_output_scaler_setup(output, mode);
      atombios_set_output_crtc_source(output);
-     if ((radeon_output->MonType == MT_CTV) ||
- 	(radeon_output->MonType == MT_STV) ||
- 	(radeon_output->MonType == MT_CV))
++    if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT))
 +	atombios_output_yuv_setup(output, TRUE);
 +    else
 +	atombios_output_yuv_setup(output, FALSE);
  
-     if (radeon_output->MonType == MT_CRT) {
-        if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT ||
- 	   radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
- 	   if (radeon_output->DACType == DAC_PRIMARY)
- 	       atombios_output_dac1_setup(output, adjusted_mode);
- 	   else if (radeon_output->DACType == DAC_TVDAC)
- 	       atombios_output_dac2_setup(output, adjusted_mode);
-        }
-     } else if (radeon_output->MonType == MT_DFP) {
- 	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
- 	    if (IS_DCE3_VARIANT) {
- 		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
- 		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
- 	    } else
- 		atombios_output_digital_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
- 	} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
- 	    if (IS_DCE32_VARIANT) {
- 		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode);
- 		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode);
- 	    } else {
- 		if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
- 		    (info->ChipFamily == CHIP_FAMILY_RS690) ||
- 		    (info->ChipFamily == CHIP_FAMILY_RS740))
- 		    atombios_output_ddia_setup(output, adjusted_mode);
- 		else
- 		    atombios_external_tmds_setup(output, adjusted_mode);
- 	    }
- 	} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
- 	    if (IS_DCE3_VARIANT) {
- 		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
- 		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
- 	    } else
- 		atombios_output_digital_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
- 	} else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) {
- 	    atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode);
- 	    atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode);
- 	} else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) {
- 	    atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode);
- 	    atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode);
- 	}
-     } else if (radeon_output->MonType == MT_LCD) {
- 	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
- 	    if (IS_DCE3_VARIANT) {
- 		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
- 		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
- 	    } else
- 		atombios_output_digital_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
- 	}
-     } else if ((radeon_output->MonType == MT_CTV) ||
- 	       (radeon_output->MonType == MT_STV) ||
- 	       (radeon_output->MonType == MT_CV)) {
- 	if (radeon_output->DACType == DAC_PRIMARY)
- 	    atombios_output_dac1_setup(output, adjusted_mode);
- 	else if (radeon_output->DACType == DAC_TVDAC)
- 	    atombios_output_dac2_setup(output, adjusted_mode);
- 	atombios_output_tv1_setup(output, adjusted_mode);
+     switch (radeon_encoder->encoder_id) {
+     case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+     case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+     case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+ 	atombios_output_digital_setup(output, adjusted_mode);
+ 	break;
+     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+ 	atombios_output_dig_encoder_setup(output, adjusted_mode);
+ 	atombios_output_dig_transmitter_setup(output, adjusted_mode);
+ 	break;
+     case ENCODER_OBJECT_ID_INTERNAL_DDI:
+ 	atombios_output_ddia_setup(output, adjusted_mode);
+ 	break;
+     case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+ 	atombios_external_tmds_setup(output, adjusted_mode);
+ 	break;
+     case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+     case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+ 	atombios_output_dac_setup(output, adjusted_mode);
+ 	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
+ 	    atombios_output_tv_setup(output, adjusted_mode);
+ 	break;
      }
-     atombios_apply_output_quirks(output);
+     atombios_apply_output_quirks(output, adjusted_mode);
  }
  
  static AtomBiosResult
diff --cc src/radeon_output.c
index dae4e1b,fd94e2c..ba4cb7f
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@@ -426,11 -387,9 +387,11 @@@ radeon_mode_valid(xf86OutputPtr output
  	    return MODE_BANDWIDTH;
      }
  
-     if (OUTPUT_IS_TV) {
- 	/* FIXME: Update when more modes are added */
- 	if (IS_AVIVO_VARIANT) {
+     if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 -	/* FIXME: Update when more modes are added */
 -	if (!info->IsAtomBios) {
++	if (IS_AVIVO_VARIANT)
 +	    return MODE_OK;
- 	} else {
++	else {
++	    /* FIXME: Update when more modes are added */
  	    if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
  		return MODE_OK;
  	    else
commit 20d5dd387da555e895e2b73fb53e2b026dd91003
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 28 14:12:26 2009 -0500

    Move encoder specific data to encoder dev_priv

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index cebd328..212208e 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -361,12 +361,13 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr output = xf86_config->output[i];
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
 
 	if (output->crtc == crtc) {
 	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
-		if (radeon_output->tvStd == TV_STD_NTSC ||
-		    radeon_output->tvStd == TV_STD_NTSC_J ||
-		    radeon_output->tvStd == TV_STD_PAL_M)
+		if (tvout->tvStd == TV_STD_NTSC ||
+		    tvout->tvStd == TV_STD_NTSC_J ||
+		    tvout->tvStd == TV_STD_PAL_M)
 		    need_tv_timings = 1;
 		else
 		    need_tv_timings = 2;
diff --git a/src/atombios_output.c b/src/atombios_output.c
index c8548db..2aa9ba5 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -66,6 +66,7 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
@@ -96,7 +97,7 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
     else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.ucDacStandard = ATOM_DAC1_CV;
     else {
-	switch (radeon_output->tvStd) {
+	switch (tvout->tvStd) {
 	case TV_STD_PAL:
 	case TV_STD_PAL_M:
 	case TV_STD_SCART_PAL:
@@ -132,6 +133,7 @@ static int
 atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     TV_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
@@ -144,7 +146,7 @@ atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode)
     if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
     else {
-	switch (radeon_output->tvStd) {
+	switch (tvout->tvStd) {
 	case TV_STD_NTSC:
 	    disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC;
 	    break;
@@ -264,10 +266,18 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
     unsigned char *space;
     int index;
     int major, minor;
+    int lvds_misc = 0;
 
     if (radeon_encoder == NULL)
 	return ATOM_NOT_IMPLEMENTED;
 
+    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+	radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
+	if (lvds == NULL)
+	    return ATOM_NOT_IMPLEMENTED;
+	lvds_misc = lvds->lvds_misc;
+    }
+
     memset(&disp_data,0, sizeof(disp_data));
     memset(&disp_data2,0, sizeof(disp_data2));
 
@@ -304,9 +314,9 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
 	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-		if (radeon_output->lvds_misc & (1 << 0))
+		if (lvds_misc & (1 << 0))
 		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-		if (radeon_output->lvds_misc & (1 << 1))
+		if (lvds_misc & (1 << 1))
 		    disp_data.ucMisc |= (1 << 1);
 	    } else {
 		if (radeon_output->linkb)
@@ -337,18 +347,18 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    disp_data2.ucTemporal = 0;
 	    disp_data2.ucFRC = 0;
 	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-		if (radeon_output->lvds_misc & (1 << 0))
+		if (lvds_misc & (1 << 0))
 		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
-		if (radeon_output->lvds_misc & (1 << 5)) {
+		if (lvds_misc & (1 << 5)) {
 		    disp_data2.ucSpatial = PANEL_ENCODER_SPATIAL_DITHER_EN;
-		    if (radeon_output->lvds_misc & (1 << 1))
+		    if (lvds_misc & (1 << 1))
 			disp_data2.ucSpatial |= PANEL_ENCODER_SPATIAL_DITHER_DEPTH;
 		}
-		if (radeon_output->lvds_misc & (1 << 6)) {
+		if (lvds_misc & (1 << 6)) {
 		    disp_data2.ucTemporal = PANEL_ENCODER_TEMPORAL_DITHER_EN;
-		    if (radeon_output->lvds_misc & (1 << 1))
+		    if (lvds_misc & (1 << 1))
 			disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_DITHER_DEPTH;
-		    if (((radeon_output->lvds_misc >> 2) & 0x3) == 2)
+		    if (((lvds_misc >> 2) & 0x3) == 2)
 			disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
 		}
 	    } else {
@@ -706,6 +716,7 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
     ENABLE_SCALER_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
@@ -716,7 +727,7 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
     disp_data.ucScaler = radeon_crtc->crtc_id;
 
     if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
-	switch (radeon_output->tvStd) {
+	switch (tvout->tvStd) {
 	case TV_STD_NTSC:
 	    disp_data.ucTVStandard = ATOM_TV_NTSC;
 	    break;
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 8ec6db2..82291e5 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -56,7 +56,7 @@ static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
 
 extern Bool
-RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo);
+RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus);
 
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
 {
@@ -105,84 +105,144 @@ static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] =
 };
 
 void
-RADEONGetTVDacAdjInfo(xf86OutputPtr output)
+RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (!RADEONGetDAC2InfoFromBIOS(output)) {
-	radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
+    if (!RADEONGetDAC2InfoFromBIOS(pScrn, tvdac)) {
+	tvdac->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
 	if (info->IsMobility) { /* some mobility chips may different */
 	    if (info->ChipFamily == CHIP_FAMILY_RV250)
-		radeon_output->ps2_tvdac_adj = 0x00880000;
+		tvdac->ps2_tvdac_adj = 0x00880000;
 	}
-	radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
-	radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+	tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj;
+	tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj;
     }
 }
 
 void
-RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
+RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i;
 
-    for (i=0; i<4; i++) {
-        radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
-        radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+    for (i = 0; i < 4; i++) {
+        tmds->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+        tmds->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
     }
 }
 
 void
-RADEONGetTMDSInfo(xf86OutputPtr output)
+RADEONGetTMDSInfo(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds)
 {
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i;
 
-    for (i=0; i<4; i++) {
-	radeon_output->tmds_pll[i].value = 0;
-	radeon_output->tmds_pll[i].freq = 0;
+    for (i = 0; i < 4; i++) {
+	tmds->tmds_pll[i].value = 0;
+	tmds->tmds_pll[i].freq = 0;
     }
 
-    if (!RADEONGetTMDSInfoFromBIOS(output))
-	RADEONGetTMDSInfoFromTable(output);
+    if (!RADEONGetTMDSInfoFromBIOS(pScrn, tmds))
+	RADEONGetTMDSInfoFromTable(pScrn, tmds);
 }
 
 void
-RADEONGetExtTMDSInfo(xf86OutputPtr output)
+RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     I2CBusPtr pDVOBus;
-    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
-
-    if (radeon_encoder == NULL)
-	return;
 
     if (!info->IsAtomBios) {
 #if defined(__powerpc__)
-	radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
-	radeon_output->dvo_i2c_slave_addr = 0x70;
+	dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+	dvo->dvo_i2c_slave_addr = 0x70;
 #else
-	if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
-	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-	    radeon_output->dvo_i2c_slave_addr = 0x70;
+	if (!RADEONGetExtTMDSInfoFromBIOS(pScrn, dvo)) {
+	    dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+	    dvo->dvo_i2c_slave_addr = 0x70;
 	}
 #endif
-	if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
-	    radeon_output->DVOChip =
-		RADEONDVODeviceInit(pDVOBus,
-				    radeon_output->dvo_i2c_slave_addr);
-	    if (!radeon_output->DVOChip)
+	if (RADEONI2CInit(pScrn, &pDVOBus, "DVO", &dvo->dvo_i2c)) {
+	    dvo->DVOChip =
+		RADEONDVODeviceInit(pDVOBus, dvo->dvo_i2c_slave_addr);
+	    if (!dvo->DVOChip)
 		xfree(pDVOBus);
 	}
     }
 }
 
+static void
+RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    radeon_native_mode_ptr native_mode = &lvds->native_mode;
+    uint32_t fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+    uint32_t fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
+
+    lvds->PanelPwrDly = 200;
+    if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
+	native_mode->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
+				  RADEON_VERT_PANEL_SHIFT) + 1;
+    } else {
+	native_mode->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
+    }
+    if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
+	native_mode->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
+				   RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
+    } else {
+	native_mode->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+    }
+
+    if ((native_mode->PanelXRes < 640) || (native_mode->PanelYRes < 480)) {
+	native_mode->PanelXRes = 640;
+	native_mode->PanelYRes = 480;
+    }
+
+    // move this to crtc function
+    if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
+           uint32_t ppll_div_sel, ppll_val;
+
+           ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+	   RADEONPllErrataAfterIndex(info);
+	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
+           if ((ppll_val & 0x000707ff) == 0x1bb)
+		   goto noprobe;
+	   info->FeedbackDivider = ppll_val & 0x7ff;
+	   info->PostDivider = (ppll_val >> 16) & 0x7;
+	   info->RefDivider = info->pll.reference_div;
+	   info->UseBiosDividers = TRUE;
+
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                      "Existing panel PLL dividers will be used.\n");
+    }
+ noprobe:
+
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "Panel size %dx%d is derived, this may not be correct.\n"
+		   "If not, use PanelSize option to overwrite this setting\n",
+	       native_mode->PanelXRes, native_mode->PanelYRes);
+}
+
+void
+RADEONGetLVDSInfo (ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    radeon_native_mode_ptr native_mode = &lvds->native_mode;
+    char* s;
+
+    if (!RADEONGetLVDSInfoFromBIOS(pScrn, lvds))
+	RADEONGetPanelInfoFromReg(pScrn, lvds);
+
+    if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
+	lvds->PanelPwrDly = 200;
+	if (sscanf (s, "%dx%d", &native_mode->PanelXRes, &native_mode->PanelYRes) != 2) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
+	    RADEONGetPanelInfoFromReg(pScrn, lvds);
+	}
+    }
+}
+
 void
 RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
 			  RADEONSavePtr restore)
@@ -407,34 +467,43 @@ static void
 RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_dvo_ptr dvo = NULL;
+
+    if (radeon_encoder == NULL)
+	return;
 
-    if (!radeon_output->DVOChip)
+    dvo = (radeon_dvo_ptr)radeon_encoder->dev_priv;
+
+    if (dvo == NULL)
+	return;
+
+    if (!dvo->DVOChip)
 	return;
 
     RADEONI2CDoLock(output, TRUE);
     if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
-	if (radeon_output->DVOChip) {
+	if (dvo->DVOChip) {
 	    switch(info->ext_tmds_chip) {
 	    case RADEON_SIL_164:
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x30);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x09, 0x00);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0a, 0x90);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0c, 0x89);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x3b);
 		break;
 #if 0
 		/* needs work see bug 10418 */
 	    case RADEON_SIL_1178:
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
-		RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
-                RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0f, 0x44);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0f, 0x4c);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0e, 0x01);
+		RADEONDVOWriteByte(dvo->DVOChip, 0x0a, 0x80);
+                RADEONDVOWriteByte(dvo->DVOChip, 0x09, 0x30);
+                RADEONDVOWriteByte(dvo->DVOChip, 0x0c, 0xc9);
+                RADEONDVOWriteByte(dvo->DVOChip, 0x0d, 0x70);
+                RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x32);
+                RADEONDVOWriteByte(dvo->DVOChip, 0x08, 0x33);
 		break;
 #endif
 	    default:
@@ -836,15 +905,20 @@ legacy_output_dpms(xf86OutputPtr output, int mode)
     case DPMSModeOn:
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	{
+	    radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
+	    if (lvds == NULL)
+		return;
 	    ErrorF("enable LVDS\n");
 	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
 	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
 	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
-	    usleep (radeon_output->PanelPwrDly * 1000);
+	    usleep (lvds->PanelPwrDly * 1000);
 	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
 	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
 	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
-	    break;
+	}
+	break;
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	    ErrorF("enable FP1\n");
 	    tmp = INREG(RADEON_FP_GEN_CNTL);
@@ -892,6 +966,7 @@ legacy_output_dpms(xf86OutputPtr output, int mode)
 		tmp = INREG(RADEON_TV_MASTER_CNTL);
 		tmp |= RADEON_TV_ON;
 		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+		radeon_output->tvout.tv_on = TRUE;
 	    } else {
 		ErrorF("enable TVDAC\n");
 		if (info->ChipFamily == CHIP_FAMILY_R200) {
@@ -990,7 +1065,7 @@ legacy_output_dpms(xf86OutputPtr output, int mode)
 		    tmp = INREG(RADEON_TV_MASTER_CNTL);
 		    tmp &= ~RADEON_TV_ON;
 		    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-		    radeon_output->tv_on = FALSE;
+		    radeon_output->tvout.tv_on = FALSE;
 		} else {
 		    ErrorF("disable TVDAC\n");
 		    if (info->ChipFamily == CHIP_FAMILY_R200) {
@@ -1023,13 +1098,24 @@ RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_tmds_ptr tmds = NULL;
     int i;
     uint32_t tmp = info->SavedReg->tmds_pll_cntl & 0xfffff;
 
-    for (i=0; i<4; i++) {
-	if (radeon_output->tmds_pll[i].freq == 0) break;
-	if ((uint32_t)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
-	    tmp = radeon_output->tmds_pll[i].value ;
+    if (radeon_encoder == NULL)
+	return;
+
+    tmds = (radeon_tmds_ptr)radeon_encoder->dev_priv;
+
+    if (tmds == NULL)
+	return;
+
+    for (i = 0; i < 4; i++) {
+	if (tmds->tmds_pll[i].freq == 0)
+	    break;
+	if ((uint32_t)(mode->Clock / 10) < tmds->tmds_pll[i].freq) {
+	    tmp = tmds->tmds_pll[i].value ;
 	    break;
 	}
     }
@@ -1233,6 +1319,7 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
     int    xres = mode->HDisplay;
     int    yres = mode->VDisplay;
     Bool   Hscale = TRUE, Vscale = TRUE;
@@ -1289,18 +1376,18 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
     if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) ||
 	(radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
 
-	ErrorF("RMX for DFP/LCD\n");
-
-	if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
+	if (native_mode->PanelXRes == 0 || native_mode->PanelYRes == 0) {
 	    Hscale = FALSE;
 	    Vscale = FALSE;
 	} else {
-	    if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
-	    if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
+	    if (xres > native_mode->PanelXRes)
+		xres = native_mode->PanelXRes;
+	    if (yres > native_mode->PanelYRes)
+		yres = native_mode->PanelYRes;
 
-	    if (xres == radeon_output->PanelXRes)
+	    if (xres == native_mode->PanelXRes)
 		Hscale = FALSE;
-	    if (yres == radeon_output->PanelYRes)
+	    if (yres == native_mode->PanelYRes)
 		Vscale = FALSE;
 	}
 
@@ -1308,28 +1395,28 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
 	    (radeon_output->rmx_type == RMX_CENTER)) {
 	    save->fp_horz_stretch |= ((xres/8-1)<<16);
 	} else {
-	    CARD32 scale, inc;
+	    uint32_t scale, inc;
 	    inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
 	    scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
-		/ radeon_output->PanelXRes + 1;
+		/ native_mode->PanelXRes + 1;
 	    save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
 				      RADEON_HORZ_STRETCH_BLEND |
 				      RADEON_HORZ_STRETCH_ENABLE |
-				      ((radeon_output->PanelXRes/8-1)<<16));
+				      ((native_mode->PanelXRes/8-1)<<16));
 	}
 
 	if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
 	    (radeon_output->rmx_type == RMX_CENTER)) {
 	    save->fp_vert_stretch |= ((yres-1)<<12);
 	} else {
-	    CARD32 scale, inc;
+	    uint32_t scale, inc;
 	    inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
 	    scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
-		/ radeon_output->PanelYRes + 1;
+		/ native_mode->PanelYRes + 1;
 	    save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
 				      RADEON_VERT_STRETCH_ENABLE |
 				      RADEON_VERT_STRETCH_BLEND |
-				      ((radeon_output->PanelYRes-1)<<12));
+				      ((native_mode->PanelYRes-1)<<12));
 	}
 
 	if ((radeon_output->rmx_type == RMX_CENTER) &&
@@ -1370,8 +1457,8 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
 					    ? RADEON_CRTC_V_SYNC_POL
 					    : 0)));
 
-	    save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) |
-					 (((radeon_output->PanelXRes / 8) & 0x1ff) << 16));
+	    save->fp_horz_vert_active = (((native_mode->PanelYRes) & 0xfff) |
+					 (((native_mode->PanelXRes / 8) & 0x1ff) << 16));
 
 	}
     }
@@ -1412,7 +1499,16 @@ RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_tvdac_ptr tvdac = NULL;
+
+    if (radeon_encoder == NULL)
+	return;
+
+    tvdac = (radeon_tvdac_ptr)radeon_encoder->dev_priv;
+
+    if (tvdac == NULL)
+	return;
 
     if (info->ChipFamily == CHIP_FAMILY_R420 ||
 	info->ChipFamily == CHIP_FAMILY_RV410) {
@@ -1437,7 +1533,7 @@ RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
     save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
 			  RADEON_TV_DAC_NHOLD |
 			  RADEON_TV_DAC_STD_PS2 |
-			  radeon_output->ps2_tvdac_adj);
+			  tvdac->ps2_tvdac_adj);
 
 }
 
diff --git a/src/radeon.h b/src/radeon.h
index 9b724ec..66b2330 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -881,6 +881,12 @@ extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
 extern void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 extern void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 
+extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac);
+extern void RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds);
+extern void RADEONGetTMDSInfo(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds);
+extern void RADEONGetExtTMDSInfo(ScrnInfoPtr pScrn, radeon_dvo_ptr dvo);
+extern void RADEONGetLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds);
+
 /* radeon_accel.c */
 extern Bool RADEONAccelInit(ScreenPtr pScreen);
 extern void RADEONEngineFlush(ScrnInfoPtr pScrn);
@@ -923,12 +929,12 @@ extern Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen);
 extern Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10);
 extern Bool RADEONGetClockInfoFromBIOS(ScrnInfoPtr pScrn);
 extern Bool RADEONGetConnectorInfoFromBIOS(ScrnInfoPtr pScrn);
-extern Bool RADEONGetDAC2InfoFromBIOS(xf86OutputPtr output);
-extern Bool RADEONGetExtTMDSInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetDAC2InfoFromBIOS(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac);
+extern Bool RADEONGetExtTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_dvo_ptr dvo);
 extern xf86MonPtr RADEONGetHardCodedEDIDFromBIOS(xf86OutputPtr output);
 extern Bool RADEONGetBIOSInitTableOffsets(ScrnInfoPtr pScrn);
-extern Bool RADEONGetLVDSInfoFromBIOS(xf86OutputPtr output);
-extern Bool RADEONGetTMDSInfoFromBIOS(xf86OutputPtr output);
+extern Bool RADEONGetLVDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds);
+extern Bool RADEONGetTMDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds);
 extern Bool RADEONGetTVInfoFromBIOS(xf86OutputPtr output);
 extern Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool RADEONPostCardFromBIOSTables(ScrnInfoPtr pScrn);
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index d7d5f7c..b2eea7d 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -77,6 +77,10 @@ rhdAtomCompassionateDataQuery(atomBiosHandlePtr handle,
 			      AtomBiosRequestID func, AtomBiosArgPtr data);
 
 
+static void
+RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds);
+
+
 enum msgDataFormat {
     MSG_FORMAT_NONE,
     MSG_FORMAT_HEX,
@@ -1612,6 +1616,25 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
 	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	    if ((info->encoders[i] != NULL) && (info->encoders[i]->encoder_id == encoder_id)) {
 		info->encoders[device_index] = info->encoders[i];
+		switch (encoder_id) {
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+		case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		    if (device_support & ATOM_DEVICE_LCD1_SUPPORT) {
+			if (info->encoders[device_index]->dev_priv == NULL) {
+			    info->encoders[device_index]->dev_priv =
+				(radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+			    if (info->encoders[device_index]->dev_priv == NULL) {
+				ErrorF("xalloc failed\n");
+				return FALSE;
+			    } else
+				RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
+			}
+		    }
+		    break;
+		}
 		return TRUE;
 	    }
 	}
@@ -1620,7 +1643,66 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
 	if (info->encoders[device_index] != NULL) {
 	    info->encoders[device_index]->encoder_id = encoder_id;
 	    info->encoders[device_index]->use_count = 0;
+	    info->encoders[device_index]->dev_priv = NULL;
 	    // add dev_priv stuff
+	    switch (encoder_id) {
+	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+		    info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+		    if (info->encoders[device_index]->dev_priv == NULL) {
+			ErrorF("xalloc failed\n");
+			return FALSE;
+		    } else {
+			if (info->IsAtomBios)
+			    RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
+			else
+			    RADEONGetLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
+		    }
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+		if (!IS_AVIVO_VARIANT) {
+		    info->encoders[device_index]->dev_priv = (radeon_tvdac_ptr)xcalloc(1,sizeof(radeon_tvdac_rec));
+		    if (info->encoders[device_index]->dev_priv == NULL) {
+			ErrorF("xalloc failed\n");
+			return FALSE;
+		    } else
+			RADEONGetTVDacAdjInfo(pScrn, (radeon_tvdac_ptr)info->encoders[device_index]->dev_priv);
+		}
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+		if (!IS_AVIVO_VARIANT) {
+		    info->encoders[device_index]->dev_priv = (radeon_tmds_ptr)xcalloc(1,sizeof(radeon_tmds_rec));
+		    if (info->encoders[device_index]->dev_priv == NULL) {
+			ErrorF("xalloc failed\n");
+			return FALSE;
+		    } else
+			RADEONGetTMDSInfo(pScrn, (radeon_tmds_ptr)info->encoders[device_index]->dev_priv);
+		}
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+		if (!IS_AVIVO_VARIANT) {
+		    info->encoders[device_index]->dev_priv = (radeon_dvo_ptr)xcalloc(1,sizeof(radeon_dvo_rec));
+		    if (info->encoders[device_index]->dev_priv == NULL) {
+			ErrorF("xalloc failed\n");
+			return FALSE;
+		    } else
+			RADEONGetExtTMDSInfo(pScrn, (radeon_dvo_ptr)info->encoders[device_index]->dev_priv);
+		}
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		if (device_support & ATOM_DEVICE_LCD1_SUPPORT) {
+		    info->encoders[device_index]->dev_priv = (radeon_lvds_ptr)xcalloc(1,sizeof(radeon_lvds_rec));
+		    if (info->encoders[device_index]->dev_priv == NULL) {
+			ErrorF("xalloc failed\n");
+			return FALSE;
+		    } else
+			RADEONGetATOMLVDSInfo(pScrn, (radeon_lvds_ptr)info->encoders[device_index]->dev_priv);
+		}
+		break;
+	    }
 	    return TRUE;
 	} else {
 	    ErrorF("xalloc failed\n");
@@ -1793,12 +1875,11 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     return TRUE;
 }
 
-Bool
-RADEONGetATOMLVDSInfo(xf86OutputPtr output)
+static void
+RADEONGetATOMLVDSInfo(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &lvds->native_mode;
     atomDataTablesPtr atomDataPtr;
     uint8_t crev, frev;
 
@@ -1807,55 +1888,52 @@ RADEONGetATOMLVDSInfo(xf86OutputPtr output)
     if (!rhdAtomGetTableRevisionAndSize(
 	    (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->LVDS_Info.base),
 	    &frev,&crev,NULL)) {
-	return FALSE;
+	return;
     }
 
     switch (crev) {
     case 1:
-	radeon_output->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHActive);
-	radeon_output->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVActive);
-	radeon_output->DotClock   = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usPixClk) * 10;
-	radeon_output->HBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHBlanking_Time);
-	radeon_output->HOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncOffset);
-	radeon_output->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncWidth);
-	radeon_output->VBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time);
-	radeon_output->VOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset);
-	radeon_output->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth);
-	radeon_output->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs);
-	radeon_output->lvds_misc   =  atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc;
-	radeon_output->lvds_ss_id  =  atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id;
+	native_mode->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHActive);
+	native_mode->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVActive);
+	native_mode->DotClock   = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usPixClk) * 10;
+	native_mode->HBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHBlanking_Time);
+	native_mode->HOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncOffset);
+	native_mode->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usHSyncWidth);
+	native_mode->VBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVBlanking_Time);
+	native_mode->VOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncOffset);
+	native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->sLCDTiming.usVSyncWidth);
+	lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info->usOffDelayInMs);
+	lvds->lvds_misc   =  atomDataPtr->LVDS_Info.LVDS_Info->ucLVDS_Misc;
+	lvds->lvds_ss_id  =  atomDataPtr->LVDS_Info.LVDS_Info->ucSS_Id;
 	break;
     case 2:
-	radeon_output->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHActive);
-	radeon_output->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVActive);
-	radeon_output->DotClock   = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usPixClk) * 10;
-	radeon_output->HBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHBlanking_Time);
-	radeon_output->HOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncOffset);
-	radeon_output->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncWidth);
-	radeon_output->VBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time);
-	radeon_output->VOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset);
-	radeon_output->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth);
-	radeon_output->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs);
-	radeon_output->lvds_misc   =  atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc;
-	radeon_output->lvds_ss_id  =  atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id;
+	native_mode->PanelXRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHActive);
+	native_mode->PanelYRes = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVActive);
+	native_mode->DotClock   = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usPixClk) * 10;
+	native_mode->HBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHBlanking_Time);
+	native_mode->HOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncOffset);
+	native_mode->HSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usHSyncWidth);
+	native_mode->VBlank     = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVBlanking_Time);
+	native_mode->VOverPlus  = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncOffset);
+	native_mode->VSyncWidth = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->sLCDTiming.usVSyncWidth);
+	lvds->PanelPwrDly = le16_to_cpu(atomDataPtr->LVDS_Info.LVDS_Info_v12->usOffDelayInMs);
+	lvds->lvds_misc   =  atomDataPtr->LVDS_Info.LVDS_Info_v12->ucLVDS_Misc;
+	lvds->lvds_ss_id  =  atomDataPtr->LVDS_Info.LVDS_Info_v12->ucSS_Id;
 	break;
     }
+    native_mode->Flags = 0;
 
-    if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
-	radeon_output->PanelPwrDly = 2000;
-
-    radeon_output->Flags = 0;
+    if (lvds->PanelPwrDly > 2000 || lvds->PanelPwrDly < 0)
+	lvds->PanelPwrDly = 2000;
 
     xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 	       "LVDS Info:\n"
 	       "XRes: %d, YRes: %d, DotClock: %d\n"
 	       "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
 	       "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
-	       radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
-	       radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
-	       radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
-
-    return TRUE;
+	       native_mode->PanelXRes, native_mode->PanelYRes, native_mode->DotClock,
+	       native_mode->HBlank, native_mode->HOverPlus, native_mode->HSyncWidth,
+	       native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth);
 }
 
 Bool
@@ -1864,6 +1942,7 @@ RADEONGetATOMTVInfo(xf86OutputPtr output)
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     ATOM_ANALOG_TV_INFO *tv_info;
 
     tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info.AnalogTV_Info;
@@ -1873,51 +1952,51 @@ RADEONGetATOMTVInfo(xf86OutputPtr output)
 
     switch(tv_info->ucTV_BootUpDefaultStandard) {
     case NTSCJ_SUPPORT:
-	radeon_output->default_tvStd = TV_STD_NTSC_J;
+	tvout->default_tvStd = TV_STD_NTSC_J;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
 	break;
     case PAL_SUPPORT:
-	radeon_output->default_tvStd = TV_STD_PAL;
+	tvout->default_tvStd = TV_STD_PAL;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
 	break;
     case PALM_SUPPORT:
-	radeon_output->default_tvStd = TV_STD_PAL_M;
+	tvout->default_tvStd = TV_STD_PAL_M;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
 	break;
     case PAL60_SUPPORT:
-	radeon_output->default_tvStd = TV_STD_PAL_60;
+	tvout->default_tvStd = TV_STD_PAL_60;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
 	break;
     default:
     case NTSC_SUPPORT:
-	radeon_output->default_tvStd = TV_STD_NTSC;
+	tvout->default_tvStd = TV_STD_NTSC;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
 	break;
     }
 
-    radeon_output->tvStd = radeon_output->default_tvStd;
+    tvout->tvStd = tvout->default_tvStd;
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
-    radeon_output->SupportedTVStds = radeon_output->default_tvStd;
+    tvout->SupportedTVStds = tvout->default_tvStd;
     if (tv_info->ucTV_SupportedStandard & NTSC_SUPPORT) {
 	ErrorF("NTSC ");
-	radeon_output->SupportedTVStds |= TV_STD_NTSC;
+	tvout->SupportedTVStds |= TV_STD_NTSC;
     }
     if (tv_info->ucTV_SupportedStandard & NTSCJ_SUPPORT) {
 	ErrorF("NTSC-J ");
-	radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+	tvout->SupportedTVStds |= TV_STD_NTSC_J;
     }
     if (tv_info->ucTV_SupportedStandard & PAL_SUPPORT) {
 	ErrorF("PAL ");
-	radeon_output->SupportedTVStds |= TV_STD_PAL;
+	tvout->SupportedTVStds |= TV_STD_PAL;
     }
     if (tv_info->ucTV_SupportedStandard & PALM_SUPPORT) {
 	ErrorF("PAL-M ");
-	radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+	tvout->SupportedTVStds |= TV_STD_PAL_M;
     }
     if (tv_info->ucTV_SupportedStandard & PAL60_SUPPORT) {
 	ErrorF("PAL-60 ");
-	radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+	tvout->SupportedTVStds |= TV_STD_PAL_60;
     }
     ErrorF("\n");
 
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index 68df40d..efebc62 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -125,9 +125,6 @@ atombios_static_pwrmgt_setup(ScrnInfoPtr pScrn, int enable);
 extern Bool
 RADEONGetATOMTVInfo(xf86OutputPtr output);
 
-extern Bool
-RADEONGetATOMLVDSInfo(xf86OutputPtr output);
-
 extern int
 atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
 
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 42b76b2..6fc0cf4 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -826,83 +826,84 @@ Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     int offset, refclk, stds;
 
     if (!info->VBIOS) return FALSE;
 
-    if (info->IsAtomBios) {
+    if (info->IsAtomBios)
         return RADEONGetATOMTVInfo(output);
-    } else {
+    else {
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
 	if (offset) {
 	    if (RADEON_BIOS8(offset + 6) == 'T') {
 		switch (RADEON_BIOS8(offset + 7) & 0xf) {
 		case 1:
-		    radeon_output->default_tvStd = TV_STD_NTSC;
+		    tvout->default_tvStd = TV_STD_NTSC;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
 		    break;
 		case 2:
-		    radeon_output->default_tvStd = TV_STD_PAL;
+		    tvout->default_tvStd = TV_STD_PAL;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
 		    break;
 		case 3:
-		    radeon_output->default_tvStd = TV_STD_PAL_M;
+		    tvout->default_tvStd = TV_STD_PAL_M;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
 		    break;
 		case 4:
-		    radeon_output->default_tvStd = TV_STD_PAL_60;
+		    tvout->default_tvStd = TV_STD_PAL_60;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
 		    break;
 		case 5:
-		    radeon_output->default_tvStd = TV_STD_NTSC_J;
+		    tvout->default_tvStd = TV_STD_NTSC_J;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
 		    break;
 		case 6:
-		    radeon_output->default_tvStd = TV_STD_SCART_PAL;
+		    tvout->default_tvStd = TV_STD_SCART_PAL;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
 		    break;
 		default:
-		    radeon_output->default_tvStd = TV_STD_NTSC;
+		    tvout->default_tvStd = TV_STD_NTSC;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
 		    break;
 		}
-		radeon_output->tvStd = radeon_output->default_tvStd;
+		tvout->tvStd = tvout->default_tvStd;
 
 		refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
 		if (refclk == 0)
-		    radeon_output->TVRefClk = 29.498928713; /* MHz */
+		    tvout->TVRefClk = 29.498928713; /* MHz */
 		else if (refclk == 1)
-		    radeon_output->TVRefClk = 28.636360000;
+		    tvout->TVRefClk = 28.636360000;
 		else if (refclk == 2)
-		    radeon_output->TVRefClk = 14.318180000;
+		    tvout->TVRefClk = 14.318180000;
 		else if (refclk == 3)
-		    radeon_output->TVRefClk = 27.000000000;
+		    tvout->TVRefClk = 27.000000000;
 
-		radeon_output->SupportedTVStds = radeon_output->default_tvStd;
+		tvout->SupportedTVStds = tvout->default_tvStd;
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
 		stds = RADEON_BIOS8(offset + 10) & 0x1f;
 		if (stds & TV_STD_NTSC) {
-		    radeon_output->SupportedTVStds |= TV_STD_NTSC;
+		    tvout->SupportedTVStds |= TV_STD_NTSC;
 		    ErrorF("NTSC ");
 		}
 		if (stds & TV_STD_PAL) {
-		    radeon_output->SupportedTVStds |= TV_STD_PAL;
+		    tvout->SupportedTVStds |= TV_STD_PAL;
 		    ErrorF("PAL ");
 		}
 		if (stds & TV_STD_PAL_M) {
-		    radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+		    tvout->SupportedTVStds |= TV_STD_PAL_M;
 		    ErrorF("PAL-M ");
 		}
 		if (stds & TV_STD_PAL_60) {
-		    radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+		    tvout->SupportedTVStds |= TV_STD_PAL_60;
 		    ErrorF("PAL-60 ");
 		}
 		if (stds & TV_STD_NTSC_J) {
-		    radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+		    tvout->SupportedTVStds |= TV_STD_NTSC_J;
 		    ErrorF("NTSC-J ");
 		}
 		if (stds & TV_STD_SCART_PAL) {
-		    radeon_output->SupportedTVStds |= TV_STD_SCART_PAL;
+		    tvout->SupportedTVStds |= TV_STD_SCART_PAL;
 		    ErrorF("SCART-PAL");
 		}
 		ErrorF("\n");
@@ -990,11 +991,9 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn)
     return TRUE;
 }
 
-Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
+Bool RADEONGetDAC2InfoFromBIOS (ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int offset, rev, bg, dac;
 
     if (!info->VBIOS) return FALSE;
@@ -1013,29 +1012,29 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
 	    if (rev > 4) {
 		bg = RADEON_BIOS8(offset + 0xc) & 0xf;
 		dac = RADEON_BIOS8(offset + 0xd) & 0xf;
-		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
 
 		bg = RADEON_BIOS8(offset + 0xe) & 0xf;
 		dac = RADEON_BIOS8(offset + 0xf) & 0xf;
-		radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->pal_tvdac_adj = (bg << 16) | (dac << 20);
 
 		bg = RADEON_BIOS8(offset + 0x10) & 0xf;
 		dac = RADEON_BIOS8(offset + 0x11) & 0xf;
-		radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
 
 		return TRUE;
 	    } else if (rev > 1) {
 		bg = RADEON_BIOS8(offset + 0xc) & 0xf;
 		dac = (RADEON_BIOS8(offset + 0xc) >> 4) & 0xf;
-		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
 
 		bg = RADEON_BIOS8(offset + 0xd) & 0xf;
 		dac = (RADEON_BIOS8(offset + 0xd) >> 4) & 0xf;
-		radeon_output->pal_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->pal_tvdac_adj = (bg << 16) | (dac << 20);
 
 		bg = RADEON_BIOS8(offset + 0xe) & 0xf;
 		dac = (RADEON_BIOS8(offset + 0xe) >> 4) & 0xf;
-		radeon_output->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->ntsc_tvdac_adj = (bg << 16) | (dac << 20);
 
 		return TRUE;
 	    }
@@ -1047,17 +1046,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
 	    if (rev < 2) {
 		bg = RADEON_BIOS8(offset + 0x3) & 0xf;
 		dac = (RADEON_BIOS8(offset + 0x3) >> 4) & 0xf;
-		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
-		radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
-		radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+		tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj;
+		tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj;
 
 		return TRUE;
 	    } else {
 		bg = RADEON_BIOS8(offset + 0x4) & 0xf;
 		dac = RADEON_BIOS8(offset + 0x5) & 0xf;
-		radeon_output->ps2_tvdac_adj = (bg << 16) | (dac << 20);
-		radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
-		radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+		tvdac->ps2_tvdac_adj = (bg << 16) | (dac << 20);
+		tvdac->pal_tvdac_adj = tvdac->ps2_tvdac_adj;
+		tvdac->ntsc_tvdac_adj = tvdac->ps2_tvdac_adj;
 
 		return TRUE;
 	    }
@@ -1067,19 +1066,17 @@ Bool RADEONGetDAC2InfoFromBIOS (xf86OutputPtr output)
     return FALSE;
 }
 
-Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
+Bool
+RADEONGetLVDSInfoFromBIOS(ScrnInfoPtr pScrn, radeon_lvds_ptr lvds)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &lvds->native_mode;
     unsigned long tmp, i;
 
-    if (!info->VBIOS) return FALSE;
-
-    if (info->IsAtomBios)
-	return RADEONGetATOMLVDSInfo(output);
-    else {
+    if (!info->VBIOS)
+	return FALSE;
 
+    if (!info->IsAtomBios) {
 	tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
 
 	if (!tmp) {
@@ -1097,14 +1094,14 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Panel ID string: %s\n", stmp);
 
-	    radeon_output->PanelXRes = RADEON_BIOS16(tmp+25);
-	    radeon_output->PanelYRes = RADEON_BIOS16(tmp+27);
+	    native_mode->PanelXRes = RADEON_BIOS16(tmp+25);
+	    native_mode->PanelYRes = RADEON_BIOS16(tmp+27);
 	    xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",
-		       radeon_output->PanelXRes, radeon_output->PanelYRes);
+		       native_mode->PanelXRes, native_mode->PanelYRes);
 
-	    radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+44);
-	    if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
-		radeon_output->PanelPwrDly = 2000;
+	    lvds->PanelPwrDly = RADEON_BIOS16(tmp+44);
+	    if (lvds->PanelPwrDly > 2000 || lvds->PanelPwrDly < 0)
+		lvds->PanelPwrDly = 2000;
 
 	    /* some panels only work well with certain divider combinations.
 	     */
@@ -1125,35 +1122,36 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 	    for (i = 0; i < 32; i++) {
 		tmp0 = RADEON_BIOS16(tmp+64+i*2);
 		if (tmp0 == 0) break;
-		if ((RADEON_BIOS16(tmp0) == radeon_output->PanelXRes) &&
-		    (RADEON_BIOS16(tmp0+2) == radeon_output->PanelYRes)) {
-		    radeon_output->HBlank     = (RADEON_BIOS16(tmp0+17) -
-					RADEON_BIOS16(tmp0+19)) * 8;
-		    radeon_output->HOverPlus  = (RADEON_BIOS16(tmp0+21) -
-					RADEON_BIOS16(tmp0+19) - 1) * 8;
-		    radeon_output->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
-		    radeon_output->VBlank     = (RADEON_BIOS16(tmp0+24) -
-					RADEON_BIOS16(tmp0+26));
-		    radeon_output->VOverPlus  = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
-					RADEON_BIOS16(tmp0+26));
-		    radeon_output->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
-		    radeon_output->DotClock   = RADEON_BIOS16(tmp0+9) * 10;
-		    radeon_output->Flags = 0;
+		if ((RADEON_BIOS16(tmp0) == native_mode->PanelXRes) &&
+		    (RADEON_BIOS16(tmp0+2) == native_mode->PanelYRes)) {
+		    native_mode->HBlank     = (RADEON_BIOS16(tmp0+17) -
+					       RADEON_BIOS16(tmp0+19)) * 8;
+		    native_mode->HOverPlus  = (RADEON_BIOS16(tmp0+21) -
+					       RADEON_BIOS16(tmp0+19) - 1) * 8;
+		    native_mode->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
+		    native_mode->VBlank     = (RADEON_BIOS16(tmp0+24) -
+					       RADEON_BIOS16(tmp0+26));
+		    native_mode->VOverPlus  = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
+					       RADEON_BIOS16(tmp0+26));
+		    native_mode->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
+		    native_mode->DotClock   = RADEON_BIOS16(tmp0+9) * 10;
+		    native_mode->Flags = 0;
 		}
 	    }
 	}
-    }
 
-    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	       "LVDS Info:\n"
-	       "XRes: %d, YRes: %d, DotClock: %d\n"
-	       "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
-	       "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
-	       radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
-	       radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
-	       radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "LVDS Info:\n"
+		   "XRes: %d, YRes: %d, DotClock: %d\n"
+		   "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
+		   "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
+		   native_mode->PanelXRes, native_mode->PanelYRes, native_mode->DotClock,
+		   native_mode->HBlank, native_mode->HOverPlus, native_mode->HSyncWidth,
+		   native_mode->VBlank, native_mode->VOverPlus, native_mode->VSyncWidth);
 
-    return TRUE;
+	return TRUE;
+    }
+    return FALSE;
 }
 
 xf86MonPtr RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
@@ -1179,11 +1177,9 @@ xf86MonPtr RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
     return mon;
 }
 
-Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
+Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_tmds_ptr tmds)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     uint32_t tmp, maxfreq;
     int i, n;
 
@@ -1193,21 +1189,21 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
 	if((tmp = RADEON_BIOS16 (info->MasterDataStart + 18))) {
 
 	    maxfreq = RADEON_BIOS16(tmp+4);
-	    
+
 	    for (i=0; i<4; i++) {
-		radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
+		tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
 		/* This assumes each field in TMDS_PLL has 6 bit as in R300/R420 */
-		radeon_output->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
+		tmds->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
 					   ((RADEON_BIOS8(tmp+i*6+10) & 0x3f)<<6) |
 					   ((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) |
 					   ((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16));
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			   "TMDS PLL from BIOS: %u %x\n", 
-			   (unsigned)radeon_output->tmds_pll[i].freq,
-			   (unsigned)radeon_output->tmds_pll[i].value);
-		       
-		if (maxfreq == radeon_output->tmds_pll[i].freq) {
-		    radeon_output->tmds_pll[i].freq = 0xffffffff;
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "TMDS PLL from BIOS: %u %x\n",
+			   (unsigned)tmds->tmds_pll[i].freq,
+			   (unsigned)tmds->tmds_pll[i].value);
+
+		if (maxfreq == tmds->tmds_pll[i].freq) {
+		    tmds->tmds_pll[i].freq = 0xffffffff;
 		    break;
 		}
 	    }
@@ -1223,8 +1219,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
 		n = RADEON_BIOS8(tmp + 5) + 1;
 		if (n > 4) n = 4;
 		for (i=0; i<n; i++) {
-		    radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
-		    radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
+		    tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
+		    tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
 		}
 		return TRUE;
 	    } else if (RADEON_BIOS8(tmp) == 4) {
@@ -1232,8 +1228,8 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
 		n = RADEON_BIOS8(tmp + 5) + 1;
 		if (n > 4) n = 4;
 		for (i=0; i<n; i++) {
-		    radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
-		    radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
+		    tmds->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+		    tmds->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
 		    if (i == 0) stride += 10;
 		    else stride += 6;
 		}
@@ -1288,18 +1284,17 @@ RADEONLookupI2CBlock(ScrnInfoPtr pScrn, int id)
     return i2c;
 }
 
-Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
+Bool RADEONGetExtTMDSInfoFromBIOS (ScrnInfoPtr pScrn, radeon_dvo_ptr dvo)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int offset, table_start, max_freq, gpio_reg, flags;
 
-    if (!info->VBIOS) return FALSE;
+    if (!info->VBIOS)
+	return FALSE;
 
-    if (info->IsAtomBios) {
+    if (info->IsAtomBios)
 	return FALSE;
-    } else if (info->IsIGP) {
+    else if (info->IsIGP) {
 	/* RS4xx TMDS stuff is in the mobile table */
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	if (offset) {
@@ -1312,7 +1307,7 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 		    if (offset && (rev > 1)) {
 			int blocks = RADEON_BIOS8(offset + 3);
 			int index = offset + 4;
-			radeon_output->dvo_i2c.valid = FALSE;
+			dvo->dvo_i2c.valid = FALSE;
 			while (blocks > 0) {
 			    int id = RADEON_BIOS16(index);
 			    index += 2;
@@ -1330,10 +1325,10 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 				index += 2;
 				break;
 			    case 6:
-				radeon_output->dvo_i2c_slave_addr =
+				dvo->dvo_i2c_slave_addr =
 				    RADEON_BIOS16(index) & 0xff;
 				index += 2;
-				radeon_output->dvo_i2c =
+				dvo->dvo_i2c =
 				    RADEONLookupI2CBlock(pScrn, RADEON_BIOS8(index));
 				return TRUE;
 			    default:
@@ -1353,17 +1348,17 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 			RADEON_BIOS8(offset));
 	    table_start = offset+4;
 	    max_freq = RADEON_BIOS16(table_start);
-	    radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
-	    radeon_output->dvo_i2c.valid = FALSE;
+	    dvo->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+	    dvo->dvo_i2c.valid = FALSE;
 	    gpio_reg = RADEON_BIOS8(table_start+3);
 	    if (gpio_reg == 1)
-		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+		dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    else if (gpio_reg == 2)
-		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+		dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	    else if (gpio_reg == 3)
-		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+		dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	    else if (gpio_reg == 4)
-		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+		dvo->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	    else if (gpio_reg == 5) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "unsupported MM gpio_reg\n");
@@ -1374,8 +1369,8 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 		return FALSE;
 	    }
 	    flags = RADEON_BIOS8(table_start+5);
-	    radeon_output->dvo_duallink = flags & 0x01;
-	    if (radeon_output->dvo_duallink) {
+	    dvo->dvo_duallink = flags & 0x01;
+	    if (dvo->dvo_duallink) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "Duallink TMDS detected\n");
 	    }
@@ -1394,15 +1389,25 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_dvo_ptr dvo = NULL;
     int offset, index, id;
     uint32_t val, reg, and_mask, or_mask;
 
-    if (!info->VBIOS) return FALSE;
+    if (radeon_encoder == NULL)
+	return FALSE;
 
-    if (info->IsAtomBios) {
+    dvo = (radeon_dvo_ptr)radeon_encoder->dev_priv;
+
+    if (dvo == NULL)
+	return FALSE;
+
+    if (!info->VBIOS)
+	return FALSE;
+
+    if (info->IsAtomBios)
 	return FALSE;
-    } else if (info->IsIGP) {
+    else if (info->IsIGP) {
 	/* RS4xx TMDS stuff is in the mobile table */
 	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	if (offset) {
@@ -1459,7 +1464,7 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
 				index++;
 				ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg,
 				       (unsigned)val);
-				RADEONDVOWriteByte(radeon_output->DVOChip, reg, val);
+				RADEONDVOWriteByte(dvo->DVOChip, reg, val);
 				break;
 			    default:
 				ErrorF("unknown id %d\n", id>>13);
@@ -1524,7 +1529,7 @@ Bool RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output)
 		    index += 1;
 		    ErrorF("i2c write: 0x%x, 0x%x\n", (unsigned)reg,
 			   (unsigned)val);
-		    RADEONDVOWriteByte(radeon_output->DVOChip, reg, val);
+		    RADEONDVOWriteByte(dvo->DVOChip, reg, val);
 		    break;
 		default:
 		    ErrorF("unknown id %d\n", id>>13);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 50b32a9..611589e 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -95,36 +95,19 @@ RADEONTVModes(xf86OutputPtr output)
 static DisplayModePtr
 RADEONATOMTVModes(xf86OutputPtr output)
 {
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  last       = NULL;
     DisplayModePtr  new        = NULL;
     DisplayModePtr  first      = NULL;
-    int max_v, i;
+    int i;
     /* Add some common sizes */
     int widths[5] = {640, 720, 800, 848, 1024};
-
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M)
-	max_v = 480;
-    else
-	max_v = 600;
+    int heights[5] = {480, 480, 600, 480, 768};
 
     for (i = 0; i < 5; i++) {
-	new = xf86CVTMode(widths[i], max_v, 60.0, FALSE, FALSE);
+	new = xf86CVTMode(widths[i], heights[i], 60.0, FALSE, FALSE);
 
 	new->type       = M_T_DRIVER;
 
-	if (radeon_output->tvStd == TV_STD_NTSC ||
-	    radeon_output->tvStd == TV_STD_NTSC_J ||
-	    radeon_output->tvStd == TV_STD_PAL_M) {
-	    if (widths[i] == 640)
-		new->type |= M_T_PREFERRED;
-	} else {
-	    if (widths[i] == 800)
-		new->type |= M_T_PREFERRED;
-	}
-
 	new->next       = NULL;
 	new->prev       = last;
 
@@ -148,28 +131,29 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
     DisplayModePtr  new   = NULL;
     char            stmp[32];
 
-    if (radeon_output->PanelXRes != 0 &&
-	radeon_output->PanelYRes != 0 &&
-	radeon_output->DotClock != 0) {
+    if (native_mode->PanelXRes != 0 &&
+	native_mode->PanelYRes != 0 &&
+	native_mode->DotClock != 0) {
 
 	new             = xnfcalloc(1, sizeof (DisplayModeRec));
-	sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes);
+	sprintf(stmp, "%dx%d", native_mode->PanelXRes, native_mode->PanelYRes);
 	new->name       = xnfalloc(strlen(stmp) + 1);
 	strcpy(new->name, stmp);
-	new->HDisplay   = radeon_output->PanelXRes;
-	new->VDisplay   = radeon_output->PanelYRes;
+	new->HDisplay   = native_mode->PanelXRes;
+	new->VDisplay   = native_mode->PanelYRes;
 
-	new->HTotal     = new->HDisplay + radeon_output->HBlank;
-	new->HSyncStart = new->HDisplay + radeon_output->HOverPlus;
-	new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
-	new->VTotal     = new->VDisplay + radeon_output->VBlank;
-	new->VSyncStart = new->VDisplay + radeon_output->VOverPlus;
-	new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
+	new->HTotal     = new->HDisplay + native_mode->HBlank;
+	new->HSyncStart = new->HDisplay + native_mode->HOverPlus;
+	new->HSyncEnd   = new->HSyncStart + native_mode->HSyncWidth;
+	new->VTotal     = new->VDisplay + native_mode->VBlank;
+	new->VSyncStart = new->VDisplay + native_mode->VOverPlus;
+	new->VSyncEnd   = new->VSyncStart + native_mode->VSyncWidth;
 
-	new->Clock      = radeon_output->DotClock;
+	new->Clock      = native_mode->DotClock;
 	new->Flags      = 0;
 
 	if (new) {
@@ -180,7 +164,7 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
 	}
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Added native panel mode: %dx%d\n",
-		   radeon_output->PanelXRes, radeon_output->PanelYRes);
+		   native_mode->PanelXRes, native_mode->PanelYRes);
     }
 
     return new;
@@ -250,6 +234,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
     DisplayModePtr  last       = NULL;
     DisplayModePtr  new        = NULL;
     DisplayModePtr  first      = NULL;
@@ -268,7 +253,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
 
 	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 	    /* already added the native mode */
-	    if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
+	    if (width == native_mode->PanelXRes && height == native_mode->PanelYRes)
 		continue;
 
 	    /* Note: We allow all non-standard modes as long as they do not
@@ -276,13 +261,13 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
 	     * need the internal RMX unit in the video chips (and there is
 	     * only one per card), this will only apply to the primary head.
 	     */
-	    if (width < 320 || width > radeon_output->PanelXRes ||
-		height < 200 || height > radeon_output->PanelYRes) {
+	    if (width < 320 || width > native_mode->PanelXRes ||
+		height < 200 || height > native_mode->PanelYRes) {
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Mode %s is out of range.\n", ppModeName[i]);
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "Valid FP modes must be between 320x200-%dx%d\n",
-			   radeon_output->PanelXRes, radeon_output->PanelYRes);
+			   native_mode->PanelXRes, native_mode->PanelYRes);
 		continue;
 	    }
 	}
@@ -316,6 +301,116 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
 
 }
 
+/* BIOS may not have right panel size, we search through all supported
+ * DDC modes looking for the maximum panel size.
+ */
+static void
+RADEONUpdatePanelSize(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
+    int             j;
+    xf86MonPtr ddc = output->MonInfo;
+    DisplayModePtr  p;
+
+    // update output's native mode
+    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
+	radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+	if (radeon_encoder) {
+	    radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
+	    if (lvds)
+		radeon_output->native_mode = lvds->native_mode;
+	}
+    }
+
+    // crtc should handle?
+    if ((info->UseBiosDividers && native_mode->DotClock != 0) || (ddc == NULL))
+       return;
+
+    /* Go thru detailed timing table first */
+    for (j = 0; j < 4; j++) {
+	if (ddc->det_mon[j].type == 0) {
+	    struct detailed_timings *d_timings =
+		&ddc->det_mon[j].section.d_timings;
+           int match = 0;
+
+           /* If we didn't get a panel clock or guessed one, try to match the
+            * mode with the panel size. We do that because we _need_ a panel
+            * clock, or ValidateFPModes will fail, even when UseBiosDividers
+            * is set.
+            */
+           if (native_mode->DotClock == 0 &&
+               native_mode->PanelXRes == d_timings->h_active &&
+               native_mode->PanelYRes == d_timings->v_active)
+               match = 1;
+
+           /* If we don't have a BIOS provided panel data with fixed dividers,
+            * check for a larger panel size
+            */
+	    if (native_mode->PanelXRes < d_timings->h_active &&
+		native_mode->PanelYRes < d_timings->v_active &&
+		!info->UseBiosDividers)
+		match = 1;
+
+             if (match) {
+		native_mode->PanelXRes  = d_timings->h_active;
+		native_mode->PanelYRes  = d_timings->v_active;
+		native_mode->DotClock   = d_timings->clock / 1000;
+		native_mode->HOverPlus  = d_timings->h_sync_off;
+		native_mode->HSyncWidth = d_timings->h_sync_width;
+		native_mode->HBlank     = d_timings->h_blanking;
+		native_mode->VOverPlus  = d_timings->v_sync_off;
+		native_mode->VSyncWidth = d_timings->v_sync_width;
+		native_mode->VBlank     = d_timings->v_blanking;
+                native_mode->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
+                switch (d_timings->misc) {
+                case 0: native_mode->Flags |= V_NHSYNC | V_NVSYNC; break;
+                case 1: native_mode->Flags |= V_PHSYNC | V_NVSYNC; break;
+                case 2: native_mode->Flags |= V_NHSYNC | V_PVSYNC; break;
+                case 3: native_mode->Flags |= V_PHSYNC | V_PVSYNC; break;
+                }
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
+                           native_mode->PanelXRes, native_mode->PanelYRes);
+	    }
+	}
+    }
+
+    if (info->UseBiosDividers && native_mode->DotClock != 0)
+       return;
+
+    /* Search thru standard VESA modes from EDID */
+    for (j = 0; j < 8; j++) {
+	if ((native_mode->PanelXRes < ddc->timings2[j].hsize) &&
+	    (native_mode->PanelYRes < ddc->timings2[j].vsize)) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
+		if ((ddc->timings2[j].hsize == p->HDisplay) &&
+		    (ddc->timings2[j].vsize == p->VDisplay)) {
+		    float  refresh =
+			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
+
+		    if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
+			/* Is this good enough? */
+			native_mode->PanelXRes  = ddc->timings2[j].hsize;
+			native_mode->PanelYRes  = ddc->timings2[j].vsize;
+			native_mode->HBlank     = p->HTotal - p->HDisplay;
+			native_mode->HOverPlus  = p->HSyncStart - p->HDisplay;
+			native_mode->HSyncWidth = p->HSyncEnd - p->HSyncStart;
+			native_mode->VBlank     = p->VTotal - p->VDisplay;
+			native_mode->VOverPlus  = p->VSyncStart - p->VDisplay;
+			native_mode->VSyncWidth = p->VSyncEnd - p->VSyncStart;
+			native_mode->DotClock   = p->Clock;
+                        native_mode->Flags      = p->Flags;
+                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
+                                   native_mode->PanelXRes, native_mode->PanelYRes);
+		    }
+		}
+	    }
+	}
+    }
+}
+
 DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
@@ -326,8 +421,6 @@ RADEONProbeOutputModes(xf86OutputPtr output)
     AtomBiosArgRec atomBiosArg;
     AtomBiosResult atomBiosResult;
 
-    ErrorF("in RADEONProbeOutputModes\n");
-
     if (output->status == XF86OutputStatusConnected) {
 	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 	    if (IS_AVIVO_VARIANT)
@@ -341,6 +434,8 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		modes = atomBiosArg.modes;
 	    }
 	} else {
+	    if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))
+		RADEONUpdatePanelSize(output);
 	    if (output->MonInfo)
 		modes = xf86OutputGetEDIDModes (output);
 #if defined(__powerpc__)
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 78af9a7..fd94e2c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -105,7 +105,6 @@ const char *ConnectorTypeName[17] = {
   "Unsupported"
 };
 
-static void RADEONUpdatePanelSize(xf86OutputPtr output);
 extern void atombios_output_mode_set(xf86OutputPtr output,
 				     DisplayModePtr mode,
 				     DisplayModePtr adjusted_mode);
@@ -114,14 +113,6 @@ extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output);
 extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
 extern AtomBiosResult
 atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock);
-extern void
-RADEONGetExtTMDSInfo(xf86OutputPtr output);
-extern void
-RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
-extern void
-RADEONGetTMDSInfo(xf86OutputPtr output);
-extern void
-RADEONGetTVDacAdjInfo(xf86OutputPtr output);
 static void
 radeon_bios_output_dpms(xf86OutputPtr output, int mode);
 static void
@@ -381,6 +372,7 @@ static int
 radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -407,12 +399,12 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 
     if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 	if (radeon_output->rmx_type == RMX_OFF) {
-	    if (pMode->HDisplay != radeon_output->PanelXRes ||
-		pMode->VDisplay != radeon_output->PanelYRes)
+	    if (pMode->HDisplay != native_mode->PanelXRes ||
+		pMode->VDisplay != native_mode->PanelYRes)
 		return MODE_PANEL;
 	}
-	if (pMode->HDisplay > radeon_output->PanelXRes ||
-	    pMode->VDisplay > radeon_output->PanelYRes)
+	if (pMode->HDisplay > native_mode->PanelXRes ||
+	    pMode->VDisplay > native_mode->PanelYRes)
 	    return MODE_PANEL;
     }
 
@@ -425,12 +417,13 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 {
     RADEONInfoPtr info = RADEONPTR(output->scrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_native_mode_ptr native_mode = &radeon_output->native_mode;
 
     radeon_output->Flags &= ~RADEON_USE_RMX;
 
-    /* 
-     *  Refresh the Crtc values without INTERLACE_HALVE_V 
-     *  Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does? 
+    /*
+     *  Refresh the Crtc values without INTERLACE_HALVE_V
+     *  Should we use output->scrn->adjustFlags like xf86RandRModeConvert() does?
      */
     xf86SetModeCrtc(adjusted_mode, 0);
 
@@ -441,51 +434,51 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
 	if (IS_AVIVO_VARIANT || radeon_crtc->crtc_id == 0) {
-	    if (mode->HDisplay < radeon_output->PanelXRes ||
-		mode->VDisplay < radeon_output->PanelYRes) {
+	    if (mode->HDisplay < native_mode->PanelXRes ||
+		mode->VDisplay < native_mode->PanelYRes) {
 		radeon_output->Flags |= RADEON_USE_RMX;
 		if (IS_AVIVO_VARIANT) {
 		    /* set to the panel's native mode */
-		    adjusted_mode->HDisplay = radeon_output->PanelXRes;
-		    adjusted_mode->VDisplay = radeon_output->PanelYRes;
-		    adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
-		    adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
-		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
-		    adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
-		    adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
-		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
+		    adjusted_mode->HDisplay = native_mode->PanelXRes;
+		    adjusted_mode->VDisplay = native_mode->PanelYRes;
+		    adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank;
+		    adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus;
+		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth;
+		    adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank;
+		    adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus;
+		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth;
 		    /* update crtc values */
 		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
 		    /* adjust crtc values */
-		    adjusted_mode->CrtcHDisplay = radeon_output->PanelXRes;
-		    adjusted_mode->CrtcVDisplay = radeon_output->PanelYRes;
-		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank;
-		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus;
-		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank;
-		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus;
-		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+		    adjusted_mode->CrtcHDisplay = native_mode->PanelXRes;
+		    adjusted_mode->CrtcVDisplay = native_mode->PanelYRes;
+		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank;
+		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus;
+		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth;
+		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank;
+		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus;
+		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth;
 		} else {
 		    /* set to the panel's native mode */
-		    adjusted_mode->HTotal = radeon_output->PanelXRes + radeon_output->HBlank;
-		    adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
-		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
-		    adjusted_mode->VTotal = radeon_output->PanelYRes + radeon_output->VBlank;
-		    adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
-		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
-		    adjusted_mode->Clock = radeon_output->DotClock;
+		    adjusted_mode->HTotal = native_mode->PanelXRes + native_mode->HBlank;
+		    adjusted_mode->HSyncStart = native_mode->PanelXRes + native_mode->HOverPlus;
+		    adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + native_mode->HSyncWidth;
+		    adjusted_mode->VTotal = native_mode->PanelYRes + native_mode->VBlank;
+		    adjusted_mode->VSyncStart = native_mode->PanelYRes + native_mode->VOverPlus;
+		    adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + native_mode->VSyncWidth;
+		    adjusted_mode->Clock = native_mode->DotClock;
 		    /* update crtc values */
 		    xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
 		    /* adjust crtc values */
-		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + radeon_output->HBlank;
-		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + radeon_output->HOverPlus;
-		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + radeon_output->VBlank;
-		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + radeon_output->VOverPlus;
-		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+		    adjusted_mode->CrtcHTotal = adjusted_mode->CrtcHDisplay + native_mode->HBlank;
+		    adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHDisplay + native_mode->HOverPlus;
+		    adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + native_mode->HSyncWidth;
+		    adjusted_mode->CrtcVTotal = adjusted_mode->CrtcVDisplay + native_mode->VBlank;
+		    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + native_mode->VOverPlus;
+		    adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + native_mode->VSyncWidth;
 		}
-		adjusted_mode->Clock = radeon_output->DotClock;
-		adjusted_mode->Flags = radeon_output->Flags;
+		adjusted_mode->Clock = native_mode->DotClock;
+		adjusted_mode->Flags = native_mode->Flags;
 	    }
 	}
     }
@@ -971,14 +964,18 @@ radeon_detect(xf86OutputPtr output)
 	}
     }
 
-    /* update panel info for RMX */
-    if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
-	RADEONUpdatePanelSize(output);
+    // if size is zero panel probably broken or not connected
+    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+	radeon_encoder_ptr radeon_encoder = info->encoders[ATOM_DEVICE_LCD1_INDEX];
+	if (radeon_encoder) {
+	    radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
+	    if (lvds) {
+		if ((lvds->native_mode.PanelXRes == 0) || (lvds->native_mode.PanelYRes == 0))
+		    radeon_output->MonType = MT_NONE;
+	    }
+	}
+    }
 
-    /* panel is probably busted or not connected */
-    if ((radeon_output->MonType == MT_LCD) &&
-	((radeon_output->PanelXRes == 0) || (radeon_output->PanelYRes == 0)))
-	radeon_output->MonType = MT_NONE;
 
     if (output->MonInfo) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n",
@@ -1270,6 +1267,7 @@ radeon_create_resources(xf86OutputPtr output)
     }
 
     if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) {
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
 	if (!IS_AVIVO_VARIANT) {
 	    tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
 
@@ -1339,7 +1337,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
 
 	/* Set the current value of the property */
-	switch (radeon_output->tvStd) {
+	switch (tvout->tvStd) {
 	case TV_STD_PAL:
 	    s = "pal";
 	    break;
@@ -1472,16 +1470,23 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	    return FALSE;
 	}
     } else if (property == tmds_pll_atom) {
+	radeon_tmds_ptr tmds = NULL;
 	const char *s;
+
+	if (info->encoders[ATOM_DEVICE_DFP1_INDEX] && info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv)
+	    tmds = (radeon_tmds_ptr)info->encoders[ATOM_DEVICE_DFP1_INDEX]->dev_priv;
+	else
+	    return FALSE;
+
 	if (value->type != XA_STRING || value->format != 8)
 	    return FALSE;
 	s = (char*)value->data;
 	if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) {
-	    if (!RADEONGetTMDSInfoFromBIOS(output))
-		RADEONGetTMDSInfoFromTable(output);
-	} else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) {
-	    RADEONGetTMDSInfoFromTable(output);
-	} else
+	    if (!RADEONGetTMDSInfoFromBIOS(output->scrn, tmds))
+		RADEONGetTMDSInfoFromTable(output->scrn, tmds);
+	} else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver")))
+	    RADEONGetTMDSInfoFromTable(output->scrn, tmds);
+	else
 	    return FALSE;
 
 	return radeon_set_mode_for_property(output);
@@ -1502,6 +1507,7 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	} else
 	    return FALSE;
     } else if (property == tv_hsize_atom) {
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
 	    value->size != 1) {
@@ -1512,11 +1518,12 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	if (val < -MAX_H_SIZE || val > MAX_H_SIZE)
 	    return FALSE;
 
-	radeon_output->hSize = val;
-	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
+	tvout->hSize = val;
+	if (tvout->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 
     } else if (property == tv_hpos_atom) {
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
 	    value->size != 1) {
@@ -1527,11 +1534,12 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
 	    return FALSE;
 
-	radeon_output->hPos = val;
-	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
+	tvout->hPos = val;
+	if (tvout->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 
     } else if (property == tv_vpos_atom) {
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
 	    value->size != 1) {
@@ -1542,38 +1550,39 @@ radeon_set_property(xf86OutputPtr output, Atom property,
 	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
 	    return FALSE;
 
-	radeon_output->vPos = val;
-	if (radeon_output->tv_on && !IS_AVIVO_VARIANT)
+	tvout->vPos = val;
+	if (tvout->tv_on && !IS_AVIVO_VARIANT)
 	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 
     } else if (property == tv_std_atom) {
 	const char *s;
-	TVStd std = radeon_output->tvStd;
+	radeon_tvout_ptr tvout = &radeon_output->tvout;
+	TVStd std = tvout->tvStd;
 
 	if (value->type != XA_STRING || value->format != 8)
 	    return FALSE;
 	s = (char*)value->data;
 	if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) {
-	    radeon_output->tvStd = TV_STD_NTSC;
+	    tvout->tvStd = TV_STD_NTSC;
 	} else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) {
-	    radeon_output->tvStd = TV_STD_PAL;
+	    tvout->tvStd = TV_STD_PAL;
 	} else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) {
-	    radeon_output->tvStd = TV_STD_PAL_M;
+	    tvout->tvStd = TV_STD_PAL_M;
 	} else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) {
-	    radeon_output->tvStd = TV_STD_PAL_60;
+	    tvout->tvStd = TV_STD_PAL_60;
 	} else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) {
-	    radeon_output->tvStd = TV_STD_NTSC_J;
+	    tvout->tvStd = TV_STD_NTSC_J;
 	} else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) {
-	    radeon_output->tvStd = TV_STD_SCART_PAL;
+	    tvout->tvStd = TV_STD_SCART_PAL;
 	} else if (value->size == strlen("pal-cn") && !strncmp("pal-cn", s, strlen("pal-cn"))) {
-	    radeon_output->tvStd = TV_STD_PAL_CN;
+	    tvout->tvStd = TV_STD_PAL_CN;
 	} else if (value->size == strlen("secam") && !strncmp("secam", s, strlen("secam"))) {
-	    radeon_output->tvStd = TV_STD_SECAM;
+	    tvout->tvStd = TV_STD_SECAM;
 	} else
 	    return FALSE;
 
 	if (!radeon_set_mode_for_property(output)) {
-	    radeon_output->tvStd = std;
+	    tvout->tvStd = std;
 	    (void)radeon_set_mode_for_property(output);
 	    return FALSE;
 	}
@@ -1676,12 +1685,9 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
 }
 
 Bool
-RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
+RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, char *name, RADEONI2CBusPtr pRADEONI2CBus)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     I2CBusPtr pI2CBus;
-    RADEONI2CBusPtr pRADEONI2CBus;
 
     pI2CBus = xf86CreateI2CBusRec();
     if (!pI2CBus) return FALSE;
@@ -1692,12 +1698,6 @@ RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
     pI2CBus->I2CGetBits = RADEONI2CGetBits;
     pI2CBus->AcknTimeout = 5;
 
-    if (dvo) {
-	pRADEONI2CBus = &(radeon_output->dvo_i2c);
-    } else {
-	pRADEONI2CBus = &(radeon_output->ddc_i2c);
-    }
-
     pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus;
 
     if (!xf86I2CBusInit(pI2CBus))
@@ -1794,267 +1794,41 @@ atom_setup_i2c_bus(int ddc_line)
 }
 
 static void
-RADEONGetPanelInfoFromReg (xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    unsigned char *RADEONMMIO = info->MMIO;
-    uint32_t fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
-    uint32_t fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
-
-    radeon_output->PanelPwrDly = 200;
-    if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
-	radeon_output->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
-				    RADEON_VERT_PANEL_SHIFT) + 1;
-    } else {
-	radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
-    }
-    if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
-	radeon_output->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
-				     RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
-    } else {
-	radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
-    }
-    
-    if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
-	radeon_output->PanelXRes = 640;
-	radeon_output->PanelYRes = 480;
-    }
-
-    // move this to crtc function
-    if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
-           uint32_t ppll_div_sel, ppll_val;
-
-           ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
-	   RADEONPllErrataAfterIndex(info);
-	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
-           if ((ppll_val & 0x000707ff) == 0x1bb)
-		   goto noprobe;
-	   info->FeedbackDivider = ppll_val & 0x7ff;
-	   info->PostDivider = (ppll_val >> 16) & 0x7;
-	   info->RefDivider = info->pll.reference_div;
-	   info->UseBiosDividers = TRUE;
-
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                      "Existing panel PLL dividers will be used.\n");
-    }
- noprobe:
-
-    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-	       "Panel size %dx%d is derived, this may not be correct.\n"
-		   "If not, use PanelSize option to overwrite this setting\n",
-	       radeon_output->PanelXRes, radeon_output->PanelYRes);
-}
-
-/* BIOS may not have right panel size, we search through all supported
- * DDC modes looking for the maximum panel size.
- */
-static void
-RADEONUpdatePanelSize(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int             j;
-    /* XXX: fixme */
-    //xf86MonPtr      ddc  = pScrn->monitor->DDC;
-    xf86MonPtr ddc = output->MonInfo;
-    DisplayModePtr  p;
-
-    // crtc should handle?
-    if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
-       return;
-
-    /* Go thru detailed timing table first */
-    for (j = 0; j < 4; j++) {
-	if (ddc->det_mon[j].type == 0) {
-	    struct detailed_timings *d_timings =
-		&ddc->det_mon[j].section.d_timings;
-           int match = 0;
-
-           /* If we didn't get a panel clock or guessed one, try to match the
-            * mode with the panel size. We do that because we _need_ a panel
-            * clock, or ValidateFPModes will fail, even when UseBiosDividers
-            * is set.
-            */
-           if (radeon_output->DotClock == 0 &&
-               radeon_output->PanelXRes == d_timings->h_active &&
-               radeon_output->PanelYRes == d_timings->v_active)
-               match = 1;
-
-           /* If we don't have a BIOS provided panel data with fixed dividers,
-            * check for a larger panel size
-            */
-	    if (radeon_output->PanelXRes < d_timings->h_active &&
-               radeon_output->PanelYRes < d_timings->v_active &&
-               !info->UseBiosDividers)
-               match = 1;
-
-             if (match) {
-		radeon_output->PanelXRes  = d_timings->h_active;
-		radeon_output->PanelYRes  = d_timings->v_active;
-		radeon_output->DotClock   = d_timings->clock / 1000;
-		radeon_output->HOverPlus  = d_timings->h_sync_off;
-		radeon_output->HSyncWidth = d_timings->h_sync_width;
-		radeon_output->HBlank     = d_timings->h_blanking;
-		radeon_output->VOverPlus  = d_timings->v_sync_off;
-		radeon_output->VSyncWidth = d_timings->v_sync_width;
-		radeon_output->VBlank     = d_timings->v_blanking;
-                radeon_output->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-                switch (d_timings->misc) {
-                case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
-                case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
-                case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
-                case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
-                }
-                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
-                           radeon_output->PanelXRes, radeon_output->PanelYRes);
-	    }
-	}
-    }
-
-    if (info->UseBiosDividers && radeon_output->DotClock != 0)
-       return;
-
-    /* Search thru standard VESA modes from EDID */
-    for (j = 0; j < 8; j++) {
-	if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
-	    (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
-	    for (p = pScrn->monitor->Modes; p; p = p->next) {
-		if ((ddc->timings2[j].hsize == p->HDisplay) &&
-		    (ddc->timings2[j].vsize == p->VDisplay)) {
-		    float  refresh =
-			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
-		    if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
-			/* Is this good enough? */
-			radeon_output->PanelXRes  = ddc->timings2[j].hsize;
-			radeon_output->PanelYRes  = ddc->timings2[j].vsize;
-			radeon_output->HBlank     = p->HTotal - p->HDisplay;
-			radeon_output->HOverPlus  = p->HSyncStart - p->HDisplay;
-			radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
-			radeon_output->VBlank     = p->VTotal - p->VDisplay;
-			radeon_output->VOverPlus  = p->VSyncStart - p->VDisplay;
-			radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
-			radeon_output->DotClock   = p->Clock;
-                        radeon_output->Flags      = p->Flags;
-                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
-                                   radeon_output->PanelXRes, radeon_output->PanelYRes);
-		    }
-		}
-	    }
-	}
-    }
-}
-
-static Bool
-RADEONGetLVDSInfo (xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    char* s;
-
-    if (!RADEONGetLVDSInfoFromBIOS(output))
-	RADEONGetPanelInfoFromReg(output);
-
-    if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
-	radeon_output->PanelPwrDly = 200;
-	if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
-	    RADEONGetPanelInfoFromReg(output);
-	}
-    }
-
-    /* The panel size we collected from BIOS may not be the
-     * maximum size supported by the panel.  If not, we update
-     * it now.  These will be used if no matching mode can be
-     * found from EDID data.
-     */
-    RADEONUpdatePanelSize(output);
-
-    if (radeon_output->DotClock == 0) {
-	DisplayModePtr  tmp_mode = NULL;
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "No valid timing info from BIOS.\n");
-	/* No timing information for the native mode,
-	   use whatever specified in the Modeline.
-	   If no Modeline specified, we'll just pick
-	   the VESA mode at 60Hz refresh rate which
-	   is likely to be the best for a flat panel.
-	*/
-	tmp_mode = pScrn->monitor->Modes;
-	while(tmp_mode) {
-	    if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
-		(tmp_mode->VDisplay == radeon_output->PanelYRes)) {
-
-		float  refresh =
-		    (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
-		if ((abs(60.0 - refresh) < 1.0) ||
-		    (tmp_mode->type == 0)) {
-		    radeon_output->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;
-		    radeon_output->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;
-		    radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
-		    radeon_output->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;
-		    radeon_output->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;
-		    radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
-		    radeon_output->DotClock   = tmp_mode->Clock;
-		    radeon_output->Flags = 0;
-		    break;
-		}
-	    }
-
-	    tmp_mode = tmp_mode->next;
-
-	    if (tmp_mode == pScrn->monitor->Modes)
-		break;
-	}
-	if ((radeon_output->DotClock == 0) && !output->MonInfo) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Panel size is not correctly detected.\n"
-		       "Please try to use PanelSize option for correct settings.\n");
-	    return FALSE;
-	}
-    }
-
-    return TRUE;
-}
-
-static void
 RADEONGetTVInfo(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     char *optstr;
 
-    radeon_output->hPos = 0;
-    radeon_output->vPos = 0;
-    radeon_output->hSize = 0;
+    tvout->hPos = 0;
+    tvout->vPos = 0;
+    tvout->hSize = 0;
+    tvout->tv_on = FALSE;
 
     if (!RADEONGetTVInfoFromBIOS(output)) {
 	/* set some reasonable defaults */
-	radeon_output->default_tvStd = TV_STD_NTSC;
-	radeon_output->tvStd = TV_STD_NTSC;
-	radeon_output->TVRefClk = 27.000000000;
-	radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+	tvout->default_tvStd = TV_STD_NTSC;
+	tvout->tvStd = TV_STD_NTSC;
+	tvout->TVRefClk = 27.000000000;
+	tvout->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
     }
 
     optstr = (char *)xf86GetOptValString(info->Options, OPTION_TVSTD);
     if (optstr) {
 	if (!strncmp("ntsc", optstr, strlen("ntsc")))
-	    radeon_output->tvStd = TV_STD_NTSC;
+	    tvout->tvStd = TV_STD_NTSC;
 	else if (!strncmp("pal", optstr, strlen("pal")))
-	    radeon_output->tvStd = TV_STD_PAL;
+	    tvout->tvStd = TV_STD_PAL;
 	else if (!strncmp("pal-m", optstr, strlen("pal-m")))
-	    radeon_output->tvStd = TV_STD_PAL_M;
+	    tvout->tvStd = TV_STD_PAL_M;
 	else if (!strncmp("pal-60", optstr, strlen("pal-60")))
-	    radeon_output->tvStd = TV_STD_PAL_60;
+	    tvout->tvStd = TV_STD_PAL_60;
 	else if (!strncmp("ntsc-j", optstr, strlen("ntsc-j")))
-	    radeon_output->tvStd = TV_STD_NTSC_J;
+	    tvout->tvStd = TV_STD_NTSC_J;
 	else if (!strncmp("scart-pal", optstr, strlen("scart-pal")))
-	    radeon_output->tvStd = TV_STD_SCART_PAL;
+	    tvout->tvStd = TV_STD_SCART_PAL;
 	else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid TV Standard: %s\n", optstr);
 	}
@@ -2071,27 +1845,12 @@ void RADEONInitConnector(xf86OutputPtr output)
     radeon_output->rmx_type = RMX_OFF;
 
     if (!IS_AVIVO_VARIANT) {
-	/* XXX fix me  - move to encoders */
-
-	if (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT))
-	    RADEONGetExtTMDSInfo(output);
-
-	if (radeon_output->devices & (ATOM_DEVICE_DFP1_SUPPORT))
-	    RADEONGetTMDSInfo(output);
-
 	if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) {
 	    if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
 		radeon_output->load_detection = 1;
-	    radeon_output->tv_on = FALSE;
-	    RADEONGetTVDacAdjInfo(output);
 	}
     }
 
-    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-	radeon_output->rmx_type = RMX_FULL;
-	RADEONGetLVDSInfo(output);
-    }
-
     if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
 	RADEONGetTVInfo(output);
 
@@ -2099,7 +1858,7 @@ void RADEONInitConnector(xf86OutputPtr output)
 	radeon_output->coherent_mode = TRUE;
 
     if (radeon_output->ddc_i2c.valid)
-	RADEONI2CInit(output, &radeon_output->pI2CBus, output->name, FALSE);
+	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, output->name, &radeon_output->ddc_i2c);
 
 }
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 6da24c2..28df696 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -165,6 +165,61 @@ typedef struct _radeon_encoder {
     void *dev_priv;
 } radeon_encoder_rec, *radeon_encoder_ptr;
 
+typedef struct _radeon_tvout {
+    /* TV out */
+    TVStd             default_tvStd;
+    TVStd             tvStd;
+    int               hPos;
+    int               vPos;
+    int               hSize;
+    float             TVRefClk;
+    int               SupportedTVStds;
+    Bool              tv_on;
+} radeon_tvout_rec, *radeon_tvout_ptr;
+
+typedef struct _radeon_native_mode {
+    /* panel stuff */
+    int               PanelXRes;
+    int               PanelYRes;
+    int               HOverPlus;
+    int               HSyncWidth;
+    int               HBlank;
+    int               VOverPlus;
+    int               VSyncWidth;
+    int               VBlank;
+    int               Flags;
+    int               DotClock;
+} radeon_native_mode_rec, *radeon_native_mode_ptr;
+
+typedef struct _radeon_tvdac {
+    // tv dac
+    uint32_t          ps2_tvdac_adj;
+    uint32_t          pal_tvdac_adj;
+    uint32_t          ntsc_tvdac_adj;
+} radeon_tvdac_rec, *radeon_tvdac_ptr;
+
+typedef struct _radeon_tmds {
+    // tmds
+    RADEONTMDSPll     tmds_pll[4];
+} radeon_tmds_rec, *radeon_tmds_ptr;
+
+typedef struct _radeon_lvds {
+    // panel mode
+    radeon_native_mode_rec native_mode;
+    // lvds
+    int               PanelPwrDly;
+    int               lvds_misc;
+    int               lvds_ss_id;
+} radeon_lvds_rec, *radeon_lvds_ptr;
+
+typedef struct _radeon_dvo {
+    /* dvo */
+    I2CDevPtr         DVOChip;
+    RADEONI2CBusRec   dvo_i2c;
+    int               dvo_i2c_slave_addr;
+    Bool              dvo_duallink;
+} radeon_dvo_rec, *radeon_dvo_ptr;
+
 typedef struct {
     RADEONConnectorType ConnectorType;
     Bool valid;
@@ -186,6 +241,12 @@ typedef struct _RADEONOutputPrivateRec {
     uint32_t active_device;
     Bool enabled;
 
+    int  load_detection;
+
+    // DVI/HDMI
+    Bool coherent_mode;
+    Bool linkb;
+
     RADEONConnectorType ConnectorType;
     RADEONDviType DVIType;
     RADEONMonitorType MonType;
@@ -197,57 +258,19 @@ typedef struct _RADEONOutputPrivateRec {
     // router info
     // HDP info
 
-    // tv dac
-    uint32_t          ps2_tvdac_adj;
-    uint32_t          pal_tvdac_adj;
-    uint32_t          ntsc_tvdac_adj;
-
-    /* panel stuff */
-    int               PanelXRes;
-    int               PanelYRes;
-    int               HOverPlus;
-    int               HSyncWidth;
-    int               HBlank;
-    int               VOverPlus;
-    int               VSyncWidth;
-    int               VBlank;
-    int               Flags;            /* Saved copy of mode flags          */
-    int               DotClock;
-
-    // lvds
-    int               PanelPwrDly;
-    int               lvds_misc;
-    int               lvds_ss_id;
-
-    // tmds
-    RADEONTMDSPll     tmds_pll[4];
+    // panel mode
+    radeon_native_mode_rec native_mode;
 
     // RMX
     RADEONRMXType     rmx_type;
+    int               Flags;
 
-    /* dvo */
-    I2CDevPtr         DVOChip;
-    RADEONI2CBusRec   dvo_i2c;
-    int               dvo_i2c_slave_addr;
-    Bool              dvo_duallink;
+    //tvout - move to encoder
+    radeon_tvout_rec tvout;
 
-    /* TV out */
-    TVStd             default_tvStd;
-    TVStd             tvStd;
-    int               hPos;
-    int               vPos;
-    int               hSize;
-    float             TVRefClk;
-    int               SupportedTVStds;
-    Bool              tv_on;
-    int               load_detection;
-
-    /* dig block */
+    /* dce 3.x dig block */
     int transmitter_config;
-    Bool coherent_mode;
     int igp_lane_info;
-    Bool linkb;
-
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 struct avivo_pll_state {
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 90d1ac9..98e3b0a 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -23,6 +23,7 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 #include "radeon_tv.h"
+#include "radeon_atombios.h"
 
 /**********************************************************************
  *
@@ -597,6 +598,7 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
 				 DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info       = RADEONPTR(output->scrn);
     RADEONPLLPtr pll = &info->pll;
     int restart;
@@ -612,9 +614,9 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
     const TVModeConstants *constPtr;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
@@ -629,20 +631,20 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
     hTotal = constPtr->horTotal;
     vTotal = constPtr->verTotal;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+        tvout->tvStd == TV_STD_PAL_M ||
+        tvout->tvStd == TV_STD_PAL_60)
 	fTotal = NTSC_TV_VFTOTAL + 1;
     else
 	fTotal = PAL_TV_VFTOTAL + 1;
 
     /* Adjust positions 1&2 in hor. code timing table */
-    hOffset = radeon_output->hPos * H_POS_UNIT;
+    hOffset = tvout->hPos * H_POS_UNIT;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	/* improve image centering */
 	hOffset -= 50;
 	p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
@@ -672,18 +674,18 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
      * Convert vPos TV lines to n. of CRTC pixels
      * Be verrrrry careful when mixing signed & unsigned values in C..
      */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-	radeon_output->tvStd == TV_STD_PAL_60)
-	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M ||
+	tvout->tvStd == TV_STD_PAL_60)
+	vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
     else
-	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
+	vOffset = ((int)(vTotal * hTotal) * 2 * tvout->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
 
     restart -= vOffset + hOffset;
 
     ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n",
-	   constPtr->defRestart , radeon_output->hPos , radeon_output->vPos , p1 , p2 , restart);
+	   constPtr->defRestart , tvout->hPos , tvout->vPos , p1 , p2 , restart);
 
     save->tv_hrestart = restart % hTotal;
     restart /= hTotal;
@@ -696,19 +698,19 @@ static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
 	   (unsigned)save->tv_hrestart);
 
     /* Compute H_INC from hSize */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M)
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M)
 	hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
-			(radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
+			(tvout->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
     else
 	hInc = (uint16_t)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) /
-			(radeon_output->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
+			(tvout->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
 
     save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) |
 	((uint32_t)hInc << RADEON_H_INC_SHIFT);
 
-    ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , radeon_output->hSize , hInc);
+    ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , tvout->hSize , hInc);
 
     return hChanged;
 }
@@ -719,6 +721,7 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     RADEONPLLPtr pll = &info->pll;
     unsigned m, n, p;
@@ -728,11 +731,21 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     const TVModeConstants *constPtr;
     const uint16_t *hor_timing;
     const uint16_t *vert_timing;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    radeon_tvdac_ptr tvdac = NULL;
+
+    if (radeon_encoder == NULL)
+	return;
+
+    tvdac = (radeon_tvdac_ptr)radeon_encoder->dev_priv;
+
+    if (tvdac == NULL)
+	return;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
@@ -764,8 +777,8 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     if (!IS_R300_VARIANT)
 	save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J)
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J)
 	save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
 
     save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
@@ -774,13 +787,13 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
 	                       | RADEON_UVFLT_EN
 	                       | (6 << RADEON_CY_FILT_BLEND_SHIFT);
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J) {
 	save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT)
 	                            | (0x3b << RADEON_BLANK_LEVEL_SHIFT);
 	save->tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
 	    ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
-    } else if (radeon_output->tvStd == TV_STD_SCART_PAL) {
+    } else if (tvout->tvStd == TV_STD_SCART_PAL) {
 	save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
 	save->tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
 	    ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
@@ -817,10 +830,10 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
 
     save->tv_sync_size = constPtr->horResolution + 8;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-	radeon_output->tvStd == TV_STD_PAL_60)
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M ||
+	tvout->tvStd == TV_STD_PAL_60)
 	vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
     else
 	vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
@@ -837,10 +850,10 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     else
 	save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-        radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+    if (tvout->tvStd == TV_STD_NTSC ||
+        tvout->tvStd == TV_STD_NTSC_J ||
+        tvout->tvStd == TV_STD_PAL_M ||
+        tvout->tvStd == TV_STD_PAL_60)
 	flicker_removal =
 	    (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
     else
@@ -876,18 +889,18 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
     save->tv_timing_cntl = tmp;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-        radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
-	save->tv_dac_cntl = radeon_output->ntsc_tvdac_adj;
+    if (tvout->tvStd == TV_STD_NTSC ||
+        tvout->tvStd == TV_STD_NTSC_J ||
+        tvout->tvStd == TV_STD_PAL_M ||
+        tvout->tvStd == TV_STD_PAL_60)
+	save->tv_dac_cntl = tvdac->ntsc_tvdac_adj;
     else
-	save->tv_dac_cntl = radeon_output->pal_tvdac_adj;
+	save->tv_dac_cntl = tvdac->pal_tvdac_adj;
 
     save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J)
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J)
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
     else
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
@@ -907,8 +920,8 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
     }
 #endif
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J) {
 	if (pll->reference_freq == 2700) {
 	    m = NTSC_TV_PLL_M_27;
 	    n = NTSC_TV_PLL_N_27;
@@ -948,28 +961,28 @@ void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
 
     save->tv_vdisp = constPtr->verResolution - 1;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-        radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+    if (tvout->tvStd == TV_STD_NTSC ||
+        tvout->tvStd == TV_STD_NTSC_J ||
+        tvout->tvStd == TV_STD_PAL_M ||
+        tvout->tvStd == TV_STD_PAL_60)
 	save->tv_ftotal = NTSC_TV_VFTOTAL;
     else
 	save->tv_ftotal = PAL_TV_VFTOTAL;
 
     save->tv_vtotal = constPtr->verTotal - 1;
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	hor_timing = hor_timing_NTSC;
     } else {
 	hor_timing = hor_timing_PAL;
     }
 
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-	radeon_output->tvStd == TV_STD_PAL_60) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M ||
+	tvout->tvStd == TV_STD_PAL_60) {
 	vert_timing = vert_timing_NTSC;
     } else {
 	vert_timing = vert_timing_PAL;
@@ -1049,13 +1062,14 @@ void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 {
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONPLLPtr pll = &info->pll;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
@@ -1089,13 +1103,14 @@ void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
     unsigned postDiv;
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONPLLPtr pll = &info->pll;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
@@ -1151,13 +1166,14 @@ void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 {
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONPLLPtr pll = &info->pll;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
@@ -1191,13 +1207,14 @@ void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
     unsigned postDiv;
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_tvout_ptr tvout = &radeon_output->tvout;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONPLLPtr pll = &info->pll;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M) {
+    if (tvout->tvStd == TV_STD_NTSC ||
+	tvout->tvStd == TV_STD_NTSC_J ||
+	tvout->tvStd == TV_STD_PAL_M) {
 	if (pll->reference_freq == 2700)
 	    constPtr = &availableTVModes[0];
 	else
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 423ea28..2fb5fcc 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2559,7 +2559,7 @@ RADEONDisplayVideo(
 	    radeon_output = output->driver_private;
 	    if (radeon_output->Flags & RADEON_USE_RMX)
 		v_inc = ((src_h * mode->CrtcVDisplay /
-			  radeon_output->PanelYRes) << v_inc_shift) / drw_h;
+			  radeon_output->native_mode.PanelYRes) << v_inc_shift) / drw_h;
 	    break;
 	}
     }
commit 1a62360e8260eaf5f98fa6be3f89f64c8cae7d32
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 10:11:28 2009 -0500

    Encoders not assigned yet, use supported devices
    
    need to move this to encoder setup

diff --git a/src/radeon_output.c b/src/radeon_output.c
index ff30770..78af9a7 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1114,14 +1114,10 @@ radeon_create_resources(xf86OutputPtr output)
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     INT32 range[2];
     int data, err;
     const char *s;
 
-    if (radeon_encoder == NULL)
-	return;
-
 #if 0
     /* backlight control */
     if (radeon_output->type == OUTPUT_LVDS) {
@@ -1197,7 +1193,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
-    if ((!IS_AVIVO_VARIANT) && (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)) {
+    if ((!IS_AVIVO_VARIANT) && (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT))) {
 	tmds_pll_atom = MAKE_ATOM("tmds_pll");
 
 	err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
commit 44d9ceacb1fa6e1859d5d8bd1c55405aea24ad85
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 03:47:32 2009 -0500

    Fix legacy output setup
    
    don't have assigned encoders at this point.  Need to
    eventually move this stuff to encoder dev_priv.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 345252d..ff30770 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2071,21 +2071,19 @@ void RADEONInitConnector(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
-
-    if (radeon_encoder == NULL)
-	return;
 
     radeon_output->rmx_type = RMX_OFF;
 
     if (!IS_AVIVO_VARIANT) {
-	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1)
+	/* XXX fix me  - move to encoders */
+
+	if (radeon_output->devices & (ATOM_DEVICE_DFP2_SUPPORT))
 	    RADEONGetExtTMDSInfo(output);
 
-	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)
+	if (radeon_output->devices & (ATOM_DEVICE_DFP1_SUPPORT))
 	    RADEONGetTMDSInfo(output);
 
-	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) {
+	if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) {
 	    if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
 		radeon_output->load_detection = 1;
 	    radeon_output->tv_on = FALSE;
commit 0c24cbcea56c8f36374aca0f8ba849adfbf0ecfe
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 03:24:19 2009 -0500

    ATOM: print useful output info for DPMS events

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 4634aeb..c8548db 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -45,6 +45,21 @@
 
 #include "ati_pciids_gen.h"
 
+const char *device_name[12] = {
+    "CRT1",
+    "LCD1",
+    "TV1",
+    "DFP1",
+    "CRT2",
+    "LCD2",
+    "TV2",
+    "DFP2",
+    "CV",
+    "DFP3",
+    "DFP4",
+    "DFP5",
+};
+
 static int
 atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
@@ -889,9 +904,11 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
 	    data.exec.pspace = &disp_data;
 
 	    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS)
-		ErrorF("Output %d enable success\n", index);
+		ErrorF("Output %s enable success\n",
+		       device_name[radeon_get_device_index(radeon_output->active_device)]);
 	    else
-		ErrorF("Output %d enable failed\n", index);
+		ErrorF("Output %s enable failed\n",
+		       device_name[radeon_get_device_index(radeon_output->active_device)]);
 	}
 	radeon_encoder->use_count++;
 	break;
@@ -909,9 +926,11 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
 
 		if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data)
 		    == ATOM_SUCCESS)
-		    ErrorF("Output %d disable success\n", index);
+		    ErrorF("Output %s disable success\n",
+			   device_name[radeon_get_device_index(radeon_output->active_device)]);
 		else
-		    ErrorF("Output %d disable failed\n", index);
+		    ErrorF("Output %s disable failed\n",
+			   device_name[radeon_get_device_index(radeon_output->active_device)]);
 	    }
 	}
 	if (radeon_encoder->use_count > 0)
commit 2f92b885457c5cee2098ebbf8c6fe5a5eb98ec48
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 03:12:44 2009 -0500

    Warning fixes

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 9f8bc69..cebd328 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -47,6 +47,9 @@
 #include "sarea.h"
 #endif
 
+extern int
+atombios_get_encoder_mode(xf86OutputPtr output);
+
 AtomBiosResult
 atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock)
 {
diff --git a/src/atombios_output.c b/src/atombios_output.c
index cb1a01c..4634aeb 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -1065,7 +1065,6 @@ atombios_output_mode_set(xf86OutputPtr output,
 			 DisplayModePtr adjusted_mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONInfoPtr info       = RADEONPTR(output->scrn);
     radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
 
     if (radeon_encoder == NULL)
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 1a5fd09..8ec6db2 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -55,6 +55,9 @@ static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color
 static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
 
+extern Bool
+RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo);
+
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
 {
     {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
@@ -823,8 +826,7 @@ legacy_output_dpms(xf86OutputPtr output, int mode)
     RADEONSavePtr save = info->ModeReg;
     unsigned char * RADEONMMIO = info->MMIO;
     unsigned long tmp;
-    RADEONOutputPrivatePtr radeon_output;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
 
     if (radeon_encoder == NULL)
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index a016359..68df40d 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -269,4 +269,13 @@ typedef struct _atomBiosHandle {
 extern Bool
 RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock);
 
+extern uint32_t
+radeon_get_device_index(uint32_t device_support);
+extern radeon_encoder_ptr
+radeon_get_encoder(xf86OutputPtr output);
+extern Bool
+radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support);
+extern uint32_t
+radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supported_device, int dac);
+
 #endif /*  RHD_ATOMBIOS_H_ */
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 349acd2..345252d 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1679,7 +1679,7 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
 
 }
 
-static Bool
+Bool
 RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
 {
     ScrnInfoPtr pScrn = output->scrn;
commit 4cbf6189f3a7945a1141b0451e4f7881ceaaadcd
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 02:59:51 2009 -0500

    Move legacy output setup functions to legacy_output.c

diff --git a/src/legacy_output.c b/src/legacy_output.c
index b7b5728..1a5fd09 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -55,6 +55,131 @@ static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color
 static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
 
+static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
+{
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_LEGACY*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RADEON*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV100*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS100*/
+    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV200*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS200*/
+    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_R200*/
+    {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV250*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS300*/
+    {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R300*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R350*/
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV350*/
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV380*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R420*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS480*/ /* FIXME: just values from rv380 used... */
+};
+
+static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] =
+{
+    0x00000000,   /* unknown */
+    0x00000000,   /* legacy */
+    0x00000000,   /* r100 */
+    0x00280000,   /* rv100 */
+    0x00000000,   /* rs100 */
+    0x00880000,   /* rv200 */
+    0x00000000,   /* rs200 */
+    0x00000000,   /* r200 */
+    0x00770000,   /* rv250 */
+    0x00290000,   /* rs300 */
+    0x00560000,   /* rv280 */
+    0x00780000,   /* r300 */
+    0x00770000,   /* r350 */
+    0x00780000,   /* rv350 */
+    0x00780000,   /* rv380 */
+    0x01080000,   /* r420 */
+    0x01080000,   /* rv410 */ /* FIXME: just values from r420 used... */
+    0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
+    0x00780000,   /* rs480 */ /* FIXME: just values from rv380 used... */
+};
+
+void
+RADEONGetTVDacAdjInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (!RADEONGetDAC2InfoFromBIOS(output)) {
+	radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
+	if (info->IsMobility) { /* some mobility chips may different */
+	    if (info->ChipFamily == CHIP_FAMILY_RV250)
+		radeon_output->ps2_tvdac_adj = 0x00880000;
+	}
+	radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
+	radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
+    }
+}
+
+void
+RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+
+    for (i=0; i<4; i++) {
+        radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+        radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+    }
+}
+
+void
+RADEONGetTMDSInfo(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+
+    for (i=0; i<4; i++) {
+	radeon_output->tmds_pll[i].value = 0;
+	radeon_output->tmds_pll[i].freq = 0;
+    }
+
+    if (!RADEONGetTMDSInfoFromBIOS(output))
+	RADEONGetTMDSInfoFromTable(output);
+}
+
+void
+RADEONGetExtTMDSInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    I2CBusPtr pDVOBus;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+
+    if (radeon_encoder == NULL)
+	return;
+
+    if (!info->IsAtomBios) {
+#if defined(__powerpc__)
+	radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+	radeon_output->dvo_i2c_slave_addr = 0x70;
+#else
+	if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
+	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+	    radeon_output->dvo_i2c_slave_addr = 0x70;
+	}
+#endif
+	if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
+	    radeon_output->DVOChip =
+		RADEONDVODeviceInit(pDVOBus,
+				    radeon_output->dvo_i2c_slave_addr);
+	    if (!radeon_output->DVOChip)
+		xfree(pDVOBus);
+	}
+    }
+}
+
 void
 RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
 			  RADEONSavePtr restore)
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2678b6c..349acd2 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -48,7 +48,7 @@
 #include "radeon_tv.h"
 #include "radeon_atombios.h"
 
-const char *encoder_name[33] = {
+const char *encoder_name[34] = {
     "NONE",
     "INTERNAL_LVDS",
     "INTERNAL_TMDS1",
@@ -105,56 +105,7 @@ const char *ConnectorTypeName[17] = {
   "Unsupported"
 };
 
-static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
-{
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_LEGACY*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RADEON*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV100*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS100*/
-    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV200*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS200*/
-    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_R200*/
-    {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV250*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS300*/
-    {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R300*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R350*/
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV350*/
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV380*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R420*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS480*/ /* FIXME: just values from rv380 used... */
-};
-
-static const uint32_t default_tvdac_adj [CHIP_FAMILY_LAST] =
-{
-    0x00000000,   /* unknown */
-    0x00000000,   /* legacy */
-    0x00000000,   /* r100 */
-    0x00280000,   /* rv100 */
-    0x00000000,   /* rs100 */
-    0x00880000,   /* rv200 */
-    0x00000000,   /* rs200 */
-    0x00000000,   /* r200 */
-    0x00770000,   /* rv250 */
-    0x00290000,   /* rs300 */
-    0x00560000,   /* rv280 */
-    0x00780000,   /* r300 */
-    0x00770000,   /* r350 */
-    0x00780000,   /* rv350 */
-    0x00780000,   /* rv380 */
-    0x01080000,   /* r420 */
-    0x01080000,   /* rv410 */ /* FIXME: just values from r420 used... */
-    0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
-    0x00780000,   /* rs480 */ /* FIXME: just values from rv380 used... */
-};
-
-
 static void RADEONUpdatePanelSize(xf86OutputPtr output);
-static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
-
 extern void atombios_output_mode_set(xf86OutputPtr output,
 				     DisplayModePtr mode,
 				     DisplayModePtr adjusted_mode);
@@ -163,6 +114,14 @@ extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output);
 extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
 extern AtomBiosResult
 atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock);
+extern void
+RADEONGetExtTMDSInfo(xf86OutputPtr output);
+extern void
+RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
+extern void
+RADEONGetTMDSInfo(xf86OutputPtr output);
+extern void
+RADEONGetTVDacAdjInfo(xf86OutputPtr output);
 static void
 radeon_bios_output_dpms(xf86OutputPtr output, int mode);
 static void
@@ -2033,7 +1992,7 @@ RADEONGetLVDSInfo (xf86OutputPtr output)
 	while(tmp_mode) {
 	    if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
 		(tmp_mode->VDisplay == radeon_output->PanelYRes)) {
-		    
+
 		float  refresh =
 		    (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
 		if ((abs(60.0 - refresh) < 1.0) ||
@@ -2067,36 +2026,6 @@ RADEONGetLVDSInfo (xf86OutputPtr output)
 }
 
 static void
-RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
-
-    for (i=0; i<4; i++) {
-        radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
-        radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
-    }
-}
-
-static void
-RADEONGetTMDSInfo(xf86OutputPtr output)
-{
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
-
-    for (i=0; i<4; i++) {
-        radeon_output->tmds_pll[i].value = 0;
-        radeon_output->tmds_pll[i].freq = 0;
-    }
-
-    if (!RADEONGetTMDSInfoFromBIOS(output))
-	RADEONGetTMDSInfoFromTable(output);
-
-}
-
-static void
 RADEONGetTVInfo(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
@@ -2137,25 +2066,6 @@ RADEONGetTVInfo(xf86OutputPtr output)
 
 }
 
-static void
-RADEONGetTVDacAdjInfo(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (!RADEONGetDAC2InfoFromBIOS(output)) {
-	radeon_output->ps2_tvdac_adj = default_tvdac_adj[info->ChipFamily];
-	if (info->IsMobility) { /* some mobility chips may different */
-	    if (info->ChipFamily == CHIP_FAMILY_RV250)
-		radeon_output->ps2_tvdac_adj = 0x00880000;
-	}
-	radeon_output->pal_tvdac_adj = radeon_output->ps2_tvdac_adj;
-	radeon_output->ntsc_tvdac_adj = radeon_output->ps2_tvdac_adj;
-    }
-
-}
-
 void RADEONInitConnector(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
@@ -2166,49 +2076,31 @@ void RADEONInitConnector(xf86OutputPtr output)
     if (radeon_encoder == NULL)
 	return;
 
-    if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) &&
-	xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
-	radeon_output->load_detection = 1;
+    radeon_output->rmx_type = RMX_OFF;
 
-    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-	radeon_output->rmx_type = RMX_FULL;
-	RADEONGetLVDSInfo(output);
-    }
+    if (!IS_AVIVO_VARIANT) {
+	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1)
+	    RADEONGetExtTMDSInfo(output);
 
-    radeon_output->rmx_type = RMX_OFF;
-    if ((!info->IsAtomBios) &&
-	(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1)) {
-	I2CBusPtr pDVOBus;
+	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)
+	    RADEONGetTMDSInfo(output);
 
-#if defined(__powerpc__)
-	radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
-	radeon_output->dvo_i2c_slave_addr = 0x70;
-#else
-	if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
-	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-	    radeon_output->dvo_i2c_slave_addr = 0x70;
-	}
-#endif
-	if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
-	    radeon_output->DVOChip =
-		RADEONDVODeviceInit(pDVOBus,
-				    radeon_output->dvo_i2c_slave_addr);
-	    if (!radeon_output->DVOChip)
-		xfree(pDVOBus);
+	if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) {
+	    if (xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
+		radeon_output->load_detection = 1;
+	    radeon_output->tv_on = FALSE;
+	    RADEONGetTVDacAdjInfo(output);
 	}
     }
 
-    if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)
-	RADEONGetTMDSInfo(output);
+    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+	radeon_output->rmx_type = RMX_FULL;
+	RADEONGetLVDSInfo(output);
+    }
 
     if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
 	RADEONGetTVInfo(output);
 
-    if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) {
-	radeon_output->tv_on = FALSE;
-	RADEONGetTVDacAdjInfo(output);
-    }
-
     if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))
 	radeon_output->coherent_mode = TRUE;
 
commit 93ed767255b60fbdf5b416b9bd06c366036a5141
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 02:40:41 2009 -0500

    Fix off by one when printing encoder name
    
    - also cleanup some debugging output

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 1957e1d..9f8bc69 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -323,11 +323,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
     data.exec.pspace = ptr;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Set CRTC PLL success\n");
+	ErrorF("Set CRTC %d PLL success\n", radeon_crtc->crtc_id);
 	return;
     }
 
-    ErrorF("Set CRTC PLL failed\n");
+    ErrorF("Set CRTC %d PLL failed\n", radeon_crtc->crtc_id);
     return;
 }
 
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 92ae3f5..cb1a01c 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -54,7 +54,7 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
     DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
-    int index;
+    int index, num = 0;
 
     if (radeon_encoder == NULL)
 	return ATOM_NOT_IMPLEMENTED;
@@ -65,10 +65,12 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
     case ENCODER_OBJECT_ID_INTERNAL_DAC1:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
 	index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
+	num = 1;
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DAC2:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 	index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
+	num = 2;
 	break;
     }
 
@@ -102,11 +104,11 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output DAC setup success\n");
+	ErrorF("Output DAC%d setup success\n", num);
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output DAC setup failed\n");
+    ErrorF("Output DAC%d setup failed\n", num);
     return ATOM_NOT_IMPLEMENTED;
 
 }
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 68adb0d..d7d5f7c 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2010,7 +2010,6 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	switch (dac) {
 	    // primary dac
 	case 1:
-	    ErrorF("adding primary dac\n");
 	    if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
 		(info->ChipFamily == CHIP_FAMILY_RS400) ||
 		(info->ChipFamily == CHIP_FAMILY_RS480))
@@ -2022,7 +2021,6 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    break;
 	    // secondary dac
 	case 2:
-	    ErrorF("adding tv dac\n");
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
 	    else {
@@ -2034,7 +2032,6 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    break;
 	    // external dac
 	case 3:
-	    ErrorF("adding external dac\n");
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
 	    else
@@ -2043,14 +2040,12 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	}
 	break;
     case ATOM_DEVICE_LCD1_SUPPORT:
-	ErrorF("adding LVDS\n");
 	if (IS_AVIVO_VARIANT)
 	    ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
 	else
 	    ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
 	break;
     case ATOM_DEVICE_DFP1_SUPPORT:
-	ErrorF("adding FP1\n");
 	if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS400) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS480))
@@ -2062,7 +2057,6 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	break;
     case ATOM_DEVICE_LCD2_SUPPORT:
     case ATOM_DEVICE_DFP2_SUPPORT:
-	ErrorF("adding FP2\n");
 	if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS740))
@@ -2073,7 +2067,6 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
 	break;
     case ATOM_DEVICE_DFP3_SUPPORT:
-	ErrorF("adding FP3\n");
 	ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
 	break;
     }
diff --git a/src/radeon_output.c b/src/radeon_output.c
index a2f0a29..2678b6c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -59,6 +59,7 @@ const char *encoder_name[33] = {
     "INTERNAL_SDVOB",
     "SI170B",
     "CH7303",
+    "CH7301",
     "INTERNAL_DVO1",
     "EXTERNAL_SDVOA",
     "EXTERNAL_SDVOB",
@@ -182,6 +183,7 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 	radeon_output = output->driver_private;
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o);
+	ErrorF("  XRANDR name: %s\n", output->name);
 	ErrorF("  Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]);
 	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
 	    ErrorF("  CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
commit b515eee4b1cafae78ed39cd91c18b4f5e671b20b
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 26 01:50:18 2009 -0500

    Additional output cleanup

diff --git a/src/atombios_output.c b/src/atombios_output.c
index a6bfa7a..92ae3f5 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -431,8 +431,7 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
-    int index;
-    int major, minor;
+    int index, major, minor, num = 0;
 
     if (radeon_encoder == NULL)
 	return ATOM_NOT_IMPLEMENTED;
@@ -444,17 +443,20 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
 	else
 	    index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	num = radeon_crtc->crtc_id + 1;
     } else {
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
 	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	    index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	    num = 1;
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	    num = 2;
 	    break;
 	}
     }
@@ -509,11 +511,11 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output DIG%d encoder setup success\n", radeon_crtc->crtc_id + 1);
+	ErrorF("Output DIG%d encoder setup success\n", num);
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output DIG%d setup failed\n", radeon_crtc->crtc_id + 1);
+    ErrorF("Output DIG%d setup failed\n", num);
     return ATOM_NOT_IMPLEMENTED;
 
 }
@@ -1073,17 +1075,16 @@ atombios_output_mode_set(xf86OutputPtr output,
     switch (radeon_encoder->encoder_id) {
     case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	atombios_output_digital_setup(output, adjusted_mode);
+	break;
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-	if (IS_DCE3_VARIANT) {
-	    atombios_output_dig_encoder_setup(output, adjusted_mode);
-	    atombios_output_dig_transmitter_setup(output, adjusted_mode);
-	} else
-	    atombios_output_digital_setup(output, adjusted_mode);
+	atombios_output_dig_encoder_setup(output, adjusted_mode);
+	atombios_output_dig_transmitter_setup(output, adjusted_mode);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DDI:
 	atombios_output_ddia_setup(output, adjusted_mode);
@@ -1097,8 +1098,7 @@ atombios_output_mode_set(xf86OutputPtr output,
     case ENCODER_OBJECT_ID_INTERNAL_DAC2:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 	atombios_output_dac_setup(output, adjusted_mode);
-	if ((radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) ||
-	    (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT)))
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT))
 	    atombios_output_tv_setup(output, adjusted_mode);
 	break;
     }
@@ -1171,8 +1171,9 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
 }
 
 RADEONMonitorType
-atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
+atombios_dac_detect(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 5489614..b7b5728 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -565,8 +565,9 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
 #endif
 
 RADEONMonitorType
-legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
+legacy_dac_detect(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info      = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONMonitorType found = MT_NONE;
diff --git a/src/radeon.h b/src/radeon.h
index 0c114c6..9b724ec 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -866,8 +866,7 @@ extern void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 extern void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save);
 
 /* legacy_output.c */
-extern RADEONMonitorType legacy_dac_detect(ScrnInfoPtr pScrn,
-					   xf86OutputPtr output);
+extern RADEONMonitorType legacy_dac_detect(xf86OutputPtr output);
 extern void legacy_output_dpms(xf86OutputPtr output, int mode);
 extern void legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 				   DisplayModePtr adjusted_mode);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index de1af5d..a2f0a29 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -48,20 +48,6 @@
 #include "radeon_tv.h"
 #include "radeon_atombios.h"
 
-
-const RADEONMonitorType MonTypeID[10] = {
-  MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
-  MT_NONE,    /* NONE -> NONE */
-  MT_CRT,     /* CRT -> CRT */
-  MT_LCD,     /* Laptop LCDs are driven via LVDS port */
-  MT_DFP,     /* DFPs are driven via TMDS */
-  MT_CTV,     /* CTV -> CTV */
-  MT_STV,     /* STV -> STV */
-  MT_CV,
-  MT_HDMI,
-  MT_DP
-};
-
 const char *encoder_name[33] = {
     "NONE",
     "INTERNAL_LVDS",
@@ -172,7 +158,7 @@ extern void atombios_output_mode_set(xf86OutputPtr output,
 				     DisplayModePtr mode,
 				     DisplayModePtr adjusted_mode);
 extern void atombios_output_dpms(xf86OutputPtr output, int mode);
-extern RADEONMonitorType atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output);
+extern RADEONMonitorType atombios_dac_detect(xf86OutputPtr output);
 extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
 extern AtomBiosResult
 atombios_lock_crtc(atomBiosHandlePtr atomBIOS, int crtc, int lock);
@@ -222,6 +208,54 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 
 }
 
+static void
+radeon_set_active_device(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    radeon_output->active_device = 0;
+
+    switch (radeon_output->MonType) {
+    case MT_DFP:
+	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
+	break;
+    case MT_CRT:
+	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
+	break;
+    case MT_LCD:
+	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
+	break;
+    case MT_STV:
+    case MT_CTV:
+	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
+	break;
+    case MT_CV:
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
+	break;
+    default:
+	radeon_output->active_device = 0;
+    }
+}
+
 static RADEONMonitorType
 radeon_ddc_connected(xf86OutputPtr output)
 {
@@ -348,50 +382,6 @@ RADEONDetectLidStatus(ScrnInfoPtr pScrn)
 #endif /* __powerpc__ */
 
 static void
-RADEONConnectorFindMonitor(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn        = output->scrn;
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (radeon_output->MonType == MT_UNKNOWN) {
-	radeon_output->MonType = radeon_ddc_connected(output);
-	if (!radeon_output->MonType) {
-	    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
-		if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE))
-		    radeon_output->MonType = MT_LCD;
-		else
-#if defined(__powerpc__)
-		    radeon_output->MonType = MT_LCD;
-#else
-		    radeon_output->MonType = RADEONDetectLidStatus(pScrn);
-#endif
-	    } else {
-		if (info->IsAtomBios)
-		    radeon_output->MonType = atombios_dac_detect(pScrn, output);
-		else
-		    radeon_output->MonType = legacy_dac_detect(pScrn, output);
-	    }
-	}
-    }
-
-    /* update panel info for RMX */
-    if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
-	RADEONUpdatePanelSize(output);
-
-    /* panel is probably busted or not connected */
-    if ((radeon_output->MonType == MT_LCD) &&
-	((radeon_output->PanelXRes == 0) || (radeon_output->PanelYRes == 0)))
-	radeon_output->MonType = MT_NONE;
-
-    if (output->MonInfo) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n",
-		   output->name);
-	xf86PrintEDID( output->MonInfo );
-    }
-}
-
-static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
     RADEONInfoPtr info = RADEONPTR(output->scrn);
@@ -484,7 +474,7 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
     xf86SetModeCrtc(adjusted_mode, 0);
 
     /* decide if we are using RMX */
-    if ((radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
+    if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT))
 	&& radeon_output->rmx_type != RMX_OFF) {
 	xf86CrtcPtr crtc = output->crtc;
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
@@ -1001,7 +991,39 @@ radeon_detect(xf86OutputPtr output)
 
     radeon_output->MonType = MT_UNKNOWN;
     radeon_bios_output_connected(output, FALSE);
-    RADEONConnectorFindMonitor(output);
+    radeon_output->MonType = radeon_ddc_connected(output);
+    if (!radeon_output->MonType) {
+	if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
+	    if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE))
+		radeon_output->MonType = MT_LCD;
+	    else
+#if defined(__powerpc__)
+		radeon_output->MonType = MT_LCD;
+#else
+	        radeon_output->MonType = RADEONDetectLidStatus(pScrn);
+#endif
+	} else {
+	    if (info->IsAtomBios)
+		radeon_output->MonType = atombios_dac_detect(output);
+	    else
+		radeon_output->MonType = legacy_dac_detect(output);
+	}
+    }
+
+    /* update panel info for RMX */
+    if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
+	RADEONUpdatePanelSize(output);
+
+    /* panel is probably busted or not connected */
+    if ((radeon_output->MonType == MT_LCD) &&
+	((radeon_output->PanelXRes == 0) || (radeon_output->PanelYRes == 0)))
+	radeon_output->MonType = MT_NONE;
+
+    if (output->MonInfo) {
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on output: %s ----------------------\n",
+		   output->name);
+	xf86PrintEDID( output->MonInfo );
+    }
 
     /* nothing connected, light up some defaults so the server comes up */
     if (radeon_output->MonType == MT_NONE &&
@@ -1064,70 +1086,17 @@ radeon_detect(xf86OutputPtr output)
 	}
     }
 
-    if (radeon_output->MonType == MT_DFP) {
-	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_LCD) {
-	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if ((radeon_output->MonType == MT_STV) ||
-	       (radeon_output->MonType == MT_CTV)){
-	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_CV) {
-	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else
-	radeon_output->active_device = 0;
-
-    if (radeon_output->MonType == MT_UNKNOWN) {
-        output->subpixel_order = SubPixelUnknown;
-	return XF86OutputStatusUnknown;
-    } else {
-
-      switch(radeon_output->MonType) {
-      case MT_LCD:
-      case MT_DFP:
-	  output->subpixel_order = SubPixelHorizontalRGB;
-	  break;
-      default:
-	  output->subpixel_order = SubPixelNone;
-	  break;
-      }
+    radeon_set_active_device(output);
 
-      if (connected)
-	  return XF86OutputStatusConnected;
-      else
-	  return XF86OutputStatusDisconnected;
-    }
+    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT))
+	output->subpixel_order = SubPixelHorizontalRGB;
+    else
+	output->subpixel_order = SubPixelNone;
 
+    if (connected)
+	return XF86OutputStatusConnected;
+    else
+	return XF86OutputStatusDisconnected;
 }
 
 static DisplayModePtr
commit 289b4a377cfff0c2a8ec938951cfbae1e270570e
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 23 20:00:43 2009 -0500

    Remove OutputType and other cruft

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 636373d..a6bfa7a 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -282,7 +282,8 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	case 1:
 	    disp_data.ucMisc = 0;
 	    disp_data.ucAction = PANEL_ENCODER_ACTION_ENABLE;
-	    if (radeon_output->type == OUTPUT_HDMI)
+	    if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
+		(radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B))
 		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
 	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
@@ -310,7 +311,8 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 		    xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Coherent Mode enabled\n");
 		}
 	    }
-	    if (radeon_output->type == OUTPUT_HDMI)
+	    if ((radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
+		(radeon_output->ConnectorType == CONNECTOR_HDMI_TYPE_B))
 		disp_data2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data2.usPixelClock = cpu_to_le16(mode->Clock / 10);
 	    disp_data2.ucTruncate = 0;
@@ -585,7 +587,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    break;
 	}
 
-	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+	if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
 	    if (radeon_output->coherent_mode) {
 		disp_data.v2.acConfig.fCoherentMode = 1;
 		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "UNIPHY%d transmitter: Coherent Mode enabled\n",disp_data.v2.acConfig.ucTransmitterSel);
@@ -653,7 +655,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    break;
 	}
 
-	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+	if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT)) {
 	    if (radeon_output->coherent_mode) {
 		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
 		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode enabled\n", num);
@@ -694,7 +696,7 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 
     disp_data.ucScaler = radeon_crtc->crtc_id;
 
-    if (OUTPUT_IS_TV) {
+    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 	switch (radeon_output->tvStd) {
 	case TV_STD_NTSC:
 	    disp_data.ucTVStandard = ATOM_TV_NTSC;
@@ -726,7 +728,10 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 	}
 	disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
         ErrorF("Using TV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable);
-
+    } else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
+	disp_data.ucTVStandard = ATOM_TV_CV;
+	disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE;
+        ErrorF("Using CV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable);
     } else if (radeon_output->Flags & RADEON_USE_RMX) {
 	ErrorF("Using RMX\n");
 	if (radeon_output->rmx_type == RMX_FULL)
@@ -1177,7 +1182,7 @@ atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
 
     if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
 	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
-	    if (radeon_output->type == OUTPUT_STV)
+	    if (radeon_output->ConnectorType == CONNECTOR_STV)
 		return MT_STV;
 	    else
 		return MT_CTV;
diff --git a/src/legacy_output.c b/src/legacy_output.c
index e4e81d0..5489614 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -573,7 +573,7 @@ legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
 
     if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) {
 	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
-	    if (radeon_output->type == OUTPUT_STV)
+	    if (radeon_output->ConnectorType == CONNECTOR_STV)
 		found = MT_STV;
 	    else
 		found = MT_CTV;
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index fa3301e..50b32a9 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -266,7 +266,7 @@ static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
 
 	if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue;
 
-	if (radeon_output->type == OUTPUT_LVDS) {
+	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 	    /* already added the native mode */
 	    if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
 		continue;
@@ -329,12 +329,12 @@ RADEONProbeOutputModes(xf86OutputPtr output)
     ErrorF("in RADEONProbeOutputModes\n");
 
     if (output->status == XF86OutputStatusConnected) {
-	if (OUTPUT_IS_TV) {
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 	    if (IS_AVIVO_VARIANT)
 		modes = RADEONATOMTVModes(output);
 	    else
 		modes = RADEONTVModes(output);
-	} else if (radeon_output->type == OUTPUT_CV) {
+	} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
 	    atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex, info->atomBIOS,
 					     ATOMBIOS_GET_CV_MODES, &atomBiosArg);
 	    if (atomBiosResult == ATOM_SUCCESS) {
@@ -350,7 +350,7 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		modes = RADEONeMacModes(output);
 #endif
 	    if (modes == NULL) {
-		if ((radeon_output->type == OUTPUT_LVDS) && info->IsAtomBios) {
+		if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && info->IsAtomBios) {
 		    atomBiosResult = RHDAtomBiosFunc(pScrn->scrnIndex,
 						     info->atomBIOS,
 						     ATOMBIOS_GET_PANEL_EDID, &atomBiosArg);
@@ -361,7 +361,7 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		    }
 		}
 		if (modes == NULL) {
-		    if (radeon_output->type == OUTPUT_LVDS)
+		    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
 			modes = RADEONFPNativeMode(output);
 		    /* add the screen modes */
 		    RADEONAddScreenModes(output, &modes);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index e502310..de1af5d 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -104,8 +104,8 @@ const char *ConnectorTypeName[17] = {
   "DVI-I",
   "DVI-D",
   "DVI-A",
-  "STV",
-  "CTV",
+  "S-video",
+  "Composite",
   "LVDS",
   "Digital",
   "SCART",
@@ -118,20 +118,6 @@ const char *ConnectorTypeName[17] = {
   "Unsupported"
 };
 
-const char *OutputType[11] = {
-    "None",
-    "VGA",
-    "DVI",
-    "DVI",
-    "DVI",
-    "LVDS",
-    "S-video",
-    "Composite",
-    "Component",
-    "HDMI",
-    "DisplayPort",
-};
-
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
 {
     {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
@@ -267,32 +253,40 @@ radeon_ddc_connected(xf86OutputPtr output)
 	}
     }
     if (MonInfo) {
-	if (radeon_output->type == OUTPUT_LVDS)
+	switch (radeon_output->ConnectorType) {
+	case CONNECTOR_LVDS:
 	    MonType = MT_LCD;
-	else if (radeon_output->type == OUTPUT_DVI_D)
-	    MonType = MT_DFP;
-	else if (radeon_output->type == OUTPUT_HDMI)
-	    MonType = MT_DFP;
-	else if (radeon_output->type == OUTPUT_DP)
-	    MonType = MT_DFP;
-	else if (radeon_output->type == OUTPUT_DVI_I &&
-		 (MonInfo->rawData[0x14] & 0x80)) /* if it's digital and DVI */
-	    MonType = MT_DFP;
-	else
-	    MonType = MT_CRT;
-
-	if (radeon_output->shared_ddc) {
-	    if (radeon_output->type == OUTPUT_VGA) {
-		if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */
-		    MonType = MT_NONE;
-		else
-		    MonType = MT_CRT;
-	    } else {
+	    break;
+	case CONNECTOR_DVI_D:
+	case CONNECTOR_HDMI_TYPE_A:
+	case CONNECTOR_HDMI_TYPE_B:
+	    if (radeon_output->shared_ddc) {
 		if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI/HDMI/etc. */
 		    MonType = MT_DFP;
 		else
 		    MonType = MT_NONE;
-	    }
+	    } else
+		MonType = MT_DFP;
+	    break;
+	case CONNECTOR_DISPLAY_PORT:
+	    MonType = MT_DP;
+	case CONNECTOR_DVI_I:
+	    if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and DVI */
+		MonType = MT_DFP;
+	    else
+		MonType = MT_CRT;
+	    break;
+	case CONNECTOR_VGA:
+	case CONNECTOR_DVI_A:
+	default:
+	    if (radeon_output->shared_ddc) {
+		if (MonInfo->rawData[0x14] & 0x80) /* if it's digital and VGA */
+		    MonType = MT_NONE;
+		else
+		    MonType = MT_CRT;
+	    } else
+		MonType = MT_CRT;
+	    break;
 	}
 
 	if (MonType != MT_NONE)
@@ -363,7 +357,7 @@ RADEONConnectorFindMonitor(xf86OutputPtr output)
     if (radeon_output->MonType == MT_UNKNOWN) {
 	radeon_output->MonType = radeon_ddc_connected(output);
 	if (!radeon_output->MonType) {
-	    if (radeon_output->type == OUTPUT_LVDS) {
+	    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 		if (xf86ReturnOptValBool(info->Options, OPTION_IGNORE_LID_STATUS, TRUE))
 		    radeon_output->MonType = MT_LCD;
 		else
@@ -450,27 +444,9 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 	    return MODE_BANDWIDTH;
     }
 
-    if (OUTPUT_IS_TV) {
+    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 	/* FIXME: Update when more modes are added */
-	if (IS_AVIVO_VARIANT) {
-	    int max_v;
-
-	    /* tv-scaler can scale horizontal width
-	     * but frame ends must match tv_pll
-	     * for now cap v size
-	     */
-	    if (radeon_output->tvStd == TV_STD_NTSC ||
-		radeon_output->tvStd == TV_STD_NTSC_J ||
-		radeon_output->tvStd == TV_STD_PAL_M)
-		max_v = 480;
-	    else
-		max_v = 600;
-
-	    if (pMode->VDisplay == max_v)
-		return MODE_OK;
-	    else
-		return MODE_CLOCK_RANGE;
-	} else {
+	if (!info->IsAtomBios) {
 	    if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
 		return MODE_OK;
 	    else
@@ -478,7 +454,7 @@ radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 	}
     }
 
-    if (radeon_output->type == OUTPUT_LVDS) {
+    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 	if (radeon_output->rmx_type == RMX_OFF) {
 	    if (pMode->HDisplay != radeon_output->PanelXRes ||
 		pMode->VDisplay != radeon_output->PanelYRes)
@@ -1031,21 +1007,20 @@ radeon_detect(xf86OutputPtr output)
     if (radeon_output->MonType == MT_NONE &&
 	info->first_load_no_devices) {
 	if (info->IsMobility) {
-	    if (radeon_output->type == OUTPUT_LVDS) {
+	    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 		radeon_output->MonType = MT_LCD;
 		info->first_load_no_devices = FALSE;
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LVDS default\n");
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using LCD default\n");
 	    }
 	} else {
-	    if (radeon_output->type == OUTPUT_VGA ||
-		radeon_output->type == OUTPUT_DVI_I) {
+	    if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
 		radeon_output->MonType = MT_CRT;
 		info->first_load_no_devices = FALSE;
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using VGA default\n");
-	    } else if (radeon_output->type == OUTPUT_DVI_D) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using CRT default\n");
+	    } else if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 		radeon_output->MonType = MT_DFP;
 		info->first_load_no_devices = FALSE;
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DVI default\n");
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Using DFP default\n");
 	    }
 	}
     }
@@ -1055,27 +1030,37 @@ radeon_detect(xf86OutputPtr output)
     /* set montype so users can force outputs on even if detection fails */
     if (radeon_output->MonType == MT_NONE) {
 	connected = FALSE;
-	if (radeon_output->type == OUTPUT_LVDS)
+	switch (radeon_output->ConnectorType) {
+	case CONNECTOR_LVDS:
 	    radeon_output->MonType = MT_LCD;
-	else if (radeon_output->type == OUTPUT_VGA)
-            radeon_output->MonType = MT_CRT;
-	else if (radeon_output->type == OUTPUT_STV)
-            radeon_output->MonType = MT_STV;
-	else if (radeon_output->type == OUTPUT_CTV)
-            radeon_output->MonType = MT_CTV;
-	else if (radeon_output->type == OUTPUT_CV)
-            radeon_output->MonType = MT_CV;
-	else if (radeon_output->type == OUTPUT_DVI_D)
-	    radeon_output->MonType = MT_DFP;
-	else if (radeon_output->type == OUTPUT_HDMI)
+	    break;
+	case CONNECTOR_DVI_D:
+	case CONNECTOR_HDMI_TYPE_A:
+	case CONNECTOR_HDMI_TYPE_B:
 	    radeon_output->MonType = MT_DFP;
-	else if (radeon_output->type == OUTPUT_DVI_A)
+	    break;
+	case CONNECTOR_VGA:
+	case CONNECTOR_DVI_A:
+	default:
 	    radeon_output->MonType = MT_CRT;
-	else if (radeon_output->type == OUTPUT_DVI_I) {
+	    break;
+	case CONNECTOR_DVI_I:
 	    if (radeon_output->DVIType == DVI_ANALOG)
 		radeon_output->MonType = MT_CRT;
 	    else if (radeon_output->DVIType == DVI_DIGITAL)
 		radeon_output->MonType = MT_DFP;
+	    break;
+	case CONNECTOR_STV:
+            radeon_output->MonType = MT_STV;
+	    break;
+	case CONNECTOR_CTV:
+            radeon_output->MonType = MT_CTV;
+	    break;
+	case CONNECTOR_DIN:
+            radeon_output->MonType = MT_CV;
+	    break;
+	case CONNECTOR_DISPLAY_PORT:
+	    break;
 	}
     }
 
@@ -1323,7 +1308,7 @@ radeon_create_resources(xf86OutputPtr output)
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the property */
-	if (radeon_output->type == OUTPUT_LVDS)
+	if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))
 	    s = "full";
 	else
 	    s = "off";
@@ -1687,59 +1672,6 @@ static const xf86OutputFuncsRec radeon_output_funcs = {
     .destroy = radeon_destroy
 };
 
-void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
-{
-    RADEONOutputType output = OUTPUT_NONE;
-
-    switch(radeon_output->ConnectorType) {
-    case CONNECTOR_VGA:
-	output = OUTPUT_VGA; break;
-    case CONNECTOR_DVI_I:
-	output = OUTPUT_DVI_I; break;
-    case CONNECTOR_DVI_D:
-	output = OUTPUT_DVI_D; break;
-    case CONNECTOR_DVI_A:
-	output = OUTPUT_DVI_A; break;
-    case CONNECTOR_DIN:
-	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-	    output = OUTPUT_CV;
-	else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-	    output = OUTPUT_STV;
-	break;
-    case CONNECTOR_STV:
-	output = OUTPUT_STV; break;
-    case CONNECTOR_CTV:
-	output = OUTPUT_CTV; break;
-    case CONNECTOR_LVDS:
-	output = OUTPUT_LVDS; break;
-    case CONNECTOR_HDMI_TYPE_A:
-    case CONNECTOR_HDMI_TYPE_B:
-	output = OUTPUT_HDMI; break;
-    case CONNECTOR_DISPLAY_PORT:
-	output = OUTPUT_DP; break;
-    case CONNECTOR_DIGITAL:
-    case CONNECTOR_NONE:
-    case CONNECTOR_UNSUPPORTED:
-    default:
-	output = OUTPUT_NONE; break;
-    }
-    radeon_output->type = output;
-}
-
-#if 0
-static
-Bool AVIVOI2CReset(ScrnInfoPtr pScrn)
-{
-  RADEONInfoPtr info = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-
-  OUTREG(AVIVO_I2C_STOP, 1);
-  INREG(AVIVO_I2C_STOP);
-  OUTREG(AVIVO_I2C_STOP, 0x0);
-  return TRUE;
-}
-#endif
-
 Bool
 RADEONI2CDoLock(xf86OutputPtr output, int lock_state)
 {
@@ -3122,7 +3054,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->MonType = MT_UNKNOWN;
 	    radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
 	    radeon_output->devices = info->BiosConnector[i].devices;
-	    radeon_output->output_id = info->BiosConnector[i].output_id;
 	    radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c;
 	    radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info;
 	    radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc;
@@ -3130,7 +3061,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->linkb = info->BiosConnector[i].linkb;
 	    radeon_output->connector_id = info->BiosConnector[i].connector_object;
 
-	    RADEONSetOutputType(pScrn, radeon_output);
 	    if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
 		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
 		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
@@ -3156,7 +3086,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, "HDMI-0");
 		}
 	    } else
-		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs,
+					  ConnectorTypeName[radeon_output->ConnectorType]);
 
 	    if (!output) {
 		return FALSE;
@@ -3164,10 +3095,10 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    output->driver_private = radeon_output;
 	    output->possible_crtcs = 1;
 	    /* crtc2 can drive LVDS, it just doesn't have RMX */
-	    if (radeon_output->type != OUTPUT_LVDS)
+	    if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)))
 		output->possible_crtcs |= 2;
 
-	    /* we can clone the DACs, and probably TV-out, 
+	    /* we can clone the DACs, and probably TV-out,
 	       but I'm not sure it's worth the trouble */
 	    output->possible_clones = 0;
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 7b52c4e..6da24c2 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -109,27 +109,6 @@ typedef struct {
     uint32_t value;
 }RADEONTMDSPll;
 
-typedef enum
-{
-    OUTPUT_NONE,
-    OUTPUT_VGA,
-    OUTPUT_DVI_I,
-    OUTPUT_DVI_D,
-    OUTPUT_DVI_A,
-    OUTPUT_LVDS,
-    OUTPUT_STV,
-    OUTPUT_CTV,
-    OUTPUT_CV,
-    OUTPUT_HDMI,
-    OUTPUT_DP
-} RADEONOutputType;
-
-#define OUTPUT_IS_DVI ((radeon_output->type == OUTPUT_DVI_D || \
-                        radeon_output->type == OUTPUT_DVI_I || \
-                        radeon_output->type == OUTPUT_DVI_A))
-#define OUTPUT_IS_TV ((radeon_output->type == OUTPUT_STV || \
-                       radeon_output->type == OUTPUT_CTV))
-
 /* standards */
 typedef enum
 {
@@ -202,18 +181,27 @@ typedef struct {
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
-    int num;
-    RADEONOutputType type;
-    void *dev_priv;
-    uint32_t ddc_line;
+    uint16_t connector_id;
+    uint32_t devices;
+    uint32_t active_device;
+    Bool enabled;
+
+    RADEONConnectorType ConnectorType;
     RADEONDviType DVIType;
     RADEONMonitorType MonType;
-    int crtc_num;
-    int DDCReg;
 
+    // DDC info
+    I2CBusPtr         pI2CBus;
+    RADEONI2CBusRec   ddc_i2c;
+    Bool shared_ddc;
+    // router info
+    // HDP info
+
+    // tv dac
     uint32_t          ps2_tvdac_adj;
     uint32_t          pal_tvdac_adj;
     uint32_t          ntsc_tvdac_adj;
+
     /* panel stuff */
     int               PanelXRes;
     int               PanelYRes;
@@ -225,16 +213,24 @@ typedef struct _RADEONOutputPrivateRec {
     int               VBlank;
     int               Flags;            /* Saved copy of mode flags          */
     int               DotClock;
+
+    // lvds
     int               PanelPwrDly;
     int               lvds_misc;
     int               lvds_ss_id;
+
+    // tmds
     RADEONTMDSPll     tmds_pll[4];
+
+    // RMX
     RADEONRMXType     rmx_type;
+
     /* dvo */
     I2CDevPtr         DVOChip;
     RADEONI2CBusRec   dvo_i2c;
     int               dvo_i2c_slave_addr;
     Bool              dvo_duallink;
+
     /* TV out */
     TVStd             default_tvStd;
     TVStd             tvStd;
@@ -245,33 +241,13 @@ typedef struct _RADEONOutputPrivateRec {
     int               SupportedTVStds;
     Bool              tv_on;
     int               load_detection;
+
     /* dig block */
     int transmitter_config;
     Bool coherent_mode;
     int igp_lane_info;
     Bool linkb;
 
-    char              *name;
-    int               output_id;
-    //int               devices;
-    Bool enabled;
-
-    // re-org
-    uint16_t connector_id;
-    uint32_t devices;
-    uint32_t active_device;
-    //RADEONConnectorType connector_type;
-    RADEONConnectorType ConnectorType;
-    // DDC info
-    I2CBusPtr         pI2CBus;
-    RADEONI2CBusRec   ddc_i2c;
-    // router info
-    // HDP info
-    // shared_ddc
-    Bool shared_ddc;
-    // cvtv pin
-    // preferred mode
-
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 struct avivo_pll_state {
commit 0faab02cc732414af3cfb2014d3ddc1139aff063
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 23 17:35:01 2009 -0500

    Remove some unused cruft

diff --git a/src/radeon.h b/src/radeon.h
index 7705b2a..0c114c6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -793,16 +793,13 @@ typedef struct {
     DisplayModePtr currentMode, savedCurrentMode;
 
     /* special handlings for DELL triple-head server */
-    Bool              IsDellServer; 
+    Bool              IsDellServer;
 
     Bool              VGAAccess;
 
     int               MaxSurfaceWidth;
     int               MaxLines;
 
-    uint32_t          tv_dac_adj;
-    uint32_t          tv_dac_enable_mask;
-
     Bool want_vblank_interrupts;
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
     radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
@@ -813,7 +810,6 @@ typedef struct {
     Bool              crtc2_on;
 
     Bool              InternalTVOut;
-    int               tvdac_use_count;
 
 #if defined(__powerpc__)
     RADEONMacModel    MacModel;
@@ -824,14 +820,6 @@ typedef struct {
     unsigned long FbFreeStart, FbFreeSize;
     unsigned char*      BIOSCopy;
 
-    /* output enable masks for outputs shared across connectors */
-    int output_crt1;
-    int output_crt2;
-    int output_dfp1;
-    int output_dfp2;
-    int output_lcd1;
-    int output_tv1;
-
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
     CreateScreenResourcesProcPtr CreateScreenResources;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 83aaf4f..e502310 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -3108,14 +3108,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	}
     }
 
-    /* clear the enable masks */
-    info->output_crt1 = 0;
-    info->output_crt2 = 0;
-    info->output_dfp1 = 0;
-    info->output_dfp2 = 0;
-    info->output_lcd1 = 0;
-    info->output_tv1 = 0;
-
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
 	    RADEONOutputPrivatePtr radeon_output;
commit 025082160c53c01a44f4d681cc63bf26ac4561d5
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 23 17:31:18 2009 -0500

    track encoder state

diff --git a/src/atombios_output.c b/src/atombios_output.c
index a39c6e4..636373d 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -819,6 +819,7 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
     AtomBiosArgRec data;
     unsigned char *space;
     int index = 0;
+    Bool is_dig = FALSE;
 
     if (radeon_encoder == NULL)
         return;
@@ -831,8 +832,8 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
     case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-	(void)atombios_dig_dpms(output, mode);
-	return;
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	is_dig = TRUE;
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DVO1:
     case ENCODER_OBJECT_ID_INTERNAL_DDI:
@@ -843,7 +844,6 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
 	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
 	    index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
 	else
@@ -871,24 +871,44 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
 
     switch (mode) {
     case DPMSModeOn:
-	disp_data.ucAction = ATOM_ENABLE;
+	if (is_dig)
+	    (void)atombios_dig_dpms(output, mode);
+	else {
+	    disp_data.ucAction = ATOM_ENABLE;
+	    data.exec.index = index;
+	    data.exec.dataSpace = (void *)&space;
+	    data.exec.pspace = &disp_data;
+
+	    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS)
+		ErrorF("Output %d enable success\n", index);
+	    else
+		ErrorF("Output %d enable failed\n", index);
+	}
+	radeon_encoder->use_count++;
 	break;
     case DPMSModeStandby:
     case DPMSModeSuspend:
     case DPMSModeOff:
-	disp_data.ucAction = ATOM_DISABLE;
+	if (radeon_encoder->use_count < 2) {
+	    if (is_dig)
+		(void)atombios_dig_dpms(output, mode);
+	    else {
+		disp_data.ucAction = ATOM_DISABLE;
+		data.exec.index = index;
+		data.exec.dataSpace = (void *)&space;
+		data.exec.pspace = &disp_data;
+
+		if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data)
+		    == ATOM_SUCCESS)
+		    ErrorF("Output %d disable success\n", index);
+		else
+		    ErrorF("Output %d disable failed\n", index);
+	    }
+	}
+	if (radeon_encoder->use_count > 0)
+	    radeon_encoder->use_count--;
 	break;
     }
-
-    data.exec.index = index;
-    data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &disp_data;
-
-    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output %d %s success\n", index, disp_data.ucAction? "enable":"disable");
-    }
-
-    ErrorF("Output %d %s failed\n", index, disp_data.ucAction? "enable":"disable");
 }
 
 static void
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 1b58c32..e4e81d0 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -689,9 +689,8 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
     }
 }
 
-/* This is to be used enable/disable displays dynamically */
-static void
-RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
+void
+legacy_output_dpms(xf86OutputPtr output, int mode)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -699,26 +698,17 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
     unsigned char * RADEONMMIO = info->MMIO;
     unsigned long tmp;
     RADEONOutputPrivatePtr radeon_output;
-    int tv_dac_change = 0, o;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
 
     if (radeon_encoder == NULL)
 	return;
 
-    radeon_output = output->driver_private;
-    for (o = 0; o < xf86_config->num_output; o++) {
-	if (output == xf86_config->output[o]) {
-	    break;
-	}
-    }
-
-    if (bEnable) {
-	/*ErrorF("enable montype: %d\n", radeon_output->MonType);*/
+    switch(mode) {
+    case DPMSModeOn:
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 	    ErrorF("enable LVDS\n");
-	    info->output_lcd1 |= (1 << o);
 	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
 	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
 	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
@@ -729,7 +719,6 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	    ErrorF("enable FP1\n");
-	    info->output_dfp1 |= (1 << o);
 	    tmp = INREG(RADEON_FP_GEN_CNTL);
 	    tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
 	    OUTREG(RADEON_FP_GEN_CNTL, tmp);
@@ -745,7 +734,6 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
 	    ErrorF("enable FP2\n");
-	    info->output_dfp2 |= (1 << o);
 	    tmp = INREG(RADEON_FP2_GEN_CNTL);
 	    tmp &= ~RADEON_FP2_BLANK_EN;
 	    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -764,28 +752,23 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 	    ErrorF("enable primary dac\n");
-	    info->output_crt1 |= (1 << o);
 	    tmp = INREG(RADEON_CRTC_EXT_CNTL);
 	    tmp |= RADEON_CRTC_CRT_ON;
 	    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
 	    save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
-	    RADEONDacPowerSet(pScrn, bEnable, TRUE);
+	    RADEONDacPowerSet(pScrn, TRUE, TRUE);
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		ErrorF("enable TV\n");
-		info->output_tv1 |= (1 << o);
 		tmp = INREG(RADEON_TV_MASTER_CNTL);
 		tmp |= RADEON_TV_ON;
 		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-		tv_dac_change = 2;
-		radeon_output->tv_on = TRUE;
 	    } else {
 		ErrorF("enable TVDAC\n");
-		info->output_crt2 |= (1 << o);
 		if (info->ChipFamily == CHIP_FAMILY_R200) {
 		    tmp = INREG(RADEON_FP2_GEN_CNTL);
-	    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
 		    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		} else {
@@ -794,18 +777,20 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
 		    save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
 		}
-		tv_dac_change = 1;
 	    }
+	    RADEONDacPowerSet(pScrn, TRUE, FALSE);
 	    break;
 	}
-    } else {
-	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
+	radeon_encoder->use_count++;
+	break;
+    case DPMSModeOff:
+    case DPMSModeSuspend:
+    case DPMSModeStandby:
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-	    ErrorF("disable LVDS\n");
-	    info->output_lcd1 &= ~(1 << o);
-	    if (!info->output_lcd1) {
+	    if (radeon_encoder->use_count < 2) {
 		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+		ErrorF("disable LVDS\n");
 		if (info->IsMobility || info->IsIGP) {
 		    /* Asic bug, when turning off LVDS_ON, we have to make sure
 		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
@@ -824,9 +809,8 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-	    ErrorF("disable FP1\n");
-	    info->output_dfp1 &= ~(1 << o);
-	    if (!info->output_dfp1) {
+	    if (radeon_encoder->use_count < 2) {
+		ErrorF("disable FP1\n");
 		tmp = INREG(RADEON_FP_GEN_CNTL);
 		tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
 		OUTREG(RADEON_FP_GEN_CNTL, tmp);
@@ -842,9 +826,8 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-	    ErrorF("disable FP2\n");
-	    info->output_dfp2 &= ~(1 << o);
-	    if (!info->output_dfp2) {
+	    if (radeon_encoder->use_count < 2) {
+		ErrorF("disable FP2\n");
 		tmp = INREG(RADEON_FP2_GEN_CNTL);
 		tmp |= RADEON_FP2_BLANK_EN;
 		tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -863,32 +846,25 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-	    ErrorF("disable primary dac\n");
-	    info->output_crt1 &= ~(1 << o);
-	    if (!info->output_crt1) {
+	    if (radeon_encoder->use_count < 2) {
+		ErrorF("disable primary dac\n");
 		tmp = INREG(RADEON_CRTC_EXT_CNTL);
 		tmp &= ~RADEON_CRTC_CRT_ON;
 		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
 		save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-		RADEONDacPowerSet(pScrn, bEnable, TRUE);
+		RADEONDacPowerSet(pScrn, FALSE, TRUE);
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
-		ErrorF("disable TV\n");
-		info->output_tv1 &= ~(1 << o);
-		tv_dac_change = 2;
-		if (!info->output_tv1) {
+	    if (radeon_encoder->use_count < 2) {
+		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+		    ErrorF("disable TV\n");
 		    tmp = INREG(RADEON_TV_MASTER_CNTL);
 		    tmp &= ~RADEON_TV_ON;
 		    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
 		    radeon_output->tv_on = FALSE;
-		}
-	    } else {
-		ErrorF("disable TVDAC\n");
-		info->output_crt2 &= ~(1 << o);
-		tv_dac_change = 1;
-		if (!info->output_crt2) {
+		} else {
+		    ErrorF("disable TVDAC\n");
 		    if (info->ChipFamily == CHIP_FAMILY_R200) {
 			tmp = INREG(RADEON_FP2_GEN_CNTL);
 			tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -901,36 +877,12 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 			save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
 		    }
 		}
+		RADEONDacPowerSet(pScrn, FALSE, FALSE);
 	    }
 	    break;
 	}
-    }
-
-    if (tv_dac_change) {
-	if (bEnable)
-	    info->tv_dac_enable_mask |= tv_dac_change;
-	else
-	    info->tv_dac_enable_mask &= ~tv_dac_change;
-
-	if (bEnable && info->tv_dac_enable_mask)
-	    RADEONDacPowerSet(pScrn, bEnable, FALSE);
-	else if (!bEnable && info->tv_dac_enable_mask == 0)
-	    RADEONDacPowerSet(pScrn, bEnable, FALSE);
-
-    }
-}
-
-void
-legacy_output_dpms(xf86OutputPtr output, int mode)
-{
-    switch(mode) {
-    case DPMSModeOn:
-	RADEONEnableDisplay(output, TRUE);
-	break;
-    case DPMSModeOff:
-    case DPMSModeSuspend:
-    case DPMSModeStandby:
-	RADEONEnableDisplay(output, FALSE);
+	if (radeon_encoder->use_count > 0)
+	    radeon_encoder->use_count--;
 	break;
     }
 }
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 26dae63..68adb0d 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1619,6 +1619,7 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
 	info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec));
 	if (info->encoders[device_index] != NULL) {
 	    info->encoders[device_index]->encoder_id = encoder_id;
+	    info->encoders[device_index]->use_count = 0;
 	    // add dev_priv stuff
 	    return TRUE;
 	} else {
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 2914e04..7b52c4e 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -182,6 +182,7 @@ typedef struct _RADEONCrtcPrivateRec {
 
 typedef struct _radeon_encoder {
     uint16_t encoder_id;
+    int use_count;
     void *dev_priv;
 } radeon_encoder_rec, *radeon_encoder_ptr;
 
commit 82f12e5a40c1fbcb91910a0f8b725c34fff02aae
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 23 16:21:33 2009 -0500

    Remove TMDSType, DACType, LVDSType from output rec

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index ada87f6..1957e1d 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -215,6 +215,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
     PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
     xf86OutputPtr output;
     RADEONOutputPrivatePtr radeon_output = NULL;
+    radeon_encoder_ptr radeon_encoder = NULL;
 
     void *ptr;
     AtomBiosArgRec data;
@@ -261,6 +262,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
 	output = xf86_config->output[i];
 	if (output->crtc == crtc) {
 	    radeon_output = output->driver_private;
+	    radeon_encoder = radeon_get_encoder(output);
 	    break;
 	}
     }
@@ -270,6 +272,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
 	return;
     }
 
+    if (radeon_encoder == NULL) {
+	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No encoder assigned to output!\n");
+	return;
+    }
+
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
     /*ErrorF("table is %d %d\n", major, minor);*/
@@ -296,57 +303,8 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
 	    spc3_ptr->ucPostDiv = post_div;
 	    spc3_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
 	    spc3_ptr->ucMiscInfo = (radeon_crtc->crtc_id << 2);
-
-	    if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
-		else if (radeon_output->DACType == DAC_TVDAC)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
-		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CRT;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		switch (radeon_output->TMDSType) {
-		case TMDS_INT:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
-		    break;
-		case TMDS_EXT:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
-		    break;
-		case TMDS_LVTMA:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
-		    break;
-		case TMDS_UNIPHY:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
-		    break;
-		case TMDS_UNIPHY1:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
-		    break;
-		case TMDS_UNIPHY2:
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
-		    break;
-		default:
-		    ErrorF("Unknown TMDS type: %d!\n", radeon_output->TMDSType);
-		    exit(-1);
-		}
-		if (OUTPUT_IS_DVI)
-		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DVI;
-		else if (radeon_output->type == OUTPUT_HDMI)
-		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_HDMI;
-		else if (radeon_output->type == OUTPUT_DP)
-		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DP;
-	    } else if (radeon_output->MonType == MT_LCD) {
-		spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
-		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
-	    } else if (OUTPUT_IS_TV) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
-		else if (radeon_output->DACType == DAC_TVDAC)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
-	    } else if (radeon_output->MonType == MT_CV) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
-		else if (radeon_output->DACType == DAC_TVDAC)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
-	    }
+	    spc3_ptr->ucTransmitterId = radeon_encoder->encoder_id;
+	    spc3_ptr->ucEncoderMode = atombios_get_encoder_mode(output);
 
 	    ptr = &spc_param;
 	    break;
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 6af7f12..a39c6e4 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -376,7 +376,7 @@ atombios_maybe_hdmi_mode(xf86OutputPtr output)
 #endif
 }
 
-static int
+int
 atombios_get_encoder_mode(xf86OutputPtr output)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
@@ -1088,44 +1088,50 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
     DAC_LOAD_DETECTION_PS_ALLOCATION dac_data;
     AtomBiosArgRec data;
     unsigned char *space;
+    int major, minor;
+    int index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
+
+    atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
     dac_data.sDacload.ucMisc = 0;
 
     if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
 	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT1_SUPPORT);
-	if (radeon_output->DACType == DAC_PRIMARY)
+	if (info->encoders[ATOM_DEVICE_CRT1_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1))
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
-	else if (radeon_output->DACType == DAC_TVDAC)
+	else
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
     } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
 	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CRT2_SUPPORT);
-	if (radeon_output->DACType == DAC_PRIMARY)
+	if (info->encoders[ATOM_DEVICE_CRT2_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1))
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
-	else if (radeon_output->DACType == DAC_TVDAC)
+	else
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
     } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
 	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_CV_SUPPORT);
-	if (radeon_output->DACType == DAC_PRIMARY)
+	if (info->encoders[ATOM_DEVICE_CV_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_CV_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1))
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
-	else if (radeon_output->DACType == DAC_TVDAC)
+	else
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
-	if (IS_DCE3_VARIANT)
-	    dac_data.sDacload.ucMisc = 1;
+	if (minor >= 3)
+	    dac_data.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
     } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
 	dac_data.sDacload.usDeviceID = cpu_to_le16(ATOM_DEVICE_TV1_SUPPORT);
-	if (radeon_output->DACType == DAC_PRIMARY)
+	if (info->encoders[ATOM_DEVICE_TV1_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1))
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
-	else if (radeon_output->DACType == DAC_TVDAC)
+	else
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
-	if (IS_DCE3_VARIANT)
-	    dac_data.sDacload.ucMisc = 1;
     } else {
 	ErrorF("invalid output device for dac detection\n");
 	return ATOM_NOT_IMPLEMENTED;
     }
 
 
-    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
+    data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
     data.exec.pspace = &dac_data;
 
@@ -1149,7 +1155,7 @@ atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
     AtomBiosResult ret;
     uint32_t bios_0_scratch;
 
-    if (OUTPUT_IS_TV) {
+    if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
 	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
 	    if (radeon_output->type == OUTPUT_STV)
 		return MT_STV;
diff --git a/src/legacy_output.c b/src/legacy_output.c
index a722253..1b58c32 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -571,32 +571,41 @@ legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONMonitorType found = MT_NONE;
 
-    if (OUTPUT_IS_TV) {
+    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) {
 	if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
 	    if (radeon_output->type == OUTPUT_STV)
 		found = MT_STV;
 	    else
 		found = MT_CTV;
 	} else {
-	    if (info->InternalTVOut) {
-		if (radeon_output->load_detection)
-		    found = radeon_detect_tv(pScrn);
+	    if (radeon_output->load_detection)
+		found = radeon_detect_tv(pScrn);
+	}
+    } else if (radeon_output->devices & (ATOM_DEVICE_CRT2_SUPPORT)) {
+	if (info->encoders[ATOM_DEVICE_CRT2_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) {
+	    if (radeon_output->load_detection)
+		found = radeon_detect_primary_dac(pScrn, TRUE);
+	} else {
+	    if (radeon_output->load_detection) {
+		if (info->ChipFamily == CHIP_FAMILY_R200)
+		    found = radeon_detect_ext_dac(pScrn);
 		else
-		    found = MT_NONE;
+		    found = radeon_detect_tv_dac(pScrn, TRUE);
 	    }
 	}
-    } else {
-	if (radeon_output->DACType == DAC_PRIMARY) {
+    } else if (radeon_output->devices & (ATOM_DEVICE_CRT1_SUPPORT)) {
+	if (info->encoders[ATOM_DEVICE_CRT1_INDEX] &&
+	    (info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC1)) {
 	    if (radeon_output->load_detection)
 		found = radeon_detect_primary_dac(pScrn, TRUE);
-	} else if (radeon_output->DACType == DAC_TVDAC) {
+	} else {
 	    if (radeon_output->load_detection) {
 		if (info->ChipFamily == CHIP_FAMILY_R200)
 		    found = radeon_detect_ext_dac(pScrn);
 		else
 		    found = radeon_detect_tv_dac(pScrn, TRUE);
-	    } else
-		found = MT_NONE;
+	    }
 	}
     }
 
@@ -776,7 +785,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		info->output_crt2 |= (1 << o);
 		if (info->ChipFamily == CHIP_FAMILY_R200) {
 		    tmp = INREG(RADEON_FP2_GEN_CNTL);
-		    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+	    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
 		    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		} else {
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index c0bd48d..26dae63 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1526,7 +1526,7 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
 	(PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1043) &&
 	(PCI_SUB_DEVICE_ID(info->PciInfo) == 0x826d)) {
 	if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) &&
-	    (info->BiosConnector[index].TMDSType == TMDS_LVTMA)) {
+	    (info->BiosConnector[index].devices & ATOM_DEVICE_DFP3_SUPPORT)) {
 	    info->BiosConnector[index].ConnectorType = CONNECTOR_DVI_D;
 	}
     }
@@ -1557,15 +1557,14 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
 	    info->BiosConnector[index].valid = FALSE;
 
 	if (index == ATOM_DEVICE_DFP1_INDEX) {
-	    info->BiosConnector[index].DACType = DAC_TVDAC;
-	    info->BiosConnector[index].devices |= (1 << ATOM_DEVICE_CRT2_INDEX);
+	    info->BiosConnector[index].devices |= ATOM_DEVICE_CRT2_SUPPORT;
 	}
     }
 
     /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */
     if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
     	(info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) {
-	info->BiosConnector[index].DACType = DAC_NONE;
+	info->BiosConnector[index].devices &= ~(ATOM_DEVICE_CRT_SUPPORT);
     }
 }
 
@@ -1729,53 +1728,6 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 
 		    if (!radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag))
 			return FALSE;
-
-		    switch(enc_obj_id) {
-		    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-			info->BiosConnector[i].LVDSType = LVDS_INT;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-			info->BiosConnector[i].TMDSType = TMDS_INT;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY;
-			else
-			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY1;
-			else
-			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY1;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY2;
-			else
-			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY2;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
-		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-			info->BiosConnector[i].TMDSType = TMDS_EXT;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-			    info->BiosConnector[i].LVDSType = LVDS_LVTMA;
-			else
-			    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-			info->BiosConnector[i].DACType = DAC_PRIMARY;
-			break;
-		    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-			info->BiosConnector[i].DACType = DAC_TVDAC;
-			break;
-		    }
 		}
 	    }
 
@@ -1820,10 +1772,6 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
 		if (info->BiosConnector[j].valid && (i != j) ) {
 		    if (info->BiosConnector[i].connector_object == info->BiosConnector[j].connector_object) {
-			if (info->BiosConnector[i].devices & (ATOM_DEVICE_CRT_SUPPORT))
-			    info->BiosConnector[i].TMDSType = info->BiosConnector[j].TMDSType;
-			else
-			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
 			info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
 			info->BiosConnector[j].valid = FALSE;
 		    }
@@ -2186,8 +2134,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	    continue;
 	}
 
-	info->BiosConnector[i].DACType = ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC;
-
 	/* don't assign a gpio for tv */
 	if ((i == ATOM_DEVICE_TV1_INDEX) ||
 	    (i == ATOM_DEVICE_TV2_INDEX) ||
@@ -2212,28 +2158,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 				(1 << i)))
 	    return FALSE;
 
-	if (i == ATOM_DEVICE_DFP1_INDEX)
-	    info->BiosConnector[i].TMDSType = TMDS_INT;
-	else if (i == ATOM_DEVICE_DFP2_INDEX) {
-	    if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
-		(info->ChipFamily == CHIP_FAMILY_RS690) ||
-		(info->ChipFamily == CHIP_FAMILY_RS740))
-		info->BiosConnector[i].TMDSType = TMDS_DDIA;
-	    else
-		info->BiosConnector[i].TMDSType = TMDS_EXT;
-	} else if (i == ATOM_DEVICE_DFP3_INDEX)
-	    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-	else
-	    info->BiosConnector[i].TMDSType = TMDS_NONE;
-
-	if (i == ATOM_DEVICE_LCD1_INDEX) {
-	    if (IS_AVIVO_VARIANT)
-		info->BiosConnector[i].LVDSType = LVDS_LVTMA;
-	    else
-		info->BiosConnector[i].LVDSType = LVDS_INT;
-	} else
-	    info->BiosConnector[i].LVDSType = LVDS_NONE;
-
 	/* Always set the connector type to VGA for CRT1/CRT2. if they are
 	 * shared with a DVI port, we'll pick up the DVI connector below when we
 	 * merge the outputs
@@ -2277,15 +2201,15 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 			if (((i == ATOM_DEVICE_DFP1_INDEX) ||
 			     (i == ATOM_DEVICE_DFP2_INDEX) ||
 			     (i == ATOM_DEVICE_DFP3_INDEX)) &&
-			    ((j == ATOM_DEVICE_CRT1_INDEX) || (j == ATOM_DEVICE_CRT2_INDEX))) {
-			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
+			    ((j == ATOM_DEVICE_CRT1_INDEX) ||
+			     (j == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
 			    info->BiosConnector[j].valid = FALSE;
 			} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
-			     (j == ATOM_DEVICE_DFP2_INDEX) ||
-			     (j == ATOM_DEVICE_DFP3_INDEX)) &&
-			    ((i == ATOM_DEVICE_CRT1_INDEX) || (i == ATOM_DEVICE_CRT2_INDEX))) {
-			    info->BiosConnector[j].DACType = info->BiosConnector[i].DACType;
+				    (j == ATOM_DEVICE_DFP2_INDEX) ||
+				    (j == ATOM_DEVICE_DFP3_INDEX)) &&
+				   ((i == ATOM_DEVICE_CRT1_INDEX) ||
+				    (i == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[j].devices |= info->BiosConnector[i].devices;
 			    info->BiosConnector[i].valid = FALSE;
 			} else {
@@ -2305,16 +2229,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	}
     }
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
-    for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
-	if (info->BiosConnector[i].valid) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d, hpd_mask-0x%x\n",
-		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
-		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType,
-		       info->BiosConnector[i].hpd_mask);
-	}
-    }
-
     return TRUE;
 }
 
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 7f17918..42b76b2 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -441,16 +441,6 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
 
-    /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC
-     * Also there is no internal TMDS
-     */
-    if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
-	(info->ChipFamily == CHIP_FAMILY_RS400) ||
-	(info->ChipFamily == CHIP_FAMILY_RS480)) {
-	info->BiosConnector[index].DACType = DAC_TVDAC;
-	info->BiosConnector[index].TMDSType = TMDS_EXT;
-    }
-
     /* XPRESS DDC quirks */
     if ((info->ChipFamily == CHIP_FAMILY_RS400 ||
 	 info->ChipFamily == CHIP_FAMILY_RS480) &&
@@ -513,7 +503,7 @@ static void RADEONApplyLegacyQuirks(ScrnInfoPtr pScrn, int index)
     if (info->Chipset == PCI_CHIP_R200_QL &&
 	PCI_SUB_VENDOR_ID(info->PciInfo) == 0x1569 &&
 	PCI_SUB_DEVICE_ID(info->PciInfo) == 0x514c &&
-	info->BiosConnector[index].DACType == DAC_PRIMARY) {
+	(info->BiosConnector[index].devices & ATOM_DEVICE_CRT1_SUPPORT)) {
 	info->BiosConnector[index].load_detection = FALSE;
     }
 
@@ -544,7 +534,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    case CONNECTOR_PROPRIETARY_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
 		if ((tmp >> 4) & 0x1) {
-		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 				       radeon_get_encoder_id_from_supported_device(pScrn,
@@ -553,7 +542,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 					    ATOM_DEVICE_DFP2_SUPPORT))
 			return FALSE;
 		} else {
-		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
@@ -566,7 +554,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    case CONNECTOR_CRT_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_VGA;
 		if (tmp & 0x1) {
-		    info->BiosConnector[i].DACType = DAC_TVDAC;
 		    info->BiosConnector[i].load_detection = FALSE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
@@ -576,7 +563,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 					    ATOM_DEVICE_CRT2_SUPPORT))
 			return FALSE;
 		} else {
-		    info->BiosConnector[i].DACType = DAC_PRIMARY;
 		    info->BiosConnector[i].load_detection = TRUE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
@@ -590,7 +576,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    case CONNECTOR_DVI_I_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I;
 		if (tmp & 0x1) {
-		    info->BiosConnector[i].DACType = DAC_TVDAC;
 		    info->BiosConnector[i].load_detection = FALSE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
@@ -600,7 +585,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 					    ATOM_DEVICE_CRT2_SUPPORT))
 			return FALSE;
 		} else {
-		    info->BiosConnector[i].DACType = DAC_PRIMARY;
 		    info->BiosConnector[i].load_detection = TRUE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
@@ -611,7 +595,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 			return FALSE;
 		}
 		if ((tmp >> 4) & 0x1) {
-		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
@@ -620,7 +603,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 					    ATOM_DEVICE_DFP2_SUPPORT))
 			return FALSE;
 		} else {
-		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
@@ -633,7 +615,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    case CONNECTOR_DVI_D_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
 		if ((tmp >> 4) & 0x1) {
-		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
@@ -642,7 +623,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 					    ATOM_DEVICE_DFP2_SUPPORT))
 			return FALSE;
 		} else {
-		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
@@ -654,7 +634,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		break;
 	    case CONNECTOR_CTV_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_CTV;
-		info->BiosConnector[i].DACType = DAC_TVDAC;
 		info->BiosConnector[i].load_detection = FALSE;
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
@@ -666,7 +645,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		break;
 	    case CONNECTOR_STV_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_STV;
-		info->BiosConnector[i].DACType = DAC_TVDAC;
 		info->BiosConnector[i].load_detection = FALSE;
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
@@ -718,12 +696,9 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		       "Found DFP table, assuming DVI connector\n");
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
-	    info->BiosConnector[0].DACType = DAC_PRIMARY;
 	    info->BiosConnector[0].load_detection = TRUE;
-	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	    info->BiosConnector[0].TMDSType = TMDS_INT;
-	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_INDEX;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
 	    if (!radeon_add_encoder(pScrn,
 				    radeon_get_encoder_id_from_supported_device(pScrn,
 										ATOM_DEVICE_DFP1_SUPPORT,
@@ -747,9 +722,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	if (offset) {
 	    info->BiosConnector[4].valid = TRUE;
 	    info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS;
-	    info->BiosConnector[4].DACType = DAC_NONE;
-	    info->BiosConnector[4].TMDSType = TMDS_NONE;
-	    info->BiosConnector[4].LVDSType = LVDS_INT;
 	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
 	    info->BiosConnector[4].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -822,9 +794,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].valid = TRUE;
 		/* assume s-video for now */
 		info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
-		info->BiosConnector[5].DACType = DAC_TVDAC;
 		info->BiosConnector[5].load_detection = FALSE;
-		info->BiosConnector[5].TMDSType = TMDS_NONE;
 		info->BiosConnector[5].ddc_i2c.valid = FALSE;
 		info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
@@ -837,15 +807,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	}
     }
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
-    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	if (info->BiosConnector[i].valid) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
-		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
-	}
-    }
-
     return TRUE;
 }
 
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 5cd4e29..fa3301e 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -345,7 +345,7 @@ RADEONProbeOutputModes(xf86OutputPtr output)
 		modes = xf86OutputGetEDIDModes (output);
 #if defined(__powerpc__)
 	    if ((info->MacModel == RADEON_MAC_EMAC) &&
-		(radeon_output->DACType == DAC_PRIMARY) &&
+		(radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) &&
 		(modes == NULL))
 		modes = RADEONeMacModes(output);
 #endif
diff --git a/src/radeon_output.c b/src/radeon_output.c
index edbb895..83aaf4f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -62,31 +62,40 @@ const RADEONMonitorType MonTypeID[10] = {
   MT_DP
 };
 
-const char *TMDSTypeName[8] = {
-  "None",
-  "Internal",
-  "External",
-  "LVTMA",
-  "DDIA",
-  "UNIPHY",
-  "UNIPHY1",
-  "UNIPHY2",
-};
-
-const char *LVDSTypeName[6] = {
-  "None",
-  "Internal",
-  "LVTMA",
-  "UNIPHY",
-  "UNIPHY1",
-  "UNIPHY2",
-};
-
-const char *DACTypeName[4] = {
-  "None",
-  "Primary",
-  "TVDAC/ExtDAC",
-  "ExtDac"
+const char *encoder_name[33] = {
+    "NONE",
+    "INTERNAL_LVDS",
+    "INTERNAL_TMDS1",
+    "INTERNAL_TMDS2",
+    "INTERNAL_DAC1",
+    "INTERNAL_DAC2",
+    "INTERNAL_SDVOA",
+    "INTERNAL_SDVOB",
+    "SI170B",
+    "CH7303",
+    "INTERNAL_DVO1",
+    "EXTERNAL_SDVOA",
+    "EXTERNAL_SDVOB",
+    "TITFP513",
+    "INTERNAL_LVTM1",
+    "VT1623",
+    "HDMI_SI1930",
+    "HDMI_INTERNAL",
+    "INTERNAL_KLDSCP_TMDS1",
+    "INTERNAL_KLDSCP_DVO1",
+    "INTERNAL_KLDSCP_DAC1",
+    "INTERNAL_KLDSCP_DAC2",
+    "SI178",
+    "MVPU_FPGA",
+    "INTERNAL_DDI",
+    "VT1625",
+    "HDMI_SI1932",
+    "DP_AN9801",
+    "DP_DP501",
+    "INTERNAL_UNIPHY",
+    "INTERNAL_KLDSCP_LVTMA",
+    "INTERNAL_UNIPHY1",
+    "INTERNAL_UNIPHY2",
 };
 
 const char *ConnectorTypeName[17] = {
@@ -190,6 +199,7 @@ radeon_bios_output_lock(xf86OutputPtr output, Bool lock);
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output;
     xf86OutputPtr output;
@@ -199,14 +209,29 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 	output = xf86_config->output[o];
 	radeon_output = output->driver_private;
 
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Port%d:\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n LVDS Type -- %s\n DDC Type  -- 0x%x\n", 
-		   o,
-		   ConnectorTypeName[radeon_output->ConnectorType],
-		   DACTypeName[radeon_output->DACType],
-		   TMDSTypeName[radeon_output->TMDSType],
-		   LVDSTypeName[radeon_output->LVDSType],
-		   (unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d:\n", o);
+	ErrorF("  Connector: %s\n", ConnectorTypeName[radeon_output->ConnectorType]);
+	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+	    ErrorF("  CRT1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	    ErrorF("  CRT2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT2_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	    ErrorF("  LCD1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_LCD1_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	    ErrorF("  DFP1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP1_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	    ErrorF("  DFP2: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP2_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	    ErrorF("  DFP3: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP3_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
+	    ErrorF("  DFP4: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP4_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
+	    ErrorF("  DFP5: %s\n", encoder_name[info->encoders[ATOM_DEVICE_DFP5_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    ErrorF("  TV1: %s\n", encoder_name[info->encoders[ATOM_DEVICE_TV1_INDEX]->encoder_id]);
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    ErrorF("  CV: %s\n", encoder_name[info->encoders[ATOM_DEVICE_CRT1_INDEX]->encoder_id]);
+	ErrorF("  DDC reg: 0x%x\n",(unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
     }
 
 }
@@ -656,79 +681,85 @@ radeon_bios_output_dpms(xf86OutputPtr output, int mode)
     RADEONSavePtr save = info->ModeReg;
 
     if (info->IsAtomBios) {
-	if (mode == DPMSModeOn) {
-	    if (radeon_output->MonType == MT_STV ||
-		radeon_output->MonType == MT_CTV) {
-		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_CV) {
-		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_CV_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-		    save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
-		    save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
-		}
+	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_TV1_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
 	    }
-	} else {
-	    if (radeon_output->MonType == MT_STV ||
-		radeon_output->MonType == MT_CTV) {
-		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_CV) {
-		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
-		}
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
-		} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-		    save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
-		    save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
-		}
+	} else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_CV_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_CV_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_CV_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_CRT1_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_CRT2_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_LCD1_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_DFP1_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_DFP2_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_DFP3_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP4_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_DFP4_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_DFP4_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_DFP4_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_DFP4_ACTIVE;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP5_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_2_scratch &= ~ATOM_S2_DFP5_DPMS_STATE;
+		save->bios_3_scratch |= ATOM_S3_DFP5_ACTIVE;
+	    } else {
+		save->bios_2_scratch |= ATOM_S2_DFP5_DPMS_STATE;
+		save->bios_3_scratch &= ~ATOM_S3_DFP5_ACTIVE;
 	    }
 	}
 	if (info->ChipFamily >= CHIP_FAMILY_R600) {
@@ -742,47 +773,56 @@ radeon_bios_output_dpms(xf86OutputPtr output, int mode)
 	if (mode == DPMSModeOn) {
 	    save->bios_6_scratch &= ~(RADEON_DPMS_MASK | RADEON_SCREEN_BLANKING);
 	    save->bios_6_scratch |= RADEON_DPMS_ON;
-	    if (radeon_output->MonType == MT_STV ||
-		radeon_output->MonType == MT_CTV) {
-		save->bios_5_scratch |= RADEON_TV1_ON;
-		save->bios_6_scratch |= RADEON_TV_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    save->bios_5_scratch |= RADEON_CRT1_ON;
-		else
-		    save->bios_5_scratch |= RADEON_CRT2_ON;
-		save->bios_6_scratch |= RADEON_CRT_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_LCD) {
-		save->bios_5_scratch |= RADEON_LCD1_ON;
-		save->bios_6_scratch |= RADEON_LCD_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->TMDSType == TMDS_INT)
-		    save->bios_5_scratch |= RADEON_DFP1_ON;
-		else
-		    save->bios_5_scratch |= RADEON_DFP2_ON;
-		save->bios_6_scratch |= RADEON_DFP_DPMS_ON;
-	    }
 	} else {
 	    save->bios_6_scratch &= ~RADEON_DPMS_MASK;
 	    save->bios_6_scratch |= (RADEON_DPMS_OFF | RADEON_SCREEN_BLANKING);
-	    if (radeon_output->MonType == MT_STV ||
-		radeon_output->MonType == MT_CTV) {
+	}
+	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_TV1_ON;
+		save->bios_6_scratch |= RADEON_TV_DPMS_ON;
+	    } else {
 		save->bios_5_scratch &= ~RADEON_TV1_ON;
 		save->bios_6_scratch &= ~RADEON_TV_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    save->bios_5_scratch &= ~RADEON_CRT1_ON;
-		else
-		    save->bios_5_scratch &= ~RADEON_CRT2_ON;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_CRT1_ON;
+		save->bios_6_scratch |= RADEON_CRT_DPMS_ON;
+	    } else {
+		save->bios_5_scratch &= ~RADEON_CRT1_ON;
 		save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_LCD) {
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_CRT2_ON;
+		save->bios_6_scratch |= RADEON_CRT_DPMS_ON;
+	    } else {
+		save->bios_5_scratch &= ~RADEON_CRT2_ON;
+		save->bios_6_scratch &= ~RADEON_CRT_DPMS_ON;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_LCD1_ON;
+		save->bios_6_scratch |= RADEON_LCD_DPMS_ON;
+	    } else {
 		save->bios_5_scratch &= ~RADEON_LCD1_ON;
 		save->bios_6_scratch &= ~RADEON_LCD_DPMS_ON;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->TMDSType == TMDS_INT)
-		    save->bios_5_scratch &= ~RADEON_DFP1_ON;
-		else
-		    save->bios_5_scratch &= ~RADEON_DFP2_ON;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_DFP1_ON;
+		save->bios_6_scratch |= RADEON_DFP_DPMS_ON;
+	    } else {
+		save->bios_5_scratch &= ~RADEON_DFP1_ON;
+		save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
+	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
+	    if (mode == DPMSModeOn) {
+		save->bios_5_scratch |= RADEON_DFP2_ON;
+		save->bios_6_scratch |= RADEON_DFP_DPMS_ON;
+	    } else {
+		save->bios_5_scratch &= ~RADEON_DFP2_ON;
 		save->bios_6_scratch &= ~RADEON_DFP_DPMS_ON;
 	    }
 	}
@@ -803,70 +843,54 @@ radeon_bios_output_crtc(xf86OutputPtr output)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
     if (info->IsAtomBios) {
-	if (radeon_output->MonType == MT_STV ||
-	    radeon_output->MonType == MT_CTV) {
-	    if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
-		save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 18);
-	    }
-	} else if (radeon_output->MonType == MT_CV) {
-	    if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 24);
-	    }
-	} else if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 16);
-	    } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 20);
-	    }
-	} else if (radeon_output->MonType == MT_LCD) {
-	    if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 17);
-	    }
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 19);
-	    } else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 23);
-	    } else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-		save->bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
-		save->bios_3_scratch |= (radeon_crtc->crtc_id << 25);
-	    }
+	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
+	    save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 18);
+	} else if (radeon_output->active_device & ATOM_DEVICE_CV_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 24);
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 16);
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 20);
+	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 17);
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 19);
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 23);
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP3_SUPPORT) {
+	    save->bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE;
+	    save->bios_3_scratch |= (radeon_crtc->crtc_id << 25);
 	}
 	if (info->ChipFamily >= CHIP_FAMILY_R600)
 	    OUTREG(R600_BIOS_3_SCRATCH, save->bios_3_scratch);
 	else
 	    OUTREG(RADEON_BIOS_3_SCRATCH, save->bios_3_scratch);
     } else {
-	if (radeon_output->MonType == MT_STV ||
-	    radeon_output->MonType == MT_CTV) {
+	if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
 	    save->bios_5_scratch &= ~RADEON_TV1_CRTC_MASK;
 	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT);
-	} else if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->DACType == DAC_PRIMARY) {
-		save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
-		save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT);
-	    } else {
-		save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
-		save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT);
-	    }
-	} else if (radeon_output->MonType == MT_LCD) {
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT1_SUPPORT) {
+	    save->bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK;
+	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT);
+	} else if (radeon_output->active_device & ATOM_DEVICE_CRT2_SUPPORT) {
+	    save->bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK;
+	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT);
+	} else if (radeon_output->active_device & ATOM_DEVICE_LCD1_SUPPORT) {
 	    save->bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK;
 	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT);
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType == TMDS_INT) {
-		save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
-		save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT);
-	    } else {
-		save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
-		save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT);
-	    }
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP1_SUPPORT) {
+	    save->bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK;
+	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT);
+	} else if (radeon_output->active_device & ATOM_DEVICE_DFP2_SUPPORT) {
+	    save->bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK;
+	    save->bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT);
 	}
 	OUTREG(RADEON_BIOS_5_SCRATCH, save->bios_5_scratch);
     }
@@ -881,97 +905,110 @@ radeon_bios_output_connected(xf86OutputPtr output, Bool connected)
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr save = info->ModeReg;
 
-    if (info->ChipFamily >= CHIP_FAMILY_R600)
-	return;
-
     if (info->IsAtomBios) {
-	if (connected) {
-	    if (radeon_output->MonType == MT_STV) {
-		/* taken care of by load detection */
-	    } else if (radeon_output->MonType == MT_CTV) {
-		/* taken care of by load detection */
-	    } else if (radeon_output->MonType == MT_CV) {
-		/* taken care of by load detection */
-	    } else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_CRT1_COLOR;
-		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_CRT2_COLOR;
-	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_LCD1;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_DFP1;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_DFP2;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-		    save->bios_0_scratch |= ATOM_S0_DFP3;
-	    }
-	} else {
-	    if (OUTPUT_IS_TV) {
-		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_TV1_MASK;
-	    }
-	    if (radeon_output->type == OUTPUT_CV) {
-		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_CV_MASK;
-	    }
-	    if (radeon_output->DACType) {
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
-		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
-	    }
-	    if (radeon_output->type == OUTPUT_LVDS) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_LCD1;
-	    }
-	    if (radeon_output->TMDSType) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_DFP1;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_DFP2;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-		    save->bios_0_scratch &= ~ATOM_S0_DFP3;
-	    }
+	switch (radeon_output->active_device) {
+	case ATOM_DEVICE_TV1_SUPPORT:
+	    if (!connected)
+		save->bios_0_scratch &= ~ATOM_S0_TV1_MASK;
+	    break;
+	case ATOM_DEVICE_CV_SUPPORT:
+	    if (!connected)
+		save->bios_0_scratch &= ~ATOM_S0_CV_MASK;
+	    break;
+	case ATOM_DEVICE_LCD1_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_LCD1;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_LCD1;
+	    break;
+	case ATOM_DEVICE_CRT1_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_CRT1_COLOR;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_CRT1_MASK;
+	    break;
+	case ATOM_DEVICE_CRT2_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_CRT2_COLOR;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_CRT2_MASK;
+	    break;
+	case ATOM_DEVICE_DFP1_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_DFP1;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_DFP1;
+	    break;
+	case ATOM_DEVICE_DFP2_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_DFP2;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_DFP2;
+	    break;
+	case ATOM_DEVICE_DFP3_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_DFP3;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_DFP3;
+	    break;
+	case ATOM_DEVICE_DFP4_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_DFP4;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_DFP4;
+	    break;
+	case ATOM_DEVICE_DFP5_SUPPORT:
+	    if (connected)
+		save->bios_0_scratch |= ATOM_S0_DFP5;
+	    else
+		save->bios_0_scratch &= ~ATOM_S0_DFP5;
+	    break;
 	}
 	if (info->ChipFamily >= CHIP_FAMILY_R600)
 	    OUTREG(R600_BIOS_0_SCRATCH, save->bios_0_scratch);
 	else
 	    OUTREG(RADEON_BIOS_0_SCRATCH, save->bios_0_scratch);
     } else {
-	if (connected) {
-	    if (radeon_output->MonType == MT_STV)
-		save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
-	    else if (radeon_output->MonType == MT_CTV)
-		save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP;
-	    else if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->DACType == DAC_PRIMARY)
-		    save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
-		else
-		    save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
-	    } else if (radeon_output->MonType == MT_LCD)
-		save->bios_4_scratch |= RADEON_LCD1_ATTACHED;
-	    else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->TMDSType == TMDS_INT)
-		    save->bios_4_scratch |= RADEON_DFP1_ATTACHED;
-		else
-		    save->bios_4_scratch |= RADEON_DFP2_ATTACHED;
-	    }
-	} else {
-	    if (OUTPUT_IS_TV)
+	switch (radeon_output->active_device) {
+	case ATOM_DEVICE_TV1_SUPPORT:
+	    if (connected) {
+		if (radeon_output->MonType == MT_STV)
+		    save->bios_4_scratch |= RADEON_TV1_ATTACHED_SVIDEO;
+		else if (radeon_output->MonType == MT_CTV)
+		    save->bios_4_scratch |= RADEON_TV1_ATTACHED_COMP;
+	    } else
 		save->bios_4_scratch &= ~RADEON_TV1_ATTACHED_MASK;
-	    else if (radeon_output->DACType == DAC_TVDAC)
-		save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
-	    if (radeon_output->DACType == DAC_PRIMARY)
-		save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
-	    if (radeon_output->type == OUTPUT_LVDS)
+	    break;
+	case ATOM_DEVICE_LCD1_SUPPORT:
+	    if (connected)
+		save->bios_4_scratch |= RADEON_LCD1_ATTACHED;
+	    else
 		save->bios_4_scratch &= ~RADEON_LCD1_ATTACHED;
-	    if (radeon_output->TMDSType == TMDS_INT)
+	    break;
+	case ATOM_DEVICE_CRT1_SUPPORT:
+	    if (connected)
+		save->bios_4_scratch |= RADEON_CRT1_ATTACHED_COLOR;
+	    else
+		save->bios_4_scratch &= ~RADEON_CRT1_ATTACHED_MASK;
+	    break;
+	case ATOM_DEVICE_CRT2_SUPPORT:
+	    if (connected)
+		save->bios_4_scratch |= RADEON_CRT2_ATTACHED_COLOR;
+	    else
+		save->bios_4_scratch &= ~RADEON_CRT2_ATTACHED_MASK;
+	    break;
+	case ATOM_DEVICE_DFP1_SUPPORT:
+	    if (connected)
+		save->bios_4_scratch |= RADEON_DFP1_ATTACHED;
+	    else
 		save->bios_4_scratch &= ~RADEON_DFP1_ATTACHED;
-	    if (radeon_output->TMDSType == TMDS_EXT)
+	    break;
+	case ATOM_DEVICE_DFP2_SUPPORT:
+	    if (connected)
+		save->bios_4_scratch |= RADEON_DFP2_ATTACHED;
+	    else
 		save->bios_4_scratch &= ~RADEON_DFP2_ATTACHED;
+	    break;
 	}
 	OUTREG(RADEON_BIOS_4_SCRATCH, save->bios_4_scratch);
     }
@@ -1162,10 +1199,15 @@ radeon_create_resources(xf86OutputPtr output)
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     INT32 range[2];
     int data, err;
     const char *s;
 
+    if (radeon_encoder == NULL)
+	return;
+
+#if 0
     /* backlight control */
     if (radeon_output->type == OUTPUT_LVDS) {
 	backlight_atom = MAKE_ATOM("backlight");
@@ -1189,9 +1231,9 @@ radeon_create_resources(xf86OutputPtr output)
 		       "RRChangeOutputProperty error, %d\n", err);
 	}
     }
+#endif
 
-    if (radeon_output->DACType == DAC_PRIMARY ||
-	radeon_output->DACType == DAC_TVDAC) {
+    if (radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) {
 	load_detection_atom = MAKE_ATOM("load_detection");
 
 	range[0] = 0; /* off */
@@ -1204,9 +1246,9 @@ radeon_create_resources(xf86OutputPtr output)
 	}
 
 	if (radeon_output->load_detection)
-	    data = 1; /* user forces on tv dac load detection */
+	    data = 1;
 	else
-	    data = 0; /* shared tvdac between vga/dvi/tv */
+	    data = 0;
 
 	err = RRChangeOutputProperty(output->randr_output, load_detection_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
@@ -1217,7 +1259,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
-    if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+    if (IS_AVIVO_VARIANT && (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))) {
 	coherent_mode_atom = MAKE_ATOM("coherent_mode");
 
 	range[0] = 0; /* off */
@@ -1240,7 +1282,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
-    if (OUTPUT_IS_DVI && radeon_output->TMDSType == TMDS_INT) {
+    if ((!IS_AVIVO_VARIANT) && (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)) {
 	tmds_pll_atom = MAKE_ATOM("tmds_pll");
 
 	err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
@@ -1271,7 +1313,7 @@ radeon_create_resources(xf86OutputPtr output)
 
     /* RMX control - fullscreen, centered, keep ratio, off */
     /* actually more of a crtc property as only crtc1 has rmx */
-    if (radeon_output->type == OUTPUT_LVDS || OUTPUT_IS_DVI) {
+    if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
 	rmx_atom = MAKE_ATOM("scaler");
 
 	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
@@ -1295,7 +1337,8 @@ radeon_create_resources(xf86OutputPtr output)
     }
 
     /* force auto/analog/digital for DVI-I ports */
-    if (radeon_output->type == OUTPUT_DVI_I) {
+    if ((radeon_output->devices & (ATOM_DEVICE_CRT_SUPPORT)) &&
+	(radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))){
 	monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
 
 	err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
@@ -1315,7 +1358,7 @@ radeon_create_resources(xf86OutputPtr output)
 	}
     }
 
-    if (OUTPUT_IS_TV) {
+    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT)) {
 	if (!IS_AVIVO_VARIANT) {
 	    tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
 
@@ -2215,49 +2258,55 @@ void RADEONInitConnector(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+
+    if (radeon_encoder == NULL)
+	return;
 
-    if ((radeon_output->DACType == DAC_TVDAC) &&
+    if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) &&
 	xf86ReturnOptValBool(info->Options, OPTION_TVDAC_LOAD_DETECT, FALSE))
 	radeon_output->load_detection = 1;
 
-    if (radeon_output->type == OUTPUT_LVDS) {
+    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
 	radeon_output->rmx_type = RMX_FULL;
 	RADEONGetLVDSInfo(output);
     }
 
-    if (OUTPUT_IS_DVI) {
+    radeon_output->rmx_type = RMX_OFF;
+    if ((!info->IsAtomBios) &&
+	(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DVO1)) {
 	I2CBusPtr pDVOBus;
-	radeon_output->rmx_type = RMX_OFF;
-	if ((!info->IsAtomBios) && radeon_output->TMDSType == TMDS_EXT) {
+
 #if defined(__powerpc__)
-	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
-	    radeon_output->dvo_i2c_slave_addr = 0x70;
+	radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
+	radeon_output->dvo_i2c_slave_addr = 0x70;
 #else
-	    if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
-		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-		radeon_output->dvo_i2c_slave_addr = 0x70;
-	    }
+	if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
+	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+	    radeon_output->dvo_i2c_slave_addr = 0x70;
+	}
 #endif
-	    if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
-		radeon_output->DVOChip =
-		    RADEONDVODeviceInit(pDVOBus,
-					radeon_output->dvo_i2c_slave_addr);
-		if (!radeon_output->DVOChip)
-		    xfree(pDVOBus);
-	    }
-	} else
-	    RADEONGetTMDSInfo(output);
+	if (RADEONI2CInit(output, &pDVOBus, "DVO", TRUE)) {
+	    radeon_output->DVOChip =
+		RADEONDVODeviceInit(pDVOBus,
+				    radeon_output->dvo_i2c_slave_addr);
+	    if (!radeon_output->DVOChip)
+		xfree(pDVOBus);
+	}
     }
 
-    if (OUTPUT_IS_TV)
+    if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_TMDS1)
+	RADEONGetTMDSInfo(output);
+
+    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
 	RADEONGetTVInfo(output);
 
-    if (radeon_output->DACType == DAC_TVDAC) {
+    if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_DAC2) {
 	radeon_output->tv_on = FALSE;
 	RADEONGetTVDacAdjInfo(output);
     }
 
-    if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI))
+    if (radeon_output->devices & (ATOM_DEVICE_DFP_SUPPORT))
 	radeon_output->coherent_mode = TRUE;
 
     if (radeon_output->ddc_i2c.valid)
@@ -2274,8 +2323,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
     switch (info->MacModel) {
     case RADEON_MAC_IBOOK:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	info->BiosConnector[0].DACType = DAC_NONE;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2287,9 +2334,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].load_detection = FALSE;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
@@ -2301,9 +2346,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2316,8 +2359,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_POWERBOOK_EXTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	info->BiosConnector[0].DACType = DAC_NONE;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2329,8 +2370,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[1].DACType = DAC_PRIMARY;
-	info->BiosConnector[1].TMDSType = TMDS_EXT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
@@ -2348,9 +2387,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2363,8 +2400,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_POWERBOOK_INTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	info->BiosConnector[0].DACType = DAC_NONE;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2376,8 +2411,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[1].DACType = DAC_PRIMARY;
-	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
@@ -2395,9 +2428,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2410,8 +2441,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_POWERBOOK_VGA:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	info->BiosConnector[0].DACType = DAC_NONE;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2423,8 +2452,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[1].DACType = DAC_PRIMARY;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2436,9 +2463,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2451,9 +2476,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_MINI_EXTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].load_detection = FALSE;
-	info->BiosConnector[0].TMDSType = TMDS_EXT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
@@ -2471,9 +2494,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].load_detection = FALSE;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2486,9 +2507,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_MINI_INTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].load_detection = FALSE;
-	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
@@ -2506,9 +2525,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].load_detection = FALSE;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2521,8 +2538,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	return TRUE;
     case RADEON_MAC_IMAC_G5_ISIGHT:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
-	info->BiosConnector[0].DACType = DAC_NONE;
-	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT;
@@ -2534,9 +2549,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].load_detection = FALSE;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
@@ -2548,9 +2561,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2567,8 +2578,6 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	 * different ddc setups.  need to verify
 	 */
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[0].DACType = DAC_PRIMARY;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2580,9 +2589,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].load_detection = FALSE;
-	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
 	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
@@ -2594,9 +2601,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2625,8 +2630,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 
     if (!pRADEONEnt->HasCRTC2) {
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	info->BiosConnector[0].DACType = DAC_PRIMARY;
-	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
 	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2642,8 +2645,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	/* Below is the most common setting, but may not be true */
 	if (info->IsIGP) {
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
-	    info->BiosConnector[0].DACType = DAC_NONE;
-	    info->BiosConnector[0].TMDSType = TMDS_NONE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2659,9 +2660,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	    else
 		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[1].DACType = DAC_TVDAC;
 	    info->BiosConnector[1].load_detection = FALSE;
-	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2676,8 +2675,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 #else
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
 #endif
-	    info->BiosConnector[0].DACType = DAC_NONE;
-	    info->BiosConnector[0].TMDSType = TMDS_NONE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
@@ -2688,8 +2685,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 			       ATOM_DEVICE_LCD1_SUPPORT);
 
 	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2707,9 +2702,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	    else
 		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].load_detection = FALSE;
-	    info->BiosConnector[0].TMDSType = TMDS_NONE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2723,8 +2716,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	     * IGP desktop chips is
 	     */
 	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
-	    info->BiosConnector[1].DACType = DAC_NONE;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
 	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT;
@@ -2735,9 +2726,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 			       ATOM_DEVICE_DFP1_SUPPORT);
 	} else {
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].load_detection = FALSE;
-	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
@@ -2754,8 +2743,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 
 #if defined(__powerpc__)
 	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
@@ -2771,8 +2758,6 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 			       ATOM_DEVICE_DFP2_SUPPORT);
 #else
 	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
@@ -2787,9 +2772,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 
     if (info->InternalTVOut) {
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].load_detection = FALSE;
-	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
@@ -2941,21 +2924,21 @@ radeon_output_clones (ScrnInfoPtr pScrn, xf86OutputPtr output)
 	return index_mask;
 
     /* LVDS is too wacky */
-    if (radeon_output->type == OUTPUT_LVDS)
+    if (radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT))
+	return index_mask;
+
+    if (radeon_output->devices & (ATOM_DEVICE_TV_SUPPORT))
 	return index_mask;
 
     for (o = 0; o < config->num_output; o++) {
 	xf86OutputPtr clone = config->output[o];
 	RADEONOutputPrivatePtr radeon_clone = clone->driver_private;
+
 	if (output == clone) /* don't clone yourself */
 	    continue;
-	else if (radeon_clone->type == OUTPUT_LVDS) /* LVDS */
-	    continue;
-	else if ((radeon_output->DACType != DAC_NONE) &&
-		 (radeon_output->DACType == radeon_clone->DACType)) /* shared dac */
+	else if (radeon_clone->devices & (ATOM_DEVICE_LCD_SUPPORT)) /* LVDS */
 	    continue;
-	else if ((radeon_output->TMDSType != TMDS_NONE) &&
-		 (radeon_output->TMDSType == radeon_clone->TMDSType)) /* shared tmds */
+	else if (radeon_clone->devices & (ATOM_DEVICE_TV_SUPPORT)) /* TV */
 	    continue;
 	else
 	    index_mask |= (1 << o);
@@ -2987,9 +2970,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[i].load_detection = TRUE;
 	info->BiosConnector[i].shared_ddc = FALSE;
 	info->BiosConnector[i].ddc_i2c.valid = FALSE;
-	info->BiosConnector[i].DACType = DAC_NONE;
-	info->BiosConnector[i].TMDSType = TMDS_NONE;
-	info->BiosConnector[i].LVDSType = LVDS_NONE;
 	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
 	info->BiosConnector[i].devices = 0;
     }
@@ -3046,40 +3026,75 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 
     if (optstr) {
 	unsigned int ddc_line[2];
+	int DACType[2], TMDSType[2];
 
 	for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	    info->BiosConnector[i].valid = FALSE;
 	}
-	info->BiosConnector[0].valid = TRUE;
-	info->BiosConnector[1].valid = TRUE;
+
 	if (sscanf(optstr, "%u,%u,%u,%u,%u,%u,%u,%u",
 		   &ddc_line[0],
-		   &info->BiosConnector[0].DACType,
-		   &info->BiosConnector[0].TMDSType,
+		   &DACType[0],
+		   &TMDSType[0],
 		   &info->BiosConnector[0].ConnectorType,
 		   &ddc_line[1],
-		   &info->BiosConnector[1].DACType,
-		   &info->BiosConnector[1].TMDSType,
+		   &DACType[1],
+		   &TMDSType[1],
 		   &info->BiosConnector[1].ConnectorType) != 8) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr);
 	    return FALSE;
 	}
 
-	if (info->BiosConnector[0].DACType == DAC_TVDAC)
-	    info->BiosConnector[0].load_detection = FALSE;
-	if (info->BiosConnector[1].DACType == DAC_TVDAC)
-	    info->BiosConnector[1].load_detection = FALSE;
-
-	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(ddc_line[0]);
-	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(ddc_line[1]);
+	for (i = 0; i < 2; i++) {
+	    info->BiosConnector[i].valid = TRUE;
+	    info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(ddc_line[i]);
+	    switch (DACType[i]) {
+	    case 1:
+		info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_CRT1_SUPPORT,
+										    1),
+					ATOM_DEVICE_CRT1_SUPPORT))
+		    return FALSE;
+		info->BiosConnector[i].load_detection = TRUE;
+		break;
+	    case 2:
+		info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_CRT1_SUPPORT,
+										    2),
+					ATOM_DEVICE_CRT1_SUPPORT))
+		    return FALSE;
+		info->BiosConnector[i].load_detection = FALSE;
+		break;
+	    }
+	    switch (TMDSType[i]) {
+	    case 1:
+		info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_DFP1_SUPPORT,
+										    0),
+					ATOM_DEVICE_DFP1_SUPPORT))
+		    return FALSE;
+		break;
+	    case 2:
+		info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_DFP2_SUPPORT,
+										    0),
+					ATOM_DEVICE_DFP2_SUPPORT))
+		    return FALSE;
+		break;
+	    }
+	}
     }
 
-    info->tvdac_use_count = 0;
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
-	    if (info->BiosConnector[i].DACType == DAC_TVDAC)
-		info->tvdac_use_count++;
-
 	    if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
 		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
 		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A)) {
@@ -3123,18 +3138,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->linkb = info->BiosConnector[i].linkb;
 	    radeon_output->connector_id = info->BiosConnector[i].connector_object;
 
-	    radeon_output->LVDSType = info->BiosConnector[i].LVDSType;
-
-	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
-		radeon_output->DACType = DAC_NONE;
-	    else
-		radeon_output->DACType = info->BiosConnector[i].DACType;
-
-	    if (radeon_output->ConnectorType == CONNECTOR_VGA)
-		radeon_output->TMDSType = TMDS_NONE;
-	    else
-		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-
 	    RADEONSetOutputType(pScrn, radeon_output);
 	    if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
 		(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I) ||
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index f72faf9..2914e04 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -92,36 +92,6 @@ typedef enum
 
 typedef enum
 {
-    DAC_NONE    = 0,
-    DAC_PRIMARY = 1,
-    DAC_TVDAC   = 2,
-    DAC_EXT     = 3
-} RADEONDacType;
-
-typedef enum
-{
-    TMDS_NONE    = 0,
-    TMDS_INT     = 1,
-    TMDS_EXT     = 2,
-    TMDS_LVTMA   = 3,
-    TMDS_DDIA    = 4,
-    TMDS_UNIPHY  = 5,
-    TMDS_UNIPHY1 = 6,
-    TMDS_UNIPHY2 = 7
-} RADEONTmdsType;
-
-typedef enum
-{
-    LVDS_NONE    = 0,
-    LVDS_INT     = 1,
-    LVDS_LVTMA   = 2,
-    LVDS_UNIPHY  = 3,
-    LVDS_UNIPHY1 = 4,
-    LVDS_UNIPHY2 = 5
-} RADEONLvdsType;
-
-typedef enum
-{
     DVI_AUTO,
     DVI_DIGITAL,
     DVI_ANALOG
@@ -216,9 +186,6 @@ typedef struct _radeon_encoder {
 } radeon_encoder_rec, *radeon_encoder_ptr;
 
 typedef struct {
-    RADEONDacType DACType;
-    RADEONTmdsType TMDSType;
-    RADEONLvdsType LVDSType;
     RADEONConnectorType ConnectorType;
     Bool valid;
     int output_id;
@@ -238,10 +205,7 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONOutputType type;
     void *dev_priv;
     uint32_t ddc_line;
-    RADEONDacType DACType;
     RADEONDviType DVIType;
-    RADEONTmdsType TMDSType;
-    RADEONLvdsType LVDSType;
     RADEONMonitorType MonType;
     int crtc_num;
     int DDCReg;
commit 7b42b57d748f77ff6ef6f8ade7cbc983a98d7204
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 16:28:00 2009 -0500

    few more logic pasto's bits I missed

diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index e71170f..cba1b5f 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -1743,10 +1743,10 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
-	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT |
-						 ATOM_DEVICE_DFP_SUPPORT))
+	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT |
+						ATOM_DEVICE_DFP_SUPPORT))
 		pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
-	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT))
+	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
 		pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
 	}
     }
@@ -1791,7 +1791,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
-	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		switch (radeon_crtc->crtc_id) {
 		case 0:
 		    RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
commit 1305376b009d17d65b4935896dc35cb7530f7c52
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 15:20:47 2009 -0500

    Move active_device setup to detect()
    
    Also add encoder debugging printouts

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 9a4927c..c0bd48d 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2299,6 +2299,12 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	}
     }
 
+    for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
+	if (info->encoders[i] != NULL) {
+	    ErrorF("encoder: 0x%x\n", info->encoders[i]->encoder_id);
+	}
+    }
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
     for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
 	if (info->BiosConnector[i].valid) {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 13243d6..edbb895 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -356,49 +356,6 @@ RADEONConnectorFindMonitor(xf86OutputPtr output)
 	}
     }
 
-    if (radeon_output->MonType == MT_DFP) {
-	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_LCD) {
-	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if ((radeon_output->MonType == MT_STV) ||
-	       (radeon_output->MonType == MT_CTV)){
-	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
-	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else if (radeon_output->MonType == MT_CV) {
-	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
-	else
-	    radeon_output->active_device = 0;
-    } else
-	radeon_output->active_device = 0;
-
     /* update panel info for RMX */
     if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
 	RADEONUpdatePanelSize(output);
@@ -1085,6 +1042,49 @@ radeon_detect(xf86OutputPtr output)
 	}
     }
 
+    if (radeon_output->MonType == MT_DFP) {
+	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_CRT) {
+	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_LCD) {
+	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if ((radeon_output->MonType == MT_STV) ||
+	       (radeon_output->MonType == MT_CTV)){
+	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_CV) {
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else
+	radeon_output->active_device = 0;
+
     if (radeon_output->MonType == MT_UNKNOWN) {
         output->subpixel_order = SubPixelUnknown;
 	return XF86OutputStatusUnknown;
commit 9e0cc0ca5d7bc68756ae92ee3b5b2392366be71a
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 14:47:08 2009 -0500

    Fix logic cut and paste error

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 56bbdf9..6af7f12 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -74,9 +74,9 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
 
     disp_data.ucAction = ATOM_ENABLE;
 
-    if (radeon_output->active_device && (ATOM_DEVICE_CRT_SUPPORT))
+    if (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT))
 	disp_data.ucDacStandard = ATOM_DAC1_PS2;
-    else if (radeon_output->active_device && (ATOM_DEVICE_CV_SUPPORT))
+    else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.ucDacStandard = ATOM_DAC1_CV;
     else {
 	switch (radeon_output->tvStd) {
@@ -124,7 +124,7 @@ atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode)
 
     disp_data.sTVEncoder.ucAction = ATOM_ENABLE;
 
-    if (radeon_output->active_device && (ATOM_DEVICE_CV_SUPPORT))
+    if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
     else {
 	switch (radeon_output->tvStd) {
@@ -264,7 +264,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
     case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-	if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT))
+	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
 	    index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
 	else
 	    index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
@@ -285,7 +285,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    if (radeon_output->type == OUTPUT_HDMI)
 		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
-	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) {
+	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 1))
@@ -317,7 +317,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    disp_data2.ucSpatial = 0;
 	    disp_data2.ucTemporal = 0;
 	    disp_data2.ucFRC = 0;
-	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) {
+	    if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 5)) {
diff --git a/src/legacy_output.c b/src/legacy_output.c
index a35d0bb..a722253 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -763,7 +763,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    RADEONDacPowerSet(pScrn, bEnable, TRUE);
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		ErrorF("enable TV\n");
 		info->output_tv1 |= (1 << o);
 		tmp = INREG(RADEON_TV_MASTER_CNTL);
@@ -861,11 +861,11 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		tmp &= ~RADEON_CRTC_CRT_ON;
 		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
 		save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+		RADEONDacPowerSet(pScrn, bEnable, TRUE);
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+	    if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		ErrorF("disable TV\n");
 		info->output_tv1 &= ~(1 << o);
 		tv_dac_change = 2;
@@ -1197,8 +1197,11 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
 
     save->fp_horz_vert_active = 0;
 
-    if ((radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) ||
-	(radeon_output->active_device && (ATOM_DEVICE_DFP_SUPPORT))) {
+    if ((radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT)) ||
+	(radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))) {
+
+	ErrorF("RMX for DFP/LCD\n");
+
 	if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
 	    Hscale = FALSE;
 	    Vscale = FALSE;
@@ -1409,6 +1412,7 @@ legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	return;
 
     if (radeon_crtc->crtc_id == 0) {
+	ErrorF("set RMX\n");
 	is_primary = TRUE;
 	RADEONInitRMXRegisters(output, info->ModeReg, adjusted_mode);
 	RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
@@ -1454,7 +1458,7 @@ legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-	if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 	    ErrorF("set TV\n");
 	    RADEONInitTVRegisters(output, info->ModeReg, adjusted_mode, is_primary);
 	    RADEONRestoreDACRegisters(pScrn, info->ModeReg);
commit 12010ae9296635ffa5f42ce0cd14482aaa290cf7
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 13:52:11 2009 -0500

    More legacy rework

diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index 78ac5b3..e71170f 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -45,6 +45,7 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
+#include "radeon_atombios.h"
 
 #ifdef XF86DRI
 #define _XF86DRI_SERVER_
@@ -1742,9 +1743,10 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
-	    if (radeon_output->MonType != MT_CRT)
+	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT |
+						 ATOM_DEVICE_DFP_SUPPORT))
 		pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
-	    if (radeon_output->MonType == MT_LCD)
+	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT))
 		pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
 	}
     }
@@ -1789,7 +1791,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
-	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
 		switch (radeon_crtc->crtc_id) {
 		case 0:
 		    RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
commit 3f8bbede8bf639050f773780888b89cbdcb425b8
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 13:45:11 2009 -0500

    fix legacy crtc routing and add some debugging info

diff --git a/src/legacy_output.c b/src/legacy_output.c
index 71fef86..a35d0bb 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -708,6 +708,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	/*ErrorF("enable montype: %d\n", radeon_output->MonType);*/
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	    ErrorF("enable LVDS\n");
 	    info->output_lcd1 |= (1 << o);
 	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
 	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
@@ -718,6 +719,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	    ErrorF("enable FP1\n");
 	    info->output_dfp1 |= (1 << o);
 	    tmp = INREG(RADEON_FP_GEN_CNTL);
 	    tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
@@ -733,6 +735,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	    ErrorF("enable FP2\n");
 	    info->output_dfp2 |= (1 << o);
 	    tmp = INREG(RADEON_FP2_GEN_CNTL);
 	    tmp &= ~RADEON_FP2_BLANK_EN;
@@ -751,6 +754,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    ErrorF("enable primary dac\n");
 	    info->output_crt1 |= (1 << o);
 	    tmp = INREG(RADEON_CRTC_EXT_CNTL);
 	    tmp |= RADEON_CRTC_CRT_ON;
@@ -760,6 +764,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+		ErrorF("enable TV\n");
 		info->output_tv1 |= (1 << o);
 		tmp = INREG(RADEON_TV_MASTER_CNTL);
 		tmp |= RADEON_TV_ON;
@@ -767,6 +772,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		tv_dac_change = 2;
 		radeon_output->tv_on = TRUE;
 	    } else {
+		ErrorF("enable TVDAC\n");
 		info->output_crt2 |= (1 << o);
 		if (info->ChipFamily == CHIP_FAMILY_R200) {
 		    tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -787,6 +793,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	    ErrorF("disable LVDS\n");
 	    info->output_lcd1 &= ~(1 << o);
 	    if (!info->output_lcd1) {
 		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
@@ -808,6 +815,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	    ErrorF("disable FP1\n");
 	    info->output_dfp1 &= ~(1 << o);
 	    if (!info->output_dfp1) {
 		tmp = INREG(RADEON_FP_GEN_CNTL);
@@ -825,6 +833,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	    ErrorF("disable FP2\n");
 	    info->output_dfp2 &= ~(1 << o);
 	    if (!info->output_dfp2) {
 		tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -845,6 +854,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    }
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    ErrorF("disable primary dac\n");
 	    info->output_crt1 &= ~(1 << o);
 	    if (!info->output_crt1) {
 		tmp = INREG(RADEON_CRTC_EXT_CNTL);
@@ -856,6 +866,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    break;
 	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+		ErrorF("disable TV\n");
 		info->output_tv1 &= ~(1 << o);
 		tv_dac_change = 2;
 		if (!info->output_tv1) {
@@ -865,6 +876,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		    radeon_output->tv_on = FALSE;
 		}
 	    } else {
+		ErrorF("disable TVDAC\n");
 		info->output_crt2 &= ~(1 << o);
 		tv_dac_change = 1;
 		if (!info->output_crt2) {
@@ -1391,26 +1403,31 @@ legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
     xf86CrtcPtr	crtc = output->crtc;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+    Bool is_primary = FALSE;
 
     if (radeon_encoder == NULL)
 	return;
 
     if (radeon_crtc->crtc_id == 0) {
+	is_primary = TRUE;
 	RADEONInitRMXRegisters(output, info->ModeReg, adjusted_mode);
 	RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
     }
 
     switch (radeon_encoder->encoder_id) {
     case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-	RADEONInitLVDSRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	ErrorF("set LVDS\n");
+	RADEONInitLVDSRegisters(output, info->ModeReg, adjusted_mode, is_primary);
 	RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-	RADEONInitFPRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	ErrorF("set FP1\n");
+	RADEONInitFPRegisters(output, info->ModeReg, adjusted_mode, is_primary);
 	RADEONRestoreFPRegisters(pScrn, info->ModeReg);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DVO1:
-	RADEONInitFP2Registers(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	ErrorF("set FP2\n");
+	RADEONInitFP2Registers(output, info->ModeReg, adjusted_mode, is_primary);
 	if (info->IsAtomBios) {
 	    unsigned char *RADEONMMIO = info->MMIO;
 	    uint32_t fp2_gen_cntl;
@@ -1432,16 +1449,19 @@ legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 	}
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-	RADEONInitDACRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	ErrorF("set primary dac\n");
+	RADEONInitDACRegisters(output, info->ModeReg, adjusted_mode, is_primary);
 	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
 	break;
     case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
-	    RADEONInitTVRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	    ErrorF("set TV\n");
+	    RADEONInitTVRegisters(output, info->ModeReg, adjusted_mode, is_primary);
 	    RADEONRestoreDACRegisters(pScrn, info->ModeReg);
 	    RADEONRestoreTVRegisters(pScrn, info->ModeReg);
 	} else {
-	    RADEONInitDAC2Registers(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	    ErrorF("set TVDAC\n");
+	    RADEONInitDAC2Registers(output, info->ModeReg, adjusted_mode, is_primary);
 	    RADEONRestoreDACRegisters(pScrn, info->ModeReg);
 	}
 	break;
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 78d6ee1..9a4927c 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1601,8 +1601,10 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
     uint32_t device_index = radeon_get_device_index(device_support);
     int i;
 
-    if (device_support == 0)
+    if (device_support == 0) {
+	ErrorF("device support == 0\n");
 	return FALSE;
+    }
 
     if (info->encoders[device_index] != NULL)
 	return TRUE;
@@ -1620,8 +1622,10 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo
 	    info->encoders[device_index]->encoder_id = encoder_id;
 	    // add dev_priv stuff
 	    return TRUE;
-	} else
+	} else {
+	    ErrorF("xalloc failed\n");
 	    return FALSE;
+	}
     }
 
 }
@@ -2057,6 +2061,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	switch (dac) {
 	    // primary dac
 	case 1:
+	    ErrorF("adding primary dac\n");
 	    if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
 		(info->ChipFamily == CHIP_FAMILY_RS400) ||
 		(info->ChipFamily == CHIP_FAMILY_RS480))
@@ -2068,6 +2073,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    break;
 	    // secondary dac
 	case 2:
+	    ErrorF("adding tv dac\n");
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
 	    else {
@@ -2079,6 +2085,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    break;
 	    // external dac
 	case 3:
+	    ErrorF("adding external dac\n");
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
 	    else
@@ -2087,12 +2094,14 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	}
 	break;
     case ATOM_DEVICE_LCD1_SUPPORT:
+	ErrorF("adding LVDS\n");
 	if (IS_AVIVO_VARIANT)
 	    ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
 	else
 	    ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
 	break;
     case ATOM_DEVICE_DFP1_SUPPORT:
+	ErrorF("adding FP1\n");
 	if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS400) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS480))
@@ -2104,6 +2113,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	break;
     case ATOM_DEVICE_LCD2_SUPPORT:
     case ATOM_DEVICE_DFP2_SUPPORT:
+	ErrorF("adding FP2\n");
 	if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
 	    (info->ChipFamily == CHIP_FAMILY_RS740))
@@ -2114,6 +2124,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
 	break;
     case ATOM_DEVICE_DFP3_SUPPORT:
+	ErrorF("adding FP3\n");
 	ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
 	break;
     }
commit 80e0162ea2c1f793964731268251aba2d3243127
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 13:28:14 2009 -0500

    ATOM: fix encoder init

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index c20e687..78d6ee1 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2198,7 +2198,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	if (!radeon_add_encoder(pScrn,
 			   radeon_get_encoder_id_from_supported_device(pScrn, (1 << i),
 					  ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC),
-				(i << 1)))
+				(1 << i)))
 	    return FALSE;
 
 	if (i == ATOM_DEVICE_DFP1_INDEX)
commit aea27d9caabb0e54e868a21e6e547733a4ca2709
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 12:33:49 2009 -0500

    Switch legacy output code to use new encoder objects

diff --git a/src/legacy_output.c b/src/legacy_output.c
index f9b0dff..71fef86 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -635,8 +635,7 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
 	uint32_t tv_dac_cntl;
 	uint32_t fp2_gen_cntl;
 
-	switch(info->ChipFamily)
-	{
+	switch(info->ChipFamily) {
 	case CHIP_FAMILY_R420:
 	case CHIP_FAMILY_RV410:
 	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
@@ -662,7 +661,6 @@ RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
 	    }
 	    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
 	    break;
-
 	default:
 	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
 	    if (IsOn) {
@@ -694,6 +692,10 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
     RADEONOutputPrivatePtr radeon_output;
     int tv_dac_change = 0, o;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+
+    if (radeon_encoder == NULL)
+	return;
 
     radeon_output = output->driver_private;
     for (o = 0; o < xf86_config->num_output; o++) {
@@ -704,15 +706,67 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 
     if (bEnable) {
 	/*ErrorF("enable montype: %d\n", radeon_output->MonType);*/
-	if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->DACType == DAC_PRIMARY) {
-		info->output_crt1 |= (1 << o);
-		tmp = INREG(RADEON_CRTC_EXT_CNTL);
-		tmp |= RADEON_CRTC_CRT_ON;
-		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-		save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
-		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-	    } else if (radeon_output->DACType == DAC_TVDAC) {
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	    info->output_lcd1 |= (1 << o);
+	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
+	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
+	    usleep (radeon_output->PanelPwrDly * 1000);
+	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	    info->output_dfp1 |= (1 << o);
+	    tmp = INREG(RADEON_FP_GEN_CNTL);
+	    tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+	    OUTREG(RADEON_FP_GEN_CNTL, tmp);
+	    save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+		(info->ChipFamily == CHIP_FAMILY_RS480)) {
+		tmp = INREG(RS400_FP_2ND_GEN_CNTL);
+		tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
+		OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
+		save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON |
+					  RS400_TMDS_2ND_EN);
+	    }
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	    info->output_dfp2 |= (1 << o);
+	    tmp = INREG(RADEON_FP2_GEN_CNTL);
+	    tmp &= ~RADEON_FP2_BLANK_EN;
+	    tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+	    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+	    save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+	    save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
+	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+		(info->ChipFamily == CHIP_FAMILY_RS480)) {
+		tmp = INREG(RS400_FP2_2_GEN_CNTL);
+		tmp &= ~RS400_FP2_2_BLANK_EN;
+		tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
+		save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN;
+	    }
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    info->output_crt1 |= (1 << o);
+	    tmp = INREG(RADEON_CRTC_EXT_CNTL);
+	    tmp |= RADEON_CRTC_CRT_ON;
+	    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+	    save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
+	    RADEONDacPowerSet(pScrn, bEnable, TRUE);
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+		info->output_tv1 |= (1 << o);
+		tmp = INREG(RADEON_TV_MASTER_CNTL);
+		tmp |= RADEON_TV_ON;
+		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+		tv_dac_change = 2;
+		radeon_output->tv_on = TRUE;
+	    } else {
 		info->output_crt2 |= (1 << o);
 		if (info->ChipFamily == CHIP_FAMILY_R200) {
 		    tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -727,70 +781,90 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		}
 		tv_dac_change = 1;
 	    }
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType == TMDS_INT) {
-		info->output_dfp1 |= (1 << o);
+	    break;
+	}
+    } else {
+	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	    info->output_lcd1 &= ~(1 << o);
+	    if (!info->output_lcd1) {
+		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+		if (info->IsMobility || info->IsIGP) {
+		    /* Asic bug, when turning off LVDS_ON, we have to make sure
+		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+		    */
+		    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+		}
+		tmp = INREG(RADEON_LVDS_GEN_CNTL);
+		tmp |= RADEON_LVDS_DISPLAY_DIS;
+		tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+		OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+		save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+		save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+		if (info->IsMobility || info->IsIGP) {
+		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+		}
+	    }
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	    info->output_dfp1 &= ~(1 << o);
+	    if (!info->output_dfp1) {
 		tmp = INREG(RADEON_FP_GEN_CNTL);
-		tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+		tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
 		OUTREG(RADEON_FP_GEN_CNTL, tmp);
-		save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+		save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
 		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
 		    (info->ChipFamily == CHIP_FAMILY_RS480)) {
 		    tmp = INREG(RS400_FP_2ND_GEN_CNTL);
-		    tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
+		    tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
 		    OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
-		    save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON |
-					      RS400_TMDS_2ND_EN);
+		    save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON |
+					       RS400_TMDS_2ND_EN);
 		}
-	    } else if (radeon_output->TMDSType == TMDS_EXT) {
-		info->output_dfp2 |= (1 << o);
+	    }
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	    info->output_dfp2 &= ~(1 << o);
+	    if (!info->output_dfp2) {
 		tmp = INREG(RADEON_FP2_GEN_CNTL);
-		tmp &= ~RADEON_FP2_BLANK_EN;
-		tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		tmp |= RADEON_FP2_BLANK_EN;
+		tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
 		OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-		save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
+		save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+		save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
 		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
 		    (info->ChipFamily == CHIP_FAMILY_RS480)) {
 		    tmp = INREG(RS400_FP2_2_GEN_CNTL);
-		    tmp &= ~RS400_FP2_2_BLANK_EN;
-		    tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		    tmp |= RS400_FP2_2_BLANK_EN;
+		    tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
 		    OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
-		    save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
-		    save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN;
+		    save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
+		    save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN;
 		}
 	    }
-	} else if (radeon_output->MonType == MT_LCD) {
-	    info->output_lcd1 |= (1 << o);
-	    tmp = INREG(RADEON_LVDS_GEN_CNTL);
-	    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-	    tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
-	    usleep (radeon_output->PanelPwrDly * 1000);
-	    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-	    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-	    save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
-	} else if (radeon_output->MonType == MT_STV ||
-		   radeon_output->MonType == MT_CTV) {
-	    info->output_tv1 |= (1 << o);
-	    tmp = INREG(RADEON_TV_MASTER_CNTL);
-	    tmp |= RADEON_TV_ON;
-	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-	    tv_dac_change = 2;
-	    radeon_output->tv_on = TRUE;
-	}
-    } else {
-	/*ErrorF("disable montype: %d\n", radeon_output->MonType);*/
-	if (radeon_output->MonType == MT_CRT) {
-	    if (radeon_output->DACType == DAC_PRIMARY) {
-		info->output_crt1 &= ~(1 << o);
-		if (!info->output_crt1) {
-		    tmp = INREG(RADEON_CRTC_EXT_CNTL);
-		    tmp &= ~RADEON_CRTC_CRT_ON;
-		    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-		    save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-		    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    info->output_crt1 &= ~(1 << o);
+	    if (!info->output_crt1) {
+		tmp = INREG(RADEON_CRTC_EXT_CNTL);
+		tmp &= ~RADEON_CRTC_CRT_ON;
+		OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+		save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
+		RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	    }
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+	    if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+		info->output_tv1 &= ~(1 << o);
+		tv_dac_change = 2;
+		if (!info->output_tv1) {
+		    tmp = INREG(RADEON_TV_MASTER_CNTL);
+		    tmp &= ~RADEON_TV_ON;
+		    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+		    radeon_output->tv_on = FALSE;
 		}
-	    } else if (radeon_output->DACType == DAC_TVDAC) {
+	    } else {
 		info->output_crt2 &= ~(1 << o);
 		tv_dac_change = 1;
 		if (!info->output_crt2) {
@@ -807,72 +881,7 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 		    }
 		}
 	    }
-	} else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType == TMDS_INT) {
-		info->output_dfp1 &= ~(1 << o);
-		if (!info->output_dfp1) {
-		    tmp = INREG(RADEON_FP_GEN_CNTL);
-		    tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-		    OUTREG(RADEON_FP_GEN_CNTL, tmp);
-		    save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-		    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
-			(info->ChipFamily == CHIP_FAMILY_RS480)) {
-			tmp = INREG(RS400_FP_2ND_GEN_CNTL);
-			tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN);
-			OUTREG(RS400_FP_2ND_GEN_CNTL, tmp);
-			save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON |
-						   RS400_TMDS_2ND_EN);
-		    }
-		}
-	    } else if (radeon_output->TMDSType == TMDS_EXT) {
-		info->output_dfp2 &= ~(1 << o);
-		if (!info->output_dfp2) {
-		    tmp = INREG(RADEON_FP2_GEN_CNTL);
-		    tmp |= RADEON_FP2_BLANK_EN;
-		    tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-		    save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-		    save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
-		    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
-			(info->ChipFamily == CHIP_FAMILY_RS480)) {
-			tmp = INREG(RS400_FP2_2_GEN_CNTL);
-			tmp |= RS400_FP2_2_BLANK_EN;
-			tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
-			OUTREG(RS400_FP2_2_GEN_CNTL, tmp);
-			save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN);
-			save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN;
-		    }
-		}
-	    }
-	} else if (radeon_output->MonType == MT_LCD) {
-	    info->output_lcd1 &= ~(1 << o);
-	    if (!info->output_lcd1) {
-		unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-		if (info->IsMobility || info->IsIGP) {
-		    /* Asic bug, when turning off LVDS_ON, we have to make sure
-		       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-		    */
-		    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-		}
-		tmp = INREG(RADEON_LVDS_GEN_CNTL);
-		tmp |= RADEON_LVDS_DISPLAY_DIS;
-		tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-		OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-		save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
-		save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
-		if (info->IsMobility || info->IsIGP) {
-		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
-		}
-	    }
-	} else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
-	    info->output_tv1 &= ~(1 << o);
-	    tv_dac_change = 2;
-	    if (!info->output_tv1) {
-		tmp = INREG(RADEON_TV_MASTER_CNTL);
-		tmp &= ~RADEON_TV_ON;
-		OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-		radeon_output->tv_on = FALSE;
-	    }
+	    break;
 	}
     }
 
@@ -883,9 +892,9 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 	    info->tv_dac_enable_mask &= ~tv_dac_change;
 
 	if (bEnable && info->tv_dac_enable_mask)
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	    RADEONDacPowerSet(pScrn, bEnable, FALSE);
 	else if (!bEnable && info->tv_dac_enable_mask == 0)
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	    RADEONDacPowerSet(pScrn, bEnable, FALSE);
 
     }
 }
@@ -1176,88 +1185,91 @@ RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
 
     save->fp_horz_vert_active = 0;
 
-    if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
-	return;
-
-    if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
-	Hscale = FALSE;
-	Vscale = FALSE;
-    } else {
-	if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
-	if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
-
-	if (xres == radeon_output->PanelXRes)
+    if ((radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) ||
+	(radeon_output->active_device && (ATOM_DEVICE_DFP_SUPPORT))) {
+	if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
 	    Hscale = FALSE;
-	if (yres == radeon_output->PanelYRes)
 	    Vscale = FALSE;
-    }
+	} else {
+	    if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+	    if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
 
-    if ((!Hscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
-	(radeon_output->rmx_type == RMX_CENTER)) {
-	save->fp_horz_stretch |= ((xres/8-1)<<16);
-    } else {
-	CARD32 scale, inc;
-	inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
-	scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
-	    / radeon_output->PanelXRes + 1;
-	save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
-				  RADEON_HORZ_STRETCH_BLEND |
-				  RADEON_HORZ_STRETCH_ENABLE |
-				  ((radeon_output->PanelXRes/8-1)<<16));
-    }
+	    if (xres == radeon_output->PanelXRes)
+		Hscale = FALSE;
+	    if (yres == radeon_output->PanelYRes)
+		Vscale = FALSE;
+	}
 
-    if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
-	(radeon_output->rmx_type == RMX_CENTER)) {
-	save->fp_vert_stretch |= ((yres-1)<<12);
-    } else {
-	CARD32 scale, inc;
-	inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
-	scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
-	    / radeon_output->PanelYRes + 1;
-	save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
-				  RADEON_VERT_STRETCH_ENABLE |
-				  RADEON_VERT_STRETCH_BLEND |
-				  ((radeon_output->PanelYRes-1)<<12));
-    }
+	if ((!Hscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
+	    (radeon_output->rmx_type == RMX_CENTER)) {
+	    save->fp_horz_stretch |= ((xres/8-1)<<16);
+	} else {
+	    CARD32 scale, inc;
+	    inc = (save->fp_horz_stretch & RADEON_HORZ_AUTO_RATIO_INC) ? 1 : 0;
+	    scale = ((xres + inc) * RADEON_HORZ_STRETCH_RATIO_MAX)
+		/ radeon_output->PanelXRes + 1;
+	    save->fp_horz_stretch |= (((scale) & RADEON_HORZ_STRETCH_RATIO_MASK) |
+				      RADEON_HORZ_STRETCH_BLEND |
+				      RADEON_HORZ_STRETCH_ENABLE |
+				      ((radeon_output->PanelXRes/8-1)<<16));
+	}
 
-    if ((radeon_output->rmx_type == RMX_CENTER) &&
-	(radeon_output->Flags & RADEON_USE_RMX)) {
-	int    blank_width;
+	if ((!Vscale) || (!(radeon_output->Flags & RADEON_USE_RMX)) ||
+	    (radeon_output->rmx_type == RMX_CENTER)) {
+	    save->fp_vert_stretch |= ((yres-1)<<12);
+	} else {
+	    CARD32 scale, inc;
+	    inc = (save->fp_vert_stretch & RADEON_VERT_AUTO_RATIO_INC) ? 1 : 0;
+	    scale = ((yres + inc) * RADEON_VERT_STRETCH_RATIO_MAX)
+		/ radeon_output->PanelYRes + 1;
+	    save->fp_vert_stretch |= (((scale) & RADEON_VERT_STRETCH_RATIO_MASK) |
+				      RADEON_VERT_STRETCH_ENABLE |
+				      RADEON_VERT_STRETCH_BLEND |
+				      ((radeon_output->PanelYRes-1)<<12));
+	}
 
-	save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
-				 RADEON_CRTC_AUTO_VERT_CENTER_EN);
+	if ((radeon_output->rmx_type == RMX_CENTER) &&
+	    (radeon_output->Flags & RADEON_USE_RMX)) {
+	    int    blank_width;
 
-	blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8;
-	if (blank_width > 110) blank_width = 110;
+	    save->crtc_more_cntl |= (RADEON_CRTC_AUTO_HORZ_CENTER_EN |
+				     RADEON_CRTC_AUTO_VERT_CENTER_EN);
 
-	save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
-				      | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
-					 << 16));
+	    blank_width = (mode->CrtcHBlankEnd - mode->CrtcHBlankStart) / 8;
+	    if (blank_width > 110)
+		blank_width = 110;
 
-	hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
-	if (!hsync_wid)       hsync_wid = 1;
+	    save->fp_crtc_h_total_disp = (((blank_width) & 0x3ff)
+					  | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+					     << 16));
 
-	save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff)
-				    | ((hsync_wid & 0x3f) << 16)
-				    | ((mode->Flags & V_NHSYNC)
-				       ? RADEON_CRTC_H_SYNC_POL
-				       : 0));
+	    hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+	    if (!hsync_wid)
+		hsync_wid = 1;
 
-	save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff)
-				      | ((mode->CrtcVDisplay - 1) << 16));
+	    save->fp_h_sync_strt_wid = ((((mode->CrtcHSyncStart - mode->CrtcHBlankStart) / 8) & 0x1fff)
+					| ((hsync_wid & 0x3f) << 16)
+					| ((mode->Flags & V_NHSYNC)
+					   ? RADEON_CRTC_H_SYNC_POL
+					   : 0));
 
-	vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
-	if (!vsync_wid)       vsync_wid = 1;
+	    save->fp_crtc_v_total_disp = (((mode->CrtcVBlankEnd - mode->CrtcVBlankStart) & 0xffff)
+					  | ((mode->CrtcVDisplay - 1) << 16));
 
-	save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff)
-				    | ((vsync_wid & 0x1f) << 16)
-				    | ((mode->Flags & V_NVSYNC)
-				       ? RADEON_CRTC_V_SYNC_POL
-				       : 0)));
+	    vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+	    if (!vsync_wid)
+		vsync_wid = 1;
 
-	save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) |
-				     (((radeon_output->PanelXRes / 8) & 0x1ff) << 16));
+	    save->fp_v_sync_strt_wid = ((((mode->CrtcVSyncStart - mode->CrtcVBlankStart) & 0xfff)
+					 | ((vsync_wid & 0x1f) << 16)
+					 | ((mode->Flags & V_NVSYNC)
+					    ? RADEON_CRTC_V_SYNC_POL
+					    : 0)));
 
+	    save->fp_horz_vert_active = (((radeon_output->PanelYRes) & 0xfff) |
+					 (((radeon_output->PanelXRes / 8) & 0x1ff) << 16));
+
+	}
     }
 }
 
@@ -1369,96 +1381,70 @@ RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
     }
 }
 
-static void
-RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
-			  DisplayModePtr mode, xf86OutputPtr output,
-			  int crtc_num)
-{
-    Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (crtc_num == 0)
-	RADEONInitRMXRegisters(output, save, mode);
-
-    if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->DACType == DAC_PRIMARY) {
-	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
-	} else {
-	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
-	}
-    } else if (radeon_output->MonType == MT_LCD) {
-	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
-    } else if (radeon_output->MonType == MT_DFP) {
-	if (radeon_output->TMDSType == TMDS_INT) {
-	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
-	} else {
-	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
-	}
-    } else if (radeon_output->MonType == MT_STV ||
-	       radeon_output->MonType == MT_CTV) {
-	RADEONInitTVRegisters(output, save, mode, IsPrimary);
-    }
-}
-
 void
 legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		  DisplayModePtr adjusted_mode)
+		       DisplayModePtr adjusted_mode)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     xf86CrtcPtr	crtc = output->crtc;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
 
-    RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
+    if (radeon_encoder == NULL)
+	return;
 
-    if (radeon_crtc->crtc_id == 0)
+    if (radeon_crtc->crtc_id == 0) {
+	RADEONInitRMXRegisters(output, info->ModeReg, adjusted_mode);
 	RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
+    }
 
-    switch(radeon_output->MonType) {
-    case MT_LCD:
-	ErrorF("restore LVDS\n");
+    switch (radeon_encoder->encoder_id) {
+    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	RADEONInitLVDSRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
 	RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
 	break;
-    case MT_DFP:
-	if (radeon_output->TMDSType == TMDS_INT) {
-	    ErrorF("restore FP\n");
-	    RADEONRestoreFPRegisters(pScrn, info->ModeReg);
-	} else {
-	    ErrorF("restore FP2\n");
-	    if (info->IsAtomBios) {
-		unsigned char *RADEONMMIO = info->MMIO;
-		uint32_t fp2_gen_cntl;
-
-		atombios_external_tmds_setup(output, mode);
-		/* r4xx atom has hard coded crtc mappings in the atom code
-		 * Fix it up here.
-		 */
-		fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK;
-		if (radeon_crtc->crtc_id == 1)
-		    fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
-		else {
-		    if (radeon_output->Flags & RADEON_USE_RMX)
-			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
-		    else
-			fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
-		}
-		OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
-	    } else {
-		RADEONRestoreFP2Registers(pScrn, info->ModeReg);
-		RADEONRestoreDVOChip(pScrn, output);
+    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	RADEONInitFPRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	RADEONRestoreFPRegisters(pScrn, info->ModeReg);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	RADEONInitFP2Registers(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	if (info->IsAtomBios) {
+	    unsigned char *RADEONMMIO = info->MMIO;
+	    uint32_t fp2_gen_cntl;
+
+	    atombios_external_tmds_setup(output, mode);
+	    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL) & ~R200_FP2_SOURCE_SEL_MASK;
+	    if (radeon_crtc->crtc_id == 1)
+		fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+	    else {
+		if (radeon_output->Flags & RADEON_USE_RMX)
+		    fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+		else
+		    fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1;
 	    }
+	    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+	} else {
+	    RADEONRestoreFP2Registers(pScrn, info->ModeReg);
+	    RADEONRestoreDVOChip(pScrn, output);
 	}
 	break;
-    case MT_STV:
-    case MT_CTV:
-	ErrorF("restore tv\n");
+    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	RADEONInitDACRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
 	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
-	RADEONRestoreTVRegisters(pScrn, info->ModeReg);
 	break;
-    default:
-	ErrorF("restore dac\n");
-	RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+	if (radeon_output->active_device && (ATOM_DEVICE_TV_SUPPORT)) {
+	    RADEONInitTVRegisters(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	    RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+	    RADEONRestoreTVRegisters(pScrn, info->ModeReg);
+	} else {
+	    RADEONInitDAC2Registers(output, info->ModeReg, adjusted_mode, radeon_crtc->crtc_id);
+	    RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+	}
+	break;
     }
 
 }
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index c9fff8c..c20e687 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2071,9 +2071,9 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
 	    else {
-		if (info->ChipFamily == CHIP_FAMILY_R200)
+		/*if (info->ChipFamily == CHIP_FAMILY_R200)
 		    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
-		else
+		    else*/
 		    ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
 	    }
 	    break;
commit 9b44a4b57b00b150d041a5d82cb2df42159c062b
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 11:32:24 2009 -0500

    ATOM: more output cleanup

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 4f5c499..56bbdf9 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -377,6 +377,49 @@ atombios_maybe_hdmi_mode(xf86OutputPtr output)
 }
 
 static int
+atombios_get_encoder_mode(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    /* DVI should really be atombios_maybe_hdmi_mode() as well */
+    switch (radeon_output->ConnectorType) {
+    case CONNECTOR_DVI_I:
+	if (radeon_output->active_device & (ATOM_DEVICE_DFP_SUPPORT))
+	    return ATOM_ENCODER_MODE_DVI;
+	else
+	    return ATOM_ENCODER_MODE_CRT;
+	break;
+    case CONNECTOR_DVI_D:
+    default:
+	return ATOM_ENCODER_MODE_DVI;
+	break;
+    case CONNECTOR_HDMI_TYPE_A:
+    case CONNECTOR_HDMI_TYPE_B:
+	return atombios_maybe_hdmi_mode(output);
+	break;
+    case CONNECTOR_LVDS:
+	return ATOM_ENCODER_MODE_LVDS;
+	break;
+    case CONNECTOR_DISPLAY_PORT:
+	return ATOM_ENCODER_MODE_DP;
+	break;
+    case CONNECTOR_DVI_A:
+    case CONNECTOR_VGA:
+    case CONNECTOR_STV:
+    case CONNECTOR_CTV:
+    case CONNECTOR_DIN:
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
+	    return ATOM_ENCODER_MODE_TV;
+	else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
+	    return ATOM_ENCODER_MODE_CV;
+	else
+	    return ATOM_ENCODER_MODE_CRT;
+	break;
+    }
+
+}
+
+static int
 atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
@@ -457,14 +500,7 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
 	disp_data.ucLaneNum = 4;
     }
 
-    if (OUTPUT_IS_DVI)
-	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DVI;
-    else if (radeon_output->type == OUTPUT_HDMI)
-	disp_data.ucEncoderMode = atombios_maybe_hdmi_mode(output);
-    else if (radeon_output->type == OUTPUT_DP)
-	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DP;
-    else if (radeon_output->type == OUTPUT_LVDS)
-	disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
+    disp_data.ucEncoderMode = atombios_get_encoder_mode(output);
 
     data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
@@ -744,9 +780,9 @@ atombios_dig_dpms(xf86OutputPtr output, int mode)
 
     disp_data.ucConfig = radeon_output->transmitter_config;
 
-    if (IS_DCE32_VARIANT) {
+    if (IS_DCE32_VARIANT)
 	data.exec.index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
-    } else {
+    else {
 	switch (radeon_encoder->encoder_id) {
 	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
@@ -891,10 +927,14 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 	    break;
 	case 2:
 	    crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
+	    crtc_src_param2.ucEncodeMode = atombios_get_encoder_mode(output);
 	    switch (radeon_encoder->encoder_id) {
 	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-
+		if (IS_DCE3_VARIANT)
+		    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+		else
+		    crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device);
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
@@ -906,23 +946,11 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 			crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
 		} else
 		    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-		if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
-		else {
-		    if (OUTPUT_IS_DVI)
-			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
-		    else if (radeon_output->type == OUTPUT_HDMI)
-			crtc_src_param2.ucEncodeMode =
-			    atombios_maybe_hdmi_mode(output);
-		    else if (radeon_output->type == OUTPUT_DP)
-			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
-		}
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
 	    case ENCODER_OBJECT_ID_INTERNAL_DDI:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
 		crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device);
-		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
@@ -931,43 +959,24 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 		    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
 		else
 		    crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device);
-		if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
-		else {
-		    if (OUTPUT_IS_DVI)
-			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
-		    else if (radeon_output->type == OUTPUT_HDMI)
-			crtc_src_param2.ucEncodeMode =
-			    atombios_maybe_hdmi_mode(output);
-		    else if (radeon_output->type == OUTPUT_DP)
-			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
-		}
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
-		} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
+		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
-		} else {
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+		else
 		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
-		}
 		break;
 	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
 	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
-		} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
+		else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
-		} else {
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+		else
 		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
-		}
 		break;
 	    }
 	    data.exec.pspace = &crtc_src_param2;
commit 9e283fa9de34407fa6f0d5a8006a611b104f4bf2
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 03:16:20 2009 -0500

    Fixup encoder setup on pre-ATOM chips

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index b704587..c9fff8c 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2055,6 +2055,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
     case ATOM_DEVICE_CRT2_SUPPORT:
     case ATOM_DEVICE_CV_SUPPORT:
 	switch (dac) {
+	    // primary dac
 	case 1:
 	    if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
 		(info->ChipFamily == CHIP_FAMILY_RS400) ||
@@ -2065,6 +2066,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    else
 		ret = ENCODER_OBJECT_ID_INTERNAL_DAC1;
 	    break;
+	    // secondary dac
 	case 2:
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
@@ -2075,6 +2077,7 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 		    ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
 	    }
 	    break;
+	    // external dac
 	case 3:
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 13e87e8..7f17918 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -572,7 +572,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
 											ATOM_DEVICE_CRT2_SUPPORT,
-											0),
+											2),
 					    ATOM_DEVICE_CRT2_SUPPORT))
 			return FALSE;
 		} else {
@@ -582,7 +582,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
 											ATOM_DEVICE_CRT1_SUPPORT,
-											0),
+											1),
 					    ATOM_DEVICE_CRT1_SUPPORT))
 			return FALSE;
 		}
@@ -596,7 +596,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
 											ATOM_DEVICE_CRT2_SUPPORT,
-											0),
+											2),
 					    ATOM_DEVICE_CRT2_SUPPORT))
 			return FALSE;
 		} else {
@@ -606,7 +606,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    if (!radeon_add_encoder(pScrn,
 					    radeon_get_encoder_id_from_supported_device(pScrn,
 											ATOM_DEVICE_CRT1_SUPPORT,
-											0),
+											1),
 					    ATOM_DEVICE_CRT1_SUPPORT))
 			return FALSE;
 		}
@@ -659,9 +659,9 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
 					radeon_get_encoder_id_from_supported_device(pScrn,
-										    ATOM_DEVICE_CRT2_SUPPORT,
-										    0),
-					ATOM_DEVICE_CRT2_SUPPORT))
+										    ATOM_DEVICE_TV1_SUPPORT,
+										    2),
+					ATOM_DEVICE_TV1_SUPPORT))
 		    return FALSE;
 		break;
 	    case CONNECTOR_STV_LEGACY:
@@ -671,9 +671,9 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
 					radeon_get_encoder_id_from_supported_device(pScrn,
-										    ATOM_DEVICE_CRT2_SUPPORT,
-										    0),
-					ATOM_DEVICE_CRT2_SUPPORT))
+										    ATOM_DEVICE_TV1_SUPPORT,
+										    2),
+					ATOM_DEVICE_TV1_SUPPORT))
 		    return FALSE;
 		break;
 	    default:
@@ -733,7 +733,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    if (!radeon_add_encoder(pScrn,
 				    radeon_get_encoder_id_from_supported_device(pScrn,
 										ATOM_DEVICE_CRT1_SUPPORT,
-										0),
+										1),
 				    ATOM_DEVICE_CRT1_SUPPORT))
 		return FALSE;
 	} else
@@ -829,9 +829,9 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT;
 		if (!radeon_add_encoder(pScrn,
 					radeon_get_encoder_id_from_supported_device(pScrn,
-										    ATOM_DEVICE_CRT2_SUPPORT,
-										    0),
-					ATOM_DEVICE_CRT2_SUPPORT))
+										    ATOM_DEVICE_TV1_SUPPORT,
+										    2),
+					ATOM_DEVICE_TV1_SUPPORT))
 		    return FALSE;
 	    }
 	}
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 89a0974..13243d6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2278,6 +2278,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_LCD1_SUPPORT,
+									    0),
+				ATOM_DEVICE_LCD1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
@@ -2285,6 +2292,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT2_SUPPORT,
+									    2),
+				ATOM_DEVICE_CRT2_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2292,6 +2306,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_EXTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
@@ -2299,12 +2320,32 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_LCD1_SUPPORT,
+									    0),
+				ATOM_DEVICE_LCD1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_EXT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_DFP2_SUPPORT,
+									    0),
+				ATOM_DEVICE_DFP2_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2312,20 +2353,46 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
-
     case RADEON_MAC_POWERBOOK_INTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_LCD1_SUPPORT,
+									    0),
+				ATOM_DEVICE_LCD1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_DFP1_SUPPORT,
+									    0),
+				ATOM_DEVICE_DFP1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2333,6 +2400,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_VGA:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
@@ -2340,12 +2414,26 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_LCD1_SUPPORT,
+									    0),
+				ATOM_DEVICE_LCD1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2353,6 +2441,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_MINI_EXTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
@@ -2361,6 +2456,19 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_EXT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_DFP2_SUPPORT,
+									    0),
+				ATOM_DEVICE_DFP2_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
@@ -2368,6 +2476,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_MINI_INTERNAL:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
@@ -2376,6 +2491,19 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_DFP1_SUPPORT,
+									    0),
+				ATOM_DEVICE_DFP1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
@@ -2383,6 +2511,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_IMAC_G5_ISIGHT:
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
@@ -2390,6 +2525,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_DFP1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_DFP1_SUPPORT,
+									    0),
+				ATOM_DEVICE_DFP1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
@@ -2397,6 +2539,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT2_SUPPORT,
+									    2),
+				ATOM_DEVICE_CRT2_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2404,6 +2553,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     case RADEON_MAC_EMAC:
 	/* eMac G4 800/1.0 with radeon 7500, no EDID on internal monitor
@@ -2415,6 +2571,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT1_SUPPORT,
+									    1),
+				ATOM_DEVICE_CRT1_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
@@ -2422,6 +2585,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[1].valid = TRUE;
+	info->BiosConnector[1].devices = ATOM_DEVICE_CRT2_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_CRT2_SUPPORT,
+									    2),
+				ATOM_DEVICE_CRT2_SUPPORT))
+	    return FALSE;
 
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
@@ -2429,6 +2599,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	if (!radeon_add_encoder(pScrn,
+				radeon_get_encoder_id_from_supported_device(pScrn,
+									    ATOM_DEVICE_TV1_SUPPORT,
+									    2),
+				ATOM_DEVICE_TV1_SUPPORT))
+	    return FALSE;
 	return TRUE;
     default:
 	return FALSE;
@@ -2443,152 +2620,192 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
 
+    if (IS_AVIVO_VARIANT)
+	return;
+
     if (!pRADEONEnt->HasCRTC2) {
 	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[0].DACType = DAC_PRIMARY;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	radeon_add_encoder(pScrn,
+			   radeon_get_encoder_id_from_supported_device(pScrn,
+								       ATOM_DEVICE_CRT1_SUPPORT,
+								       1),
+			   ATOM_DEVICE_CRT1_SUPPORT);
 	return;
     }
 
-    if (IS_AVIVO_VARIANT) {
-	if (info->IsMobility) {
-	    info->BiosConnector[0].ddc_i2c = atom_setup_i2c_bus(0x7e60);
+    if (info->IsMobility) {
+	/* Below is the most common setting, but may not be true */
+	if (info->IsIGP) {
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
 	    info->BiosConnector[0].DACType = DAC_NONE;
 	    info->BiosConnector[0].TMDSType = TMDS_NONE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
+	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_LCD1_SUPPORT,
+									   0),
+			       ATOM_DEVICE_LCD1_SUPPORT);
+
+	    /* IGP only has TVDAC */
+	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+		(info->ChipFamily == CHIP_FAMILY_RS480))
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+	    else
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	    info->BiosConnector[1].DACType = DAC_TVDAC;
+	    info->BiosConnector[1].load_detection = FALSE;
+	    info->BiosConnector[1].TMDSType = TMDS_NONE;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+	    info->BiosConnector[1].valid = TRUE;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT1_SUPPORT,
+									   2),
+			       ATOM_DEVICE_CRT1_SUPPORT);
+	} else {
+#if defined(__powerpc__)
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+#else
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+#endif
+	    info->BiosConnector[0].DACType = DAC_NONE;
+	    info->BiosConnector[0].TMDSType = TMDS_NONE;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[0].valid = TRUE;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_LCD1_SUPPORT,
+									   0),
+			       ATOM_DEVICE_LCD1_SUPPORT);
 
-	    info->BiosConnector[1].ddc_i2c = atom_setup_i2c_bus(0x7e40);
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
+	    info->BiosConnector[1].valid = TRUE;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT1_SUPPORT,
+									   1),
+			       ATOM_DEVICE_CRT1_SUPPORT);
+	}
+    } else {
+	/* Below is the most common setting, but may not be true */
+	if (info->IsIGP) {
+	    if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+		(info->ChipFamily == CHIP_FAMILY_RS480))
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
+	    else
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	    info->BiosConnector[0].DACType = DAC_TVDAC;
+	    info->BiosConnector[0].load_detection = FALSE;
+	    info->BiosConnector[0].TMDSType = TMDS_NONE;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
+	    info->BiosConnector[0].valid = TRUE;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT1_SUPPORT,
+									   1),
+			       ATOM_DEVICE_CRT1_SUPPORT);
+
+	    /* not sure what a good default DDCType for DVI on
+	     * IGP desktop chips is
+	     */
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
+	    info->BiosConnector[1].DACType = DAC_NONE;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
 	    info->BiosConnector[1].valid = TRUE;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_DFP1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_DFP1_SUPPORT,
+									   0),
+			       ATOM_DEVICE_DFP1_SUPPORT);
 	} else {
-	    info->BiosConnector[0].ddc_i2c = atom_setup_i2c_bus(0x7e50);
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	    info->BiosConnector[0].DACType = DAC_TVDAC;
+	    info->BiosConnector[0].load_detection = FALSE;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
-	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
 	    info->BiosConnector[0].valid = TRUE;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT2_SUPPORT,
+									   2),
+			       ATOM_DEVICE_CRT2_SUPPORT);
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_DFP1_SUPPORT,
+									   0),
+			       ATOM_DEVICE_DFP1_SUPPORT);
 
-	    info->BiosConnector[1].ddc_i2c = atom_setup_i2c_bus(0x7e40);
+#if defined(__powerpc__)
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	    info->BiosConnector[1].DACType = DAC_PRIMARY;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
+	    info->BiosConnector[1].valid = TRUE;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP2_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT1_SUPPORT,
+									   1),
+			       ATOM_DEVICE_CRT1_SUPPORT);
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_DFP2_SUPPORT,
+									   0),
+			       ATOM_DEVICE_DFP2_SUPPORT);
+#else
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
-	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
 	    info->BiosConnector[1].valid = TRUE;
+	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_CRT1_SUPPORT,
+									   1),
+			       ATOM_DEVICE_CRT1_SUPPORT);
+#endif
 	}
+    }
 
+    if (info->InternalTVOut) {
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
+	info->BiosConnector[2].load_detection = FALSE;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
 	info->BiosConnector[2].ddc_i2c.valid = FALSE;
-	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
 	info->BiosConnector[2].valid = TRUE;
-    } else {
-	if (info->IsMobility) {
-	    /* Below is the most common setting, but may not be true */
-	    if (info->IsIGP) {
-		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
-		info->BiosConnector[0].DACType = DAC_NONE;
-		info->BiosConnector[0].TMDSType = TMDS_NONE;
-		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
-		info->BiosConnector[0].valid = TRUE;
-
-		/* IGP only has TVDAC */
-		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
-		    (info->ChipFamily == CHIP_FAMILY_RS480))
-		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-		else
-		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-		info->BiosConnector[1].DACType = DAC_TVDAC;
-		info->BiosConnector[1].load_detection = FALSE;
-		info->BiosConnector[1].TMDSType = TMDS_NONE;
-		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
-		info->BiosConnector[1].valid = TRUE;
-	    } else {
-#if defined(__powerpc__)
-		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-#else
-		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
-#endif
-		info->BiosConnector[0].DACType = DAC_NONE;
-		info->BiosConnector[0].TMDSType = TMDS_NONE;
-		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
-		info->BiosConnector[0].valid = TRUE;
-
-		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-		info->BiosConnector[1].DACType = DAC_PRIMARY;
-		info->BiosConnector[1].TMDSType = TMDS_NONE;
-		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
-		info->BiosConnector[1].valid = TRUE;
-	    }
-	} else {
-	    /* Below is the most common setting, but may not be true */
-	    if (info->IsIGP) {
-		if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
-		    (info->ChipFamily == CHIP_FAMILY_RS480))
-		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
-		else
-		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-		info->BiosConnector[0].DACType = DAC_TVDAC;
-		info->BiosConnector[0].load_detection = FALSE;
-		info->BiosConnector[0].TMDSType = TMDS_NONE;
-		info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
-		info->BiosConnector[0].valid = TRUE;
-
-		/* not sure what a good default DDCType for DVI on
-		 * IGP desktop chips is
-		 */
-		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
-		info->BiosConnector[1].DACType = DAC_NONE;
-		info->BiosConnector[1].TMDSType = TMDS_EXT;
-		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
-		info->BiosConnector[1].valid = TRUE;
-	    } else {
-		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-		info->BiosConnector[0].DACType = DAC_TVDAC;
-		info->BiosConnector[0].load_detection = FALSE;
-		info->BiosConnector[0].TMDSType = TMDS_INT;
-		info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
-		info->BiosConnector[0].valid = TRUE;
-
-#if defined(__powerpc__)
-		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-		info->BiosConnector[1].DACType = DAC_PRIMARY;
-		info->BiosConnector[1].TMDSType = TMDS_EXT;
-		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
-		info->BiosConnector[1].valid = TRUE;
-#else
-		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-		info->BiosConnector[1].DACType = DAC_PRIMARY;
-		info->BiosConnector[1].TMDSType = TMDS_EXT;
-		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
-		info->BiosConnector[1].valid = TRUE;
-#endif
-	    }
-	}
-
-	if (info->InternalTVOut) {
-	    info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	    info->BiosConnector[2].DACType = DAC_TVDAC;
-	    info->BiosConnector[2].load_detection = FALSE;
-	    info->BiosConnector[2].TMDSType = TMDS_NONE;
-	    info->BiosConnector[2].ddc_i2c.valid = FALSE;
-	    info->BiosConnector[2].valid = TRUE;
-	}
+	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
+	radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn,
+									   ATOM_DEVICE_TV1_SUPPORT,
+									   2),
+			       ATOM_DEVICE_TV1_SUPPORT);
+    }
 
-	/* Some cards have the DDC lines swapped and we have no way to
-	 * detect it yet (Mac cards)
-	 */
-	if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
-	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
-	}
+    /* Some cards have the DDC lines swapped and we have no way to
+     * detect it yet (Mac cards)
+     */
+    if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
     }
 }
 
@@ -2772,7 +2989,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[i].ddc_i2c.valid = FALSE;
 	info->BiosConnector[i].DACType = DAC_NONE;
 	info->BiosConnector[i].TMDSType = TMDS_NONE;
+	info->BiosConnector[i].LVDSType = LVDS_NONE;
 	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
+	info->BiosConnector[i].devices = 0;
     }
 
 #if defined(__powerpc__)
commit 5850abbdcd22b70bdbccd3642f8ba1a27e38e7cd
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Jan 21 02:28:47 2009 -0500

    clean up encoder setup
    
    - make sure not to duplicate encoders
    - use single encoder array

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 9b79d66..b704587 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1588,30 +1588,40 @@ radeon_encoder_ptr
 radeon_get_encoder(xf86OutputPtr output)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info = RADEONPTR(output->scrn);
 
-    return radeon_output->encoders[radeon_get_device_index(radeon_output->active_device)];
+    return info->encoders[radeon_get_device_index(radeon_output->active_device)];
 
 }
 
-radeon_encoder_ptr
+Bool
 radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     uint32_t device_index = radeon_get_device_index(device_support);
+    int i;
 
     if (device_support == 0)
-	return NULL;
+	return FALSE;
 
     if (info->encoders[device_index] != NULL)
-	return info->encoders[device_index];
+	return TRUE;
     else {
+	/* look for the encoder */
+	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	    if ((info->encoders[i] != NULL) && (info->encoders[i]->encoder_id == encoder_id)) {
+		info->encoders[device_index] = info->encoders[i];
+		return TRUE;
+	    }
+	}
+
 	info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec));
 	if (info->encoders[device_index] != NULL) {
 	    info->encoders[device_index]->encoder_id = encoder_id;
 	    // add dev_priv stuff
-	    return info->encoders[device_index];
+	    return TRUE;
 	} else
-	    return NULL;
+	    return FALSE;
     }
 
 }
@@ -1626,7 +1636,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
     ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
     ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL;
-    int i, j, k, path_size, device_support;
+    int i, j, path_size, device_support;
     Bool enable_tv = FALSE;
 
     if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE))
@@ -1713,8 +1723,8 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		    else
 			info->BiosConnector[i].linkb = FALSE;
 
-		    info->BiosConnector[i].encoders[radeon_get_device_index(path->usDeviceTag)] =
-			radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag);
+		    if (!radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag))
+			return FALSE;
 
 		    switch(enc_obj_id) {
 		    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
@@ -1811,10 +1821,6 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 			else
 			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
 			info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
-			for (k = 0; k < ATOM_MAX_SUPPORTED_DEVICE; k++) {
-			    if (info->BiosConnector[j].encoders[k])
-				info->BiosConnector[i].encoders[k] = info->BiosConnector[j].encoders[k];
-			}
 			info->BiosConnector[j].valid = FALSE;
 		    }
 		}
@@ -2186,11 +2192,11 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	    info->BiosConnector[i].ddc_i2c =
 		RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
 
-	info->BiosConnector[i].encoders[radeon_get_device_index((1 << i))] =
-	    radeon_add_encoder(pScrn,
-			       radeon_get_encoder_id_from_supported_device(pScrn, (1 << i),
-					     ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC),
-			       (i << 1));
+	if (!radeon_add_encoder(pScrn,
+			   radeon_get_encoder_id_from_supported_device(pScrn, (1 << i),
+					  ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC),
+				(i << 1)))
+	    return FALSE;
 
 	if (i == ATOM_DEVICE_DFP1_INDEX)
 	    info->BiosConnector[i].TMDSType = TMDS_INT;
@@ -2260,7 +2266,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 			    ((j == ATOM_DEVICE_CRT1_INDEX) || (j == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
 			    info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
-			    info->BiosConnector[i].encoders[j] = info->BiosConnector[j].encoders[j];
 			    info->BiosConnector[j].valid = FALSE;
 			} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
 			     (j == ATOM_DEVICE_DFP2_INDEX) ||
@@ -2268,7 +2273,6 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 			    ((i == ATOM_DEVICE_CRT1_INDEX) || (i == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[j].DACType = info->BiosConnector[i].DACType;
 			    info->BiosConnector[j].devices |= info->BiosConnector[i].devices;
-			    info->BiosConnector[i].encoders[j] = info->BiosConnector[j].encoders[j];
 			    info->BiosConnector[i].valid = FALSE;
 			} else {
 			    info->BiosConnector[i].shared_ddc = TRUE;
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index cfd858f..13e87e8 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -546,21 +546,21 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		if ((tmp >> 4) & 0x1) {
 		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP2_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP2_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+				       radeon_get_encoder_id_from_supported_device(pScrn,
+										   ATOM_DEVICE_DFP2_SUPPORT,
+										   0),
+					    ATOM_DEVICE_DFP2_SUPPORT))
+			return FALSE;
 		} else {
 		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP1_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP1_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_DFP1_SUPPORT,
+											0),
+					    ATOM_DEVICE_DFP1_SUPPORT))
+			return FALSE;
 		}
 		break;
 	    case CONNECTOR_CRT_LEGACY:
@@ -569,22 +569,22 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    info->BiosConnector[i].DACType = DAC_TVDAC;
 		    info->BiosConnector[i].load_detection = FALSE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_CRT2_SUPPORT,
-										       0),
-					   ATOM_DEVICE_CRT2_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_CRT2_SUPPORT,
+											0),
+					    ATOM_DEVICE_CRT2_SUPPORT))
+			return FALSE;
 		} else {
 		    info->BiosConnector[i].DACType = DAC_PRIMARY;
 		    info->BiosConnector[i].load_detection = TRUE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT1_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_CRT1_SUPPORT,
-										       0),
-					   ATOM_DEVICE_CRT1_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_CRT1_SUPPORT,
+											0),
+					    ATOM_DEVICE_CRT1_SUPPORT))
+			return FALSE;
 		}
 		break;
 	    case CONNECTOR_DVI_I_LEGACY:
@@ -593,41 +593,41 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    info->BiosConnector[i].DACType = DAC_TVDAC;
 		    info->BiosConnector[i].load_detection = FALSE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_CRT2_SUPPORT,
-										       0),
-					   ATOM_DEVICE_CRT2_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_CRT2_SUPPORT,
+											0),
+					    ATOM_DEVICE_CRT2_SUPPORT))
+			return FALSE;
 		} else {
 		    info->BiosConnector[i].DACType = DAC_PRIMARY;
 		    info->BiosConnector[i].load_detection = TRUE;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT1_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_CRT1_SUPPORT,
-										       0),
-					   ATOM_DEVICE_CRT1_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_CRT1_SUPPORT,
+											0),
+					    ATOM_DEVICE_CRT1_SUPPORT))
+			return FALSE;
 		}
 		if ((tmp >> 4) & 0x1) {
 		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP2_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP2_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_DFP2_SUPPORT,
+											0),
+					    ATOM_DEVICE_DFP2_SUPPORT))
+			return FALSE;
 		} else {
 		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP1_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP1_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_DFP1_SUPPORT,
+											0),
+					    ATOM_DEVICE_DFP1_SUPPORT))
+			return FALSE;
 		}
 		break;
 	    case CONNECTOR_DVI_D_LEGACY:
@@ -635,21 +635,21 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		if ((tmp >> 4) & 0x1) {
 		    info->BiosConnector[i].TMDSType = TMDS_EXT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP2_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP2_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_DFP2_SUPPORT,
+											0),
+					    ATOM_DEVICE_DFP2_SUPPORT))
+			return FALSE;
 		} else {
 		    info->BiosConnector[i].TMDSType = TMDS_INT;
 		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
-		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
-			radeon_add_encoder(pScrn,
-					   radeon_get_encoder_id_from_supported_device(pScrn,
-										       ATOM_DEVICE_DFP1_SUPPORT,
-										       0),
-					   ATOM_DEVICE_DFP1_SUPPORT);
+		    if (!radeon_add_encoder(pScrn,
+					    radeon_get_encoder_id_from_supported_device(pScrn,
+											ATOM_DEVICE_DFP1_SUPPORT,
+											0),
+					    ATOM_DEVICE_DFP1_SUPPORT))
+			return FALSE;
 		}
 		break;
 	    case CONNECTOR_CTV_LEGACY:
@@ -657,24 +657,24 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[i].DACType = DAC_TVDAC;
 		info->BiosConnector[i].load_detection = FALSE;
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
-		info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
-		    radeon_add_encoder(pScrn,
-				       radeon_get_encoder_id_from_supported_device(pScrn,
-										   ATOM_DEVICE_CRT2_SUPPORT,
-										   0),
-				       ATOM_DEVICE_CRT2_SUPPORT);
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_CRT2_SUPPORT,
+										    0),
+					ATOM_DEVICE_CRT2_SUPPORT))
+		    return FALSE;
 		break;
 	    case CONNECTOR_STV_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_STV;
 		info->BiosConnector[i].DACType = DAC_TVDAC;
 		info->BiosConnector[i].load_detection = FALSE;
 		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
-		info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
-		    radeon_add_encoder(pScrn,
-				       radeon_get_encoder_id_from_supported_device(pScrn,
-										   ATOM_DEVICE_CRT2_SUPPORT,
-										   0),
-				       ATOM_DEVICE_CRT2_SUPPORT);
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_CRT2_SUPPORT,
+										    0),
+					ATOM_DEVICE_CRT2_SUPPORT))
+		    return FALSE;
 		break;
 	    default:
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Connector Type: %d\n", ConnectorType);
@@ -724,18 +724,18 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_INDEX;
-	    info->BiosConnector[0].encoders[ATOM_DEVICE_DFP1_INDEX] =
-		radeon_add_encoder(pScrn,
-				   radeon_get_encoder_id_from_supported_device(pScrn,
-									       ATOM_DEVICE_DFP1_SUPPORT,
-									       0),
-				   ATOM_DEVICE_DFP1_SUPPORT);
-	    info->BiosConnector[0].encoders[ATOM_DEVICE_CRT1_INDEX] =
-		radeon_add_encoder(pScrn,
-				   radeon_get_encoder_id_from_supported_device(pScrn,
-									       ATOM_DEVICE_CRT1_SUPPORT,
-									       0),
-				   ATOM_DEVICE_CRT1_SUPPORT);
+	    if (!radeon_add_encoder(pScrn,
+				    radeon_get_encoder_id_from_supported_device(pScrn,
+										ATOM_DEVICE_DFP1_SUPPORT,
+										0),
+				    ATOM_DEVICE_DFP1_SUPPORT))
+		return FALSE;
+	    if (!radeon_add_encoder(pScrn,
+				    radeon_get_encoder_id_from_supported_device(pScrn,
+										ATOM_DEVICE_CRT1_SUPPORT,
+										0),
+				    ATOM_DEVICE_CRT1_SUPPORT))
+		return FALSE;
 	} else
 	    return FALSE;
     }
@@ -753,12 +753,12 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
 	    info->BiosConnector[4].devices = ATOM_DEVICE_LCD1_SUPPORT;
-	    info->BiosConnector[4].encoders[ATOM_DEVICE_LCD1_INDEX] =
-		radeon_add_encoder(pScrn,
-				   radeon_get_encoder_id_from_supported_device(pScrn,
-									       ATOM_DEVICE_LCD1_SUPPORT,
-									       0),
-				   ATOM_DEVICE_LCD1_SUPPORT);
+	    if (!radeon_add_encoder(pScrn,
+				    radeon_get_encoder_id_from_supported_device(pScrn,
+										ATOM_DEVICE_LCD1_SUPPORT,
+										0),
+				    ATOM_DEVICE_LCD1_SUPPORT))
+		return FALSE;
 
 	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	    if (tmp) {
@@ -827,12 +827,12 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].TMDSType = TMDS_NONE;
 		info->BiosConnector[5].ddc_i2c.valid = FALSE;
 		info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT;
-		info->BiosConnector[5].encoders[ATOM_DEVICE_CRT2_INDEX] =
-		    radeon_add_encoder(pScrn,
-				       radeon_get_encoder_id_from_supported_device(pScrn,
-										   ATOM_DEVICE_CRT2_SUPPORT,
-										   0),
-				       ATOM_DEVICE_CRT2_SUPPORT);
+		if (!radeon_add_encoder(pScrn,
+					radeon_get_encoder_id_from_supported_device(pScrn,
+										    ATOM_DEVICE_CRT2_SUPPORT,
+										    0),
+					ATOM_DEVICE_CRT2_SUPPORT))
+		    return FALSE;
 	    }
 	}
     }
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2ac577c..89a0974 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2755,7 +2755,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     xf86OutputPtr output;
     char *optstr;
-    int i, j;
+    int i;
     int num_vga = 0;
     int num_dvi = 0;
     int num_hdmi = 0;
@@ -2766,8 +2766,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
      */
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	info->encoders[i] = NULL;
-	for (j = 0; j < RADEON_MAX_BIOS_CONNECTOR; j++)
-	    info->BiosConnector[i].encoders[j] = NULL;
 	info->BiosConnector[i].valid = FALSE;
 	info->BiosConnector[i].load_detection = TRUE;
 	info->BiosConnector[i].shared_ddc = FALSE;
@@ -2905,8 +2903,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->load_detection = info->BiosConnector[i].load_detection;
 	    radeon_output->linkb = info->BiosConnector[i].linkb;
 	    radeon_output->connector_id = info->BiosConnector[i].connector_object;
-	    for (j = 0; j < RADEON_MAX_BIOS_CONNECTOR; j++)
-		radeon_output->encoders[j] = info->BiosConnector[i].encoders[j];
 
 	    radeon_output->LVDSType = info->BiosConnector[i].LVDSType;
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 36f6483..f72faf9 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -231,7 +231,6 @@ typedef struct {
     Bool load_detection;
     Bool linkb;
     uint16_t connector_object;
-    radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -296,7 +295,6 @@ typedef struct _RADEONOutputPrivateRec {
     uint16_t connector_id;
     uint32_t devices;
     uint32_t active_device;
-    radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
     //RADEONConnectorType connector_type;
     RADEONConnectorType ConnectorType;
     // DDC info
commit 152d1d4c179c262be4d0a5618400aa13b4820342
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 20 00:58:18 2009 -0500

    First pass at converting legacy code to encoder objects

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index e136180..9b79d66 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2050,7 +2050,11 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
     case ATOM_DEVICE_CV_SUPPORT:
 	switch (dac) {
 	case 1:
-	    if (IS_AVIVO_VARIANT)
+	    if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
+		(info->ChipFamily == CHIP_FAMILY_RS400) ||
+		(info->ChipFamily == CHIP_FAMILY_RS480))
+		ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
+	    else if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
 	    else
 		ret = ENCODER_OBJECT_ID_INTERNAL_DAC1;
@@ -2058,8 +2062,12 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	case 2:
 	    if (IS_AVIVO_VARIANT)
 		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
-	    else
-		ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
+	    else {
+		if (info->ChipFamily == CHIP_FAMILY_R200)
+		    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
+		else
+		    ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
+	    }
 	    break;
 	case 3:
 	    if (IS_AVIVO_VARIANT)
@@ -2076,7 +2084,11 @@ radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supporte
 	    ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
 	break;
     case ATOM_DEVICE_DFP1_SUPPORT:
-	if (IS_AVIVO_VARIANT)
+	if ((info->ChipFamily == CHIP_FAMILY_RS300) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS400) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS480))
+	    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
+	else if (IS_AVIVO_VARIANT)
 	    ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
 	else
 	    ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1;
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index badcb01..cfd858f 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -543,21 +543,138 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    switch (ConnectorType) {
 	    case CONNECTOR_PROPRIETARY_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
+		if ((tmp >> 4) & 0x1) {
+		    info->BiosConnector[i].TMDSType = TMDS_EXT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP2_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP2_SUPPORT);
+		} else {
+		    info->BiosConnector[i].TMDSType = TMDS_INT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP1_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP1_SUPPORT);
+		}
 		break;
 	    case CONNECTOR_CRT_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_VGA;
+		if (tmp & 0x1) {
+		    info->BiosConnector[i].DACType = DAC_TVDAC;
+		    info->BiosConnector[i].load_detection = FALSE;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_CRT2_SUPPORT,
+										       0),
+					   ATOM_DEVICE_CRT2_SUPPORT);
+		} else {
+		    info->BiosConnector[i].DACType = DAC_PRIMARY;
+		    info->BiosConnector[i].load_detection = TRUE;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT1_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_CRT1_SUPPORT,
+										       0),
+					   ATOM_DEVICE_CRT1_SUPPORT);
+		}
 		break;
 	    case CONNECTOR_DVI_I_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_I;
+		if (tmp & 0x1) {
+		    info->BiosConnector[i].DACType = DAC_TVDAC;
+		    info->BiosConnector[i].load_detection = FALSE;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT2_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_CRT2_SUPPORT,
+										       0),
+					   ATOM_DEVICE_CRT2_SUPPORT);
+		} else {
+		    info->BiosConnector[i].DACType = DAC_PRIMARY;
+		    info->BiosConnector[i].load_detection = TRUE;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_CRT1_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_CRT1_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_CRT1_SUPPORT,
+										       0),
+					   ATOM_DEVICE_CRT1_SUPPORT);
+		}
+		if ((tmp >> 4) & 0x1) {
+		    info->BiosConnector[i].TMDSType = TMDS_EXT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP2_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP2_SUPPORT);
+		} else {
+		    info->BiosConnector[i].TMDSType = TMDS_INT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP1_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP1_SUPPORT);
+		}
 		break;
 	    case CONNECTOR_DVI_D_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_DVI_D;
+		if ((tmp >> 4) & 0x1) {
+		    info->BiosConnector[i].TMDSType = TMDS_EXT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP2_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP2_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP2_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP2_SUPPORT);
+		} else {
+		    info->BiosConnector[i].TMDSType = TMDS_INT;
+		    info->BiosConnector[i].devices |= ATOM_DEVICE_DFP1_SUPPORT;
+		    info->BiosConnector[i].encoders[ATOM_DEVICE_DFP1_INDEX] =
+			radeon_add_encoder(pScrn,
+					   radeon_get_encoder_id_from_supported_device(pScrn,
+										       ATOM_DEVICE_DFP1_SUPPORT,
+										       0),
+					   ATOM_DEVICE_DFP1_SUPPORT);
+		}
 		break;
 	    case CONNECTOR_CTV_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_CTV;
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+		info->BiosConnector[i].load_detection = FALSE;
+		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
+		info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
+		    radeon_add_encoder(pScrn,
+				       radeon_get_encoder_id_from_supported_device(pScrn,
+										   ATOM_DEVICE_CRT2_SUPPORT,
+										   0),
+				       ATOM_DEVICE_CRT2_SUPPORT);
 		break;
 	    case CONNECTOR_STV_LEGACY:
 		info->BiosConnector[i].ConnectorType = CONNECTOR_STV;
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+		info->BiosConnector[i].load_detection = FALSE;
+		info->BiosConnector[i].devices = ATOM_DEVICE_TV1_SUPPORT;
+		info->BiosConnector[i].encoders[ATOM_DEVICE_CRT2_INDEX] =
+		    radeon_add_encoder(pScrn,
+				       radeon_get_encoder_id_from_supported_device(pScrn,
+										   ATOM_DEVICE_CRT2_SUPPORT,
+										   0),
+				       ATOM_DEVICE_CRT2_SUPPORT);
 		break;
 	    default:
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown Connector Type: %d\n", ConnectorType);
@@ -586,21 +703,6 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		break;
 	    }
 
-	    if (tmp & 0x1)
-		info->BiosConnector[i].DACType = DAC_TVDAC;
-	    else
-		info->BiosConnector[i].DACType = DAC_PRIMARY;
-
-	    if ((tmp >> 4) & 0x1)
-		info->BiosConnector[i].TMDSType = TMDS_EXT;
-	    else
-		info->BiosConnector[i].TMDSType = TMDS_INT;
-
-	    if (info->BiosConnector[i].DACType == DAC_TVDAC)
-		info->BiosConnector[i].load_detection = FALSE;
-	    else
-		info->BiosConnector[i].load_detection = TRUE;
-
 	    RADEONApplyLegacyQuirks(pScrn, i);
 
 	}
@@ -617,8 +719,23 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[0].valid = TRUE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[0].DACType = DAC_PRIMARY;
+	    info->BiosConnector[0].load_detection = TRUE;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
+	    info->BiosConnector[0].TMDSType = TMDS_INT;
+	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT1_SUPPORT | ATOM_DEVICE_DFP1_INDEX;
+	    info->BiosConnector[0].encoders[ATOM_DEVICE_DFP1_INDEX] =
+		radeon_add_encoder(pScrn,
+				   radeon_get_encoder_id_from_supported_device(pScrn,
+									       ATOM_DEVICE_DFP1_SUPPORT,
+									       0),
+				   ATOM_DEVICE_DFP1_SUPPORT);
+	    info->BiosConnector[0].encoders[ATOM_DEVICE_CRT1_INDEX] =
+		radeon_add_encoder(pScrn,
+				   radeon_get_encoder_id_from_supported_device(pScrn,
+									       ATOM_DEVICE_CRT1_SUPPORT,
+									       0),
+				   ATOM_DEVICE_CRT1_SUPPORT);
 	} else
 	    return FALSE;
     }
@@ -635,6 +752,14 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[4].LVDSType = LVDS_INT;
 	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
+	    info->BiosConnector[4].devices = ATOM_DEVICE_LCD1_SUPPORT;
+	    info->BiosConnector[4].encoders[ATOM_DEVICE_LCD1_INDEX] =
+		radeon_add_encoder(pScrn,
+				   radeon_get_encoder_id_from_supported_device(pScrn,
+									       ATOM_DEVICE_LCD1_SUPPORT,
+									       0),
+				   ATOM_DEVICE_LCD1_SUPPORT);
+
 	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	    if (tmp) {
 		tmp0 = RADEON_BIOS16(tmp + 0x15);
@@ -701,6 +826,13 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].load_detection = FALSE;
 		info->BiosConnector[5].TMDSType = TMDS_NONE;
 		info->BiosConnector[5].ddc_i2c.valid = FALSE;
+		info->BiosConnector[5].devices = ATOM_DEVICE_TV1_SUPPORT;
+		info->BiosConnector[5].encoders[ATOM_DEVICE_CRT2_INDEX] =
+		    radeon_add_encoder(pScrn,
+				       radeon_get_encoder_id_from_supported_device(pScrn,
+										   ATOM_DEVICE_CRT2_SUPPORT,
+										   0),
+				       ATOM_DEVICE_CRT2_SUPPORT);
 	    }
 	}
     }
commit 7cc7ba8bf9ce2f0eebfd9b48aa648c416c333ff4
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 19 18:42:12 2009 -0500

    ATOM: round 1 of output rework

diff --git a/src/atombios_output.c b/src/atombios_output.c
index efe487b..4f5c499 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -50,25 +50,35 @@ atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
     int index;
 
+    if (radeon_encoder == NULL)
+	return ATOM_NOT_IMPLEMENTED;
+
     memset(&disp_data,0, sizeof(disp_data));
 
-    if (radeon_output->DACType == DAC_PRIMARY)
+    switch (radeon_encoder->encoder_id) {
+    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
 	index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-    else
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
 	index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
+	break;
+    }
 
     disp_data.ucAction = ATOM_ENABLE;
 
-    if (radeon_output->MonType == MT_CRT)
+    if (radeon_output->active_device && (ATOM_DEVICE_CRT_SUPPORT))
 	disp_data.ucDacStandard = ATOM_DAC1_PS2;
-    else if (radeon_output->MonType == MT_CV)
+    else if (radeon_output->active_device && (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.ucDacStandard = ATOM_DAC1_CV;
-    else if (OUTPUT_IS_TV) {
+    else {
 	switch (radeon_output->tvStd) {
 	case TV_STD_PAL:
 	case TV_STD_PAL_M:
@@ -114,7 +124,7 @@ atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode)
 
     disp_data.sTVEncoder.ucAction = ATOM_ENABLE;
 
-    if (radeon_output->MonType == MT_CV)
+    if (radeon_output->active_device && (ATOM_DEVICE_CV_SUPPORT))
 	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
     else {
 	switch (radeon_output->tvStd) {
@@ -230,6 +240,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info       = RADEONPTR(pScrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     LVDS_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     LVDS_ENCODER_CONTROL_PS_ALLOCATION_V2 disp_data2;
     AtomBiosArgRec data;
@@ -237,16 +248,27 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
     int index;
     int major, minor;
 
+    if (radeon_encoder == NULL)
+	return ATOM_NOT_IMPLEMENTED;
+
     memset(&disp_data,0, sizeof(disp_data));
     memset(&disp_data2,0, sizeof(disp_data2));
 
-    if (radeon_output->type == OUTPUT_LVDS)
+    switch (radeon_encoder->encoder_id) {
+    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 	index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
-    else {
-	if (radeon_output->TMDSType == TMDS_LVTMA)
-	    index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
 	else
-	    index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
+	    index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
+	break;
     }
 
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
@@ -263,7 +285,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    if (radeon_output->type == OUTPUT_HDMI)
 		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
-	    if (radeon_output->MonType == MT_LCD) {
+	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 1))
@@ -295,7 +317,7 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    disp_data2.ucSpatial = 0;
 	    disp_data2.ucTemporal = 0;
 	    disp_data2.ucFRC = 0;
-	    if (radeon_output->type == OUTPUT_LVDS) {
+	    if (radeon_output->active_device && (ATOM_DEVICE_LCD_SUPPORT)) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 5)) {
@@ -360,12 +382,16 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
     int index;
     int major, minor;
 
+    if (radeon_encoder == NULL)
+	return ATOM_NOT_IMPLEMENTED;
+
     memset(&disp_data,0, sizeof(disp_data));
 
     if (IS_DCE32_VARIANT) {
@@ -374,13 +400,17 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
 	else
 	    index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
     } else {
-	if (radeon_output->type == OUTPUT_LVDS)
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-	else {
-	    if (radeon_output->TMDSType == TMDS_LVTMA)
-		index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-	    else
-		index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	    break;
 	}
     }
 
@@ -390,29 +420,29 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
 
     if (IS_DCE32_VARIANT) {
-	if (radeon_output->type == OUTPUT_LVDS) {
-	    if (radeon_output->LVDSType == LVDS_UNIPHY)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
-	    else if (radeon_output->LVDSType == LVDS_UNIPHY1)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
-	    else if (radeon_output->LVDSType == LVDS_UNIPHY2)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
-	} else {
-	    if (radeon_output->TMDSType == TMDS_UNIPHY)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
-	    else if (radeon_output->TMDSType == TMDS_UNIPHY1)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
-	    else if (radeon_output->TMDSType == TMDS_UNIPHY2)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+	    break;
 	}
     } else {
-	if (radeon_output->type == OUTPUT_LVDS)
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
-	else {
-	    if (radeon_output->TMDSType == TMDS_LVTMA)
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
-	    else
-		disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
+	    break;
 	}
     }
 
@@ -461,24 +491,32 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     union dig_transmitter_control disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
     int index, num = 0;
     int major, minor;
 
+    if (radeon_encoder == NULL)
+        return ATOM_NOT_IMPLEMENTED;
+
     memset(&disp_data,0, sizeof(disp_data));
 
     if (IS_DCE32_VARIANT)
 	index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
     else {
-	if (radeon_output->type == OUTPUT_LVDS)
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
-	else {
-	    if (radeon_output->TMDSType == TMDS_LVTMA)
-		index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
-	    else
-		index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+	    break;
 	}
     }
 
@@ -496,42 +534,19 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 	if (radeon_crtc->crtc_id)
 	    disp_data.v2.acConfig.ucEncoderSel = 1;
 
-	if (radeon_output->type == OUTPUT_LVDS) {
-	    switch (radeon_output->LVDSType) {
-	    case LVDS_UNIPHY:
-		disp_data.v2.acConfig.ucTransmitterSel = 0;
-		num = 0;
-		break;
-	    case LVDS_UNIPHY1:
-		disp_data.v2.acConfig.ucTransmitterSel = 1;
-		num = 1;
-		break;
-	    case LVDS_UNIPHY2:
-		disp_data.v2.acConfig.ucTransmitterSel = 2;
-		num = 2;
-		break;
-	    default:
-		return ATOM_NOT_IMPLEMENTED;
-		break;
-	    }
-	} else {
-	    switch (radeon_output->TMDSType) {
-	    case TMDS_UNIPHY:
-		disp_data.v2.acConfig.ucTransmitterSel = 0;
-		num = 0;
-		break;
-	    case TMDS_UNIPHY1:
-		disp_data.v2.acConfig.ucTransmitterSel = 1;
-		num = 1;
-		break;
-	    case TMDS_UNIPHY2:
-		disp_data.v2.acConfig.ucTransmitterSel = 2;
-		num = 2;
-		break;
-	    default:
-		return ATOM_NOT_IMPLEMENTED;
-		break;
-	    }
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    disp_data.v2.acConfig.ucTransmitterSel = 0;
+	    num = 0;
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	    disp_data.v2.acConfig.ucTransmitterSel = 1;
+	    num = 1;
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	    disp_data.v2.acConfig.ucTransmitterSel = 2;
+	    num = 2;
+	    break;
 	}
 
 	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
@@ -545,44 +560,49 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 	disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 	disp_data.v1.usPixelClock = cpu_to_le16((mode->Clock) / 10);
 
-	if (radeon_output->type == OUTPUT_LVDS)
-	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-	else {
-	    if (radeon_output->TMDSType == TMDS_LVTMA)
-		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-	    else
-		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
-	}
-
-	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
-	    if (radeon_output->coherent_mode) {
-		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
-		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode enabled\n", num);
-	    } else
-		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode disabled\n", num);
-	}
-
-	if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
-	    if (mode->Clock > 165000) {
-		disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-				       ATOM_TRANSMITTER_CONFIG_LINKA_B);
-		/* guess */
-		if (radeon_output->igp_lane_info & 0x3)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
-		else if (radeon_output->igp_lane_info & 0xc)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+	    if (info->IsIGP) {
+		if (mode->Clock > 165000) {
+		    disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+					      ATOM_TRANSMITTER_CONFIG_LINKA_B);
+		    /* guess */
+		    if (radeon_output->igp_lane_info & 0x3)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
+		    else if (radeon_output->igp_lane_info & 0xc)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
+		} else {
+		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
+		    if (radeon_output->igp_lane_info & 0x1)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+		    else if (radeon_output->igp_lane_info & 0x2)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
+		    else if (radeon_output->igp_lane_info & 0x4)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
+		    else if (radeon_output->igp_lane_info & 0x8)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+		}
 	    } else {
-		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
-		if (radeon_output->igp_lane_info & 0x1)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
-		else if (radeon_output->igp_lane_info & 0x2)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
-		else if (radeon_output->igp_lane_info & 0x4)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
-		else if (radeon_output->igp_lane_info & 0x8)
-		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
+		if (mode->Clock > 165000)
+		    disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+					      ATOM_TRANSMITTER_CONFIG_LINKA_B |
+					      ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+		else {
+		    /* XXX */
+		    if (radeon_output->linkb)
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+		    else
+			disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+		}
 	    }
-	} else {
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
 	    if (mode->Clock > 165000)
 		disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
 					  ATOM_TRANSMITTER_CONFIG_LINKA_B |
@@ -594,9 +614,17 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 		else
 		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
 	    }
+	    break;
 	}
-    }
 
+	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
+	    if (radeon_output->coherent_mode) {
+		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
+		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode enabled\n", num);
+	    } else
+		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode disabled\n", num);
+	}
+    }
     radeon_output->transmitter_config = disp_data.v1.ucConfig;
 
     data.exec.index = index;
@@ -688,44 +716,20 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 
 }
 
-static AtomBiosResult
-atombios_display_device_control(atomBiosHandlePtr atomBIOS, int index, Bool state)
-{
-    DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data;
-    AtomBiosArgRec data;
-    unsigned char *space;
-
-    disp_data.ucAction = state;
-    data.exec.index = index;
-    data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &disp_data;
-
-    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output %d %s success\n", index, state? "enable":"disable");
-	return ATOM_SUCCESS;
-    }
-
-    ErrorF("Output %d %s failed\n", index, state? "enable":"disable");
-    return ATOM_NOT_IMPLEMENTED;
-}
-
 static int
 atombios_dig_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
-    int block;
 
-    memset(&disp_data, 0, sizeof(disp_data));
+    if (radeon_encoder == NULL)
+	return ATOM_NOT_IMPLEMENTED;
 
-    if ((radeon_output->type == OUTPUT_LVDS) ||
-	(radeon_output->TMDSType == TMDS_LVTMA))
-	block = 2;
-    else
-	block = 1;
+    memset(&disp_data, 0, sizeof(disp_data));
 
     switch (mode) {
     case DPMSModeOn:
@@ -743,95 +747,112 @@ atombios_dig_dpms(xf86OutputPtr output, int mode)
     if (IS_DCE32_VARIANT) {
 	data.exec.index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
     } else {
-	if (block == 1)
+	switch (radeon_encoder->encoder_id) {
+	case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 	    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
-	else
+	    break;
+	case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+	    break;
+	}
     }
     data.exec.dataSpace = (void *)&space;
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output DIG%d dpms success\n", block);
+	ErrorF("Output DIG dpms success\n");
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output DIG%d dpms failed\n", block);
+    ErrorF("Output DIG dpms failed\n");
     return ATOM_NOT_IMPLEMENTED;
 
 }
 
-static void
-atombios_device_dpms(xf86OutputPtr output, int mode)
+void
+atombios_output_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
     int index = 0;
 
-    if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->DACType == DAC_PRIMARY)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
-	else if (radeon_output->DACType == DAC_TVDAC)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+    if (radeon_encoder == NULL)
+        return;
+
+    switch (radeon_encoder->encoder_id) {
+    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+	index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+	(void)atombios_dig_dpms(output, mode);
+	return;
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+    case ENCODER_OBJECT_ID_INTERNAL_DDI:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+	index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+	if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
 	else
-	    return;
-    } else if (radeon_output->MonType == MT_DFP) {
-	switch (radeon_output->TMDSType) {
-	case TMDS_INT:
-	    index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
-	    break;
-	case TMDS_EXT:
-	case TMDS_DDIA:
-	    index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
-	    break;
-	case TMDS_LVTMA:
 	    index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
-	    break;
-	default:
-	    return;
-	}
-    } else if (radeon_output->MonType == MT_LCD) {
-	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
-    } else if (radeon_output->MonType == MT_STV ||
-               radeon_output->MonType == MT_CTV) {
-	index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-    } else if (radeon_output->MonType == MT_CV) {
-	index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
-    } else
-	return;
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+	else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+	else
+	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+	if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+	else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT))
+	    index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+	else
+	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+	break;
+    }
 
     switch (mode) {
     case DPMSModeOn:
-	atombios_display_device_control(info->atomBIOS, index, ATOM_ENABLE);
+	disp_data.ucAction = ATOM_ENABLE;
 	break;
     case DPMSModeStandby:
     case DPMSModeSuspend:
     case DPMSModeOff:
-	atombios_display_device_control(info->atomBIOS, index, ATOM_DISABLE);
+	disp_data.ucAction = ATOM_DISABLE;
 	break;
     }
-}
 
-void
-atombios_output_dpms(xf86OutputPtr output, int mode)
-{
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    data.exec.index = index;
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
 
-    /*ErrorF("output dpms %d\n", mode);*/
-    if (IS_DCE3_VARIANT) {
-	if (radeon_output->MonType == MT_LCD)
-	    atombios_dig_dpms(output, mode);
-	else if (radeon_output->MonType == MT_DFP) {
-	    if (radeon_output->TMDSType >= TMDS_LVTMA)
-		atombios_dig_dpms(output, mode);
-	    else
-		atombios_device_dpms(output, mode);
-	} else
-	    atombios_device_dpms(output, mode);
-    } else
-	atombios_device_dpms(output, mode);
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output %d %s success\n", index, disp_data.ucAction? "enable":"disable");
+    }
 
+    ErrorF("Output %d %s failed\n", index, disp_data.ucAction? "enable":"disable");
 }
 
 static void
@@ -840,6 +861,7 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
     AtomBiosArgRec data;
     unsigned char *space;
     SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
@@ -847,6 +869,9 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
     int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
     int major, minor;
 
+    if (radeon_encoder == NULL)
+	return;
+
     memset(&crtc_src_param, 0, sizeof(crtc_src_param));
     memset(&crtc_src_param2, 0, sizeof(crtc_src_param2));
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
@@ -860,98 +885,91 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 	case 1:
 	default:
 	    crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
-	    crtc_src_param.ucDevice = 0;
-	    if (radeon_output->MonType == MT_CRT) {
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_CRT1_INDEX;
-		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_CRT2_INDEX;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP1_INDEX;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP2_INDEX;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP3_INDEX;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP4_INDEX;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_DFP5_INDEX;
-	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_LCD1_INDEX;
-	    } else if (OUTPUT_IS_TV) {
-		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_TV1_INDEX;
-	    } else if (radeon_output->MonType == MT_CV) {
-		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-		    crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
-	    }
+	    crtc_src_param.ucDevice = radeon_get_device_index(radeon_output->active_device);
 	    data.exec.pspace = &crtc_src_param;
 	    /*ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);*/
 	    break;
 	case 2:
 	    crtc_src_param2.ucCRTC = radeon_crtc->crtc_id;
-	    if (radeon_output->MonType == MT_CRT) {
-		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
-		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
-		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
-	    } else if (radeon_output->MonType == MT_DFP) {
-		if (IS_DCE3_VARIANT) {
-		    if (IS_DCE32_VARIANT) {
-			/* we route digital encoders using the CRTC ids */
-			if (radeon_crtc->crtc_id)
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-			else
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-		    } else {
-			if (radeon_output->TMDSType == TMDS_LVTMA)
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-			else
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-		    }
-		} else {
-		    if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-			crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP1_INDEX;
-		    else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-			crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP2_INDEX;
-		    else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-			crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP3_INDEX;
-		}
-		if (OUTPUT_IS_DVI)
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
-		else if (radeon_output->type == OUTPUT_HDMI)
-		    crtc_src_param2.ucEncodeMode =
-			atombios_maybe_hdmi_mode(output);
-		else if (radeon_output->type == OUTPUT_DP)
-		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
-	    } else if (radeon_output->MonType == MT_LCD) {
-		if (IS_DCE3_VARIANT) {
-		    if (IS_DCE32_VARIANT) {
-			/* we route digital encoders using the CRTC ids */
-			if (radeon_crtc->crtc_id)
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-			else
-			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
-		    } else
+	    switch (radeon_encoder->encoder_id) {
+	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+		if (IS_DCE32_VARIANT) {
+		    if (radeon_crtc->crtc_id)
 			crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+		    else
+			crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		} else
+		    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+		else {
+		    if (OUTPUT_IS_DVI)
+			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
+		    else if (radeon_output->type == OUTPUT_HDMI)
+			crtc_src_param2.ucEncodeMode =
+			    atombios_maybe_hdmi_mode(output);
+		    else if (radeon_output->type == OUTPUT_DP)
+			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
+		}
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+	    case ENCODER_OBJECT_ID_INTERNAL_DDI:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+		crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device);
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+		if (IS_DCE3_VARIANT)
+		    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+		else
+		    crtc_src_param2.ucEncoderID = radeon_get_device_index(radeon_output->active_device);
+		if (radeon_output->active_device & (ATOM_DEVICE_LCD_SUPPORT))
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+		else {
+		    if (OUTPUT_IS_DVI)
+			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DVI;
+		    else if (radeon_output->type == OUTPUT_HDMI)
+			crtc_src_param2.ucEncodeMode =
+			    atombios_maybe_hdmi_mode(output);
+		    else if (radeon_output->type == OUTPUT_DP)
+			crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
+		}
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
+		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
+		} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
+		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
 		} else {
-		    if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-			crtc_src_param2.ucEncoderID = ATOM_DEVICE_LCD1_INDEX;
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC1_ENCODER_ID;
 		}
-		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
-	    } else if (OUTPUT_IS_TV) {
-		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+		break;
+	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+		if (radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) {
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
-	    } else if (radeon_output->MonType == MT_CV) {
-		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV;
+		} else if (radeon_output->active_device & (ATOM_DEVICE_CV_SUPPORT)) {
 		    crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID;
-		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
+		} else {
+		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
+		}
+		break;
 	    }
-
 	    data.exec.pspace = &crtc_src_param2;
 	    /*ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);*/
 	    break;
@@ -975,9 +993,10 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 }
 
 static void
-atombios_apply_output_quirks(xf86OutputPtr output)
+atombios_apply_output_quirks(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
@@ -996,6 +1015,10 @@ atombios_apply_output_quirks(xf86OutputPtr output)
 	    }
 	}
     }
+
+    /* set scaler clears this on some chips */
+    if (mode->Flags & V_INTERLACE)
+	OUTREG(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, AVIVO_D1MODE_INTERLEAVE_EN);
 }
 
 void
@@ -1005,33 +1028,47 @@ atombios_output_mode_set(xf86OutputPtr output,
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    radeon_encoder_ptr radeon_encoder = radeon_get_encoder(output);
+
+    if (radeon_encoder == NULL)
+        return;
 
     atombios_output_scaler_setup(output, mode);
     atombios_set_output_crtc_source(output);
 
-    if (radeon_output->MonType == MT_CRT) {
-	atombios_output_dac_setup(output, adjusted_mode);
-    } else if ((radeon_output->MonType == MT_CTV) ||
-	       (radeon_output->MonType == MT_STV) ||
-	       (radeon_output->MonType == MT_CV)) {
-	atombios_output_dac_setup(output, adjusted_mode);
-	atombios_output_tv_setup(output, adjusted_mode);
-    } else {
+    switch (radeon_encoder->encoder_id) {
+    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
 	if (IS_DCE3_VARIANT) {
 	    atombios_output_dig_encoder_setup(output, adjusted_mode);
 	    atombios_output_dig_transmitter_setup(output, adjusted_mode);
-	} else if ((info->ChipFamily < CHIP_FAMILY_R600) &&
-		   (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
-	    if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
-		(info->ChipFamily == CHIP_FAMILY_RS690) ||
-		(info->ChipFamily == CHIP_FAMILY_RS740))
-		atombios_output_ddia_setup(output, adjusted_mode);
-	    else
-		atombios_external_tmds_setup(output, adjusted_mode);
 	} else
 	    atombios_output_digital_setup(output, adjusted_mode);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DDI:
+	atombios_output_ddia_setup(output, adjusted_mode);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DVO1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+	atombios_external_tmds_setup(output, adjusted_mode);
+	break;
+    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+	atombios_output_dac_setup(output, adjusted_mode);
+	if ((radeon_output->active_device & (ATOM_DEVICE_TV_SUPPORT)) ||
+	    (radeon_output->active_device & (ATOM_DEVICE_CRT_SUPPORT)))
+	    atombios_output_tv_setup(output, adjusted_mode);
+	break;
     }
-    atombios_apply_output_quirks(output);
+    atombios_apply_output_quirks(output, adjusted_mode);
 }
 
 static AtomBiosResult
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index f79cb2d..e136180 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1585,6 +1585,15 @@ radeon_get_device_index(uint32_t device_support)
 }
 
 radeon_encoder_ptr
+radeon_get_encoder(xf86OutputPtr output)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    return radeon_output->encoders[radeon_get_device_index(radeon_output->active_device)];
+
+}
+
+radeon_encoder_ptr
 radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
@@ -1617,7 +1626,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
     ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
     ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL;
-    int i, j, path_size, device_support;
+    int i, j, k, path_size, device_support;
     Bool enable_tv = FALSE;
 
     if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE))
@@ -1793,15 +1802,6 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 
     for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
 	if (info->BiosConnector[i].valid) {
-	    /* shared ddc */
-	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
-		if (info->BiosConnector[j].valid && (i != j) ) {
-		    if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) {
-			info->BiosConnector[i].shared_ddc = TRUE;
-			info->BiosConnector[j].shared_ddc = TRUE;
-		    }
-		}
-	    }
 	    /* shared connectors */
 	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
 		if (info->BiosConnector[j].valid && (i != j) ) {
@@ -1811,10 +1811,23 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 			else
 			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
 			info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
+			for (k = 0; k < ATOM_MAX_SUPPORTED_DEVICE; k++) {
+			    if (info->BiosConnector[j].encoders[k])
+				info->BiosConnector[i].encoders[k] = info->BiosConnector[j].encoders[k];
+			}
 			info->BiosConnector[j].valid = FALSE;
 		    }
 		}
 	    }
+	    /* shared ddc */
+	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+		if (info->BiosConnector[j].valid && (i != j) ) {
+		    if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) {
+			info->BiosConnector[i].shared_ddc = TRUE;
+			info->BiosConnector[j].shared_ddc = TRUE;
+		    }
+		}
+	    }
 	}
     }
 
@@ -2023,7 +2036,69 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
     return TRUE;
 }
 
+uint32_t
+radeon_get_encoder_id_from_supported_device(ScrnInfoPtr pScrn, uint32_t supported_device, int dac)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    uint32_t ret = 0;
+
+    switch (supported_device) {
+    case ATOM_DEVICE_CRT1_SUPPORT:
+    case ATOM_DEVICE_TV1_SUPPORT:
+    case ATOM_DEVICE_TV2_SUPPORT:
+    case ATOM_DEVICE_CRT2_SUPPORT:
+    case ATOM_DEVICE_CV_SUPPORT:
+	switch (dac) {
+	case 1:
+	    if (IS_AVIVO_VARIANT)
+		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1;
+	    else
+		ret = ENCODER_OBJECT_ID_INTERNAL_DAC1;
+	    break;
+	case 2:
+	    if (IS_AVIVO_VARIANT)
+		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
+	    else
+		ret = ENCODER_OBJECT_ID_INTERNAL_DAC2;
+	    break;
+	case 3:
+	    if (IS_AVIVO_VARIANT)
+		ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
+	    else
+		ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
+	    break;
+	}
+	break;
+    case ATOM_DEVICE_LCD1_SUPPORT:
+	if (IS_AVIVO_VARIANT)
+	    ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
+	else
+	    ret = ENCODER_OBJECT_ID_INTERNAL_LVDS;
+	break;
+    case ATOM_DEVICE_DFP1_SUPPORT:
+	if (IS_AVIVO_VARIANT)
+	    ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
+	else
+	    ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1;
+	break;
+    case ATOM_DEVICE_LCD2_SUPPORT:
+    case ATOM_DEVICE_DFP2_SUPPORT:
+	if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740))
+	    ret = ENCODER_OBJECT_ID_INTERNAL_DDI;
+	else if (IS_AVIVO_VARIANT)
+	    ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
+	else
+	    ret = ENCODER_OBJECT_ID_INTERNAL_DVO1;
+	break;
+    case ATOM_DEVICE_DFP3_SUPPORT:
+	ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1;
+	break;
+    }
 
+    return ret;
+}
 
 Bool
 RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
@@ -2099,6 +2174,12 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	    info->BiosConnector[i].ddc_i2c =
 		RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
 
+	info->BiosConnector[i].encoders[radeon_get_device_index((1 << i))] =
+	    radeon_add_encoder(pScrn,
+			       radeon_get_encoder_id_from_supported_device(pScrn, (1 << i),
+					     ci.sucConnectorInfo.sbfAccess.bfAssociatedDAC),
+			       (i << 1));
+
 	if (i == ATOM_DEVICE_DFP1_INDEX)
 	    info->BiosConnector[i].TMDSType = TMDS_INT;
 	else if (i == ATOM_DEVICE_DFP2_INDEX) {
@@ -2167,6 +2248,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 			    ((j == ATOM_DEVICE_CRT1_INDEX) || (j == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
 			    info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
+			    info->BiosConnector[i].encoders[j] = info->BiosConnector[j].encoders[j];
 			    info->BiosConnector[j].valid = FALSE;
 			} else if (((j == ATOM_DEVICE_DFP1_INDEX) ||
 			     (j == ATOM_DEVICE_DFP2_INDEX) ||
@@ -2174,6 +2256,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 			    ((i == ATOM_DEVICE_CRT1_INDEX) || (i == ATOM_DEVICE_CRT2_INDEX))) {
 			    info->BiosConnector[j].DACType = info->BiosConnector[i].DACType;
 			    info->BiosConnector[j].devices |= info->BiosConnector[i].devices;
+			    info->BiosConnector[i].encoders[j] = info->BiosConnector[j].encoders[j];
 			    info->BiosConnector[i].valid = FALSE;
 			} else {
 			    info->BiosConnector[i].shared_ddc = TRUE;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index efbfdfe..2ac577c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -356,6 +356,49 @@ RADEONConnectorFindMonitor(xf86OutputPtr output)
 	}
     }
 
+    if (radeon_output->MonType == MT_DFP) {
+	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP2_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP3_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP4_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_DFP5_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_CRT) {
+	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CRT2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_LCD) {
+	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_LCD2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_LCD2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if ((radeon_output->MonType == MT_STV) ||
+	       (radeon_output->MonType == MT_CTV)){
+	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV1_SUPPORT;
+	else if (radeon_output->devices & ATOM_DEVICE_TV2_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_TV2_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else if (radeon_output->MonType == MT_CV) {
+	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
+	    radeon_output->active_device = ATOM_DEVICE_CV_SUPPORT;
+	else
+	    radeon_output->active_device = 0;
+    } else
+	radeon_output->active_device = 0;
+
     /* update panel info for RMX */
     if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
 	RADEONUpdatePanelSize(output);
commit 25f3878858e6efb486888e5271b60d4ba08c73c6
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Mon Jan 19 15:54:42 2009 -0500

    start to re-org outputs

diff --git a/src/radeon.h b/src/radeon.h
index 2a6f150..7705b2a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -805,6 +805,7 @@ typedef struct {
 
     Bool want_vblank_interrupts;
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
+    radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
     RADEONBIOSInitTable BiosTable;
 
     /* save crtc state for console restore */
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index feebdba..f79cb2d 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1569,6 +1569,44 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
     }
 }
 
+uint32_t
+radeon_get_device_index(uint32_t device_support)
+{
+    uint32_t device_index = 0;
+
+    if (device_support == 0)
+	return 0;
+
+    while ((device_support & 1) == 0) {
+	device_support >>= 1;
+	device_index++;
+    }
+    return device_index;
+}
+
+radeon_encoder_ptr
+radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_support)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    uint32_t device_index = radeon_get_device_index(device_support);
+
+    if (device_support == 0)
+	return NULL;
+
+    if (info->encoders[device_index] != NULL)
+	return info->encoders[device_index];
+    else {
+	info->encoders[device_index] = (radeon_encoder_ptr)xcalloc(1,sizeof(radeon_encoder_rec));
+	if (info->encoders[device_index] != NULL) {
+	    info->encoders[device_index]->encoder_id = encoder_id;
+	    // add dev_priv stuff
+	    return info->encoders[device_index];
+	} else
+	    return NULL;
+    }
+
+}
+
 Bool
 RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 {
@@ -1666,6 +1704,9 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		    else
 			info->BiosConnector[i].linkb = FALSE;
 
+		    info->BiosConnector[i].encoders[radeon_get_device_index(path->usDeviceTag)] =
+			radeon_add_encoder(pScrn, enc_obj_id, path->usDeviceTag);
+
 		    switch(enc_obj_id) {
 		    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
 			info->BiosConnector[i].LVDSType = LVDS_INT;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index bf7fa8a..efbfdfe 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2712,7 +2712,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     xf86OutputPtr output;
     char *optstr;
-    int i = 0;
+    int i, j;
     int num_vga = 0;
     int num_dvi = 0;
     int num_hdmi = 0;
@@ -2722,6 +2722,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
      * The information should be correct even on a OEM card.
      */
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	info->encoders[i] = NULL;
+	for (j = 0; j < RADEON_MAX_BIOS_CONNECTOR; j++)
+	    info->BiosConnector[i].encoders[j] = NULL;
 	info->BiosConnector[i].valid = FALSE;
 	info->BiosConnector[i].load_detection = TRUE;
 	info->BiosConnector[i].shared_ddc = FALSE;
@@ -2858,6 +2861,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc;
 	    radeon_output->load_detection = info->BiosConnector[i].load_detection;
 	    radeon_output->linkb = info->BiosConnector[i].linkb;
+	    radeon_output->connector_id = info->BiosConnector[i].connector_object;
+	    for (j = 0; j < RADEON_MAX_BIOS_CONNECTOR; j++)
+		radeon_output->encoders[j] = info->BiosConnector[i].encoders[j];
 
 	    radeon_output->LVDSType = info->BiosConnector[i].LVDSType;
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 9cde274..36f6483 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -52,6 +52,9 @@
 
 extern DriverRec RADEON;
 
+#define RADEON_MAX_CRTC 2
+#define RADEON_MAX_BIOS_CONNECTOR 16
+
 typedef enum
 {
     MT_UNKNOWN = -1,
@@ -207,6 +210,11 @@ typedef struct _RADEONCrtcPrivateRec {
     Bool enabled;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
+typedef struct _radeon_encoder {
+    uint16_t encoder_id;
+    void *dev_priv;
+} radeon_encoder_rec, *radeon_encoder_ptr;
+
 typedef struct {
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
@@ -223,6 +231,7 @@ typedef struct {
     Bool load_detection;
     Bool linkb;
     uint16_t connector_object;
+    radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -234,12 +243,10 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONDviType DVIType;
     RADEONTmdsType TMDSType;
     RADEONLvdsType LVDSType;
-    RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
     int crtc_num;
     int DDCReg;
-    I2CBusPtr         pI2CBus;
-    RADEONI2CBusRec   ddc_i2c;
+
     uint32_t          ps2_tvdac_adj;
     uint32_t          pal_tvdac_adj;
     uint32_t          ntsc_tvdac_adj;
@@ -282,9 +289,26 @@ typedef struct _RADEONOutputPrivateRec {
 
     char              *name;
     int               output_id;
-    int               devices;
+    //int               devices;
     Bool enabled;
+
+    // re-org
+    uint16_t connector_id;
+    uint32_t devices;
+    uint32_t active_device;
+    radeon_encoder_ptr encoders[RADEON_MAX_BIOS_CONNECTOR];
+    //RADEONConnectorType connector_type;
+    RADEONConnectorType ConnectorType;
+    // DDC info
+    I2CBusPtr         pI2CBus;
+    RADEONI2CBusRec   ddc_i2c;
+    // router info
+    // HDP info
+    // shared_ddc
     Bool shared_ddc;
+    // cvtv pin
+    // preferred mode
+
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 struct avivo_pll_state {
@@ -588,9 +612,6 @@ typedef struct {
 
 } RADEONSaveRec, *RADEONSavePtr;
 
-#define RADEON_MAX_CRTC 2
-#define RADEON_MAX_BIOS_CONNECTOR 16
-
 typedef struct
 {
     Bool HasSecondary;
commit cbeb310d35e5ea25ba7a45a2c555468391cdf29e
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 16 19:53:49 2009 -0500

    ATOM: switch to define for external tmds

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 27c62bc..efe487b 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -177,7 +177,7 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode)
     disp_data.sXTmdsEncoder.ucEnable = ATOM_ENABLE;
 
     if (mode->Clock > 165000)
-	disp_data.sXTmdsEncoder.ucMisc = 1;
+	disp_data.sXTmdsEncoder.ucMisc = PANEL_ENCODER_MISC_DUAL;
 
     if (pScrn->rgbBits == 8)
 	disp_data.sXTmdsEncoder.ucMisc |= (1 << 1);
commit d0d157abced43f822885fa26f14a4924766594cd
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 16 19:51:07 2009 -0500

    ATOM: combine DAC setup functions
    
    plus a few other clean-ups

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 18ace77..27c62bc 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -46,15 +46,23 @@
 #include "ati_pciids_gen.h"
 
 static int
-atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_dac_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
+    int index;
+
+    memset(&disp_data,0, sizeof(disp_data));
+
+    if (radeon_output->DACType == DAC_PRIMARY)
+	index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
+    else
+	index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
 
-    disp_data.ucAction = 1;
+    disp_data.ucAction = ATOM_ENABLE;
 
     if (radeon_output->MonType == MT_CRT)
 	disp_data.ucDacStandard = ATOM_DAC1_PS2;
@@ -77,74 +85,24 @@ atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode)
 	    break;
 	}
     }
-
     disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
-    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl);
-    data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &disp_data;
-
-    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output DAC1 setup success\n");
-	return ATOM_SUCCESS;
-    }
-
-    ErrorF("Output DAC1 setup failed\n");
-    return ATOM_NOT_IMPLEMENTED;
-
-}
-
-static int
-atombios_output_dac2_setup(xf86OutputPtr output, DisplayModePtr mode)
-{
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONInfoPtr info       = RADEONPTR(output->scrn);
-    DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data;
-    AtomBiosArgRec data;
-    unsigned char *space;
-
-    disp_data.ucAction = 1;
-
-    if (radeon_output->MonType == MT_CRT)
-	disp_data.ucDacStandard = ATOM_DAC2_PS2;
-    else if (radeon_output->MonType == MT_CV)
-	disp_data.ucDacStandard = ATOM_DAC2_CV;
-    else if (OUTPUT_IS_TV) {
-	switch (radeon_output->tvStd) {
-	case TV_STD_NTSC:
-	case TV_STD_NTSC_J:
-	case TV_STD_PAL_60:
-	    disp_data.ucDacStandard = ATOM_DAC2_NTSC;
-	    break;
-	case TV_STD_PAL:
-	case TV_STD_PAL_M:
-	case TV_STD_SCART_PAL:
-	case TV_STD_SECAM:
-	case TV_STD_PAL_CN:
-	    disp_data.ucDacStandard = ATOM_DAC2_PAL;
-	    break;
-	default:
-	    disp_data.ucDacStandard = ATOM_DAC2_NTSC;
-	    break;
-	}
-    }
 
-    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
-    data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl);
+    data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output DAC2 setup success\n");
+	ErrorF("Output DAC setup success\n");
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output DAC2 setup failed\n");
+    ErrorF("Output DAC setup failed\n");
     return ATOM_NOT_IMPLEMENTED;
 
 }
 
 static int
-atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_tv_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
@@ -152,7 +110,9 @@ atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode)
     AtomBiosArgRec data;
     unsigned char *space;
 
-    disp_data.sTVEncoder.ucAction = 1;
+    memset(&disp_data,0, sizeof(disp_data));
+
+    disp_data.sTVEncoder.ucAction = ATOM_ENABLE;
 
     if (radeon_output->MonType == MT_CV)
 	disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV;
@@ -194,11 +154,11 @@ atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode)
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output TV1 setup success\n");
+	ErrorF("Output TV setup success\n");
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output TV1 setup failed\n");
+    ErrorF("Output TV setup failed\n");
     return ATOM_NOT_IMPLEMENTED;
 
 }
@@ -212,12 +172,12 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode)
     AtomBiosArgRec data;
     unsigned char *space;
 
-    disp_data.sXTmdsEncoder.ucEnable = 1;
+    memset(&disp_data,0, sizeof(disp_data));
+
+    disp_data.sXTmdsEncoder.ucEnable = ATOM_ENABLE;
 
     if (mode->Clock > 165000)
 	disp_data.sXTmdsEncoder.ucMisc = 1;
-    else
-	disp_data.sXTmdsEncoder.ucMisc = 0;
 
     if (pScrn->rgbBits == 8)
 	disp_data.sXTmdsEncoder.ucMisc |= (1 << 1);
@@ -243,13 +203,13 @@ atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
     AtomBiosArgRec data;
     unsigned char *space;
 
+    memset(&disp_data,0, sizeof(disp_data));
+
     disp_data.sDVOEncoder.ucAction = ATOM_ENABLE;
     disp_data.sDVOEncoder.usPixelClock = cpu_to_le16(mode->Clock / 10);
 
     if (mode->Clock > 165000)
 	disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = PANEL_ENCODER_MISC_DUAL;
-    else
-	disp_data.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0;
 
     data.exec.index = GetIndexIntoMasterTable(COMMAND, DVOEncoderControl);
     data.exec.dataSpace = (void *)&space;
@@ -277,6 +237,9 @@ atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
     int index;
     int major, minor;
 
+    memset(&disp_data,0, sizeof(disp_data));
+    memset(&disp_data2,0, sizeof(disp_data2));
+
     if (radeon_output->type == OUTPUT_LVDS)
 	index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
     else {
@@ -403,6 +366,8 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     int index;
     int major, minor;
 
+    memset(&disp_data,0, sizeof(disp_data));
+
     if (IS_DCE32_VARIANT) {
 	if (radeon_crtc->crtc_id)
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
@@ -503,6 +468,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
     int major, minor;
 
     memset(&disp_data,0, sizeof(disp_data));
+
     if (IS_DCE32_VARIANT)
 	index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
     else {
@@ -1044,18 +1010,12 @@ atombios_output_mode_set(xf86OutputPtr output,
     atombios_set_output_crtc_source(output);
 
     if (radeon_output->MonType == MT_CRT) {
-	if (radeon_output->DACType == DAC_PRIMARY)
-	    atombios_output_dac1_setup(output, adjusted_mode);
-	else if (radeon_output->DACType == DAC_TVDAC)
-	    atombios_output_dac2_setup(output, adjusted_mode);
+	atombios_output_dac_setup(output, adjusted_mode);
     } else if ((radeon_output->MonType == MT_CTV) ||
 	       (radeon_output->MonType == MT_STV) ||
 	       (radeon_output->MonType == MT_CV)) {
-	if (radeon_output->DACType == DAC_PRIMARY)
-	    atombios_output_dac1_setup(output, adjusted_mode);
-	else if (radeon_output->DACType == DAC_TVDAC)
-	    atombios_output_dac2_setup(output, adjusted_mode);
-	atombios_output_tv1_setup(output, adjusted_mode);
+	atombios_output_dac_setup(output, adjusted_mode);
+	atombios_output_tv_setup(output, adjusted_mode);
     } else {
 	if (IS_DCE3_VARIANT) {
 	    atombios_output_dig_encoder_setup(output, adjusted_mode);
commit f6f969338f8187529c7ae9b2adc980b71a3f5837
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Fri Jan 16 18:10:34 2009 -0500

    DCE30: LVTMA requires DIG2 encoder
    
    Fixes bug 19544

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 4877beb..18ace77 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -403,10 +403,21 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
     int index;
     int major, minor;
 
-    if (radeon_crtc->crtc_id)
-	index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
-    else
-	index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+    if (IS_DCE32_VARIANT) {
+	if (radeon_crtc->crtc_id)
+	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	else
+	    index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+    } else {
+	if (radeon_output->type == OUTPUT_LVDS)
+	    index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	else {
+	    if (radeon_output->TMDSType == TMDS_LVTMA)
+		index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+	    else
+		index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+	}
+    }
 
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
@@ -568,10 +579,14 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 	disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 	disp_data.v1.usPixelClock = cpu_to_le16((mode->Clock) / 10);
 
-	if (radeon_crtc->crtc_id)
+	if (radeon_output->type == OUTPUT_LVDS)
 	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
-	else
-	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+	else {
+	    if (radeon_output->TMDSType == TMDS_LVTMA)
+		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+	    else
+		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
+	}
 
 	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
 	    if (radeon_output->coherent_mode) {
@@ -919,11 +934,18 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 		    crtc_src_param2.ucEncoderID = ASIC_INT_DAC2_ENCODER_ID;
 	    } else if (radeon_output->MonType == MT_DFP) {
 		if (IS_DCE3_VARIANT) {
-		    /* we route digital encoders using the CRTC ids */
-		    if (radeon_crtc->crtc_id)
-			crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
-		    else
-			crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		    if (IS_DCE32_VARIANT) {
+			/* we route digital encoders using the CRTC ids */
+			if (radeon_crtc->crtc_id)
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+			else
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		    } else {
+			if (radeon_output->TMDSType == TMDS_LVTMA)
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+			else
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		    }
 		} else {
 		    if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
 			crtc_src_param2.ucEncoderID = ATOM_DEVICE_DFP1_INDEX;
@@ -940,8 +962,19 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 		else if (radeon_output->type == OUTPUT_DP)
 		    crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_DP;
 	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_LCD1_INDEX;
+		if (IS_DCE3_VARIANT) {
+		    if (IS_DCE32_VARIANT) {
+			/* we route digital encoders using the CRTC ids */
+			if (radeon_crtc->crtc_id)
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+			else
+			    crtc_src_param2.ucEncoderID = ASIC_INT_DIG1_ENCODER_ID;
+		    } else
+			crtc_src_param2.ucEncoderID = ASIC_INT_DIG2_ENCODER_ID;
+		} else {
+		    if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+			crtc_src_param2.ucEncoderID = ATOM_DEVICE_LCD1_INDEX;
+		}
 		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
 	    } else if (OUTPUT_IS_TV) {
 		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
commit 1795706a6bb13272a58e8fa1bd5ad2603d553dde
Author: Nicos Gollan <gtdev at spearhead.de>
Date:   Wed Jan 7 14:25:24 2009 -0500

    [PATCH] Fixed enumerations in radeon-output.c

diff --git a/src/radeon_output.c b/src/radeon_output.c
index c5c6f5c..bf7fa8a 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -68,18 +68,18 @@ const char *TMDSTypeName[8] = {
   "External",
   "LVTMA",
   "DDIA",
-  "UNIPHY"
-  "UNIPHY1"
-  "UNIPHY2"
+  "UNIPHY",
+  "UNIPHY1",
+  "UNIPHY2",
 };
 
 const char *LVDSTypeName[6] = {
   "None",
   "Internal",
   "LVTMA",
-  "UNIPHY"
-  "UNIPHY1"
-  "UNIPHY2"
+  "UNIPHY",
+  "UNIPHY1",
+  "UNIPHY2",
 };
 
 const char *DACTypeName[4] = {
commit c3fb8bb279959512a4ced644a64cc660c5cd97bd
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 6 17:41:22 2009 -0500

    ATOM: rework encoder/transmitter setup

diff --git a/src/atombios_output.c b/src/atombios_output.c
index 8a84e6b..4877beb 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -265,7 +265,7 @@ atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static int
-atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr mode)
+atombios_output_digital_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     ScrnInfoPtr pScrn = output->scrn;
@@ -277,19 +277,13 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m
     int index;
     int major, minor;
 
-    switch (device) {
-    case ATOM_DEVICE_DFP1_INDEX:
-	index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
-	break;
-    case ATOM_DEVICE_LCD1_INDEX:
+    if (radeon_output->type == OUTPUT_LVDS)
 	index = GetIndexIntoMasterTable(COMMAND, LVDSEncoderControl);
-	break;
-    case ATOM_DEVICE_DFP3_INDEX:
-	index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
-	break;
-    default:
-	return ATOM_NOT_IMPLEMENTED;
-	break;
+    else {
+	if (radeon_output->TMDSType == TMDS_LVTMA)
+	    index = GetIndexIntoMasterTable(COMMAND, TMDS2EncoderControl);
+	else
+	    index = GetIndexIntoMasterTable(COMMAND, TMDS1EncoderControl);
     }
 
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
@@ -306,7 +300,7 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m
 	    if (radeon_output->type == OUTPUT_HDMI)
 		disp_data.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
 	    disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
-	    if (device == ATOM_DEVICE_LCD1_INDEX) {
+	    if (radeon_output->MonType == MT_LCD) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 1))
@@ -338,7 +332,7 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m
 	    disp_data2.ucSpatial = 0;
 	    disp_data2.ucTemporal = 0;
 	    disp_data2.ucFRC = 0;
-	    if (device == ATOM_DEVICE_LCD1_INDEX) {
+	    if (radeon_output->type == OUTPUT_LVDS) {
 		if (radeon_output->lvds_misc & (1 << 0))
 		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (radeon_output->lvds_misc & (1 << 5)) {
@@ -398,7 +392,7 @@ atombios_maybe_hdmi_mode(xf86OutputPtr output)
 }
 
 static int
-atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModePtr mode)
+atombios_output_dig_encoder_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
@@ -420,24 +414,29 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModeP
     disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
 
     if (IS_DCE32_VARIANT) {
-	if (radeon_output->TMDSType == TMDS_UNIPHY)
-	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
-	if (radeon_output->TMDSType == TMDS_UNIPHY1)
-	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
-	if (radeon_output->TMDSType == TMDS_UNIPHY2)
-	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    if (radeon_output->LVDSType == LVDS_UNIPHY)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+	    else if (radeon_output->LVDSType == LVDS_UNIPHY1)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+	    else if (radeon_output->LVDSType == LVDS_UNIPHY2)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+	} else {
+	    if (radeon_output->TMDSType == TMDS_UNIPHY)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER1;
+	    else if (radeon_output->TMDSType == TMDS_UNIPHY1)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER2;
+	    else if (radeon_output->TMDSType == TMDS_UNIPHY2)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3;
+	}
     } else {
-	switch (device) {
-	case ATOM_DEVICE_DFP1_INDEX:
-	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
-	    break;
-	case ATOM_DEVICE_LCD1_INDEX:
-	case ATOM_DEVICE_DFP3_INDEX:
+	if (radeon_output->type == OUTPUT_LVDS)
 	    disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
-	    break;
-	default:
-	    return ATOM_NOT_IMPLEMENTED;
-	    break;
+	else {
+	    if (radeon_output->TMDSType == TMDS_LVTMA)
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
+	    else
+		disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
 	}
     }
 
@@ -481,7 +480,7 @@ union dig_transmitter_control {
 };
 
 static int
-atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayModePtr mode)
+atombios_output_dig_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
@@ -496,19 +495,13 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM
     if (IS_DCE32_VARIANT)
 	index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
     else {
-	switch (device) {
-	case ATOM_DEVICE_DFP1_INDEX:
-	    index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
-	    num = 1;
-	    break;
-	case ATOM_DEVICE_LCD1_INDEX:
-	case ATOM_DEVICE_DFP3_INDEX:
+	if (radeon_output->type == OUTPUT_LVDS)
 	    index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
-	    num = 2;
-	    break;
-	default:
-	    return ATOM_NOT_IMPLEMENTED;
-	    break;
+	else {
+	    if (radeon_output->TMDSType == TMDS_LVTMA)
+		index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+	    else
+		index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
 	}
     }
 
@@ -525,25 +518,45 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM
 	}
 	if (radeon_crtc->crtc_id)
 	    disp_data.v2.acConfig.ucEncoderSel = 1;
-	
-	switch (radeon_output->TMDSType) {
-	case TMDS_UNIPHY:
-	    disp_data.v2.acConfig.ucTransmitterSel = 0;
-	    num = 0;
-	    break;
-	case TMDS_UNIPHY1:
-	    disp_data.v2.acConfig.ucTransmitterSel = 1;
-	    num = 1;
-	    break;
-	case TMDS_UNIPHY2:
-	    disp_data.v2.acConfig.ucTransmitterSel = 2;
-	    num = 2;
-	    break;
-	default:
-	    return ATOM_NOT_IMPLEMENTED;
-	    break;
+
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    switch (radeon_output->LVDSType) {
+	    case LVDS_UNIPHY:
+		disp_data.v2.acConfig.ucTransmitterSel = 0;
+		num = 0;
+		break;
+	    case LVDS_UNIPHY1:
+		disp_data.v2.acConfig.ucTransmitterSel = 1;
+		num = 1;
+		break;
+	    case LVDS_UNIPHY2:
+		disp_data.v2.acConfig.ucTransmitterSel = 2;
+		num = 2;
+		break;
+	    default:
+		return ATOM_NOT_IMPLEMENTED;
+		break;
+	    }
+	} else {
+	    switch (radeon_output->TMDSType) {
+	    case TMDS_UNIPHY:
+		disp_data.v2.acConfig.ucTransmitterSel = 0;
+		num = 0;
+		break;
+	    case TMDS_UNIPHY1:
+		disp_data.v2.acConfig.ucTransmitterSel = 1;
+		num = 1;
+		break;
+	    case TMDS_UNIPHY2:
+		disp_data.v2.acConfig.ucTransmitterSel = 2;
+		num = 2;
+		break;
+	    default:
+		return ATOM_NOT_IMPLEMENTED;
+		break;
+	    }
 	}
-	
+
 	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
 	    if (radeon_output->coherent_mode) {
 		disp_data.v2.acConfig.fCoherentMode = 1;
@@ -554,12 +567,12 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM
     } else {
 	disp_data.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 	disp_data.v1.usPixelClock = cpu_to_le16((mode->Clock) / 10);
-	
+
 	if (radeon_crtc->crtc_id)
 	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
 	else
 	    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
-	
+
 	if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
 	    if (radeon_output->coherent_mode) {
 		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
@@ -567,7 +580,7 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM
 	    } else
 		xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode disabled\n", num);
 	}
-	
+
 	if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
 	    if (mode->Clock > 165000) {
 		disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
@@ -591,15 +604,20 @@ atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayM
 	} else {
 	    if (mode->Clock > 165000)
 		disp_data.v1.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
-				       ATOM_TRANSMITTER_CONFIG_LINKA_B |
-				       ATOM_TRANSMITTER_CONFIG_LANE_0_7);
-	    else
-		disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+					  ATOM_TRANSMITTER_CONFIG_LINKA_B |
+					  ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+	    else {
+		/* XXX */
+		if (radeon_output->linkb)
+		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+		else
+		    disp_data.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+	    }
 	}
     }
 
     radeon_output->transmitter_config = disp_data.v1.ucConfig;
-	
+
     data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
     data.exec.pspace = &disp_data;
@@ -722,7 +740,7 @@ atombios_dig_dpms(xf86OutputPtr output, int mode)
 
     memset(&disp_data, 0, sizeof(disp_data));
 
-    if ((radeon_output->MonType == MT_LCD) ||
+    if ((radeon_output->type == OUTPUT_LVDS) ||
 	(radeon_output->TMDSType == TMDS_LVTMA))
 	block = 2;
     else
@@ -993,53 +1011,10 @@ atombios_output_mode_set(xf86OutputPtr output,
     atombios_set_output_crtc_source(output);
 
     if (radeon_output->MonType == MT_CRT) {
-       if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT ||
-	   radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) {
-	   if (radeon_output->DACType == DAC_PRIMARY)
-	       atombios_output_dac1_setup(output, adjusted_mode);
-	   else if (radeon_output->DACType == DAC_TVDAC)
-	       atombios_output_dac2_setup(output, adjusted_mode);
-       }
-    } else if (radeon_output->MonType == MT_DFP) {
-	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-	    if (IS_DCE3_VARIANT) {
-		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
-		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
-	    } else
-		atombios_output_digital_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-	    if (IS_DCE32_VARIANT) {
-		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode);
-		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP2_INDEX, adjusted_mode);
-	    } else {
-		if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
-		    (info->ChipFamily == CHIP_FAMILY_RS690) ||
-		    (info->ChipFamily == CHIP_FAMILY_RS740))
-		    atombios_output_ddia_setup(output, adjusted_mode);
-		else
-		    atombios_external_tmds_setup(output, adjusted_mode);
-	    }
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-	    if (IS_DCE3_VARIANT) {
-		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
-		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
-	    } else
-		atombios_output_digital_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) {
-	    atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode);
-	    atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP4_INDEX, adjusted_mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) {
-	    atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode);
-	    atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP5_INDEX, adjusted_mode);
-	}
-    } else if (radeon_output->MonType == MT_LCD) {
-	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-	    if (IS_DCE3_VARIANT) {
-		atombios_output_dig_encoder_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
-		atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
-	    } else
-		atombios_output_digital_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
-	}
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    atombios_output_dac1_setup(output, adjusted_mode);
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    atombios_output_dac2_setup(output, adjusted_mode);
     } else if ((radeon_output->MonType == MT_CTV) ||
 	       (radeon_output->MonType == MT_STV) ||
 	       (radeon_output->MonType == MT_CV)) {
@@ -1048,6 +1023,20 @@ atombios_output_mode_set(xf86OutputPtr output,
 	else if (radeon_output->DACType == DAC_TVDAC)
 	    atombios_output_dac2_setup(output, adjusted_mode);
 	atombios_output_tv1_setup(output, adjusted_mode);
+    } else {
+	if (IS_DCE3_VARIANT) {
+	    atombios_output_dig_encoder_setup(output, adjusted_mode);
+	    atombios_output_dig_transmitter_setup(output, adjusted_mode);
+	} else if ((info->ChipFamily < CHIP_FAMILY_R600) &&
+		   (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)) {
+	    if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
+		(info->ChipFamily == CHIP_FAMILY_RS690) ||
+		(info->ChipFamily == CHIP_FAMILY_RS740))
+		atombios_output_ddia_setup(output, adjusted_mode);
+	    else
+		atombios_external_tmds_setup(output, adjusted_mode);
+	} else
+	    atombios_output_digital_setup(output, adjusted_mode);
     }
     atombios_apply_output_quirks(output);
 }
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 717211e..feebdba 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1666,43 +1666,52 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		    else
 			info->BiosConnector[i].linkb = FALSE;
 
-		    /* dac/tmds type */
-		    if (path->usDeviceTag != ATOM_DEVICE_LCD1_SUPPORT) {
-			switch(enc_obj_id) {
-			case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-			    info->BiosConnector[i].TMDSType = TMDS_INT;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+		    switch(enc_obj_id) {
+		    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+			info->BiosConnector[i].LVDSType = LVDS_INT;
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+			info->BiosConnector[i].TMDSType = TMDS_INT;
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
+			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY;
+			else
 			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
+			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY1;
+			else
 			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY1;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
+			    info->BiosConnector[i].LVDSType = LVDS_UNIPHY2;
+			else
 			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY2;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-			    info->BiosConnector[i].TMDSType = TMDS_EXT;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
+		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+			info->BiosConnector[i].TMDSType = TMDS_EXT;
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
+			    info->BiosConnector[i].LVDSType = LVDS_LVTMA;
+			else
 			    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-			    info->BiosConnector[i].DACType = DAC_PRIMARY;
-			    break;
-			case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-			    info->BiosConnector[i].DACType = DAC_TVDAC;
-			    break;
-			}
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+			info->BiosConnector[i].DACType = DAC_PRIMARY;
+			break;
+		    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+		    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+			info->BiosConnector[i].DACType = DAC_TVDAC;
+			break;
 		    }
-		    break;
 		}
 	    }
 
@@ -2063,6 +2072,14 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	else
 	    info->BiosConnector[i].TMDSType = TMDS_NONE;
 
+	if (i == ATOM_DEVICE_LCD1_INDEX) {
+	    if (IS_AVIVO_VARIANT)
+		info->BiosConnector[i].LVDSType = LVDS_LVTMA;
+	    else
+		info->BiosConnector[i].LVDSType = LVDS_INT;
+	} else
+	    info->BiosConnector[i].LVDSType = LVDS_NONE;
+
 	/* Always set the connector type to VGA for CRT1/CRT2. if they are
 	 * shared with a DVI port, we'll pick up the DVI connector below when we
 	 * merge the outputs
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 37954d3..badcb01 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -632,6 +632,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[4].DACType = DAC_NONE;
 	    info->BiosConnector[4].TMDSType = TMDS_NONE;
+	    info->BiosConnector[4].LVDSType = LVDS_INT;
 	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
 	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 4aa99d6..c5c6f5c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -48,18 +48,6 @@
 #include "radeon_tv.h"
 #include "radeon_atombios.h"
 
-const char *MonTypeName[10] = {
-  "AUTO",
-  "NONE",
-  "CRT",
-  "LVDS",
-  "TMDS",
-  "CTV",
-  "STV",
-  "CV",
-  "HDMI",
-  "DP"
-};
 
 const RADEONMonitorType MonTypeID[10] = {
   MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
@@ -74,13 +62,24 @@ const RADEONMonitorType MonTypeID[10] = {
   MT_DP
 };
 
-const char *TMDSTypeName[6] = {
+const char *TMDSTypeName[8] = {
   "None",
   "Internal",
   "External",
   "LVTMA",
   "DDIA",
   "UNIPHY"
+  "UNIPHY1"
+  "UNIPHY2"
+};
+
+const char *LVDSTypeName[6] = {
+  "None",
+  "Internal",
+  "LVTMA",
+  "UNIPHY"
+  "UNIPHY1"
+  "UNIPHY2"
 };
 
 const char *DACTypeName[4] = {
@@ -201,12 +200,12 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 	radeon_output = output->driver_private;
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- 0x%x\n", 
+		   "Port%d:\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n LVDS Type -- %s\n DDC Type  -- 0x%x\n", 
 		   o,
-		   MonTypeName[radeon_output->MonType+1],
 		   ConnectorTypeName[radeon_output->ConnectorType],
 		   DACTypeName[radeon_output->DACType],
 		   TMDSTypeName[radeon_output->TMDSType],
+		   LVDSTypeName[radeon_output->LVDSType],
 		   (unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
     }
 
@@ -2860,6 +2859,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->load_detection = info->BiosConnector[i].load_detection;
 	    radeon_output->linkb = info->BiosConnector[i].linkb;
 
+	    radeon_output->LVDSType = info->BiosConnector[i].LVDSType;
+
 	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
 		radeon_output->DACType = DAC_NONE;
 	    else
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 1886b4e..9cde274 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -109,6 +109,16 @@ typedef enum
 
 typedef enum
 {
+    LVDS_NONE    = 0,
+    LVDS_INT     = 1,
+    LVDS_LVTMA   = 2,
+    LVDS_UNIPHY  = 3,
+    LVDS_UNIPHY1 = 4,
+    LVDS_UNIPHY2 = 5
+} RADEONLvdsType;
+
+typedef enum
+{
     DVI_AUTO,
     DVI_DIGITAL,
     DVI_ANALOG
@@ -200,6 +210,7 @@ typedef struct _RADEONCrtcPrivateRec {
 typedef struct {
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
+    RADEONLvdsType LVDSType;
     RADEONConnectorType ConnectorType;
     Bool valid;
     int output_id;
@@ -222,6 +233,7 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONDacType DACType;
     RADEONDviType DVIType;
     RADEONTmdsType TMDSType;
+    RADEONLvdsType LVDSType;
     RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
     int crtc_num;
commit 9bb6b8ceaf772e1ce63610812a12260ee3860c27
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 6 16:25:26 2009 -0500

    ATOM: refactor output dpms

diff --git a/src/atombios_output.c b/src/atombios_output.c
index e4e0604..8a84e6b 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -690,91 +690,44 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static AtomBiosResult
-atombios_display_device_control(atomBiosHandlePtr atomBIOS, int device, Bool state)
+atombios_display_device_control(atomBiosHandlePtr atomBIOS, int index, Bool state)
 {
     DISPLAY_DEVICE_OUTPUT_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
 
     disp_data.ucAction = state;
-    data.exec.index = device;
+    data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
     data.exec.pspace = &disp_data;
 
     if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
-	ErrorF("Output %d %s success\n", device, state? "enable":"disable");
+	ErrorF("Output %d %s success\n", index, state? "enable":"disable");
 	return ATOM_SUCCESS;
     }
 
-    ErrorF("Output %d %s failed\n", device, state? "enable":"disable");
+    ErrorF("Output %d %s failed\n", index, state? "enable":"disable");
     return ATOM_NOT_IMPLEMENTED;
 }
 
-static void
-atombios_device_dpms(xf86OutputPtr output, int device, int mode)
-{
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONInfoPtr info       = RADEONPTR(output->scrn);
-    int index = 0;
-
-    switch (device) {
-    case ATOM_DEVICE_CRT1_SUPPORT:
-    case ATOM_DEVICE_CRT2_SUPPORT:
-	if (radeon_output->DACType == DAC_PRIMARY)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
-	else if (radeon_output->DACType == DAC_TVDAC)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
-	break;
-    case ATOM_DEVICE_DFP1_SUPPORT:
-	index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
-	break;
-    case ATOM_DEVICE_DFP2_SUPPORT:
-	index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
-	break;
-    case ATOM_DEVICE_DFP3_SUPPORT:
-	index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
-	break;
-    case ATOM_DEVICE_LCD1_SUPPORT:
-	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
-	break;
-    case ATOM_DEVICE_TV1_SUPPORT:
-	if (IS_DCE3_VARIANT)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
-	else
-	    index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
-	break;
-    case ATOM_DEVICE_CV_SUPPORT:
-	if (IS_DCE3_VARIANT)
-	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
-	else
-	    index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
-	break;
-    default:
-	return;
-    }
-
-    switch (mode) {
-    case DPMSModeOn:
-	atombios_display_device_control(info->atomBIOS, index, ATOM_ENABLE);
-	break;
-    case DPMSModeStandby:
-    case DPMSModeSuspend:
-    case DPMSModeOff:
-	atombios_display_device_control(info->atomBIOS, index, ATOM_DISABLE);
-	break;
-    }
-}
-
 static int
-atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block)
+atombios_dig_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
     AtomBiosArgRec data;
     unsigned char *space;
+    int block;
 
     memset(&disp_data, 0, sizeof(disp_data));
+
+    if ((radeon_output->MonType == MT_LCD) ||
+	(radeon_output->TMDSType == TMDS_LVTMA))
+	block = 2;
+    else
+	block = 1;
+
     switch (mode) {
     case DPMSModeOn:
 	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT;
@@ -790,8 +743,7 @@ atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block)
 
     if (IS_DCE32_VARIANT) {
 	data.exec.index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
-    }
-    else {
+    } else {
 	if (block == 1)
 	    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
 	else
@@ -810,61 +762,76 @@ atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block)
 
 }
 
-void
-atombios_output_dpms(xf86OutputPtr output, int mode)
+static void
+atombios_device_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    int index = 0;
 
-    /*ErrorF("output dpms %d\n", mode);*/
-
-    if (radeon_output->MonType == MT_LCD) {
-	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-	    if (IS_DCE3_VARIANT)
-		atombios_output_dig_dpms(output, mode, 2);
-	    else
-		atombios_device_dpms(output, ATOM_DEVICE_LCD1_SUPPORT, mode);
-	}
+    if (radeon_output->MonType == MT_CRT) {
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl);
+	else if (radeon_output->DACType == DAC_TVDAC)
+	    index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl);
+	else
+	    return;
     } else if (radeon_output->MonType == MT_DFP) {
-	/*ErrorF("tmds dpms\n");*/
-	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-	    if (IS_DCE3_VARIANT)
-		atombios_output_dig_dpms(output, mode, 1);
-	    else
-		atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-	    if (IS_DCE32_VARIANT)
-		atombios_output_dig_dpms(output, mode, 2);
-	    else if (IS_DCE3_VARIANT)
-		return; // fixme
-	    else
-		atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-	    if (IS_DCE3_VARIANT)
-		atombios_output_dig_dpms(output, mode, 0);
-	    else
-		atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP4_SUPPORT) {
-	    atombios_output_dig_dpms(output, mode, 1);
-	} else if (radeon_output->devices & ATOM_DEVICE_DFP5_SUPPORT) {
-	    atombios_output_dig_dpms(output, mode, 2);
+	switch (radeon_output->TMDSType) {
+	case TMDS_INT:
+	    index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl);
+	    break;
+	case TMDS_EXT:
+	case TMDS_DDIA:
+	    index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl);
+	    break;
+	case TMDS_LVTMA:
+	    index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl);
+	    break;
+	default:
+	    return;
 	}
-    } else if (radeon_output->MonType == MT_CRT) {
-	/*ErrorF("AGD: dac dpms\n");*/
-	if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
-	    atombios_device_dpms(output, ATOM_DEVICE_CRT1_SUPPORT, mode);
-	else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
-	    atombios_device_dpms(output, ATOM_DEVICE_CRT2_SUPPORT, mode);
-    } else if (radeon_output->MonType == MT_CV) {
-	/*ErrorF("AGD: cv dpms\n");*/
-	if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
-	    atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode);
+    } else if (radeon_output->MonType == MT_LCD) {
+	index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl);
     } else if (radeon_output->MonType == MT_STV ||
-	       radeon_output->MonType == MT_CTV) {
-	/*ErrorF("AGD: tv dpms\n");*/
-	if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
-	    atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode);
+               radeon_output->MonType == MT_CTV) {
+	index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl);
+    } else if (radeon_output->MonType == MT_CV) {
+	index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl);
+    } else
+	return;
+
+    switch (mode) {
+    case DPMSModeOn:
+	atombios_display_device_control(info->atomBIOS, index, ATOM_ENABLE);
+	break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+	atombios_display_device_control(info->atomBIOS, index, ATOM_DISABLE);
+	break;
     }
+}
+
+void
+atombios_output_dpms(xf86OutputPtr output, int mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+
+    /*ErrorF("output dpms %d\n", mode);*/
+    if (IS_DCE3_VARIANT) {
+	if (radeon_output->MonType == MT_LCD)
+	    atombios_dig_dpms(output, mode);
+	else if (radeon_output->MonType == MT_DFP) {
+	    if (radeon_output->TMDSType >= TMDS_LVTMA)
+		atombios_dig_dpms(output, mode);
+	    else
+		atombios_device_dpms(output, mode);
+	} else
+	    atombios_device_dpms(output, mode);
+    } else
+	atombios_device_dpms(output, mode);
 
 }
 
commit 467995d960bdefb1911eabfc2a047cf816013101
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 6 15:18:41 2009 -0500

    ATOM: Adjust PLL setup for recent atom changes

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 9a8594a..ada87f6 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -304,12 +304,29 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
 		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2;
 		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CRT;
 	    } else if (radeon_output->MonType == MT_DFP) {
-		if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
+		switch (radeon_output->TMDSType) {
+		case TMDS_INT:
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1;
+		    break;
+		case TMDS_EXT:
 		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
-		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+		    break;
+		case TMDS_LVTMA:
 		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+		    break;
+		case TMDS_UNIPHY:
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY;
+		    break;
+		case TMDS_UNIPHY1:
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY1;
+		    break;
+		case TMDS_UNIPHY2:
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_UNIPHY2;
+		    break;
+		default:
+		    ErrorF("Unknown TMDS type: %d!\n", radeon_output->TMDSType);
+		    exit(-1);
+		}
 		if (OUTPUT_IS_DVI)
 		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DVI;
 		else if (radeon_output->type == OUTPUT_HDMI)
@@ -317,8 +334,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags)
 		else if (radeon_output->type == OUTPUT_DP)
 		    spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_DP;
 	    } else if (radeon_output->MonType == MT_LCD) {
-		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+		spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
 		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
 	    } else if (OUTPUT_IS_TV) {
 		if (radeon_output->DACType == DAC_PRIMARY)
commit ee6310174c44809c761dbdb423e56e61392a0e10
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 6 14:59:22 2009 -0500

    ATOM: handle cases where TMDS uses linkb
    
    fixes bug 18564

diff --git a/src/atombios_output.c b/src/atombios_output.c
index eb52f5c..e4e0604 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -312,6 +312,8 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m
 		if (radeon_output->lvds_misc & (1 << 1))
 		    disp_data.ucMisc |= (1 << 1);
 	    } else {
+		if (radeon_output->linkb)
+		    disp_data.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
 		if (mode->Clock > 165000)
 		    disp_data.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 		if (pScrn->rgbBits == 8)
@@ -352,6 +354,8 @@ atombios_output_digital_setup(xf86OutputPtr output, int device, DisplayModePtr m
 			disp_data2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4;
 		}
 	    } else {
+		if (radeon_output->linkb)
+		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
 		if (mode->Clock > 165000)
 		    disp_data2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
 	    }
@@ -441,7 +445,10 @@ atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModeP
 	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
 	disp_data.ucLaneNum = 8;
     } else {
-	disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
+	if (radeon_output->linkb)
+	    disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKB;
+	else
+	    disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
 	disp_data.ucLaneNum = 4;
     }
 
commit 690999b682c0f954e27d9f1b3a3d8db4ef865c21
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Jan 6 14:55:49 2009 -0500

    ATOM: rework object table parsing

diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 1ca9f86..717211e 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1562,7 +1562,7 @@ static void RADEONApplyATOMQuirks(ScrnInfoPtr pScrn, int index)
 	}
     }
 
-    /* BIOSes seem to report DAC on HDMI - they hurt me with their lies */
+    /* some BIOSes seem to report DAC on HDMI - they hurt me with their lies */
     if ((info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_A) ||
     	(info->BiosConnector[index].ConnectorType == CONNECTOR_HDMI_TYPE_B)) {
 	info->BiosConnector[index].DACType = DAC_NONE;
@@ -1577,8 +1577,9 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     unsigned short size;
     atomDataTablesPtr atomDataPtr;
     ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
+    ATOM_DISPLAY_OBJECT_PATH_TABLE *path_obj;
     ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL;
-    int i, j;
+    int i, j, path_size, device_support;
     Bool enable_tv = FALSE;
 
     if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE))
@@ -1591,185 +1592,158 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     if (crev < 2)
 	return FALSE;
 
+    path_obj = (ATOM_DISPLAY_OBJECT_PATH_TABLE *)
+	((char *)&atomDataPtr->Object_Header->sHeader +
+	 le16_to_cpu(atomDataPtr->Object_Header->usDisplayPathTableOffset));
     con_obj = (ATOM_CONNECTOR_OBJECT_TABLE *)
 	((char *)&atomDataPtr->Object_Header->sHeader +
 	 le16_to_cpu(atomDataPtr->Object_Header->usConnectorObjectTableOffset));
-
-    for (i = 0; i < con_obj->ucNumberOfObjects; i++) {
-	ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *SrcDstTable;
-	ATOM_COMMON_RECORD_HEADER *Record;
-	uint8_t obj_id, num, obj_type;
-	int record_base;
-	uint16_t con_obj_id = le16_to_cpu(con_obj->asObjects[i].usObjectID);
-
-	obj_id = (con_obj_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-	num = (con_obj_id & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
-	obj_type = (con_obj_id & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
-	if (obj_type != GRAPH_OBJECT_TYPE_CONNECTOR)
-	    continue;
-
-	SrcDstTable = (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *)
-	    ((char *)&atomDataPtr->Object_Header->sHeader
-	     + le16_to_cpu(con_obj->asObjects[i].usSrcDstTableOffset));
-
-	ErrorF("object id %04x %02x\n", obj_id, SrcDstTable->ucNumberOfSrc);
-
-	if ((info->ChipFamily == CHIP_FAMILY_RS780) &&
-	    (obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
-	    uint32_t slot_config, ct;
-
-	    igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2;
-
-	    if (!igp_obj)
-		info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
-	    else {
-		if (num == 1)
-		    slot_config = igp_obj->ulDDISlot1Config;
-		else
-		    slot_config = igp_obj->ulDDISlot2Config;
-
-		ct = (slot_config  >> 16) & 0xff;
-		info->BiosConnector[i].ConnectorType = object_connector_convert[ct];
-		info->BiosConnector[i].igp_lane_info = slot_config & 0xffff;
+    device_support = le16_to_cpu(atomDataPtr->Object_Header->usDeviceSupport);
+
+    path_size = 0;
+    for (i = 0; i < path_obj->ucNumOfDispPath; i++) {
+	uint8_t *addr = (uint8_t *)path_obj->asDispPath;
+	ATOM_DISPLAY_OBJECT_PATH *path;
+	addr += path_size;
+	path = (ATOM_DISPLAY_OBJECT_PATH *)addr;
+	path_size += path->usSize;
+
+	if (device_support & path->usDeviceTag) {
+	    uint8_t con_obj_id, con_obj_num, con_obj_type;
+
+	    con_obj_id = (path->usConnObjectId & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+	    con_obj_num = (path->usConnObjectId & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+	    con_obj_type = (path->usConnObjectId & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+
+	    if ((path->usDeviceTag == ATOM_DEVICE_TV1_SUPPORT) ||
+		(path->usDeviceTag == ATOM_DEVICE_TV2_SUPPORT) ||
+		(path->usDeviceTag == ATOM_DEVICE_CV_SUPPORT)) {
+		if (!enable_tv) {
+		    info->BiosConnector[i].valid = FALSE;
+		    continue;
+		}
 	    }
-	} else
-	    info->BiosConnector[i].ConnectorType = object_connector_convert[obj_id];
-
-	if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE)
-	    info->BiosConnector[i].valid = FALSE;
-	else
-	    info->BiosConnector[i].valid = TRUE;
-	info->BiosConnector[i].devices = 0;
 
-	for (j = 0; j < SrcDstTable->ucNumberOfSrc; j++) {
-	    uint8_t sobj_id;
+	    if ((info->ChipFamily == CHIP_FAMILY_RS780) &&
+		(con_obj_id == CONNECTOR_OBJECT_ID_PCIE_CONNECTOR)) {
+		uint32_t slot_config, ct;
 
-	    sobj_id = (le16_to_cpu(SrcDstTable->usSrcObjectID[j]) & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
-	    ErrorF("src object id %04x %d\n", le16_to_cpu(SrcDstTable->usSrcObjectID[j]), sobj_id);
+		igp_obj = info->atomBIOS->atomDataPtr->IntegratedSystemInfo.IntegratedSystemInfo_v2;
 
-	    switch(sobj_id) {
-	    case ENCODER_OBJECT_ID_INTERNAL_LVDS:
-		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
-	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
-		else {
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX);
-		    info->BiosConnector[i].TMDSType = TMDS_INT;
-		}
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
-		else {
-		    if (num == 1)
-			info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP1_INDEX);
-		    else
-			info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX);
-		    info->BiosConnector[i].TMDSType = TMDS_UNIPHY;
-		}
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
+		if (!igp_obj)
+		    info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id];
 		else {
-		    if (num == 1)
-			info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX);
+		    if (con_obj_num == 1)
+			slot_config = igp_obj->ulDDISlot1Config;
 		    else
-			info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP4_INDEX);
-		    info->BiosConnector[i].TMDSType = TMDS_UNIPHY1;
-		}
-		break;
+			slot_config = igp_obj->ulDDISlot2Config;
 
-	    case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
-		else {
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP5_INDEX);
-		    info->BiosConnector[i].TMDSType = TMDS_UNIPHY2;
+		    ct = (slot_config  >> 16) & 0xff;
+		    info->BiosConnector[i].ConnectorType = object_connector_convert[ct];
+		    info->BiosConnector[i].igp_lane_info = slot_config & 0xffff;
 		}
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
-	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-		info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP2_INDEX);
-		info->BiosConnector[i].TMDSType = TMDS_EXT;
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
-	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_LVDS)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_LCD1_INDEX);
-		else {
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_DFP3_INDEX);
-		    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
-		}
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_DAC1:
-	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-    		if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A ||
-	   	    info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B)
-		    break;
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN ||
-		    info->BiosConnector[i].ConnectorType == CONNECTOR_STV ||
-		    info->BiosConnector[i].ConnectorType == CONNECTOR_CTV)
-		    if (enable_tv)
-		    	info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
+	    } else
+		info->BiosConnector[i].ConnectorType = object_connector_convert[con_obj_id];
+
+	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_NONE) {
+		info->BiosConnector[i].valid = FALSE;
+		continue;
+	    } else
+		info->BiosConnector[i].valid = TRUE;
+	    info->BiosConnector[i].devices = path->usDeviceTag;
+	    info->BiosConnector[i].connector_object = path->usConnObjectId;
+
+	    for (j = 0; j < ((path->usSize - 8) / 2); j++) {
+		uint8_t enc_obj_id, enc_obj_num, enc_obj_type;
+
+		enc_obj_id = (path->usGraphicObjIds[j] & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+		enc_obj_num = (path->usGraphicObjIds[j] & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+		enc_obj_type = (path->usGraphicObjIds[j] & OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
+
+		if (enc_obj_type == GRAPH_OBJECT_TYPE_ENCODER) {
+		    if (enc_obj_num == 2)
+			info->BiosConnector[i].linkb = TRUE;
 		    else
-		    	info->BiosConnector[i].valid = FALSE;
-		else
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX);
-		info->BiosConnector[i].DACType = DAC_PRIMARY;
-		break;
-	    case ENCODER_OBJECT_ID_INTERNAL_DAC2:
-	    case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-    		if (info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_A ||
-	   	    info->BiosConnector[i].ConnectorType == CONNECTOR_HDMI_TYPE_B)
+			info->BiosConnector[i].linkb = FALSE;
+
+		    /* dac/tmds type */
+		    if (path->usDeviceTag != ATOM_DEVICE_LCD1_SUPPORT) {
+			switch(enc_obj_id) {
+			case ENCODER_OBJECT_ID_INTERNAL_LVDS:
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
+			    info->BiosConnector[i].TMDSType = TMDS_INT;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
+			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
+			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY1;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+			    info->BiosConnector[i].TMDSType = TMDS_UNIPHY2;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_TMDS2:
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
+			    info->BiosConnector[i].TMDSType = TMDS_EXT;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
+			    info->BiosConnector[i].TMDSType = TMDS_LVTMA;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_DAC1:
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
+			    info->BiosConnector[i].DACType = DAC_PRIMARY;
+			    break;
+			case ENCODER_OBJECT_ID_INTERNAL_DAC2:
+			case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
+			    info->BiosConnector[i].DACType = DAC_TVDAC;
+			    break;
+			}
+		    }
 		    break;
-		if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN ||
-		    info->BiosConnector[i].ConnectorType == CONNECTOR_STV ||
-		    info->BiosConnector[i].ConnectorType == CONNECTOR_CTV)
-		    if (enable_tv)
-		        info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
-		    else
-		    	info->BiosConnector[i].valid = FALSE;
-		else
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX);
-		info->BiosConnector[i].DACType = DAC_TVDAC;
-		break;
+		}
 	    }
-	}
-
-	Record = (ATOM_COMMON_RECORD_HEADER *)
-	    ((char *)&atomDataPtr->Object_Header->sHeader
-	     + le16_to_cpu(con_obj->asObjects[i].usRecordOffset));
-
-	record_base = le16_to_cpu(con_obj->asObjects[i].usRecordOffset);
-
-	while (Record->ucRecordType > 0
-	       && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) {
 
-	    ErrorF("record type %d\n", Record->ucRecordType);
-	    switch (Record->ucRecordType) {
-		case ATOM_I2C_RECORD_TYPE:
-		    info->BiosConnector[i].ddc_i2c = rhdAtomParseI2CRecord(pScrn, info->atomBIOS,
-									   (ATOM_I2C_RECORD *)Record, i);
-		    break;
-		case ATOM_HPD_INT_RECORD_TYPE:
-		    break;
-		case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE:
-		    break;
+	    /* look up gpio for ddc */
+	    if ((path->usDeviceTag & (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) == 0) {
+		for (j = 0; j < con_obj->ucNumberOfObjects; j++) {
+		    if (path->usConnObjectId == le16_to_cpu(con_obj->asObjects[j].usObjectID)) {
+			ATOM_COMMON_RECORD_HEADER *Record = (ATOM_COMMON_RECORD_HEADER *)
+			    ((char *)&atomDataPtr->Object_Header->sHeader
+			     + le16_to_cpu(con_obj->asObjects[j].usRecordOffset));
+
+			while (Record->ucRecordType > 0
+			       && Record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER ) {
+
+			    /*ErrorF("record type %d\n", Record->ucRecordType);*/
+			    switch (Record->ucRecordType) {
+			    case ATOM_I2C_RECORD_TYPE:
+				info->BiosConnector[i].ddc_i2c =
+				    rhdAtomParseI2CRecord(pScrn, info->atomBIOS,
+							  (ATOM_I2C_RECORD *)Record, j);
+				break;
+			    case ATOM_HPD_INT_RECORD_TYPE:
+				break;
+			    case ATOM_CONNECTOR_DEVICE_TAG_RECORD_TYPE:
+				break;
+			    }
+
+			    Record = (ATOM_COMMON_RECORD_HEADER*)
+				((char *)Record + Record->ucRecordSize);
+			}
+			break;
+		    }
+		}
 	    }
-
-	    Record = (ATOM_COMMON_RECORD_HEADER*)
-		((char *)Record + Record->ucRecordSize);
 	}
-
 	RADEONApplyATOMQuirks(pScrn, i);
     }
 
     for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
 	if (info->BiosConnector[i].valid) {
+	    /* shared ddc */
 	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
 		if (info->BiosConnector[j].valid && (i != j) ) {
 		    if (info->BiosConnector[i].i2c_line_mux == info->BiosConnector[j].i2c_line_mux) {
@@ -1778,6 +1752,19 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		    }
 		}
 	    }
+	    /* shared connectors */
+	    for (j = 0; j < ATOM_MAX_SUPPORTED_DEVICE; j++) {
+		if (info->BiosConnector[j].valid && (i != j) ) {
+		    if (info->BiosConnector[i].connector_object == info->BiosConnector[j].connector_object) {
+			if (info->BiosConnector[i].devices & (ATOM_DEVICE_CRT_SUPPORT))
+			    info->BiosConnector[i].TMDSType = info->BiosConnector[j].TMDSType;
+			else
+			    info->BiosConnector[i].DACType = info->BiosConnector[j].DACType;
+			info->BiosConnector[i].devices |= info->BiosConnector[j].devices;
+			info->BiosConnector[j].valid = FALSE;
+		    }
+		}
+	    }
 	}
     }
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 5924c81..4aa99d6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2858,6 +2858,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    radeon_output->igp_lane_info = info->BiosConnector[i].igp_lane_info;
 	    radeon_output->shared_ddc = info->BiosConnector[i].shared_ddc;
 	    radeon_output->load_detection = info->BiosConnector[i].load_detection;
+	    radeon_output->linkb = info->BiosConnector[i].linkb;
 
 	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
 		radeon_output->DACType = DAC_NONE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 5cd610c..1886b4e 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -210,6 +210,8 @@ typedef struct {
     Bool shared_ddc;
     int i2c_line_mux;
     Bool load_detection;
+    Bool linkb;
+    uint16_t connector_object;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -264,6 +266,7 @@ typedef struct _RADEONOutputPrivateRec {
     int transmitter_config;
     Bool coherent_mode;
     int igp_lane_info;
+    Bool linkb;
 
     char              *name;
     int               output_id;


More information about the xorg-commit mailing list