diff mbox

[BISECTED,REGRESSION] v4.12-rc: omapdrm fails to probe on Nokia N900

Message ID ef561ff4-c96d-b59c-0df1-dfcac8163259@ti.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomi Valkeinen June 30, 2017, 8:47 a.m. UTC
On 30/06/17 09:41, Tomi Valkeinen wrote:

> So, I don't know... I guess I need to try to invent some horrible hacks
> around the driver to somehow manage the omap3 problems. Perhaps
> disabling/enabling the outputs when sync lost happens...

Well, I tried that (attached), but it didn't work either. For some
reason the error worker seems to stop after the disable. Possibly the
irq flood keeps it from running, so maybe it should catch all the errors
(I see underflows too).

Sorry, but I can't use more time on this today, and I'm leaving for
vacation today. I hope Laurent can help during my absence.

We could try reverting the patch you mention, but I think it doesn't
cause the problem.

Did you have CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV enabled earlier when
things worked? If you didn't, and the dts did not contain display
aliases, I think the omapdrm may have started without TV. So maybe the
TV side is the culprit, somehow (I couldn't find anything when I looked
at that side either).

 Tomi

Comments

Aaro Koskinen June 30, 2017, 9:37 a.m. UTC | #1
Hi,

On Fri, Jun 30, 2017 at 11:47:55AM +0300, Tomi Valkeinen wrote:
> > So, I don't know... I guess I need to try to invent some horrible hacks
> > around the driver to somehow manage the omap3 problems. Perhaps
> > disabling/enabling the outputs when sync lost happens...
> 
> Well, I tried that (attached), but it didn't work either. For some
> reason the error worker seems to stop after the disable. Possibly the
> irq flood keeps it from running, so maybe it should catch all the errors
> (I see underflows too).
> 
> Sorry, but I can't use more time on this today, and I'm leaving for
> vacation today. I hope Laurent can help during my absence.
> 
> We could try reverting the patch you mention, but I think it doesn't
> cause the problem.

True, reverting the patch only allows me to use display without connector.
And apparently it just works by luck.

> Did you have CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV enabled earlier when
> things worked?

No. I have never enabled it before, I didn't even know it was supported
by the mainline.

> If you didn't, and the dts did not contain display aliases, I think the
> omapdrm may have started without TV. So maybe the TV side is the culprit,
> somehow (I couldn't find anything when I looked at that side either).

Could be. 

Here is the summary from my testing:

0) v4.17-rc7 + connector disabled

	==> nothing happens, omapdrm waits forever for connector driver

1) v4.17-rc7 + connector disabled +
   Revert "drm/omap: Use omapdss_stack_is_ready()"

	==> LCD error flood, system unusable

2) v4.17-rc7 + connector disabled +
   Revert "drm/omap: Use omapdss_stack_is_ready()" +
   Apply "drm/omap: work-around for omap3 display enable"

	==> display works!

3) v4.17-rc7 + connector enabled +
   Revert "drm/omap: Use omapdss_stack_is_ready()" +
   Apply "drm/omap: work-around for omap3 display enable"

	==> LCD error flood, system unusable

4) v4.17-rc7 + connector enabled +
   Apply "drm/omap: work-around for omap3 display enable"

	==> LCD error flood, system unusable

A.
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Clayton Craft July 21, 2017, 1:28 a.m. UTC | #2
> Well, I tried that (attached), but it didn't work either. For some
> reason the error worker seems to stop after the disable. Possibly the
> irq flood keeps it from running, so maybe it should catch all the errors
> (I see underflows too).
> 
> Sorry, but I can't use more time on this today, and I'm leaving for
> vacation today. I hope Laurent can help during my absence.
> 
> We could try reverting the patch you mention, but I think it doesn't
> cause the problem.
> 
> Did you have CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV enabled earlier when
> things worked? If you didn't, and the dts did not contain display
> aliases, I think the omapdrm may have started without TV. So maybe the
> TV side is the culprit, somehow (I couldn't find anything when I looked
> at that side either).

Just curious if any progress has been made on this issue. It's still
happening with 4.13-rc1, and it doesn't look like any of the suspect
patches were reverted.
diff mbox

Patch

From c4ceb8934dbfa51bc966b927b17394c4b622712c Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Fri, 30 Jun 2017 11:39:53 +0300
Subject: [PATCH] drm/omap: hack error worker

