diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 8b3d8ed..33d9e0d 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -827,6 +827,28 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) return ret; } +static bool radeon_check_hpd_status_unchanged(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + enum drm_connector_status status; + + /* We only trust HPD on R600 and newer ASICS. */ + if (rdev->family >= CHIP_R600 + && radeon_connector->hpd.hpd != RADEON_HPD_NONE) { + if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) + status = connector_status_connected; + else + status = connector_status_disconnected; + + if (connector->status == status) + return true; + } + + return false; +} + /* * DVI is complicated * Do a DDC probe, if DDC probe passes, get the full EDID so @@ -851,6 +873,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) enum drm_connector_status ret = connector_status_disconnected; bool dret = false; + if (!force && radeon_check_hpd_status_unchanged(connector)) + return connector->status; + if (radeon_connector->ddc_bus) dret = radeon_ddc_probe(radeon_connector); if (dret) { @@ -1250,6 +1277,9 @@ radeon_dp_detect(struct drm_connector *connector, bool force) struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct drm_encoder *encoder = radeon_best_single_encoder(connector); + if (!force && radeon_check_hpd_status_unchanged(connector)) + return connector->status; + if (radeon_connector->edid) { kfree(radeon_connector->edid); radeon_connector->edid = NULL;