summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/panel')
-rw-r--r--drivers/gpu/drm/panel/panel-simple.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index e8634c146270..8f255087ffd8 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -376,7 +376,7 @@ static int panel_simple_get_hpd_gpio(struct device *dev,
return 0;
}
-static int panel_simple_prepare(struct drm_panel *panel)
+static int panel_simple_prepare_once(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);
unsigned int delay;
@@ -422,8 +422,9 @@ static int panel_simple_prepare(struct drm_panel *panel)
err = hpd_asserted;
if (err) {
- dev_err(panel->dev,
- "error waiting for hpd GPIO: %d\n", err);
+ if (err != -ETIMEDOUT)
+ dev_err(panel->dev,
+ "error waiting for hpd GPIO: %d\n", err);
goto error;
}
}
@@ -440,6 +441,31 @@ error:
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
+
+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);
+
+ return ret;
+}
+
static int panel_simple_enable(struct drm_panel *panel)
{
struct panel_simple *p = to_panel_simple(panel);