[PATCH] drm/tilcdc: Turn raster off in crtc reset, if it was on in the HW

Jyri Sarha jsarha at ti.com
Fri May 26 10:56:03 UTC 2017


This forces the HW to be in sync with the empty state. This should
help with the problem when LCDC is already enabled (e.g. by the
bootloader) at the initialization phase and the enable fails when a
new mode is applied.

Signed-off-by: Jyri Sarha <jsarha at ti.com>
---
There is two earlier patches that try to tackle the same problem:
1. https://lists.freedesktop.org/archives/dri-devel/2017-March/137091.html
  - This supposedly works, but I did not like second guessing if the display
    was already on every we enable the display
2. https://patchwork.kernel.org/patch/9672341/
  - My first attempt to try to fix the problem

The best possible crtc reset callback implementation would be reading
the video mode information from the registers and generating the new
crtc state based on that. But I have no idea what I should do with
framebuffer that was used and how to show that in the state variable.
Anyway, right now I do not have more time to spend with this.

 drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
index d524ed0..9ca134d 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c
@@ -716,11 +716,39 @@ static void tilcdc_crtc_disable_vblank(struct drm_crtc *crtc)
 {
 }
 
+static void tilcdc_crtc_reset(struct drm_crtc *crtc)
+{
+	struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	int ret;
+
+	drm_atomic_helper_crtc_reset(crtc);
+
+	/* Turn the raster off if it for some reason is on. */
+	pm_runtime_get_sync(dev->dev);
+	if (tilcdc_read(dev, LCDC_RASTER_CTRL_REG) & LCDC_RASTER_ENABLE) {
+		/* Enable DMA Frame Done Interrupt */
+		tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG, LCDC_FRAME_DONE);
+		tilcdc_clear_irqstatus(dev, 0xffffffff);
+
+		tilcdc_crtc->frame_done = false;
+		tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
+
+		ret = wait_event_timeout(tilcdc_crtc->frame_done_wq,
+					 tilcdc_crtc->frame_done,
+					 msecs_to_jiffies(500));
+		if (ret == 0)
+			dev_err(dev->dev, "%s: timeout waiting for framedone\n",
+				__func__);
+	}
+	pm_runtime_put_sync(dev->dev);
+}
+
 static const struct drm_crtc_funcs tilcdc_crtc_funcs = {
 	.destroy        = tilcdc_crtc_destroy,
 	.set_config     = drm_atomic_helper_set_config,
 	.page_flip      = drm_atomic_helper_page_flip,
-	.reset		= drm_atomic_helper_crtc_reset,
+	.reset		= tilcdc_crtc_reset,
 	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
 	.enable_vblank	= tilcdc_crtc_enable_vblank,
-- 
1.9.1



More information about the dri-devel mailing list