xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Wed Mar 5 15:41:14 PST 2008


 src/ati_pciids_gen.h              |   19 +
 src/atombios_crtc.c               |   89 ++++++-
 src/atombios_output.c             |  342 +++++++++++++++++++++++++++--
 src/pcidb/ati_pciids.csv          |   31 ++
 src/radeon.h                      |    7 
 src/radeon_atombios.c             |    9 
 src/radeon_chipinfo_gen.h         |   19 +
 src/radeon_chipset_gen.h          |   31 ++
 src/radeon_commonfuncs.c          |   10 
 src/radeon_driver.c               |  436 +++++++++++++++++++++++++++++---------
 src/radeon_exa_funcs.c            |    2 
 src/radeon_exa_render.c           |    8 
 src/radeon_pci_chipset_gen.h      |   19 +
 src/radeon_pci_device_match_gen.h |   19 +
 src/radeon_probe.h                |   21 +
 src/radeon_textured_videofuncs.c  |    8 
 16 files changed, 902 insertions(+), 168 deletions(-)

New commits:
commit 0ed48f8f651a28e189f9fee8c6b593da0178d21c
Author: Alex Deucher <alex at cube.(none)>
Date:   Wed Mar 5 18:41:01 2008 -0500

    AVIVO: Initial support for DCE 3.0 using atombios
    
    DACs are working well, DIG support (DVI, HDMI, LVDS, etc.)
    still has some issues.

diff --git a/src/ati_pciids_gen.h b/src/ati_pciids_gen.h
index 330d1a9..b6b79c1 100644
--- a/src/ati_pciids_gen.h
+++ b/src/ati_pciids_gen.h
@@ -356,3 +356,22 @@
 #define PCI_CHIP_RV630_958C 0x958C
 #define PCI_CHIP_RV630_958D 0x958D
 #define PCI_CHIP_RV630_958E 0x958E
+#define PCI_CHIP_RV620_95C0 0x95C0
+#define PCI_CHIP_RV620_95C5 0x95C5
+#define PCI_CHIP_RV620_95C7 0x95C7
+#define PCI_CHIP_RV620_95C2 0x95C2
+#define PCI_CHIP_RV620_95C4 0x95C4
+#define PCI_CHIP_RV620_95CD 0x95CD
+#define PCI_CHIP_RV620_95CE 0x95CE
+#define PCI_CHIP_RV620_95CF 0x95CF
+#define PCI_CHIP_RV635_9590 0x9590
+#define PCI_CHIP_RV635_9596 0x9596
+#define PCI_CHIP_RV635_9597 0x9597
+#define PCI_CHIP_RV635_9598 0x9598
+#define PCI_CHIP_RV635_9599 0x9599
+#define PCI_CHIP_RV635_9591 0x9591
+#define PCI_CHIP_RV635_9593 0x9593
+#define PCI_CHIP_RS780_9610 0x9610
+#define PCI_CHIP_RS780_9611 0x9611
+#define PCI_CHIP_RS780_9612 0x9612
+#define PCI_CHIP_RS780_9613 0x9613
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index f7d9c37..8f76e30 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -155,12 +155,19 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 {
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
     unsigned char *RADEONMMIO = info->MMIO;
     int index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
     CARD32 sclock = mode->Clock;
     CARD32 ref_div = 0, fb_div = 0, post_div = 0;
-    int major, minor;
+    int major, minor, i;
     SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
+    PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
+    PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
+
+    xf86OutputPtr output;
+    RADEONOutputPrivatePtr radeon_output = NULL;
+
     void *ptr;
     AtomBiosArgRec data;
     unsigned char *space;
@@ -193,6 +200,20 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	       "crtc(%d) PLL  : refdiv %u, fbdiv 0x%X(%u), pdiv %u\n",
 	       radeon_crtc->crtc_id, (unsigned int)ref_div, (unsigned int)fb_div, (unsigned int)fb_div, (unsigned int)post_div);
 
+    /* Can't really do cloning easily on DCE3 cards */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    radeon_output = output->driver_private;
+	    break;
+	}
+    }
+
+    if (radeon_output == NULL) {
+	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
+	return;
+    }
+
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
     ErrorF("table is %d %d\n", major, minor);
@@ -200,18 +221,66 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
     case 1:
 	switch(minor) {
 	case 1:
-	case 2: {
-	    spc_param.sPCLKInput.usPixelClock = sclock;
-	    spc_param.sPCLKInput.usRefDiv = ref_div;
-	    spc_param.sPCLKInput.usFbDiv = fb_div;
-	    spc_param.sPCLKInput.ucPostDiv = post_div;
-	    spc_param.sPCLKInput.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
-	    spc_param.sPCLKInput.ucCRTC = radeon_crtc->crtc_id;
-	    spc_param.sPCLKInput.ucRefDivSrc = 1;
+	case 2:
+	    spc2_ptr = &spc_param.sPCLKInput;
+	    spc2_ptr->usPixelClock = sclock;
+	    spc2_ptr->usRefDiv = ref_div;
+	    spc2_ptr->usFbDiv = fb_div;
+	    spc2_ptr->ucPostDiv = post_div;
+	    spc2_ptr->ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
+	    spc2_ptr->ucCRTC = radeon_crtc->crtc_id;
+	    spc2_ptr->ucRefDivSrc = 1;
+	    ptr = &spc_param;
+	    break;
+	case 3:
+	    spc3_ptr = &spc_param.sPCLKInput;
+
+	    spc3_ptr->usPixelClock = sclock;
+	    spc3_ptr->usRefDiv = ref_div;
+	    spc3_ptr->usFbDiv = fb_div;
+	    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) {
+		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)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1;
+		else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
+		    spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA;
+		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) {
+		if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
+		    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;
+		spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_TV;
+	    } 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->ucEncoderMode = ATOM_ENCODER_MODE_CV;
+	    }
 
 	    ptr = &spc_param;
 	    break;
-	}
 	default:
 	    ErrorF("Unknown table version\n");
 	    exit(-1);
diff --git a/src/atombios_output.c b/src/atombios_output.c
index da3f533..81740a8 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -235,7 +235,7 @@ atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static int
-atombios_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_ddia_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DVO_ENCODER_CONTROL_PS_ALLOCATION disp_data;
@@ -346,6 +346,165 @@ atombios_output_lvds_setup(xf86OutputPtr output, DisplayModePtr mode)
 }
 
 static int
