Merge tag 'memblock-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rppt...
[linux-2.6-microblaze.git] / drivers / gpu / drm / mediatek / mtk_drm_crtc.c
index d661edf..ede435d 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/soc/mediatek/mtk-mutex.h>
 
 #include <asm/barrier.h>
-#include <soc/mediatek/smi.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -56,6 +55,7 @@ struct mtk_drm_crtc {
        struct cmdq_pkt                 cmdq_handle;
        u32                             cmdq_event;
        u32                             cmdq_vblank_cnt;
+       wait_queue_head_t               cb_blocking_queue;
 #endif
 
        struct device                   *mmsys_dev;
@@ -314,6 +314,7 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
        }
 
        mtk_crtc->cmdq_vblank_cnt = 0;
+       wake_up(&mtk_crtc->cb_blocking_queue);
 }
 #endif
 
@@ -661,15 +662,15 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 
-       ret = mtk_smi_larb_get(comp->larb_dev);
-       if (ret) {
-               DRM_ERROR("Failed to get larb: %d\n", ret);
+       ret = pm_runtime_resume_and_get(comp->dev);
+       if (ret < 0) {
+               DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
                return;
        }
 
        ret = mtk_crtc_ddp_hw_init(mtk_crtc);
        if (ret) {
-               mtk_smi_larb_put(comp->larb_dev);
+               pm_runtime_put(comp->dev);
                return;
        }
 
@@ -682,7 +683,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 {
        struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
        struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
-       int i;
+       int i, ret;
 
        DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
        if (!mtk_crtc->enabled)
@@ -700,12 +701,21 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
        mtk_crtc->pending_planes = true;
 
        mtk_drm_crtc_update_config(mtk_crtc, false);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+       /* Wait for planes to be disabled by cmdq */
+       if (mtk_crtc->cmdq_client.chan)
+               wait_event_timeout(mtk_crtc->cb_blocking_queue,
+                                  mtk_crtc->cmdq_vblank_cnt == 0,
+                                  msecs_to_jiffies(500));
+#endif
        /* Wait for planes to be disabled */
        drm_crtc_wait_one_vblank(crtc);
 
        drm_crtc_vblank_off(crtc);
        mtk_crtc_ddp_hw_fini(mtk_crtc);
-       mtk_smi_larb_put(comp->larb_dev);
+       ret = pm_runtime_put(comp->dev);
+       if (ret < 0)
+               DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
 
        mtk_crtc->enabled = false;
 }
@@ -976,6 +986,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                                mtk_crtc->cmdq_client.chan = NULL;
                        }
                }
+
+               /* for sending blocking cmd in crtc disable */
+               init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
        }
 #endif
        return 0;