dri-devel.lists.freedesktop.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).