Re: [PATCH v2 3/5] drm/panel-simple: Retry if we timeout waiting for HPD

From: Stephen Boyd
Date: Mon Jan 25 2021 - 15:31:14 EST


Quoting Douglas Anderson (2021-01-15 14:44:18)
> On an Innolux N116BCA panel that I have in front of me, sometimes HPD
> simply doesn't assert no matter how long you wait for it. As per the
> very wise advice of The IT Crowd ("Have you tried turning it off and
> on again?") it appears that power cycling is enough to kick this panel
> back into a sane state.
>
> From tests on this panel, it appears that leaving it powered off for a
> while stimulates the problem. Adding a 6 second sleep at the start of
> panel_simple_prepare_once() makes it happen fairly reliably and, with
> this delay, I saw up to 3 retries needed sometimes. Without the 6
> second sleep, however, the panel came up much more reliably the first
> time or after only 1 retry.
>
> While it's unknown what the problems are with this panel (and probably
> the hardware should be debugged), adding a few retries to the power on
> routine doesn't seem insane. Even if this panel's problems are
> attributed to the fact that it's pre-production and/or can be fixed,
> retries clearly can help in some cases and really don't hurt.
>
> Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx>

Reviewed-by: Stephen Boyd <swboyd@xxxxxxxxxxxx>

> @@ -440,6 +441,31 @@ static int panel_simple_prepare(struct drm_panel *panel)
> return err;
> }
>
> +/*
> + * Some panels simply don't always come up and need to be power cycled to
> + * work properly. We'll allow for a handful of retries.
> + */
> +#define MAX_PANEL_PREPARE_TRIES 5

Is this define used anywhere else? Feels like it would be better to
inline the constant and move the comment above the loop, but I guess
this is OK too.

> +
> +static int panel_simple_prepare(struct drm_panel *panel)
> +{
> + int ret;
> + int try;
> +
> + for (try = 0; try < MAX_PANEL_PREPARE_TRIES; try++) {
> + ret = panel_simple_prepare_once(panel);
> + if (ret != -ETIMEDOUT)
> + break;
> + }
> +
> + if (ret == -ETIMEDOUT)
> + dev_err(panel->dev, "Prepare timeout after %d tries\n", try);
> + else if (try)
> + dev_warn(panel->dev, "Prepare needed %d retries\n", try);
> +