From e4e277ad36df3cc30827af0727fd469887353eb7 Mon Sep 17 00:00:00 2001 From: Sandeep Gangadharaiah Date: Tue, 17 May 2022 14:22:19 -0700 Subject: [PATCH] disp: msm: dp: Convert clock operations to byte2 ops Convert clock operation to byte2 ops to meet DISPCC requirement. Clock unit is changed from KHZ to HZ. Added link clock parent as freq table is no longer supported in byte2 ops. Change-Id: Icf5a595708040e8afefecebe7f371bb832d6673e Signed-off-by: Sandeep Gangadharaiah --- msm/dp/dp_ctrl.c | 3 ++ msm/dp/dp_pll.h | 1 + msm/dp/dp_pll_4nm.c | 11 +++-- msm/dp/dp_pll_5nm.c | 11 +++-- msm/dp/dp_power.c | 99 ++++++++++++++++++++++++++++----------------- 5 files changed, 75 insertions(+), 50 deletions(-) diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index 2c6b6a1c7d..7a53e7923d 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -647,6 +647,9 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl, u32 num = ctrl->parser->mp[clk_type].num_clk; struct dss_clk *cfg = ctrl->parser->mp[clk_type].clk_config; + /* convert to HZ for byte2 ops */ + rate *= ctrl->pll->clk_factor; + while (num && strcmp(cfg->clk_name, name)) { num--; cfg++; diff --git a/msm/dp/dp_pll.h b/msm/dp/dp_pll.h index bd4006688d..529670569a 100644 --- a/msm/dp/dp_pll.h +++ b/msm/dp/dp_pll.h @@ -95,6 +95,7 @@ struct dp_pll { struct dp_pll_io io; struct clk_onecell_data *clk_data; u32 dp_core_revision; + u32 clk_factor; int (*pll_cfg)(struct dp_pll *pll, unsigned long rate); int (*pll_prepare)(struct dp_pll *pll); diff --git a/msm/dp/dp_pll_4nm.c b/msm/dp/dp_pll_4nm.c index 46f15102ee..0785df72ac 100644 --- a/msm/dp/dp_pll_4nm.c +++ b/msm/dp/dp_pll_4nm.c @@ -737,8 +737,7 @@ static unsigned long dp_pll_link_clk_recalc_rate(struct clk_hw *hw, pll_link = to_dp_vco_hw(hw); pll = pll_link->priv; - rate = pll->vco_rate; - rate = pll->vco_rate / 10; + rate = pll->vco_rate * pll->clk_factor / 10; return rate; } @@ -757,7 +756,7 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate, pll_link = to_dp_vco_hw(hw); pll = pll_link->priv; - rate = pll->vco_rate / 10; + rate = pll->vco_rate * pll->clk_factor / 10; return rate; } @@ -765,11 +764,11 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate, static unsigned long dp_pll_vco_div_clk_get_rate(struct dp_pll *pll) { if (pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) - return (pll->vco_rate / 6); + return (pll->vco_rate / (6 * pll->clk_factor)); else if (pll->vco_rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000) - return (pll->vco_rate / 4); + return (pll->vco_rate / (4 * pll->clk_factor)); else - return (pll->vco_rate / 2); + return (pll->vco_rate / (2 * pll->clk_factor)); } static unsigned long dp_pll_vco_div_clk_recalc_rate(struct clk_hw *hw, diff --git a/msm/dp/dp_pll_5nm.c b/msm/dp/dp_pll_5nm.c index 0af078d8e9..9ddd9ae35d 100644 --- a/msm/dp/dp_pll_5nm.c +++ b/msm/dp/dp_pll_5nm.c @@ -719,8 +719,7 @@ static unsigned long dp_pll_link_clk_recalc_rate(struct clk_hw *hw, pll_link = to_dp_vco_hw(hw); pll = pll_link->priv; - rate = pll->vco_rate; - rate = pll->vco_rate / 10; + rate = pll->vco_rate * pll->clk_factor / 10; return rate; } @@ -739,7 +738,7 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate, pll_link = to_dp_vco_hw(hw); pll = pll_link->priv; - rate = pll->vco_rate / 10; + rate = pll->vco_rate * pll->clk_factor / 10; return rate; } @@ -747,11 +746,11 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate, static unsigned long dp_pll_vco_div_clk_get_rate(struct dp_pll *pll) { if (pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) - return (pll->vco_rate / 6); + return (pll->vco_rate / (6 * pll->clk_factor)); else if (pll->vco_rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000) - return (pll->vco_rate / 4); + return (pll->vco_rate / (4 * pll->clk_factor)); else - return (pll->vco_rate / 2); + return (pll->vco_rate / (2 * pll->clk_factor)); } static unsigned long dp_pll_vco_div_clk_recalc_rate(struct clk_hw *hw, diff --git a/msm/dp/dp_power.c b/msm/dp/dp_power.c index de8ba05b2f..0ae2cf5097 100644 --- a/msm/dp/dp_power.c +++ b/msm/dp/dp_power.c @@ -22,6 +22,8 @@ struct dp_power_private { struct clk *pixel_parent; struct clk *pixel1_clk_rcg; struct clk *xo_clk; + struct clk *link_clk_rcg; + struct clk *link_parent; struct dp_power dp_power; @@ -245,6 +247,25 @@ static int dp_power_clk_init(struct dp_power_private *power, bool enable) goto err_pixel1_clk_rcg; } } + + power->link_clk_rcg = clk_get(dev, "link_clk_src"); + if (IS_ERR(power->link_clk_rcg)) { + DP_ERR("Unable to get DP link clk RCG: %ld\n", + PTR_ERR(power->link_clk_rcg)); + rc = PTR_ERR(power->link_clk_rcg); + power->link_clk_rcg = NULL; + goto err_link_clk_rcg; + } + + /* If link_parent node is available, convert clk rates to HZ for byte2 ops */ + power->pll->clk_factor = 1000; + power->link_parent = clk_get(dev, "link_parent"); + if (IS_ERR(power->link_parent)) { + DP_WARN("Unable to get DP link parent: %ld\n", + PTR_ERR(power->link_parent)); + power->link_parent = NULL; + power->pll->clk_factor = 1; + } } else { if (power->pixel1_clk_rcg) clk_put(power->pixel1_clk_rcg); @@ -255,10 +276,19 @@ static int dp_power_clk_init(struct dp_power_private *power, bool enable) if (power->pixel_clk_rcg) clk_put(power->pixel_clk_rcg); + if (power->link_parent) + clk_put(power->link_parent); + + if (power->link_clk_rcg) + clk_put(power->link_clk_rcg); + dp_power_clk_put(power); } return rc; +err_link_clk_rcg: + if (power->pixel1_clk_rcg) + clk_put(power->pixel1_clk_rcg); err_pixel1_clk_rcg: clk_put(power->xo_clk); err_xo_clk: @@ -363,6 +393,29 @@ exit: return rc; } +static bool dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type) +{ + struct dp_power_private *power; + + if (!dp_power) { + DP_ERR("invalid power data\n"); + return false; + } + + power = container_of(dp_power, struct dp_power_private, dp_power); + + if (pm_type == DP_LINK_PM) + return power->link_clks_on; + else if (pm_type == DP_CORE_PM) + return power->core_clks_on; + else if (pm_type == DP_STREAM0_PM) + return power->strm0_clks_on; + else if (pm_type == DP_STREAM1_PM) + return power->strm1_clks_on; + else + return false; +} + static int dp_power_clk_enable(struct dp_power *dp_power, enum dp_pm_type pm_type, bool enable) { @@ -387,18 +440,8 @@ static int dp_power_clk_enable(struct dp_power *dp_power, } if (enable) { - if (pm_type == DP_CORE_PM && power->core_clks_on) { - DP_DEBUG("core clks already enabled\n"); - return 0; - } - - if ((pm_type == DP_STREAM0_PM) && (power->strm0_clks_on)) { - DP_DEBUG("strm0 clks already enabled\n"); - return 0; - } - - if ((pm_type == DP_STREAM1_PM) && (power->strm1_clks_on)) { - DP_DEBUG("strm1 clks already enabled\n"); + if (dp_power_clk_status(dp_power, pm_type)) { + DP_DEBUG("%s clks already enabled\n", dp_parser_pm_name(pm_type)); return 0; } @@ -415,9 +458,12 @@ static int dp_power_clk_enable(struct dp_power *dp_power, } } - if (pm_type == DP_LINK_PM && power->link_clks_on) { - DP_DEBUG("links clks already enabled\n"); - return 0; + if (pm_type == DP_LINK_PM && power->link_parent) { + rc = clk_set_parent(power->link_clk_rcg, power->link_parent); + if (rc) { + DP_ERR("failed to set link parent\n"); + goto error; + } } } @@ -458,29 +504,6 @@ error: return rc; } -static bool dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type) -{ - struct dp_power_private *power; - - if (!dp_power) { - DP_ERR("invalid power data\n"); - return false; - } - - power = container_of(dp_power, struct dp_power_private, dp_power); - - if (pm_type == DP_LINK_PM) - return power->link_clks_on; - else if (pm_type == DP_CORE_PM) - return power->core_clks_on; - else if (pm_type == DP_STREAM0_PM) - return power->strm0_clks_on; - else if (pm_type == DP_STREAM1_PM) - return power->strm1_clks_on; - else - return false; -} - static int dp_power_request_gpios(struct dp_power_private *power) { int rc = 0, i;