diff options
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock.c | 201 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.h | 47 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.c | 299 | ||||
-rw-r--r-- | arch/arm/mach-omap2/clock34xx.h | 147 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm-regbits-34xx.h | 18 | ||||
-rw-r--r-- | arch/arm/mach-omap2/cm.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-omap2/control.c | 24 | ||||
-rw-r--r-- | arch/arm/mach-omap2/id.c | 195 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mcbsp.c | 208 | ||||
-rw-r--r-- | arch/arm/mach-omap2/memory.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prcm-common.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prcm.c | 98 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prm.h | 30 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sdrc.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sram242x.S (renamed from arch/arm/mach-omap2/sram-fn.S) | 105 | ||||
-rw-r--r-- | arch/arm/mach-omap2/sram243x.S | 321 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer-gp.c | 9 |
22 files changed, 1569 insertions, 205 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 2feb6870b735..93ee990618ef 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -3,9 +3,15 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := irq.o id.o io.o sram-fn.o memory.o control.o prcm.o clock.o mux.o \ | 6 | obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \ |
7 | devices.o serial.o gpmc.o timer-gp.o | 7 | devices.o serial.o gpmc.o timer-gp.o |
8 | 8 | ||
9 | obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o | ||
10 | |||
11 | # Functions loaded to SRAM | ||
12 | obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o | ||
13 | obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o | ||
14 | |||
9 | # Power Management | 15 | # Power Management |
10 | obj-$(CONFIG_PM) += pm.o sleep.o | 16 | obj-$(CONFIG_PM) += pm.o sleep.o |
11 | 17 | ||
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index ab9fc57d25f1..15675bce8012 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c | |||
@@ -41,6 +41,24 @@ | |||
41 | 41 | ||
42 | #define MAX_CLOCK_ENABLE_WAIT 100000 | 42 | #define MAX_CLOCK_ENABLE_WAIT 100000 |
43 | 43 | ||
44 | /* DPLL rate rounding: minimum DPLL multiplier, divider values */ | ||
45 | #define DPLL_MIN_MULTIPLIER 1 | ||
46 | #define DPLL_MIN_DIVIDER 1 | ||
47 | |||
48 | /* Possible error results from _dpll_test_mult */ | ||
49 | #define DPLL_MULT_UNDERFLOW (1 << 0) | ||
50 | |||
51 | /* | ||
52 | * Scale factor to mitigate roundoff errors in DPLL rate rounding. | ||
53 | * The higher the scale factor, the greater the risk of arithmetic overflow, | ||
54 | * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR | ||
55 | * must be a power of DPLL_SCALE_BASE. | ||
56 | */ | ||
57 | #define DPLL_SCALE_FACTOR 64 | ||
58 | #define DPLL_SCALE_BASE 2 | ||
59 | #define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ | ||
60 | (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) | ||
61 | |||
44 | u8 cpu_mask; | 62 | u8 cpu_mask; |
45 | 63 | ||
46 | /*------------------------------------------------------------------------- | 64 | /*------------------------------------------------------------------------- |
@@ -95,7 +113,7 @@ u32 omap2_get_dpll_rate(struct clk *clk) | |||
95 | { | 113 | { |
96 | long long dpll_clk; | 114 | long long dpll_clk; |
97 | u32 dpll_mult, dpll_div, dpll; | 115 | u32 dpll_mult, dpll_div, dpll; |
98 | const struct dpll_data *dd; | 116 | struct dpll_data *dd; |
99 | 117 | ||
100 | dd = clk->dpll_data; | 118 | dd = clk->dpll_data; |
101 | /* REVISIT: What do we return on error? */ | 119 | /* REVISIT: What do we return on error? */ |
@@ -603,7 +621,8 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) | |||
603 | clk->rate = clk->parent->rate / new_div; | 621 | clk->rate = clk->parent->rate / new_div; |
604 | 622 | ||
605 | if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { | 623 | if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { |
606 | __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL); | 624 | prm_write_mod_reg(OMAP24XX_VALID_CONFIG, |
625 | OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET); | ||
607 | wmb(); | 626 | wmb(); |
608 | } | 627 | } |
609 | 628 | ||
@@ -723,6 +742,184 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) | |||
723 | return 0; | 742 | return 0; |
724 | } | 743 | } |
725 | 744 | ||
745 | /* DPLL rate rounding code */ | ||
746 | |||
747 | /** | ||
748 | * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding | ||
749 | * @clk: struct clk * of the DPLL | ||
750 | * @tolerance: maximum rate error tolerance | ||
751 | * | ||
752 | * Set the maximum DPLL rate error tolerance for the rate rounding | ||
753 | * algorithm. The rate tolerance is an attempt to balance DPLL power | ||
754 | * saving (the least divider value "n") vs. rate fidelity (the least | ||
755 | * difference between the desired DPLL target rate and the rounded | ||
756 | * rate out of the algorithm). So, increasing the tolerance is likely | ||
757 | * to decrease DPLL power consumption and increase DPLL rate error. | ||
758 | * Returns -EINVAL if provided a null clock ptr or a clk that is not a | ||
759 | * DPLL; or 0 upon success. | ||
760 | */ | ||
761 | int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance) | ||
762 | { | ||
763 | if (!clk || !clk->dpll_data) | ||
764 | return -EINVAL; | ||
765 | |||
766 | clk->dpll_data->rate_tolerance = tolerance; | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n) | ||
772 | { | ||
773 | unsigned long long num; | ||
774 | |||
775 | num = (unsigned long long)parent_rate * m; | ||
776 | do_div(num, n); | ||
777 | return num; | ||
778 | } | ||
779 | |||
780 | /* | ||
781 | * _dpll_test_mult - test a DPLL multiplier value | ||
782 | * @m: pointer to the DPLL m (multiplier) value under test | ||
783 | * @n: current DPLL n (divider) value under test | ||
784 | * @new_rate: pointer to storage for the resulting rounded rate | ||
785 | * @target_rate: the desired DPLL rate | ||
786 | * @parent_rate: the DPLL's parent clock rate | ||
787 | * | ||
788 | * This code tests a DPLL multiplier value, ensuring that the | ||
789 | * resulting rate will not be higher than the target_rate, and that | ||
790 | * the multiplier value itself is valid for the DPLL. Initially, the | ||
791 | * integer pointed to by the m argument should be prescaled by | ||
792 | * multiplying by DPLL_SCALE_FACTOR. The code will replace this with | ||
793 | * a non-scaled m upon return. This non-scaled m will result in a | ||
794 | * new_rate as close as possible to target_rate (but not greater than | ||
795 | * target_rate) given the current (parent_rate, n, prescaled m) | ||
796 | * triple. Returns DPLL_MULT_UNDERFLOW in the event that the | ||
797 | * non-scaled m attempted to underflow, which can allow the calling | ||
798 | * function to bail out early; or 0 upon success. | ||
799 | */ | ||
800 | static int _dpll_test_mult(int *m, int n, unsigned long *new_rate, | ||
801 | unsigned long target_rate, | ||
802 | unsigned long parent_rate) | ||
803 | { | ||
804 | int flags = 0, carry = 0; | ||
805 | |||
806 | /* Unscale m and round if necessary */ | ||
807 | if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) | ||
808 | carry = 1; | ||
809 | *m = (*m / DPLL_SCALE_FACTOR) + carry; | ||
810 | |||
811 | /* | ||
812 | * The new rate must be <= the target rate to avoid programming | ||
813 | * a rate that is impossible for the hardware to handle | ||
814 | */ | ||
815 | *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); | ||
816 | if (*new_rate > target_rate) { | ||
817 | (*m)--; | ||
818 | *new_rate = 0; | ||
819 | } | ||
820 | |||
821 | /* Guard against m underflow */ | ||
822 | if (*m < DPLL_MIN_MULTIPLIER) { | ||
823 | *m = DPLL_MIN_MULTIPLIER; | ||
824 | *new_rate = 0; | ||
825 | flags = DPLL_MULT_UNDERFLOW; | ||
826 | } | ||
827 | |||
828 | if (*new_rate == 0) | ||
829 | *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); | ||
830 | |||
831 | return flags; | ||
832 | } | ||
833 | |||
834 | /** | ||
835 | * omap2_dpll_round_rate - round a target rate for an OMAP DPLL | ||
836 | * @clk: struct clk * for a DPLL | ||
837 | * @target_rate: desired DPLL clock rate | ||
838 | * | ||
839 | * Given a DPLL, a desired target rate, and a rate tolerance, round | ||
840 | * the target rate to a possible, programmable rate for this DPLL. | ||
841 | * Rate tolerance is assumed to be set by the caller before this | ||
842 | * function is called. Attempts to select the minimum possible n | ||
843 | * within the tolerance to reduce power consumption. Stores the | ||
844 | * computed (m, n) in the DPLL's dpll_data structure so set_rate() | ||
845 | * will not need to call this (expensive) function again. Returns ~0 | ||
846 | * if the target rate cannot be rounded, either because the rate is | ||
847 | * too low or because the rate tolerance is set too tightly; or the | ||
848 | * rounded rate upon success. | ||
849 | */ | ||
850 | long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate) | ||
851 | { | ||
852 | int m, n, r, e, scaled_max_m; | ||
853 | unsigned long scaled_rt_rp, new_rate; | ||
854 | int min_e = -1, min_e_m = -1, min_e_n = -1; | ||
855 | |||
856 | if (!clk || !clk->dpll_data) | ||
857 | return ~0; | ||
858 | |||
859 | pr_debug("clock: starting DPLL round_rate for clock %s, target rate " | ||
860 | "%ld\n", clk->name, target_rate); | ||
861 | |||
862 | scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR); | ||
863 | scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR; | ||
864 | |||
865 | clk->dpll_data->last_rounded_rate = 0; | ||
866 | |||
867 | for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) { | ||
868 | |||
869 | /* Compute the scaled DPLL multiplier, based on the divider */ | ||
870 | m = scaled_rt_rp * n; | ||
871 | |||
872 | /* | ||
873 | * Since we're counting n down, a m overflow means we can | ||
874 | * can immediately skip to the next n | ||
875 | */ | ||
876 | if (m > scaled_max_m) | ||
877 | continue; | ||
878 | |||
879 | r = _dpll_test_mult(&m, n, &new_rate, target_rate, | ||
880 | clk->parent->rate); | ||
881 | |||
882 | e = target_rate - new_rate; | ||
883 | pr_debug("clock: n = %d: m = %d: rate error is %d " | ||
884 | "(new_rate = %ld)\n", n, m, e, new_rate); | ||
885 | |||
886 | if (min_e == -1 || | ||
887 | min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) { | ||
888 | min_e = e; | ||
889 | min_e_m = m; | ||
890 | min_e_n = n; | ||
891 | |||
892 | pr_debug("clock: found new least error %d\n", min_e); | ||
893 | } | ||
894 | |||
895 | /* | ||
896 | * Since we're counting n down, a m underflow means we | ||
897 | * can bail out completely (since as n decreases in | ||
898 | * the next iteration, there's no way that m can | ||
899 | * increase beyond the current m) | ||
900 | */ | ||
901 | if (r & DPLL_MULT_UNDERFLOW) | ||
902 | break; | ||
903 | } | ||
904 | |||
905 | if (min_e < 0) { | ||
906 | pr_debug("clock: error: target rate or tolerance too low\n"); | ||
907 | return ~0; | ||
908 | } | ||
909 | |||
910 | clk->dpll_data->last_rounded_m = min_e_m; | ||
911 | clk->dpll_data->last_rounded_n = min_e_n; | ||
912 | clk->dpll_data->last_rounded_rate = | ||
913 | _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n); | ||
914 | |||
915 | pr_debug("clock: final least error: e = %d, m = %d, n = %d\n", | ||
916 | min_e, min_e_m, min_e_n); | ||
917 | pr_debug("clock: final rate: %ld (target rate: %ld)\n", | ||
918 | clk->dpll_data->last_rounded_rate, target_rate); | ||
919 | |||
920 | return clk->dpll_data->last_rounded_rate; | ||
921 | } | ||
922 | |||
726 | /*------------------------------------------------------------------------- | 923 | /*------------------------------------------------------------------------- |
727 | * Omap2 clock reset and init functions | 924 | * Omap2 clock reset and init functions |
728 | *-------------------------------------------------------------------------*/ | 925 | *-------------------------------------------------------------------------*/ |
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index d5980a9e09a4..3cd37cb57c5a 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h | |||
@@ -18,11 +18,16 @@ | |||
18 | 18 | ||
19 | #include <asm/arch/clock.h> | 19 | #include <asm/arch/clock.h> |
20 | 20 | ||
21 | /* The maximum error between a target DPLL rate and the rounded rate in Hz */ | ||
22 | #define DEFAULT_DPLL_RATE_TOLERANCE 50000 | ||
23 | |||
21 | int omap2_clk_enable(struct clk *clk); | 24 | int omap2_clk_enable(struct clk *clk); |
22 | void omap2_clk_disable(struct clk *clk); | 25 | void omap2_clk_disable(struct clk *clk); |
23 | long omap2_clk_round_rate(struct clk *clk, unsigned long rate); | 26 | long omap2_clk_round_rate(struct clk *clk, unsigned long rate); |
24 | int omap2_clk_set_rate(struct clk *clk, unsigned long rate); | 27 | int omap2_clk_set_rate(struct clk *clk, unsigned long rate); |
25 | int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); | 28 | int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent); |
29 | int omap2_dpll_rate_tolerance_set(struct clk *clk, unsigned int tolerance); | ||
30 | long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate); | ||
26 | 31 | ||
27 | #ifdef CONFIG_OMAP_RESET_CLOCKS | 32 | #ifdef CONFIG_OMAP_RESET_CLOCKS |
28 | void omap2_clk_disable_unused(struct clk *clk); | 33 | void omap2_clk_disable_unused(struct clk *clk); |
@@ -42,6 +47,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate); | |||
42 | int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); | 47 | int omap2_clksel_set_rate(struct clk *clk, unsigned long rate); |
43 | u32 omap2_get_dpll_rate(struct clk *clk); | 48 | u32 omap2_get_dpll_rate(struct clk *clk); |
44 | int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); | 49 | int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name); |
50 | void omap2_clk_prepare_for_reboot(void); | ||
45 | 51 | ||
46 | extern u8 cpu_mask; | 52 | extern u8 cpu_mask; |
47 | 53 | ||
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index ece32d8acba4..aa567876651d 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
@@ -154,7 +154,7 @@ static void omap2_clk_fixed_disable(struct clk *clk) | |||
154 | * Uses the current prcm set to tell if a rate is valid. | 154 | * Uses the current prcm set to tell if a rate is valid. |
155 | * You can go slower, but not faster within a given rate set. | 155 | * You can go slower, but not faster within a given rate set. |
156 | */ | 156 | */ |
157 | static u32 omap2_dpll_round_rate(unsigned long target_rate) | 157 | long omap2_dpllcore_round_rate(unsigned long target_rate) |
158 | { | 158 | { |
159 | u32 high, low, core_clk_src; | 159 | u32 high, low, core_clk_src; |
160 | 160 | ||
@@ -183,14 +183,14 @@ static u32 omap2_dpll_round_rate(unsigned long target_rate) | |||
183 | 183 | ||
184 | } | 184 | } |
185 | 185 | ||
186 | static void omap2_dpll_recalc(struct clk *clk) | 186 | static void omap2_dpllcore_recalc(struct clk *clk) |
187 | { | 187 | { |
188 | clk->rate = omap2_get_dpll_rate_24xx(clk); | 188 | clk->rate = omap2_get_dpll_rate_24xx(clk); |
189 | 189 | ||
190 | propagate_rate(clk); | 190 | propagate_rate(clk); |
191 | } | 191 | } |
192 | 192 | ||
193 | static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) | 193 | static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) |
194 | { | 194 | { |
195 | u32 cur_rate, low, mult, div, valid_rate, done_rate; | 195 | u32 cur_rate, low, mult, div, valid_rate, done_rate; |
196 | u32 bypass = 0; | 196 | u32 bypass = 0; |
@@ -209,7 +209,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) | |||
209 | } else if ((rate == (cur_rate * 2)) && (mult == 1)) { | 209 | } else if ((rate == (cur_rate * 2)) && (mult == 1)) { |
210 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); | 210 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); |
211 | } else if (rate != cur_rate) { | 211 | } else if (rate != cur_rate) { |
212 | valid_rate = omap2_dpll_round_rate(rate); | 212 | valid_rate = omap2_dpllcore_round_rate(rate); |
213 | if (valid_rate != rate) | 213 | if (valid_rate != rate) |
214 | goto dpll_exit; | 214 | goto dpll_exit; |
215 | 215 | ||
@@ -256,7 +256,7 @@ static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate) | |||
256 | omap2_init_memory_params(omap2_dll_force_needed()); | 256 | omap2_init_memory_params(omap2_dll_force_needed()); |
257 | omap2_reprogram_sdrc(done_rate, 0); | 257 | omap2_reprogram_sdrc(done_rate, 0); |
258 | } | 258 | } |
259 | omap2_dpll_recalc(&dpll_ck); | 259 | omap2_dpllcore_recalc(&dpll_ck); |
260 | ret = 0; | 260 | ret = 0; |
261 | 261 | ||
262 | dpll_exit: | 262 | dpll_exit: |
@@ -383,7 +383,7 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) | |||
383 | 383 | ||
384 | local_irq_restore(flags); | 384 | local_irq_restore(flags); |
385 | } | 385 | } |
386 | omap2_dpll_recalc(&dpll_ck); | 386 | omap2_dpllcore_recalc(&dpll_ck); |
387 | 387 | ||
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h index 88081ed13f96..be4e25554e05 100644 --- a/arch/arm/mach-omap2/clock24xx.h +++ b/arch/arm/mach-omap2/clock24xx.h | |||
@@ -30,12 +30,12 @@ static long omap2_round_to_table_rate(struct clk *clk, unsigned long rate); | |||
30 | static void omap2_sys_clk_recalc(struct clk *clk); | 30 | static void omap2_sys_clk_recalc(struct clk *clk); |
31 | static void omap2_osc_clk_recalc(struct clk *clk); | 31 | static void omap2_osc_clk_recalc(struct clk *clk); |
32 | static void omap2_sys_clk_recalc(struct clk *clk); | 32 | static void omap2_sys_clk_recalc(struct clk *clk); |
33 | static void omap2_dpll_recalc(struct clk *clk); | 33 | static void omap2_dpllcore_recalc(struct clk *clk); |
34 | static int omap2_clk_fixed_enable(struct clk *clk); | 34 | static int omap2_clk_fixed_enable(struct clk *clk); |
35 | static void omap2_clk_fixed_disable(struct clk *clk); | 35 | static void omap2_clk_fixed_disable(struct clk *clk); |
36 | static int omap2_enable_osc_ck(struct clk *clk); | 36 | static int omap2_enable_osc_ck(struct clk *clk); |
37 | static void omap2_disable_osc_ck(struct clk *clk); | 37 | static void omap2_disable_osc_ck(struct clk *clk); |
38 | static int omap2_reprogram_dpll(struct clk *clk, unsigned long rate); | 38 | static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate); |
39 | 39 | ||
40 | /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. | 40 | /* Key dividers which make up a PRCM set. Ratio's for a PRCM are mandated. |
41 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP | 41 | * xtal_speed, dpll_speed, mpu_speed, CM_CLKSEL_MPU,CM_CLKSEL_DSP |
@@ -665,20 +665,27 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */ | |||
665 | * deal with this | 665 | * deal with this |
666 | */ | 666 | */ |
667 | 667 | ||
668 | static const struct dpll_data dpll_dd = { | 668 | static struct dpll_data dpll_dd = { |
669 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), | 669 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), |
670 | .mult_mask = OMAP24XX_DPLL_MULT_MASK, | 670 | .mult_mask = OMAP24XX_DPLL_MULT_MASK, |
671 | .div1_mask = OMAP24XX_DPLL_DIV_MASK, | 671 | .div1_mask = OMAP24XX_DPLL_DIV_MASK, |
672 | .max_multiplier = 1024, | ||
673 | .max_divider = 16, | ||
674 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
672 | }; | 675 | }; |
673 | 676 | ||
677 | /* | ||
678 | * XXX Cannot add round_rate here yet, as this is still a composite clock, | ||
679 | * not just a DPLL | ||
680 | */ | ||
674 | static struct clk dpll_ck = { | 681 | static struct clk dpll_ck = { |
675 | .name = "dpll_ck", | 682 | .name = "dpll_ck", |
676 | .parent = &sys_ck, /* Can be func_32k also */ | 683 | .parent = &sys_ck, /* Can be func_32k also */ |
677 | .dpll_data = &dpll_dd, | 684 | .dpll_data = &dpll_dd, |
678 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | | 685 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | |
679 | RATE_PROPAGATES | ALWAYS_ENABLED, | 686 | RATE_PROPAGATES | ALWAYS_ENABLED, |
680 | .recalc = &omap2_dpll_recalc, | 687 | .recalc = &omap2_dpllcore_recalc, |
681 | .set_rate = &omap2_reprogram_dpll, | 688 | .set_rate = &omap2_reprogram_dpllcore, |
682 | }; | 689 | }; |
683 | 690 | ||
684 | static struct clk apll96_ck = { | 691 | static struct clk apll96_ck = { |
@@ -1747,7 +1754,8 @@ static struct clk gpt12_fck = { | |||
1747 | }; | 1754 | }; |
1748 | 1755 | ||
1749 | static struct clk mcbsp1_ick = { | 1756 | static struct clk mcbsp1_ick = { |
1750 | .name = "mcbsp1_ick", | 1757 | .name = "mcbsp_ick", |
1758 | .id = 1, | ||
1751 | .parent = &l4_ck, | 1759 | .parent = &l4_ck, |
1752 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1760 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1753 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1761 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
@@ -1756,7 +1764,8 @@ static struct clk mcbsp1_ick = { | |||
1756 | }; | 1764 | }; |
1757 | 1765 | ||
1758 | static struct clk mcbsp1_fck = { | 1766 | static struct clk mcbsp1_fck = { |
1759 | .name = "mcbsp1_fck", | 1767 | .name = "mcbsp_fck", |
1768 | .id = 1, | ||
1760 | .parent = &func_96m_ck, | 1769 | .parent = &func_96m_ck, |
1761 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1770 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1762 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1771 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
@@ -1765,7 +1774,8 @@ static struct clk mcbsp1_fck = { | |||
1765 | }; | 1774 | }; |
1766 | 1775 | ||
1767 | static struct clk mcbsp2_ick = { | 1776 | static struct clk mcbsp2_ick = { |
1768 | .name = "mcbsp2_ick", | 1777 | .name = "mcbsp_ick", |
1778 | .id = 2, | ||
1769 | .parent = &l4_ck, | 1779 | .parent = &l4_ck, |
1770 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1780 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1771 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1781 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
@@ -1774,7 +1784,8 @@ static struct clk mcbsp2_ick = { | |||
1774 | }; | 1784 | }; |
1775 | 1785 | ||
1776 | static struct clk mcbsp2_fck = { | 1786 | static struct clk mcbsp2_fck = { |
1777 | .name = "mcbsp2_fck", | 1787 | .name = "mcbsp_fck", |
1788 | .id = 2, | ||
1778 | .parent = &func_96m_ck, | 1789 | .parent = &func_96m_ck, |
1779 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, | 1790 | .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, |
1780 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1791 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
@@ -1783,7 +1794,8 @@ static struct clk mcbsp2_fck = { | |||
1783 | }; | 1794 | }; |
1784 | 1795 | ||
1785 | static struct clk mcbsp3_ick = { | 1796 | static struct clk mcbsp3_ick = { |
1786 | .name = "mcbsp3_ick", | 1797 | .name = "mcbsp_ick", |
1798 | .id = 3, | ||
1787 | .parent = &l4_ck, | 1799 | .parent = &l4_ck, |
1788 | .flags = CLOCK_IN_OMAP243X, | 1800 | .flags = CLOCK_IN_OMAP243X, |
1789 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), | 1801 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), |
@@ -1792,7 +1804,8 @@ static struct clk mcbsp3_ick = { | |||
1792 | }; | 1804 | }; |
1793 | 1805 | ||
1794 | static struct clk mcbsp3_fck = { | 1806 | static struct clk mcbsp3_fck = { |
1795 | .name = "mcbsp3_fck", | 1807 | .name = "mcbsp_fck", |
1808 | .id = 3, | ||
1796 | .parent = &func_96m_ck, | 1809 | .parent = &func_96m_ck, |
1797 | .flags = CLOCK_IN_OMAP243X, | 1810 | .flags = CLOCK_IN_OMAP243X, |
1798 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), | 1811 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), |
@@ -1801,7 +1814,8 @@ static struct clk mcbsp3_fck = { | |||
1801 | }; | 1814 | }; |
1802 | 1815 | ||
1803 | static struct clk mcbsp4_ick = { | 1816 | static struct clk mcbsp4_ick = { |
1804 | .name = "mcbsp4_ick", | 1817 | .name = "mcbsp_ick", |
1818 | .id = 4, | ||
1805 | .parent = &l4_ck, | 1819 | .parent = &l4_ck, |
1806 | .flags = CLOCK_IN_OMAP243X, | 1820 | .flags = CLOCK_IN_OMAP243X, |
1807 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), | 1821 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), |
@@ -1810,7 +1824,8 @@ static struct clk mcbsp4_ick = { | |||
1810 | }; | 1824 | }; |
1811 | 1825 | ||
1812 | static struct clk mcbsp4_fck = { | 1826 | static struct clk mcbsp4_fck = { |
1813 | .name = "mcbsp4_fck", | 1827 | .name = "mcbsp_fck", |
1828 | .id = 4, | ||
1814 | .parent = &func_96m_ck, | 1829 | .parent = &func_96m_ck, |
1815 | .flags = CLOCK_IN_OMAP243X, | 1830 | .flags = CLOCK_IN_OMAP243X, |
1816 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), | 1831 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), |
@@ -1819,7 +1834,8 @@ static struct clk mcbsp4_fck = { | |||
1819 | }; | 1834 | }; |
1820 | 1835 | ||
1821 | static struct clk mcbsp5_ick = { | 1836 | static struct clk mcbsp5_ick = { |
1822 | .name = "mcbsp5_ick", | 1837 | .name = "mcbsp_ick", |
1838 | .id = 5, | ||
1823 | .parent = &l4_ck, | 1839 | .parent = &l4_ck, |
1824 | .flags = CLOCK_IN_OMAP243X, | 1840 | .flags = CLOCK_IN_OMAP243X, |
1825 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), | 1841 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2), |
@@ -1828,7 +1844,8 @@ static struct clk mcbsp5_ick = { | |||
1828 | }; | 1844 | }; |
1829 | 1845 | ||
1830 | static struct clk mcbsp5_fck = { | 1846 | static struct clk mcbsp5_fck = { |
1831 | .name = "mcbsp5_fck", | 1847 | .name = "mcbsp_fck", |
1848 | .id = 5, | ||
1832 | .parent = &func_96m_ck, | 1849 | .parent = &func_96m_ck, |
1833 | .flags = CLOCK_IN_OMAP243X, | 1850 | .flags = CLOCK_IN_OMAP243X, |
1834 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), | 1851 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2), |
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index b42bdd6079a5..4263099b1ad3 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP3-specific clock framework functions | 2 | * OMAP3-specific clock framework functions |
3 | * | 3 | * |
4 | * Copyright (C) 2007 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. |
5 | * Copyright (C) 2007 Nokia Corporation | 5 | * Copyright (C) 2007-2008 Nokia Corporation |
6 | * | 6 | * |
7 | * Written by Paul Walmsley | 7 | * Written by Paul Walmsley |
8 | * Testing and integration fixes by Jouni Högander | ||
8 | * | 9 | * |
9 | * Parts of this code are based on code written by | 10 | * Parts of this code are based on code written by |
10 | * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu | 11 | * Richard Woodruff, Tony Lindgren, Tuukka Tikkanen, Karthik Dasu |
@@ -23,6 +24,7 @@ | |||
23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
24 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/limits.h> | ||
26 | 28 | ||
27 | #include <asm/arch/clock.h> | 29 | #include <asm/arch/clock.h> |
28 | #include <asm/arch/sram.h> | 30 | #include <asm/arch/sram.h> |
@@ -37,8 +39,11 @@ | |||
37 | #include "cm.h" | 39 | #include "cm.h" |
38 | #include "cm-regbits-34xx.h" | 40 | #include "cm-regbits-34xx.h" |
39 | 41 | ||
40 | /* CM_CLKEN_PLL*.EN* bit values */ | 42 | /* CM_AUTOIDLE_PLL*.AUTO_* bit values */ |
41 | #define DPLL_LOCKED 0x7 | 43 | #define DPLL_AUTOIDLE_DISABLE 0x0 |
44 | #define DPLL_AUTOIDLE_LOW_POWER_STOP 0x1 | ||
45 | |||
46 | #define MAX_DPLL_WAIT_TRIES 1000000 | ||
42 | 47 | ||
43 | /** | 48 | /** |
44 | * omap3_dpll_recalc - recalculate DPLL rate | 49 | * omap3_dpll_recalc - recalculate DPLL rate |
@@ -53,6 +58,290 @@ static void omap3_dpll_recalc(struct clk *clk) | |||
53 | propagate_rate(clk); | 58 | propagate_rate(clk); |
54 | } | 59 | } |
55 | 60 | ||
61 | /* _omap3_dpll_write_clken - write clken_bits arg to a DPLL's enable bits */ | ||
62 | static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) | ||
63 | { | ||
64 | const struct dpll_data *dd; | ||
65 | |||
66 | dd = clk->dpll_data; | ||
67 | |||
68 | cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask), | ||
69 | dd->control_reg); | ||
70 | } | ||
71 | |||
72 | /* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */ | ||
73 | static int _omap3_wait_dpll_status(struct clk *clk, u8 state) | ||
74 | { | ||
75 | const struct dpll_data *dd; | ||
76 | int i = 0; | ||
77 | int ret = -EINVAL; | ||
78 | u32 idlest_mask; | ||
79 | |||
80 | dd = clk->dpll_data; | ||
81 | |||
82 | state <<= dd->idlest_bit; | ||
83 | idlest_mask = 1 << dd->idlest_bit; | ||
84 | |||
85 | while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) && | ||
86 | i < MAX_DPLL_WAIT_TRIES) { | ||
87 | i++; | ||
88 | udelay(1); | ||
89 | } | ||
90 | |||
91 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
92 | printk(KERN_ERR "clock: %s failed transition to '%s'\n", | ||
93 | clk->name, (state) ? "locked" : "bypassed"); | ||
94 | } else { | ||
95 | pr_debug("clock: %s transition to '%s' in %d loops\n", | ||
96 | clk->name, (state) ? "locked" : "bypassed", i); | ||
97 | |||
98 | ret = 0; | ||
99 | } | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | /* Non-CORE DPLL (e.g., DPLLs that do not control SDRC) clock functions */ | ||
105 | |||
106 | /* | ||
107 | * _omap3_noncore_dpll_lock - instruct a DPLL to lock and wait for readiness | ||
108 | * @clk: pointer to a DPLL struct clk | ||
109 | * | ||
110 | * Instructs a non-CORE DPLL to lock. Waits for the DPLL to report | ||
111 | * readiness before returning. Will save and restore the DPLL's | ||
112 | * autoidle state across the enable, per the CDP code. If the DPLL | ||
113 | * locked successfully, return 0; if the DPLL did not lock in the time | ||
114 | * allotted, or DPLL3 was passed in, return -EINVAL. | ||
115 | */ | ||
116 | static int _omap3_noncore_dpll_lock(struct clk *clk) | ||
117 | { | ||
118 | u8 ai; | ||
119 | int r; | ||
120 | |||
121 | if (clk == &dpll3_ck) | ||
122 | return -EINVAL; | ||
123 | |||
124 | pr_debug("clock: locking DPLL %s\n", clk->name); | ||
125 | |||
126 | ai = omap3_dpll_autoidle_read(clk); | ||
127 | |||
128 | _omap3_dpll_write_clken(clk, DPLL_LOCKED); | ||
129 | |||
130 | if (ai) { | ||
131 | /* | ||
132 | * If no downstream clocks are enabled, CM_IDLEST bit | ||
133 | * may never become active, so don't wait for DPLL to lock. | ||
134 | */ | ||
135 | r = 0; | ||
136 | omap3_dpll_allow_idle(clk); | ||
137 | } else { | ||
138 | r = _omap3_wait_dpll_status(clk, 1); | ||
139 | omap3_dpll_deny_idle(clk); | ||
140 | }; | ||
141 | |||
142 | return r; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * omap3_noncore_dpll_bypass - instruct a DPLL to bypass and wait for readiness | ||
147 | * @clk: pointer to a DPLL struct clk | ||
148 | * | ||
149 | * Instructs a non-CORE DPLL to enter low-power bypass mode. In | ||
150 | * bypass mode, the DPLL's rate is set equal to its parent clock's | ||
151 | * rate. Waits for the DPLL to report readiness before returning. | ||
152 | * Will save and restore the DPLL's autoidle state across the enable, | ||
153 | * per the CDP code. If the DPLL entered bypass mode successfully, | ||
154 | * return 0; if the DPLL did not enter bypass in the time allotted, or | ||
155 | * DPLL3 was passed in, or the DPLL does not support low-power bypass, | ||
156 | * return -EINVAL. | ||
157 | */ | ||
158 | static int _omap3_noncore_dpll_bypass(struct clk *clk) | ||
159 | { | ||
160 | int r; | ||
161 | u8 ai; | ||
162 | |||
163 | if (clk == &dpll3_ck) | ||
164 | return -EINVAL; | ||
165 | |||
166 | if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_BYPASS))) | ||
167 | return -EINVAL; | ||
168 | |||
169 | pr_debug("clock: configuring DPLL %s for low-power bypass\n", | ||
170 | clk->name); | ||
171 | |||
172 | ai = omap3_dpll_autoidle_read(clk); | ||
173 | |||
174 | _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_BYPASS); | ||
175 | |||
176 | r = _omap3_wait_dpll_status(clk, 0); | ||
177 | |||
178 | if (ai) | ||
179 | omap3_dpll_allow_idle(clk); | ||
180 | else | ||
181 | omap3_dpll_deny_idle(clk); | ||
182 | |||
183 | return r; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * _omap3_noncore_dpll_stop - instruct a DPLL to stop | ||
188 | * @clk: pointer to a DPLL struct clk | ||
189 | * | ||
190 | * Instructs a non-CORE DPLL to enter low-power stop. Will save and | ||
191 | * restore the DPLL's autoidle state across the stop, per the CDP | ||
192 | * code. If DPLL3 was passed in, or the DPLL does not support | ||
193 | * low-power stop, return -EINVAL; otherwise, return 0. | ||
194 | */ | ||
195 | static int _omap3_noncore_dpll_stop(struct clk *clk) | ||
196 | { | ||
197 | u8 ai; | ||
198 | |||
199 | if (clk == &dpll3_ck) | ||
200 | return -EINVAL; | ||
201 | |||
202 | if (!(clk->dpll_data->modes & (1 << DPLL_LOW_POWER_STOP))) | ||
203 | return -EINVAL; | ||
204 | |||
205 | pr_debug("clock: stopping DPLL %s\n", clk->name); | ||
206 | |||
207 | ai = omap3_dpll_autoidle_read(clk); | ||
208 | |||
209 | _omap3_dpll_write_clken(clk, DPLL_LOW_POWER_STOP); | ||
210 | |||
211 | if (ai) | ||
212 | omap3_dpll_allow_idle(clk); | ||
213 | else | ||
214 | omap3_dpll_deny_idle(clk); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | /** | ||
220 | * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode | ||
221 | * @clk: pointer to a DPLL struct clk | ||
222 | * | ||
223 | * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. | ||
224 | * The choice of modes depends on the DPLL's programmed rate: if it is | ||
225 | * the same as the DPLL's parent clock, it will enter bypass; | ||
226 | * otherwise, it will enter lock. This code will wait for the DPLL to | ||
227 | * indicate readiness before returning, unless the DPLL takes too long | ||
228 | * to enter the target state. Intended to be used as the struct clk's | ||
229 | * enable function. If DPLL3 was passed in, or the DPLL does not | ||
230 | * support low-power stop, or if the DPLL took too long to enter | ||
231 | * bypass or lock, return -EINVAL; otherwise, return 0. | ||
232 | */ | ||
233 | static int omap3_noncore_dpll_enable(struct clk *clk) | ||
234 | { | ||
235 | int r; | ||
236 | |||
237 | if (clk == &dpll3_ck) | ||
238 | return -EINVAL; | ||
239 | |||
240 | if (clk->parent->rate == clk_get_rate(clk)) | ||
241 | r = _omap3_noncore_dpll_bypass(clk); | ||
242 | else | ||
243 | r = _omap3_noncore_dpll_lock(clk); | ||
244 | |||
245 | return r; | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * omap3_noncore_dpll_enable - instruct a DPLL to enter bypass or lock mode | ||
250 | * @clk: pointer to a DPLL struct clk | ||
251 | * | ||
252 | * Instructs a non-CORE DPLL to enable, e.g., to enter bypass or lock. | ||
253 | * The choice of modes depends on the DPLL's programmed rate: if it is | ||
254 | * the same as the DPLL's parent clock, it will enter bypass; | ||
255 | * otherwise, it will enter lock. This code will wait for the DPLL to | ||
256 | * indicate readiness before returning, unless the DPLL takes too long | ||
257 | * to enter the target state. Intended to be used as the struct clk's | ||
258 | * enable function. If DPLL3 was passed in, or the DPLL does not | ||
259 | * support low-power stop, or if the DPLL took too long to enter | ||
260 | * bypass or lock, return -EINVAL; otherwise, return 0. | ||
261 | */ | ||
262 | static void omap3_noncore_dpll_disable(struct clk *clk) | ||
263 | { | ||
264 | if (clk == &dpll3_ck) | ||
265 | return; | ||
266 | |||
267 | _omap3_noncore_dpll_stop(clk); | ||
268 | } | ||
269 | |||
270 | /** | ||
271 | * omap3_dpll_autoidle_read - read a DPLL's autoidle bits | ||
272 | * @clk: struct clk * of the DPLL to read | ||
273 | * | ||
274 | * Return the DPLL's autoidle bits, shifted down to bit 0. Returns | ||
275 | * -EINVAL if passed a null pointer or if the struct clk does not | ||
276 | * appear to refer to a DPLL. | ||
277 | */ | ||
278 | static u32 omap3_dpll_autoidle_read(struct clk *clk) | ||
279 | { | ||
280 | const struct dpll_data *dd; | ||
281 | u32 v; | ||
282 | |||
283 | if (!clk || !clk->dpll_data) | ||
284 | return -EINVAL; | ||
285 | |||
286 | dd = clk->dpll_data; | ||
287 | |||
288 | v = cm_read_reg(dd->autoidle_reg); | ||
289 | v &= dd->autoidle_mask; | ||
290 | v >>= __ffs(dd->autoidle_mask); | ||
291 | |||
292 | return v; | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * omap3_dpll_allow_idle - enable DPLL autoidle bits | ||
297 | * @clk: struct clk * of the DPLL to operate on | ||
298 | * | ||
299 | * Enable DPLL automatic idle control. This automatic idle mode | ||
300 | * switching takes effect only when the DPLL is locked, at least on | ||
301 | * OMAP3430. The DPLL will enter low-power stop when its downstream | ||
302 | * clocks are gated. No return value. | ||
303 | */ | ||
304 | static void omap3_dpll_allow_idle(struct clk *clk) | ||
305 | { | ||
306 | const struct dpll_data *dd; | ||
307 | |||
308 | if (!clk || !clk->dpll_data) | ||
309 | return; | ||
310 | |||
311 | dd = clk->dpll_data; | ||
312 | |||
313 | /* | ||
314 | * REVISIT: CORE DPLL can optionally enter low-power bypass | ||
315 | * by writing 0x5 instead of 0x1. Add some mechanism to | ||
316 | * optionally enter this mode. | ||
317 | */ | ||
318 | cm_rmw_reg_bits(dd->autoidle_mask, | ||
319 | DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask), | ||
320 | dd->autoidle_reg); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * omap3_dpll_deny_idle - prevent DPLL from automatically idling | ||
325 | * @clk: struct clk * of the DPLL to operate on | ||
326 | * | ||
327 | * Disable DPLL automatic idle control. No return value. | ||
328 | */ | ||
329 | static void omap3_dpll_deny_idle(struct clk *clk) | ||
330 | { | ||
331 | const struct dpll_data *dd; | ||
332 | |||
333 | if (!clk || !clk->dpll_data) | ||
334 | return; | ||
335 | |||
336 | dd = clk->dpll_data; | ||
337 | |||
338 | cm_rmw_reg_bits(dd->autoidle_mask, | ||
339 | DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask), | ||
340 | dd->autoidle_reg); | ||
341 | } | ||
342 | |||
343 | /* Clock control for DPLL outputs */ | ||
344 | |||
56 | /** | 345 | /** |
57 | * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate | 346 | * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate |
58 | * @clk: DPLL output struct clk | 347 | * @clk: DPLL output struct clk |
@@ -89,6 +378,8 @@ static void omap3_clkoutx2_recalc(struct clk *clk) | |||
89 | propagate_rate(clk); | 378 | propagate_rate(clk); |
90 | } | 379 | } |
91 | 380 | ||
381 | /* Common clock code */ | ||
382 | |||
92 | /* | 383 | /* |
93 | * As it is structured now, this will prevent an OMAP2/3 multiboot | 384 | * As it is structured now, this will prevent an OMAP2/3 multiboot |
94 | * kernel from compiling. This will need further attention. | 385 | * kernel from compiling. This will need further attention. |
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h index c9c5972a2e25..05757eb032bc 100644 --- a/arch/arm/mach-omap2/clock34xx.h +++ b/arch/arm/mach-omap2/clock34xx.h | |||
@@ -1,14 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * OMAP3 clock framework | 2 | * OMAP3 clock framework |
3 | * | 3 | * |
4 | * Virtual clocks are introduced as a convenient tools. | ||
5 | * They are sources for other clocks and not supposed | ||
6 | * to be requested from drivers directly. | ||
7 | * | ||
8 | * Copyright (C) 2007-2008 Texas Instruments, Inc. | 4 | * Copyright (C) 2007-2008 Texas Instruments, Inc. |
9 | * Copyright (C) 2007-2008 Nokia Corporation | 5 | * Copyright (C) 2007-2008 Nokia Corporation |
10 | * | 6 | * |
11 | * Written by Paul Walmsley | 7 | * Written by Paul Walmsley |
8 | * With many device clock fixes by Kevin Hilman and Jouni Högander | ||
9 | * DPLL bypass clock support added by Roman Tereshonkov | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Virtual clocks are introduced as convenient tools. | ||
15 | * They are sources for other clocks and not supposed | ||
16 | * to be requested from drivers directly. | ||
12 | */ | 17 | */ |
13 | 18 | ||
14 | #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H | 19 | #ifndef __ARCH_ARM_MACH_OMAP2_CLOCK34XX_H |
@@ -24,6 +29,15 @@ | |||
24 | 29 | ||
25 | static void omap3_dpll_recalc(struct clk *clk); | 30 | static void omap3_dpll_recalc(struct clk *clk); |
26 | static void omap3_clkoutx2_recalc(struct clk *clk); | 31 | static void omap3_clkoutx2_recalc(struct clk *clk); |
32 | static void omap3_dpll_allow_idle(struct clk *clk); | ||
33 | static void omap3_dpll_deny_idle(struct clk *clk); | ||
34 | static u32 omap3_dpll_autoidle_read(struct clk *clk); | ||
35 | static int omap3_noncore_dpll_enable(struct clk *clk); | ||
36 | static void omap3_noncore_dpll_disable(struct clk *clk); | ||
37 | |||
38 | /* Maximum DPLL multiplier, divider values for OMAP3 */ | ||
39 | #define OMAP3_MAX_DPLL_MULT 2048 | ||
40 | #define OMAP3_MAX_DPLL_DIV 128 | ||
27 | 41 | ||
28 | /* | 42 | /* |
29 | * DPLL1 supplies clock to the MPU. | 43 | * DPLL1 supplies clock to the MPU. |
@@ -33,6 +47,11 @@ static void omap3_clkoutx2_recalc(struct clk *clk); | |||
33 | * DPLL5 supplies other peripheral clocks (USBHOST, USIM). | 47 | * DPLL5 supplies other peripheral clocks (USBHOST, USIM). |
34 | */ | 48 | */ |
35 | 49 | ||
50 | /* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ | ||
51 | #define DPLL_LOW_POWER_STOP 0x1 | ||
52 | #define DPLL_LOW_POWER_BYPASS 0x5 | ||
53 | #define DPLL_LOCKED 0x7 | ||
54 | |||
36 | /* PRM CLOCKS */ | 55 | /* PRM CLOCKS */ |
37 | 56 | ||
38 | /* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */ | 57 | /* According to timer32k.c, this is a 32768Hz clock, not a 32000Hz clock. */ |
@@ -240,15 +259,23 @@ static const struct clksel_rate div16_dpll_rates[] = { | |||
240 | /* DPLL1 */ | 259 | /* DPLL1 */ |
241 | /* MPU clock source */ | 260 | /* MPU clock source */ |
242 | /* Type: DPLL */ | 261 | /* Type: DPLL */ |
243 | static const struct dpll_data dpll1_dd = { | 262 | static struct dpll_data dpll1_dd = { |
244 | .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), | 263 | .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), |
245 | .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, | 264 | .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, |
246 | .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, | 265 | .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, |
247 | .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), | 266 | .control_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKEN_PLL), |
248 | .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, | 267 | .enable_mask = OMAP3430_EN_MPU_DPLL_MASK, |
268 | .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), | ||
249 | .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, | 269 | .auto_recal_bit = OMAP3430_EN_MPU_DPLL_DRIFTGUARD_SHIFT, |
250 | .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, | 270 | .recal_en_bit = OMAP3430_MPU_DPLL_RECAL_EN_SHIFT, |
251 | .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, | 271 | .recal_st_bit = OMAP3430_MPU_DPLL_ST_SHIFT, |
272 | .autoidle_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_AUTOIDLE_PLL), | ||
273 | .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, | ||
274 | .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), | ||
275 | .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, | ||
276 | .max_multiplier = OMAP3_MAX_DPLL_MULT, | ||
277 | .max_divider = OMAP3_MAX_DPLL_DIV, | ||
278 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
252 | }; | 279 | }; |
253 | 280 | ||
254 | static struct clk dpll1_ck = { | 281 | static struct clk dpll1_ck = { |
@@ -256,6 +283,7 @@ static struct clk dpll1_ck = { | |||
256 | .parent = &sys_ck, | 283 | .parent = &sys_ck, |
257 | .dpll_data = &dpll1_dd, | 284 | .dpll_data = &dpll1_dd, |
258 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, | 285 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, |
286 | .round_rate = &omap2_dpll_round_rate, | ||
259 | .recalc = &omap3_dpll_recalc, | 287 | .recalc = &omap3_dpll_recalc, |
260 | }; | 288 | }; |
261 | 289 | ||
@@ -297,22 +325,34 @@ static struct clk dpll1_x2m2_ck = { | |||
297 | /* IVA2 clock source */ | 325 | /* IVA2 clock source */ |
298 | /* Type: DPLL */ | 326 | /* Type: DPLL */ |
299 | 327 | ||
300 | static const struct dpll_data dpll2_dd = { | 328 | static struct dpll_data dpll2_dd = { |
301 | .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), | 329 | .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), |
302 | .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, | 330 | .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, |
303 | .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, | 331 | .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, |
304 | .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), | 332 | .control_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL), |
305 | .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, | 333 | .enable_mask = OMAP3430_EN_IVA2_DPLL_MASK, |
334 | .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED) | | ||
335 | (1 << DPLL_LOW_POWER_BYPASS), | ||
306 | .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, | 336 | .auto_recal_bit = OMAP3430_EN_IVA2_DPLL_DRIFTGUARD_SHIFT, |
307 | .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, | 337 | .recal_en_bit = OMAP3430_PRM_IRQENABLE_MPU_IVA2_DPLL_RECAL_EN_SHIFT, |
308 | .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, | 338 | .recal_st_bit = OMAP3430_PRM_IRQSTATUS_MPU_IVA2_DPLL_ST_SHIFT, |
339 | .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), | ||
340 | .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, | ||
341 | .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), | ||
342 | .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT, | ||
343 | .max_multiplier = OMAP3_MAX_DPLL_MULT, | ||
344 | .max_divider = OMAP3_MAX_DPLL_DIV, | ||
345 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
309 | }; | 346 | }; |
310 | 347 | ||
311 | static struct clk dpll2_ck = { | 348 | static struct clk dpll2_ck = { |
312 | .name = "dpll2_ck", | 349 | .name = "dpll2_ck", |
313 | .parent = &sys_ck, | 350 | .parent = &sys_ck, |
314 | .dpll_data = &dpll2_dd, | 351 | .dpll_data = &dpll2_dd, |
315 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, | 352 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, |
353 | .enable = &omap3_noncore_dpll_enable, | ||
354 | .disable = &omap3_noncore_dpll_disable, | ||
355 | .round_rate = &omap2_dpll_round_rate, | ||
316 | .recalc = &omap3_dpll_recalc, | 356 | .recalc = &omap3_dpll_recalc, |
317 | }; | 357 | }; |
318 | 358 | ||
@@ -338,10 +378,12 @@ static struct clk dpll2_m2_ck = { | |||
338 | .recalc = &omap2_clksel_recalc, | 378 | .recalc = &omap2_clksel_recalc, |
339 | }; | 379 | }; |
340 | 380 | ||
341 | /* DPLL3 */ | 381 | /* |
342 | /* Source clock for all interfaces and for some device fclks */ | 382 | * DPLL3 |
343 | /* Type: DPLL */ | 383 | * Source clock for all interfaces and for some device fclks |
344 | static const struct dpll_data dpll3_dd = { | 384 | * REVISIT: Also supports fast relock bypass - not included below |
385 | */ | ||
386 | static struct dpll_data dpll3_dd = { | ||
345 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), | 387 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), |
346 | .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, | 388 | .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, |
347 | .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, | 389 | .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, |
@@ -350,6 +392,11 @@ static const struct dpll_data dpll3_dd = { | |||
350 | .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, | 392 | .auto_recal_bit = OMAP3430_EN_CORE_DPLL_DRIFTGUARD_SHIFT, |
351 | .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, | 393 | .recal_en_bit = OMAP3430_CORE_DPLL_RECAL_EN_SHIFT, |
352 | .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, | 394 | .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, |
395 | .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), | ||
396 | .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, | ||
397 | .max_multiplier = OMAP3_MAX_DPLL_MULT, | ||
398 | .max_divider = OMAP3_MAX_DPLL_DIV, | ||
399 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
353 | }; | 400 | }; |
354 | 401 | ||
355 | static struct clk dpll3_ck = { | 402 | static struct clk dpll3_ck = { |
@@ -357,6 +404,7 @@ static struct clk dpll3_ck = { | |||
357 | .parent = &sys_ck, | 404 | .parent = &sys_ck, |
358 | .dpll_data = &dpll3_dd, | 405 | .dpll_data = &dpll3_dd, |
359 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, | 406 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, |
407 | .round_rate = &omap2_dpll_round_rate, | ||
360 | .recalc = &omap3_dpll_recalc, | 408 | .recalc = &omap3_dpll_recalc, |
361 | }; | 409 | }; |
362 | 410 | ||
@@ -439,7 +487,7 @@ static struct clk core_ck = { | |||
439 | .name = "core_ck", | 487 | .name = "core_ck", |
440 | .init = &omap2_init_clksel_parent, | 488 | .init = &omap2_init_clksel_parent, |
441 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 489 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
442 | .clksel_mask = OMAP3430_ST_CORE_CLK, | 490 | .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, |
443 | .clksel = core_ck_clksel, | 491 | .clksel = core_ck_clksel, |
444 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 492 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
445 | PARENT_CONTROLS_CLOCK, | 493 | PARENT_CONTROLS_CLOCK, |
@@ -456,7 +504,7 @@ static struct clk dpll3_m2x2_ck = { | |||
456 | .name = "dpll3_m2x2_ck", | 504 | .name = "dpll3_m2x2_ck", |
457 | .init = &omap2_init_clksel_parent, | 505 | .init = &omap2_init_clksel_parent, |
458 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 506 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
459 | .clksel_mask = OMAP3430_ST_CORE_CLK, | 507 | .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, |
460 | .clksel = dpll3_m2x2_ck_clksel, | 508 | .clksel = dpll3_m2x2_ck_clksel, |
461 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 509 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
462 | PARENT_CONTROLS_CLOCK, | 510 | PARENT_CONTROLS_CLOCK, |
@@ -503,7 +551,7 @@ static struct clk emu_core_alwon_ck = { | |||
503 | .parent = &dpll3_m3x2_ck, | 551 | .parent = &dpll3_m3x2_ck, |
504 | .init = &omap2_init_clksel_parent, | 552 | .init = &omap2_init_clksel_parent, |
505 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 553 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
506 | .clksel_mask = OMAP3430_ST_CORE_CLK, | 554 | .clksel_mask = OMAP3430_ST_CORE_CLK_MASK, |
507 | .clksel = emu_core_alwon_ck_clksel, | 555 | .clksel = emu_core_alwon_ck_clksel, |
508 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 556 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
509 | PARENT_CONTROLS_CLOCK, | 557 | PARENT_CONTROLS_CLOCK, |
@@ -513,22 +561,33 @@ static struct clk emu_core_alwon_ck = { | |||
513 | /* DPLL4 */ | 561 | /* DPLL4 */ |
514 | /* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ | 562 | /* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ |
515 | /* Type: DPLL */ | 563 | /* Type: DPLL */ |
516 | static const struct dpll_data dpll4_dd = { | 564 | static struct dpll_data dpll4_dd = { |
517 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), | 565 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), |
518 | .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, | 566 | .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, |
519 | .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, | 567 | .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, |
520 | .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), | 568 | .control_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN), |
521 | .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, | 569 | .enable_mask = OMAP3430_EN_PERIPH_DPLL_MASK, |
570 | .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), | ||
522 | .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, | 571 | .auto_recal_bit = OMAP3430_EN_PERIPH_DPLL_DRIFTGUARD_SHIFT, |
523 | .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, | 572 | .recal_en_bit = OMAP3430_PERIPH_DPLL_RECAL_EN_SHIFT, |
524 | .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, | 573 | .recal_st_bit = OMAP3430_PERIPH_DPLL_ST_SHIFT, |
574 | .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), | ||
575 | .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, | ||
576 | .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | ||
577 | .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, | ||
578 | .max_multiplier = OMAP3_MAX_DPLL_MULT, | ||
579 | .max_divider = OMAP3_MAX_DPLL_DIV, | ||
580 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
525 | }; | 581 | }; |
526 | 582 | ||
527 | static struct clk dpll4_ck = { | 583 | static struct clk dpll4_ck = { |
528 | .name = "dpll4_ck", | 584 | .name = "dpll4_ck", |
529 | .parent = &sys_ck, | 585 | .parent = &sys_ck, |
530 | .dpll_data = &dpll4_dd, | 586 | .dpll_data = &dpll4_dd, |
531 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, | 587 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, |
588 | .enable = &omap3_noncore_dpll_enable, | ||
589 | .disable = &omap3_noncore_dpll_disable, | ||
590 | .round_rate = &omap2_dpll_round_rate, | ||
532 | .recalc = &omap3_dpll_recalc, | 591 | .recalc = &omap3_dpll_recalc, |
533 | }; | 592 | }; |
534 | 593 | ||
@@ -584,7 +643,7 @@ static struct clk omap_96m_alwon_fck = { | |||
584 | .parent = &dpll4_m2x2_ck, | 643 | .parent = &dpll4_m2x2_ck, |
585 | .init = &omap2_init_clksel_parent, | 644 | .init = &omap2_init_clksel_parent, |
586 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 645 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
587 | .clksel_mask = OMAP3430_ST_PERIPH_CLK, | 646 | .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
588 | .clksel = omap_96m_alwon_fck_clksel, | 647 | .clksel = omap_96m_alwon_fck_clksel, |
589 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 648 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
590 | PARENT_CONTROLS_CLOCK, | 649 | PARENT_CONTROLS_CLOCK, |
@@ -610,7 +669,7 @@ static struct clk cm_96m_fck = { | |||
610 | .parent = &dpll4_m2x2_ck, | 669 | .parent = &dpll4_m2x2_ck, |
611 | .init = &omap2_init_clksel_parent, | 670 | .init = &omap2_init_clksel_parent, |
612 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 671 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
613 | .clksel_mask = OMAP3430_ST_PERIPH_CLK, | 672 | .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
614 | .clksel = cm_96m_fck_clksel, | 673 | .clksel = cm_96m_fck_clksel, |
615 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 674 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
616 | PARENT_CONTROLS_CLOCK, | 675 | PARENT_CONTROLS_CLOCK, |
@@ -652,7 +711,7 @@ static struct clk virt_omap_54m_fck = { | |||
652 | .parent = &dpll4_m3x2_ck, | 711 | .parent = &dpll4_m3x2_ck, |
653 | .init = &omap2_init_clksel_parent, | 712 | .init = &omap2_init_clksel_parent, |
654 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 713 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
655 | .clksel_mask = OMAP3430_ST_PERIPH_CLK, | 714 | .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
656 | .clksel = virt_omap_54m_fck_clksel, | 715 | .clksel = virt_omap_54m_fck_clksel, |
657 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | | 716 | .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | |
658 | PARENT_CONTROLS_CLOCK, | 717 | PARENT_CONTROLS_CLOCK, |
@@ -804,23 +863,33 @@ static struct clk emu_per_alwon_ck = { | |||
804 | /* Supplies 120MHz clock, USIM source clock */ | 863 | /* Supplies 120MHz clock, USIM source clock */ |
805 | /* Type: DPLL */ | 864 | /* Type: DPLL */ |
806 | /* 3430ES2 only */ | 865 | /* 3430ES2 only */ |
807 | static const struct dpll_data dpll5_dd = { | 866 | static struct dpll_data dpll5_dd = { |
808 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), | 867 | .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), |
809 | .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, | 868 | .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, |
810 | .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, | 869 | .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, |
811 | .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), | 870 | .control_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKEN2), |
812 | .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, | 871 | .enable_mask = OMAP3430ES2_EN_PERIPH2_DPLL_MASK, |
872 | .modes = (1 << DPLL_LOW_POWER_STOP) | (1 << DPLL_LOCKED), | ||
813 | .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, | 873 | .auto_recal_bit = OMAP3430ES2_EN_PERIPH2_DPLL_DRIFTGUARD_SHIFT, |
814 | .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, | 874 | .recal_en_bit = OMAP3430ES2_SND_PERIPH_DPLL_RECAL_EN_SHIFT, |
815 | .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, | 875 | .recal_st_bit = OMAP3430ES2_SND_PERIPH_DPLL_ST_SHIFT, |
876 | .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_AUTOIDLE2_PLL), | ||
877 | .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, | ||
878 | .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), | ||
879 | .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, | ||
880 | .max_multiplier = OMAP3_MAX_DPLL_MULT, | ||
881 | .max_divider = OMAP3_MAX_DPLL_DIV, | ||
882 | .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE | ||
816 | }; | 883 | }; |
817 | 884 | ||
818 | static struct clk dpll5_ck = { | 885 | static struct clk dpll5_ck = { |
819 | .name = "dpll5_ck", | 886 | .name = "dpll5_ck", |
820 | .parent = &sys_ck, | 887 | .parent = &sys_ck, |
821 | .dpll_data = &dpll5_dd, | 888 | .dpll_data = &dpll5_dd, |
822 | .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES | | 889 | .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, |
823 | ALWAYS_ENABLED, | 890 | .enable = &omap3_noncore_dpll_enable, |
891 | .disable = &omap3_noncore_dpll_disable, | ||
892 | .round_rate = &omap2_dpll_round_rate, | ||
824 | .recalc = &omap3_dpll_recalc, | 893 | .recalc = &omap3_dpll_recalc, |
825 | }; | 894 | }; |
826 | 895 | ||
@@ -1365,7 +1434,8 @@ static const struct clksel mcbsp_15_clksel[] = { | |||
1365 | }; | 1434 | }; |
1366 | 1435 | ||
1367 | static struct clk mcbsp5_fck = { | 1436 | static struct clk mcbsp5_fck = { |
1368 | .name = "mcbsp5_fck", | 1437 | .name = "mcbsp_fck", |
1438 | .id = 5, | ||
1369 | .init = &omap2_init_clksel_parent, | 1439 | .init = &omap2_init_clksel_parent, |
1370 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1440 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
1371 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, | 1441 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, |
@@ -1377,7 +1447,8 @@ static struct clk mcbsp5_fck = { | |||
1377 | }; | 1447 | }; |
1378 | 1448 | ||
1379 | static struct clk mcbsp1_fck = { | 1449 | static struct clk mcbsp1_fck = { |
1380 | .name = "mcbsp1_fck", | 1450 | .name = "mcbsp_fck", |
1451 | .id = 1, | ||
1381 | .init = &omap2_init_clksel_parent, | 1452 | .init = &omap2_init_clksel_parent, |
1382 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), | 1453 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), |
1383 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, | 1454 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, |
@@ -1789,7 +1860,8 @@ static struct clk gpt10_ick = { | |||
1789 | }; | 1860 | }; |
1790 | 1861 | ||
1791 | static struct clk mcbsp5_ick = { | 1862 | static struct clk mcbsp5_ick = { |
1792 | .name = "mcbsp5_ick", | 1863 | .name = "mcbsp_ick", |
1864 | .id = 5, | ||
1793 | .parent = &core_l4_ick, | 1865 | .parent = &core_l4_ick, |
1794 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1866 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
1795 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, | 1867 | .enable_bit = OMAP3430_EN_MCBSP5_SHIFT, |
@@ -1798,7 +1870,8 @@ static struct clk mcbsp5_ick = { | |||
1798 | }; | 1870 | }; |
1799 | 1871 | ||
1800 | static struct clk mcbsp1_ick = { | 1872 | static struct clk mcbsp1_ick = { |
1801 | .name = "mcbsp1_ick", | 1873 | .name = "mcbsp_ick", |
1874 | .id = 1, | ||
1802 | .parent = &core_l4_ick, | 1875 | .parent = &core_l4_ick, |
1803 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), | 1876 | .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1), |
1804 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, | 1877 | .enable_bit = OMAP3430_EN_MCBSP1_SHIFT, |
@@ -1935,7 +2008,7 @@ static struct clk dss1_alwon_fck = { | |||
1935 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), | 2008 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN), |
1936 | .enable_bit = OMAP3430_EN_DSS1_SHIFT, | 2009 | .enable_bit = OMAP3430_EN_DSS1_SHIFT, |
1937 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 2010 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
1938 | .clksel_mask = OMAP3430_ST_PERIPH_CLK, | 2011 | .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
1939 | .clksel = dss1_alwon_fck_clksel, | 2012 | .clksel = dss1_alwon_fck_clksel, |
1940 | .flags = CLOCK_IN_OMAP343X, | 2013 | .flags = CLOCK_IN_OMAP343X, |
1941 | .recalc = &omap2_clksel_recalc, | 2014 | .recalc = &omap2_clksel_recalc, |
@@ -1991,7 +2064,7 @@ static struct clk cam_mclk = { | |||
1991 | .parent = &dpll4_m5x2_ck, | 2064 | .parent = &dpll4_m5x2_ck, |
1992 | .init = &omap2_init_clksel_parent, | 2065 | .init = &omap2_init_clksel_parent, |
1993 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), | 2066 | .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), |
1994 | .clksel_mask = OMAP3430_ST_PERIPH_CLK, | 2067 | .clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK, |
1995 | .clksel = cam_mclk_clksel, | 2068 | .clksel = cam_mclk_clksel, |
1996 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), | 2069 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN), |
1997 | .enable_bit = OMAP3430_EN_CAM_SHIFT, | 2070 | .enable_bit = OMAP3430_EN_CAM_SHIFT, |
@@ -2541,7 +2614,8 @@ static struct clk gpt2_ick = { | |||
2541 | }; | 2614 | }; |
2542 | 2615 | ||
2543 | static struct clk mcbsp2_ick = { | 2616 | static struct clk mcbsp2_ick = { |
2544 | .name = "mcbsp2_ick", | 2617 | .name = "mcbsp_ick", |
2618 | .id = 2, | ||
2545 | .parent = &per_l4_ick, | 2619 | .parent = &per_l4_ick, |
2546 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2620 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
2547 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, | 2621 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, |
@@ -2550,7 +2624,8 @@ static struct clk mcbsp2_ick = { | |||
2550 | }; | 2624 | }; |
2551 | 2625 | ||
2552 | static struct clk mcbsp3_ick = { | 2626 | static struct clk mcbsp3_ick = { |
2553 | .name = "mcbsp3_ick", | 2627 | .name = "mcbsp_ick", |
2628 | .id = 3, | ||
2554 | .parent = &per_l4_ick, | 2629 | .parent = &per_l4_ick, |
2555 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2630 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
2556 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, | 2631 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, |
@@ -2559,7 +2634,8 @@ static struct clk mcbsp3_ick = { | |||
2559 | }; | 2634 | }; |
2560 | 2635 | ||
2561 | static struct clk mcbsp4_ick = { | 2636 | static struct clk mcbsp4_ick = { |
2562 | .name = "mcbsp4_ick", | 2637 | .name = "mcbsp_ick", |
2638 | .id = 4, | ||
2563 | .parent = &per_l4_ick, | 2639 | .parent = &per_l4_ick, |
2564 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), | 2640 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN), |
2565 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, | 2641 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, |
@@ -2574,7 +2650,8 @@ static const struct clksel mcbsp_234_clksel[] = { | |||
2574 | }; | 2650 | }; |
2575 | 2651 | ||
2576 | static struct clk mcbsp2_fck = { | 2652 | static struct clk mcbsp2_fck = { |
2577 | .name = "mcbsp2_fck", | 2653 | .name = "mcbsp_fck", |
2654 | .id = 2, | ||
2578 | .init = &omap2_init_clksel_parent, | 2655 | .init = &omap2_init_clksel_parent, |
2579 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2656 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2580 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, | 2657 | .enable_bit = OMAP3430_EN_MCBSP2_SHIFT, |
@@ -2586,7 +2663,8 @@ static struct clk mcbsp2_fck = { | |||
2586 | }; | 2663 | }; |
2587 | 2664 | ||
2588 | static struct clk mcbsp3_fck = { | 2665 | static struct clk mcbsp3_fck = { |
2589 | .name = "mcbsp3_fck", | 2666 | .name = "mcbsp_fck", |
2667 | .id = 3, | ||
2590 | .init = &omap2_init_clksel_parent, | 2668 | .init = &omap2_init_clksel_parent, |
2591 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2669 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2592 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, | 2670 | .enable_bit = OMAP3430_EN_MCBSP3_SHIFT, |
@@ -2598,7 +2676,8 @@ static struct clk mcbsp3_fck = { | |||
2598 | }; | 2676 | }; |
2599 | 2677 | ||
2600 | static struct clk mcbsp4_fck = { | 2678 | static struct clk mcbsp4_fck = { |
2601 | .name = "mcbsp4_fck", | 2679 | .name = "mcbsp_fck", |
2680 | .id = 4, | ||
2602 | .init = &omap2_init_clksel_parent, | 2681 | .init = &omap2_init_clksel_parent, |
2603 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), | 2682 | .enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN), |
2604 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, | 2683 | .enable_bit = OMAP3430_EN_MCBSP4_SHIFT, |
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 3c38395f6442..ee4c0ca1a708 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h | |||
@@ -72,7 +72,8 @@ | |||
72 | #define OMAP3430_ST_IVA2 (1 << 0) | 72 | #define OMAP3430_ST_IVA2 (1 << 0) |
73 | 73 | ||
74 | /* CM_IDLEST_PLL_IVA2 */ | 74 | /* CM_IDLEST_PLL_IVA2 */ |
75 | #define OMAP3430_ST_IVA2_CLK (1 << 0) | 75 | #define OMAP3430_ST_IVA2_CLK_SHIFT 0 |
76 | #define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) | ||
76 | 77 | ||
77 | /* CM_AUTOIDLE_PLL_IVA2 */ | 78 | /* CM_AUTOIDLE_PLL_IVA2 */ |
78 | #define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0 | 79 | #define OMAP3430_AUTO_IVA2_DPLL_SHIFT 0 |
@@ -115,10 +116,7 @@ | |||
115 | #define OMAP3430_ST_MPU (1 << 0) | 116 | #define OMAP3430_ST_MPU (1 << 0) |
116 | 117 | ||
117 | /* CM_IDLEST_PLL_MPU */ | 118 | /* CM_IDLEST_PLL_MPU */ |
118 | #define OMAP3430_ST_MPU_CLK (1 << 0) | 119 | #define OMAP3430_ST_MPU_CLK_SHIFT 0 |
119 | #define OMAP3430_ST_IVA2_CLK_MASK (1 << 0) | ||
120 | |||
121 | /* CM_IDLEST_PLL_MPU */ | ||
122 | #define OMAP3430_ST_MPU_CLK_MASK (1 << 0) | 120 | #define OMAP3430_ST_MPU_CLK_MASK (1 << 0) |
123 | 121 | ||
124 | /* CM_AUTOIDLE_PLL_MPU */ | 122 | /* CM_AUTOIDLE_PLL_MPU */ |
@@ -408,8 +406,10 @@ | |||
408 | #define OMAP3430_ST_12M_CLK (1 << 4) | 406 | #define OMAP3430_ST_12M_CLK (1 << 4) |
409 | #define OMAP3430_ST_48M_CLK (1 << 3) | 407 | #define OMAP3430_ST_48M_CLK (1 << 3) |
410 | #define OMAP3430_ST_96M_CLK (1 << 2) | 408 | #define OMAP3430_ST_96M_CLK (1 << 2) |
411 | #define OMAP3430_ST_PERIPH_CLK (1 << 1) | 409 | #define OMAP3430_ST_PERIPH_CLK_SHIFT 1 |
412 | #define OMAP3430_ST_CORE_CLK (1 << 0) | 410 | #define OMAP3430_ST_PERIPH_CLK_MASK (1 << 1) |
411 | #define OMAP3430_ST_CORE_CLK_SHIFT 0 | ||
412 | #define OMAP3430_ST_CORE_CLK_MASK (1 << 0) | ||
413 | 413 | ||
414 | /* CM_IDLEST2_CKGEN */ | 414 | /* CM_IDLEST2_CKGEN */ |
415 | #define OMAP3430ES2_ST_120M_CLK_SHIFT 1 | 415 | #define OMAP3430ES2_ST_120M_CLK_SHIFT 1 |
@@ -423,6 +423,10 @@ | |||
423 | #define OMAP3430_AUTO_CORE_DPLL_SHIFT 0 | 423 | #define OMAP3430_AUTO_CORE_DPLL_SHIFT 0 |
424 | #define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0) | 424 | #define OMAP3430_AUTO_CORE_DPLL_MASK (0x7 << 0) |
425 | 425 | ||
426 | /* CM_AUTOIDLE2_PLL */ | ||
427 | #define OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT 0 | ||
428 | #define OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK (0x7 << 0) | ||
429 | |||
426 | /* CM_CLKSEL1_PLL */ | 430 | /* CM_CLKSEL1_PLL */ |
427 | /* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */ | 431 | /* Note that OMAP3430_CORE_DPLL_CLKOUT_DIV_MASK was (0x3 << 27) on 3430ES1 */ |
428 | #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27 | 432 | #define OMAP3430_CORE_DPLL_CLKOUT_DIV_SHIFT 27 |
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index 8489f3029fed..87a44c715aa4 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h | |||
@@ -81,6 +81,7 @@ | |||
81 | #define OMAP3430ES2_CM_FCLKEN3 0x0008 | 81 | #define OMAP3430ES2_CM_FCLKEN3 0x0008 |
82 | #define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 | 82 | #define OMAP3430_CM_IDLEST_PLL CM_IDLEST2 |
83 | #define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 | 83 | #define OMAP3430_CM_AUTOIDLE_PLL CM_AUTOIDLE2 |
84 | #define OMAP3430ES2_CM_AUTOIDLE2_PLL CM_AUTOIDLE2 | ||
84 | #define OMAP3430_CM_CLKSEL1 CM_CLKSEL | 85 | #define OMAP3430_CM_CLKSEL1 CM_CLKSEL |
85 | #define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL | 86 | #define OMAP3430_CM_CLKSEL1_PLL CM_CLKSEL |
86 | #define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 | 87 | #define OMAP3430_CM_CLKSEL2_PLL CM_CLKSEL2 |
@@ -96,15 +97,21 @@ | |||
96 | /* Clock management domain register get/set */ | 97 | /* Clock management domain register get/set */ |
97 | 98 | ||
98 | #ifndef __ASSEMBLER__ | 99 | #ifndef __ASSEMBLER__ |
99 | static inline void cm_write_mod_reg(u32 val, s16 module, s16 idx) | 100 | |
101 | extern u32 cm_read_mod_reg(s16 module, u16 idx); | ||
102 | extern void cm_write_mod_reg(u32 val, s16 module, u16 idx); | ||
103 | extern u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | ||
104 | |||
105 | static inline u32 cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
100 | { | 106 | { |
101 | __raw_writel(val, OMAP_CM_REGADDR(module, idx)); | 107 | return cm_rmw_mod_reg_bits(bits, bits, module, idx); |
102 | } | 108 | } |
103 | 109 | ||
104 | static inline u32 cm_read_mod_reg(s16 module, s16 idx) | 110 | static inline u32 cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) |
105 | { | 111 | { |
106 | return __raw_readl(OMAP_CM_REGADDR(module, idx)); | 112 | return cm_rmw_mod_reg_bits(bits, 0x0, module, idx); |
107 | } | 113 | } |
114 | |||
108 | #endif | 115 | #endif |
109 | 116 | ||
110 | /* CM register bits shared between 24XX and 3430 */ | 117 | /* CM register bits shared between 24XX and 3430 */ |
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index a5d86a49c213..51f70300996f 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c | |||
@@ -13,22 +13,21 @@ | |||
13 | #undef DEBUG | 13 | #undef DEBUG |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/io.h> | ||
16 | 17 | ||
17 | #include <asm/io.h> | 18 | #include <asm/arch/common.h> |
18 | |||
19 | #include <asm/arch/control.h> | 19 | #include <asm/arch/control.h> |
20 | 20 | ||
21 | static u32 omap2_ctrl_base; | 21 | static void __iomem *omap2_ctrl_base; |
22 | 22 | ||
23 | #define OMAP_CTRL_REGADDR(reg) (void __iomem *)IO_ADDRESS(omap2_ctrl_base \ | 23 | #define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg)) |
24 | + (reg)) | ||
25 | 24 | ||
26 | void omap_ctrl_base_set(u32 base) | 25 | void __init omap2_set_globals_control(struct omap_globals *omap2_globals) |
27 | { | 26 | { |
28 | omap2_ctrl_base = base; | 27 | omap2_ctrl_base = omap2_globals->ctrl; |
29 | } | 28 | } |
30 | 29 | ||
31 | u32 omap_ctrl_base_get(void) | 30 | void __iomem *omap_ctrl_base_get(void) |
32 | { | 31 | { |
33 | return omap2_ctrl_base; | 32 | return omap2_ctrl_base; |
34 | } | 33 | } |
@@ -50,25 +49,16 @@ u32 omap_ctrl_readl(u16 offset) | |||
50 | 49 | ||
51 | void omap_ctrl_writeb(u8 val, u16 offset) | 50 | void omap_ctrl_writeb(u8 val, u16 offset) |
52 | { | 51 | { |
53 | pr_debug("omap_ctrl_writeb: writing 0x%0x to 0x%0x\n", val, | ||
54 | (u32)OMAP_CTRL_REGADDR(offset)); | ||
55 | |||
56 | __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); | 52 | __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); |
57 | } | 53 | } |
58 | 54 | ||
59 | void omap_ctrl_writew(u16 val, u16 offset) | 55 | void omap_ctrl_writew(u16 val, u16 offset) |
60 | { | 56 | { |
61 | pr_debug("omap_ctrl_writew: writing 0x%0x to 0x%0x\n", val, | ||
62 | (u32)OMAP_CTRL_REGADDR(offset)); | ||
63 | |||
64 | __raw_writew(val, OMAP_CTRL_REGADDR(offset)); | 57 | __raw_writew(val, OMAP_CTRL_REGADDR(offset)); |
65 | } | 58 | } |
66 | 59 | ||
67 | void omap_ctrl_writel(u32 val, u16 offset) | 60 | void omap_ctrl_writel(u32 val, u16 offset) |
68 | { | 61 | { |
69 | pr_debug("omap_ctrl_writel: writing 0x%0x to 0x%0x\n", val, | ||
70 | (u32)OMAP_CTRL_REGADDR(offset)); | ||
71 | |||
72 | __raw_writel(val, OMAP_CTRL_REGADDR(offset)); | 62 | __raw_writel(val, OMAP_CTRL_REGADDR(offset)); |
73 | } | 63 | } |
74 | 64 | ||
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 4dfd878d7968..dff4b16cead6 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -17,16 +17,23 @@ | |||
17 | 17 | ||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | 19 | ||
20 | #if defined(CONFIG_ARCH_OMAP2420) | 20 | #include <asm/arch/control.h> |
21 | #define OMAP24XX_TAP_BASE io_p2v(0x48014000) | 21 | #include <asm/arch/cpu.h> |
22 | #endif | ||
23 | 22 | ||
24 | #if defined(CONFIG_ARCH_OMAP2430) | 23 | #if defined(CONFIG_ARCH_OMAP2420) |
25 | #define OMAP24XX_TAP_BASE io_p2v(0x4900A000) | 24 | #define TAP_BASE io_p2v(0x48014000) |
25 | #elif defined(CONFIG_ARCH_OMAP2430) | ||
26 | #define TAP_BASE io_p2v(0x4900A000) | ||
27 | #elif defined(CONFIG_ARCH_OMAP34XX) | ||
28 | #define TAP_BASE io_p2v(0x4830A000) | ||
26 | #endif | 29 | #endif |
27 | 30 | ||
28 | #define OMAP_TAP_IDCODE 0x0204 | 31 | #define OMAP_TAP_IDCODE 0x0204 |
32 | #if defined(CONFIG_ARCH_OMAP34XX) | ||
33 | #define OMAP_TAP_PROD_ID 0x0210 | ||
34 | #else | ||
29 | #define OMAP_TAP_PROD_ID 0x0208 | 35 | #define OMAP_TAP_PROD_ID 0x0208 |
36 | #endif | ||
30 | 37 | ||
31 | #define OMAP_TAP_DIE_ID_0 0x0218 | 38 | #define OMAP_TAP_DIE_ID_0 0x0218 |
32 | #define OMAP_TAP_DIE_ID_1 0x021C | 39 | #define OMAP_TAP_DIE_ID_1 0x021C |
@@ -56,9 +63,134 @@ static struct omap_id omap_ids[] __initdata = { | |||
56 | { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, | 63 | { .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300000 }, |
57 | }; | 64 | }; |
58 | 65 | ||
66 | static struct omap_chip_id omap_chip; | ||
67 | |||
68 | /** | ||
69 | * omap_chip_is - test whether currently running OMAP matches a chip type | ||
70 | * @oc: omap_chip_t to test against | ||
71 | * | ||
72 | * Test whether the currently-running OMAP chip matches the supplied | ||
73 | * chip type 'oc'. Returns 1 upon a match; 0 upon failure. | ||
74 | */ | ||
75 | int omap_chip_is(struct omap_chip_id oci) | ||
76 | { | ||
77 | return (oci.oc & omap_chip.oc) ? 1 : 0; | ||
78 | } | ||
79 | EXPORT_SYMBOL(omap_chip_is); | ||
80 | |||
59 | static u32 __init read_tap_reg(int reg) | 81 | static u32 __init read_tap_reg(int reg) |
60 | { | 82 | { |
61 | return __raw_readl(OMAP24XX_TAP_BASE + reg); | 83 | unsigned int regval = 0; |
84 | u32 cpuid; | ||
85 | |||
86 | /* Reading the IDCODE register on 3430 ES1 results in a | ||
87 | * data abort as the register is not exposed on the OCP | ||
88 | * Hence reading the Cortex Rev | ||
89 | */ | ||
90 | cpuid = read_cpuid(CPUID_ID); | ||
91 | |||
92 | /* If the processor type is Cortex-A8 and the revision is 0x0 | ||
93 | * it means its Cortex r0p0 which is 3430 ES1 | ||
94 | */ | ||
95 | if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) { | ||
96 | switch (reg) { | ||
97 | case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break; | ||
98 | /* Making DevType as 0xF in ES1 to differ from ES2 */ | ||
99 | case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break; | ||
100 | case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break; | ||
101 | case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break; | ||
102 | case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break; | ||
103 | case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break; | ||
104 | } | ||
105 | } else | ||
106 | regval = __raw_readl(TAP_BASE + reg); | ||
107 | |||
108 | return regval; | ||
109 | |||
110 | } | ||
111 | |||
112 | /* | ||
113 | * _set_system_rev - set the system_rev global based on current OMAP chip type | ||
114 | * | ||
115 | * Set the system_rev global. This is primarily used by the cpu_is_omapxxxx() | ||
116 | * macros. | ||
117 | */ | ||
118 | static void __init _set_system_rev(u32 type, u8 rev) | ||
119 | { | ||
120 | u32 i, ctrl_status; | ||
121 | |||
122 | /* | ||
123 | * system_rev encoding is as follows | ||
124 | * system_rev & 0xff000000 -> Omap Class (24xx/34xx) | ||
125 | * system_rev & 0xfff00000 -> Omap Sub Class (242x/343x) | ||
126 | * system_rev & 0xffff0000 -> Omap type (2420/2422/2423/2430/3430) | ||
127 | * system_rev & 0x0000f000 -> Silicon revision (ES1, ES2 ) | ||
128 | * system_rev & 0x00000700 -> Device Type ( EMU/HS/GP/BAD ) | ||
129 | * system_rev & 0x000000c0 -> IDCODE revision[6:7] | ||
130 | * system_rev & 0x0000003f -> sys_boot[0:5] | ||
131 | */ | ||
132 | /* Embedding the ES revision info in type field */ | ||
133 | system_rev = type; | ||
134 | /* Also add IDCODE revision info only two lower bits */ | ||
135 | system_rev |= ((rev & 0x3) << 6); | ||
136 | |||
137 | /* Add in the device type and sys_boot fields (see above) */ | ||
138 | if (cpu_is_omap24xx()) { | ||
139 | i = OMAP24XX_CONTROL_STATUS; | ||
140 | } else if (cpu_is_omap343x()) { | ||
141 | i = OMAP343X_CONTROL_STATUS; | ||
142 | } else { | ||
143 | printk(KERN_ERR "id: unknown CPU type\n"); | ||
144 | BUG(); | ||
145 | } | ||
146 | ctrl_status = omap_ctrl_readl(i); | ||
147 | system_rev |= (ctrl_status & (OMAP2_SYSBOOT_5_MASK | | ||
148 | OMAP2_SYSBOOT_4_MASK | | ||
149 | OMAP2_SYSBOOT_3_MASK | | ||
150 | OMAP2_SYSBOOT_2_MASK | | ||
151 | OMAP2_SYSBOOT_1_MASK | | ||
152 | OMAP2_SYSBOOT_0_MASK)); | ||
153 | system_rev |= (ctrl_status & OMAP2_DEVICETYPE_MASK); | ||
154 | } | ||
155 | |||
156 | |||
157 | /* | ||
158 | * _set_omap_chip - set the omap_chip global based on OMAP chip type | ||
159 | * | ||
160 | * Build the omap_chip bits. This variable is used by powerdomain and | ||
161 | * clockdomain code to indicate whether structures are applicable for | ||
162 | * the current OMAP chip type by ANDing it against a 'platform' bitfield | ||
163 | * in the structure. | ||
164 | */ | ||
165 | static void __init _set_omap_chip(void) | ||
166 | { | ||
167 | if (cpu_is_omap343x()) { | ||
168 | |||
169 | omap_chip.oc = CHIP_IS_OMAP3430; | ||
170 | if (is_sil_rev_equal_to(OMAP3430_REV_ES1_0)) | ||
171 | omap_chip.oc |= CHIP_IS_OMAP3430ES1; | ||
172 | else if (is_sil_rev_greater_than(OMAP3430_REV_ES1_0)) | ||
173 | omap_chip.oc |= CHIP_IS_OMAP3430ES2; | ||
174 | |||
175 | } else if (cpu_is_omap243x()) { | ||
176 | |||
177 | /* Currently only supports 2430ES2.1 and 2430-all */ | ||
178 | omap_chip.oc |= CHIP_IS_OMAP2430; | ||
179 | |||
180 | } else if (cpu_is_omap242x()) { | ||
181 | |||
182 | /* Currently only supports 2420ES2.1.1 and 2420-all */ | ||
183 | omap_chip.oc |= CHIP_IS_OMAP2420; | ||
184 | |||
185 | } else { | ||
186 | |||
187 | /* Current CPU not supported by this code. */ | ||
188 | printk(KERN_WARNING "OMAP chip type code does not yet support " | ||
189 | "this CPU type.\n"); | ||
190 | WARN_ON(1); | ||
191 | |||
192 | } | ||
193 | |||
62 | } | 194 | } |
63 | 195 | ||
64 | void __init omap2_check_revision(void) | 196 | void __init omap2_check_revision(void) |
@@ -76,21 +208,31 @@ void __init omap2_check_revision(void) | |||
76 | rev = (idcode >> 28) & 0x0f; | 208 | rev = (idcode >> 28) & 0x0f; |
77 | dev_type = (prod_id >> 16) & 0x0f; | 209 | dev_type = (prod_id >> 16) & 0x0f; |
78 | 210 | ||
79 | #ifdef DEBUG | 211 | pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", |
80 | printk(KERN_DEBUG "OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n", | 212 | idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); |
81 | idcode, rev, hawkeye, (idcode >> 1) & 0x7ff); | 213 | pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", |
82 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_0: 0x%08x\n", | 214 | read_tap_reg(OMAP_TAP_DIE_ID_0)); |
83 | read_tap_reg(OMAP_TAP_DIE_ID_0)); | 215 | pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", |
84 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n", | 216 | read_tap_reg(OMAP_TAP_DIE_ID_1), |
85 | read_tap_reg(OMAP_TAP_DIE_ID_1), | 217 | (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); |
86 | (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf); | 218 | pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", |
87 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_2: 0x%08x\n", | 219 | read_tap_reg(OMAP_TAP_DIE_ID_2)); |
88 | read_tap_reg(OMAP_TAP_DIE_ID_2)); | 220 | pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", |
89 | printk(KERN_DEBUG "OMAP_TAP_DIE_ID_3: 0x%08x\n", | 221 | read_tap_reg(OMAP_TAP_DIE_ID_3)); |
90 | read_tap_reg(OMAP_TAP_DIE_ID_3)); | 222 | pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", |
91 | printk(KERN_DEBUG "OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n", | 223 | prod_id, dev_type); |
92 | prod_id, dev_type); | 224 | |
93 | #endif | 225 | /* |
226 | * Detection for 34xx ES2.0 and above can be done with just | ||
227 | * hawkeye and rev. See TRM 1.5.2 Device Identification. | ||
228 | * Note that rev cannot be used directly as ES1.0 uses value 0. | ||
229 | */ | ||
230 | if (hawkeye == 0xb7ae) { | ||
231 | system_rev = 0x34300000 | ((1 + rev) << 12); | ||
232 | pr_info("OMAP%04x ES2.%i\n", system_rev >> 16, rev); | ||
233 | _set_omap_chip(); | ||
234 | return; | ||
235 | } | ||
94 | 236 | ||
95 | /* Check hawkeye ids */ | 237 | /* Check hawkeye ids */ |
96 | for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { | 238 | for (i = 0; i < ARRAY_SIZE(omap_ids); i++) { |
@@ -114,16 +256,15 @@ void __init omap2_check_revision(void) | |||
114 | omap_ids[i].type >> 16); | 256 | omap_ids[i].type >> 16); |
115 | j = i; | 257 | j = i; |
116 | } | 258 | } |
117 | system_rev = omap_ids[j].type; | ||
118 | 259 | ||
119 | system_rev |= rev << 8; | 260 | _set_system_rev(omap_ids[j].type, rev); |
120 | 261 | ||
121 | /* Add the cpu class info (24xx) */ | 262 | _set_omap_chip(); |
122 | system_rev |= 0x24; | ||
123 | 263 | ||
124 | pr_info("OMAP%04x", system_rev >> 16); | 264 | pr_info("OMAP%04x", system_rev >> 16); |
125 | if ((system_rev >> 8) & 0x0f) | 265 | if ((system_rev >> 8) & 0x0f) |
126 | printk("%x", (system_rev >> 8) & 0x0f); | 266 | pr_info("ES%x", (system_rev >> 12) & 0xf); |
127 | printk("\n"); | 267 | pr_info("\n"); |
268 | |||
128 | } | 269 | } |
129 | 270 | ||
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c new file mode 100644 index 000000000000..17cf199d1130 --- /dev/null +++ b/arch/arm/mach-omap2/mcbsp.c | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/mcbsp.c | ||
3 | * | ||
4 | * Copyright (C) 2008 Instituto Nokia de Tecnologia | ||
5 | * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * Multichannel mode not supported. | ||
12 | */ | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | |||
20 | #include <asm/arch/dma.h> | ||
21 | #include <asm/arch/mux.h> | ||
22 | #include <asm/arch/cpu.h> | ||
23 | #include <asm/arch/mcbsp.h> | ||
24 | |||
25 | struct mcbsp_internal_clk { | ||
26 | struct clk clk; | ||
27 | struct clk **childs; | ||
28 | int n_childs; | ||
29 | }; | ||
30 | |||
31 | #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) | ||
32 | static void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk) | ||
33 | { | ||
34 | const char *clk_names[] = { "mcbsp_ick", "mcbsp_fck" }; | ||
35 | int i; | ||
36 | |||
37 | mclk->n_childs = ARRAY_SIZE(clk_names); | ||
38 | mclk->childs = kzalloc(mclk->n_childs * sizeof(struct clk *), | ||
39 | GFP_KERNEL); | ||
40 | |||
41 | for (i = 0; i < mclk->n_childs; i++) { | ||
42 | /* We fake a platform device to get correct device id */ | ||
43 | struct platform_device pdev; | ||
44 | |||
45 | pdev.dev.bus = &platform_bus_type; | ||
46 | pdev.id = mclk->clk.id; | ||
47 | mclk->childs[i] = clk_get(&pdev.dev, clk_names[i]); | ||
48 | if (IS_ERR(mclk->childs[i])) | ||
49 | printk(KERN_ERR "Could not get clock %s (%d).\n", | ||
50 | clk_names[i], mclk->clk.id); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | static int omap_mcbsp_clk_enable(struct clk *clk) | ||
55 | { | ||
56 | struct mcbsp_internal_clk *mclk = container_of(clk, | ||
57 | struct mcbsp_internal_clk, clk); | ||
58 | int i; | ||
59 | |||
60 | for (i = 0; i < mclk->n_childs; i++) | ||
61 | clk_enable(mclk->childs[i]); | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static void omap_mcbsp_clk_disable(struct clk *clk) | ||
66 | { | ||
67 | struct mcbsp_internal_clk *mclk = container_of(clk, | ||
68 | struct mcbsp_internal_clk, clk); | ||
69 | int i; | ||
70 | |||
71 | for (i = 0; i < mclk->n_childs; i++) | ||
72 | clk_disable(mclk->childs[i]); | ||
73 | } | ||
74 | |||
75 | static struct mcbsp_internal_clk omap_mcbsp_clks[] = { | ||
76 | { | ||
77 | .clk = { | ||
78 | .name = "mcbsp_clk", | ||
79 | .id = 1, | ||
80 | .enable = omap_mcbsp_clk_enable, | ||
81 | .disable = omap_mcbsp_clk_disable, | ||
82 | }, | ||
83 | }, | ||
84 | { | ||
85 | .clk = { | ||
86 | .name = "mcbsp_clk", | ||
87 | .id = 2, | ||
88 | .enable = omap_mcbsp_clk_enable, | ||
89 | .disable = omap_mcbsp_clk_disable, | ||
90 | }, | ||
91 | }, | ||
92 | }; | ||
93 | |||
94 | #define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks) | ||
95 | #else | ||
96 | #define omap_mcbsp_clks_size 0 | ||
97 | static struct mcbsp_internal_clk __initdata *omap_mcbsp_clks; | ||
98 | static inline void omap_mcbsp_clk_init(struct clk *clk) | ||
99 | { } | ||
100 | #endif | ||
101 | |||
102 | static void omap2_mcbsp2_mux_setup(void) | ||
103 | { | ||
104 | omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); | ||
105 | omap_cfg_reg(R14_24XX_MCBSP2_FSX); | ||
106 | omap_cfg_reg(W15_24XX_MCBSP2_DR); | ||
107 | omap_cfg_reg(V15_24XX_MCBSP2_DX); | ||
108 | omap_cfg_reg(V14_24XX_GPIO117); | ||
109 | /* | ||
110 | * TODO: Need to add MUX settings for OMAP 2430 SDP | ||
111 | */ | ||
112 | } | ||
113 | |||
114 | static void omap2_mcbsp_request(unsigned int id) | ||
115 | { | ||
116 | if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) | ||
117 | omap2_mcbsp2_mux_setup(); | ||
118 | } | ||
119 | |||
120 | static int omap2_mcbsp_check(unsigned int id) | ||
121 | { | ||
122 | if (id > OMAP_MAX_MCBSP_COUNT - 1) { | ||
123 | printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1); | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct omap_mcbsp_ops omap2_mcbsp_ops = { | ||
130 | .request = omap2_mcbsp_request, | ||
131 | .check = omap2_mcbsp_check, | ||
132 | }; | ||
133 | |||
134 | #ifdef CONFIG_ARCH_OMAP24XX | ||
135 | static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = { | ||
136 | { | ||
137 | .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE), | ||
138 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
139 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
140 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
141 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
142 | .ops = &omap2_mcbsp_ops, | ||
143 | .clk_name = "mcbsp_clk", | ||
144 | }, | ||
145 | { | ||
146 | .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE), | ||
147 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
148 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
149 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
150 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
151 | .ops = &omap2_mcbsp_ops, | ||
152 | .clk_name = "mcbsp_clk", | ||
153 | }, | ||
154 | }; | ||
155 | #define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata) | ||
156 | #else | ||
157 | #define omap24xx_mcbsp_pdata NULL | ||
158 | #define OMAP24XX_MCBSP_PDATA_SZ 0 | ||
159 | #endif | ||
160 | |||
161 | #ifdef CONFIG_ARCH_OMAP34XX | ||
162 | static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { | ||
163 | { | ||
164 | .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE), | ||
165 | .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, | ||
166 | .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, | ||
167 | .rx_irq = INT_24XX_MCBSP1_IRQ_RX, | ||
168 | .tx_irq = INT_24XX_MCBSP1_IRQ_TX, | ||
169 | .ops = &omap2_mcbsp_ops, | ||
170 | .clk_name = "mcbsp_clk", | ||
171 | }, | ||
172 | { | ||
173 | .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE), | ||
174 | .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, | ||
175 | .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, | ||
176 | .rx_irq = INT_24XX_MCBSP2_IRQ_RX, | ||
177 | .tx_irq = INT_24XX_MCBSP2_IRQ_TX, | ||
178 | .ops = &omap2_mcbsp_ops, | ||
179 | .clk_name = "mcbsp_clk", | ||
180 | }, | ||
181 | }; | ||
182 | #define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) | ||
183 | #else | ||
184 | #define omap34xx_mcbsp_pdata NULL | ||
185 | #define OMAP34XX_MCBSP_PDATA_SZ 0 | ||
186 | #endif | ||
187 | |||
188 | int __init omap2_mcbsp_init(void) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | for (i = 0; i < omap_mcbsp_clks_size; i++) { | ||
193 | /* Once we call clk_get inside init, we do not register it */ | ||
194 | omap_mcbsp_clk_init(&omap_mcbsp_clks[i]); | ||
195 | clk_register(&omap_mcbsp_clks[i].clk); | ||
196 | } | ||
197 | |||
198 | if (cpu_is_omap24xx()) | ||
199 | omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata, | ||
200 | OMAP24XX_MCBSP_PDATA_SZ); | ||
201 | |||
202 | if (cpu_is_omap34xx()) | ||
203 | omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, | ||
204 | OMAP34XX_MCBSP_PDATA_SZ); | ||
205 | |||
206 | return omap_mcbsp_init(); | ||
207 | } | ||
208 | arch_initcall(omap2_mcbsp_init); | ||
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c index 12479081881a..73cadb2c75cf 100644 --- a/arch/arm/mach-omap2/memory.c +++ b/arch/arm/mach-omap2/memory.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <asm/io.h> | 25 | #include <asm/io.h> |
26 | 26 | ||
27 | #include <asm/arch/common.h> | ||
27 | #include <asm/arch/clock.h> | 28 | #include <asm/arch/clock.h> |
28 | #include <asm/arch/sram.h> | 29 | #include <asm/arch/sram.h> |
29 | 30 | ||
@@ -32,8 +33,8 @@ | |||
32 | #include "memory.h" | 33 | #include "memory.h" |
33 | #include "sdrc.h" | 34 | #include "sdrc.h" |
34 | 35 | ||
35 | unsigned long omap2_sdrc_base; | 36 | void __iomem *omap2_sdrc_base; |
36 | unsigned long omap2_sms_base; | 37 | void __iomem *omap2_sms_base; |
37 | 38 | ||
38 | static struct memory_timings mem_timings; | 39 | static struct memory_timings mem_timings; |
39 | static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; | 40 | static u32 curr_perf_level = CORE_CLK_SRC_DPLL_X2; |
@@ -154,6 +155,12 @@ void omap2_init_memory_params(u32 force_lock_to_unlock_mode) | |||
154 | mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); | 155 | mem_timings.slow_dll_ctrl |= ((1 << 1) | (3 << 8)); |
155 | } | 156 | } |
156 | 157 | ||
158 | void __init omap2_set_globals_memory(struct omap_globals *omap2_globals) | ||
159 | { | ||
160 | omap2_sdrc_base = omap2_globals->sdrc; | ||
161 | omap2_sms_base = omap2_globals->sms; | ||
162 | } | ||
163 | |||
157 | /* turn on smart idle modes for SDRAM scheduler and controller */ | 164 | /* turn on smart idle modes for SDRAM scheduler and controller */ |
158 | void __init omap2_init_memory(void) | 165 | void __init omap2_init_memory(void) |
159 | { | 166 | { |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 930770012a75..8f98b20f30a1 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -236,7 +236,7 @@ void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg) | |||
236 | warn = (orig != reg); | 236 | warn = (orig != reg); |
237 | if (debug || warn) | 237 | if (debug || warn) |
238 | printk(KERN_WARNING | 238 | printk(KERN_WARNING |
239 | "MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n", | 239 | "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n", |
240 | cfg->name, omap_ctrl_base_get() + cfg->mux_reg, | 240 | cfg->name, omap_ctrl_base_get() + cfg->mux_reg, |
241 | orig, reg); | 241 | orig, reg); |
242 | } | 242 | } |
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index aad781dcf1b1..d6c9de82ca0c 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c | |||
@@ -57,13 +57,6 @@ void omap2_pm_idle(void) | |||
57 | return; | 57 | return; |
58 | } | 58 | } |
59 | 59 | ||
60 | /* | ||
61 | * Since an interrupt may set up a timer, we don't want to | ||
62 | * reprogram the hardware timer with interrupts enabled. | ||
63 | * Re-enable interrupts only after returning from idle. | ||
64 | */ | ||
65 | timer_dyn_reprogram(); | ||
66 | |||
67 | omap2_sram_idle(); | 60 | omap2_sram_idle(); |
68 | local_fiq_enable(); | 61 | local_fiq_enable(); |
69 | local_irq_enable(); | 62 | local_irq_enable(); |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index cacb34086e35..54c32f482131 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | 33 | ||
34 | /* Chip-specific module offsets */ | 34 | /* Chip-specific module offsets */ |
35 | #define OMAP24XX_GR_MOD OCP_MOD | ||
35 | #define OMAP24XX_DSP_MOD 0x800 | 36 | #define OMAP24XX_DSP_MOD 0x800 |
36 | 37 | ||
37 | #define OMAP2430_MDM_MOD 0xc00 | 38 | #define OMAP2430_MDM_MOD 0xc00 |
diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index b12f423b8595..fd92a80f38f2 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c | |||
@@ -16,16 +16,21 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/io.h> | ||
19 | 20 | ||
20 | #include <asm/io.h> | 21 | #include <asm/arch/common.h> |
22 | #include <asm/arch/prcm.h> | ||
21 | 23 | ||
24 | #include "clock.h" | ||
22 | #include "prm.h" | 25 | #include "prm.h" |
23 | #include "prm-regbits-24xx.h" | 26 | #include "prm-regbits-24xx.h" |
24 | 27 | ||
25 | extern void omap2_clk_prepare_for_reboot(void); | 28 | static void __iomem *prm_base; |
29 | static void __iomem *cm_base; | ||
26 | 30 | ||
27 | u32 omap_prcm_get_reset_sources(void) | 31 | u32 omap_prcm_get_reset_sources(void) |
28 | { | 32 | { |
33 | /* XXX This presumably needs modification for 34XX */ | ||
29 | return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f; | 34 | return prm_read_mod_reg(WKUP_MOD, RM_RSTST) & 0x7f; |
30 | } | 35 | } |
31 | EXPORT_SYMBOL(omap_prcm_get_reset_sources); | 36 | EXPORT_SYMBOL(omap_prcm_get_reset_sources); |
@@ -33,11 +38,90 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources); | |||
33 | /* Resets clock rates and reboots the system. Only called from system.h */ | 38 | /* Resets clock rates and reboots the system. Only called from system.h */ |
34 | void omap_prcm_arch_reset(char mode) | 39 | void omap_prcm_arch_reset(char mode) |
35 | { | 40 | { |
36 | u32 wkup; | 41 | s16 prcm_offs; |
37 | omap2_clk_prepare_for_reboot(); | 42 | omap2_clk_prepare_for_reboot(); |
38 | 43 | ||
39 | if (cpu_is_omap24xx()) { | 44 | if (cpu_is_omap24xx()) |
40 | wkup = prm_read_mod_reg(WKUP_MOD, RM_RSTCTRL) | OMAP_RST_DPLL3; | 45 | prcm_offs = WKUP_MOD; |
41 | prm_write_mod_reg(wkup, WKUP_MOD, RM_RSTCTRL); | 46 | else if (cpu_is_omap34xx()) |
42 | } | 47 | prcm_offs = OMAP3430_GR_MOD; |
48 | else | ||
49 | WARN_ON(1); | ||
50 | |||
51 | prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs, RM_RSTCTRL); | ||
52 | } | ||
53 | |||
54 | static inline u32 __omap_prcm_read(void __iomem *base, s16 module, u16 reg) | ||
55 | { | ||
56 | BUG_ON(!base); | ||
57 | return __raw_readl(base + module + reg); | ||
58 | } | ||
59 | |||
60 | static inline void __omap_prcm_write(u32 value, void __iomem *base, | ||
61 | s16 module, u16 reg) | ||
62 | { | ||
63 | BUG_ON(!base); | ||
64 | __raw_writel(value, base + module + reg); | ||
65 | } | ||
66 | |||
67 | /* Read a register in a PRM module */ | ||
68 | u32 prm_read_mod_reg(s16 module, u16 idx) | ||
69 | { | ||
70 | return __omap_prcm_read(prm_base, module, idx); | ||
71 | } | ||
72 | EXPORT_SYMBOL(prm_read_mod_reg); | ||
73 | |||
74 | /* Write into a register in a PRM module */ | ||
75 | void prm_write_mod_reg(u32 val, s16 module, u16 idx) | ||
76 | { | ||
77 | __omap_prcm_write(val, prm_base, module, idx); | ||
78 | } | ||
79 | EXPORT_SYMBOL(prm_write_mod_reg); | ||
80 | |||
81 | /* Read-modify-write a register in a PRM module. Caller must lock */ | ||
82 | u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) | ||
83 | { | ||
84 | u32 v; | ||
85 | |||
86 | v = prm_read_mod_reg(module, idx); | ||
87 | v &= ~mask; | ||
88 | v |= bits; | ||
89 | prm_write_mod_reg(v, module, idx); | ||
90 | |||
91 | return v; | ||
92 | } | ||
93 | EXPORT_SYMBOL(prm_rmw_mod_reg_bits); | ||
94 | |||
95 | /* Read a register in a CM module */ | ||
96 | u32 cm_read_mod_reg(s16 module, u16 idx) | ||
97 | { | ||
98 | return __omap_prcm_read(cm_base, module, idx); | ||
99 | } | ||
100 | EXPORT_SYMBOL(cm_read_mod_reg); | ||
101 | |||
102 | /* Write into a register in a CM module */ | ||
103 | void cm_write_mod_reg(u32 val, s16 module, u16 idx) | ||
104 | { | ||
105 | __omap_prcm_write(val, cm_base, module, idx); | ||
106 | } | ||
107 | EXPORT_SYMBOL(cm_write_mod_reg); | ||
108 | |||
109 | /* Read-modify-write a register in a CM module. Caller must lock */ | ||
110 | u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) | ||
111 | { | ||
112 | u32 v; | ||
113 | |||
114 | v = cm_read_mod_reg(module, idx); | ||
115 | v &= ~mask; | ||
116 | v |= bits; | ||
117 | cm_write_mod_reg(v, module, idx); | ||
118 | |||
119 | return v; | ||
120 | } | ||
121 | EXPORT_SYMBOL(cm_rmw_mod_reg_bits); | ||
122 | |||
123 | void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) | ||
124 | { | ||
125 | prm_base = omap2_globals->prm; | ||
126 | cm_base = omap2_globals->cm; | ||
43 | } | 127 | } |
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 618f8111658a..bbf41fc8e9a9 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h | |||
@@ -38,13 +38,29 @@ | |||
38 | * | 38 | * |
39 | */ | 39 | */ |
40 | 40 | ||
41 | /* Global 24xx registers in GR_MOD (Same as OCP_MOD for 24xx) */ | ||
42 | #define OMAP24XX_PRCM_VOLTCTRL_OFFSET 0x0050 | ||
43 | #define OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET 0x0080 | ||
44 | |||
45 | /* 242x GR_MOD registers, use these only for assembly code */ | ||
46 | #define OMAP242X_PRCM_VOLTCTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ | ||
47 | OMAP24XX_PRCM_VOLTCTRL_OFFSET) | ||
48 | #define OMAP242X_PRCM_CLKCFG_CTRL OMAP2420_PRM_REGADDR(OMAP24XX_GR_MOD, \ | ||
49 | OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) | ||
50 | |||
51 | /* 243x GR_MOD registers, use these only for assembly code */ | ||
52 | #define OMAP243X_PRCM_VOLTCTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ | ||
53 | OMAP24XX_PRCM_VOLTCTRL_OFFSET) | ||
54 | #define OMAP243X_PRCM_CLKCFG_CTRL OMAP2430_PRM_REGADDR(OMAP24XX_GR_MOD, \ | ||
55 | OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET) | ||
56 | |||
57 | /* These will disappear */ | ||
41 | #define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) | 58 | #define OMAP24XX_PRCM_REVISION OMAP_PRM_REGADDR(OCP_MOD, 0x0000) |
42 | #define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) | 59 | #define OMAP24XX_PRCM_SYSCONFIG OMAP_PRM_REGADDR(OCP_MOD, 0x0010) |
43 | 60 | ||
44 | #define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) | 61 | #define OMAP24XX_PRCM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) |
45 | #define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) | 62 | #define OMAP24XX_PRCM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) |
46 | 63 | ||
47 | #define OMAP24XX_PRCM_VOLTCTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0050) | ||
48 | #define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) | 64 | #define OMAP24XX_PRCM_VOLTST OMAP_PRM_REGADDR(OCP_MOD, 0x0054) |
49 | #define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) | 65 | #define OMAP24XX_PRCM_CLKSRC_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0060) |
50 | #define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) | 66 | #define OMAP24XX_PRCM_CLKOUT_CTRL OMAP_PRM_REGADDR(OCP_MOD, 0x0070) |
@@ -150,15 +166,19 @@ | |||
150 | #ifndef __ASSEMBLER__ | 166 | #ifndef __ASSEMBLER__ |
151 | 167 | ||
152 | /* Power/reset management domain register get/set */ | 168 | /* Power/reset management domain register get/set */ |
169 | extern u32 prm_read_mod_reg(s16 module, u16 idx); | ||
170 | extern void prm_write_mod_reg(u32 val, s16 module, u16 idx); | ||
171 | extern u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx); | ||
153 | 172 | ||
154 | static inline void prm_write_mod_reg(u32 val, s16 module, s16 idx) | 173 | /* Read-modify-write bits in a PRM register (by domain) */ |
174 | static inline u32 prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) | ||
155 | { | 175 | { |
156 | __raw_writel(val, OMAP_PRM_REGADDR(module, idx)); | 176 | return prm_rmw_mod_reg_bits(bits, bits, module, idx); |
157 | } | 177 | } |
158 | 178 | ||
159 | static inline u32 prm_read_mod_reg(s16 module, s16 idx) | 179 | static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) |
160 | { | 180 | { |
161 | return __raw_readl(OMAP_PRM_REGADDR(module, idx)); | 181 | return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); |
162 | } | 182 | } |
163 | 183 | ||
164 | #endif | 184 | #endif |
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index d7f23bc9550a..1b1fe4f6e030 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h | |||
@@ -18,13 +18,11 @@ | |||
18 | #include <asm/arch/sdrc.h> | 18 | #include <asm/arch/sdrc.h> |
19 | 19 | ||
20 | #ifndef __ASSEMBLER__ | 20 | #ifndef __ASSEMBLER__ |
21 | extern unsigned long omap2_sdrc_base; | 21 | extern void __iomem *omap2_sdrc_base; |
22 | extern unsigned long omap2_sms_base; | 22 | extern void __iomem *omap2_sms_base; |
23 | 23 | ||
24 | #define OMAP_SDRC_REGADDR(reg) \ | 24 | #define OMAP_SDRC_REGADDR(reg) (omap2_sdrc_base + (reg)) |
25 | (void __iomem *)IO_ADDRESS(omap2_sdrc_base + (reg)) | 25 | #define OMAP_SMS_REGADDR(reg) (omap2_sms_base + (reg)) |
26 | #define OMAP_SMS_REGADDR(reg) \ | ||
27 | (void __iomem *)IO_ADDRESS(omap2_sms_base + (reg)) | ||
28 | 26 | ||
29 | /* SDRC global register get/set */ | 27 | /* SDRC global register get/set */ |
30 | 28 | ||
diff --git a/arch/arm/mach-omap2/sram-fn.S b/arch/arm/mach-omap2/sram242x.S index 4a9e49140716..4c274510f3e9 100644 --- a/arch/arm/mach-omap2/sram-fn.S +++ b/arch/arm/mach-omap2/sram242x.S | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/sram-fn.S | 2 | * linux/arch/arm/mach-omap2/sram242x.S |
3 | * | 3 | * |
4 | * Omap2 specific functions that need to be run in internal SRAM | 4 | * Omap2 specific functions that need to be run in internal SRAM |
5 | * | 5 | * |
@@ -27,22 +27,20 @@ | |||
27 | #include <asm/arch/io.h> | 27 | #include <asm/arch/io.h> |
28 | #include <asm/hardware.h> | 28 | #include <asm/hardware.h> |
29 | 29 | ||
30 | #include "sdrc.h" | ||
31 | #include "prm.h" | 30 | #include "prm.h" |
32 | #include "cm.h" | 31 | #include "cm.h" |
33 | 32 | #include "sdrc.h" | |
34 | #define TIMER_32KSYNCT_CR_V IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) | ||
35 | 33 | ||
36 | .text | 34 | .text |
37 | 35 | ||
38 | ENTRY(sram_ddr_init) | 36 | ENTRY(omap242x_sram_ddr_init) |
39 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 37 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
40 | 38 | ||
41 | mov r12, r2 @ capture CS1 vs CS0 | 39 | mov r12, r2 @ capture CS1 vs CS0 |
42 | mov r8, r3 @ capture force parameter | 40 | mov r8, r3 @ capture force parameter |
43 | 41 | ||
44 | /* frequency shift down */ | 42 | /* frequency shift down */ |
45 | ldr r2, cm_clksel2_pll @ get address of dpllout reg | 43 | ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg |
46 | mov r3, #0x1 @ value for 1x operation | 44 | mov r3, #0x1 @ value for 1x operation |
47 | str r3, [r2] @ go to L1-freq operation | 45 | str r3, [r2] @ go to L1-freq operation |
48 | 46 | ||
@@ -51,7 +49,7 @@ ENTRY(sram_ddr_init) | |||
51 | bl voltage_shift @ go drop voltage | 49 | bl voltage_shift @ go drop voltage |
52 | 50 | ||
53 | /* dll lock mode */ | 51 | /* dll lock mode */ |
54 | ldr r11, sdrc_dlla_ctrl @ addr of dlla ctrl | 52 | ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl |
55 | ldr r10, [r11] @ get current val | 53 | ldr r10, [r11] @ get current val |
56 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) | 54 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) |
57 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB | 55 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB |
@@ -102,7 +100,7 @@ i_dll_delay: | |||
102 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 100 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
103 | */ | 101 | */ |
104 | voltage_shift: | 102 | voltage_shift: |
105 | ldr r4, prcm_voltctrl @ get addr of volt ctrl. | 103 | ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl. |
106 | ldr r5, [r4] @ get value. | 104 | ldr r5, [r4] @ get value. |
107 | ldr r6, prcm_mask_val @ get value of mask | 105 | ldr r6, prcm_mask_val @ get value of mask |
108 | and r5, r5, r6 @ apply mask to clear bits | 106 | and r5, r5, r6 @ apply mask to clear bits |
@@ -112,7 +110,7 @@ voltage_shift: | |||
112 | orr r5, r5, r3 @ build value for force | 110 | orr r5, r5, r3 @ build value for force |
113 | str r5, [r4] @ Force transition to L1 | 111 | str r5, [r4] @ Force transition to L1 |
114 | 112 | ||
115 | ldr r3, timer_32ksynct_cr @ get addr of counter | 113 | ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter |
116 | ldr r5, [r3] @ get value | 114 | ldr r5, [r3] @ get value |
117 | add r5, r5, #0x3 @ give it at most 93uS | 115 | add r5, r5, #0x3 @ give it at most 93uS |
118 | volt_delay: | 116 | volt_delay: |
@@ -121,32 +119,31 @@ volt_delay: | |||
121 | bhi volt_delay @ not yet->branch | 119 | bhi volt_delay @ not yet->branch |
122 | mov pc, lr @ back to caller. | 120 | mov pc, lr @ back to caller. |
123 | 121 | ||
124 | /* relative load constants */ | 122 | omap242x_sdi_cm_clksel2_pll: |
125 | cm_clksel2_pll: | ||
126 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 123 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
127 | sdrc_dlla_ctrl: | 124 | omap242x_sdi_sdrc_dlla_ctrl: |
128 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 125 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
129 | prcm_voltctrl: | 126 | omap242x_sdi_prcm_voltctrl: |
130 | .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) | 127 | .word OMAP242X_PRCM_VOLTCTRL |
131 | prcm_mask_val: | 128 | prcm_mask_val: |
132 | .word 0xFFFF3FFC | 129 | .word 0xFFFF3FFC |
133 | timer_32ksynct_cr: | 130 | omap242x_sdi_timer_32ksynct_cr: |
134 | .word TIMER_32KSYNCT_CR_V | 131 | .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) |
135 | ENTRY(sram_ddr_init_sz) | 132 | ENTRY(omap242x_sram_ddr_init_sz) |
136 | .word . - sram_ddr_init | 133 | .word . - omap242x_sram_ddr_init |
137 | 134 | ||
138 | /* | 135 | /* |
139 | * Reprograms memory timings. | 136 | * Reprograms memory timings. |
140 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] | 137 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] |
141 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 | 138 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 |
142 | */ | 139 | */ |
143 | ENTRY(sram_reprogram_sdrc) | 140 | ENTRY(omap242x_sram_reprogram_sdrc) |
144 | stmfd sp!, {r0 - r10, lr} @ save registers on stack | 141 | stmfd sp!, {r0 - r10, lr} @ save registers on stack |
145 | mov r3, #0x0 @ clear for mrc call | 142 | mov r3, #0x0 @ clear for mrc call |
146 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR | 143 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR |
147 | nop | 144 | nop |
148 | nop | 145 | nop |
149 | ldr r6, ddr_sdrc_rfr_ctrl @ get addr of refresh reg | 146 | ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg |
150 | ldr r5, [r6] @ get value | 147 | ldr r5, [r6] @ get value |
151 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst | 148 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst |
152 | 149 | ||
@@ -160,7 +157,7 @@ ENTRY(sram_reprogram_sdrc) | |||
160 | movne r5, r5, lsl #1 @ mult by 2 if to full | 157 | movne r5, r5, lsl #1 @ mult by 2 if to full |
161 | mov r5, r5, lsl #8 @ put rfr field back into place | 158 | mov r5, r5, lsl #8 @ put rfr field back into place |
162 | add r5, r5, #0x1 @ turn on burst of 1 | 159 | add r5, r5, #0x1 @ turn on burst of 1 |
163 | ldr r4, ddr_cm_clksel2_pll @ get address of out reg | 160 | ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg |
164 | ldr r3, [r4] @ get curr value | 161 | ldr r3, [r4] @ get curr value |
165 | orr r3, r3, #0x3 | 162 | orr r3, r3, #0x3 |
166 | bic r3, r3, #0x3 @ clear lower bits | 163 | bic r3, r3, #0x3 @ clear lower bits |
@@ -181,7 +178,7 @@ ENTRY(sram_reprogram_sdrc) | |||
181 | bne freq_out @ leave if SDR, no DLL function | 178 | bne freq_out @ leave if SDR, no DLL function |
182 | 179 | ||
183 | /* With DDR, we need to take care of the DLL for the frequency change */ | 180 | /* With DDR, we need to take care of the DLL for the frequency change */ |
184 | ldr r2, ddr_sdrc_dlla_ctrl @ addr of dlla ctrl | 181 | ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl |
185 | str r1, [r2] @ write out new SDRC_DLLA_CTRL | 182 | str r1, [r2] @ write out new SDRC_DLLA_CTRL |
186 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL | 183 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL |
187 | str r1, [r2] @ commit to SDRC_DLLB_CTRL | 184 | str r1, [r2] @ commit to SDRC_DLLB_CTRL |
@@ -197,7 +194,7 @@ freq_out: | |||
197 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 194 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
198 | */ | 195 | */ |
199 | voltage_shift_c: | 196 | voltage_shift_c: |
200 | ldr r10, ddr_prcm_voltctrl @ get addr of volt ctrl | 197 | ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl |
201 | ldr r8, [r10] @ get value | 198 | ldr r8, [r10] @ get value |
202 | ldr r7, ddr_prcm_mask_val @ get value of mask | 199 | ldr r7, ddr_prcm_mask_val @ get value of mask |
203 | and r8, r8, r7 @ apply mask to clear bits | 200 | and r8, r8, r7 @ apply mask to clear bits |
@@ -207,7 +204,7 @@ voltage_shift_c: | |||
207 | orr r8, r8, r7 @ build value for force | 204 | orr r8, r8, r7 @ build value for force |
208 | str r8, [r10] @ Force transition to L1 | 205 | str r8, [r10] @ Force transition to L1 |
209 | 206 | ||
210 | ldr r10, ddr_timer_32ksynct @ get addr of counter | 207 | ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter |
211 | ldr r8, [r10] @ get value | 208 | ldr r8, [r10] @ get value |
212 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) | 209 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) |
213 | volt_delay_c: | 210 | volt_delay_c: |
@@ -216,39 +213,39 @@ volt_delay_c: | |||
216 | bhi volt_delay_c @ not yet->branch | 213 | bhi volt_delay_c @ not yet->branch |
217 | mov pc, lr @ back to caller | 214 | mov pc, lr @ back to caller |
218 | 215 | ||
219 | ddr_cm_clksel2_pll: | 216 | omap242x_srs_cm_clksel2_pll: |
220 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 217 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
221 | ddr_sdrc_dlla_ctrl: | 218 | omap242x_srs_sdrc_dlla_ctrl: |
222 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 219 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
223 | ddr_sdrc_rfr_ctrl: | 220 | omap242x_srs_sdrc_rfr_ctrl: |
224 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 221 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
225 | ddr_prcm_voltctrl: | 222 | omap242x_srs_prcm_voltctrl: |
226 | .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x50) | 223 | .word OMAP242X_PRCM_VOLTCTRL |
227 | ddr_prcm_mask_val: | 224 | ddr_prcm_mask_val: |
228 | .word 0xFFFF3FFC | 225 | .word 0xFFFF3FFC |
229 | ddr_timer_32ksynct: | 226 | omap242x_srs_timer_32ksynct: |
230 | .word TIMER_32KSYNCT_CR_V | 227 | .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) |
231 | 228 | ||
232 | ENTRY(sram_reprogram_sdrc_sz) | 229 | ENTRY(omap242x_sram_reprogram_sdrc_sz) |
233 | .word . - sram_reprogram_sdrc | 230 | .word . - omap242x_sram_reprogram_sdrc |
234 | 231 | ||
235 | /* | 232 | /* |
236 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. | 233 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. |
237 | */ | 234 | */ |
238 | ENTRY(sram_set_prcm) | 235 | ENTRY(omap242x_sram_set_prcm) |
239 | stmfd sp!, {r0-r12, lr} @ regs to stack | 236 | stmfd sp!, {r0-r12, lr} @ regs to stack |
240 | adr r4, pbegin @ addr of preload start | 237 | adr r4, pbegin @ addr of preload start |
241 | adr r8, pend @ addr of preload end | 238 | adr r8, pend @ addr of preload end |
242 | mcrr p15, 1, r8, r4, c12 @ preload into icache | 239 | mcrr p15, 1, r8, r4, c12 @ preload into icache |
243 | pbegin: | 240 | pbegin: |
244 | /* move into fast relock bypass */ | 241 | /* move into fast relock bypass */ |
245 | ldr r8, pll_ctl @ get addr | 242 | ldr r8, omap242x_ssp_pll_ctl @ get addr |
246 | ldr r5, [r8] @ get val | 243 | ldr r5, [r8] @ get val |
247 | mvn r6, #0x3 @ clear mask | 244 | mvn r6, #0x3 @ clear mask |
248 | and r5, r5, r6 @ clear field | 245 | and r5, r5, r6 @ clear field |
249 | orr r7, r5, #0x2 @ fast relock val | 246 | orr r7, r5, #0x2 @ fast relock val |
250 | str r7, [r8] @ go to fast relock | 247 | str r7, [r8] @ go to fast relock |
251 | ldr r4, pll_stat @ addr of stat | 248 | ldr r4, omap242x_ssp_pll_stat @ addr of stat |
252 | block: | 249 | block: |
253 | /* wait for bypass */ | 250 | /* wait for bypass */ |
254 | ldr r8, [r4] @ stat value | 251 | ldr r8, [r4] @ stat value |
@@ -257,10 +254,10 @@ block: | |||
257 | bne block @ loop if not | 254 | bne block @ loop if not |
258 | 255 | ||
259 | /* set new dpll dividers _after_ in bypass */ | 256 | /* set new dpll dividers _after_ in bypass */ |
260 | ldr r4, pll_div @ get addr | 257 | ldr r4, omap242x_ssp_pll_div @ get addr |
261 | str r0, [r4] @ set dpll ctrl val | 258 | str r0, [r4] @ set dpll ctrl val |
262 | 259 | ||
263 | ldr r4, set_config @ get addr | 260 | ldr r4, omap242x_ssp_set_config @ get addr |
264 | mov r8, #1 @ valid cfg msk | 261 | mov r8, #1 @ valid cfg msk |
265 | str r8, [r4] @ make dividers take | 262 | str r8, [r4] @ make dividers take |
266 | 263 | ||
@@ -274,8 +271,8 @@ wait_a_bit: | |||
274 | beq pend @ jump over dpll relock | 271 | beq pend @ jump over dpll relock |
275 | 272 | ||
276 | /* relock DPLL with new vals */ | 273 | /* relock DPLL with new vals */ |
277 | ldr r5, pll_stat @ get addr | 274 | ldr r5, omap242x_ssp_pll_stat @ get addr |
278 | ldr r4, pll_ctl @ get addr | 275 | ldr r4, omap242x_ssp_pll_ctl @ get addr |
279 | orr r8, r7, #0x3 @ val for lock dpll | 276 | orr r8, r7, #0x3 @ val for lock dpll |
280 | str r8, [r4] @ set val | 277 | str r8, [r4] @ set val |
281 | mov r0, #1000 @ dead spin a bit | 278 | mov r0, #1000 @ dead spin a bit |
@@ -289,9 +286,9 @@ wait_lock: | |||
289 | bne wait_lock @ wait if not | 286 | bne wait_lock @ wait if not |
290 | pend: | 287 | pend: |
291 | /* update memory timings & briefly lock dll */ | 288 | /* update memory timings & briefly lock dll */ |
292 | ldr r4, sdrc_rfr @ get addr | 289 | ldr r4, omap242x_ssp_sdrc_rfr @ get addr |
293 | str r1, [r4] @ update refresh timing | 290 | str r1, [r4] @ update refresh timing |
294 | ldr r11, dlla_ctrl @ get addr of DLLA ctrl | 291 | ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl |
295 | ldr r10, [r11] @ get current val | 292 | ldr r10, [r11] @ get current val |
296 | mvn r9, #0x4 @ mask to get clear bit2 | 293 | mvn r9, #0x4 @ mask to get clear bit2 |
297 | and r10, r10, r9 @ clear bit2 for lock mode | 294 | and r10, r10, r9 @ clear bit2 for lock mode |
@@ -307,18 +304,18 @@ wait_dll_lock: | |||
307 | nop | 304 | nop |
308 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 305 | ldmfd sp!, {r0-r12, pc} @ restore regs and return |
309 | 306 | ||
310 | set_config: | 307 | omap242x_ssp_set_config: |
311 | .word OMAP2420_PRM_REGADDR(OCP_MOD, 0x80) | 308 | .word OMAP242X_PRCM_CLKCFG_CTRL |
312 | pll_ctl: | 309 | omap242x_ssp_pll_ctl: |
313 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_FCLKEN1) | 310 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) |
314 | pll_stat: | 311 | omap242x_ssp_pll_stat: |
315 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST1) | 312 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST) |
316 | pll_div: | 313 | omap242x_ssp_pll_div: |
317 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL) | 314 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1) |
318 | sdrc_rfr: | 315 | omap242x_ssp_sdrc_rfr: |
319 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 316 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
320 | dlla_ctrl: | 317 | omap242x_ssp_dlla_ctrl: |
321 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 318 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
322 | 319 | ||
323 | ENTRY(sram_set_prcm_sz) | 320 | ENTRY(omap242x_sram_set_prcm_sz) |
324 | .word . - sram_set_prcm | 321 | .word . - omap242x_sram_set_prcm |
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S new file mode 100644 index 000000000000..a3fa48dc08cd --- /dev/null +++ b/arch/arm/mach-omap2/sram243x.S | |||
@@ -0,0 +1,321 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-omap2/sram243x.S | ||
3 | * | ||
4 | * Omap2 specific functions that need to be run in internal SRAM | ||
5 | * | ||
6 | * (C) Copyright 2004 | ||
7 | * Texas Instruments, <www.ti.com> | ||
8 | * Richard Woodruff <r-woodruff2@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License as | ||
12 | * published by the Free Software Foundation; either version 2 of | ||
13 | * the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
23 | * MA 02111-1307 USA | ||
24 | */ | ||
25 | #include <linux/linkage.h> | ||
26 | #include <asm/assembler.h> | ||
27 | #include <asm/arch/io.h> | ||
28 | #include <asm/hardware.h> | ||
29 | |||
30 | #include "prm.h" | ||
31 | #include "cm.h" | ||
32 | #include "sdrc.h" | ||
33 | |||
34 | .text | ||
35 | |||
36 | ENTRY(omap243x_sram_ddr_init) | ||
37 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | ||
38 | |||
39 | mov r12, r2 @ capture CS1 vs CS0 | ||
40 | mov r8, r3 @ capture force parameter | ||
41 | |||
42 | /* frequency shift down */ | ||
43 | ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg | ||
44 | mov r3, #0x1 @ value for 1x operation | ||
45 | str r3, [r2] @ go to L1-freq operation | ||
46 | |||
47 | /* voltage shift down */ | ||
48 | mov r9, #0x1 @ set up for L1 voltage call | ||
49 | bl voltage_shift @ go drop voltage | ||
50 | |||
51 | /* dll lock mode */ | ||
52 | ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl | ||
53 | ldr r10, [r11] @ get current val | ||
54 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) | ||
55 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB | ||
56 | mvn r9, #0x4 @ mask to get clear bit2 | ||
57 | and r10, r10, r9 @ clear bit2 for lock mode. | ||
58 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | ||
59 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz | ||
60 | str r10, [r11] @ commit to DLLA_CTRL | ||
61 | bl i_dll_wait @ wait for dll to lock | ||
62 | |||
63 | /* get dll value */ | ||
64 | add r11, r11, #0x4 @ get addr of status reg | ||
65 | ldr r10, [r11] @ get locked value | ||
66 | |||
67 | /* voltage shift up */ | ||
68 | mov r9, #0x0 @ shift back to L0-voltage | ||
69 | bl voltage_shift @ go raise voltage | ||
70 | |||
71 | /* frequency shift up */ | ||
72 | mov r3, #0x2 @ value for 2x operation | ||
73 | str r3, [r2] @ go to L0-freq operation | ||
74 | |||
75 | /* reset entry mode for dllctrl */ | ||
76 | sub r11, r11, #0x4 @ move from status to ctrl | ||
77 | cmp r12, #0x1 @ normalize if cs1 based | ||
78 | subeq r11, r11, #0x8 @ possibly back to DLLA | ||
79 | cmp r8, #0x1 @ if forced unlock exit | ||
80 | orreq r1, r1, #0x4 @ make sure exit with unlocked value | ||
81 | str r1, [r11] @ restore DLLA_CTRL high value | ||
82 | add r11, r11, #0x8 @ move to DLLB_CTRL addr | ||
83 | str r1, [r11] @ set value DLLB_CTRL | ||
84 | bl i_dll_wait @ wait for possible lock | ||
85 | |||
86 | /* set up for return, DDR should be good */ | ||
87 | str r10, [r0] @ write dll_status and return counter | ||
88 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | ||
89 | |||
90 | /* ensure the DLL has relocked */ | ||
91 | i_dll_wait: | ||
92 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks | ||
93 | i_dll_delay: | ||
94 | subs r4, r4, #0x1 | ||
95 | bne i_dll_delay | ||
96 | mov pc, lr | ||
97 | |||
98 | /* | ||
99 | * shift up or down voltage, use R9 as input to tell level. | ||
100 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | ||
101 | */ | ||
102 | voltage_shift: | ||
103 | ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl. | ||
104 | ldr r5, [r4] @ get value. | ||
105 | ldr r6, prcm_mask_val @ get value of mask | ||
106 | and r5, r5, r6 @ apply mask to clear bits | ||
107 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. | ||
108 | str r5, [r4] @ set up for change. | ||
109 | mov r3, #0x4000 @ get val for force | ||
110 | orr r5, r5, r3 @ build value for force | ||
111 | str r5, [r4] @ Force transition to L1 | ||
112 | |||
113 | ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter | ||
114 | ldr r5, [r3] @ get value | ||
115 | add r5, r5, #0x3 @ give it at most 93uS | ||
116 | volt_delay: | ||
117 | ldr r7, [r3] @ get timer value | ||
118 | cmp r5, r7 @ time up? | ||
119 | bhi volt_delay @ not yet->branch | ||
120 | mov pc, lr @ back to caller. | ||
121 | |||
122 | omap243x_sdi_cm_clksel2_pll: | ||
123 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | ||
124 | omap243x_sdi_sdrc_dlla_ctrl: | ||
125 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | ||
126 | omap243x_sdi_prcm_voltctrl: | ||
127 | .word OMAP243X_PRCM_VOLTCTRL | ||
128 | prcm_mask_val: | ||
129 | .word 0xFFFF3FFC | ||
130 | omap243x_sdi_timer_32ksynct_cr: | ||
131 | .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) | ||
132 | ENTRY(omap243x_sram_ddr_init_sz) | ||
133 | .word . - omap243x_sram_ddr_init | ||
134 | |||
135 | /* | ||
136 | * Reprograms memory timings. | ||
137 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] | ||
138 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 | ||
139 | */ | ||
140 | ENTRY(omap243x_sram_reprogram_sdrc) | ||
141 | stmfd sp!, {r0 - r10, lr} @ save registers on stack | ||
142 | mov r3, #0x0 @ clear for mrc call | ||
143 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR | ||
144 | nop | ||
145 | nop | ||
146 | ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg | ||
147 | ldr r5, [r6] @ get value | ||
148 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst | ||
149 | |||
150 | cmp r0, #0x1 @ going to half speed? | ||
151 | movne r9, #0x0 @ if up set flag up for pre up, hi volt | ||
152 | |||
153 | blne voltage_shift_c @ adjust voltage | ||
154 | |||
155 | cmp r0, #0x1 @ going to half speed (post branch link) | ||
156 | moveq r5, r5, lsr #1 @ divide by 2 if to half | ||
157 | movne r5, r5, lsl #1 @ mult by 2 if to full | ||
158 | mov r5, r5, lsl #8 @ put rfr field back into place | ||
159 | add r5, r5, #0x1 @ turn on burst of 1 | ||
160 | ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg | ||
161 | ldr r3, [r4] @ get curr value | ||
162 | orr r3, r3, #0x3 | ||
163 | bic r3, r3, #0x3 @ clear lower bits | ||
164 | orr r3, r3, r0 @ new state value | ||
165 | str r3, [r4] @ set new state (pll/x, x=1 or 2) | ||
166 | nop | ||
167 | nop | ||
168 | |||
169 | moveq r9, #0x1 @ if speed down, post down, drop volt | ||
170 | bleq voltage_shift_c | ||
171 | |||
172 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier | ||
173 | str r5, [r6] @ set new RFR_1 value | ||
174 | add r6, r6, #0x30 @ get RFR_2 addr | ||
175 | str r5, [r6] @ set RFR_2 | ||
176 | nop | ||
177 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL | ||
178 | bne freq_out @ leave if SDR, no DLL function | ||
179 | |||
180 | /* With DDR, we need to take care of the DLL for the frequency change */ | ||
181 | ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl | ||
182 | str r1, [r2] @ write out new SDRC_DLLA_CTRL | ||
183 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL | ||
184 | str r1, [r2] @ commit to SDRC_DLLB_CTRL | ||
185 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks | ||
186 | dll_wait: | ||
187 | subs r1, r1, #0x1 | ||
188 | bne dll_wait | ||
189 | freq_out: | ||
190 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return | ||
191 | |||
192 | /* | ||
193 | * shift up or down voltage, use R9 as input to tell level. | ||
194 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | ||
195 | */ | ||
196 | voltage_shift_c: | ||
197 | ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl | ||
198 | ldr r8, [r10] @ get value | ||
199 | ldr r7, ddr_prcm_mask_val @ get value of mask | ||
200 | and r8, r8, r7 @ apply mask to clear bits | ||
201 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. | ||
202 | str r8, [r10] @ set up for change. | ||
203 | mov r7, #0x4000 @ get val for force | ||
204 | orr r8, r8, r7 @ build value for force | ||
205 | str r8, [r10] @ Force transition to L1 | ||
206 | |||
207 | ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter | ||
208 | ldr r8, [r10] @ get value | ||
209 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) | ||
210 | volt_delay_c: | ||
211 | ldr r7, [r10] @ get timer value | ||
212 | cmp r8, r7 @ time up? | ||
213 | bhi volt_delay_c @ not yet->branch | ||
214 | mov pc, lr @ back to caller | ||
215 | |||
216 | omap243x_srs_cm_clksel2_pll: | ||
217 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | ||
218 | omap243x_srs_sdrc_dlla_ctrl: | ||
219 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | ||
220 | omap243x_srs_sdrc_rfr_ctrl: | ||
221 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | ||
222 | omap243x_srs_prcm_voltctrl: | ||
223 | .word OMAP243X_PRCM_VOLTCTRL | ||
224 | ddr_prcm_mask_val: | ||
225 | .word 0xFFFF3FFC | ||
226 | omap243x_srs_timer_32ksynct: | ||
227 | .word IO_ADDRESS(OMAP2_32KSYNCT_BASE + 0x010) | ||
228 | |||
229 | ENTRY(omap243x_sram_reprogram_sdrc_sz) | ||
230 | .word . - omap243x_sram_reprogram_sdrc | ||
231 | |||
232 | /* | ||
233 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. | ||
234 | */ | ||
235 | ENTRY(omap243x_sram_set_prcm) | ||
236 | stmfd sp!, {r0-r12, lr} @ regs to stack | ||
237 | adr r4, pbegin @ addr of preload start | ||
238 | adr r8, pend @ addr of preload end | ||
239 | mcrr p15, 1, r8, r4, c12 @ preload into icache | ||
240 | pbegin: | ||
241 | /* move into fast relock bypass */ | ||
242 | ldr r8, omap243x_ssp_pll_ctl @ get addr | ||
243 | ldr r5, [r8] @ get val | ||
244 | mvn r6, #0x3 @ clear mask | ||
245 | and r5, r5, r6 @ clear field | ||
246 | orr r7, r5, #0x2 @ fast relock val | ||
247 | str r7, [r8] @ go to fast relock | ||
248 | ldr r4, omap243x_ssp_pll_stat @ addr of stat | ||
249 | block: | ||
250 | /* wait for bypass */ | ||
251 | ldr r8, [r4] @ stat value | ||
252 | and r8, r8, #0x3 @ mask for stat | ||
253 | cmp r8, #0x1 @ there yet | ||
254 | bne block @ loop if not | ||
255 | |||
256 | /* set new dpll dividers _after_ in bypass */ | ||
257 | ldr r4, omap243x_ssp_pll_div @ get addr | ||
258 | str r0, [r4] @ set dpll ctrl val | ||
259 | |||
260 | ldr r4, omap243x_ssp_set_config @ get addr | ||
261 | mov r8, #1 @ valid cfg msk | ||
262 | str r8, [r4] @ make dividers take | ||
263 | |||
264 | mov r4, #100 @ dead spin a bit | ||
265 | wait_a_bit: | ||
266 | subs r4, r4, #1 @ dec loop | ||
267 | bne wait_a_bit @ delay done? | ||
268 | |||
269 | /* check if staying in bypass */ | ||
270 | cmp r2, #0x1 @ stay in bypass? | ||
271 | beq pend @ jump over dpll relock | ||
272 | |||
273 | /* relock DPLL with new vals */ | ||
274 | ldr r5, omap243x_ssp_pll_stat @ get addr | ||
275 | ldr r4, omap243x_ssp_pll_ctl @ get addr | ||
276 | orr r8, r7, #0x3 @ val for lock dpll | ||
277 | str r8, [r4] @ set val | ||
278 | mov r0, #1000 @ dead spin a bit | ||
279 | wait_more: | ||
280 | subs r0, r0, #1 @ dec loop | ||
281 | bne wait_more @ delay done? | ||
282 | wait_lock: | ||
283 | ldr r8, [r5] @ get lock val | ||
284 | and r8, r8, #3 @ isolate field | ||
285 | cmp r8, #2 @ locked? | ||
286 | bne wait_lock @ wait if not | ||
287 | pend: | ||
288 | /* update memory timings & briefly lock dll */ | ||
289 | ldr r4, omap243x_ssp_sdrc_rfr @ get addr | ||
290 | str r1, [r4] @ update refresh timing | ||
291 | ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl | ||
292 | ldr r10, [r11] @ get current val | ||
293 | mvn r9, #0x4 @ mask to get clear bit2 | ||
294 | and r10, r10, r9 @ clear bit2 for lock mode | ||
295 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | ||
296 | str r10, [r11] @ commit to DLLA_CTRL | ||
297 | add r11, r11, #0x8 @ move to dllb | ||
298 | str r10, [r11] @ hit DLLB also | ||
299 | |||
300 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) | ||
301 | wait_dll_lock: | ||
302 | subs r4, r4, #0x1 | ||
303 | bne wait_dll_lock | ||
304 | nop | ||
305 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | ||
306 | |||
307 | omap243x_ssp_set_config: | ||
308 | .word OMAP243X_PRCM_CLKCFG_CTRL | ||
309 | omap243x_ssp_pll_ctl: | ||
310 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) | ||
311 | omap243x_ssp_pll_stat: | ||
312 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST) | ||
313 | omap243x_ssp_pll_div: | ||
314 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1) | ||
315 | omap243x_ssp_sdrc_rfr: | ||
316 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | ||
317 | omap243x_ssp_dlla_ctrl: | ||
318 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | ||
319 | |||
320 | ENTRY(omap243x_sram_set_prcm_sz) | ||
321 | .word . - omap243x_sram_set_prcm | ||
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 78d05f203fff..557603f99313 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c | |||
@@ -59,8 +59,7 @@ static struct irqaction omap2_gp_timer_irq = { | |||
59 | static int omap2_gp_timer_set_next_event(unsigned long cycles, | 59 | static int omap2_gp_timer_set_next_event(unsigned long cycles, |
60 | struct clock_event_device *evt) | 60 | struct clock_event_device *evt) |
61 | { | 61 | { |
62 | omap_dm_timer_set_load(gptimer, 0, 0xffffffff - cycles); | 62 | omap_dm_timer_set_load_start(gptimer, 0, 0xffffffff - cycles); |
63 | omap_dm_timer_start(gptimer); | ||
64 | 63 | ||
65 | return 0; | 64 | return 0; |
66 | } | 65 | } |
@@ -77,8 +76,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode, | |||
77 | period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; | 76 | period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; |
78 | period -= 1; | 77 | period -= 1; |
79 | 78 | ||
80 | omap_dm_timer_set_load(gptimer, 1, 0xffffffff - period); | 79 | omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - period); |
81 | omap_dm_timer_start(gptimer); | ||
82 | break; | 80 | break; |
83 | case CLOCK_EVT_MODE_ONESHOT: | 81 | case CLOCK_EVT_MODE_ONESHOT: |
84 | break; | 82 | break; |
@@ -172,8 +170,7 @@ static void __init omap2_gp_clocksource_init(void) | |||
172 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); | 170 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gpt)); |
173 | tick_period = (tick_rate / HZ) - 1; | 171 | tick_period = (tick_rate / HZ) - 1; |
174 | 172 | ||
175 | omap_dm_timer_set_load(gpt, 1, 0); | 173 | omap_dm_timer_set_load_start(gpt, 1, 0); |
176 | omap_dm_timer_start(gpt); | ||
177 | 174 | ||
178 | clocksource_gpt.mult = | 175 | clocksource_gpt.mult = |
179 | clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); | 176 | clocksource_khz2mult(tick_rate/1000, clocksource_gpt.shift); |