drm/msm: split power control from prepare/complete_commit
authorRob Clark <robdclark@chromium.org>
Thu, 29 Aug 2019 16:45:15 +0000 (09:45 -0700)
committerRob Clark <robdclark@chromium.org>
Tue, 3 Sep 2019 23:17:01 +0000 (16:17 -0700)
With atomic commit, ->prepare_commit() and ->complete_commit() may not
be evenly balanced (although ->complete_commit() will complete each
crtc that had been previously prepared).  So these will no longer be
a good place to enable/disable clocks needed for hw access.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Sean Paul <sean@poorly.run>
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c
drivers/gpu/drm/msm/msm_atomic.c
drivers/gpu/drm/msm/msm_kms.h

index de6223a..2f0f379 100644 (file)
@@ -250,6 +250,18 @@ static void dpu_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
        dpu_crtc_vblank(crtc, false);
 }
 
+static void dpu_kms_enable_commit(struct msm_kms *kms)
+{
+       struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+       pm_runtime_get_sync(&dpu_kms->pdev->dev);
+}
+
+static void dpu_kms_disable_commit(struct msm_kms *kms)
+{
+       struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+       pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
+
 static void dpu_kms_prepare_commit(struct msm_kms *kms,
                struct drm_atomic_state *state)
 {
@@ -269,7 +281,6 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
        if (!dev || !dev->dev_private)
                return;
        priv = dev->dev_private;
-       pm_runtime_get_sync(&dpu_kms->pdev->dev);
 
        /* Call prepare_commit for all affected encoders */
        for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
@@ -337,8 +348,6 @@ static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
        for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask)
                dpu_crtc_complete_commit(crtc);
 
-       pm_runtime_put_sync(&dpu_kms->pdev->dev);
-
        DPU_ATRACE_END("kms_complete_commit");
 }
 
@@ -684,6 +693,8 @@ static const struct msm_kms_funcs kms_funcs = {
        .irq_preinstall  = dpu_irq_preinstall,
        .irq_uninstall   = dpu_irq_uninstall,
        .irq             = dpu_irq,
+       .enable_commit   = dpu_kms_enable_commit,
+       .disable_commit  = dpu_kms_disable_commit,
        .prepare_commit  = dpu_kms_prepare_commit,
        .flush_commit    = dpu_kms_flush_commit,
        .commit          = dpu_kms_commit,
index 63e7a4a..50711cc 100644 (file)
@@ -96,15 +96,24 @@ out:
        return ret;
 }
 
-static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+static void mdp4_enable_commit(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+       mdp4_enable(mdp4_kms);
+}
+
+static void mdp4_disable_commit(struct msm_kms *kms)
 {
        struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+       mdp4_disable(mdp4_kms);
+}
+
+static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
        int i;
        struct drm_crtc *crtc;
        struct drm_crtc_state *crtc_state;
 
-       mdp4_enable(mdp4_kms);
-
        /* see 119ecb7fd */
        for_each_new_crtc_in_state(state, crtc, crtc_state, i)
                drm_crtc_vblank_get(crtc);
@@ -132,8 +141,6 @@ static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
        /* see 119ecb7fd */
        for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask)
                drm_crtc_vblank_put(crtc);
-
-       mdp4_disable(mdp4_kms);
 }
 
 static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
@@ -185,6 +192,8 @@ static const struct mdp_kms_funcs kms_funcs = {
                .irq             = mdp4_irq,
                .enable_vblank   = mdp4_enable_vblank,
                .disable_vblank  = mdp4_disable_vblank,
+               .enable_commit   = mdp4_enable_commit,
+               .disable_commit  = mdp4_disable_commit,
                .prepare_commit  = mdp4_prepare_commit,
                .flush_commit    = mdp4_flush_commit,
                .wait_flush      = mdp4_wait_flush,
index b374ccd..91cd76a 100644 (file)
@@ -146,16 +146,25 @@ static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
        return 0;
 }
 
+static void mdp5_enable_commit(struct msm_kms *kms)
+{
+       struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+       pm_runtime_get_sync(&mdp5_kms->pdev->dev);
+}
+
+static void mdp5_disable_commit(struct msm_kms *kms)
+{
+       struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+       pm_runtime_put_sync(&mdp5_kms->pdev->dev);
+}
+
 static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-       struct device *dev = &mdp5_kms->pdev->dev;
        struct mdp5_global_state *global_state;
 
        global_state = mdp5_get_existing_global_state(mdp5_kms);
 
-       pm_runtime_get_sync(dev);
-
        if (mdp5_kms->smp)
                mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
 }
@@ -177,15 +186,12 @@ static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
 static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
 {
        struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-       struct device *dev = &mdp5_kms->pdev->dev;
        struct mdp5_global_state *global_state;
 
        global_state = mdp5_get_existing_global_state(mdp5_kms);
 
        if (mdp5_kms->smp)
                mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp);
-
-       pm_runtime_put_sync(dev);
 }
 
 static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
@@ -284,6 +290,8 @@ static const struct mdp_kms_funcs kms_funcs = {
                .enable_vblank   = mdp5_enable_vblank,
                .disable_vblank  = mdp5_disable_vblank,
                .flush_commit    = mdp5_flush_commit,
+               .enable_commit   = mdp5_enable_commit,
+               .disable_commit  = mdp5_disable_commit,
                .prepare_commit  = mdp5_prepare_commit,
                .wait_flush      = mdp5_wait_flush,
                .complete_commit = mdp5_complete_commit,
index 7a1c47c..517d3a7 100644 (file)
@@ -49,6 +49,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
        struct msm_kms *kms = priv->kms;
        unsigned crtc_mask = get_crtc_mask(state);
 
+       kms->funcs->enable_commit(kms);
        kms->funcs->prepare_commit(kms, state);
 
        /*
@@ -69,6 +70,7 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
 
        kms->funcs->wait_flush(kms, crtc_mask);
        kms->funcs->complete_commit(kms, crtc_mask);
+       kms->funcs->disable_commit(kms);
 
        drm_atomic_helper_commit_hw_done(state);
 
index 80bccbf..85264a2 100644 (file)
@@ -35,6 +35,16 @@ struct msm_kms_funcs {
         * Atomic commit handling:
         */
 
+       /**
+        * Enable/disable power/clks needed for hw access done in other
+        * commit related methods.
+        *
+        * If mdp4 is migrated to runpm, we could probably drop these
+        * and use runpm directly.
+        */
+       void (*enable_commit)(struct msm_kms *kms);
+       void (*disable_commit)(struct msm_kms *kms);
+
        /**
         * Prepare for atomic commit.  This is called after any previous
         * (async or otherwise) commit has completed.