aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c3
-rw-r--r--arch/arm/mach-omap2/dpll3xxx.c53
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h5
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
54int omap2_clk_enable(struct clk *clk); 53int omap2_clk_enable(struct clk *clk);
55void omap2_clk_disable(struct clk *clk); 54void 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 = {
992static struct dpll_data dpll_usb_dd = { 993static 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 */
238static void lookup_dco_sddiv(struct clk *clk, u8 *dco, u8 *sd_div, u16 m, 237static 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 */
262static 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,
276static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel) 294static 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;