diff options
author | Alex Deucher <alexdeucher@gmail.com> | 2014-04-30 09:27:15 -0400 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-05-01 06:28:09 -0400 |
commit | aa019b791a3e138ca0eaa38e72b4ea97d482a7bc (patch) | |
tree | c410500d6aae5314a2be50196d1e9efb687144a8 | |
parent | 3b333c55485fef0089ae7398906599d000df195e (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/radeon/atombios_dp.c | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index bc0119fb6c12..54e4f52549af 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) | |||
366 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) | 366 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
367 | return; | 367 | return; |
368 | 368 | ||
369 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3)) | 369 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3) |
370 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", | 370 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", |
371 | buf[0], buf[1], buf[2]); | 371 | buf[0], buf[1], buf[2]); |
372 | 372 | ||
373 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3)) | 373 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3) |
374 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", | 374 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", |
375 | buf[0], buf[1], buf[2]); | 375 | buf[0], buf[1], buf[2]); |
376 | } | 376 | } |
@@ -419,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
419 | 419 | ||
420 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { | 420 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
421 | /* DP bridge chips */ | 421 | /* DP bridge chips */ |
422 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, | 422 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
423 | DP_EDP_CONFIGURATION_CAP, &tmp); | 423 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
424 | if (tmp & 1) | 424 | if (tmp & 1) |
425 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 425 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
426 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || | 426 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
427 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) | 427 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
428 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 428 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
429 | else | 429 | else |
430 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 430 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
431 | } | ||
431 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 432 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
432 | /* eDP */ | 433 | /* eDP */ |
433 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, | 434 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
434 | DP_EDP_CONFIGURATION_CAP, &tmp); | 435 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
435 | if (tmp & 1) | 436 | if (tmp & 1) |
436 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 437 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
438 | } | ||
437 | } | 439 | } |
438 | 440 | ||
439 | return panel_mode; | 441 | return panel_mode; |
@@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
809 | else | 811 | else |
810 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; | 812 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; |
811 | 813 | ||
812 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp); | 814 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp) |
813 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) | 815 | == 1) { |
814 | dp_info.tp3_supported = true; | 816 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) |
815 | else | 817 | dp_info.tp3_supported = true; |
818 | else | ||
819 | dp_info.tp3_supported = false; | ||
820 | } else { | ||
816 | dp_info.tp3_supported = false; | 821 | dp_info.tp3_supported = false; |
822 | } | ||
817 | 823 | ||
818 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); | 824 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); |
819 | dp_info.rdev = rdev; | 825 | dp_info.rdev = rdev; |