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,
 };
 
        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;
        }
                      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);
 
        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);