All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC
@ 2016-04-08  9:31 Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function Jyri Sarha
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jyri Sarha @ 2016-04-08  9:31 UTC (permalink / raw)
  To: dri-devel; +Cc: Jyri Sarha, tomi.valkeinen, laurent.pinchart

Since first version:
- Add "drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function"
  - This is actually an independent fix (see patch description)
- Add "drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop()"
  - Wait for LCDC_FRAME_DONE before reseting the LCDC
- Fix typo in description
- Use system work queue
- Check DPMS state after drm_modeset_lock_crtc() has been taken

Jyri Sarha (3):
  drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ
    function
  drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop()
  drm/tilcdc: Recover from sync lost error flood by resetting the LCDC

 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 83 +++++++++++++++++++++++++-----------
 1 file changed, 58 insertions(+), 25 deletions(-)

-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function
  2016-04-08  9:31 [PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC Jyri Sarha
@ 2016-04-08  9:31 ` Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 2/3] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop() Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 3/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC Jyri Sarha
  2 siblings, 0 replies; 4+ messages in thread
From: Jyri Sarha @ 2016-04-08  9:31 UTC (permalink / raw)
  To: dri-devel; +Cc: Jyri Sarha, tomi.valkeinen, laurent.pinchart

Reorder the IRQ function so that the write to LCDC_END_OF_INT_IND_REG
is done last. The write to LCDC_END_OF_INT_IND_REG indicates to LCDC
that the interrupt service routine has completed (see section
13.3.6.1.6 in AM335x TRM). This is needed if LCDC's ipgvmodirq module
is configured for pulse interrupts.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 051e5e1..a06e73a 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -718,14 +718,19 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
 			tilcdc_crtc->frame_intact = true;
 	}
 
-	if (priv->rev == 2) {
-		if (stat & LCDC_FRAME_DONE) {
-			tilcdc_crtc->frame_done = true;
-			wake_up(&tilcdc_crtc->frame_done_wq);
-		}
-		tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
+	if (priv->rev == 1)
+		return IRQ_HANDLED;
+	/* The rest is for revision 2 only */
+
+	if (stat & LCDC_FRAME_DONE) {
+		tilcdc_crtc->frame_done = true;
+		wake_up(&tilcdc_crtc->frame_done_wq);
 	}
 
+	if (stat & LCDC_FIFO_UNDERFLOW)
+		dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow",
+				    __func__, stat);
+
 	if (stat & LCDC_SYNC_LOST) {
 		dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost",
 				    __func__, stat);
@@ -739,9 +744,10 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
 		}
 	}
 
-	if (stat & LCDC_FIFO_UNDERFLOW)
-		dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow",
-				    __func__, stat);
+	/* Indicate to LCDC that the interrupt service routine has
+	 * completed, see 13.3.6.1.6 in AM335x TRM.
+	 */
+	tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0);
 
 	return IRQ_HANDLED;
 }
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/3] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop()
  2016-04-08  9:31 [PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function Jyri Sarha
@ 2016-04-08  9:31 ` Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 3/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC Jyri Sarha
  2 siblings, 0 replies; 4+ messages in thread
From: Jyri Sarha @ 2016-04-08  9:31 UTC (permalink / raw)
  To: dri-devel; +Cc: Jyri Sarha, tomi.valkeinen, laurent.pinchart

Move wait queue waiting of LCDC_FRAME_DONE IRQ from tilcdc_crtc_dpms()
into stop() function.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index a06e73a..7a5cc03 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -113,9 +113,25 @@ static void start(struct drm_crtc *crtc)
 
 static void stop(struct drm_crtc *crtc)
 {
+	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
 	struct drm_device *dev = crtc->dev;
+	struct tilcdc_drm_private *priv = dev->dev_private;
 
+	tilcdc_crtc->frame_done = false;
 	tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+
+	/*
+	 * if necessary wait for framedone irq which will still come
+	 * before putting things to sleep..
+	 */
+	if (priv->rev == 2) {
+		int ret = wait_event_timeout(tilcdc_crtc->frame_done_wq,
+					     tilcdc_crtc->frame_done,
+					     msecs_to_jiffies(50));
+		if (ret == 0)
+			dev_err(dev->dev, "%s: timeout waiting for framedone\n",
+				__func__);
+	}
 }
 
 static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
@@ -212,22 +228,7 @@ void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode)
 		pm_runtime_get_sync(dev->dev);
 		start(crtc);
 	} else {
-		tilcdc_crtc->frame_done = false;
 		stop(crtc);
-
-		/*
-		 * if necessary wait for framedone irq which will still come
-		 * before putting things to sleep..
-		 */
-		if (priv->rev == 2) {
-			int ret = wait_event_timeout(
-					tilcdc_crtc->frame_done_wq,
-					tilcdc_crtc->frame_done,
-					msecs_to_jiffies(50));
-			if (ret == 0)
-				dev_err(dev->dev, "timeout waiting for framedone\n");
-		}
-
 		pm_runtime_put_sync(dev->dev);
 
 		if (tilcdc_crtc->next_fb) {
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 3/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC
  2016-04-08  9:31 [PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function Jyri Sarha
  2016-04-08  9:31 ` [PATCH v2 2/3] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop() Jyri Sarha
@ 2016-04-08  9:31 ` Jyri Sarha
  2 siblings, 0 replies; 4+ messages in thread
From: Jyri Sarha @ 2016-04-08  9:31 UTC (permalink / raw)
  To: dri-devel; +Cc: Jyri Sarha, tomi.valkeinen, laurent.pinchart

Recover from sync lost error flood by resetting the LCDC instead of
turning off the SYNC_LOST error IRQ. When LCDC starves on limited
memory bandwidth it may sometimes result an error situation when the
picture may have shifted couple of pixels to right and SYNC_LOST
interrupt is generated on every frame. LCDC main reset recovers from
this situation and causes a brief blanking on the screen.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
---
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index 7a5cc03..6dce763 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -46,6 +46,7 @@ struct tilcdc_crtc {
 
 	int sync_lost_count;
 	bool frame_intact;
+	struct work_struct recover_work;
 };
 #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
 
@@ -134,6 +135,28 @@ static void stop(struct drm_crtc *crtc)
 	}
 }
 
+static void tilcdc_crtc_recover_work(struct work_struct *work)
+{
+	struct tilcdc_crtc *tilcdc_crtc =
+		container_of(work, struct tilcdc_crtc, recover_work);
+	struct drm_crtc *crtc = &tilcdc_crtc->base;
+	struct drm_device *dev = crtc->dev;
+
+	dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__);
+
+	drm_modeset_lock_crtc(crtc, NULL);
+
+	if (tilcdc_crtc->dpms == DRM_MODE_DPMS_OFF)
+		goto out;
+
+	tilcdc_crtc->frame_done = false;
+	stop(crtc);
+	tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_SYNC_LOST);
+	start(crtc);
+out:
+	drm_modeset_unlock_crtc(crtc);
+}
+
 static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
