diff options
Diffstat (limited to 'arch/arm/mach-omap2/dpll3xxx.c')
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index ebb888f59365..f77022be783d 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -32,9 +32,7 @@ | |||
32 | #include <plat/clock.h> | 32 | #include <plat/clock.h> |
33 | 33 | ||
34 | #include "clock.h" | 34 | #include "clock.h" |
35 | #include "prm.h" | 35 | #include "cm2xxx_3xxx.h" |
36 | #include "prm-regbits-34xx.h" | ||
37 | #include "cm.h" | ||
38 | #include "cm-regbits-34xx.h" | 36 | #include "cm-regbits-34xx.h" |
39 | 37 | ||
40 | /* CM_AUTOIDLE_PLL*.AUTO_* bit values */ | 38 | /* CM_AUTOIDLE_PLL*.AUTO_* bit values */ |
@@ -225,10 +223,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) | |||
225 | } | 223 | } |
226 | 224 | ||
227 | /** | 225 | /** |
228 | * lookup_dco_sddiv - Set j-type DPLL4 compensation variables | 226 | * _lookup_dco - Lookup DCO used by j-type DPLL |
229 | * @clk: pointer to a DPLL struct clk | 227 | * @clk: pointer to a DPLL struct clk |
230 | * @dco: digital control oscillator selector | 228 | * @dco: digital control oscillator selector |
231 | * @sd_div: target sigma-delta divider | ||
232 | * @m: DPLL multiplier to set | 229 | * @m: DPLL multiplier to set |
233 | * @n: DPLL divider to set | 230 | * @n: DPLL divider to set |
234 | * | 231 | * |
@@ -237,11 +234,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) | |||
237 | * XXX This code is not needed for 3430/AM35xx; can it be optimized | 234 | * XXX This code is not needed for 3430/AM35xx; can it be optimized |
238 | * out in non-multi-OMAP builds for those chips? | 235 | * out in non-multi-OMAP builds for those chips? |
239 | */ | 236 | */ |
240 | static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, | 237 | static void _lookup_dco(struct clk *clk, u8 *dco, u16 m, u8 n) |
241 | u8 n) | ||
242 | { | 238 | { |
243 | unsigned long fint, clkinp, sd; /* watch out for overflow */ | 239 | unsigned long fint, clkinp; /* watch out for overflow */ |
244 | int mod1, mod2; | ||
245 | 240 | ||
246 | clkinp = clk->parent->rate; | 241 | clkinp = clk->parent->rate; |
247 | fint = (clkinp / n) * m; | 242 | fint = (clkinp / n) * m; |
@@ -250,6 +245,27 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, | |||
250 | *dco = 2; | 245 | *dco = 2; |
251 | else | 246 | else |
252 | *dco = 4; | 247 | *dco = 4; |
248 | } | ||
249 | |||
250 | /** | ||
251 | * _lookup_sddiv - Calculate sigma delta divider for j-type DPLL | ||
252 | * @clk: pointer to a DPLL struct clk | ||
253 | * @sd_div: target sigma-delta divider | ||
254 | * @m: DPLL multiplier to set | ||
255 | * @n: DPLL divider to set | ||
256 | * | ||
257 | * See 36xx TRM section 3.5.3.3.3.2 "Type B DPLL (Low-Jitter)" | ||
258 | * | ||
259 | * XXX This code is not needed for 3430/AM35xx; can it be optimized | ||
260 | * out in non-multi-OMAP builds for those chips? | ||
261 | */ | ||
262 | static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n) | ||
263 | { | ||
264 | unsigned long clkinp, sd; /* watch out for overflow */ | ||
265 | int mod1, mod2; | ||
266 | |||
267 | clkinp = clk->parent->rate; | ||
268 | |||
253 | /* | 269 | /* |
254 | * target sigma-delta to near 250MHz | 270 | * target sigma-delta to near 250MHz |
255 | * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] | 271 | * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] |
@@ -278,6 +294,7 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, | |||
278 | static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) | 294 | static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) |
279 | { | 295 | { |
280 | struct dpll_data *dd = clk->dpll_data; | 296 | struct dpll_data *dd = clk->dpll_data; |
297 | u8 dco, sd_div; | ||
281 | u32 v; | 298 | u32 v; |
282 | 299 | ||
283 | /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ | 300 | /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ |
@@ -300,18 +317,16 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) | |||
300 | v |= m << __ffs(dd->mult_mask); | 317 | v |= m << __ffs(dd->mult_mask); |
301 | v |= (n - 1) << __ffs(dd->div1_mask); | 318 | v |= (n - 1) << __ffs(dd->div1_mask); |
302 | 319 | ||
303 | /* | 320 | /* Configure dco and sd_div for dplls that have these fields */ |
304 | * XXX This code is not needed for 3430/AM35XX; can it be optimized | 321 | if (dd->dco_mask) { |
305 | * out in non-multi-OMAP builds for those chips? | 322 | _lookup_dco(clk, &dco, m, n); |
306 | */ | 323 | v &= ~(dd->dco_mask); |
307 | if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) { | 324 | v |= dco << __ffs(dd->dco_mask); |
308 | u8 dco, sd_div; | 325 | } |
309 | lookup_dco_sddiv(clk, &dco, &sd_div, m, n); | 326 | if (dd->sddiv_mask) { |
310 | /* XXX This probably will need revision for OMAP4 */ | 327 | _lookup_sddiv(clk, &sd_div, m, n); |
311 | v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK | 328 | v &= ~(dd->sddiv_mask); |
312 | | OMAP3630_PERIPH_DPLL_SD_DIV_MASK); | 329 | v |= sd_div << __ffs(dd->sddiv_mask); |
313 | v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK); | ||
314 | v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK); | ||
315 | } | 330 | } |
316 | 331 | ||
317 | __raw_writel(v, dd->mult_div1_reg); | 332 | __raw_writel(v, dd->mult_div1_reg); |