From e66a2089f4f76b98b10dbd13066ab58c815cde37 Mon Sep 17 00:00:00 2001 From: Sudarsan Ramesh Date: Wed, 17 Feb 2021 15:35:22 -0500 Subject: [PATCH] disp: msm: dp: update pll driver to fix clock names per target With the change in the clock names for newer targets, this fix updates the driver to support different clock names per target. Change-Id: I58c35fce34356f8c79adb0ac8a907e2fb60813ae Signed-off-by: Sudarsan Ramesh --- msm/dp/dp_catalog.c | 18 +++++++++++++- msm/dp/dp_catalog.h | 3 ++- msm/dp/dp_display.c | 1 + msm/dp/dp_pll.c | 31 +++++++++++++++++++++++- msm/dp/dp_pll.h | 3 +++ msm/dp/dp_pll_5nm.c | 58 ++++++++++++++++++++++++++------------------- 6 files changed, 86 insertions(+), 28 deletions(-) diff --git a/msm/dp/dp_catalog.c b/msm/dp/dp_catalog.c index 37b68a7e88..1ed5f52e93 100644 --- a/msm/dp/dp_catalog.c +++ b/msm/dp/dp_catalog.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ @@ -1938,6 +1938,22 @@ static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl, wmb(); } +u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog) +{ + struct dp_catalog_private *catalog; + struct dp_io_data *io_data; + + if (!dp_catalog) { + DP_ERR("invalid input\n"); + return 0; + } + + catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); + io_data = catalog->io.dp_ahb; + + return dp_read(DP_HW_VERSION); +} + static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog, char *name, u8 **out_buf, u32 *out_buf_len) { diff --git a/msm/dp/dp_catalog.h b/msm/dp/dp_catalog.h index f73a1713ff..f5c804bebf 100644 --- a/msm/dp/dp_catalog.h +++ b/msm/dp/dp_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef _DP_CATALOG_H_ @@ -336,4 +336,5 @@ struct dp_catalog_sub *dp_catalog_get_v420(struct device *dev, struct dp_catalog_sub *dp_catalog_get_v200(struct device *dev, struct dp_catalog *catalog, struct dp_catalog_io *io); +u32 dp_catalog_get_dp_core_version(struct dp_catalog *dp_catalog); #endif /* _DP_CATALOG_H_ */ diff --git a/msm/dp/dp_display.c b/msm/dp/dp_display.c index 224d0054af..2ce9c24b55 100644 --- a/msm/dp/dp_display.c +++ b/msm/dp/dp_display.c @@ -1919,6 +1919,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) pll_in.aux = dp->aux; pll_in.parser = dp->parser; + pll_in.dp_core_revision = dp_catalog_get_dp_core_version(dp->catalog); dp->pll = dp_pll_get(&pll_in); if (IS_ERR(dp->pll)) { diff --git a/msm/dp/dp_pll.c b/msm/dp/dp_pll.c index 31f91c84ce..3f31b856f2 100644 --- a/msm/dp/dp_pll.c +++ b/msm/dp/dp_pll.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #include @@ -74,6 +74,34 @@ static void dp_pll_clock_unregister(struct dp_pll *pll) } } +int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks) +{ + int rc = 0, i = 0; + struct platform_device *pdev; + struct clk *clk; + + if (!pll || !clks) { + DP_ERR("input not initialized\n"); + return -EINVAL; + } + + pdev = pll->pdev; + + for (i = 0; i < num_clks; i++) { + clks[i].priv = pll; + + clk = clk_register(&pdev->dev, &clks[i].hw); + if (IS_ERR(clk)) { + DP_ERR("%s registration failed for DP: %d\n", + clk_hw_get_name(&clks[i].hw), pll->index); + return -EINVAL; + } + pll->clk_data->clks[i] = clk; + } + + return rc; +} + struct dp_pll *dp_pll_get(struct dp_pll_in *in) { int rc = 0; @@ -93,6 +121,7 @@ struct dp_pll *dp_pll_get(struct dp_pll_in *in) pll->pdev = in->pdev; pll->parser = in->parser; pll->aux = in->aux; + pll->dp_core_revision = in->dp_core_revision; parser = pll->parser; pdev = pll->pdev; diff --git a/msm/dp/dp_pll.h b/msm/dp/dp_pll.h index 19bfbe5f2e..eca3435d3c 100644 --- a/msm/dp/dp_pll.h +++ b/msm/dp/dp_pll.h @@ -80,6 +80,7 @@ struct dp_pll { struct dp_aux *aux; struct dp_pll_io io; struct clk_onecell_data *clk_data; + u32 dp_core_revision; int (*pll_cfg)(struct dp_pll *pll, unsigned long rate); int (*pll_prepare)(struct dp_pll *pll); @@ -128,8 +129,10 @@ struct dp_pll_in { struct platform_device *pdev; struct dp_aux *aux; struct dp_parser *parser; + u32 dp_core_revision; }; +int dp_pll_clock_register_helper(struct dp_pll *pll, struct dp_pll_vco_clk *clks, int num_clks); struct dp_pll *dp_pll_get(struct dp_pll_in *in); void dp_pll_put(struct dp_pll *pll); #endif /* __DP_PLL_H */ diff --git a/msm/dp/dp_pll_5nm.c b/msm/dp/dp_pll_5nm.c index fb40271bce..effe800060 100644 --- a/msm/dp/dp_pll_5nm.c +++ b/msm/dp/dp_pll_5nm.c @@ -121,6 +121,8 @@ #define DP_VCO_RATE_9720MHZDIV1000 9720000UL #define DP_VCO_RATE_10800MHZDIV1000 10800000UL +#define DP_PLL_NUM_CLKS 2 + #define DP_5NM_C_READY BIT(0) #define DP_5NM_FREQ_DONE BIT(0) #define DP_5NM_PLL_LOCKED BIT(1) @@ -826,17 +828,33 @@ static const struct clk_ops pll_vco_div_clk_ops = { .set_rate = dp_pll_vco_div_clk_set_rate, }; -static struct dp_pll_vco_clk dp_phy_pll_link_clk = { +static struct dp_pll_vco_clk dp0_phy_pll_clks[DP_PLL_NUM_CLKS] = { + { .hw.init = &(struct clk_init_data) { - .name = "dp_phy_pll_link_clk", + .name = "dp0_phy_pll_link_clk", .ops = &pll_link_clk_ops, + }, + }, + { + .hw.init = &(struct clk_init_data) { + .name = "dp0_phy_pll_vco_div_clk", + .ops = &pll_vco_div_clk_ops, + }, }, }; -static struct dp_pll_vco_clk dp_phy_pll_vco_div_clk = { +static struct dp_pll_vco_clk dp_phy_pll_clks[DP_PLL_NUM_CLKS] = { + { + .hw.init = &(struct clk_init_data) { + .name = "dp_phy_pll_link_clk", + .ops = &pll_link_clk_ops, + }, + }, + { .hw.init = &(struct clk_init_data) { .name = "dp_phy_pll_vco_div_clk", .ops = &pll_vco_div_clk_ops, + }, }, }; @@ -844,9 +862,9 @@ static struct dp_pll_db dp_pdb; int dp_pll_clock_register_5nm(struct dp_pll *pll) { - int rc = 0, num_clks = 2; + int rc = 0; struct platform_device *pdev; - struct clk *clk; + struct dp_pll_vco_clk *pll_clks; if (!pll) { DP_ERR("pll data not initialized\n"); @@ -858,46 +876,36 @@ int dp_pll_clock_register_5nm(struct dp_pll *pll) if (!pll->clk_data) return -ENOMEM; - pll->clk_data->clks = kcalloc(num_clks, sizeof(struct clk *), + pll->clk_data->clks = kcalloc(DP_PLL_NUM_CLKS, sizeof(struct clk *), GFP_KERNEL); if (!pll->clk_data->clks) { kfree(pll->clk_data); return -ENOMEM; } - pll->clk_data->clk_num = num_clks; + pll->clk_data->clk_num = DP_PLL_NUM_CLKS; pll->priv = &dp_pdb; dp_pdb.pll = pll; - dp_phy_pll_link_clk.priv = pll; - dp_phy_pll_vco_div_clk.priv = pll; - pll->pll_cfg = dp_pll_configure; pll->pll_prepare = dp_pll_prepare; pll->pll_unprepare = dp_pll_unprepare; - clk = clk_register(&pdev->dev, &dp_phy_pll_link_clk.hw); - if (IS_ERR(clk)) { - DP_ERR("%s registration failed for DP: %d\n", - clk_hw_get_name(&dp_phy_pll_link_clk.hw), pll->index); - rc = -EINVAL; - goto clk_reg_fail; - } - pll->clk_data->clks[0] = clk; + if (pll->dp_core_revision >= 0x10040000) + pll_clks = dp0_phy_pll_clks; + else + pll_clks = dp_phy_pll_clks; - clk = clk_register(&pdev->dev, &dp_phy_pll_vco_div_clk.hw); - if (IS_ERR(clk)) { - DP_ERR("%s registration failed for DP: %d\n", - clk_hw_get_name(&dp_phy_pll_vco_div_clk.hw), pll->index); - rc = -EINVAL; + rc = dp_pll_clock_register_helper(pll, pll_clks, DP_PLL_NUM_CLKS); + if (rc) { + DP_ERR("Clock register failed rc=%d\n", rc); goto clk_reg_fail; } - pll->clk_data->clks[1] = clk; rc = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, pll->clk_data); if (rc) { - DP_ERR("Clock register failed rc=%d\n", rc); + DP_ERR("Clock add provider failed rc=%d\n", rc); goto clk_reg_fail; }