MLK-17889 drm/imx: dpu: crtc: Enable irqs before HWs are triggered in ->enable
authorLiu Ying <victor.liu@nxp.com>
Thu, 22 Mar 2018 03:43:46 +0000 (11:43 +0800)
committerHaibo Chen <haibo.chen@nxp.com>
Thu, 12 Apr 2018 10:45:55 +0000 (18:45 +0800)
We should enable irqs before HWs are triggered in ->enable and then
wait for shadow loads are done, otherwise we would miss the irqs if
the irqs come right after the triggers although it's not very likely
to happen.

Signed-off-by: Liu Ying <victor.liu@nxp.com>
drivers/gpu/drm/imx/dpu/dpu-crtc.c

index 5b7a08c..39677d9 100644 (file)
@@ -90,19 +90,23 @@ crtc_state_get_dpu_plane_states(struct drm_crtc_state *state)
 static void dpu_crtc_enable(struct drm_crtc *crtc)
 {
        struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+       struct dpu_plane *dplane = to_dpu_plane(crtc->primary);
+       struct dpu_plane_res *res = &dplane->grp->res;
+       struct dpu_extdst *plane_ed = res->ed[dplane->stream_id];
        unsigned long ret;
 
        drm_crtc_vblank_on(crtc);
 
+       enable_irq(dpu_crtc->safety_shdld_irq);
+       enable_irq(dpu_crtc->content_shdld_irq);
+       enable_irq(dpu_crtc->dec_shdld_irq);
+
        framegen_enable_clock(dpu_crtc->fg);
+       extdst_pixengcfg_sync_trigger(plane_ed);
        extdst_pixengcfg_sync_trigger(dpu_crtc->ed);
        framegen_shdtokgen(dpu_crtc->fg);
        framegen_enable(dpu_crtc->fg);
 
-       enable_irq(dpu_crtc->safety_shdld_irq);
-       enable_irq(dpu_crtc->content_shdld_irq);
-       enable_irq(dpu_crtc->dec_shdld_irq);
-
        ret = wait_for_completion_timeout(&dpu_crtc->safety_shdld_done, HZ);
        if (ret == 0)
                dev_warn(dpu_crtc->dev,
@@ -404,12 +408,11 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
        if (!crtc->state->active && !old_crtc_state->active)
                return;
 
-       if (!need_modeset)
+       if (!need_modeset) {
                enable_irq(dpu_crtc->content_shdld_irq);
 
-       extdst_pixengcfg_sync_trigger(ed);
+               extdst_pixengcfg_sync_trigger(ed);
 
-       if (!need_modeset) {
                ret = wait_for_completion_timeout(&dpu_crtc->content_shdld_done,
                                                  HZ);
                if (ret == 0)
@@ -427,6 +430,8 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
 
                        crtc->state->event = NULL;
                }
+       } else if (!crtc->state->active) {
+               extdst_pixengcfg_sync_trigger(ed);
        }
 
        for (i = 0; i < dpu_crtc->hw_plane_num; i++) {