From: Tvrtko Ursulin <tvrtko.ursu...@onelan.co.uk>

On a system with one HDMI and one VGA connector the latter
causes output polling to run every ten seconds. This causes
full EDID re-fetch on every poll and approx. 100ms rendering
stalls are experienced by full screen page-flipping applications.
Optimisation is to trust HPD sense on R600+ ASICs and to skip
doing these expensive probes unless HPD sense has changed.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=47007

agd5f: fix patch and message formatting.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at onelan.co.uk>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/radeon_connectors.c |   27 +++++++++++++++++++++++++++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c 
b/drivers/gpu/drm/radeon/radeon_connectors.c
index f7d39ac..dfbd391 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -827,6 +827,27 @@ 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 +872,9 @@ 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) {
@@ -1245,6 +1269,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;
-- 
1.7.7.5

Reply via email to