summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 72e413e)
raw | patch | inline | side by side (parent: 72e413e)
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | |
Wed, 19 Nov 2014 10:50:14 +0000 (12:50 +0200) | ||
committer | Jyri Sarha <jsarha@ti.com> | |
Fri, 21 Nov 2014 14:10:23 +0000 (16:10 +0200) |
omapdrm tries to avoid error floods by unregistering the error irq when
an error happens, and then registering the error irq again later.
However, the code is racy, as it sometimes tries to unregister the error
irq when it's already unregistered, leading to WARN().
Also, the code only registers the error irq again when something is done
on that particular output, i.e. if only TV is used to flip the buffers,
and LCD is showing a same buffer, an error on LCD will cause the LCD
error irq to be unregistered and never registered again.
To fix this, let's keep the error irqs always enabled and trust the
DRM_ERROR_RATELIMITED to limit the flood.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
an error happens, and then registering the error irq again later.
However, the code is racy, as it sometimes tries to unregister the error
irq when it's already unregistered, leading to WARN().
Also, the code only registers the error irq again when something is done
on that particular output, i.e. if only TV is used to flip the buffers,
and LCD is showing a same buffer, an error on LCD will cause the LCD
error irq to be unregistered and never registered again.
To fix this, let's keep the error irqs always enabled and trust the
DRM_ERROR_RATELIMITED to limit the flood.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
drivers/gpu/drm/omapdrm/omap_crtc.c | patch | blob | history |
index 953820fb3ba623084aedae38baffe6e006e2613a..1cb87ff53aeff598c15891ddcc9803364e8879bb 100644 (file)
* XXX maybe fold into apply_work??
*/
struct work_struct page_flip_work;
+
+ bool ignore_digit_sync_lost;
};
uint32_t pipe2vbl(struct drm_crtc *crtc)
{
struct omap_crtc *omap_crtc =
container_of(irq, struct omap_crtc, error_irq);
- struct drm_crtc *crtc = &omap_crtc->base;
+
+ if (omap_crtc->ignore_digit_sync_lost) {
+ irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+ if (!irqstatus)
+ return;
+ }
+
DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
- /* avoid getting in a flood, unregister the irq until next vblank */
- __omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
}
static void omap_crtc_apply_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
container_of(irq, struct omap_crtc, apply_irq);
struct drm_crtc *crtc = &omap_crtc->base;
- if (!omap_crtc->error_irq.registered)
- __omap_irq_register(crtc->dev, &omap_crtc->error_irq);
-
/* make sure we see the most recent 'go_bit_set' */
rmb();
if (omap_crtc->go_bit_set && !dispc_mgr_go_busy(omap_crtc->channel)) {
* Digit output produces some sync lost interrupts during the first
* frame when enabling, so we need to ignore those.
*/
- omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
+ omap_crtc->ignore_digit_sync_lost = true;
framedone_irq = dispc_mgr_get_framedone_irq(channel);
vsync_irq = dispc_mgr_get_vsync_irq(channel);
omap_crtc->name, enable ? "enable" : "disable");
}
- omap_irq_register(crtc->dev, &omap_crtc->error_irq);
+ omap_crtc->ignore_digit_sync_lost = false;
+ /* make sure the irq handler sees the value above */
+ mb();
}
static void omap_crtc_pre_apply(struct omap_drm_apply *apply)