summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/atombios_output.c183
1 files changed, 58 insertions, 125 deletions
diff --git a/src/atombios_output.c b/src/atombios_output.c
index 81187ae1..34796f85 100644
--- a/src/atombios_output.c
+++ b/src/atombios_output.c
@@ -389,23 +389,35 @@ atombios_maybe_hdmi_mode(xf86OutputPtr output)
}
static int
-atombios_output_dig1_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_dig_encoder_setup(xf86OutputPtr output, int device, DisplayModePtr mode)
{
RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(output->scrn);
DIG_ENCODER_CONTROL_PS_ALLOCATION disp_data;
AtomBiosArgRec data;
unsigned char *space;
+ int index;
- disp_data.ucAction = 1;
+ if (radeon_crtc->crtc_id)
+ index = GetIndexIntoMasterTable(COMMAND, DIG2EncoderControl);
+ else
+ index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+
+ disp_data.ucAction = ATOM_ENABLE;
disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
- if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
- if (radeon_output->coherent_mode) {
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG1: Coherent Mode enabled\n");
- } else
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG1: Coherent Mode disabled\n");
+
+ switch (device) {
+ case ATOM_DEVICE_DFP1_INDEX:
+ disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER1;
+ break;
+ case ATOM_DEVICE_LCD1_INDEX:
+ case ATOM_DEVICE_DFP3_INDEX:
+ disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
+ break;
+ default:
+ return ATOM_NOT_IMPLEMENTED;
+ break;
}
if (mode->Clock > 165000) {
@@ -425,142 +437,63 @@ atombios_output_dig1_setup(xf86OutputPtr output, DisplayModePtr mode)
else if (radeon_output->type == OUTPUT_LVDS)
disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
- data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG1EncoderControl);
+ data.exec.index = index;
data.exec.dataSpace = (void *)&space;
data.exec.pspace = &disp_data;
if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- ErrorF("Output DIG1 setup success\n");
+ ErrorF("Output DIG%d setup success\n", radeon_crtc->crtc_id + 1);
return ATOM_SUCCESS;
}
- ErrorF("Output DIG1 setup failed\n");
+ ErrorF("Output DIG%d setup failed\n", radeon_crtc->crtc_id + 1);
return ATOM_NOT_IMPLEMENTED;
}
static int
-atombios_output_dig1_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode)
+atombios_output_dig_transmitter_setup(xf86OutputPtr output, int device, DisplayModePtr mode)
{
RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONCrtcPrivatePtr radeon_crtc = output->crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(output->scrn);
DIG_TRANSMITTER_CONTROL_PS_ALLOCATION disp_data;
AtomBiosArgRec data;
unsigned char *space;
+ int index, num = 0;
- disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
- disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
- disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-
- if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
- if (mode->Clock > 165000) {
- disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
- ATOM_TRANSMITTER_CONFIG_LINKA_B);
- /* guess */
- if (radeon_output->igp_lane_info & 0x3)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7;
- else if (radeon_output->igp_lane_info & 0xc)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15;
- } else {
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA;
- if (radeon_output->igp_lane_info & 0x1)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
- else if (radeon_output->igp_lane_info & 0x2)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7;
- else if (radeon_output->igp_lane_info & 0x4)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11;
- else if (radeon_output->igp_lane_info & 0x8)
- disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15;
- }
- } else {
- 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;
+ switch (device) {
+ case ATOM_DEVICE_DFP1_INDEX:
+ index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl);
+ num = 1;
+ break;
+ case ATOM_DEVICE_LCD1_INDEX:
+ case ATOM_DEVICE_DFP3_INDEX:
+ index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+ num = 2;
+ break;
+ default:
+ return ATOM_NOT_IMPLEMENTED;
+ break;
}
- ErrorF("Output DIG1 transmitter setup failed\n");
- return ATOM_NOT_IMPLEMENTED;
-
-}
+ disp_data.ucAction = ATOM_TRANSMITTER_ACTION_ENABLE;
+ disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
+ disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-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;
+ if (radeon_crtc->crtc_id)
+ disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
+ else
+ disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
- disp_data.ucAction = 1;
- disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
- disp_data.ucConfig = ATOM_ENCODER_CONFIG_TRANSMITTER2;
if (OUTPUT_IS_DVI || (radeon_output->type == OUTPUT_HDMI)) {
if (radeon_output->coherent_mode) {
disp_data.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG2: Coherent Mode enabled\n");
+ xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode enabled\n", num);
} else
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG2: Coherent Mode disabled\n");
- }
-
- if (mode->Clock > 165000) {
- disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA_B;
- disp_data.ucLaneNum = 8;
- } else {
- disp_data.ucConfig |= ATOM_ENCODER_CONFIG_LINKA;
- disp_data.ucLaneNum = 4;
- }
-
- if (OUTPUT_IS_DVI)
- disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DVI;
- else if (radeon_output->type == OUTPUT_HDMI)
- disp_data.ucEncoderMode = atombios_maybe_hdmi_mode(output);
- else if (radeon_output->type == OUTPUT_DP)
- disp_data.ucEncoderMode = ATOM_ENCODER_MODE_DP;
- else if (radeon_output->type == OUTPUT_LVDS)
- disp_data.ucEncoderMode = ATOM_ENCODER_MODE_LVDS;
-
- 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;
+ xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "DIG%d transmitter: Coherent Mode disabled\n", num);
}
- 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_ENABLE;
- disp_data.usPixelClock = cpu_to_le16(mode->Clock / 10);
- disp_data.ucConfig = ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER | ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
-
if (info->IsIGP && (radeon_output->TMDSType == TMDS_UNIPHY)) {
if (mode->Clock > 165000) {
disp_data.ucConfig |= (ATOM_TRANSMITTER_CONFIG_8LANE_LINK |
@@ -592,16 +525,16 @@ atombios_output_dig2_transmitter_setup(xf86OutputPtr output, DisplayModePtr mode
radeon_output->transmitter_config = disp_data.ucConfig;
- data.exec.index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl);
+ data.exec.index = index;
data.exec.dataSpace = (void *)&space;
data.exec.pspace = &disp_data;
if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
- ErrorF("Output DIG2 transmitter setup success\n");
+ ErrorF("Output DIG%d transmitter setup success\n", num);
return ATOM_SUCCESS;
}
- ErrorF("Output DIG2 transmitter setup failed\n");
+ ErrorF("Output DIG%d transmitter setup failed\n", num);
return ATOM_NOT_IMPLEMENTED;
}
@@ -958,8 +891,8 @@ atombios_output_mode_set(xf86OutputPtr output,
} else if (radeon_output->MonType == MT_DFP) {
if (radeon_output->devices & ATOM_DEVICE_DFP1_SUPPORT) {
if (IS_DCE3_VARIANT) {
- atombios_output_dig1_setup(output, adjusted_mode);
- atombios_output_dig1_transmitter_setup(output, adjusted_mode);
+ atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
+ atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
} else
atombios_output_digital_setup(output, ATOM_DEVICE_DFP1_INDEX, adjusted_mode);
} else if (radeon_output->devices & ATOM_DEVICE_DFP2_SUPPORT) {
@@ -975,16 +908,16 @@ atombios_output_mode_set(xf86OutputPtr output,
}
} else if (radeon_output->devices & ATOM_DEVICE_DFP3_SUPPORT) {
if (IS_DCE3_VARIANT) {
- atombios_output_dig2_setup(output, adjusted_mode);
- atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+ atombios_output_dig_encoder_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
+ atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
} else
atombios_output_digital_setup(output, ATOM_DEVICE_DFP3_INDEX, adjusted_mode);
}
} else if (radeon_output->MonType == MT_LCD) {
if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) {
if (IS_DCE3_VARIANT) {
- atombios_output_dig2_setup(output, adjusted_mode);
- atombios_output_dig2_transmitter_setup(output, adjusted_mode);
+ atombios_output_dig_encoder_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
+ atombios_output_dig_transmitter_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
} else
atombios_output_digital_setup(output, ATOM_DEVICE_LCD1_INDEX, adjusted_mode);
}