diff options
Diffstat (limited to 'arch/arm/mach-omap2/clock34xx.c')
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.c | 193 |
1 files changed, 168 insertions, 25 deletions
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 9e43fe5209d3..cd7819cc0c9e 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * OMAP3-specific clock framework functions | 2 | * OMAP3-specific clock framework functions |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. |
5 | * Copyright (C) 2007-2008 Nokia Corporation | 5 | * Copyright (C) 2007-2009 Nokia Corporation |
6 | * | 6 | * |
7 | * Written by Paul Walmsley | 7 | * Written by Paul Walmsley |
8 | * Testing and integration fixes by Jouni Högander | 8 | * Testing and integration fixes by Jouni Högander |
@@ -41,6 +41,37 @@ | |||
41 | 41 | ||
42 | static const struct clkops clkops_noncore_dpll_ops; | 42 | static const struct clkops clkops_noncore_dpll_ops; |
43 | 43 | ||
44 | static void omap3430es2_clk_ssi_find_idlest(struct clk *clk, | ||
45 | void __iomem **idlest_reg, | ||
46 | u8 *idlest_bit); | ||
47 | static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk, | ||
48 | void __iomem **idlest_reg, | ||
49 | u8 *idlest_bit); | ||
50 | static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk, | ||
51 | void __iomem **idlest_reg, | ||
52 | u8 *idlest_bit); | ||
53 | |||
54 | static const struct clkops clkops_omap3430es2_ssi_wait = { | ||
55 | .enable = omap2_dflt_clk_enable, | ||
56 | .disable = omap2_dflt_clk_disable, | ||
57 | .find_idlest = omap3430es2_clk_ssi_find_idlest, | ||
58 | .find_companion = omap2_clk_dflt_find_companion, | ||
59 | }; | ||
60 | |||
61 | static const struct clkops clkops_omap3430es2_hsotgusb_wait = { | ||
62 | .enable = omap2_dflt_clk_enable, | ||
63 | .disable = omap2_dflt_clk_disable, | ||
64 | .find_idlest = omap3430es2_clk_hsotgusb_find_idlest, | ||
65 | .find_companion = omap2_clk_dflt_find_companion, | ||
66 | }; | ||
67 | |||
68 | static const struct clkops clkops_omap3430es2_dss_usbhost_wait = { | ||
69 | .enable = omap2_dflt_clk_enable, | ||
70 | .disable = omap2_dflt_clk_disable, | ||
71 | .find_idlest = omap3430es2_clk_dss_usbhost_find_idlest, | ||
72 | .find_companion = omap2_clk_dflt_find_companion, | ||
73 | }; | ||
74 | |||
44 | #include "clock34xx.h" | 75 | #include "clock34xx.h" |
45 | 76 | ||
46 | struct omap_clk { | 77 | struct omap_clk { |
@@ -157,10 +188,13 @@ static struct omap_clk omap34xx_clks[] = { | |||
157 | CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), | 188 | CLK(NULL, "fshostusb_fck", &fshostusb_fck, CK_3430ES1), |
158 | CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X), | 189 | CLK(NULL, "core_12m_fck", &core_12m_fck, CK_343X), |
159 | CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X), | 190 | CLK("omap_hdq.0", "fck", &hdq_fck, CK_343X), |
160 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck, CK_343X), | 191 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es1, CK_3430ES1), |
161 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck, CK_343X), | 192 | CLK(NULL, "ssi_ssr_fck", &ssi_ssr_fck_3430es2, CK_3430ES2), |
193 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es1, CK_3430ES1), | ||
194 | CLK(NULL, "ssi_sst_fck", &ssi_sst_fck_3430es2, CK_3430ES2), | ||
162 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), | 195 | CLK(NULL, "core_l3_ick", &core_l3_ick, CK_343X), |
163 | CLK("musb_hdrc", "ick", &hsotgusb_ick, CK_343X), | 196 | CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es1, CK_3430ES1), |
197 | CLK("musb_hdrc", "ick", &hsotgusb_ick_3430es2, CK_3430ES2), | ||
164 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), | 198 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_343X), |
165 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), | 199 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_343X), |
166 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), | 200 | CLK(NULL, "security_l3_ick", &security_l3_ick, CK_343X), |
@@ -193,18 +227,21 @@ static struct omap_clk omap34xx_clks[] = { | |||
193 | CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X), | 227 | CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_343X), |
194 | CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X), | 228 | CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_343X), |
195 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X), | 229 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_343X), |
196 | CLK(NULL, "ssi_ick", &ssi_ick, CK_343X), | 230 | CLK(NULL, "ssi_ick", &ssi_ick_3430es1, CK_3430ES1), |
231 | CLK(NULL, "ssi_ick", &ssi_ick_3430es2, CK_3430ES2), | ||
197 | CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1), | 232 | CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_3430ES1), |
198 | CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X), | 233 | CLK(NULL, "security_l4_ick2", &security_l4_ick2, CK_343X), |
199 | CLK(NULL, "aes1_ick", &aes1_ick, CK_343X), | 234 | CLK(NULL, "aes1_ick", &aes1_ick, CK_343X), |
200 | CLK("omap_rng", "ick", &rng_ick, CK_343X), | 235 | CLK("omap_rng", "ick", &rng_ick, CK_343X), |
201 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), | 236 | CLK(NULL, "sha11_ick", &sha11_ick, CK_343X), |
202 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), | 237 | CLK(NULL, "des1_ick", &des1_ick, CK_343X), |
203 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck, CK_343X), | 238 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), |
239 | CLK("omapfb", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2), | ||
204 | CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), | 240 | CLK("omapfb", "tv_fck", &dss_tv_fck, CK_343X), |
205 | CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), | 241 | CLK("omapfb", "video_fck", &dss_96m_fck, CK_343X), |
206 | CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), | 242 | CLK("omapfb", "dss2_fck", &dss2_alwon_fck, CK_343X), |
207 | CLK("omapfb", "ick", &dss_ick, CK_343X), | 243 | CLK("omapfb", "ick", &dss_ick_3430es1, CK_3430ES1), |
244 | CLK("omapfb", "ick", &dss_ick_3430es2, CK_3430ES2), | ||
208 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), | 245 | CLK(NULL, "cam_mclk", &cam_mclk, CK_343X), |
209 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), | 246 | CLK(NULL, "cam_ick", &cam_ick, CK_343X), |
210 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), | 247 | CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_343X), |
@@ -286,6 +323,87 @@ static struct omap_clk omap34xx_clks[] = { | |||
286 | 323 | ||
287 | #define MIN_SDRC_DLL_LOCK_FREQ 83000000 | 324 | #define MIN_SDRC_DLL_LOCK_FREQ 83000000 |
288 | 325 | ||
326 | #define CYCLES_PER_MHZ 1000000 | ||
327 | |||
328 | /* Scale factor for fixed-point arith in omap3_core_dpll_m2_set_rate() */ | ||
329 | #define SDRC_MPURATE_SCALE 8 | ||
330 | |||
331 | /* 2^SDRC_MPURATE_BASE_SHIFT: MPU MHz that SDRC_MPURATE_LOOPS is defined for */ | ||
332 | #define SDRC_MPURATE_BASE_SHIFT 9 | ||
333 | |||
334 | /* | ||
335 | * SDRC_MPURATE_LOOPS: Number of MPU loops to execute at | ||
336 | * 2^MPURATE_BASE_SHIFT MHz for SDRC to stabilize | ||
337 | */ | ||
338 | #define SDRC_MPURATE_LOOPS 96 | ||
339 | |||
340 | /** | ||
341 | * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI | ||
342 | * @clk: struct clk * being enabled | ||
343 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
344 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
345 | * | ||
346 | * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift | ||
347 | * from the CM_{I,F}CLKEN bit. Pass back the correct info via | ||
348 | * @idlest_reg and @idlest_bit. No return value. | ||
349 | */ | ||
350 | static void omap3430es2_clk_ssi_find_idlest(struct clk *clk, | ||
351 | void __iomem **idlest_reg, | ||
352 | u8 *idlest_bit) | ||
353 | { | ||
354 | u32 r; | ||
355 | |||
356 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
357 | *idlest_reg = (__force void __iomem *)r; | ||
358 | *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT; | ||
359 | } | ||
360 | |||
361 | /** | ||
362 | * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST | ||
363 | * @clk: struct clk * being enabled | ||
364 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
365 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
366 | * | ||
367 | * Some OMAP modules on OMAP3 ES2+ chips have both initiator and | ||
368 | * target IDLEST bits. For our purposes, we are concerned with the | ||
369 | * target IDLEST bits, which exist at a different bit position than | ||
370 | * the *CLKEN bit position for these modules (DSS and USBHOST) (The | ||
371 | * default find_idlest code assumes that they are at the same | ||
372 | * position.) No return value. | ||
373 | */ | ||
374 | static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk, | ||
375 | void __iomem **idlest_reg, | ||
376 | u8 *idlest_bit) | ||
377 | { | ||
378 | u32 r; | ||
379 | |||
380 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
381 | *idlest_reg = (__force void __iomem *)r; | ||
382 | /* USBHOST_IDLE has same shift */ | ||
383 | *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT; | ||
384 | } | ||
385 | |||
386 | /** | ||
387 | * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB | ||
388 | * @clk: struct clk * being enabled | ||
389 | * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into | ||
390 | * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into | ||
391 | * | ||
392 | * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different | ||
393 | * shift from the CM_{I,F}CLKEN bit. Pass back the correct info via | ||
394 | * @idlest_reg and @idlest_bit. No return value. | ||
395 | */ | ||
396 | static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk, | ||
397 | void __iomem **idlest_reg, | ||
398 | u8 *idlest_bit) | ||
399 | { | ||
400 | u32 r; | ||
401 | |||
402 | r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20); | ||
403 | *idlest_reg = (__force void __iomem *)r; | ||
404 | *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT; | ||
405 | } | ||
406 | |||
289 | /** | 407 | /** |
290 | * omap3_dpll_recalc - recalculate DPLL rate | 408 | * omap3_dpll_recalc - recalculate DPLL rate |
291 | * @clk: DPLL struct clk | 409 | * @clk: DPLL struct clk |
@@ -709,8 +827,11 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
709 | { | 827 | { |
710 | u32 new_div = 0; | 828 | u32 new_div = 0; |
711 | u32 unlock_dll = 0; | 829 | u32 unlock_dll = 0; |
712 | unsigned long validrate, sdrcrate; | 830 | u32 c; |
713 | struct omap_sdrc_params *sp; | 831 | unsigned long validrate, sdrcrate, mpurate; |
832 | struct omap_sdrc_params *sdrc_cs0; | ||
833 | struct omap_sdrc_params *sdrc_cs1; | ||
834 | int ret; | ||
714 | 835 | ||
715 | if (!clk || !rate) | 836 | if (!clk || !rate) |
716 | return -EINVAL; | 837 | return -EINVAL; |
@@ -718,21 +839,18 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
718 | if (clk != &dpll3_m2_ck) | 839 | if (clk != &dpll3_m2_ck) |
719 | return -EINVAL; | 840 | return -EINVAL; |
720 | 841 | ||
721 | if (rate == clk->rate) | ||
722 | return 0; | ||
723 | |||
724 | validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); | 842 | validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); |
725 | if (validrate != rate) | 843 | if (validrate != rate) |
726 | return -EINVAL; | 844 | return -EINVAL; |
727 | 845 | ||
728 | sdrcrate = sdrc_ick.rate; | 846 | sdrcrate = sdrc_ick.rate; |
729 | if (rate > clk->rate) | 847 | if (rate > clk->rate) |
730 | sdrcrate <<= ((rate / clk->rate) - 1); | 848 | sdrcrate <<= ((rate / clk->rate) >> 1); |
731 | else | 849 | else |
732 | sdrcrate >>= ((clk->rate / rate) - 1); | 850 | sdrcrate >>= ((clk->rate / rate) >> 1); |
733 | 851 | ||
734 | sp = omap2_sdrc_get_params(sdrcrate); | 852 | ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1); |
735 | if (!sp) | 853 | if (ret) |
736 | return -EINVAL; | 854 | return -EINVAL; |
737 | 855 | ||
738 | if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { | 856 | if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) { |
@@ -740,17 +858,42 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) | |||
740 | unlock_dll = 1; | 858 | unlock_dll = 1; |
741 | } | 859 | } |
742 | 860 | ||
861 | /* | ||
862 | * XXX This only needs to be done when the CPU frequency changes | ||
863 | */ | ||
864 | mpurate = arm_fck.rate / CYCLES_PER_MHZ; | ||
865 | c = (mpurate << SDRC_MPURATE_SCALE) >> SDRC_MPURATE_BASE_SHIFT; | ||
866 | c += 1; /* for safety */ | ||
867 | c *= SDRC_MPURATE_LOOPS; | ||
868 | c >>= SDRC_MPURATE_SCALE; | ||
869 | if (c == 0) | ||
870 | c = 1; | ||
871 | |||
743 | pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, | 872 | pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate, |
744 | validrate); | 873 | validrate); |
745 | pr_debug("clock: SDRC timing params used: %08x %08x %08x\n", | 874 | pr_debug("clock: SDRC CS0 timing params used:" |
746 | sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb); | 875 | " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", |
747 | 876 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | |
748 | /* REVISIT: SRAM code doesn't support other M2 divisors yet */ | 877 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr); |
749 | WARN_ON(new_div != 1 && new_div != 2); | 878 | if (sdrc_cs1) |
750 | 879 | pr_debug("clock: SDRC CS1 timing params used: " | |
751 | /* REVISIT: Add SDRC_MR changing to this code also */ | 880 | " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n", |
752 | omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla, | 881 | sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, |
753 | sp->actim_ctrlb, new_div, unlock_dll); | 882 | sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); |
883 | |||
884 | if (sdrc_cs1) | ||
885 | omap3_configure_core_dpll( | ||
886 | new_div, unlock_dll, c, rate > clk->rate, | ||
887 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | ||
888 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, | ||
889 | sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla, | ||
890 | sdrc_cs1->actim_ctrlb, sdrc_cs1->mr); | ||
891 | else | ||
892 | omap3_configure_core_dpll( | ||
893 | new_div, unlock_dll, c, rate > clk->rate, | ||
894 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, | ||
895 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, | ||
896 | 0, 0, 0, 0); | ||
754 | 897 | ||
755 | return 0; | 898 | return 0; |
756 | } | 899 | } |