aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/zynqmp/pll.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/zynqmp/pll.c')
-rw-r--r--drivers/clk/zynqmp/pll.c63
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
index 036e4ff64a2f..0d3e1377b092 100644
--- a/drivers/clk/zynqmp/pll.c
+++ b/drivers/clk/zynqmp/pll.c
@@ -56,8 +56,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
if (ret) {
- pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() PLL get frac mode failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
return PLL_MODE_ERROR;
}
@@ -84,8 +84,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
if (ret)
- pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() PLL set frac mode failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
else
clk->set_pll_mode = true;
}
@@ -102,26 +102,25 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
u32 fbdiv;
- long rate_div, f;
+ u32 mult, div;
- /* Enable the fractional mode if needed */
- rate_div = (rate * FRAC_DIV) / *prate;
- f = rate_div % FRAC_DIV;
- if (f) {
- if (rate > PS_PLL_VCO_MAX) {
- fbdiv = rate / PS_PLL_VCO_MAX;
- rate = rate / (fbdiv + 1);
- }
- if (rate < PS_PLL_VCO_MIN) {
- fbdiv = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
- rate = rate * fbdiv;
- }
- return rate;
+ /* Let rate fall inside the range PS_PLL_VCO_MIN ~ PS_PLL_VCO_MAX */
+ if (rate > PS_PLL_VCO_MAX) {
+ div = DIV_ROUND_UP(rate, PS_PLL_VCO_MAX);
+ rate = rate / div;
+ }
+ if (rate < PS_PLL_VCO_MIN) {
+ mult = DIV_ROUND_UP(PS_PLL_VCO_MIN, rate);
+ rate = rate * mult;
}
fbdiv = DIV_ROUND_CLOSEST(rate, *prate);
- fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
- return *prate * fbdiv;
+ if (fbdiv < PLL_FBDIV_MIN || fbdiv > PLL_FBDIV_MAX) {
+ fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
+ rate = *prate * fbdiv;
+ }
+
+ return rate;
}
/**
@@ -145,8 +144,8 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
if (ret) {
- pr_warn_once("%s() get divider failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() get divider failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
return 0ul;
}
@@ -200,8 +199,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
clk_name);
else if (ret)
- pr_warn_once("%s() set divider failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() set divider failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
zynqmp_pm_set_pll_frac_data(clk_id, f);
return rate + frac;
@@ -211,8 +210,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
if (ret)
- pr_warn_once("%s() set divider failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() set divider failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
return parent_rate * fbdiv;
}
@@ -233,8 +232,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)
ret = zynqmp_pm_clock_getstate(clk_id, &state);
if (ret) {
- pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() clock get state failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
return -EIO;
}
@@ -265,8 +264,8 @@ static int zynqmp_pll_enable(struct clk_hw *hw)
ret = zynqmp_pm_clock_enable(clk_id);
if (ret)
- pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() clock enable failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
return ret;
}
@@ -287,8 +286,8 @@ static void zynqmp_pll_disable(struct clk_hw *hw)
ret = zynqmp_pm_clock_disable(clk_id);
if (ret)
- pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
- __func__, clk_name, ret);
+ pr_debug("%s() clock disable failed for %s, ret = %d\n",
+ __func__, clk_name, ret);
}
static const struct clk_ops zynqmp_pll_ops = {