drm/tilcdc: Enable and disable interrupts in crtc start() and stop()
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>
This commit is contained in:
Родитель
018cfbde63
Коммит
afaf833dd5
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче