drm/tilcdc: Enable and disable interrupts in crtc start() and stop()
authorJyri Sarha <jsarha@ti.com>
Tue, 21 Jun 2016 13:00:44 +0000 (16:00 +0300)
committerJyri Sarha <jsarha@ti.com>
Mon, 8 Aug 2016 20:05:15 +0000 (23:05 +0300)
Enable and disable interrupts in crtc start() and stop(). None of the
interrupts can fire if CRTC is disabled, so it is cleaner - when
considering suspend/resume code etc. - to enable the interrupts when
CRTC is turned on and to disable them when CRTC is turned off.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
drivers/gpu/drm/tilcdc/tilcdc_drv.c

index 3d6000c..773bee2 100644 (file)
@@ -89,6 +89,41 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
        tilcdc_crtc->curr_fb = fb;
 }
 
+static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
+{
+       struct tilcdc_drm_private *priv = dev->dev_private;
+
+       tilcdc_clear_irqstatus(dev, 0xffffffff);
+
+       if (priv->rev == 1) {
+               tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
+                       LCDC_V1_UNDERFLOW_INT_ENA);
+       } else {
+               tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG,
+                       LCDC_V2_UNDERFLOW_INT_ENA |
+                       LCDC_V2_END_OF_FRAME0_INT_ENA |
+                       LCDC_FRAME_DONE | LCDC_SYNC_LOST);
+       }
+}
+
+static void tilcdc_crtc_disable_irqs(struct drm_device *dev)
+{
+       struct tilcdc_drm_private *priv = dev->dev_private;
+
+       /* disable irqs that we might have enabled: */
+       if (priv->rev == 1) {
+               tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
+                       LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
+               tilcdc_clear(dev, LCDC_DMA_CTRL_REG,
+                       LCDC_V1_END_OF_FRAME_INT_ENA);
+       } else {
+               tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
+                       LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA |
+                       LCDC_V2_END_OF_FRAME0_INT_ENA |
+                       LCDC_FRAME_DONE | LCDC_SYNC_LOST);
+       }
+}
+
 static void reset(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -108,6 +143,8 @@ static void start(struct drm_crtc *crtc)
 
        reset(crtc);
 
+       tilcdc_crtc_enable_irqs(dev);
+
        tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE);
        tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY));
        tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE);
@@ -138,6 +175,8 @@ static void stop(struct drm_crtc *crtc)
        }
 
        drm_crtc_vblank_off(crtc);
+
+       tilcdc_crtc_disable_irqs(dev);
 }
 
 static void tilcdc_crtc_destroy(struct drm_crtc *crtc)
index 576e4e1..d612d03 100644 (file)
@@ -192,9 +192,7 @@ static int tilcdc_unload(struct drm_device *dev)
        drm_mode_config_cleanup(dev);
        drm_vblank_cleanup(dev);
 
-       pm_runtime_get_sync(dev->dev);
        drm_irq_uninstall(dev);
-       pm_runtime_put_sync(dev->dev);
 
 #ifdef CONFIG_CPU_FREQ
        cpufreq_unregister_notifier(&priv->freq_transition,
@@ -350,9 +348,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
                goto fail_external_cleanup;
        }
 
-       pm_runtime_get_sync(dev->dev);
        ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
-       pm_runtime_put_sync(dev->dev);
        if (ret < 0) {
                dev_err(dev->dev, "failed to install IRQ handler\n");
                goto fail_vblank_cleanup;
@@ -382,9 +378,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
        return 0;
 
 fail_irq_uninstall:
-       pm_runtime_get_sync(dev->dev);
        drm_irq_uninstall(dev);
-       pm_runtime_put_sync(dev->dev);
 
 fail_vblank_cleanup:
        drm_vblank_cleanup(dev);
@@ -435,45 +429,6 @@ static irqreturn_t tilcdc_irq(int irq, void *arg)
        return tilcdc_crtc_irq(priv->crtc);
 }
 
-static void tilcdc_irq_preinstall(struct drm_device *dev)
-{
-       tilcdc_clear_irqstatus(dev, 0xffffffff);
-}
-
-static int tilcdc_irq_postinstall(struct drm_device *dev)
-{
-       struct tilcdc_drm_private *priv = dev->dev_private;
-
-       /* enable FIFO underflow irq: */
-       if (priv->rev == 1) {
-               tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA);
-       } else {
-               tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG,
-                          LCDC_V2_UNDERFLOW_INT_ENA |
-                          LCDC_V2_END_OF_FRAME0_INT_ENA |
-                          LCDC_FRAME_DONE | LCDC_SYNC_LOST);
-       }
-
-       return 0;
-}
-
-static void tilcdc_irq_uninstall(struct drm_device *dev)
-{
-       struct tilcdc_drm_private *priv = dev->dev_private;
-
-       /* disable irqs that we might have enabled: */
-       if (priv->rev == 1) {
-               tilcdc_clear(dev, LCDC_RASTER_CTRL_REG,
-                               LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA);
-               tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA);
-       } else {
-               tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG,
-                       LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA |
-                       LCDC_V2_END_OF_FRAME0_INT_ENA |
-                       LCDC_FRAME_DONE | LCDC_SYNC_LOST);
-       }
-}
-
 static int tilcdc_enable_vblank(struct drm_device *dev, unsigned int pipe)
 {
        return 0;
@@ -616,9 +571,6 @@ static struct drm_driver tilcdc_driver = {
        .unload             = tilcdc_unload,
        .lastclose          = tilcdc_lastclose,
        .irq_handler        = tilcdc_irq,
-       .irq_preinstall     = tilcdc_irq_preinstall,
-       .irq_postinstall    = tilcdc_irq_postinstall,
-       .irq_uninstall      = tilcdc_irq_uninstall,
        .get_vblank_counter = drm_vblank_no_hw_counter,
        .enable_vblank      = tilcdc_enable_vblank,
        .disable_vblank     = tilcdc_disable_vblank,