summaryrefslogtreecommitdiff
path: root/drivers/clk/qcom
diff options
context:
space:
mode:
authorPadmanabhan Komanduru <pkomandu@codeaurora.org>2017-02-05 09:16:08 +0530
committerPadmanabhan Komanduru <pkomandu@codeaurora.org>2017-02-10 16:44:58 +0530
commit21e7c25c87a4c27012e3573fc279df3912351443 (patch)
tree0ef1b8bee6ef7a54a11fcea29d30badf3eef21d9 /drivers/clk/qcom
parentd24550bbf50f61b07668a28a20878e1f91cf544c (diff)
clk: qcom: mdss: update the clk_ops for dp_vco_divided_clk_src_mux
The fractional divider values for DP pixel clock RCG needs to be determined dynamically. Add the recalc_rate operation for the DP PLL mux clock dp_vco_divided_clk_src_mux which is the parent of DP pixel clock RCG. This enables the RCG clock to calculate the fractional dividers correctly. Modify the determine rate op for the mux clock to also set the new parent after performing the determine rate operation. Change-Id: Id931a60677380ecee28eb9aec6468548898b812b Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
Diffstat (limited to 'drivers/clk/qcom')
-rw-r--r--drivers/clk/qcom/mdss/mdss-dp-pll-14nm-util.c1
-rw-r--r--drivers/clk/qcom/mdss/mdss-dp-pll-14nm.c47
2 files changed, 47 insertions, 1 deletions
diff --git a/drivers/clk/qcom/mdss/mdss-dp-pll-14nm-util.c b/drivers/clk/qcom/mdss/mdss-dp-pll-14nm-util.c
index 0965d5590a28..f0d4e1ff52be 100644
--- a/drivers/clk/qcom/mdss/mdss-dp-pll-14nm-util.c
+++ b/drivers/clk/qcom/mdss/mdss-dp-pll-14nm-util.c
@@ -600,6 +600,7 @@ unsigned long dp_vco_recalc_rate_14nm(struct clk_hw *hw,
mdss_pll_resource_enable(dp_res, false);
+ dp_res->vco_cached_rate = vco->rate = vco_rate;
return (unsigned long)vco_rate;
}
diff --git a/drivers/clk/qcom/mdss/mdss-dp-pll-14nm.c b/drivers/clk/qcom/mdss/mdss-dp-pll-14nm.c
index ffe8286cfaaa..d74584850259 100644
--- a/drivers/clk/qcom/mdss/mdss-dp-pll-14nm.c
+++ b/drivers/clk/qcom/mdss/mdss-dp-pll-14nm.c
@@ -62,6 +62,7 @@ v----------+----------v | divsel_two | | divsel_four |
#include "mdss-dp-pll-14nm.h"
static struct dp_pll_db dp_pdb;
+static struct clk_ops mux_clk_ops;
static struct regmap_config dp_pll_14nm_cfg = {
.reg_bits = 32,
@@ -137,6 +138,47 @@ static struct clk_fixed_factor dp_vco_divsel_four_clk_src = {
},
};
+static int clk_mux_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ int ret = 0;
+
+ ret = __clk_mux_determine_rate_closest(hw, req);
+ if (ret)
+ return ret;
+
+ /* Set the new parent of mux if there is a new valid parent */
+ if (hw->clk && req->best_parent_hw->clk)
+ clk_set_parent(hw->clk, req->best_parent_hw->clk);
+
+ return 0;
+}
+
+
+static unsigned long mux_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk *div_clk = NULL, *vco_clk = NULL;
+ struct dp_pll_vco_clk *vco = NULL;
+
+ div_clk = clk_get_parent(hw->clk);
+ if (!div_clk)
+ return 0;
+
+ vco_clk = clk_get_parent(div_clk);
+ if (!vco_clk)
+ return 0;
+
+ vco = to_dp_vco_hw(__clk_get_hw(vco_clk));
+ if (!vco)
+ return 0;
+
+ if (vco->rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000)
+ return (vco->rate / 4);
+ else
+ return (vco->rate / 2);
+}
+
static struct clk_regmap_mux dp_vco_divided_clk_src_mux = {
.reg = 0x64,
.shift = 0,
@@ -149,7 +191,7 @@ static struct clk_regmap_mux dp_vco_divided_clk_src_mux = {
(const char *[]){"dp_vco_divsel_two_clk_src",
"dp_vco_divsel_four_clk_src"},
.num_parents = 2,
- .ops = &clk_regmap_mux_closest_ops,
+ .ops = &mux_clk_ops,
.flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT),
},
},
@@ -202,6 +244,9 @@ int dp_pll_clock_register_14nm(struct platform_device *pdev,
regmap = devm_regmap_init(&pdev->dev, &dp_pixel_mux_regmap_ops,
pll_res, &dp_pll_14nm_cfg);
dp_vco_divided_clk_src_mux.clkr.regmap = regmap;
+ mux_clk_ops = clk_regmap_mux_closest_ops;
+ mux_clk_ops.determine_rate = clk_mux_determine_rate;
+ mux_clk_ops.recalc_rate = mux_recalc_rate;
dp_vco_clk.priv = pll_res;