|
@@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static struct drm_connector *
|
|
|
-radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
|
|
|
-{
|
|
|
- struct drm_device *dev = encoder->dev;
|
|
|
- struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
|
|
- struct drm_connector *connector;
|
|
|
- struct radeon_connector *radeon_connector;
|
|
|
-
|
|
|
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
|
|
- radeon_connector = to_radeon_connector(connector);
|
|
|
- if (radeon_encoder->devices & radeon_connector->devices)
|
|
|
- return connector;
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
|
|
|
struct drm_display_mode *mode,
|
|
|
struct drm_display_mode *adjusted_mode)
|
|
@@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
|
|
|
/* R4xx, R5xx */
|
|
|
args.ext_tmds.sXTmdsEncoder.ucEnable = action;
|
|
|
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
|
|
|
|
|
args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB;
|
|
@@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
|
|
|
/* DFP1, CRT1, TV1 depending on the type of port */
|
|
|
args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX;
|
|
|
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL;
|
|
|
break;
|
|
|
case 3:
|
|
@@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
|
|
|
} else {
|
|
|
if (dig->linkb)
|
|
|
args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
|
|
/*if (pScrn->rgbBits == 8) */
|
|
|
args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB;
|
|
@@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
|
|
|
} else {
|
|
|
if (dig->linkb)
|
|
|
args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL;
|
|
|
}
|
|
|
break;
|
|
@@ -432,7 +416,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
|
|
switch (connector->connector_type) {
|
|
|
case DRM_MODE_CONNECTOR_DVII:
|
|
|
case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
|
|
|
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
|
|
|
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
|
|
|
radeon_audio)
|
|
|
return ATOM_ENCODER_MODE_HDMI;
|
|
|
else if (radeon_connector->use_digital)
|
|
@@ -443,7 +427,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
|
|
case DRM_MODE_CONNECTOR_DVID:
|
|
|
case DRM_MODE_CONNECTOR_HDMIA:
|
|
|
default:
|
|
|
- if (drm_detect_monitor_audio(radeon_connector->edid) &&
|
|
|
+ if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
|
|
|
radeon_audio)
|
|
|
return ATOM_ENCODER_MODE_HDMI;
|
|
|
else
|
|
@@ -457,7 +441,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
|
|
|
if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
|
|
|
(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
|
|
|
return ATOM_ENCODER_MODE_DP;
|
|
|
- else if (drm_detect_monitor_audio(radeon_connector->edid) &&
|
|
|
+ else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
|
|
|
radeon_audio)
|
|
|
return ATOM_ENCODER_MODE_HDMI;
|
|
|
else
|
|
@@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
|
|
|
|
|
|
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
|
|
|
args.v1.ucLaneNum = dp_lane_count;
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v1.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v1.ucLaneNum = 4;
|
|
@@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
|
|
|
|
|
|
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
|
|
|
args.v3.ucLaneNum = dp_lane_count;
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v3.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v3.ucLaneNum = 4;
|
|
@@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
|
|
|
|
|
|
if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode))
|
|
|
args.v4.ucLaneNum = dp_lane_count;
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v4.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v4.ucLaneNum = 4;
|
|
@@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
if (is_dp)
|
|
|
args.v1.usPixelClock =
|
|
|
cpu_to_le16(dp_clock / 10);
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
|
|
else
|
|
|
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
|
@@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
|
|
|
if ((rdev->flags & RADEON_IS_IGP) &&
|
|
|
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) {
|
|
|
- if (is_dp || (radeon_encoder->pixel_clock <= 165000)) {
|
|
|
+ if (is_dp ||
|
|
|
+ !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) {
|
|
|
if (igp_lane_info & 0x1)
|
|
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3;
|
|
|
else if (igp_lane_info & 0x2)
|
|
@@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
|
|
if (dig->coherent_mode)
|
|
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK;
|
|
|
}
|
|
|
break;
|
|
@@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
if (is_dp)
|
|
|
args.v2.usPixelClock =
|
|
|
cpu_to_le16(dp_clock / 10);
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
|
|
else
|
|
|
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
|
@@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
|
|
if (dig->coherent_mode)
|
|
|
args.v2.acConfig.fCoherentMode = 1;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v2.acConfig.fDualLinkConnector = 1;
|
|
|
}
|
|
|
break;
|
|
@@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
if (is_dp)
|
|
|
args.v3.usPixelClock =
|
|
|
cpu_to_le16(dp_clock / 10);
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
|
|
else
|
|
|
args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
|
@@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
|
|
|
if (is_dp)
|
|
|
args.v3.ucLaneNum = dp_lane_count;
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v3.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v3.ucLaneNum = 4;
|
|
@@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
|
|
if (dig->coherent_mode)
|
|
|
args.v3.acConfig.fCoherentMode = 1;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v3.acConfig.fDualLinkConnector = 1;
|
|
|
}
|
|
|
break;
|
|
@@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
if (is_dp)
|
|
|
args.v4.usPixelClock =
|
|
|
cpu_to_le16(dp_clock / 10);
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10);
|
|
|
else
|
|
|
args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
|
|
@@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
|
|
|
if (is_dp)
|
|
|
args.v4.ucLaneNum = dp_lane_count;
|
|
|
- else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v4.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v4.ucLaneNum = 4;
|
|
@@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|
|
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
|
|
|
if (dig->coherent_mode)
|
|
|
args.v4.acConfig.fCoherentMode = 1;
|
|
|
- if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v4.acConfig.fDualLinkConnector = 1;
|
|
|
}
|
|
|
break;
|
|
@@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
|
|
if (dp_clock == 270000)
|
|
|
args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
|
|
|
args.v1.sDigEncoder.ucLaneNum = dp_lane_count;
|
|
|
- } else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v1.sDigEncoder.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v1.sDigEncoder.ucLaneNum = 4;
|
|
@@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder,
|
|
|
else if (dp_clock == 540000)
|
|
|
args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ;
|
|
|
args.v3.sExtEncoder.ucLaneNum = dp_lane_count;
|
|
|
- } else if (radeon_encoder->pixel_clock > 165000)
|
|
|
+ } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock))
|
|
|
args.v3.sExtEncoder.ucLaneNum = 8;
|
|
|
else
|
|
|
args.v3.sExtEncoder.ucLaneNum = 4;
|
|
@@ -1341,7 +1326,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
|
|
|
switch (mode) {
|
|
|
case DRM_MODE_DPMS_ON:
|
|
|
/* some early dce3.2 boards have a bug in their transmitter control table */
|
|
|
- if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
|
|
|
+ if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) ||
|
|
|
+ ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
|
|
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
|
|
|
else
|
|
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
|
|
@@ -1351,8 +1337,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
|
|
|
ATOM_TRANSMITTER_ACTION_POWER_ON);
|
|
|
radeon_dig_connector->edp_on = true;
|
|
|
}
|
|
|
- if (ASIC_IS_DCE4(rdev))
|
|
|
- atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
|
|
|
radeon_dp_link_train(encoder, connector);
|
|
|
if (ASIC_IS_DCE4(rdev))
|
|
|
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
|
|
@@ -1363,7 +1347,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode)
|
|
|
case DRM_MODE_DPMS_STANDBY:
|
|
|
case DRM_MODE_DPMS_SUSPEND:
|
|
|
case DRM_MODE_DPMS_OFF:
|
|
|
- atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
|
|
|
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev))
|
|
|
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
|
|
|
+ else
|
|
|
+ atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0);
|
|
|
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
|
|
|
if (ASIC_IS_DCE4(rdev))
|
|
|
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
|
|
@@ -1810,7 +1797,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
|
|
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
|
|
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
|
|
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
|
|
|
- if (ASIC_IS_DCE4(rdev)) {
|
|
|
+ if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
|
|
|
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
|
|
|
+ struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
|
|
+
|
|
|
+ if (!connector)
|
|
|
+ dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
|
|
|
+ else
|
|
|
+ dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector);
|
|
|
+
|
|
|
+ /* setup and enable the encoder */
|
|
|
+ atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
|
|
|
+ atombios_dig_encoder_setup(encoder,
|
|
|
+ ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
|
|
|
+ dig->panel_mode);
|
|
|
+ } else if (ASIC_IS_DCE4(rdev)) {
|
|
|
/* disable the transmitter */
|
|
|
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
|
|
|
/* setup and enable the encoder */
|