public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: Todd Previte <tprevite@gmail.com>
To: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH] drm/i915: Retry reading DPCD when bogus values are read
Date: Wed, 22 Jan 2014 17:59:18 -0700	[thread overview]
Message-ID: <52E06966.2040006@gmail.com> (raw)
In-Reply-To: <s5hpppshlza.wl%tiwai@suse.de>

On 11/22/13 1:36 AM, Takashi Iwai wrote:
> I got kernel WARNINGs frequently on Haswell laptops complaining about
> invalid max DP link bw.  With drm.debug=0x0e, it turned out that the
> obtained DPCD is utterly bogus when it happens:
>    [drm:intel_dp_get_dpcd], DPCD: 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d 4d
>
> This seems happening intermittently without plug state changes and
> even after the first few reads succeeded.  As a workaround, add a
> sanity check for such bogus values and retry reading if it hits.
>
> Signed-off-by: Takashi Iwai <tiwai@suse.de>
> ---
>
>   drivers/gpu/drm/i915/intel_dp.c | 15 ++++++++++++++-
>   1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index eb8139da9763..f596353da557 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -2792,13 +2792,26 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
>   	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>   	struct drm_device *dev = dig_port->base.base.dev;
>   	struct drm_i915_private *dev_priv = dev->dev_private;
> -
> +	int retry = 0;
>   	char dpcd_hex_dump[sizeof(intel_dp->dpcd) * 3];
>
> + again:
>   	if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
>   					   sizeof(intel_dp->dpcd)) == 0)
>   		return false; /* aux transfer failed */
>
> +	/* sanity check: sometimes DPCD contains a series of same bogus value
> +	 * even though the above returned success.  Retry reading in that case.
> +	 */
> +	if (intel_dp->dpcd[0]) {
> +		int i;
> +		for (i = 1; i < sizeof(intel_dp->dpcd); i++)
> +			if (intel_dp->dpcd[i] != intel_dp->dpcd[0])
> +				break;
> +		if (i >= sizeof(intel_dp->dpcd) && retry++ < 2)
> +			goto again;
> +	}
> +
>   	hex_dump_to_buffer(intel_dp->dpcd, sizeof(intel_dp->dpcd),
>   			   32, 1, dpcd_hex_dump, sizeof(dpcd_hex_dump), false);
>   	DRM_DEBUG_KMS("DPCD: %s\n", dpcd_hex_dump);
I'm in agreement with Jani's assessment. While it does address the 
particular problem at hand, it just looks for duplicate data and issues 
a retry if that specific condition is detected. It seems more 
appropriate that instead of checking for specific failure modes, we 
check to ensure that we have useable values for the basic, critical 
fields required for Displayport.

I would suggest that we validate the first 3 bytes of the DPCD. Those 
fields are as follows:
     0x00 - DPCD revision level
         Currently can only be 0x10, 0x11 or 0x12
     0x01 - Link rate
         Also only 3 values currently - 0x06, 0x0A and 0x14
     0x02 - Max lane count
         For validation purposes, we just need to look at 4:0 and verify 
it's 0x01, 0x02 or 0x04
         While bits 6 and 7 are used, they're just feature bits and we 
check them later anyways.

This is kind of what I was thinking:

     #define MAX_DPCD_REVISION 0x12
     u8 lane_count = DPCD[2] & 0x1F;

     // Verify DPCD revision is in a valid range. MAX_DPCD_REVISION 
should be updated as necessasry
     // to reflect the current supported DPCD version.
     if (DPCD[0] < 0x10 || DPCD > MAX_DPCD_REVISION)
         goto retry;
     // These are the only valid values for link rate. More will surely 
be added as Displayport moves forward.
     if  !(DPCD[1] == 0x06 || DPCD[1] == 0x0A || DPCD[1] == 0x14)
         goto retry;
     // Lane count must be 1, 2 or 4. 3 shalt thou not count, and 5 is 
right out...
     if !(lane_count == 0x01 || lane_count == 0x02 || lane_count == 0x04)
         goto retry;

retry:
         retry_count++;
         if retry_count > max_retries
             goto error
         else
             goto read_dpcd


-T

      parent reply	other threads:[~2014-01-23  0:59 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-22  8:36 [PATCH] drm/i915: Retry reading DPCD when bogus values are read Takashi Iwai
2013-11-25 15:47 ` Daniel Vetter
2013-11-25 15:52   ` Takashi Iwai
2013-11-25 16:16     ` Daniel Vetter
2013-12-04 10:17 ` Jani Nikula
2013-12-04 10:28   ` Takashi Iwai
2014-01-23  0:59 ` Todd Previte [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52E06966.2040006@gmail.com \
    --to=tprevite@gmail.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox