Lakka-LibreELEC/projects/NXP/devices/iMX8/patches/linux/0040-drm-imx-dcss-use-the-external-27MHz-phy-clock.patch

109 lines
3.4 KiB
Diff

From c2af9b24bfa69ffb12e72153f89ed3bb3245fafb Mon Sep 17 00:00:00 2001
From: Laurentiu Palcu <laurentiu.palcu@nxp.com>
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 <laurentiu.palcu@nxp.com>
---
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