+atombios_output_dig1_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    disp_data.usPixelClock = mode->Clock / 10;
+    if (mode->Clock > 165000) {
+	disp_data.ucConfig = ATOM_ENCODER_CONFIG_LINKA_B | ATOM_ENCODER_CONFIG_TRANSMITTER1;
+	disp_data.ucLaneNum = 8;
+    } else {
+	disp_data.ucConfig = ATOM_ENCODER_CONFIG_LINKA | ATOM_ENCODER_CONFIG_TRANSMITTER1;
+	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 = ATOM_ENCODER_MODE_HDMI;
+    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;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG1 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG1 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig1_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
+    disp_data.usPixelClock = mode->Clock / 10;
+    // not sure on clk src...
+    disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
+    if (mode->Clock > 165000)
+	disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+			       ATOM_TRANSMITTER_CONFIG_LINKA_B |
+			       ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+    else
+	disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+
+    radeon_output->transmitter_config = disp_data.ucConfig;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG1 transmitter setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG1 transmitter setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig2_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = 1;
+    disp_data.usPixelClock = mode->Clock / 10;
+    if (mode->Clock > 165000) {
+	disp_data.ucConfig = ATOM_ENCODER_CONFIG_LINKA_B | ATOM_ENCODER_CONFIG_TRANSMITTER2;
+	disp_data.ucLaneNum = 8;
+    } else {
+	disp_data.ucConfig = ATOM_ENCODER_CONFIG_LINKA | ATOM_ENCODER_CONFIG_TRANSMITTER2;
+	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 = ATOM_ENCODER_MODE_HDMI;
+    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;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	ErrorF("Output DIG2 setup success\n");
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG2 setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
+atombios_output_dig2_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    disp_data.ucAction = ATOM_TRANSMITTER_ACTION_SETUP;
+    disp_data.usPixelClock = mode->Clock / 10;
+    // not sure on clk src...
+    disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
+    if (mode->Clock > 165000)
+	disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
+			       ATOM_TRANSMITTER_CONFIG_LINKA_B |
+			       ATOM_TRANSMITTER_CONFIG_LANE_0_7);
+    else
+	disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA | ATOM_TRANSMITTER_CONFIG_LANE_0_3;
+
+    radeon_output->transmitter_config = disp_data.ucConfig;
+
+    data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+    data.exec.dataSpace = (void *)&space;
+    data.exec.pspace = &disp_data;
+
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
+	if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	    ErrorF("Output DIG2 transmitter setup success\n");
+	    return ATOM_SUCCESS;
+	}
+    }
+
+    ErrorF("Output DIG2 transmitter setup failed\n");
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
+static int
 atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode)
 {
     RADEONInfoPtr info       = RADEONPTR(output->scrn);
@@ -393,7 +552,8 @@ dfp_disable_dither(xf86OutputPtr output, int device)
 	OUTREG(AVIVO_TMDSA_BIT_DEPTH_CONTROL, 0); /* TMDSA */
 	break;
     case ATOM_DEVICE_DFP2_SUPPORT:
-	if (info->ChipFamily == CHIP_FAMILY_RS690)
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740))
 	    OUTREG(AVIVO_DDIA_BIT_DEPTH_CONTROL, 0); /* DDIA */
 	else
 	    OUTREG(AVIVO_DVOA_BIT_DEPTH_CONTROL, 0); /* DVO */
@@ -478,24 +638,83 @@ atombios_device_dpms(xf86OutputPtr output, int device, int mode)
     }
 }
 
+static int
+atombios_output_dig_dpms(xf86OutputPtr output, int mode, int block)
+{
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
+    DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
+    AtomBiosArgRec data;
+    unsigned char *space;
+
+    /* this tends to cause problems
+     * just turning off the crtc seems to be adequte for now
+     */
+    return ATOM_NOT_IMPLEMENTED;
+
+    switch (mode) {
+    case DPMSModeOn:
+	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT;
+	break;
+    case DPMSModeStandby:
+    case DPMSModeSuspend:
+    case DPMSModeOff:
+	disp_data.ucAction = ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT;
+	break;
+    }
+
+    disp_data.ucConfig = radeon_output->transmitter_config;
+
+    if (block == 1)
+	data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+    else
+	data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+    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);
+	return ATOM_SUCCESS;
+    }
+
+    ErrorF("Output DIG%d dpms failed\n", block);
+    return ATOM_NOT_IMPLEMENTED;
+
+}
+
 void
 atombios_output_dpms(xf86OutputPtr output, int mode)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
 
     ErrorF("AGD: output dpms %d\n", mode);
 
    if (radeon_output->MonType == MT_LCD) {
-       if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_LCD1_SUPPORT, mode);
+       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);
+       }
    } else if (radeon_output->MonType == MT_DFP) {
        ErrorF("AGD: tmds dpms\n");
-       if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP1_SUPPORT, mode);
-       else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP2_SUPPORT, mode);
-       else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT)
-	   atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode);
+       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_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, 2);
+	   else
+	       atombios_device_dpms(output, ATOM_DEVICE_DFP3_SUPPORT, mode);
+       }
    } else if (radeon_output->MonType == MT_CRT) {
        ErrorF("AGD: dac dpms\n");
        if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
@@ -506,8 +725,8 @@ atombios_output_dpms(xf86OutputPtr output, int mode)
        ErrorF("AGD: cv dpms\n");
        if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
 	   atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode);
-   } else if (0 /*radeon_output->MonType == MT_STV ||
-		  radeon_output->MonType == MT_CTV*/) {
+   } 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);
@@ -524,6 +743,7 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
     AtomBiosArgRec data;
     unsigned char *space;
     SELECT_CRTC_SOURCE_PS_ALLOCATION crtc_src_param;
+    SELECT_CRTC_SOURCE_PARAMETERS_V2 crtc_src_param2;
     int index = GetIndexIntoMasterTable(COMMAND, SelectCRTC_Source);
     int major, minor;
 
@@ -531,15 +751,14 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 
     ErrorF("select crtc source table is %d %d\n", major, minor);
 
-    crtc_src_param.ucCRTC = radeon_crtc->crtc_id;
-    crtc_src_param.ucDevice = 0;
-
     switch(major) {
     case 1: {
 	switch(minor) {
 	case 0:
 	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;
@@ -562,6 +781,46 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 		if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT)
 		    crtc_src_param.ucDevice = ATOM_DEVICE_CV_INDEX;
 	    }
+	    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) {
+		if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_CRT1_INDEX;
+		else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_CRT2_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+	    } else if (radeon_output->MonType == MT_DFP) {
+		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 = ATOM_ENCODER_MODE_HDMI;
+		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;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+	    } else if (OUTPUT_IS_TV) {
+		if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT)
+		    crtc_src_param2.ucEncoderID = ATOM_DEVICE_TV1_INDEX;
+		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.ucEncoderID = ATOM_DEVICE_CV_INDEX;
+		crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV;
+	    }
+
+	    data.exec.pspace = &crtc_src_param2;
+	    ErrorF("device sourced: 0x%x\n", crtc_src_param2.ucEncoderID);
 	    break;
 	}
 	break;
@@ -570,11 +829,8 @@ atombios_set_output_crtc_source(xf86OutputPtr output)
 	break;
     }
 
-    ErrorF("device sourced: 0x%x\n", crtc_src_param.ucDevice);
-
     data.exec.index = index;
     data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &crtc_src_param;
 
     if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
 	ErrorF("Set CRTC %d Source success\n", radeon_crtc->crtc_id);
@@ -606,22 +862,42 @@ atombios_output_mode_set(xf86OutputPtr output,
        }
     } else if (radeon_output->MonType == MT_DFP) {
 	if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
-	    atombios_output_tmds1_setup(output, adjusted_mode);
-	    dfp_disable_dither(output, ATOM_DEVICE_DFP1_SUPPORT);
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig1_setup(output, adjusted_mode);
+		atombios_output_dig1_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_tmds1_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP1_SUPPORT);
+	    }
 	} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
