Commit f6a1906674005377b64ee5431c1418077c1b2425

Authored by Ville Syrjälä
Committed by Jani Nikula
1 parent cac7f24298

drm/i915: Do a dummy DPCD read before the actual read

Sometimes we seem to get utter garbage from DPCD reads. The resulting
buffer is filled with the same byte, and the operation completed without
errors. My HP ZR24w monitor seems particularly susceptible to this
problem once it's gone into a sleep mode.

The issue seems to happen only for the first AUX message that wakes the
sink up. But as the first AUX read we often do is the DPCD receiver
cap it does wreak a bit of havoc with subsequent link training etc. when
the receiver cap bw/lane/etc. information is garbage.

A sufficient workaround seems to be to perform a single byte dummy read
before reading the actual data. I suppose that just wakes up the sink
sufficiently and we can just throw away the returned data in case it's
crap. DP_DPCD_REV seems like a sufficiently safe location to read here.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Todd Previte <tprevite@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Showing 1 changed file with 7 additions and 0 deletions Side-by-side Diff

drivers/gpu/drm/i915/intel_dp.c
... ... @@ -2806,6 +2806,13 @@
2806 2806 ssize_t ret;
2807 2807 int i;
2808 2808  
  2809 + /*
  2810 + * Sometime we just get the same incorrect byte repeated
  2811 + * over the entire buffer. Doing just one throw away read
  2812 + * initially seems to "solve" it.
  2813 + */
  2814 + drm_dp_dpcd_read(aux, DP_DPCD_REV, buffer, 1);
  2815 +
2809 2816 for (i = 0; i < 3; i++) {
2810 2817 ret = drm_dp_dpcd_read(aux, offset, buffer, size);
2811 2818 if (ret == size)