diff options
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock3xxx_data.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock44xx_data.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 53 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/clock.h | 5 |
5 files changed, 42 insertions, 22 deletions
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index a535c7a2a62a..896584e3c4ab 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -49,7 +49,6 @@ | |||
49 | 49 | ||
50 | /* DPLL Type and DCO Selection Flags */ | 50 | /* DPLL Type and DCO Selection Flags */ |
51 | #define DPLL_J_TYPE 0x1 | 51 | #define DPLL_J_TYPE 0x1 |
52 | #define DPLL_NO_DCO_SEL 0x2 | ||
53 | 52 | ||
54 | int omap2_clk_enable(struct clk *clk); | 53 | int omap2_clk_enable(struct clk *clk); |
55 | void omap2_clk_disable(struct clk *clk); | 54 | void omap2_clk_disable(struct clk *clk); |
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index e7a41bcf0a86..9ab817e6c300 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c | |||
@@ -602,6 +602,8 @@ static struct dpll_data dpll4_dd_3630 __initdata = { | |||
602 | .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, | 602 | .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, |
603 | .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 603 | .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
604 | .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, | 604 | .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
605 | .dco_mask = OMAP3630_PERIPH_DPLL_DCO_SEL_MASK, | ||
606 | .sddiv_mask = OMAP3630_PERIPH_DPLL_SD_DIV_MASK, | ||
605 | .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT, | 607 | .max_multiplier = OMAP3630_MAX_JTYPE_DPLL_MULT, |
606 | .min_divider = 1, | 608 | .min_divider = 1, |
607 | .max_divider = OMAP3_MAX_DPLL_DIV, | 609 | .max_divider = OMAP3_MAX_DPLL_DIV, |
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 850ffc7b70c0..4fa62f9496c0 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c | |||
@@ -940,6 +940,7 @@ static struct dpll_data dpll_unipro_dd = { | |||
940 | .enable_mask = OMAP4430_DPLL_EN_MASK, | 940 | .enable_mask = OMAP4430_DPLL_EN_MASK, |
941 | .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, | 941 | .autoidle_mask = OMAP4430_AUTO_DPLL_MODE_MASK, |
942 | .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, | 942 | .idlest_mask = OMAP4430_ST_DPLL_CLK_MASK, |
943 | .sddiv_mask = OMAP4430_DPLL_SD_DIV_MASK, | ||
943 | .max_multiplier = OMAP4430_MAX_DPLL_MULT, | 944 | .max_multiplier = OMAP4430_MAX_DPLL_MULT, |
944 | .max_divider = OMAP4430_MAX_DPLL_DIV, | 945 | .max_divider = OMAP4430_MAX_DPLL_DIV, |
945 | .min_divider = 1, | 946 | .min_divider = 1, |
@@ -992,7 +993,7 @@ static struct clk usb_hs_clk_div_ck = { | |||
992 | static struct dpll_data dpll_usb_dd = { | 993 | static struct dpll_data dpll_usb_dd = { |
993 | .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB, | 994 | .mult_div1_reg = OMAP4430_CM_CLKSEL_DPLL_USB, |
994 | .clk_bypass = &usb_hs_clk_div_ck, | 995 | .clk_bypass = &usb_hs_clk_div_ck, |
995 | .flags = DPLL_J_TYPE | DPLL_NO_DCO_SEL, | 996 | .flags = DPLL_J_TYPE, |
996 | .clk_ref = &sys_clkin_ck, | 997 | .clk_ref = &sys_clkin_ck, |
997 | .control_reg = OMAP4430_CM_CLKMODE_DPLL_USB, | 998 | .control_reg = OMAP4430_CM_CLKMODE_DPLL_USB, |
998 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | 999 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), |
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index cb535ee4e8fe..5df9f53e6d01 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c | |||
@@ -223,10 +223,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) | |||
223 | } | 223 | } |
224 | 224 | ||
225 | /** | 225 | /** |
226 | * lookup_dco_sddiv - Set j-type DPLL4 compensation variables | 226 | * _lookup_dco - Lookup DCO used by j-type DPLL |
227 | * @clk: pointer to a DPLL struct clk | 227 | * @clk: pointer to a DPLL struct clk |
228 | * @dco: digital control oscillator selector | 228 | * @dco: digital control oscillator selector |
229 | * @sd_div: target sigma-delta divider | ||
230 | * @m: DPLL multiplier to set | 229 | * @m: DPLL multiplier to set |
231 | * @n: DPLL divider to set | 230 | * @n: DPLL divider to set |
232 | * | 231 | * |
@@ -235,11 +234,9 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) | |||
235 | * 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 |
236 | * out in non-multi-OMAP builds for those chips? | 235 | * out in non-multi-OMAP builds for those chips? |
237 | */ | 236 | */ |
238 | 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) |
239 | u8 n) | ||
240 | { | 238 | { |
241 | unsigned long fint, clkinp, sd; /* watch out for overflow */ | 239 | unsigned long fint, clkinp; /* watch out for overflow */ |
242 | int mod1, mod2; | ||
243 | 240 | ||
244 | clkinp = clk->parent->rate; | 241 | clkinp = clk->parent->rate; |
245 | fint = (clkinp / n) * m; | 242 | fint = (clkinp / n) * m; |
@@ -248,6 +245,27 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, | |||
248 | *dco = 2; | 245 | *dco = 2; |
249 | else | 246 | else |
250 | *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 | |||
251 | /* | 269 | /* |
252 | * target sigma-delta to near 250MHz | 270 | * target sigma-delta to near 250MHz |
253 | * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] | 271 | * sd = ceil[(m/(n+1)) * (clkinp_MHz / 250)] |
@@ -276,6 +294,7 @@ static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, | |||
276 | 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) |
277 | { | 295 | { |
278 | struct dpll_data *dd = clk->dpll_data; | 296 | struct dpll_data *dd = clk->dpll_data; |
297 | u8 dco, sd_div; | ||
279 | u32 v; | 298 | u32 v; |
280 | 299 | ||
281 | /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ | 300 | /* 3430 ES2 TRM: 4.7.6.9 DPLL Programming Sequence */ |
@@ -298,18 +317,16 @@ static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) | |||
298 | v |= m << __ffs(dd->mult_mask); | 317 | v |= m << __ffs(dd->mult_mask); |
299 | v |= (n - 1) << __ffs(dd->div1_mask); | 318 | v |= (n - 1) << __ffs(dd->div1_mask); |
300 | 319 | ||
301 | /* | 320 | /* Configure dco and sd_div for dplls that have these fields */ |
302 | * XXX This code is not needed for 3430/AM35XX; can it be optimized | 321 | if (dd->dco_mask) { |
303 | * out in non-multi-OMAP builds for those chips? | 322 | _lookup_dco(clk, &dco, m, n); |
304 | */ | 323 | v &= ~(dd->dco_mask); |
305 | if ((dd->flags & DPLL_J_TYPE) && !(dd->flags & DPLL_NO_DCO_SEL)) { | 324 | v |= dco << __ffs(dd->dco_mask); |
306 | u8 dco, sd_div; | 325 | } |
307 | lookup_dco_sddiv(clk, &dco, &sd_div, m, n); | 326 | if (dd->sddiv_mask) { |
308 | /* XXX This probably will need revision for OMAP4 */ | 327 | _lookup_sddiv(clk, &sd_div, m, n); |
309 | v &= ~(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK | 328 | v &= ~(dd->sddiv_mask); |
310 | | OMAP3630_PERIPH_DPLL_SD_DIV_MASK); | 329 | v |= sd_div << __ffs(dd->sddiv_mask); |
311 | v |= dco << __ffs(OMAP3630_PERIPH_DPLL_DCO_SEL_MASK); | ||
312 | v |= sd_div << __ffs(OMAP3630_PERIPH_DPLL_SD_DIV_MASK); | ||
313 | } | 330 | } |
314 | 331 | ||
315 | __raw_writel(v, dd->mult_div1_reg); | 332 | __raw_writel(v, dd->mult_div1_reg); |
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index 6e223158268b..8eb0adab19ea 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h | |||
@@ -124,8 +124,7 @@ struct clksel { | |||
124 | * | 124 | * |
125 | * Possible values for @flags: | 125 | * Possible values for @flags: |
126 | * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) | 126 | * DPLL_J_TYPE: "J-type DPLL" (only some 36xx, 4xxx DPLLs) |
127 | * NO_DCO_SEL: don't program DCO (only for some J-type DPLLs) | 127 | * |
128 | |||
129 | * @freqsel_mask is only used on the OMAP34xx family and AM35xx. | 128 | * @freqsel_mask is only used on the OMAP34xx family and AM35xx. |
130 | * | 129 | * |
131 | * XXX Some DPLLs have multiple bypass inputs, so it's not technically | 130 | * XXX Some DPLLs have multiple bypass inputs, so it's not technically |
@@ -161,6 +160,8 @@ struct dpll_data { | |||
161 | u32 autoidle_mask; | 160 | u32 autoidle_mask; |
162 | u32 freqsel_mask; | 161 | u32 freqsel_mask; |
163 | u32 idlest_mask; | 162 | u32 idlest_mask; |
163 | u32 dco_mask; | ||
164 | u32 sddiv_mask; | ||
164 | u8 auto_recal_bit; | 165 | u8 auto_recal_bit; |
165 | u8 recal_en_bit; | 166 | u8 recal_en_bit; |
166 | u8 recal_st_bit; | 167 | u8 recal_st_bit; |