-	    if (info->ChipFamily == CHIP_FAMILY_RS690)
-		atombios_ddia_setup(output, adjusted_mode);
-	    else
-		atombios_external_tmds_setup(output, adjusted_mode);
-	    dfp_disable_dither(output, ATOM_DEVICE_DFP2_SUPPORT);
+	    if (IS_DCE3_VARIANT) {
+		// fix me
+	    } else {
+		if ((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);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP2_SUPPORT);
+	    }
 	} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
-	    atombios_output_tmds2_setup(output, adjusted_mode);
-	    dfp_disable_dither(output, ATOM_DEVICE_DFP3_SUPPORT);
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig2_setup(output, adjusted_mode);
+		atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_tmds2_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_DFP3_SUPPORT);
+	    }
 	}
     } else if (radeon_output->MonType == MT_LCD) {
 	if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
-	    atombios_output_lvds_setup(output, adjusted_mode);
-	    dfp_disable_dither(output, ATOM_DEVICE_LCD1_SUPPORT);
+	    if (IS_DCE3_VARIANT) {
+		atombios_output_dig2_setup(output, adjusted_mode);
+		atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+	    } else {
+		atombios_output_lvds_setup(output, adjusted_mode);
+		dfp_disable_dither(output, ATOM_DEVICE_LCD1_SUPPORT);
+	    }
 	}
     } else if ((radeon_output->MonType == MT_CTV) ||
 	       (radeon_output->MonType == MT_STV) ||
@@ -639,10 +915,13 @@ static AtomBiosResult
 atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr info       = RADEONPTR(output->scrn);
     DAC_LOAD_DETECTION_PS_ALLOCATION dac_data;
     AtomBiosArgRec data;
     unsigned char *space;
 
+    dac_data.sDacload.ucMisc = 0;
+
     if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) {
 	dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT1_SUPPORT;
 	if (radeon_output->DACType == DAC_PRIMARY)
@@ -661,18 +940,21 @@ atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output)
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
 	else if (radeon_output->DACType == DAC_TVDAC)
 	    dac_data.sDacload.ucDacType = ATOM_DAC_B;
+	if (IS_DCE3_VARIANT)
+	    dac_data.sDacload.ucMisc = 1;
     } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) {
 	dac_data.sDacload.usDeviceID = ATOM_DEVICE_TV1_SUPPORT;
 	if (radeon_output->DACType == DAC_PRIMARY)
 	    dac_data.sDacload.ucDacType = ATOM_DAC_A;
 	else if (radeon_output->DACType == DAC_TVDAC)
 	    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;
     }
 
-    dac_data.sDacload.ucMisc = 0;
 
     data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection);
     data.exec.dataSpace = (void *)&space;
diff --git a/src/pcidb/ati_pciids.csv b/src/pcidb/ati_pciids.csv
index 5a2191a..8851e60 100644
--- a/src/pcidb/ati_pciids.csv
+++ b/src/pcidb/ati_pciids.csv
@@ -331,13 +331,13 @@
 "0x94C0","RV610_94C0","RV610",,,,,,"ATI RV610"
 "0x94C1","RV610_94C1","RV610",,,,,,"ATI Radeon HD 2400 XT"
 "0x94C3","RV610_94C3","RV610",,,,,,"ATI Radeon HD 2400 Pro"
-"0x94C4","RV610_94C4","RV610",,,,,,"ATI ATI Radeon HD 2400 PRO AGP"
+"0x94C4","RV610_94C4","RV610",,,,,,"ATI Radeon HD 2400 PRO AGP"
 "0x94C5","RV610_94C5","RV610",,,,,,"ATI FireGL V4000"
 "0x94C6","RV610_94C6","RV610",,,,,,"ATI RV610"
 "0x94C7","RV610_94C7","RV610",,,,,,"ATI ATI Radeon HD 2350"
 "0x94C8","RV610_94C8","RV610",1,,,,,"ATI Mobility Radeon HD 2400 XT"
 "0x94C9","RV610_94C9","RV610",1,,,,,"ATI Mobility Radeon HD 2400"
-"0x94CB","RV610_94CB","RV610",1,,,,,"ATI ATI RADEON E2400"
+"0x94CB","RV610_94CB","RV610",1,,,,,"ATI RADEON E2400"
 "0x94CC","RV610_94CC","RV610",,,,,,"ATI RV610"
 "0x9500","RV670_9500","RV670",,,,,,"ATI RV670"
 "0x9501","RV670_9501","RV670",,,,,,"ATI Radeon HD3870"
@@ -348,12 +348,31 @@
 "0x9580","RV630_9580","RV630",,,,,,"ATI RV630"
 "0x9581","RV630_9581","RV630",1,,,,,"ATI Mobility Radeon HD 2600"
 "0x9583","RV630_9583","RV630",1,,,,,"ATI Mobility Radeon HD 2600 XT"
-"0x9586","RV630_9586","RV630",,,,,,"ATI ATI Radeon HD 2600 XT AGP"
-"0x9587","RV630_9587","RV630",,,,,,"ATI ATI Radeon HD 2600 Pro AGP"
+"0x9586","RV630_9586","RV630",,,,,,"ATI Radeon HD 2600 XT AGP"
+"0x9587","RV630_9587","RV630",,,,,,"ATI Radeon HD 2600 Pro AGP"
 "0x9588","RV630_9588","RV630",,,,,,"ATI Radeon HD 2600 XT"
 "0x9589","RV630_9589","RV630",,,,,,"ATI Radeon HD 2600 Pro"
 "0x958A","RV630_958A","RV630",,,,,,"ATI Gemini RV630"
-"0x958B","RV630_958B","RV630",1,,,,,"ATI Gemini ATI Mobility Radeon HD 2600 XT"
+"0x958B","RV630_958B","RV630",1,,,,,"ATI Gemini Mobility Radeon HD 2600 XT"
 "0x958C","RV630_958C","RV630",,,,,,"ATI FireGL V5600"
 "0x958D","RV630_958D","RV630",,,,,,"ATI FireGL V3600"
