drm/armada: push responsibility for clock management to backend
authorRussell King <rmk+kernel@armlinux.org.uk>
Mon, 30 Jul 2018 10:52:34 +0000 (11:52 +0100)
committerRussell King <rmk+kernel@armlinux.org.uk>
Mon, 30 Jul 2018 10:52:34 +0000 (11:52 +0100)
Push responsibility for managing the clock during DPMS down into the
variant backend, rather than the CRTC layer having knowledge of its
state.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
drivers/gpu/drm/armada/armada_510.c
drivers/gpu/drm/armada/armada_crtc.c
drivers/gpu/drm/armada/armada_drm.h

index 9a4fbb6a24b8f1258ce67431d167633d5b69a6b9..2f7c048c53613b9086beaa1a5ecaa26c508df884 100644 (file)
@@ -79,8 +79,27 @@ static int armada510_crtc_compute_clock(struct armada_crtc *dcrtc,
        return 0;
 }
 
+static void armada510_crtc_disable(struct armada_crtc *dcrtc)
+{
+       if (!IS_ERR(dcrtc->clk)) {
+               clk_disable_unprepare(dcrtc->clk);
+               dcrtc->clk = ERR_PTR(-EINVAL);
+       }
+}
+
+static void armada510_crtc_enable(struct armada_crtc *dcrtc,
+       const struct drm_display_mode *mode)
+{
+       if (IS_ERR(dcrtc->clk)) {
+               dcrtc->clk = dcrtc->extclk[0];
+               WARN_ON(clk_prepare_enable(dcrtc->clk));
+       }
+}
+
 const struct armada_variant armada510_ops = {
        .has_spu_adv_reg = true,
        .init = armada510_crtc_init,
        .compute_clock = armada510_crtc_compute_clock,
+       .disable = armada510_crtc_disable,
+       .enable = armada510_crtc_enable,
 };
index a0c67ec892cf51340e0d8cf9a9cf066cf2d41ce9..5d8fdcda27ee8b6c8c982c4593bcfd48ccbeed57 100644 (file)
@@ -253,14 +253,14 @@ static void armada_drm_crtc_dpms(struct drm_crtc *crtc, int dpms)
        if (dpms_blanked(dcrtc->dpms) != dpms_blanked(dpms)) {
                if (dpms_blanked(dpms))
                        armada_drm_vblank_off(dcrtc);
-               else if (!IS_ERR(dcrtc->clk))
-                       WARN_ON(clk_prepare_enable(dcrtc->clk));
+               else if (dcrtc->variant->enable)
+                       dcrtc->variant->enable(dcrtc, &crtc->hwmode);
                dcrtc->dpms = dpms;
                armada_drm_crtc_update(dcrtc);
                if (!dpms_blanked(dpms))
                        drm_crtc_vblank_on(&dcrtc->crtc);
-               else if (!IS_ERR(dcrtc->clk))
-                       clk_disable_unprepare(dcrtc->clk);
+               else if (dcrtc->variant->disable)
+                       dcrtc->variant->disable(dcrtc);
        } else if (dcrtc->dpms != dpms) {
                dcrtc->dpms = dpms;
        }
@@ -462,13 +462,6 @@ static void armada_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
                      adj->type, adj->flags);
        DRM_DEBUG_KMS("lm %d rm %d tm %d bm %d\n", lm, rm, tm, bm);
 
-       /*
-        * If we are blanked, we would have disabled the clock.  Re-enable
-        * it so that compute_clock() does the right thing.
-        */
-       if (!IS_ERR(dcrtc->clk) && dpms_blanked(dcrtc->dpms))
-               WARN_ON(clk_prepare_enable(dcrtc->clk));
-
        /* Now compute the divider for real */
        dcrtc->variant->compute_clock(dcrtc, adj, &sclk);
 
@@ -824,8 +817,8 @@ static void armada_drm_crtc_destroy(struct drm_crtc *crtc)
        priv->dcrtc[dcrtc->num] = NULL;
        drm_crtc_cleanup(&dcrtc->crtc);
 
-       if (!IS_ERR(dcrtc->clk))
-               clk_disable_unprepare(dcrtc->clk);
+       if (dcrtc->variant->disable)
+               dcrtc->variant->disable(dcrtc);
 
        writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ENA);
 
index a6f919b0084c6ff1de455c049cfc2e330cddb94c..9658be917ea1edc3af229050c4822c3222b53ee2 100644 (file)
@@ -46,6 +46,8 @@ struct armada_variant {
        int (*compute_clock)(struct armada_crtc *,
                             const struct drm_display_mode *,
                             uint32_t *);
+       void (*disable)(struct armada_crtc *);
+       void (*enable)(struct armada_crtc *, const struct drm_display_mode *);
 };
 
 /* Variant ops */