aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/pistachio/clk-pll.c26
-rw-r--r--drivers/clk/pistachio/clk.h14
2 files changed, 19 insertions, 21 deletions
diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c
index addfec731333..f71bfcc0d367 100644
--- a/drivers/clk/pistachio/clk-pll.c
+++ b/drivers/clk/pistachio/clk-pll.c
@@ -88,12 +88,10 @@ static inline void pll_lock(struct pistachio_clk_pll *pll)
88 cpu_relax(); 88 cpu_relax();
89} 89}
90 90
91static inline u32 do_div_round_closest(u64 dividend, u32 divisor) 91static inline u64 do_div_round_closest(u64 dividend, u64 divisor)
92{ 92{
93 dividend += divisor / 2; 93 dividend += divisor / 2;
94 do_div(dividend, divisor); 94 return div64_u64(dividend, divisor);
95
96 return dividend;
97} 95}
98 96
99static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw) 97static inline struct pistachio_clk_pll *to_pistachio_pll(struct clk_hw *hw)
@@ -173,7 +171,7 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
173 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 171 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
174 struct pistachio_pll_rate_table *params; 172 struct pistachio_pll_rate_table *params;
175 int enabled = pll_gf40lp_frac_is_enabled(hw); 173 int enabled = pll_gf40lp_frac_is_enabled(hw);
176 u32 val, vco, old_postdiv1, old_postdiv2; 174 u64 val, vco, old_postdiv1, old_postdiv2;
177 const char *name = clk_hw_get_name(hw); 175 const char *name = clk_hw_get_name(hw);
178 176
179 if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC) 177 if (rate < MIN_OUTPUT_FRAC || rate > MAX_OUTPUT_FRAC)
@@ -183,17 +181,17 @@ static int pll_gf40lp_frac_set_rate(struct clk_hw *hw, unsigned long rate,
183 if (!params || !params->refdiv) 181 if (!params || !params->refdiv)
184 return -EINVAL; 182 return -EINVAL;
185 183
186 vco = params->fref * params->fbdiv / params->refdiv; 184 vco = div64_u64(params->fref * params->fbdiv, params->refdiv);
187 if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC) 185 if (vco < MIN_VCO_FRAC_FRAC || vco > MAX_VCO_FRAC_FRAC)
188 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco, 186 pr_warn("%s: VCO %llu is out of range %lu..%lu\n", name, vco,
189 MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC); 187 MIN_VCO_FRAC_FRAC, MAX_VCO_FRAC_FRAC);
190 188
191 val = params->fref / params->refdiv; 189 val = div64_u64(params->fref, params->refdiv);
192 if (val < MIN_PFD) 190 if (val < MIN_PFD)
193 pr_warn("%s: PFD %u is too low (min %lu)\n", 191 pr_warn("%s: PFD %llu is too low (min %lu)\n",
194 name, val, MIN_PFD); 192 name, val, MIN_PFD);
195 if (val > vco / 16) 193 if (val > vco / 16)
196 pr_warn("%s: PFD %u is too high (max %u)\n", 194 pr_warn("%s: PFD %llu is too high (max %llu)\n",
197 name, val, vco / 16); 195 name, val, vco / 16);
198 196
199 val = pll_readl(pll, PLL_CTRL1); 197 val = pll_readl(pll, PLL_CTRL1);
@@ -237,8 +235,7 @@ static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
237 unsigned long parent_rate) 235 unsigned long parent_rate)
238{ 236{
239 struct pistachio_clk_pll *pll = to_pistachio_pll(hw); 237 struct pistachio_clk_pll *pll = to_pistachio_pll(hw);
240 u32 val, prediv, fbdiv, frac, postdiv1, postdiv2; 238 u64 val, prediv, fbdiv, frac, postdiv1, postdiv2, rate;
241 u64 rate = parent_rate;
242 239
243 val = pll_readl(pll, PLL_CTRL1); 240 val = pll_readl(pll, PLL_CTRL1);
244 prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK; 241 prediv = (val >> PLL_CTRL1_REFDIV_SHIFT) & PLL_CTRL1_REFDIV_MASK;
@@ -251,6 +248,7 @@ static unsigned long pll_gf40lp_frac_recalc_rate(struct clk_hw *hw,
251 PLL_FRAC_CTRL2_POSTDIV2_MASK; 248 PLL_FRAC_CTRL2_POSTDIV2_MASK;
252 frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK; 249 frac = (val >> PLL_FRAC_CTRL2_FRAC_SHIFT) & PLL_FRAC_CTRL2_FRAC_MASK;
253 250
251 rate = parent_rate;
254 rate *= (fbdiv << 24) + frac; 252 rate *= (fbdiv << 24) + frac;
255 rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24); 253 rate = do_div_round_closest(rate, (prediv * postdiv1 * postdiv2) << 24);
256 254
@@ -325,12 +323,12 @@ static int pll_gf40lp_laint_set_rate(struct clk_hw *hw, unsigned long rate,
325 if (!params || !params->refdiv) 323 if (!params || !params->refdiv)
326 return -EINVAL; 324 return -EINVAL;
327 325
328 vco = params->fref * params->fbdiv / params->refdiv; 326 vco = div_u64(params->fref * params->fbdiv, params->refdiv);
329 if (vco < MIN_VCO_LA || vco > MAX_VCO_LA) 327 if (vco < MIN_VCO_LA || vco > MAX_VCO_LA)
330 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco, 328 pr_warn("%s: VCO %u is out of range %lu..%lu\n", name, vco,
331 MIN_VCO_LA, MAX_VCO_LA); 329 MIN_VCO_LA, MAX_VCO_LA);
332 330
333 val = params->fref / params->refdiv; 331 val = div_u64(params->fref, params->refdiv);
334 if (val < MIN_PFD) 332 if (val < MIN_PFD)
335 pr_warn("%s: PFD %u is too low (min %lu)\n", 333 pr_warn("%s: PFD %u is too low (min %lu)\n",
336 name, val, MIN_PFD); 334 name, val, MIN_PFD);
diff --git a/drivers/clk/pistachio/clk.h b/drivers/clk/pistachio/clk.h
index 52fabbc24624..8d45178dbde3 100644
--- a/drivers/clk/pistachio/clk.h
+++ b/drivers/clk/pistachio/clk.h
@@ -95,13 +95,13 @@ struct pistachio_fixed_factor {
95 } 95 }
96 96
97struct pistachio_pll_rate_table { 97struct pistachio_pll_rate_table {
98 unsigned long fref; 98 unsigned long long fref;
99 unsigned long fout; 99 unsigned long long fout;
100 unsigned int refdiv; 100 unsigned long long refdiv;
101 unsigned int fbdiv; 101 unsigned long long fbdiv;
102 unsigned int postdiv1; 102 unsigned long long postdiv1;
103 unsigned int postdiv2; 103 unsigned long long postdiv2;
104 unsigned int frac; 104 unsigned long long frac;
105}; 105};
106 106
107enum pistachio_pll_type { 107enum pistachio_pll_type {