---
 drivers/gpu/drm/omapdrm/omap_crtc.c | 69 ++++++++++++++++++++++++++++++++-----
 1 file changed, 61 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index dccd03726796..eb36b35f5eb8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -36,12 +36,15 @@  struct omap_crtc {
 
 	struct videomode vm;
 
-	bool ignore_digit_sync_lost;
+	bool ignore_sync_lost;
 
 	bool enabled;
 	bool pending;
 	wait_queue_head_t pending_wait;
 	struct drm_pending_vblank_event *event;
+
+	struct work_struct error_work;
+	u32 error_channels;
 };
 
 /* -----------------------------------------------------------------------------
@@ -157,7 +160,7 @@  static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 		 * Digit output produces some sync lost interrupts during the
 		 * first frame when enabling, so we need to ignore those.
 		 */
-		omap_crtc->ignore_digit_sync_lost = true;
+		omap_crtc->ignore_sync_lost = true;
 	}
 
 	framedone_irq = priv->dispc_ops->mgr_get_framedone_irq(channel);
@@ -191,7 +194,7 @@  static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
 	}
 
 	if (omap_crtc->channel == OMAP_DSS_CHANNEL_DIGIT) {
-		omap_crtc->ignore_digit_sync_lost = false;
+		omap_crtc->ignore_sync_lost = false;
 		/* make sure the irq handler sees the value above */
 		mb();
 	}
@@ -263,17 +266,65 @@  static const struct dss_mgr_ops mgr_ops = {
  * Setup, Flush and Page Flip
  */
 
+static void omap_crtc_error_worker(struct work_struct *work)
+{
+	struct omap_crtc *omap_crtc = container_of(work, struct omap_crtc, error_work);
+	struct drm_crtc *crtc = &omap_crtc->base;
+	struct drm_device *dev = omap_crtc->base.dev;
+	struct omap_drm_private *priv = dev->dev_private;
+
+	drm_modeset_lock(&crtc->mutex, NULL);
+
+	dev_warn(dev->dev, "sync lost on %s, enabling & disabling...\n",
+		omap_crtc->name);
+
+	priv->dispc_ops->mgr_enable(omap_crtc->channel, false);
+
+	msleep(50);
+	dev_warn(dev->dev, "sync lost enabling %s\n",
+			omap_crtc->name);
+
+	priv->dispc_ops->mgr_enable(omap_crtc->channel, true);
+
+	msleep(50);
+
+	dev_warn(dev->dev, "sync lost recovery done on on %s\n",
+		omap_crtc->name);
+
+	omap_crtc->ignore_sync_lost = false;
+	/* make sure the irq handler sees the value above */
+	mb();
+
+	drm_modeset_unlock(&crtc->mutex);
+}
+
 void omap_crtc_error_irq(struct drm_crtc *crtc, uint32_t irqstatus)
 {
 	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+	struct drm_device *dev = omap_crtc->base.dev;
+	struct omap_drm_private *priv = dev->dev_private;
+	enum omap_channel channel = omap_crtc_channel(crtc);
+	u32 sync_lost_irq;
+	bool sync_lost;
+
+	sync_lost_irq = priv->dispc_ops->mgr_get_sync_lost_irq(channel);
 
-	if (omap_crtc->ignore_digit_sync_lost) {
-		irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
-		if (!irqstatus)
-			return;
+	sync_lost = irqstatus & sync_lost_irq;
+
+	if (sync_lost) {
+		if (omap_crtc->ignore_sync_lost) {
+			irqstatus &= ~sync_lost_irq;
+		} else {
+			/* error worker will set this to false */
+			omap_crtc->ignore_sync_lost = true;
+			schedule_work(&omap_crtc->error_work);
+		}
 	}
 
-	DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+	if (!irqstatus)
+		return;
+
+	printk("%s: errors: %08x\n", omap_crtc->name, irqstatus);
 }
 
 void omap_crtc_vblank_irq(struct drm_crtc *crtc)
@@ -612,6 +663,8 @@  struct drm_crtc *omap_crtc_init(struct drm_device *dev,
 
 	init_waitqueue_head(&omap_crtc->pending_wait);
 
+	INIT_WORK(&omap_crtc->error_work, omap_crtc_error_worker);
+
 	omap_crtc->channel = channel;
 	omap_crtc->name = channel_names[channel];
 
-- 
2.7.4