diff options
author | Jyri Sarha <jsarha@ti.com> | 2016-04-06 07:02:38 -0400 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2016-11-30 07:14:40 -0500 |
commit | 13b3d72705817cdcf003226dd9f22f3ecee64ba4 (patch) | |
tree | 6ea4f220a76be5661e7d485c97736c93aecacbea | |
parent | 2d53a18098e5a03a30b1b1419ab4103357b69f0d (diff) |
drm/tilcdc: Recover from sync lost error flood by resetting the LCDC
Recover from sync lost error flood by resetting the LCDC instead of
turning off the SYNC_LOST error IRQ. When LCDC starves on limited
memory bandwidth it may sometimes result an error situation when the
picture may have shifted couple of pixels to right and SYNC_LOST
interrupt is generated on every frame. LCDC main reset recovers from
this situation and causes a brief blanking on the screen.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Tested-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
-rw-r--r-- | drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c index 0d09acce4916..c7873493f506 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_crtc.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_crtc.c | |||
@@ -55,6 +55,7 @@ struct tilcdc_crtc { | |||
55 | 55 | ||
56 | int sync_lost_count; | 56 | int sync_lost_count; |
57 | bool frame_intact; | 57 | bool frame_intact; |
58 | struct work_struct recover_work; | ||
58 | }; | 59 | }; |
59 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) | 60 | #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) |
60 | 61 | ||
@@ -252,6 +253,25 @@ static bool tilcdc_crtc_is_on(struct drm_crtc *crtc) | |||
252 | return crtc->state && crtc->state->enable && crtc->state->active; | 253 | return crtc->state && crtc->state->enable && crtc->state->active; |
253 | } | 254 | } |
254 | 255 | ||
256 | static void tilcdc_crtc_recover_work(struct work_struct *work) | ||
257 | { | ||
258 | struct tilcdc_crtc *tilcdc_crtc = | ||
259 | container_of(work, struct tilcdc_crtc, recover_work); | ||
260 | struct drm_crtc *crtc = &tilcdc_crtc->base; | ||
261 | |||
262 | dev_info(crtc->dev->dev, "%s: Reset CRTC", __func__); | ||
263 | |||
264 | drm_modeset_lock_crtc(crtc, NULL); | ||
265 | |||
266 | if (!tilcdc_crtc_is_on(crtc)) | ||
267 | goto out; | ||
268 | |||
269 | tilcdc_crtc_disable(crtc); | ||
270 | tilcdc_crtc_enable(crtc); | ||
271 | out: | ||
272 | drm_modeset_unlock_crtc(crtc); | ||
273 | } | ||
274 | |||
255 | static void tilcdc_crtc_destroy(struct drm_crtc *crtc) | 275 | static void tilcdc_crtc_destroy(struct drm_crtc *crtc) |
256 | { | 276 | { |
257 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); | 277 | struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); |
@@ -838,9 +858,12 @@ irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) | |||
838 | tilcdc_crtc->frame_intact = false; | 858 | tilcdc_crtc->frame_intact = false; |
839 | if (tilcdc_crtc->sync_lost_count++ > | 859 | if (tilcdc_crtc->sync_lost_count++ > |
840 | SYNC_LOST_COUNT_LIMIT) { | 860 | SYNC_LOST_COUNT_LIMIT) { |
841 | dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, disabling the interrupt", __func__, stat); | 861 | dev_err(dev->dev, "%s(0x%08x): Sync lost flood detected, recovering", __func__, stat); |
862 | queue_work(system_wq, | ||
863 | &tilcdc_crtc->recover_work); | ||
842 | tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, | 864 | tilcdc_write(dev, LCDC_INT_ENABLE_CLR_REG, |
843 | LCDC_SYNC_LOST); | 865 | LCDC_SYNC_LOST); |
866 | tilcdc_crtc->sync_lost_count = 0; | ||
844 | } | 867 | } |
845 | } | 868 | } |
846 | 869 | ||
@@ -880,6 +903,7 @@ struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) | |||
880 | "unref", unref_worker); | 903 | "unref", unref_worker); |
881 | 904 | ||
882 | spin_lock_init(&tilcdc_crtc->irq_lock); | 905 | spin_lock_init(&tilcdc_crtc->irq_lock); |
906 | INIT_WORK(&tilcdc_crtc->recover_work, tilcdc_crtc_recover_work); | ||
883 | 907 | ||
884 | ret = drm_crtc_init_with_planes(dev, crtc, | 908 | ret = drm_crtc_init_with_planes(dev, crtc, |
885 | &tilcdc_crtc->primary, | 909 | &tilcdc_crtc->primary, |