diff options
author | Jyri Sarha <jsarha@ti.com> | 2016-01-08 07:33:09 -0500 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2016-02-25 09:39:45 -0500 |
commit | 5895d08f6ff2175dabc373dada7d1bfa26123fc9 (patch) | |
tree | ba01bad72821ac99d67b5f21868b002662d935be /drivers/gpu/drm/tilcdc | |
parent | c0c2baaab1b553df92a24e9175440f15e6ad3e2c (diff) |
drm/tilcdc: Disable sync lost interrupt if it fires on every frame
Disable the sync lost interrupt if it fires on every frame for 50
consecutive frames in a row. This is relatively sure sign of the sync
lost interrupt being stuck and firing on every frame even if the
display otherwise appears to work OK.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 5ee22c6b37e8..248e3ea7568c 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c | |||
@@ -43,6 +43,9 @@ struct tilcdc_crtc { | |||
43 | 43 | ||
44 | /* Only set if an external encoder is connected */ | 44 | /* Only set if an external encoder is connected */ |
45 | bool simulate_vesa_sync; | 45 | bool simulate_vesa_sync; |
46 | |||
47 | int sync_lost_count; | ||
48 | bool frame_intact; | ||
46 | }; | 49 | }; |
47 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) | 50 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) |
48 | 51 | ||
@@ -662,6 +665,8 @@ out: | |||
662 | pm_runtime_put_sync(dev->dev); | 665 | pm_runtime_put_sync(dev->dev); |
663 | } | 666 | } |
664 | 667 | ||
668 | #define SYNC_LOST_COUNT_LIMIT 50 | ||
669 | |||
665 | irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) | 670 | irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) |
666 | { | 671 | { |
667 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); | 672 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); |
@@ -707,6 +712,11 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) | |||
707 | 712 | ||
708 | spin_unlock_irqrestore(&dev->event_lock, flags); | 713 | spin_unlock_irqrestore(&dev->event_lock, flags); |
709 | } | 714 | } |
715 | |||
716 | if (tilcdc_crtc->frame_intact) | ||
717 | tilcdc_crtc->sync_lost_count = 0; | ||
718 | else | ||
719 | tilcdc_crtc->frame_intact = true; | ||
710 | } | 720 | } |
711 | 721 | ||
712 | if (priv->rev == 2) { | 722 | if (priv->rev == 2) { |
@@ -717,9 +727,18 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) | |||
717 | tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); | 727 | tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); |
718 | } | 728 | } |
719 | 729 | ||
720 | if (stat & LCDC_SYNC_LOST) | 730 | if (stat & LCDC_SYNC_LOST) { |
721 | dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", | 731 | dev_err_ratelimited(dev->dev, "%s(0x%08x): Sync lost", |
722 | __func__, stat); | 732 | __func__, stat); |
733 | tilcdc_crtc->frame_intact = false; | ||
734 | if (tilcdc_crtc->sync_lost_count++ > SYNC_LOST_COUNT_LIMIT) { | ||
735 | dev_err(dev->dev, | ||
736 | "%s(0x%08x): Sync lost flood detected, disabling the interrupt", | ||
737 | __func__, stat); | ||
738 | tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, | ||
739 | LCDC_SYNC_LOST); | ||
740 | } | ||
741 | } | ||
723 | 742 | ||
724 | if (stat & LCDC_FIFO_UNDERFLOW) | 743 | if (stat & LCDC_FIFO_UNDERFLOW) |
725 | dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", | 744 | dev_err_ratelimited(dev->dev, "%s(0x%08x): FIFO underfow", |