diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2009-01-19 18:42:12 -0500 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-01-19 18:42:12 -0500 |
commit | 7cc7ba8bf9ce2f0eebfd9b48aa648c416c333ff4 (patch) | |
tree | 52f2785eb48ce1278ee8e82a6b1b6d46ab3753d1 /src | |
parent | 25f3878858e6efb486888e5271b60d4ba08c73c6 (diff) |
ATOM: round 1 of output rework
Diffstat (limited to 'src')
-rw-r--r-- | src/atombios_output.c | 639 | ||||
-rw-r--r-- | src/radeon_atombios.c | 103 | ||||
-rw-r--r-- | src/radeon_output.c | 43 |
3 files changed, 474 insertions, 311 deletions
diff --git a/src/atombios_output.c b/src/atombios_output.c index efe487b3..4f5c499a 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 f79cb2d0..e1361804 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 efbfdfeb..2ac577ce 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); |