-"0x958E","RV630_958E","RV630",,,,,,"ATI ATI Radeon HD 2600 LE"
+"0x958E","RV630_958E","RV630",,,,,,"ATI Radeon HD 2600 LE"
+"0x95C0","RV620_95C0","RV620",,,,,,"ATI Radeon HD 3470"
+"0x95C5","RV620_95C5","RV620",,,,,,"ATI Radeon HD 3450"
+"0x95C7","RV620_95C7","RV620",,,,,,"ATI Radeon HD 3430"
+"0x95C2","RV620_95C2","RV620",1,,,,,"ATI Mobility Radeon HD 3430"
+"0x95C4","RV620_95C4","RV620",1,,,,,"ATI Mobility Radeon HD 3400 Series"
+"0x95CD","RV620_95CD","RV620",,,,,,"ATI FireMV 2450"
+"0x95CE","RV620_95CE","RV620",,,,,,"ATI FireMV 2260"
+"0x95CF","RV620_95CF","RV620",,,,,,"ATI FireMV 2260"
+"0x9590","RV635_9590","RV635",,,,,,"ATI ATI Radeon HD 3600 Series"
+"0x9596","RV635_9596","RV635",,,,,,"ATI ATI Radeon HD 3650 AGP"
+"0x9597","RV635_9597","RV635",,,,,,"ATI ATI Radeon HD 3600 PRO"
+"0x9598","RV635_9598","RV635",,,,,,"ATI ATI Radeon HD 3600 XT"
+"0x9599","RV635_9599","RV635",,,,,,"ATI ATI Radeon HD 3600 PRO"
+"0x9591","RV635_9591","RV635",1,,,,,"ATI Mobility Radeon HD 3650"
+"0x9593","RV635_9593","RV635",1,,,,,"ATI Mobility Radeon HD 3670"
+"0x9610","RS780_9610","RS780",,1,,,1,"ATI Radeon HD 3200 Graphics"
+"0x9611","RS780_9611","RS780",,1,,,1,"ATI Radeon 3100 Graphics"
+"0x9612","RS780_9612","RS780",,1,,,1,"ATI Radeon HD 3200 Graphics"
+"0x9613","RS780_9613","RS780",,1,,,1,"ATI Radeon 3100 Graphics"
diff --git a/src/radeon.h b/src/radeon.h
index b00d1e2..787a851 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -268,12 +268,15 @@ typedef enum {
     CHIP_FAMILY_RV560,   /* rv560 */
     CHIP_FAMILY_RV570,   /* rv570 */
     CHIP_FAMILY_RS690,
+    CHIP_FAMILY_RS740,
     CHIP_FAMILY_R600,    /* r60 */
     CHIP_FAMILY_R630,
     CHIP_FAMILY_RV610,
     CHIP_FAMILY_RV630,
     CHIP_FAMILY_RV670,
-    CHIP_FAMILY_RS740,
+    CHIP_FAMILY_RV620,
+    CHIP_FAMILY_RV635,
+    CHIP_FAMILY_RS780,
     CHIP_FAMILY_LAST
 } RADEONChipFamily;
 
@@ -296,6 +299,8 @@ typedef enum {
 
 #define IS_AVIVO_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV515))
 
+#define IS_DCE3_VARIANT ((info->ChipFamily >= CHIP_FAMILY_RV620))
+
 /*
  * Errata workarounds
  */
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 1da5e5c..3efe4c9 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1568,7 +1568,8 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN ||
 		    info->BiosConnector[i].ConnectorType == CONNECTOR_STV ||
 		    info->BiosConnector[i].ConnectorType == CONNECTOR_CTV)
-		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
+		    //info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX);
+		    info->BiosConnector[i].valid = FALSE;
 		else
 		    info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX);
 		info->BiosConnector[i].DACType = DAC_TVDAC;
@@ -1754,7 +1755,8 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	    (i == ATOM_DEVICE_TV2_INDEX) ||
 	    (i == ATOM_DEVICE_CV_INDEX))
 	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
-	else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+	else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+		 (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    /* IGP DFP ports use non-standard gpio entries */
 	    if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX))
 		info->BiosConnector[i].ddc_i2c =
@@ -1769,7 +1771,8 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	if (i == ATOM_DEVICE_DFP1_INDEX)
 	    info->BiosConnector[i].TMDSType = TMDS_INT;
 	else if (i == ATOM_DEVICE_DFP2_INDEX) {
-	    if (info->ChipFamily == CHIP_FAMILY_RS690)
+	    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+		(info->ChipFamily == CHIP_FAMILY_RS740))
 		info->BiosConnector[i].TMDSType = TMDS_DDIA;
 	    else
 		info->BiosConnector[i].TMDSType = TMDS_EXT;