@@ -738,10 +761,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc)
 		tilcdc_crtc->frame_intact = false;
 		if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) {
 			dev_err(dev->dev,
-				"%s(0x%08x): Sync lost flood detected, disabling the interrupt",
+				"%s(0x%08x): Sync lost flood detected, recovering",
 				__func__, stat);
+			queue_work(system_wq, &tilcdc_crtc->recover_work);
 			tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
 				     LCDC_SYNC_LOST);
+			tilcdc_crtc->sync_lost_count = 0;
 		}
 	}
 
@@ -775,6 +800,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev)
 			"unref", unref_worker);
 
 	spin_lock_init(&tilcdc_crtc->irq_lock);
+	INIT_WORK(&tilcdc_crtc->recover_work, tilcdc_crtc_recover_work);
 
 	ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs);
 	if (ret < 0)
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-04-08  9:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-08  9:31 [PATCH v2 0/3] Recover from sync lost error flood by resetting the LCDC Jyri Sarha
2016-04-08  9:31 ` [PATCH v2 1/3] drm/tilcdc: Write to LCDC_END_OF_INT_IND_REG at the end of IRQ function Jyri Sarha
2016-04-08  9:31 ` [PATCH v2 2/3] drm/tilcdc: Move waiting of LCDC_FRAME_DONE IRQ into stop() Jyri Sarha
2016-04-08  9:31 ` [PATCH v2 3/3] drm/tilcdc: Recover from sync lost error flood by resetting the LCDC Jyri Sarha

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.