drm/radeon/dp: check for errors in dpcd reads

Check to make sure the transaction succeeded before
using the register value.  Fixes occasional link training
problems.

Noticed-by: Sergei Antonov <saproj@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
Alex Deucher
2014-04-30 09:27:15 -04:00
committed by Christian König
parent 3b333c5548
commit aa019b791a

View File

@@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return; return;
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3)) if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]); buf[0], buf[1], buf[2]);
if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3)) if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3)
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]); buf[0], buf[1], buf[2]);
} }
@@ -419,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
if (dp_bridge != ENCODER_OBJECT_ID_NONE) { if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
/* DP bridge chips */ /* DP bridge chips */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp); DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1) if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) ||
(dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) (dp_bridge == ENCODER_OBJECT_ID_TRAVIS))
panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
else else
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
}
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP */ /* eDP */
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp); DP_EDP_CONFIGURATION_CAP, &tmp) == 1) {
if (tmp & 1) if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
}
} }
return panel_mode; return panel_mode;
@@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
else else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp); if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp)
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) == 1) {
dp_info.tp3_supported = true; if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
else dp_info.tp3_supported = true;
else
dp_info.tp3_supported = false;
} else {
dp_info.tp3_supported = false; dp_info.tp3_supported = false;
}
memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE);
dp_info.rdev = rdev; dp_info.rdev = rdev;