diff --git a/src/radeon_chipinfo_gen.h b/src/radeon_chipinfo_gen.h
index 420f5d8..c80802a 100644
--- a/src/radeon_chipinfo_gen.h
+++ b/src/radeon_chipinfo_gen.h
@@ -276,4 +276,23 @@ RADEONCardInfo RADEONCards[] = {
  { 0x958C, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
  { 0x958D, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
  { 0x958E, CHIP_FAMILY_RV630, 0, 0, 0, 0, 0 },
+ { 0x95C0, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C5, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C7, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95C2, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
+ { 0x95C4, CHIP_FAMILY_RV620, 1, 0, 0, 0, 0 },
+ { 0x95CD, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95CE, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x95CF, CHIP_FAMILY_RV620, 0, 0, 0, 0, 0 },
+ { 0x9590, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9596, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9597, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9598, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9599, CHIP_FAMILY_RV635, 0, 0, 0, 0, 0 },
+ { 0x9591, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
+ { 0x9593, CHIP_FAMILY_RV635, 1, 0, 0, 0, 0 },
+ { 0x9610, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9611, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9612, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
+ { 0x9613, CHIP_FAMILY_RS780, 0, 1, 0, 0, 1 },
 };
diff --git a/src/radeon_chipset_gen.h b/src/radeon_chipset_gen.h
index e6890be..61f8da7 100644
--- a/src/radeon_chipset_gen.h
+++ b/src/radeon_chipset_gen.h
@@ -250,13 +250,13 @@ static SymTabRec RADEONChipsets[] = {
   { PCI_CHIP_RV610_94C0, "ATI RV610" },
   { PCI_CHIP_RV610_94C1, "ATI Radeon HD 2400 XT" },
   { PCI_CHIP_RV610_94C3, "ATI Radeon HD 2400 Pro" },
-  { PCI_CHIP_RV610_94C4, "ATI ATI Radeon HD 2400 PRO AGP" },
+  { PCI_CHIP_RV610_94C4, "ATI Radeon HD 2400 PRO AGP" },
   { PCI_CHIP_RV610_94C5, "ATI FireGL V4000" },
   { PCI_CHIP_RV610_94C6, "ATI RV610" },
   { PCI_CHIP_RV610_94C7, "ATI ATI Radeon HD 2350" },
   { PCI_CHIP_RV610_94C8, "ATI Mobility Radeon HD 2400 XT" },
   { PCI_CHIP_RV610_94C9, "ATI Mobility Radeon HD 2400" },
-  { PCI_CHIP_RV610_94CB, "ATI ATI RADEON E2400" },
+  { PCI_CHIP_RV610_94CB, "ATI RADEON E2400" },
   { PCI_CHIP_RV610_94CC, "ATI RV610" },
   { PCI_CHIP_RV670_9500, "ATI RV670" },
   { PCI_CHIP_RV670_9501, "ATI Radeon HD3870" },
@@ -267,14 +267,33 @@ static SymTabRec RADEONChipsets[] = {
   { PCI_CHIP_RV630_9580, "ATI RV630" },
   { PCI_CHIP_RV630_9581, "ATI Mobility Radeon HD 2600" },
   { PCI_CHIP_RV630_9583, "ATI Mobility Radeon HD 2600 XT" },
-  { PCI_CHIP_RV630_9586, "ATI ATI Radeon HD 2600 XT AGP" },
-  { PCI_CHIP_RV630_9587, "ATI ATI Radeon HD 2600 Pro AGP" },
+  { PCI_CHIP_RV630_9586, "ATI Radeon HD 2600 XT AGP" },
+  { PCI_CHIP_RV630_9587, "ATI Radeon HD 2600 Pro AGP" },
   { PCI_CHIP_RV630_9588, "ATI Radeon HD 2600 XT" },
   { PCI_CHIP_RV630_9589, "ATI Radeon HD 2600 Pro" },
   { PCI_CHIP_RV630_958A, "ATI Gemini RV630" },
-  { PCI_CHIP_RV630_958B, "ATI Gemini ATI Mobility Radeon HD 2600 XT" },
+  { PCI_CHIP_RV630_958B, "ATI Gemini Mobility Radeon HD 2600 XT" },
   { PCI_CHIP_RV630_958C, "ATI FireGL V5600" },
   { PCI_CHIP_RV630_958D, "ATI FireGL V3600" },
-  { PCI_CHIP_RV630_958E, "ATI ATI Radeon HD 2600 LE" },
+  { PCI_CHIP_RV630_958E, "ATI Radeon HD 2600 LE" },
+  { PCI_CHIP_RV620_95C0, "ATI Radeon HD 3470" },
+  { PCI_CHIP_RV620_95C5, "ATI Radeon HD 3450" },
+  { PCI_CHIP_RV620_95C7, "ATI Radeon HD 3430" },
+  { PCI_CHIP_RV620_95C2, "ATI Mobility Radeon HD 3430" },
+  { PCI_CHIP_RV620_95C4, "ATI Mobility Radeon HD 3400 Series" },
+  { PCI_CHIP_RV620_95CD, "ATI FireMV 2450" },
+  { PCI_CHIP_RV620_95CE, "ATI FireMV 2260" },
+  { PCI_CHIP_RV620_95CF, "ATI FireMV 2260" },
+  { PCI_CHIP_RV635_9590, "ATI ATI Radeon HD 3600 Series" },
+  { PCI_CHIP_RV635_9596, "ATI ATI Radeon HD 3650 AGP" },
+  { PCI_CHIP_RV635_9597, "ATI ATI Radeon HD 3600 PRO" },
+  { PCI_CHIP_RV635_9598, "ATI ATI Radeon HD 3600 XT" },
+  { PCI_CHIP_RV635_9599, "ATI ATI Radeon HD 3600 PRO" },
+  { PCI_CHIP_RV635_9591, "ATI Mobility Radeon HD 3650" },
+  { PCI_CHIP_RV635_9593, "ATI Mobility Radeon HD 3670" },
+  { PCI_CHIP_RS780_9610, "ATI Radeon HD 3200 Graphics" },
+  { PCI_CHIP_RS780_9611, "ATI Radeon 3100 Graphics" },
+  { PCI_CHIP_RS780_9612, "ATI Radeon HD 3200 Graphics" },
+  { PCI_CHIP_RS780_9613, "ATI Radeon 3100 Graphics" },
   { -1,                 NULL }
 };
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index c9cd8a9..45dc14b 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -60,7 +60,9 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 
     info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1;
 
-    if (IS_R300_VARIANT || IS_AVIVO_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
+    if (IS_R300_VARIANT || IS_AVIVO_VARIANT ||
+	(info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
 
 	BEGIN_ACCEL(3);
 	OUT_ACCEL_REG(R300_RB3D_DSTCACHE_CTLSTAT, R300_DC_FLUSH_3D | R300_DC_FREE_3D);
@@ -84,7 +86,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	    /* R3xx chips */
 	    gb_tile_config |= R300_PIPE_COUNT_R300;
 	} else if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
-		   (info->ChipFamily == CHIP_FAMILY_RS690)) {
+		   (info->ChipFamily == CHIP_FAMILY_RS690) ||
+		   (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    /* RV4xx, RS6xx chips */
 	    gb_tile_config |= R300_PIPE_COUNT_R420_3P;
 	} else {
@@ -205,7 +208,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn)
 	OUT_ACCEL_REG(R300_SC_SCISSOR1, ((8191 << R300_SCISSOR_X_SHIFT) |
 					 (8191 << R300_SCISSOR_Y_SHIFT)));
 
-	if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS690)) {
+	if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    /* clip has offset 1440 */
 	    OUT_ACCEL_REG(R300_SC_CLIP_0_A, ((1088 << R300_CLIP_X_SHIFT) |
 					     (1088 << R300_CLIP_Y_SHIFT)));
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 4943629..d1cbf49 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -585,10 +585,10 @@ unsigned RADEONINMC(ScrnInfoPtr pScrn, int addr)
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32         data;
 
-    if (info->ChipFamily == CHIP_FAMILY_RS690)
-    {
-        OUTREG(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
-        data = INREG(RS690_MC_DATA);
+    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
+	OUTREG(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
+	data = INREG(RS690_MC_DATA);
     } else if (IS_AVIVO_VARIANT) {
 	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0x7f0000);
 	(void)INREG(AVIVO_MC_INDEX);
@@ -614,12 +614,12 @@ void RADEONOUTMC(ScrnInfoPtr pScrn, int addr, CARD32 data)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    if (info->ChipFamily == CHIP_FAMILY_RS690)
-    {
-        OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) |
-                        RS690_MC_INDEX_WR_EN));
-        OUTREG(RS690_MC_DATA, data);
-        OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
+    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
+	OUTREG(RS690_MC_INDEX, ((addr & RS690_MC_INDEX_MASK) |
+				RS690_MC_INDEX_WR_EN));
+	OUTREG(RS690_MC_DATA, data);
+	OUTREG(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
     } else if (IS_AVIVO_VARIANT) {
 	OUTREG(AVIVO_MC_INDEX, (addr & 0xff) | 0xff0000);
 	(void)INREG(AVIVO_MC_INDEX);
@@ -648,7 +648,8 @@ Bool avivo_get_mc_idle(ScrnInfoPtr pScrn)
 	    return TRUE;
 	else
 	    return FALSE;
-    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	if (INMC(pScrn, RS690_MC_STATUS) & RS690_MC_STATUS_IDLE)
 	    return TRUE;
 	else
@@ -681,12 +682,13 @@ void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 fb_loc,
 	if (mask & LOC_AGP)
 	    OUTMC(pScrn, RV515_MC_AGP_LOCATION, agp_loc);
 	(void)INMC(pScrn, RV515_MC_AGP_LOCATION);
-    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	if (mask & LOC_FB)
 	    OUTMC(pScrn, RS690_MC_FB_LOCATION, fb_loc);
 	if (mask & LOC_AGP)
 	    OUTMC(pScrn, RS690_MC_AGP_LOCATION, agp_loc);
-    } else if (info->ChipFamily >= CHIP_FAMILY_R520) { 
+    } else if (info->ChipFamily >= CHIP_FAMILY_R520) {
 	if (mask & LOC_FB)
 	    OUTMC(pScrn, R520_MC_FB_LOCATION, fb_loc);
 	if (mask & LOC_AGP)
@@ -719,7 +721,8 @@ void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, CARD32 *fb_loc,
 	    *agp_loc = INMC(pScrn, RV515_MC_AGP_LOCATION);
 	    *agp_loc_hi = 0;
 	}
-    } else if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    } else if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	       (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	if (mask & LOC_FB)
 	    *fb_loc = INMC(pScrn, RS690_MC_FB_LOCATION);
 	if (mask & LOC_AGP) {
@@ -1244,7 +1247,8 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn, RADEONSavePtr save)
     }
 #endif
 
-    if (info->ChipFamily != CHIP_FAMILY_RS690) {
+    if ((info->ChipFamily != CHIP_FAMILY_RS690) &&
+	(info->ChipFamily != CHIP_FAMILY_RS740)) {
 	if (info->IsIGP)
 	    save->mc_fb_location = INREG(RADEON_NB_TOM);
 	else
@@ -1448,7 +1452,8 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     MessageType    from = X_PROBED;
     CARD32         accessible, bar_size;
 
-    if (info->ChipFamily == CHIP_FAMILY_RS690) {
+    if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
 	pScrn->videoRam = INREG(RADEON_CONFIG_MEMSIZE);
     } else if (info->IsIGP) {
         CARD32 tom = INREG(RADEON_NB_TOM);
@@ -4137,56 +4142,169 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
     state->grph2.viewport_start = INREG(AVIVO_D2MODE_VIEWPORT_START);
     state->grph2.viewport_size = INREG(AVIVO_D2MODE_VIEWPORT_SIZE);
 
-    j = 0;
-    /* save DVOA regs */
-    for (i = 0x7980; i <= 0x79bc; i += 4) {
-	state->dvoa[j] = INREG(i);
-	j++;
-    }
+    if (IS_DCE3_VARIANT) {
+	/* save DVOA regs */
+	state->dvoa[0] = INREG(0x7080);
+	state->dvoa[1] = INREG(0x7084);
+	state->dvoa[2] = INREG(0x708c);
+	state->dvoa[3] = INREG(0x7090);
+	state->dvoa[4] = INREG(0x7094);
+	state->dvoa[5] = INREG(0x70ac);
+	state->dvoa[6] = INREG(0x70b0);
 
-    j = 0;
-    /* save DAC regs */
-    for (i = 0x7800; i <= 0x782c; i += 4) {
-	state->daca[j] = INREG(i);
-	state->dacb[j] = INREG(i + 0x200);
-	j++;
-    }
-    for (i = 0x7834; i <= 0x7840; i += 4) {
-	state->daca[j] = INREG(i);
-	state->dacb[j] = INREG(i + 0x200);
-	j++;
-    }
-    for (i = 0x7850; i <= 0x7868; i += 4) {
-	state->daca[j] = INREG(i);
-	state->dacb[j] = INREG(i + 0x200);
-	j++;
-    }
+	j = 0;
+	/* save DAC regs */
+	for (i = 0x7000; i <= 0x7040; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7058; i <= 0x7060; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7068; i <= 0x706c; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x100);
+	    j++;
+	}
+	state->daca[j] = INREG(0x7050);
+	state->dacb[j] = INREG(0x7050 + 0x100);
 
-    j = 0;
-    /* save TMDSA regs */
-    for (i = 0x7880; i <= 0x78e0; i += 4) {
-	state->tmdsa[j] = INREG(i);
-	j++;
-    }
-    for (i = 0x7904; i <= 0x7918; i += 4) {
-	state->tmdsa[j] = INREG(i);
-	j++;
-    }
+	j = 0;
+	/* save FMT regs */
+	for (i = 0x6700; i <= 0x6744; i += 4) {
+	    state->fmt1[j] = INREG(i);
+	    state->fmt2[j] = INREG(i + 0x800);
+	    j++;
+	}
 
-    j = 0;
-    /* save LVTMA regs */
-    for (i = 0x7a80; i <= 0x7b18; i += 4) {
-	state->lvtma[j] = INREG(i);
-	j++;
-    }
+	j = 0;
+	/* save DIG regs */
+	for (i = 0x75a0; i <= 0x75e0; i += 4) {
+	    state->dig1[j] = INREG(i);
+	    state->dig2[j] = INREG(i + 0x400);
+	    j++;
+	}
+	for (i = 0x75e8; i <= 0x75ec; i += 4) {
+	    state->dig1[j] = INREG(i);
+	    state->dig2[j] = INREG(i + 0x400);
+	    j++;
+	}
 
-    if (info->ChipFamily == CHIP_FAMILY_RS690) {
 	j = 0;
-	/* save DDIA regs */
-	for (i = 0x7200; i <= 0x7290; i += 4) {
-	    state->ddia[j] = INREG(i);
+	/* save HDMI regs */
+	for (i = 0x7400; i <= 0x741c; i += 4) {
+	    state->hdmi1[j] = INREG(i);
+	    state->hdmi2[j] = INREG(i + 0x400);
+	    j++;
+	}
+	for (i = 0x7430; i <= 0x74ec; i += 4) {
+	    state->hdmi1[j] = INREG(i);
+	    state->hdmi2[j] = INREG(i + 0x400);
 	    j++;
 	}
+	state->hdmi1[j] = INREG(0x7428);
+	state->hdmi2[j] = INREG(0x7828);
+
+	j = 0;
+	/* save AUX regs */
+	for (i = 0x7780; i <= 0x77b4; i += 4) {
+	    state->aux_cntl1[j] = INREG(i);
+	    state->aux_cntl2[j] = INREG(i + 0x040);
+	    state->aux_cntl3[j] = INREG(i + 0x400);
+	    state->aux_cntl4[j] = INREG(i + 0x440);
+	    j++;
+	}
+
+	j = 0;
+	/* save UNIPHY regs */
+	for (i = 0x7ec0; i <= 0x7edc; i += 4) {
+	    state->uniphy1[j] = INREG(i);
+	    state->uniphy2[j] = INREG(i + 0x100);
+	    j++;
+	}
+	j = 0;
+	/* save PHY,LINK regs */
+	for (i = 0x7f20; i <= 0x7f34; i += 4) {
+	    state->phy[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
+	    state->phy[j] = INREG(i);
+	    j++;
+	}
+	state->phy[j] = INREG(0x7f40);
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7f80; i <= 0x7f98; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
+    } else {
+	j = 0;
+	/* save DVOA regs */
+	for (i = 0x7980; i <= 0x79bc; i += 4) {
+	    state->dvoa[j] = INREG(i);
+	    j++;
+	}
+
+	j = 0;
+	/* save DAC regs */
+	for (i = 0x7800; i <= 0x782c; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+	for (i = 0x7834; i <= 0x7840; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+	for (i = 0x7850; i <= 0x7868; i += 4) {
+	    state->daca[j] = INREG(i);
+	    state->dacb[j] = INREG(i + 0x200);
+	    j++;
+	}
+
+	j = 0;
+	/* save TMDSA regs */
+	for (i = 0x7880; i <= 0x78e0; i += 4) {
+	    state->tmdsa[j] = INREG(i);
+	    j++;
+	}
+	for (i = 0x7904; i <= 0x7918; i += 4) {
+	    state->tmdsa[j] = INREG(i);
+	    j++;
+	}
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7a80; i <= 0x7b18; i += 4) {
+	    state->lvtma[j] = INREG(i);
+	    j++;
+	}
+
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
+	    j = 0;
+	    /* save DDIA regs */
+	    for (i = 0x7200; i <= 0x7290; i += 4) {
+		state->ddia[j] = INREG(i);
+		j++;
+	    }
+	}
     }
 
     /* scalers */
@@ -4327,56 +4445,170 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
     OUTREG(AVIVO_D2MODE_VIEWPORT_START, state->grph2.viewport_start);
     OUTREG(AVIVO_D2MODE_VIEWPORT_SIZE, state->grph2.viewport_size);
 
-    j = 0;
-    /* DVOA regs */
-    for (i = 0x7980; i <= 0x79bc; i += 4) {
-	OUTREG(i, state->dvoa[j]);
-	j++;
-    }
 
-    j = 0;
-    /* DAC regs */
-    for (i = 0x7800; i <= 0x782c; i += 4) {
-	OUTREG(i, state->daca[j]);
-	OUTREG((i + 0x200), state->dacb[j]);
-	j++;
-    }
-    for (i = 0x7834; i <= 0x7840; i += 4) {
-	OUTREG(i, state->daca[j]);
-	OUTREG((i + 0x200), state->dacb[j]);
-	j++;
-    }
-    for (i = 0x7850; i <= 0x7868; i += 4) {
-	OUTREG(i, state->daca[j]);
-	OUTREG((i + 0x200), state->dacb[j]);
-	j++;
-    }
+    if (IS_DCE3_VARIANT) {
+	/* DVOA regs */
+	OUTREG(0x7080, state->dvoa[0]);
+	OUTREG(0x7084, state->dvoa[1]);
+	OUTREG(0x708c, state->dvoa[2]);
+	OUTREG(0x7090, state->dvoa[3]);
+	OUTREG(0x7094, state->dvoa[4]);
+	OUTREG(0x70ac, state->dvoa[5]);
+	OUTREG(0x70b0, state->dvoa[6]);
 
-    j = 0;
-    /* TMDSA regs */
-    for (i = 0x7880; i <= 0x78e0; i += 4) {
-	OUTREG(i, state->tmdsa[j]);
-	j++;
-    }
-    for (i = 0x7904; i <= 0x7918; i += 4) {
-	OUTREG(i, state->tmdsa[j]);
-	j++;
-    }
+	j = 0;
+	/* DAC regs */
+	for (i = 0x7000; i <= 0x7040; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7058; i <= 0x7060; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7068; i <= 0x706c; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7ef0; i <= 0x7ef8; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x100), state->dacb[j]);
+	    j++;
+	}
+	OUTREG(0x7050, state->daca[j]);
+	OUTREG((0x7050 + 0x100), state->dacb[j]);
 
-    j = 0;
-    /* LVTMA regs */
-    for (i = 0x7a80; i <= 0x7b18; i += 4) {
-	OUTREG(i, state->lvtma[j]);
-	j++;
-    }
+	j = 0;
+	/* FMT regs */
+	for (i = 0x6700; i <= 0x6744; i += 4) {
+	    OUTREG(i, state->fmt1[j]);
+	    OUTREG((i + 0x800), state->fmt2[j]);
+	    j++;
+	}
 
-    /* DDIA regs */
-    if (info->ChipFamily == CHIP_FAMILY_RS690) {
 	j = 0;
-	for (i = 0x7200; i <= 0x7290; i += 4) {
-	    OUTREG(i, state->ddia[j]);
+	/* DIG regs */
+	for (i = 0x75a0; i <= 0x75e0; i += 4) {
+	    OUTREG(i, state->dig1[j]);
+	    OUTREG((i + 0x400), state->dig2[j]);
 	    j++;
 	}
+	for (i = 0x75e8; i <= 0x75ec; i += 4) {
+	    OUTREG(i, state->dig1[j]);
+	    OUTREG((i + 0x400), state->dig2[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* HDMI regs */
+	for (i = 0x7400; i <= 0x741c; i += 4) {
+	    OUTREG(i, state->hdmi1[j]);
+	    OUTREG((i + 0x400), state->hdmi2[j]);
+	    j++;
+	}
+	for (i = 0x7430; i <= 0x74ec; i += 4) {
+	    OUTREG(i, state->hdmi1[j]);
+	    OUTREG((i + 0x400), state->hdmi2[j]);
+	    j++;
+	}
+	OUTREG(0x7428, state->hdmi1[j]);
+	OUTREG((0x7428 + 0x400), state->hdmi2[j]);
+
+	j = 0;
+	/* save AUX regs */
+	for (i = 0x7780; i <= 0x77b4; i += 4) {
+	    OUTREG(i, state->aux_cntl1[j]);
+	    OUTREG((i + 0x040), state->aux_cntl2[j]);
+	    OUTREG((i + 0x400), state->aux_cntl3[j]);
+	    OUTREG((i + 0x440), state->aux_cntl4[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* save UNIPHY regs */
+	for (i = 0x7ec0; i <= 0x7edc; i += 4) {
+	    OUTREG(i, state->uniphy1[j]);
+	    OUTREG((i + 0x100), state->uniphy2[j]);
+	    j++;
+	}
+	j = 0;
+	/* save PHY,LINK regs */
+	for (i = 0x7f20; i <= 0x7f34; i += 4) {
+	    OUTREG(i, state->phy[j]);
+	    j++;
+	}
+	for (i = 0x7f9c; i <= 0x7fa4; i += 4) {
+	    OUTREG(i, state->phy[j]);
+	    j++;
+	}
+	state->phy[j] = INREG(0x7f40);
+
+	j = 0;
+	/* save LVTMA regs */
+	for (i = 0x7f00; i <= 0x7f1c; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
+	for (i = 0x7f80; i <= 0x7f98; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
+    } else {
+	j = 0;
+	/* DVOA regs */
+	for (i = 0x7980; i <= 0x79bc; i += 4) {
+	    OUTREG(i, state->dvoa[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* DAC regs */
+	for (i = 0x7800; i <= 0x782c; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7834; i <= 0x7840; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+	for (i = 0x7850; i <= 0x7868; i += 4) {
+	    OUTREG(i, state->daca[j]);
+	    OUTREG((i + 0x200), state->dacb[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* TMDSA regs */
+	for (i = 0x7880; i <= 0x78e0; i += 4) {
+	    OUTREG(i, state->tmdsa[j]);
+	    j++;
+	}
+	for (i = 0x7904; i <= 0x7918; i += 4) {
+	    OUTREG(i, state->tmdsa[j]);
+	    j++;
+	}
+
+	j = 0;
+	/* LVTMA regs */
+	for (i = 0x7a80; i <= 0x7b18; i += 4) {
+	    OUTREG(i, state->lvtma[j]);
+	    j++;
+	}
+
+	/* DDIA regs */
+	if ((info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
+	    j = 0;
+	    for (i = 0x7200; i <= 0x7290; i += 4) {
+		OUTREG(i, state->ddia[j]);
+		j++;
+	    }
+	}
     }
 
     /* scalers */
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 8a58df2..84beec3 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -536,7 +536,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
 	if (info->ChipFamily >= CHIP_FAMILY_R600)
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
 			       "unsupported on R600 and newer cards.\n");
-	else if (IS_R300_VARIANT || (IS_AVIVO_VARIANT && info->ChipFamily <= CHIP_FAMILY_RS690)) {
+	else if (IS_R300_VARIANT || (IS_AVIVO_VARIANT && info->ChipFamily <= CHIP_FAMILY_RS740)) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
 			       "enabled for R300 type cards.\n");
 		info->exa->CheckComposite = R300CheckComposite;
diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
index a433143..4410cf5 100644
--- a/src/radeon_exa_render.c
+++ b/src/radeon_exa_render.c
@@ -1034,7 +1034,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     CARD32 txenable, colorpitch;
     CARD32 blendcntl;
     int pixel_shift;
-    int has_tcl = (info->ChipFamily != CHIP_FAMILY_RS690 && info->ChipFamily != CHIP_FAMILY_RS400);
+    int has_tcl = ((info->ChipFamily != CHIP_FAMILY_RS690) &&
+		   (info->ChipFamily != CHIP_FAMILY_RS740) &&
+		   (info->ChipFamily != CHIP_FAMILY_RS400));
     ACCEL_PREAMBLE();
 
     TRACE;
@@ -1203,7 +1205,9 @@ static Bool FUNC_NAME(R300PrepareComposite)(int op, PicturePtr pSrcPicture,
     FINISH_ACCEL();
 
     /* setup pixel shader */
-    if (IS_R300_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
+    if (IS_R300_VARIANT ||
+	(info->ChipFamily == CHIP_FAMILY_RS690) ||
+	(info->ChipFamily == CHIP_FAMILY_RS740)) {
       BEGIN_ACCEL(16);
       OUT_ACCEL_REG(R300_RS_COUNT,
 		    ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |
diff --git a/src/radeon_pci_chipset_gen.h b/src/radeon_pci_chipset_gen.h
index ab6b62a..ad77dbd 100644
--- a/src/radeon_pci_chipset_gen.h
+++ b/src/radeon_pci_chipset_gen.h
@@ -276,5 +276,24 @@ PciChipsets RADEONPciChipsets[] = {
  { PCI_CHIP_RV630_958C, PCI_CHIP_RV630_958C, RES_SHARED_VGA },
  { PCI_CHIP_RV630_958D, PCI_CHIP_RV630_958D, RES_SHARED_VGA },
  { PCI_CHIP_RV630_958E, PCI_CHIP_RV630_958E, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C0, PCI_CHIP_RV620_95C0, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C5, PCI_CHIP_RV620_95C5, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C7, PCI_CHIP_RV620_95C7, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C2, PCI_CHIP_RV620_95C2, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95C4, PCI_CHIP_RV620_95C4, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CD, PCI_CHIP_RV620_95CD, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CE, PCI_CHIP_RV620_95CE, RES_SHARED_VGA },
+ { PCI_CHIP_RV620_95CF, PCI_CHIP_RV620_95CF, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9590, PCI_CHIP_RV635_9590, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9596, PCI_CHIP_RV635_9596, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9597, PCI_CHIP_RV635_9597, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9598, PCI_CHIP_RV635_9598, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9599, PCI_CHIP_RV635_9599, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9591, PCI_CHIP_RV635_9591, RES_SHARED_VGA },
+ { PCI_CHIP_RV635_9593, PCI_CHIP_RV635_9593, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9610, PCI_CHIP_RS780_9610, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9611, PCI_CHIP_RS780_9611, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9612, PCI_CHIP_RS780_9612, RES_SHARED_VGA },
+ { PCI_CHIP_RS780_9613, PCI_CHIP_RS780_9613, RES_SHARED_VGA },
  { -1,                 -1,                 RES_UNDEFINED }
 };
diff --git a/src/radeon_pci_device_match_gen.h b/src/radeon_pci_device_match_gen.h
index 04393da..77ca75d 100644
--- a/src/radeon_pci_device_match_gen.h
+++ b/src/radeon_pci_device_match_gen.h
@@ -276,5 +276,24 @@ static const struct pci_id_match radeon_device_match[] = {
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958C, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958D, 0 ),
  ATI_DEVICE_MATCH( PCI_CHIP_RV630_958E, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C0, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C5, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C7, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C2, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95C4, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CD, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CE, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV620_95CF, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9590, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9596, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9597, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9598, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9599, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9591, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RV635_9593, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9610, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9611, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9612, 0 ),
+ ATI_DEVICE_MATCH( PCI_CHIP_RS780_9613, 0 ),
  { 0, 0, 0 }
 };
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index c399cc2..935b6b8 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -256,6 +256,8 @@ typedef struct _RADEONOutputPrivateRec {
     int               SupportedTVStds;
     Bool              tv_on;
     int               load_detection;
+    /* dig block */
+    int transmitter_config;
 
     char              *name;
     int               output_id;
@@ -343,8 +345,8 @@ struct avivo_state
     CARD32 dxscl[6+2];
 
     /* dac regs */
-    CARD32 daca[23];
-    CARD32 dacb[23];
+    CARD32 daca[26];
+    CARD32 dacb[26];
 
     /* tmdsa */
     CARD32 tmdsa[31];
@@ -355,6 +357,21 @@ struct avivo_state
     /* dvoa */
     CARD32 dvoa[16];
 
+    /* DCE3 chips */
+    CARD32 fmt1[18];
+    CARD32 fmt2[18];
+    CARD32 dig1[19];
+    CARD32 dig2[19];
+    CARD32 hdmi1[57];
+    CARD32 hdmi2[57];
+    CARD32 aux_cntl1[14];
+    CARD32 aux_cntl2[14];
+    CARD32 aux_cntl3[14];
+    CARD32 aux_cntl4[14];
+    CARD32 phy[10];
+    CARD32 uniphy1[8];
+    CARD32 uniphy2[8];
+
 };
 
 /*
diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
index 9a5187b..4ebb73b 100644
--- a/src/radeon_textured_videofuncs.c
+++ b/src/radeon_textured_videofuncs.c
@@ -128,7 +128,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
     FINISH_VIDEO();
 
     if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
-	int has_tcl = (info->ChipFamily != CHIP_FAMILY_RS690 && info->ChipFamily != CHIP_FAMILY_RS400);
+	int has_tcl = ((info->ChipFamily != CHIP_FAMILY_RS690) &&
+		       (info->ChipFamily != CHIP_FAMILY_RS740) &&
+		       (info->ChipFamily != CHIP_FAMILY_RS400));
 
 	switch (pPixmap->drawable.bitsPerPixel) {
 	case 16:
@@ -289,7 +291,9 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
 	FINISH_VIDEO();
 
 	/* setup pixel shader */
-	if (IS_R300_VARIANT || info->ChipFamily == CHIP_FAMILY_RS690) {
+	if (IS_R300_VARIANT ||
+	    (info->ChipFamily == CHIP_FAMILY_RS690) ||
+	    (info->ChipFamily == CHIP_FAMILY_RS740)) {
 	    BEGIN_VIDEO(16);
 	    OUT_VIDEO_REG(R300_RS_COUNT,
 			  ((2 << R300_RS_COUNT_IT_COUNT_SHIFT) |


More information about the xorg-commit mailing list