From c2af9b24bfa69ffb12e72153f89ed3bb3245fafb Mon Sep 17 00:00:00 2001 From: Laurentiu Palcu Date: Fri, 22 Nov 2019 10:00:56 +0200 Subject: [PATCH 40/49] drm/imx/dcss: use the external 27MHz phy clock The 27MHz external oscillator offers a high precision low jitter clock and is suitable for high pixel clocks modes(ie 4K@60). Signed-off-by: Laurentiu Palcu --- drivers/gpu/drm/imx/dcss/dcss-dev.c | 25 +++++++++++++++++++------ drivers/gpu/drm/imx/dcss/dcss-dtg.c | 11 +++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/imx/dcss/dcss-dev.c b/drivers/gpu/drm/imx/dcss/dcss-dev.c index c849533ca83e..1977f6b058f8 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dev.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dev.c @@ -17,6 +17,11 @@ static void dcss_clocks_enable(struct dcss_dev *dcss) { + if (dcss->hdmi_output) { + clk_prepare_enable(dcss->pll_phy_ref_clk); + clk_prepare_enable(dcss->pll_src_clk); + } + clk_prepare_enable(dcss->axi_clk); clk_prepare_enable(dcss->apb_clk); clk_prepare_enable(dcss->rtrm_clk); @@ -31,6 +36,11 @@ static void dcss_clocks_disable(struct dcss_dev *dcss) clk_disable_unprepare(dcss->rtrm_clk); clk_disable_unprepare(dcss->apb_clk); clk_disable_unprepare(dcss->axi_clk); + + if (dcss->hdmi_output) { + clk_disable_unprepare(dcss->pll_src_clk); + clk_disable_unprepare(dcss->pll_phy_ref_clk); + } } static void dcss_disable_dtg_and_ss_cb(void *data) @@ -133,17 +143,20 @@ static int dcss_clks_init(struct dcss_dev *dcss) struct { const char *id; struct clk **clk; + bool required; } clks[] = { - {"apb", &dcss->apb_clk}, - {"axi", &dcss->axi_clk}, - {"pix", &dcss->pix_clk}, - {"rtrm", &dcss->rtrm_clk}, - {"dtrc", &dcss->dtrc_clk}, + {"apb", &dcss->apb_clk, true}, + {"axi", &dcss->axi_clk, true}, + {"pix", &dcss->pix_clk, true}, + {"rtrm", &dcss->rtrm_clk, true}, + {"dtrc", &dcss->dtrc_clk, true}, + {"pll_src", &dcss->pll_src_clk, dcss->hdmi_output}, + {"pll_phy_ref", &dcss->pll_phy_ref_clk, dcss->hdmi_output}, }; for (i = 0; i < ARRAY_SIZE(clks); i++) { *clks[i].clk = devm_clk_get(dcss->dev, clks[i].id); - if (IS_ERR(*clks[i].clk)) { + if (IS_ERR(*clks[i].clk) && clks[i].required) { dev_err(dcss->dev, "failed to get %s clock\n", clks[i].id); return PTR_ERR(*clks[i].clk); diff --git a/drivers/gpu/drm/imx/dcss/dcss-dtg.c b/drivers/gpu/drm/imx/dcss/dcss-dtg.c index 30de00540f63..b70785d69ad9 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-dtg.c +++ b/drivers/gpu/drm/imx/dcss/dcss-dtg.c @@ -83,6 +83,7 @@ struct dcss_dtg { u32 ctx_id; bool in_use; + bool hdmi_output; u32 dis_ulc_x; u32 dis_ulc_y; @@ -159,6 +160,7 @@ int dcss_dtg_init(struct dcss_dev *dcss, unsigned long dtg_base) dcss->dtg = dtg; dtg->dev = dcss->dev; dtg->ctxld = dcss->ctxld; + dtg->hdmi_output = dcss->hdmi_output; dtg->base_reg = ioremap(dtg_base, SZ_4K); if (!dtg->base_reg) { @@ -221,6 +223,15 @@ void dcss_dtg_sync_set(struct dcss_dtg *dtg, struct videomode *vm) vm->vactive - 1; clk_disable_unprepare(dcss->pix_clk); + if (dcss->hdmi_output) { + int err; + + clk_disable_unprepare(dcss->pll_src_clk); + err = clk_set_parent(dcss->pll_src_clk, dcss->pll_phy_ref_clk); + if (err < 0) + dev_warn(dcss->dev, "clk_set_parent() returned %d", err); + clk_prepare_enable(dcss->pll_src_clk); + } clk_set_rate(dcss->pix_clk, vm->pixelclock); clk_prepare_enable(dcss->pix_clk); -- 2.29.2