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@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/armada/armada_510.c | 19 +++++++++++++++++++ drivers/gpu/drm/armada/armada_crtc.c | 19 ++++++------------- drivers/gpu/drm/armada/armada_drm.h | 2 ++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_510.c b/drivers/gpu/drm/armada/armada_510.c index 9a4fbb6a24b8..2f7c048c5361 100644 --- a/drivers/gpu/drm/armada/armada_510.c +++ b/drivers/gpu/drm/armada/armada_510.c @@ -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, }; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index a0c67ec892cf..5d8fdcda27ee 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -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); diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index a6f919b0084c..9658be917ea1 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h @@ -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 */ -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel