[PATCH 09/20] drm/armada: push responsibility for clock management to backend
Russell King
rmk+kernel at armlinux.org.uk
Tue Jul 10 10:41:57 UTC 2018
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 at armlinux.org.uk>
---
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
More information about the dri-devel
mailing list