Enable the DPU and DSI clocks specified in the device tree. Disable the DSI clock when it is not needed.
Signed-off-by: Otto Pflüger <otto.pflue...@abscue.de> --- drivers/gpu/drm/sprd/sprd_dpu.c | 7 +++++++ drivers/gpu/drm/sprd/sprd_dpu.h | 1 + drivers/gpu/drm/sprd/sprd_dsi.c | 9 +++++++++ drivers/gpu/drm/sprd/sprd_dsi.h | 4 +++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/sprd/sprd_dpu.c b/drivers/gpu/drm/sprd/sprd_dpu.c index 0d9eb778794d92418b39f8535d94abde3566de43..9d274600e6a80bdfc435f6c6eff77c9dd71cb38c 100644 --- a/drivers/gpu/drm/sprd/sprd_dpu.c +++ b/drivers/gpu/drm/sprd/sprd_dpu.c @@ -3,6 +3,7 @@ * Copyright (C) 2020 Unisoc Inc. */ +#include <linux/clk.h> #include <linux/component.h> #include <linux/delay.h> #include <linux/dma-buf.h> @@ -794,6 +795,12 @@ static int sprd_dpu_context_init(struct sprd_dpu *dpu, if (ctx->irq < 0) return ctx->irq; + ctx->clk = devm_clk_get_optional_enabled(dev, "core"); + if (IS_ERR(ctx->clk)) { + dev_err(dev, "failed to get DPU core clock\n"); + return PTR_ERR(ctx->clk); + } + /* disable and clear interrupts before register dpu IRQ. */ writel(0x00, ctx->base + REG_DPU_INT_EN); writel(0xff, ctx->base + REG_DPU_INT_CLR); diff --git a/drivers/gpu/drm/sprd/sprd_dpu.h b/drivers/gpu/drm/sprd/sprd_dpu.h index 157a78f24dc18b071602552ea9d005af66525263..d48b922de580a8a4bf07c4610c431d3321f7b810 100644 --- a/drivers/gpu/drm/sprd/sprd_dpu.h +++ b/drivers/gpu/drm/sprd/sprd_dpu.h @@ -44,6 +44,7 @@ enum { */ struct dpu_context { void __iomem *base; + struct clk *clk; int irq; u8 if_type; struct videomode vm; diff --git a/drivers/gpu/drm/sprd/sprd_dsi.c b/drivers/gpu/drm/sprd/sprd_dsi.c index 071313b605447525326f6b869bc09991d4fcd691..0edb626eb35a7eeb759c2a2f5b8428cd3b092d1f 100644 --- a/drivers/gpu/drm/sprd/sprd_dsi.c +++ b/drivers/gpu/drm/sprd/sprd_dsi.c @@ -832,6 +832,8 @@ static void sprd_dsi_bridge_pre_enable(struct drm_bridge *bridge) struct sprd_dsi *dsi = bridge_to_dsi(bridge); struct dsi_context *ctx = &dsi->ctx; + clk_prepare_enable(ctx->clk); + sprd_dsi_init(ctx); if (ctx->work_mode == DSI_MODE_VIDEO) sprd_dsi_dpi_video(ctx); @@ -886,6 +888,8 @@ static void sprd_dsi_bridge_post_disable(struct drm_bridge *bridge) sprd_dphy_fini(ctx); sprd_dsi_fini(ctx); + + clk_disable_unprepare(ctx->clk); } static const struct drm_bridge_funcs sprd_dsi_bridge_funcs = { @@ -1109,6 +1113,11 @@ static int sprd_dsi_probe(struct platform_device *pdev) if (!dsi->ctx.pll.platform) return -EINVAL; + dsi->ctx.clk = devm_clk_get_optional(dev, "pclk"); + if (IS_ERR(dsi->ctx.clk)) + return dev_err_probe(dev, PTR_ERR(dsi->ctx.clk), + "failed to get pclk\n"); + return mipi_dsi_host_register(&dsi->host); } diff --git a/drivers/gpu/drm/sprd/sprd_dsi.h b/drivers/gpu/drm/sprd/sprd_dsi.h index 1aa609b1da33601217941390673553552f2923b1..14d06236087255f15b2704a0aff2589889fda5e9 100644 --- a/drivers/gpu/drm/sprd/sprd_dsi.h +++ b/drivers/gpu/drm/sprd/sprd_dsi.h @@ -6,8 +6,9 @@ #ifndef __SPRD_DSI_H__ #define __SPRD_DSI_H__ -#include <linux/of.h> +#include <linux/clk.h> #include <linux/device.h> +#include <linux/of.h> #include <linux/regmap.h> #include <video/videomode.h> @@ -93,6 +94,7 @@ struct dphy_pll { struct dsi_context { void __iomem *base; struct regmap *regmap; + struct clk *clk; struct dphy_pll pll; struct videomode vm; -- 2.50.0