diff options
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r-- | arch/arm/mach-mx3/Kconfig | 36 | ||||
-rw-r--r-- | arch/arm/mach-mx3/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-mx3/clock-imx35.c | 487 | ||||
-rw-r--r-- | arch/arm/mach-mx3/clock.c | 959 | ||||
-rw-r--r-- | arch/arm/mach-mx3/crm_regs.h | 153 | ||||
-rw-r--r-- | arch/arm/mach-mx3/devices.c | 193 | ||||
-rw-r--r-- | arch/arm/mach-mx3/devices.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-mx3/iomux.c | 88 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mm.c | 37 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31ads.c | 328 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31lite.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard-devboard.c | 48 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard-marxbot.c | 37 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard.c | 74 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31pdk.c | 44 | ||||
-rw-r--r-- | arch/arm/mach-mx3/pcm037.c | 138 | ||||
-rw-r--r-- | arch/arm/mach-mx3/qong.c | 312 |
17 files changed, 1894 insertions, 1069 deletions
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index e79659e8176e..d6235583e979 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig | |||
@@ -1,21 +1,40 @@ | |||
1 | menu "MX3 Options" | 1 | if ARCH_MX3 |
2 | depends on ARCH_MX3 | 2 | |
3 | config ARCH_MX31 | ||
4 | bool | ||
5 | |||
6 | config ARCH_MX35 | ||
7 | bool | ||
8 | |||
9 | comment "MX3 platforms:" | ||
3 | 10 | ||
4 | config MACH_MX31ADS | 11 | config MACH_MX31ADS |
5 | bool "Support MX31ADS platforms" | 12 | bool "Support MX31ADS platforms" |
13 | select ARCH_MX31 | ||
6 | default y | 14 | default y |
7 | help | 15 | help |
8 | Include support for MX31ADS platform. This includes specific | 16 | Include support for MX31ADS platform. This includes specific |
9 | configurations for the board and its peripherals. | 17 | configurations for the board and its peripherals. |
10 | 18 | ||
19 | config MACH_MX31ADS_WM1133_EV1 | ||
20 | bool "Support Wolfson Microelectronics 1133-EV1 module" | ||
21 | depends on MACH_MX31ADS | ||
22 | select MFD_WM8350_CONFIG_MODE_0 | ||
23 | select MFD_WM8352_CONFIG_MODE_0 | ||
24 | help | ||
25 | Include support for the Wolfson Microelectronics 1133-EV1 PMU | ||
26 | and audio module for the MX31ADS platform. | ||
27 | |||
11 | config MACH_PCM037 | 28 | config MACH_PCM037 |
12 | bool "Support Phytec pcm037 platforms" | 29 | bool "Support Phytec pcm037 (i.MX31) platforms" |
30 | select ARCH_MX31 | ||
13 | help | 31 | help |
14 | Include support for Phytec pcm037 platform. This includes | 32 | Include support for Phytec pcm037 platform. This includes |
15 | specific configurations for the board and its peripherals. | 33 | specific configurations for the board and its peripherals. |
16 | 34 | ||
17 | config MACH_MX31LITE | 35 | config MACH_MX31LITE |
18 | bool "Support MX31 LITEKIT (LogicPD)" | 36 | bool "Support MX31 LITEKIT (LogicPD)" |
37 | select ARCH_MX31 | ||
19 | default n | 38 | default n |
20 | help | 39 | help |
21 | Include support for MX31 LITEKIT platform. This includes specific | 40 | Include support for MX31 LITEKIT platform. This includes specific |
@@ -23,6 +42,7 @@ config MACH_MX31LITE | |||
23 | 42 | ||
24 | config MACH_MX31_3DS | 43 | config MACH_MX31_3DS |
25 | bool "Support MX31PDK (3DS)" | 44 | bool "Support MX31PDK (3DS)" |
45 | select ARCH_MX31 | ||
26 | default n | 46 | default n |
27 | help | 47 | help |
28 | Include support for MX31PDK (3DS) platform. This includes specific | 48 | Include support for MX31PDK (3DS) platform. This includes specific |
@@ -30,10 +50,18 @@ config MACH_MX31_3DS | |||
30 | 50 | ||
31 | config MACH_MX31MOBOARD | 51 | config MACH_MX31MOBOARD |
32 | bool "Support mx31moboard platforms (EPFL Mobots group)" | 52 | bool "Support mx31moboard platforms (EPFL Mobots group)" |
53 | select ARCH_MX31 | ||
33 | default n | 54 | default n |
34 | help | 55 | help |
35 | Include support for mx31moboard platform. This includes specific | 56 | Include support for mx31moboard platform. This includes specific |
36 | configurations for the board and its peripherals. | 57 | configurations for the board and its peripherals. |
37 | 58 | ||
38 | endmenu | 59 | config MACH_QONG |
60 | bool "Support Dave/DENX QongEVB-LITE platform" | ||
61 | select ARCH_MX31 | ||
62 | default n | ||
63 | help | ||
64 | Include support for Dave/DENX QongEVB-LITE platform. This includes | ||
65 | specific configurations for the board and its peripherals. | ||
39 | 66 | ||
67 | endif | ||
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 5a151540fe83..272c8a953b30 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile | |||
@@ -4,9 +4,13 @@ | |||
4 | 4 | ||
5 | # Object file lists. | 5 | # Object file lists. |
6 | 6 | ||
7 | obj-y := mm.o clock.o devices.o iomux.o | 7 | obj-y := mm.o devices.o |
8 | obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o | ||
9 | obj-$(CONFIG_ARCH_MX35) += clock-imx35.o | ||
8 | obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o | 10 | obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o |
9 | obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o | 11 | obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o |
10 | obj-$(CONFIG_MACH_PCM037) += pcm037.o | 12 | obj-$(CONFIG_MACH_PCM037) += pcm037.o |
11 | obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o | 13 | obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o |
12 | obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o | 14 | obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ |
15 | mx31moboard-marxbot.o | ||
16 | obj-$(CONFIG_MACH_QONG) += qong.o | ||
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c new file mode 100644 index 000000000000..53a112d4e04a --- /dev/null +++ b/arch/arm/mach-mx3/clock-imx35.c | |||
@@ -0,0 +1,487 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 by Sascha Hauer, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | ||
16 | * MA 02110-1301, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/io.h> | ||
24 | |||
25 | #include <asm/clkdev.h> | ||
26 | |||
27 | #include <mach/clock.h> | ||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/common.h> | ||
30 | |||
31 | #define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR) | ||
32 | |||
33 | #define CCM_CCMR 0x00 | ||
34 | #define CCM_PDR0 0x04 | ||
35 | #define CCM_PDR1 0x08 | ||
36 | #define CCM_PDR2 0x0C | ||
37 | #define CCM_PDR3 0x10 | ||
38 | #define CCM_PDR4 0x14 | ||
39 | #define CCM_RCSR 0x18 | ||
40 | #define CCM_MPCTL 0x1C | ||
41 | #define CCM_PPCTL 0x20 | ||
42 | #define CCM_ACMR 0x24 | ||
43 | #define CCM_COSR 0x28 | ||
44 | #define CCM_CGR0 0x2C | ||
45 | #define CCM_CGR1 0x30 | ||
46 | #define CCM_CGR2 0x34 | ||
47 | #define CCM_CGR3 0x38 | ||
48 | |||
49 | #ifdef HAVE_SET_RATE_SUPPORT | ||
50 | static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) | ||
51 | { | ||
52 | u32 min_pre, temp_pre, old_err, err; | ||
53 | |||
54 | min_pre = (div - 1) / maxpost + 1; | ||
55 | old_err = 8; | ||
56 | |||
57 | for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { | ||
58 | if (div > (temp_pre * maxpost)) | ||
59 | break; | ||
60 | |||
61 | if (div < (temp_pre * temp_pre)) | ||
62 | continue; | ||
63 | |||
64 | err = div % temp_pre; | ||
65 | |||
66 | if (err == 0) { | ||
67 | *pre = temp_pre; | ||
68 | break; | ||
69 | } | ||
70 | |||
71 | err = temp_pre - err; | ||
72 | |||
73 | if (err < old_err) { | ||
74 | old_err = err; | ||
75 | *pre = temp_pre; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | *post = (div + *pre - 1) / *pre; | ||
80 | } | ||
81 | |||
82 | /* get the best values for a 3-bit divider combined with a 6-bit divider */ | ||
83 | static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post) | ||
84 | { | ||
85 | if (div >= 512) { | ||
86 | *pre = 8; | ||
87 | *post = 64; | ||
88 | } else if (div >= 64) { | ||
89 | calc_dividers(div, pre, post, 64); | ||
90 | } else if (div <= 8) { | ||
91 | *pre = div; | ||
92 | *post = 1; | ||
93 | } else { | ||
94 | *pre = 1; | ||
95 | *post = div; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* get the best values for two cascaded 3-bit dividers */ | ||
100 | static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) | ||
101 | { | ||
102 | if (div >= 64) { | ||
103 | *pre = *post = 8; | ||
104 | } else if (div > 8) { | ||
105 | calc_dividers(div, pre, post, 8); | ||
106 | } else { | ||
107 | *pre = 1; | ||
108 | *post = div; | ||
109 | } | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | static unsigned long get_rate_mpll(void) | ||
114 | { | ||
115 | ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL); | ||
116 | |||
117 | return mxc_decode_pll(mpctl, 24000000); | ||
118 | } | ||
119 | |||
120 | static unsigned long get_rate_ppll(void) | ||
121 | { | ||
122 | ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL); | ||
123 | |||
124 | return mxc_decode_pll(ppctl, 24000000); | ||
125 | } | ||
126 | |||
127 | struct arm_ahb_div { | ||
128 | unsigned char arm, ahb, sel; | ||
129 | }; | ||
130 | |||
131 | static struct arm_ahb_div clk_consumer[] = { | ||
132 | { .arm = 1, .ahb = 4, .sel = 0}, | ||
133 | { .arm = 1, .ahb = 3, .sel = 1}, | ||
134 | { .arm = 2, .ahb = 2, .sel = 0}, | ||
135 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
136 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
137 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
138 | { .arm = 4, .ahb = 1, .sel = 0}, | ||
139 | { .arm = 1, .ahb = 5, .sel = 0}, | ||
140 | { .arm = 1, .ahb = 8, .sel = 0}, | ||
141 | { .arm = 1, .ahb = 6, .sel = 1}, | ||
142 | { .arm = 2, .ahb = 4, .sel = 0}, | ||
143 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
144 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
145 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
146 | { .arm = 4, .ahb = 2, .sel = 0}, | ||
147 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
148 | }; | ||
149 | |||
150 | static struct arm_ahb_div clk_automotive[] = { | ||
151 | { .arm = 1, .ahb = 3, .sel = 0}, | ||
152 | { .arm = 1, .ahb = 2, .sel = 1}, | ||
153 | { .arm = 2, .ahb = 1, .sel = 1}, | ||
154 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
155 | { .arm = 1, .ahb = 6, .sel = 0}, | ||
156 | { .arm = 1, .ahb = 4, .sel = 1}, | ||
157 | { .arm = 2, .ahb = 2, .sel = 1}, | ||
158 | { .arm = 0, .ahb = 0, .sel = 0}, | ||
159 | }; | ||
160 | |||
161 | static unsigned long get_rate_arm(void) | ||
162 | { | ||
163 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
164 | struct arm_ahb_div *aad; | ||
165 | unsigned long fref = get_rate_mpll(); | ||
166 | |||
167 | if (pdr0 & 1) { | ||
168 | /* consumer path */ | ||
169 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
170 | if (aad->sel) | ||
171 | fref = fref * 2 / 3; | ||
172 | } else { | ||
173 | /* auto path */ | ||
174 | aad = &clk_automotive[(pdr0 >> 9) & 0x7]; | ||
175 | if (aad->sel) | ||
176 | fref = fref * 3 / 4; | ||
177 | } | ||
178 | return fref / aad->arm; | ||
179 | } | ||
180 | |||
181 | static unsigned long get_rate_ahb(struct clk *clk) | ||
182 | { | ||
183 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
184 | struct arm_ahb_div *aad; | ||
185 | unsigned long fref = get_rate_mpll(); | ||
186 | |||
187 | if (pdr0 & 1) | ||
188 | /* consumer path */ | ||
189 | aad = &clk_consumer[(pdr0 >> 16) & 0xf]; | ||
190 | else | ||
191 | /* auto path */ | ||
192 | aad = &clk_automotive[(pdr0 >> 9) & 0x7]; | ||
193 | |||
194 | return fref / aad->ahb; | ||
195 | } | ||
196 | |||
197 | static unsigned long get_rate_ipg(struct clk *clk) | ||
198 | { | ||
199 | return get_rate_ahb(NULL) >> 1; | ||
200 | } | ||
201 | |||
202 | static unsigned long get_3_3_div(unsigned long in) | ||
203 | { | ||
204 | return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1); | ||
205 | } | ||
206 | |||
207 | static unsigned long get_rate_uart(struct clk *clk) | ||
208 | { | ||
209 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); | ||
210 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
211 | unsigned long div = get_3_3_div(pdr4 >> 10); | ||
212 | |||
213 | if (pdr3 & (1 << 14)) | ||
214 | return get_rate_arm() / div; | ||
215 | else | ||
216 | return get_rate_ppll() / div; | ||
217 | } | ||
218 | |||
219 | static unsigned long get_rate_sdhc(struct clk *clk) | ||
220 | { | ||
221 | unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); | ||
222 | unsigned long div, rate; | ||
223 | |||
224 | if (pdr3 & (1 << 6)) | ||
225 | rate = get_rate_arm(); | ||
226 | else | ||
227 | rate = get_rate_ppll(); | ||
228 | |||
229 | switch (clk->id) { | ||
230 | default: | ||
231 | case 0: | ||
232 | div = pdr3 & 0x3f; | ||
233 | break; | ||
234 | case 1: | ||
235 | div = (pdr3 >> 8) & 0x3f; | ||
236 | break; | ||
237 | case 2: | ||
238 | div = (pdr3 >> 16) & 0x3f; | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | return rate / get_3_3_div(div); | ||
243 | } | ||
244 | |||
245 | static unsigned long get_rate_mshc(struct clk *clk) | ||
246 | { | ||
247 | unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1); | ||
248 | unsigned long div1, div2, rate; | ||
249 | |||
250 | if (pdr1 & (1 << 7)) | ||
251 | rate = get_rate_arm(); | ||
252 | else | ||
253 | rate = get_rate_ppll(); | ||
254 | |||
255 | div1 = (pdr1 >> 29) & 0x7; | ||
256 | div2 = (pdr1 >> 22) & 0x3f; | ||
257 | |||
258 | return rate / ((div1 + 1) * (div2 + 1)); | ||
259 | } | ||
260 | |||
261 | static unsigned long get_rate_ssi(struct clk *clk) | ||
262 | { | ||
263 | unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); | ||
264 | unsigned long div1, div2, rate; | ||
265 | |||
266 | if (pdr2 & (1 << 6)) | ||
267 | rate = get_rate_arm(); | ||
268 | else | ||
269 | rate = get_rate_ppll(); | ||
270 | |||
271 | switch (clk->id) { | ||
272 | default: | ||
273 | case 0: | ||
274 | div1 = pdr2 & 0x3f; | ||
275 | div2 = (pdr2 >> 24) & 0x7; | ||
276 | break; | ||
277 | case 1: | ||
278 | div1 = (pdr2 >> 8) & 0x3f; | ||
279 | div2 = (pdr2 >> 27) & 0x7; | ||
280 | break; | ||
281 | } | ||
282 | |||
283 | return rate / ((div1 + 1) * (div2 + 1)); | ||
284 | } | ||
285 | |||
286 | static unsigned long get_rate_csi(struct clk *clk) | ||
287 | { | ||
288 | unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); | ||
289 | unsigned long rate; | ||
290 | |||
291 | if (pdr2 & (1 << 7)) | ||
292 | rate = get_rate_arm(); | ||
293 | else | ||
294 | rate = get_rate_ppll(); | ||
295 | |||
296 | return rate / get_3_3_div((pdr2 >> 16) & 0x3f); | ||
297 | } | ||
298 | |||
299 | static unsigned long get_rate_ipg_per(struct clk *clk) | ||
300 | { | ||
301 | unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); | ||
302 | unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); | ||
303 | unsigned long div1, div2; | ||
304 | |||
305 | if (pdr0 & (1 << 26)) { | ||
306 | div1 = (pdr4 >> 19) & 0x7; | ||
307 | div2 = (pdr4 >> 16) & 0x7; | ||
308 | return get_rate_arm() / ((div1 + 1) * (div2 + 1)); | ||
309 | } else { | ||
310 | div1 = (pdr0 >> 12) & 0x7; | ||
311 | return get_rate_ahb(NULL) / div1; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | static int clk_cgr_enable(struct clk *clk) | ||
316 | { | ||
317 | u32 reg; | ||
318 | |||
319 | reg = __raw_readl(clk->enable_reg); | ||
320 | reg |= 3 << clk->enable_shift; | ||
321 | __raw_writel(reg, clk->enable_reg); | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | static void clk_cgr_disable(struct clk *clk) | ||
327 | { | ||
328 | u32 reg; | ||
329 | |||
330 | reg = __raw_readl(clk->enable_reg); | ||
331 | reg &= ~(3 << clk->enable_shift); | ||
332 | __raw_writel(reg, clk->enable_reg); | ||
333 | } | ||
334 | |||
335 | #define DEFINE_CLOCK(name, i, er, es, gr, sr) \ | ||
336 | static struct clk name = { \ | ||
337 | .id = i, \ | ||
338 | .enable_reg = CCM_BASE + er, \ | ||
339 | .enable_shift = es, \ | ||
340 | .get_rate = gr, \ | ||
341 | .set_rate = sr, \ | ||
342 | .enable = clk_cgr_enable, \ | ||
343 | .disable = clk_cgr_disable, \ | ||
344 | } | ||
345 | |||
346 | DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL); | ||
347 | DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL); | ||
348 | DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); | ||
349 | DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL); | ||
350 | DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL); | ||
351 | DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL); | ||
352 | DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL); | ||
353 | DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL); | ||
354 | DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL); | ||
355 | DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL); | ||
356 | DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL); | ||
357 | DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL); | ||
358 | DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL); | ||
359 | DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL); | ||
360 | DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL); | ||
361 | DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL); | ||
362 | |||
363 | DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL); | ||
364 | DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL); | ||
365 | DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL); | ||
366 | DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL); | ||
367 | DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL); | ||
368 | DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); | ||
369 | DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); | ||
370 | DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); | ||
371 | DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); | ||
372 | DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, NULL, NULL); | ||
373 | DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); | ||
374 | DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); | ||
375 | DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); | ||
376 | DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL); | ||
377 | DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL); | ||
378 | DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL); | ||
379 | |||
380 | DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL); | ||
381 | DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL); | ||
382 | DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL); | ||
383 | DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL); | ||
384 | DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL); | ||
385 | DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL); | ||
386 | DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL); | ||
387 | DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL); | ||
388 | DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); | ||
389 | DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); | ||
390 | DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); | ||
391 | DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL); | ||
392 | DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); | ||
393 | DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); | ||
394 | DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); | ||
395 | |||
396 | DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL); | ||
397 | DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL); | ||
398 | DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); | ||
399 | |||
400 | #define _REGISTER_CLOCK(d, n, c) \ | ||
401 | { \ | ||
402 | .dev_id = d, \ | ||
403 | .con_id = n, \ | ||
404 | .clk = &c, \ | ||
405 | }, | ||
406 | |||
407 | static struct clk_lookup lookups[] __initdata = { | ||
408 | _REGISTER_CLOCK(NULL, "asrc", asrc_clk) | ||
409 | _REGISTER_CLOCK(NULL, "ata", ata_clk) | ||
410 | _REGISTER_CLOCK(NULL, "audmux", audmux_clk) | ||
411 | _REGISTER_CLOCK(NULL, "can", can1_clk) | ||
412 | _REGISTER_CLOCK(NULL, "can", can2_clk) | ||
413 | _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) | ||
414 | _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) | ||
415 | _REGISTER_CLOCK(NULL, "ect", ect_clk) | ||
416 | _REGISTER_CLOCK(NULL, "edio", edio_clk) | ||
417 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
418 | _REGISTER_CLOCK(NULL, "epit", epit1_clk) | ||
419 | _REGISTER_CLOCK(NULL, "epit", epit2_clk) | ||
420 | _REGISTER_CLOCK(NULL, "esai", esai_clk) | ||
421 | _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk) | ||
422 | _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk) | ||
423 | _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk) | ||
424 | _REGISTER_CLOCK("fec.0", NULL, fec_clk) | ||
425 | _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) | ||
426 | _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) | ||
427 | _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) | ||
428 | _REGISTER_CLOCK("gpt.0", NULL, gpt_clk) | ||
429 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
430 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
431 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
432 | _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) | ||
433 | _REGISTER_CLOCK(NULL, "ipu", ipu_clk) | ||
434 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
435 | _REGISTER_CLOCK(NULL, "mlb", mlb_clk) | ||
436 | _REGISTER_CLOCK(NULL, "mshc", mshc_clk) | ||
437 | _REGISTER_CLOCK("mxc_w1", NULL, owire_clk) | ||
438 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
439 | _REGISTER_CLOCK(NULL, "rngc", rngc_clk) | ||
440 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
441 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
442 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
443 | _REGISTER_CLOCK(NULL, "sdma", sdma_clk) | ||
444 | _REGISTER_CLOCK(NULL, "spba", spba_clk) | ||
445 | _REGISTER_CLOCK(NULL, "spdif", spdif_clk) | ||
446 | _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) | ||
447 | _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) | ||
448 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | ||
449 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | ||
450 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | ||
451 | _REGISTER_CLOCK(NULL, "usbotg", usbotg_clk) | ||
452 | _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk) | ||
453 | _REGISTER_CLOCK(NULL, "max", max_clk) | ||
454 | _REGISTER_CLOCK(NULL, "admux", admux_clk) | ||
455 | _REGISTER_CLOCK(NULL, "csi", csi_clk) | ||
456 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
457 | _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) | ||
458 | }; | ||
459 | |||
460 | int __init mx35_clocks_init() | ||
461 | { | ||
462 | int i; | ||
463 | unsigned int ll = 0; | ||
464 | |||
465 | mxc_set_cpu_type(MXC_CPU_MX35); | ||
466 | |||
467 | #ifdef CONFIG_DEBUG_LL_CONSOLE | ||
468 | ll = (3 << 16); | ||
469 | #endif | ||
470 | |||
471 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
472 | clkdev_add(&lookups[i]); | ||
473 | |||
474 | /* Turn off all clocks except the ones we need to survive, namely: | ||
475 | * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart | ||
476 | */ | ||
477 | __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); | ||
478 | __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), | ||
479 | CCM_BASE + CCM_CGR1); | ||
480 | __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); | ||
481 | __raw_writel(0, CCM_BASE + CCM_CGR3); | ||
482 | |||
483 | mxc_timer_init(&gpt_clk); | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index b1746aae1f89..ca46f4801c3d 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c | |||
@@ -23,9 +23,13 @@ | |||
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/io.h> | 25 | #include <linux/io.h> |
26 | |||
27 | #include <asm/clkdev.h> | ||
28 | #include <asm/div64.h> | ||
29 | |||
26 | #include <mach/clock.h> | 30 | #include <mach/clock.h> |
27 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
28 | #include <asm/div64.h> | 32 | #include <mach/common.h> |
29 | 33 | ||
30 | #include "crm_regs.h" | 34 | #include "crm_regs.h" |
31 | 35 | ||
@@ -64,17 +68,17 @@ static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) | |||
64 | } | 68 | } |
65 | 69 | ||
66 | static struct clk mcu_pll_clk; | 70 | static struct clk mcu_pll_clk; |
67 | static struct clk mcu_main_clk; | ||
68 | static struct clk usb_pll_clk; | ||
69 | static struct clk serial_pll_clk; | 71 | static struct clk serial_pll_clk; |
70 | static struct clk ipg_clk; | 72 | static struct clk ipg_clk; |
71 | static struct clk ckih_clk; | 73 | static struct clk ckih_clk; |
72 | static struct clk ahb_clk; | ||
73 | 74 | ||
74 | static int _clk_enable(struct clk *clk) | 75 | static int cgr_enable(struct clk *clk) |
75 | { | 76 | { |
76 | u32 reg; | 77 | u32 reg; |
77 | 78 | ||
79 | if (!clk->enable_reg) | ||
80 | return 0; | ||
81 | |||
78 | reg = __raw_readl(clk->enable_reg); | 82 | reg = __raw_readl(clk->enable_reg); |
79 | reg |= 3 << clk->enable_shift; | 83 | reg |= 3 << clk->enable_shift; |
80 | __raw_writel(reg, clk->enable_reg); | 84 | __raw_writel(reg, clk->enable_reg); |
@@ -82,133 +86,69 @@ static int _clk_enable(struct clk *clk) | |||
82 | return 0; | 86 | return 0; |
83 | } | 87 | } |
84 | 88 | ||
85 | static void _clk_disable(struct clk *clk) | 89 | static void cgr_disable(struct clk *clk) |
86 | { | 90 | { |
87 | u32 reg; | 91 | u32 reg; |
88 | 92 | ||
93 | if (!clk->enable_reg) | ||
94 | return; | ||
95 | |||
89 | reg = __raw_readl(clk->enable_reg); | 96 | reg = __raw_readl(clk->enable_reg); |
90 | reg &= ~(3 << clk->enable_shift); | 97 | reg &= ~(3 << clk->enable_shift); |
98 | |||
99 | /* special case for EMI clock */ | ||
100 | if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) | ||
101 | reg |= (1 << clk->enable_shift); | ||
102 | |||
91 | __raw_writel(reg, clk->enable_reg); | 103 | __raw_writel(reg, clk->enable_reg); |
92 | } | 104 | } |
93 | 105 | ||
94 | static void _clk_emi_disable(struct clk *clk) | 106 | static unsigned long pll_ref_get_rate(void) |
95 | { | 107 | { |
96 | u32 reg; | 108 | unsigned long ccmr; |
109 | unsigned int prcs; | ||
97 | 110 | ||
98 | reg = __raw_readl(clk->enable_reg); | 111 | ccmr = __raw_readl(MXC_CCM_CCMR); |
99 | reg &= ~(3 << clk->enable_shift); | 112 | prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; |
100 | reg |= (1 << clk->enable_shift); | 113 | if (prcs == 0x1) |
101 | __raw_writel(reg, clk->enable_reg); | 114 | return CKIL_CLK_FREQ * 1024; |
115 | else | ||
116 | return clk_get_rate(&ckih_clk); | ||
102 | } | 117 | } |
103 | 118 | ||
104 | static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) | 119 | static unsigned long usb_pll_get_rate(struct clk *clk) |
105 | { | 120 | { |
106 | u32 reg; | 121 | unsigned long reg; |
107 | signed long pd = 1; /* Pre-divider */ | ||
108 | signed long mfi; /* Multiplication Factor (Integer part) */ | ||
109 | signed long mfn; /* Multiplication Factor (Integer part) */ | ||
110 | signed long mfd; /* Multiplication Factor (Denominator Part) */ | ||
111 | signed long tmp; | ||
112 | u32 ref_freq = clk_get_rate(clk->parent); | ||
113 | 122 | ||
114 | while (((ref_freq / pd) * 10) > rate) | 123 | reg = __raw_readl(MXC_CCM_UPCTL); |
115 | pd++; | ||
116 | 124 | ||
117 | if ((ref_freq / pd) < PRE_DIV_MIN_FREQ) | 125 | return mxc_decode_pll(reg, pll_ref_get_rate()); |
118 | return -EINVAL; | 126 | } |
119 | 127 | ||
120 | /* the ref_freq/2 in the following is to round up */ | 128 | static unsigned long serial_pll_get_rate(struct clk *clk) |
121 | mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; | 129 | { |
122 | if (mfi < 5 || mfi > 15) | 130 | unsigned long reg; |
123 | return -EINVAL; | ||
124 | 131 | ||
125 | /* pick a mfd value that will work | 132 | reg = __raw_readl(MXC_CCM_SRPCTL); |
126 | * then solve for mfn */ | ||
127 | mfd = ref_freq / 50000; | ||
128 | |||
129 | /* | ||
130 | * pll_freq * pd * mfd | ||
131 | * mfn = -------------------- - (mfi * mfd) | ||
132 | * 2 * ref_freq | ||
133 | */ | ||
134 | /* the tmp/2 is for rounding */ | ||
135 | tmp = ref_freq / 10000; | ||
136 | mfn = | ||
137 | ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - | ||
138 | (mfi * mfd); | ||
139 | |||
140 | mfn = mfn & 0x3ff; | ||
141 | pd--; | ||
142 | mfd--; | ||
143 | |||
144 | /* Change the Pll value */ | ||
145 | reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) | | ||
146 | (mfn << MXC_CCM_PCTL_MFN_OFFSET) | | ||
147 | (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET); | ||
148 | |||
149 | if (clk == &mcu_pll_clk) | ||
150 | __raw_writel(reg, MXC_CCM_MPCTL); | ||
151 | else if (clk == &usb_pll_clk) | ||
152 | __raw_writel(reg, MXC_CCM_UPCTL); | ||
153 | else if (clk == &serial_pll_clk) | ||
154 | __raw_writel(reg, MXC_CCM_SRPCTL); | ||
155 | 133 | ||
156 | return 0; | 134 | return mxc_decode_pll(reg, pll_ref_get_rate()); |
157 | } | 135 | } |
158 | 136 | ||
159 | static unsigned long _clk_pll_get_rate(struct clk *clk) | 137 | static unsigned long mcu_pll_get_rate(struct clk *clk) |
160 | { | 138 | { |
161 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; | ||
162 | unsigned long reg, ccmr; | 139 | unsigned long reg, ccmr; |
163 | s64 temp; | ||
164 | unsigned int prcs; | ||
165 | 140 | ||
166 | ccmr = __raw_readl(MXC_CCM_CCMR); | 141 | ccmr = __raw_readl(MXC_CCM_CCMR); |
167 | prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; | ||
168 | if (prcs == 0x1) | ||
169 | ref_clk = CKIL_CLK_FREQ * 1024; | ||
170 | else | ||
171 | ref_clk = clk_get_rate(&ckih_clk); | ||
172 | |||
173 | if (clk == &mcu_pll_clk) { | ||
174 | if ((ccmr & MXC_CCM_CCMR_MPE) == 0) | ||
175 | return ref_clk; | ||
176 | if ((ccmr & MXC_CCM_CCMR_MDS) != 0) | ||
177 | return ref_clk; | ||
178 | reg = __raw_readl(MXC_CCM_MPCTL); | ||
179 | } else if (clk == &usb_pll_clk) | ||
180 | reg = __raw_readl(MXC_CCM_UPCTL); | ||
181 | else if (clk == &serial_pll_clk) | ||
182 | reg = __raw_readl(MXC_CCM_SRPCTL); | ||
183 | else { | ||
184 | BUG(); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET; | ||
189 | mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET; | ||
190 | mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET; | ||
191 | mfi = (mfi <= 5) ? 5 : mfi; | ||
192 | mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK; | ||
193 | 142 | ||
194 | if (mfn >= 0x200) { | 143 | if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) |
195 | mfn |= 0xFFFFFE00; | 144 | return clk_get_rate(&ckih_clk); |
196 | mfn_abs = -mfn; | ||
197 | } | ||
198 | |||
199 | ref_clk *= 2; | ||
200 | ref_clk /= pdf + 1; | ||
201 | 145 | ||
202 | temp = (u64) ref_clk * mfn_abs; | 146 | reg = __raw_readl(MXC_CCM_MPCTL); |
203 | do_div(temp, mfd + 1); | ||
204 | if (mfn < 0) | ||
205 | temp = -temp; | ||
206 | temp = (ref_clk * mfi) + temp; | ||
207 | 147 | ||
208 | return temp; | 148 | return mxc_decode_pll(reg, pll_ref_get_rate()); |
209 | } | 149 | } |
210 | 150 | ||
211 | static int _clk_usb_pll_enable(struct clk *clk) | 151 | static int usb_pll_enable(struct clk *clk) |
212 | { | 152 | { |
213 | u32 reg; | 153 | u32 reg; |
214 | 154 | ||
@@ -222,7 +162,7 @@ static int _clk_usb_pll_enable(struct clk *clk) | |||
222 | return 0; | 162 | return 0; |
223 | } | 163 | } |
224 | 164 | ||
225 | static void _clk_usb_pll_disable(struct clk *clk) | 165 | static void usb_pll_disable(struct clk *clk) |
226 | { | 166 | { |
227 | u32 reg; | 167 | u32 reg; |
228 | 168 | ||
@@ -231,7 +171,7 @@ static void _clk_usb_pll_disable(struct clk *clk) | |||
231 | __raw_writel(reg, MXC_CCM_CCMR); | 171 | __raw_writel(reg, MXC_CCM_CCMR); |
232 | } | 172 | } |
233 | 173 | ||
234 | static int _clk_serial_pll_enable(struct clk *clk) | 174 | static int serial_pll_enable(struct clk *clk) |
235 | { | 175 | { |
236 | u32 reg; | 176 | u32 reg; |
237 | 177 | ||
@@ -245,7 +185,7 @@ static int _clk_serial_pll_enable(struct clk *clk) | |||
245 | return 0; | 185 | return 0; |
246 | } | 186 | } |
247 | 187 | ||
248 | static void _clk_serial_pll_disable(struct clk *clk) | 188 | static void serial_pll_disable(struct clk *clk) |
249 | { | 189 | { |
250 | u32 reg; | 190 | u32 reg; |
251 | 191 | ||
@@ -258,7 +198,7 @@ static void _clk_serial_pll_disable(struct clk *clk) | |||
258 | #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) | 198 | #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) |
259 | #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) | 199 | #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) |
260 | 200 | ||
261 | static unsigned long _clk_mcu_main_get_rate(struct clk *clk) | 201 | static unsigned long mcu_main_get_rate(struct clk *clk) |
262 | { | 202 | { |
263 | u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); | 203 | u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); |
264 | 204 | ||
@@ -268,7 +208,7 @@ static unsigned long _clk_mcu_main_get_rate(struct clk *clk) | |||
268 | return clk_get_rate(&mcu_pll_clk); | 208 | return clk_get_rate(&mcu_pll_clk); |
269 | } | 209 | } |
270 | 210 | ||
271 | static unsigned long _clk_hclk_get_rate(struct clk *clk) | 211 | static unsigned long ahb_get_rate(struct clk *clk) |
272 | { | 212 | { |
273 | unsigned long max_pdf; | 213 | unsigned long max_pdf; |
274 | 214 | ||
@@ -277,7 +217,7 @@ static unsigned long _clk_hclk_get_rate(struct clk *clk) | |||
277 | return clk_get_rate(clk->parent) / (max_pdf + 1); | 217 | return clk_get_rate(clk->parent) / (max_pdf + 1); |
278 | } | 218 | } |
279 | 219 | ||
280 | static unsigned long _clk_ipg_get_rate(struct clk *clk) | 220 | static unsigned long ipg_get_rate(struct clk *clk) |
281 | { | 221 | { |
282 | unsigned long ipg_pdf; | 222 | unsigned long ipg_pdf; |
283 | 223 | ||
@@ -286,7 +226,7 @@ static unsigned long _clk_ipg_get_rate(struct clk *clk) | |||
286 | return clk_get_rate(clk->parent) / (ipg_pdf + 1); | 226 | return clk_get_rate(clk->parent) / (ipg_pdf + 1); |
287 | } | 227 | } |
288 | 228 | ||
289 | static unsigned long _clk_nfc_get_rate(struct clk *clk) | 229 | static unsigned long nfc_get_rate(struct clk *clk) |
290 | { | 230 | { |
291 | unsigned long nfc_pdf; | 231 | unsigned long nfc_pdf; |
292 | 232 | ||
@@ -295,7 +235,7 @@ static unsigned long _clk_nfc_get_rate(struct clk *clk) | |||
295 | return clk_get_rate(clk->parent) / (nfc_pdf + 1); | 235 | return clk_get_rate(clk->parent) / (nfc_pdf + 1); |
296 | } | 236 | } |
297 | 237 | ||
298 | static unsigned long _clk_hsp_get_rate(struct clk *clk) | 238 | static unsigned long hsp_get_rate(struct clk *clk) |
299 | { | 239 | { |
300 | unsigned long hsp_pdf; | 240 | unsigned long hsp_pdf; |
301 | 241 | ||
@@ -304,7 +244,7 @@ static unsigned long _clk_hsp_get_rate(struct clk *clk) | |||
304 | return clk_get_rate(clk->parent) / (hsp_pdf + 1); | 244 | return clk_get_rate(clk->parent) / (hsp_pdf + 1); |
305 | } | 245 | } |
306 | 246 | ||
307 | static unsigned long _clk_usb_get_rate(struct clk *clk) | 247 | static unsigned long usb_get_rate(struct clk *clk) |
308 | { | 248 | { |
309 | unsigned long usb_pdf, usb_prepdf; | 249 | unsigned long usb_pdf, usb_prepdf; |
310 | 250 | ||
@@ -315,7 +255,7 @@ static unsigned long _clk_usb_get_rate(struct clk *clk) | |||
315 | return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); | 255 | return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); |
316 | } | 256 | } |
317 | 257 | ||
318 | static unsigned long _clk_csi_get_rate(struct clk *clk) | 258 | static unsigned long csi_get_rate(struct clk *clk) |
319 | { | 259 | { |
320 | u32 reg, pre, post; | 260 | u32 reg, pre, post; |
321 | 261 | ||
@@ -329,7 +269,7 @@ static unsigned long _clk_csi_get_rate(struct clk *clk) | |||
329 | return clk_get_rate(clk->parent) / (pre * post); | 269 | return clk_get_rate(clk->parent) / (pre * post); |
330 | } | 270 | } |
331 | 271 | ||
332 | static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) | 272 | static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) |
333 | { | 273 | { |
334 | u32 pre, post, parent = clk_get_rate(clk->parent); | 274 | u32 pre, post, parent = clk_get_rate(clk->parent); |
335 | u32 div = parent / rate; | 275 | u32 div = parent / rate; |
@@ -342,7 +282,7 @@ static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) | |||
342 | return parent / (pre * post); | 282 | return parent / (pre * post); |
343 | } | 283 | } |
344 | 284 | ||
345 | static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) | 285 | static int csi_set_rate(struct clk *clk, unsigned long rate) |
346 | { | 286 | { |
347 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | 287 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); |
348 | 288 | ||
@@ -363,16 +303,7 @@ static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) | |||
363 | return 0; | 303 | return 0; |
364 | } | 304 | } |
365 | 305 | ||
366 | static unsigned long _clk_per_get_rate(struct clk *clk) | 306 | static unsigned long ssi1_get_rate(struct clk *clk) |
367 | { | ||
368 | unsigned long per_pdf; | ||
369 | |||
370 | per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK, | ||
371 | MXC_CCM_PDR0_PER_PODF_OFFSET); | ||
372 | return clk_get_rate(clk->parent) / (per_pdf + 1); | ||
373 | } | ||
374 | |||
375 | static unsigned long _clk_ssi1_get_rate(struct clk *clk) | ||
376 | { | 307 | { |
377 | unsigned long ssi1_pdf, ssi1_prepdf; | 308 | unsigned long ssi1_pdf, ssi1_prepdf; |
378 | 309 | ||
@@ -383,7 +314,7 @@ static unsigned long _clk_ssi1_get_rate(struct clk *clk) | |||
383 | return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); | 314 | return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); |
384 | } | 315 | } |
385 | 316 | ||
386 | static unsigned long _clk_ssi2_get_rate(struct clk *clk) | 317 | static unsigned long ssi2_get_rate(struct clk *clk) |
387 | { | 318 | { |
388 | unsigned long ssi2_pdf, ssi2_prepdf; | 319 | unsigned long ssi2_pdf, ssi2_prepdf; |
389 | 320 | ||
@@ -394,7 +325,7 @@ static unsigned long _clk_ssi2_get_rate(struct clk *clk) | |||
394 | return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); | 325 | return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); |
395 | } | 326 | } |
396 | 327 | ||
397 | static unsigned long _clk_firi_get_rate(struct clk *clk) | 328 | static unsigned long firi_get_rate(struct clk *clk) |
398 | { | 329 | { |
399 | unsigned long firi_pdf, firi_prepdf; | 330 | unsigned long firi_pdf, firi_prepdf; |
400 | 331 | ||
@@ -405,7 +336,7 @@ static unsigned long _clk_firi_get_rate(struct clk *clk) | |||
405 | return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); | 336 | return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); |
406 | } | 337 | } |
407 | 338 | ||
408 | static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) | 339 | static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) |
409 | { | 340 | { |
410 | u32 pre, post; | 341 | u32 pre, post; |
411 | u32 parent = clk_get_rate(clk->parent); | 342 | u32 parent = clk_get_rate(clk->parent); |
@@ -420,7 +351,7 @@ static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) | |||
420 | 351 | ||
421 | } | 352 | } |
422 | 353 | ||
423 | static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) | 354 | static int firi_set_rate(struct clk *clk, unsigned long rate) |
424 | { | 355 | { |
425 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); | 356 | u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); |
426 | 357 | ||
@@ -441,12 +372,12 @@ static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) | |||
441 | return 0; | 372 | return 0; |
442 | } | 373 | } |
443 | 374 | ||
444 | static unsigned long _clk_mbx_get_rate(struct clk *clk) | 375 | static unsigned long mbx_get_rate(struct clk *clk) |
445 | { | 376 | { |
446 | return clk_get_rate(clk->parent) / 2; | 377 | return clk_get_rate(clk->parent) / 2; |
447 | } | 378 | } |
448 | 379 | ||
449 | static unsigned long _clk_mstick1_get_rate(struct clk *clk) | 380 | static unsigned long mstick1_get_rate(struct clk *clk) |
450 | { | 381 | { |
451 | unsigned long msti_pdf; | 382 | unsigned long msti_pdf; |
452 | 383 | ||
@@ -455,7 +386,7 @@ static unsigned long _clk_mstick1_get_rate(struct clk *clk) | |||
455 | return clk_get_rate(clk->parent) / (msti_pdf + 1); | 386 | return clk_get_rate(clk->parent) / (msti_pdf + 1); |
456 | } | 387 | } |
457 | 388 | ||
458 | static unsigned long _clk_mstick2_get_rate(struct clk *clk) | 389 | static unsigned long mstick2_get_rate(struct clk *clk) |
459 | { | 390 | { |
460 | unsigned long msti_pdf; | 391 | unsigned long msti_pdf; |
461 | 392 | ||
@@ -472,661 +403,185 @@ static unsigned long clk_ckih_get_rate(struct clk *clk) | |||
472 | } | 403 | } |
473 | 404 | ||
474 | static struct clk ckih_clk = { | 405 | static struct clk ckih_clk = { |
475 | .name = "ckih", | ||
476 | .get_rate = clk_ckih_get_rate, | 406 | .get_rate = clk_ckih_get_rate, |
477 | }; | 407 | }; |
478 | 408 | ||
479 | static unsigned long clk_ckil_get_rate(struct clk *clk) | ||
480 | { | ||
481 | return CKIL_CLK_FREQ; | ||
482 | } | ||
483 | |||
484 | static struct clk ckil_clk = { | ||
485 | .name = "ckil", | ||
486 | .get_rate = clk_ckil_get_rate, | ||
487 | }; | ||
488 | |||
489 | static struct clk mcu_pll_clk = { | 409 | static struct clk mcu_pll_clk = { |
490 | .name = "mcu_pll", | ||
491 | .parent = &ckih_clk, | 410 | .parent = &ckih_clk, |
492 | .set_rate = _clk_pll_set_rate, | 411 | .get_rate = mcu_pll_get_rate, |
493 | .get_rate = _clk_pll_get_rate, | ||
494 | }; | 412 | }; |
495 | 413 | ||
496 | static struct clk mcu_main_clk = { | 414 | static struct clk mcu_main_clk = { |
497 | .name = "mcu_main_clk", | ||
498 | .parent = &mcu_pll_clk, | 415 | .parent = &mcu_pll_clk, |
499 | .get_rate = _clk_mcu_main_get_rate, | 416 | .get_rate = mcu_main_get_rate, |
500 | }; | 417 | }; |
501 | 418 | ||
502 | static struct clk serial_pll_clk = { | 419 | static struct clk serial_pll_clk = { |
503 | .name = "serial_pll", | ||
504 | .parent = &ckih_clk, | 420 | .parent = &ckih_clk, |
505 | .set_rate = _clk_pll_set_rate, | 421 | .get_rate = serial_pll_get_rate, |
506 | .get_rate = _clk_pll_get_rate, | 422 | .enable = serial_pll_enable, |
507 | .enable = _clk_serial_pll_enable, | 423 | .disable = serial_pll_disable, |
508 | .disable = _clk_serial_pll_disable, | ||
509 | }; | 424 | }; |
510 | 425 | ||
511 | static struct clk usb_pll_clk = { | 426 | static struct clk usb_pll_clk = { |
512 | .name = "usb_pll", | ||
513 | .parent = &ckih_clk, | 427 | .parent = &ckih_clk, |
514 | .set_rate = _clk_pll_set_rate, | 428 | .get_rate = usb_pll_get_rate, |
515 | .get_rate = _clk_pll_get_rate, | 429 | .enable = usb_pll_enable, |
516 | .enable = _clk_usb_pll_enable, | 430 | .disable = usb_pll_disable, |
517 | .disable = _clk_usb_pll_disable, | ||
518 | }; | 431 | }; |
519 | 432 | ||
520 | static struct clk ahb_clk = { | 433 | static struct clk ahb_clk = { |
521 | .name = "ahb_clk", | ||
522 | .parent = &mcu_main_clk, | 434 | .parent = &mcu_main_clk, |
523 | .get_rate = _clk_hclk_get_rate, | 435 | .get_rate = ahb_get_rate, |
524 | }; | 436 | }; |
525 | 437 | ||
526 | static struct clk per_clk = { | 438 | #define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ |
527 | .name = "per_clk", | 439 | static struct clk name = { \ |
528 | .parent = &usb_pll_clk, | 440 | .id = i, \ |
529 | .get_rate = _clk_per_get_rate, | 441 | .enable_reg = er, \ |
530 | }; | 442 | .enable_shift = es, \ |
531 | 443 | .get_rate = gr, \ | |
532 | static struct clk perclk_clk = { | 444 | .enable = cgr_enable, \ |
533 | .name = "perclk_clk", | 445 | .disable = cgr_disable, \ |
534 | .parent = &ipg_clk, | 446 | .secondary = s, \ |
535 | }; | 447 | .parent = p, \ |
536 | 448 | } | |
537 | static struct clk cspi_clk[] = { | ||
538 | { | ||
539 | .name = "cspi_clk", | ||
540 | .id = 0, | ||
541 | .parent = &ipg_clk, | ||
542 | .enable = _clk_enable, | ||
543 | .enable_reg = MXC_CCM_CGR2, | ||
544 | .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET, | ||
545 | .disable = _clk_disable,}, | ||
546 | { | ||
547 | .name = "cspi_clk", | ||
548 | .id = 1, | ||
549 | .parent = &ipg_clk, | ||
550 | .enable = _clk_enable, | ||
551 | .enable_reg = MXC_CCM_CGR2, | ||
552 | .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET, | ||
553 | .disable = _clk_disable,}, | ||
554 | { | ||
555 | .name = "cspi_clk", | ||
556 | .id = 2, | ||
557 | .parent = &ipg_clk, | ||
558 | .enable = _clk_enable, | ||
559 | .enable_reg = MXC_CCM_CGR0, | ||
560 | .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET, | ||
561 | .disable = _clk_disable,}, | ||
562 | }; | ||
563 | |||
564 | static struct clk ipg_clk = { | ||
565 | .name = "ipg_clk", | ||
566 | .parent = &ahb_clk, | ||
567 | .get_rate = _clk_ipg_get_rate, | ||
568 | }; | ||
569 | |||
570 | static struct clk emi_clk = { | ||
571 | .name = "emi_clk", | ||
572 | .parent = &ahb_clk, | ||
573 | .enable = _clk_enable, | ||
574 | .enable_reg = MXC_CCM_CGR2, | ||
575 | .enable_shift = MXC_CCM_CGR2_EMI_OFFSET, | ||
576 | .disable = _clk_emi_disable, | ||
577 | }; | ||
578 | |||
579 | static struct clk gpt_clk = { | ||
580 | .name = "gpt_clk", | ||
581 | .parent = &perclk_clk, | ||
582 | .enable = _clk_enable, | ||
583 | .enable_reg = MXC_CCM_CGR0, | ||
584 | .enable_shift = MXC_CCM_CGR0_GPT_OFFSET, | ||
585 | .disable = _clk_disable, | ||
586 | }; | ||
587 | |||
588 | static struct clk pwm_clk = { | ||
589 | .name = "pwm_clk", | ||
590 | .parent = &perclk_clk, | ||
591 | .enable = _clk_enable, | ||
592 | .enable_reg = MXC_CCM_CGR0, | ||
593 | .enable_shift = MXC_CCM_CGR1_PWM_OFFSET, | ||
594 | .disable = _clk_disable, | ||
595 | }; | ||
596 | |||
597 | static struct clk epit_clk[] = { | ||
598 | { | ||
599 | .name = "epit_clk", | ||
600 | .id = 0, | ||
601 | .parent = &perclk_clk, | ||
602 | .enable = _clk_enable, | ||
603 | .enable_reg = MXC_CCM_CGR0, | ||
604 | .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET, | ||
605 | .disable = _clk_disable,}, | ||
606 | { | ||
607 | .name = "epit_clk", | ||
608 | .id = 1, | ||
609 | .parent = &perclk_clk, | ||
610 | .enable = _clk_enable, | ||
611 | .enable_reg = MXC_CCM_CGR0, | ||
612 | .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET, | ||
613 | .disable = _clk_disable,}, | ||
614 | }; | ||
615 | |||
616 | static struct clk nfc_clk = { | ||
617 | .name = "nfc_clk", | ||
618 | .parent = &ahb_clk, | ||
619 | .get_rate = _clk_nfc_get_rate, | ||
620 | }; | ||
621 | |||
622 | static struct clk scc_clk = { | ||
623 | .name = "scc_clk", | ||
624 | .parent = &ipg_clk, | ||
625 | }; | ||
626 | |||
627 | static struct clk ipu_clk = { | ||
628 | .name = "ipu_clk", | ||
629 | .parent = &mcu_main_clk, | ||
630 | .get_rate = _clk_hsp_get_rate, | ||
631 | .enable = _clk_enable, | ||
632 | .enable_reg = MXC_CCM_CGR1, | ||
633 | .enable_shift = MXC_CCM_CGR1_IPU_OFFSET, | ||
634 | .disable = _clk_disable, | ||
635 | }; | ||
636 | |||
637 | static struct clk kpp_clk = { | ||
638 | .name = "kpp_clk", | ||
639 | .parent = &ipg_clk, | ||
640 | .enable = _clk_enable, | ||
641 | .enable_reg = MXC_CCM_CGR1, | ||
642 | .enable_shift = MXC_CCM_CGR1_KPP_OFFSET, | ||
643 | .disable = _clk_disable, | ||
644 | }; | ||
645 | |||
646 | static struct clk wdog_clk = { | ||
647 | .name = "wdog_clk", | ||
648 | .parent = &ipg_clk, | ||
649 | .enable = _clk_enable, | ||
650 | .enable_reg = MXC_CCM_CGR1, | ||
651 | .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET, | ||
652 | .disable = _clk_disable, | ||
653 | }; | ||
654 | static struct clk rtc_clk = { | ||
655 | .name = "rtc_clk", | ||
656 | .parent = &ipg_clk, | ||
657 | .enable = _clk_enable, | ||
658 | .enable_reg = MXC_CCM_CGR1, | ||
659 | .enable_shift = MXC_CCM_CGR1_RTC_OFFSET, | ||
660 | .disable = _clk_disable, | ||
661 | }; | ||
662 | |||
663 | static struct clk usb_clk[] = { | ||
664 | { | ||
665 | .name = "usb_clk", | ||
666 | .parent = &usb_pll_clk, | ||
667 | .get_rate = _clk_usb_get_rate,}, | ||
668 | { | ||
669 | .name = "usb_ahb_clk", | ||
670 | .parent = &ahb_clk, | ||
671 | .enable = _clk_enable, | ||
672 | .enable_reg = MXC_CCM_CGR1, | ||
673 | .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET, | ||
674 | .disable = _clk_disable,}, | ||
675 | }; | ||
676 | |||
677 | static struct clk csi_clk = { | ||
678 | .name = "csi_clk", | ||
679 | .parent = &serial_pll_clk, | ||
680 | .get_rate = _clk_csi_get_rate, | ||
681 | .round_rate = _clk_csi_round_rate, | ||
682 | .set_rate = _clk_csi_set_rate, | ||
683 | .enable = _clk_enable, | ||
684 | .enable_reg = MXC_CCM_CGR1, | ||
685 | .enable_shift = MXC_CCM_CGR1_CSI_OFFSET, | ||
686 | .disable = _clk_disable, | ||
687 | }; | ||
688 | |||
689 | static struct clk uart_clk[] = { | ||
690 | { | ||
691 | .name = "uart_clk", | ||
692 | .id = 0, | ||
693 | .parent = &perclk_clk, | ||
694 | .enable = _clk_enable, | ||
695 | .enable_reg = MXC_CCM_CGR0, | ||
696 | .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, | ||
697 | .disable = _clk_disable,}, | ||
698 | { | ||
699 | .name = "uart_clk", | ||
700 | .id = 1, | ||
701 | .parent = &perclk_clk, | ||
702 | .enable = _clk_enable, | ||
703 | .enable_reg = MXC_CCM_CGR0, | ||
704 | .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, | ||
705 | .disable = _clk_disable,}, | ||
706 | { | ||
707 | .name = "uart_clk", | ||
708 | .id = 2, | ||
709 | .parent = &perclk_clk, | ||
710 | .enable = _clk_enable, | ||
711 | .enable_reg = MXC_CCM_CGR1, | ||
712 | .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, | ||
713 | .disable = _clk_disable,}, | ||
714 | { | ||
715 | .name = "uart_clk", | ||
716 | .id = 3, | ||
717 | .parent = &perclk_clk, | ||
718 | .enable = _clk_enable, | ||
719 | .enable_reg = MXC_CCM_CGR1, | ||
720 | .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, | ||
721 | .disable = _clk_disable,}, | ||
722 | { | ||
723 | .name = "uart_clk", | ||
724 | .id = 4, | ||
725 | .parent = &perclk_clk, | ||
726 | .enable = _clk_enable, | ||
727 | .enable_reg = MXC_CCM_CGR1, | ||
728 | .enable_shift = MXC_CCM_CGR1_UART5_OFFSET, | ||
729 | .disable = _clk_disable,}, | ||
730 | }; | ||
731 | |||
732 | static struct clk i2c_clk[] = { | ||
733 | { | ||
734 | .name = "i2c_clk", | ||
735 | .id = 0, | ||
736 | .parent = &perclk_clk, | ||
737 | .enable = _clk_enable, | ||
738 | .enable_reg = MXC_CCM_CGR0, | ||
739 | .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET, | ||
740 | .disable = _clk_disable,}, | ||
741 | { | ||
742 | .name = "i2c_clk", | ||
743 | .id = 1, | ||
744 | .parent = &perclk_clk, | ||
745 | .enable = _clk_enable, | ||
746 | .enable_reg = MXC_CCM_CGR0, | ||
747 | .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET, | ||
748 | .disable = _clk_disable,}, | ||
749 | { | ||
750 | .name = "i2c_clk", | ||
751 | .id = 2, | ||
752 | .parent = &perclk_clk, | ||
753 | .enable = _clk_enable, | ||
754 | .enable_reg = MXC_CCM_CGR0, | ||
755 | .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET, | ||
756 | .disable = _clk_disable,}, | ||
757 | }; | ||
758 | |||
759 | static struct clk owire_clk = { | ||
760 | .name = "owire_clk", | ||
761 | .parent = &perclk_clk, | ||
762 | .enable_reg = MXC_CCM_CGR1, | ||
763 | .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, | ||
764 | .enable = _clk_enable, | ||
765 | .disable = _clk_disable, | ||
766 | }; | ||
767 | |||
768 | static struct clk sdhc_clk[] = { | ||
769 | { | ||
770 | .name = "sdhc_clk", | ||
771 | .id = 0, | ||
772 | .parent = &perclk_clk, | ||
773 | .enable = _clk_enable, | ||
774 | .enable_reg = MXC_CCM_CGR0, | ||
775 | .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET, | ||
776 | .disable = _clk_disable,}, | ||
777 | { | ||
778 | .name = "sdhc_clk", | ||
779 | .id = 1, | ||
780 | .parent = &perclk_clk, | ||
781 | .enable = _clk_enable, | ||
782 | .enable_reg = MXC_CCM_CGR0, | ||
783 | .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET, | ||
784 | .disable = _clk_disable,}, | ||
785 | }; | ||
786 | |||
787 | static struct clk ssi_clk[] = { | ||
788 | { | ||
789 | .name = "ssi_clk", | ||
790 | .parent = &serial_pll_clk, | ||
791 | .get_rate = _clk_ssi1_get_rate, | ||
792 | .enable = _clk_enable, | ||
793 | .enable_reg = MXC_CCM_CGR0, | ||
794 | .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET, | ||
795 | .disable = _clk_disable,}, | ||
796 | { | ||
797 | .name = "ssi_clk", | ||
798 | .id = 1, | ||
799 | .parent = &serial_pll_clk, | ||
800 | .get_rate = _clk_ssi2_get_rate, | ||
801 | .enable = _clk_enable, | ||
802 | .enable_reg = MXC_CCM_CGR2, | ||
803 | .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET, | ||
804 | .disable = _clk_disable,}, | ||
805 | }; | ||
806 | |||
807 | static struct clk firi_clk = { | ||
808 | .name = "firi_clk", | ||
809 | .parent = &usb_pll_clk, | ||
810 | .round_rate = _clk_firi_round_rate, | ||
811 | .set_rate = _clk_firi_set_rate, | ||
812 | .get_rate = _clk_firi_get_rate, | ||
813 | .enable = _clk_enable, | ||
814 | .enable_reg = MXC_CCM_CGR2, | ||
815 | .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET, | ||
816 | .disable = _clk_disable, | ||
817 | }; | ||
818 | |||
819 | static struct clk ata_clk = { | ||
820 | .name = "ata_clk", | ||
821 | .parent = &ipg_clk, | ||
822 | .enable = _clk_enable, | ||
823 | .enable_reg = MXC_CCM_CGR0, | ||
824 | .enable_shift = MXC_CCM_CGR0_ATA_OFFSET, | ||
825 | .disable = _clk_disable, | ||
826 | }; | ||
827 | |||
828 | static struct clk mbx_clk = { | ||
829 | .name = "mbx_clk", | ||
830 | .parent = &ahb_clk, | ||
831 | .enable = _clk_enable, | ||
832 | .enable_reg = MXC_CCM_CGR2, | ||
833 | .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, | ||
834 | .get_rate = _clk_mbx_get_rate, | ||
835 | }; | ||
836 | |||
837 | static struct clk vpu_clk = { | ||
838 | .name = "vpu_clk", | ||
839 | .parent = &ahb_clk, | ||
840 | .enable = _clk_enable, | ||
841 | .enable_reg = MXC_CCM_CGR2, | ||
842 | .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, | ||
843 | .get_rate = _clk_mbx_get_rate, | ||
844 | }; | ||
845 | |||
846 | static struct clk rtic_clk = { | ||
847 | .name = "rtic_clk", | ||
848 | .parent = &ahb_clk, | ||
849 | .enable = _clk_enable, | ||
850 | .enable_reg = MXC_CCM_CGR2, | ||
851 | .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET, | ||
852 | .disable = _clk_disable, | ||
853 | }; | ||
854 | |||
855 | static struct clk rng_clk = { | ||
856 | .name = "rng_clk", | ||
857 | .parent = &ipg_clk, | ||
858 | .enable = _clk_enable, | ||
859 | .enable_reg = MXC_CCM_CGR0, | ||
860 | .enable_shift = MXC_CCM_CGR0_RNG_OFFSET, | ||
861 | .disable = _clk_disable, | ||
862 | }; | ||
863 | |||
864 | static struct clk sdma_clk[] = { | ||
865 | { | ||
866 | .name = "sdma_ahb_clk", | ||
867 | .parent = &ahb_clk, | ||
868 | .enable = _clk_enable, | ||
869 | .enable_reg = MXC_CCM_CGR0, | ||
870 | .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET, | ||
871 | .disable = _clk_disable,}, | ||
872 | { | ||
873 | .name = "sdma_ipg_clk", | ||
874 | .parent = &ipg_clk,} | ||
875 | }; | ||
876 | |||
877 | static struct clk mpeg4_clk = { | ||
878 | .name = "mpeg4_clk", | ||
879 | .parent = &ahb_clk, | ||
880 | .enable = _clk_enable, | ||
881 | .enable_reg = MXC_CCM_CGR1, | ||
882 | .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, | ||
883 | .disable = _clk_disable, | ||
884 | }; | ||
885 | |||
886 | static struct clk vl2cc_clk = { | ||
887 | .name = "vl2cc_clk", | ||
888 | .parent = &ahb_clk, | ||
889 | .enable = _clk_enable, | ||
890 | .enable_reg = MXC_CCM_CGR1, | ||
891 | .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, | ||
892 | .disable = _clk_disable, | ||
893 | }; | ||
894 | |||
895 | static struct clk mstick_clk[] = { | ||
896 | { | ||
897 | .name = "mstick_clk", | ||
898 | .id = 0, | ||
899 | .parent = &usb_pll_clk, | ||
900 | .get_rate = _clk_mstick1_get_rate, | ||
901 | .enable = _clk_enable, | ||
902 | .enable_reg = MXC_CCM_CGR1, | ||
903 | .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET, | ||
904 | .disable = _clk_disable,}, | ||
905 | { | ||
906 | .name = "mstick_clk", | ||
907 | .id = 1, | ||
908 | .parent = &usb_pll_clk, | ||
909 | .get_rate = _clk_mstick2_get_rate, | ||
910 | .enable = _clk_enable, | ||
911 | .enable_reg = MXC_CCM_CGR1, | ||
912 | .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET, | ||
913 | .disable = _clk_disable,}, | ||
914 | }; | ||
915 | |||
916 | static struct clk iim_clk = { | ||
917 | .name = "iim_clk", | ||
918 | .parent = &ipg_clk, | ||
919 | .enable = _clk_enable, | ||
920 | .enable_reg = MXC_CCM_CGR0, | ||
921 | .enable_shift = MXC_CCM_CGR0_IIM_OFFSET, | ||
922 | .disable = _clk_disable, | ||
923 | }; | ||
924 | |||
925 | static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate) | ||
926 | { | ||
927 | u32 div, parent = clk_get_rate(clk->parent); | ||
928 | |||
929 | div = parent / rate; | ||
930 | if (parent % rate) | ||
931 | div++; | ||
932 | |||
933 | if (div > 8) | ||
934 | div = 16; | ||
935 | else if (div > 4) | ||
936 | div = 8; | ||
937 | else if (div > 2) | ||
938 | div = 4; | ||
939 | |||
940 | return parent / div; | ||
941 | } | ||
942 | |||
943 | static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate) | ||
944 | { | ||
945 | u32 reg, div, parent = clk_get_rate(clk->parent); | ||
946 | |||
947 | div = parent / rate; | ||
948 | |||
949 | if (div == 16) | ||
950 | div = 4; | ||
951 | else if (div == 8) | ||
952 | div = 3; | ||
953 | else if (div == 4) | ||
954 | div = 2; | ||
955 | else if (div == 2) | ||
956 | div = 1; | ||
957 | else if (div == 1) | ||
958 | div = 0; | ||
959 | else | ||
960 | return -EINVAL; | ||
961 | |||
962 | reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK; | ||
963 | reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET; | ||
964 | __raw_writel(reg, MXC_CCM_COSR); | ||
965 | |||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static unsigned long _clk_cko1_get_rate(struct clk *clk) | ||
970 | { | ||
971 | u32 div; | ||
972 | |||
973 | div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >> | ||
974 | MXC_CCM_COSR_CLKOUTDIV_OFFSET; | ||
975 | |||
976 | return clk_get_rate(clk->parent) / (1 << div); | ||
977 | } | ||
978 | |||
979 | static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent) | ||
980 | { | ||
981 | u32 reg; | ||
982 | |||
983 | reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK; | ||
984 | |||
985 | if (parent == &mcu_main_clk) | ||
986 | reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
987 | else if (parent == &ipg_clk) | ||
988 | reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
989 | else if (parent == &usb_pll_clk) | ||
990 | reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
991 | else if (parent == mcu_main_clk.parent) | ||
992 | reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
993 | else if (parent == &ahb_clk) | ||
994 | reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
995 | else if (parent == &serial_pll_clk) | ||
996 | reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
997 | else if (parent == &ckih_clk) | ||
998 | reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
999 | else if (parent == &emi_clk) | ||
1000 | reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
1001 | else if (parent == &ipu_clk) | ||
1002 | reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
1003 | else if (parent == &nfc_clk) | ||
1004 | reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
1005 | else if (parent == &uart_clk[0]) | ||
1006 | reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET; | ||
1007 | else | ||
1008 | return -EINVAL; | ||
1009 | |||
1010 | __raw_writel(reg, MXC_CCM_COSR); | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int _clk_cko1_enable(struct clk *clk) | ||
1016 | { | ||
1017 | u32 reg; | ||
1018 | |||
1019 | reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN; | ||
1020 | __raw_writel(reg, MXC_CCM_COSR); | ||
1021 | 449 | ||
1022 | return 0; | 450 | #define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ |
1023 | } | 451 | static struct clk name = { \ |
452 | .id = i, \ | ||
453 | .enable_reg = er, \ | ||
454 | .enable_shift = es, \ | ||
455 | .get_rate = getsetround##_get_rate, \ | ||
456 | .set_rate = getsetround##_set_rate, \ | ||
457 | .round_rate = getsetround##_round_rate, \ | ||
458 | .enable = cgr_enable, \ | ||
459 | .disable = cgr_disable, \ | ||
460 | .secondary = s, \ | ||
461 | .parent = p, \ | ||
462 | } | ||
1024 | 463 | ||
1025 | static void _clk_cko1_disable(struct clk *clk) | 464 | DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); |
465 | |||
466 | DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); | ||
467 | DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); | ||
468 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); | ||
469 | DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); | ||
470 | DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); | ||
471 | DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); | ||
472 | DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); | ||
473 | DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk); | ||
474 | DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); | ||
475 | DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); | ||
476 | DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); | ||
477 | DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); | ||
478 | DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); | ||
479 | DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); | ||
480 | DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); | ||
481 | DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); | ||
482 | |||
483 | DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); | ||
484 | DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); | ||
485 | DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); | ||
486 | DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &ahb_clk); | ||
487 | DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); | ||
488 | DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); | ||
489 | DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); | ||
490 | DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); | ||
491 | DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); | ||
492 | DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); | ||
493 | DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); | ||
494 | DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); | ||
495 | DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); | ||
496 | DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); | ||
497 | |||
498 | DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); | ||
499 | DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); | ||
500 | DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); | ||
501 | DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); | ||
502 | DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); | ||
503 | DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); | ||
504 | DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); | ||
505 | |||
506 | DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
507 | DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); | ||
508 | DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); | ||
509 | DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); | ||
510 | DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); | ||
511 | |||
512 | #define _REGISTER_CLOCK(d, n, c) \ | ||
513 | { \ | ||
514 | .dev_id = d, \ | ||
515 | .con_id = n, \ | ||
516 | .clk = &c, \ | ||
517 | }, | ||
518 | |||
519 | static struct clk_lookup lookups[] __initdata = { | ||
520 | _REGISTER_CLOCK(NULL, "emi", emi_clk) | ||
521 | _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) | ||
522 | _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) | ||
523 | _REGISTER_CLOCK(NULL, "cspi", cspi3_clk) | ||
524 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
525 | _REGISTER_CLOCK(NULL, "pwm", pwm_clk) | ||
526 | _REGISTER_CLOCK(NULL, "wdog", wdog_clk) | ||
527 | _REGISTER_CLOCK(NULL, "rtc", rtc_clk) | ||
528 | _REGISTER_CLOCK(NULL, "epit", epit1_clk) | ||
529 | _REGISTER_CLOCK(NULL, "epit", epit2_clk) | ||
530 | _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) | ||
531 | _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) | ||
532 | _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) | ||
533 | _REGISTER_CLOCK(NULL, "kpp", kpp_clk) | ||
534 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) | ||
535 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) | ||
536 | _REGISTER_CLOCK("mx3-camera.0", "csi", csi_clk) | ||
537 | _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) | ||
538 | _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) | ||
539 | _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) | ||
540 | _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) | ||
541 | _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) | ||
542 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
543 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
544 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) | ||
545 | _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) | ||
546 | _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) | ||
547 | _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) | ||
548 | _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) | ||
549 | _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) | ||
550 | _REGISTER_CLOCK(NULL, "firi", firi_clk) | ||
551 | _REGISTER_CLOCK(NULL, "ata", ata_clk) | ||
552 | _REGISTER_CLOCK(NULL, "rtic", rtic_clk) | ||
553 | _REGISTER_CLOCK(NULL, "rng", rng_clk) | ||
554 | _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1) | ||
555 | _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) | ||
556 | _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) | ||
557 | _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) | ||
558 | _REGISTER_CLOCK(NULL, "scc", scc_clk) | ||
559 | _REGISTER_CLOCK(NULL, "iim", iim_clk) | ||
560 | _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) | ||
561 | _REGISTER_CLOCK(NULL, "mbx", mbx_clk) | ||
562 | }; | ||
563 | |||
564 | int __init mx31_clocks_init(unsigned long fref) | ||
1026 | { | 565 | { |
1027 | u32 reg; | 566 | u32 reg; |
567 | int i; | ||
1028 | 568 | ||
1029 | reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN; | 569 | mxc_set_cpu_type(MXC_CPU_MX31); |
1030 | __raw_writel(reg, MXC_CCM_COSR); | ||
1031 | } | ||
1032 | |||
1033 | static struct clk cko1_clk = { | ||
1034 | .name = "cko1_clk", | ||
1035 | .get_rate = _clk_cko1_get_rate, | ||
1036 | .set_rate = _clk_cko1_set_rate, | ||
1037 | .round_rate = _clk_cko1_round_rate, | ||
1038 | .set_parent = _clk_cko1_set_parent, | ||
1039 | .enable = _clk_cko1_enable, | ||
1040 | .disable = _clk_cko1_disable, | ||
1041 | }; | ||
1042 | |||
1043 | static struct clk *mxc_clks[] = { | ||
1044 | &ckih_clk, | ||
1045 | &ckil_clk, | ||
1046 | &mcu_pll_clk, | ||
1047 | &usb_pll_clk, | ||
1048 | &serial_pll_clk, | ||
1049 | &mcu_main_clk, | ||
1050 | &ahb_clk, | ||
1051 | &per_clk, | ||
1052 | &perclk_clk, | ||
1053 | &cko1_clk, | ||
1054 | &emi_clk, | ||
1055 | &cspi_clk[0], | ||
1056 | &cspi_clk[1], | ||
1057 | &cspi_clk[2], | ||
1058 | &ipg_clk, | ||
1059 | &gpt_clk, | ||
1060 | &pwm_clk, | ||
1061 | &wdog_clk, | ||
1062 | &rtc_clk, | ||
1063 | &epit_clk[0], | ||
1064 | &epit_clk[1], | ||
1065 | &nfc_clk, | ||
1066 | &ipu_clk, | ||
1067 | &kpp_clk, | ||
1068 | &usb_clk[0], | ||
1069 | &usb_clk[1], | ||
1070 | &csi_clk, | ||
1071 | &uart_clk[0], | ||
1072 | &uart_clk[1], | ||
1073 | &uart_clk[2], | ||
1074 | &uart_clk[3], | ||
1075 | &uart_clk[4], | ||
1076 | &i2c_clk[0], | ||
1077 | &i2c_clk[1], | ||
1078 | &i2c_clk[2], | ||
1079 | &owire_clk, | ||
1080 | &sdhc_clk[0], | ||
1081 | &sdhc_clk[1], | ||
1082 | &ssi_clk[0], | ||
1083 | &ssi_clk[1], | ||
1084 | &firi_clk, | ||
1085 | &ata_clk, | ||
1086 | &rtic_clk, | ||
1087 | &rng_clk, | ||
1088 | &sdma_clk[0], | ||
1089 | &sdma_clk[1], | ||
1090 | &mstick_clk[0], | ||
1091 | &mstick_clk[1], | ||
1092 | &scc_clk, | ||
1093 | &iim_clk, | ||
1094 | }; | ||
1095 | |||
1096 | int __init mxc_clocks_init(unsigned long fref) | ||
1097 | { | ||
1098 | u32 reg; | ||
1099 | struct clk **clkp; | ||
1100 | 570 | ||
1101 | ckih_rate = fref; | 571 | ckih_rate = fref; |
1102 | 572 | ||
1103 | for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) | 573 | for (i = 0; i < ARRAY_SIZE(lookups); i++) |
1104 | clk_register(*clkp); | 574 | clkdev_add(&lookups[i]); |
1105 | |||
1106 | if (cpu_is_mx31()) { | ||
1107 | clk_register(&mpeg4_clk); | ||
1108 | clk_register(&mbx_clk); | ||
1109 | } else { | ||
1110 | clk_register(&vpu_clk); | ||
1111 | clk_register(&vl2cc_clk); | ||
1112 | } | ||
1113 | 575 | ||
1114 | /* Turn off all possible clocks */ | 576 | /* Turn off all possible clocks */ |
1115 | __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0); | 577 | __raw_writel((3 << 4), MXC_CCM_CGR0); |
1116 | __raw_writel(0, MXC_CCM_CGR1); | 578 | __raw_writel(0, MXC_CCM_CGR1); |
1117 | 579 | __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| | |
1118 | __raw_writel(MXC_CCM_CGR2_EMI_MASK | | ||
1119 | MXC_CCM_CGR2_IPMUX1_MASK | | ||
1120 | MXC_CCM_CGR2_IPMUX2_MASK | | ||
1121 | MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */ | ||
1122 | MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */ | ||
1123 | MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */ | ||
1124 | 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for | 580 | 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for |
1125 | MX32, but still required to be set */ | 581 | MX32, but still required to be set */ |
1126 | MXC_CCM_CGR2); | 582 | MXC_CCM_CGR2); |
1127 | 583 | ||
1128 | clk_disable(&cko1_clk); | 584 | usb_pll_disable(&usb_pll_clk); |
1129 | clk_disable(&usb_pll_clk); | ||
1130 | 585 | ||
1131 | pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); | 586 | pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); |
1132 | 587 | ||
@@ -1143,6 +598,8 @@ int __init mxc_clocks_init(unsigned long fref) | |||
1143 | __raw_writel(reg, MXC_CCM_PMCR1); | 598 | __raw_writel(reg, MXC_CCM_PMCR1); |
1144 | } | 599 | } |
1145 | 600 | ||
601 | mxc_timer_init(&ipg_clk); | ||
602 | |||
1146 | return 0; | 603 | return 0; |
1147 | } | 604 | } |
1148 | 605 | ||
diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h index 4a0e0ede23bb..adfa3627ad84 100644 --- a/arch/arm/mach-mx3/crm_regs.h +++ b/arch/arm/mach-mx3/crm_regs.h | |||
@@ -91,47 +91,6 @@ | |||
91 | #define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 | 91 | #define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 |
92 | #define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 | 92 | #define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 |
93 | 93 | ||
94 | #define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11) | ||
95 | #define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11) | ||
96 | #define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11) | ||
97 | #define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11) | ||
98 | #define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11) | ||
99 | #define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11) | ||
100 | #define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11) | ||
101 | #define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11) | ||
102 | |||
103 | #define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6) | ||
104 | #define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6) | ||
105 | #define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6) | ||
106 | #define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6) | ||
107 | |||
108 | #define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3) | ||
109 | #define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3) | ||
110 | #define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3) | ||
111 | #define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3) | ||
112 | #define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3) | ||
113 | #define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3) | ||
114 | #define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3) | ||
115 | #define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3) | ||
116 | |||
117 | #define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8) | ||
118 | #define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8) | ||
119 | #define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8) | ||
120 | #define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8) | ||
121 | #define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8) | ||
122 | #define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8) | ||
123 | #define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8) | ||
124 | #define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8) | ||
125 | |||
126 | #define MXC_CCM_PDR0_MCU_DIV_1 0x0 | ||
127 | #define MXC_CCM_PDR0_MCU_DIV_2 0x1 | ||
128 | #define MXC_CCM_PDR0_MCU_DIV_3 0x2 | ||
129 | #define MXC_CCM_PDR0_MCU_DIV_4 0x3 | ||
130 | #define MXC_CCM_PDR0_MCU_DIV_5 0x4 | ||
131 | #define MXC_CCM_PDR0_MCU_DIV_6 0x5 | ||
132 | #define MXC_CCM_PDR0_MCU_DIV_7 0x6 | ||
133 | #define MXC_CCM_PDR0_MCU_DIV_8 0x7 | ||
134 | |||
135 | #define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 | 94 | #define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 |
136 | #define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) | 95 | #define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) |
137 | #define MXC_CCM_PDR1_USB_PODF_OFFSET 27 | 96 | #define MXC_CCM_PDR1_USB_PODF_OFFSET 27 |
@@ -152,118 +111,6 @@ | |||
152 | /* Bit definitions for RCSR */ | 111 | /* Bit definitions for RCSR */ |
153 | #define MXC_CCM_RCSR_NF16B 0x80000000 | 112 | #define MXC_CCM_RCSR_NF16B 0x80000000 |
154 | 113 | ||
155 | /* Bit definitions for both MCU, USB and SR PLL control registers */ | ||
156 | #define MXC_CCM_PCTL_BRM 0x80000000 | ||
157 | #define MXC_CCM_PCTL_PD_OFFSET 26 | ||
158 | #define MXC_CCM_PCTL_PD_MASK (0xF << 26) | ||
159 | #define MXC_CCM_PCTL_MFD_OFFSET 16 | ||
160 | #define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16) | ||
161 | #define MXC_CCM_PCTL_MFI_OFFSET 10 | ||
162 | #define MXC_CCM_PCTL_MFI_MASK (0xF << 10) | ||
163 | #define MXC_CCM_PCTL_MFN_OFFSET 0 | ||
164 | #define MXC_CCM_PCTL_MFN_MASK 0x3FF | ||
165 | |||
166 | #define MXC_CCM_CGR0_SD_MMC1_OFFSET 0 | ||
167 | #define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0) | ||
168 | #define MXC_CCM_CGR0_SD_MMC2_OFFSET 2 | ||
169 | #define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2) | ||
170 | #define MXC_CCM_CGR0_GPT_OFFSET 4 | ||
171 | #define MXC_CCM_CGR0_GPT_MASK (0x3 << 4) | ||
172 | #define MXC_CCM_CGR0_EPIT1_OFFSET 6 | ||
173 | #define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6) | ||
174 | #define MXC_CCM_CGR0_EPIT2_OFFSET 8 | ||
175 | #define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8) | ||
176 | #define MXC_CCM_CGR0_IIM_OFFSET 10 | ||
177 | #define MXC_CCM_CGR0_IIM_MASK (0x3 << 10) | ||
178 | #define MXC_CCM_CGR0_ATA_OFFSET 12 | ||
179 | #define MXC_CCM_CGR0_ATA_MASK (0x3 << 12) | ||
180 | #define MXC_CCM_CGR0_SDMA_OFFSET 14 | ||
181 | #define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14) | ||
182 | #define MXC_CCM_CGR0_CSPI3_OFFSET 16 | ||
183 | #define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16) | ||
184 | #define MXC_CCM_CGR0_RNG_OFFSET 18 | ||
185 | #define MXC_CCM_CGR0_RNG_MASK (0x3 << 18) | ||
186 | #define MXC_CCM_CGR0_UART1_OFFSET 20 | ||
187 | #define MXC_CCM_CGR0_UART1_MASK (0x3 << 20) | ||
188 | #define MXC_CCM_CGR0_UART2_OFFSET 22 | ||
189 | #define MXC_CCM_CGR0_UART2_MASK (0x3 << 22) | ||
190 | #define MXC_CCM_CGR0_SSI1_OFFSET 24 | ||
191 | #define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24) | ||
192 | #define MXC_CCM_CGR0_I2C1_OFFSET 26 | ||
193 | #define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26) | ||
194 | #define MXC_CCM_CGR0_I2C2_OFFSET 28 | ||
195 | #define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28) | ||
196 | #define MXC_CCM_CGR0_I2C3_OFFSET 30 | ||
197 | #define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30) | ||
198 | |||
199 | #define MXC_CCM_CGR1_HANTRO_OFFSET 0 | ||
200 | #define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0) | ||
201 | #define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2 | ||
202 | #define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2) | ||
203 | #define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4 | ||
204 | #define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4) | ||
205 | #define MXC_CCM_CGR1_CSI_OFFSET 6 | ||
206 | #define MXC_CCM_CGR1_CSI_MASK (0x3 << 6) | ||
207 | #define MXC_CCM_CGR1_RTC_OFFSET 8 | ||
208 | #define MXC_CCM_CGR1_RTC_MASK (0x3 << 8) | ||
209 | #define MXC_CCM_CGR1_WDOG_OFFSET 10 | ||
210 | #define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10) | ||
211 | #define MXC_CCM_CGR1_PWM_OFFSET 12 | ||
212 | #define MXC_CCM_CGR1_PWM_MASK (0x3 << 12) | ||
213 | #define MXC_CCM_CGR1_SIM_OFFSET 14 | ||
214 | #define MXC_CCM_CGR1_SIM_MASK (0x3 << 14) | ||
215 | #define MXC_CCM_CGR1_ECT_OFFSET 16 | ||
216 | #define MXC_CCM_CGR1_ECT_MASK (0x3 << 16) | ||
217 | #define MXC_CCM_CGR1_USBOTG_OFFSET 18 | ||
218 | #define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18) | ||
219 | #define MXC_CCM_CGR1_KPP_OFFSET 20 | ||
220 | #define MXC_CCM_CGR1_KPP_MASK (0x3 << 20) | ||
221 | #define MXC_CCM_CGR1_IPU_OFFSET 22 | ||
222 | #define MXC_CCM_CGR1_IPU_MASK (0x3 << 22) | ||
223 | #define MXC_CCM_CGR1_UART3_OFFSET 24 | ||
224 | #define MXC_CCM_CGR1_UART3_MASK (0x3 << 24) | ||
225 | #define MXC_CCM_CGR1_UART4_OFFSET 26 | ||
226 | #define MXC_CCM_CGR1_UART4_MASK (0x3 << 26) | ||
227 | #define MXC_CCM_CGR1_UART5_OFFSET 28 | ||
228 | #define MXC_CCM_CGR1_UART5_MASK (0x3 << 28) | ||
229 | #define MXC_CCM_CGR1_OWIRE_OFFSET 30 | ||
230 | #define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30) | ||
231 | |||
232 | #define MXC_CCM_CGR2_SSI2_OFFSET 0 | ||
233 | #define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0) | ||
234 | #define MXC_CCM_CGR2_CSPI1_OFFSET 2 | ||
235 | #define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2) | ||
236 | #define MXC_CCM_CGR2_CSPI2_OFFSET 4 | ||
237 | #define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4) | ||
238 | #define MXC_CCM_CGR2_GACC_OFFSET 6 | ||
239 | #define MXC_CCM_CGR2_GACC_MASK (0x3 << 6) | ||
240 | #define MXC_CCM_CGR2_EMI_OFFSET 8 | ||
241 | #define MXC_CCM_CGR2_EMI_MASK (0x3 << 8) | ||
242 | #define MXC_CCM_CGR2_RTIC_OFFSET 10 | ||
243 | #define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10) | ||
244 | #define MXC_CCM_CGR2_FIRI_OFFSET 12 | ||
245 | #define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12) | ||
246 | #define MXC_CCM_CGR2_IPMUX1_OFFSET 14 | ||
247 | #define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14) | ||
248 | #define MXC_CCM_CGR2_IPMUX2_OFFSET 16 | ||
249 | #define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16) | ||
250 | |||
251 | /* These new CGR2 bits are added in MX32 */ | ||
252 | #define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18 | ||
253 | #define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18) | ||
254 | #define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20 | ||
255 | #define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20) | ||
256 | #define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22 | ||
257 | #define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22) | ||
258 | #define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24 | ||
259 | #define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24) | ||
260 | #define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25 | ||
261 | #define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25) | ||
262 | #define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26 | ||
263 | #define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26) | ||
264 | #define MXC_CCM_CGR2_APMENA_OFFSET 30 | ||
265 | #define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30) | ||
266 | |||
267 | /* | 114 | /* |
268 | * LTR0 register offsets | 115 | * LTR0 register offsets |
269 | */ | 116 | */ |
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index f8428800f286..380be0c9b213 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <mach/irqs.h> | 25 | #include <mach/irqs.h> |
26 | #include <mach/imx-uart.h> | 26 | #include <mach/imx-uart.h> |
27 | 27 | ||
28 | #include "devices.h" | ||
29 | |||
28 | static struct resource uart0[] = { | 30 | static struct resource uart0[] = { |
29 | { | 31 | { |
30 | .start = UART1_BASE_ADDR, | 32 | .start = UART1_BASE_ADDR, |
@@ -82,6 +84,7 @@ struct platform_device mxc_uart_device2 = { | |||
82 | .num_resources = ARRAY_SIZE(uart2), | 84 | .num_resources = ARRAY_SIZE(uart2), |
83 | }; | 85 | }; |
84 | 86 | ||
87 | #ifdef CONFIG_ARCH_MX31 | ||
85 | static struct resource uart3[] = { | 88 | static struct resource uart3[] = { |
86 | { | 89 | { |
87 | .start = UART4_BASE_ADDR, | 90 | .start = UART4_BASE_ADDR, |
@@ -119,6 +122,7 @@ struct platform_device mxc_uart_device4 = { | |||
119 | .resource = uart4, | 122 | .resource = uart4, |
120 | .num_resources = ARRAY_SIZE(uart4), | 123 | .num_resources = ARRAY_SIZE(uart4), |
121 | }; | 124 | }; |
125 | #endif /* CONFIG_ARCH_MX31 */ | ||
122 | 126 | ||
123 | /* GPIO port description */ | 127 | /* GPIO port description */ |
124 | static struct mxc_gpio_port imx_gpio_ports[] = { | 128 | static struct mxc_gpio_port imx_gpio_ports[] = { |
@@ -164,8 +168,8 @@ struct platform_device mxc_w1_master_device = { | |||
164 | 168 | ||
165 | static struct resource mxc_nand_resources[] = { | 169 | static struct resource mxc_nand_resources[] = { |
166 | { | 170 | { |
167 | .start = NFC_BASE_ADDR, | 171 | .start = 0, /* runtime dependent */ |
168 | .end = NFC_BASE_ADDR + 0xfff, | 172 | .end = 0, |
169 | .flags = IORESOURCE_MEM | 173 | .flags = IORESOURCE_MEM |
170 | }, { | 174 | }, { |
171 | .start = MXC_INT_NANDFC, | 175 | .start = MXC_INT_NANDFC, |
@@ -180,3 +184,188 @@ struct platform_device mxc_nand_device = { | |||
180 | .num_resources = ARRAY_SIZE(mxc_nand_resources), | 184 | .num_resources = ARRAY_SIZE(mxc_nand_resources), |
181 | .resource = mxc_nand_resources, | 185 | .resource = mxc_nand_resources, |
182 | }; | 186 | }; |
187 | |||
188 | static struct resource mxc_i2c0_resources[] = { | ||
189 | { | ||
190 | .start = I2C_BASE_ADDR, | ||
191 | .end = I2C_BASE_ADDR + SZ_4K - 1, | ||
192 | .flags = IORESOURCE_MEM, | ||
193 | }, | ||
194 | { | ||
195 | .start = MXC_INT_I2C, | ||
196 | .end = MXC_INT_I2C, | ||
197 | .flags = IORESOURCE_IRQ, | ||
198 | }, | ||
199 | }; | ||
200 | |||
201 | struct platform_device mxc_i2c_device0 = { | ||
202 | .name = "imx-i2c", | ||
203 | .id = 0, | ||
204 | .num_resources = ARRAY_SIZE(mxc_i2c0_resources), | ||
205 | .resource = mxc_i2c0_resources, | ||
206 | }; | ||
207 | |||
208 | static struct resource mxc_i2c1_resources[] = { | ||
209 | { | ||
210 | .start = I2C2_BASE_ADDR, | ||
211 | .end = I2C2_BASE_ADDR + SZ_4K - 1, | ||
212 | .flags = IORESOURCE_MEM, | ||
213 | }, | ||
214 | { | ||
215 | .start = MXC_INT_I2C2, | ||
216 | .end = MXC_INT_I2C2, | ||
217 | .flags = IORESOURCE_IRQ, | ||
218 | }, | ||
219 | }; | ||
220 | |||
221 | struct platform_device mxc_i2c_device1 = { | ||
222 | .name = "imx-i2c", | ||
223 | .id = 1, | ||
224 | .num_resources = ARRAY_SIZE(mxc_i2c1_resources), | ||
225 | .resource = mxc_i2c1_resources, | ||
226 | }; | ||
227 | |||
228 | static struct resource mxc_i2c2_resources[] = { | ||
229 | { | ||
230 | .start = I2C3_BASE_ADDR, | ||
231 | .end = I2C3_BASE_ADDR + SZ_4K - 1, | ||
232 | .flags = IORESOURCE_MEM, | ||
233 | }, | ||
234 | { | ||
235 | .start = MXC_INT_I2C3, | ||
236 | .end = MXC_INT_I2C3, | ||
237 | .flags = IORESOURCE_IRQ, | ||
238 | }, | ||
239 | }; | ||
240 | |||
241 | struct platform_device mxc_i2c_device2 = { | ||
242 | .name = "imx-i2c", | ||
243 | .id = 2, | ||
244 | .num_resources = ARRAY_SIZE(mxc_i2c2_resources), | ||
245 | .resource = mxc_i2c2_resources, | ||
246 | }; | ||
247 | |||
248 | #ifdef CONFIG_ARCH_MX31 | ||
249 | static struct resource mxcsdhc0_resources[] = { | ||
250 | { | ||
251 | .start = MMC_SDHC1_BASE_ADDR, | ||
252 | .end = MMC_SDHC1_BASE_ADDR + SZ_16K - 1, | ||
253 | .flags = IORESOURCE_MEM, | ||
254 | }, { | ||
255 | .start = MXC_INT_MMC_SDHC1, | ||
256 | .end = MXC_INT_MMC_SDHC1, | ||
257 | .flags = IORESOURCE_IRQ, | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | static struct resource mxcsdhc1_resources[] = { | ||
262 | { | ||
263 | .start = MMC_SDHC2_BASE_ADDR, | ||
264 | .end = MMC_SDHC2_BASE_ADDR + SZ_16K - 1, | ||
265 | .flags = IORESOURCE_MEM, | ||
266 | }, { | ||
267 | .start = MXC_INT_MMC_SDHC2, | ||
268 | .end = MXC_INT_MMC_SDHC2, | ||
269 | .flags = IORESOURCE_IRQ, | ||
270 | }, | ||
271 | }; | ||
272 | |||
273 | struct platform_device mxcsdhc_device0 = { | ||
274 | .name = "mxc-mmc", | ||
275 | .id = 0, | ||
276 | .num_resources = ARRAY_SIZE(mxcsdhc0_resources), | ||
277 | .resource = mxcsdhc0_resources, | ||
278 | }; | ||
279 | |||
280 | struct platform_device mxcsdhc_device1 = { | ||
281 | .name = "mxc-mmc", | ||
282 | .id = 1, | ||
283 | .num_resources = ARRAY_SIZE(mxcsdhc1_resources), | ||
284 | .resource = mxcsdhc1_resources, | ||
285 | }; | ||
286 | #endif /* CONFIG_ARCH_MX31 */ | ||
287 | |||
288 | /* i.MX31 Image Processing Unit */ | ||
289 | |||
290 | /* The resource order is important! */ | ||
291 | static struct resource mx3_ipu_rsrc[] = { | ||
292 | { | ||
293 | .start = IPU_CTRL_BASE_ADDR, | ||
294 | .end = IPU_CTRL_BASE_ADDR + 0x5F, | ||
295 | .flags = IORESOURCE_MEM, | ||
296 | }, { | ||
297 | .start = IPU_CTRL_BASE_ADDR + 0x88, | ||
298 | .end = IPU_CTRL_BASE_ADDR + 0xB3, | ||
299 | .flags = IORESOURCE_MEM, | ||
300 | }, { | ||
301 | .start = MXC_INT_IPU_SYN, | ||
302 | .end = MXC_INT_IPU_SYN, | ||
303 | .flags = IORESOURCE_IRQ, | ||
304 | }, { | ||
305 | .start = MXC_INT_IPU_ERR, | ||
306 | .end = MXC_INT_IPU_ERR, | ||
307 | .flags = IORESOURCE_IRQ, | ||
308 | }, | ||
309 | }; | ||
310 | |||
311 | struct platform_device mx3_ipu = { | ||
312 | .name = "ipu-core", | ||
313 | .id = -1, | ||
314 | .num_resources = ARRAY_SIZE(mx3_ipu_rsrc), | ||
315 | .resource = mx3_ipu_rsrc, | ||
316 | }; | ||
317 | |||
318 | static struct resource fb_resources[] = { | ||
319 | { | ||
320 | .start = IPU_CTRL_BASE_ADDR + 0xB4, | ||
321 | .end = IPU_CTRL_BASE_ADDR + 0x1BF, | ||
322 | .flags = IORESOURCE_MEM, | ||
323 | }, | ||
324 | }; | ||
325 | |||
326 | struct platform_device mx3_fb = { | ||
327 | .name = "mx3_sdc_fb", | ||
328 | .id = -1, | ||
329 | .num_resources = ARRAY_SIZE(fb_resources), | ||
330 | .resource = fb_resources, | ||
331 | .dev = { | ||
332 | .coherent_dma_mask = 0xffffffff, | ||
333 | }, | ||
334 | }; | ||
335 | |||
336 | #ifdef CONFIG_ARCH_MX35 | ||
337 | static struct resource mxc_fec_resources[] = { | ||
338 | { | ||
339 | .start = MXC_FEC_BASE_ADDR, | ||
340 | .end = MXC_FEC_BASE_ADDR + 0xfff, | ||
341 | .flags = IORESOURCE_MEM | ||
342 | }, { | ||
343 | .start = MXC_INT_FEC, | ||
344 | .end = MXC_INT_FEC, | ||
345 | .flags = IORESOURCE_IRQ | ||
346 | }, | ||
347 | }; | ||
348 | |||
349 | struct platform_device mxc_fec_device = { | ||
350 | .name = "fec", | ||
351 | .id = 0, | ||
352 | .num_resources = ARRAY_SIZE(mxc_fec_resources), | ||
353 | .resource = mxc_fec_resources, | ||
354 | }; | ||
355 | #endif | ||
356 | |||
357 | static int mx3_devices_init(void) | ||
358 | { | ||
359 | if (cpu_is_mx31()) { | ||
360 | mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR; | ||
361 | mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff; | ||
362 | } | ||
363 | if (cpu_is_mx35()) { | ||
364 | mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR; | ||
365 | mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0xfff; | ||
366 | } | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | subsys_initcall(mx3_devices_init); | ||
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index 9949ef4e0694..88c04b296fab 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h | |||
@@ -6,3 +6,11 @@ extern struct platform_device mxc_uart_device3; | |||
6 | extern struct platform_device mxc_uart_device4; | 6 | extern struct platform_device mxc_uart_device4; |
7 | extern struct platform_device mxc_w1_master_device; | 7 | extern struct platform_device mxc_w1_master_device; |
8 | extern struct platform_device mxc_nand_device; | 8 | extern struct platform_device mxc_nand_device; |
9 | extern struct platform_device mxc_i2c_device0; | ||
10 | extern struct platform_device mxc_i2c_device1; | ||
11 | extern struct platform_device mxc_i2c_device2; | ||
12 | extern struct platform_device mx3_ipu; | ||
13 | extern struct platform_device mx3_fb; | ||
14 | extern struct platform_device mxc_fec_device; | ||
15 | extern struct platform_device mxcsdhc_device0; | ||
16 | extern struct platform_device mxcsdhc_device1; | ||
diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c index 7a5088b519a8..40ffc5a664d9 100644 --- a/arch/arm/mach-mx3/iomux.c +++ b/arch/arm/mach-mx3/iomux.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. | 2 | * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. |
3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> | 3 | * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de> |
4 | * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License | 7 | * modify it under the terms of the GNU General Public License |
@@ -21,6 +22,7 @@ | |||
21 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
22 | #include <linux/io.h> | 23 | #include <linux/io.h> |
23 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/kernel.h> | ||
24 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
25 | #include <mach/gpio.h> | 27 | #include <mach/gpio.h> |
26 | #include <mach/iomux-mx3.h> | 28 | #include <mach/iomux-mx3.h> |
@@ -38,6 +40,8 @@ | |||
38 | static DEFINE_SPINLOCK(gpio_mux_lock); | 40 | static DEFINE_SPINLOCK(gpio_mux_lock); |
39 | 41 | ||
40 | #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) | 42 | #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) |
43 | |||
44 | unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; | ||
41 | /* | 45 | /* |
42 | * set the mode for a IOMUX pin. | 46 | * set the mode for a IOMUX pin. |
43 | */ | 47 | */ |
@@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode) | |||
50 | field = pin_mode & 0x3; | 54 | field = pin_mode & 0x3; |
51 | mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; | 55 | mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; |
52 | 56 | ||
53 | pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n", | ||
54 | __func__, (pin_mode & IOMUX_REG_MASK), field, mode); | ||
55 | |||
56 | spin_lock(&gpio_mux_lock); | 57 | spin_lock(&gpio_mux_lock); |
57 | 58 | ||
58 | l = __raw_readl(reg); | 59 | l = __raw_readl(reg); |
@@ -93,6 +94,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) | |||
93 | EXPORT_SYMBOL(mxc_iomux_set_pad); | 94 | EXPORT_SYMBOL(mxc_iomux_set_pad); |
94 | 95 | ||
95 | /* | 96 | /* |
97 | * setups a single pin: | ||
98 | * - reserves the pin so that it is not claimed by another driver | ||
99 | * - setups the iomux according to the configuration | ||
100 | * - if the pin is configured as a GPIO, we claim it through kernel gpiolib | ||
101 | */ | ||
102 | int mxc_iomux_setup_pin(const unsigned int pin, const char *label) | ||
103 | { | ||
104 | unsigned pad = pin & IOMUX_PADNUM_MASK; | ||
105 | unsigned gpio; | ||
106 | |||
107 | if (pad >= (PIN_MAX + 1)) { | ||
108 | printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n", | ||
109 | pad, label ? label : "?"); | ||
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | if (test_and_set_bit(pad, mxc_pin_alloc_map)) { | ||
114 | printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", | ||
115 | pad, label ? label : "?"); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | mxc_iomux_mode(pin); | ||
119 | |||
120 | /* if we have a gpio, we can allocate it */ | ||
121 | gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT; | ||
122 | if (gpio < (GPIO_PORT_MAX + 1) * 32) | ||
123 | if (gpio_request(gpio, label)) | ||
124 | return -EINVAL; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | EXPORT_SYMBOL(mxc_iomux_setup_pin); | ||
129 | |||
130 | int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, | ||
131 | const char *label) | ||
132 | { | ||
133 | unsigned int *p = pin_list; | ||
134 | int i; | ||
135 | int ret = -EINVAL; | ||
136 | |||
137 | for (i = 0; i < count; i++) { | ||
138 | if (mxc_iomux_setup_pin(*p, label)) | ||
139 | goto setup_error; | ||
140 | p++; | ||
141 | } | ||
142 | return 0; | ||
143 | |||
144 | setup_error: | ||
145 | mxc_iomux_release_multiple_pins(pin_list, i); | ||
146 | return ret; | ||
147 | } | ||
148 | EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins); | ||
149 | |||
150 | void mxc_iomux_release_pin(const unsigned int pin) | ||
151 | { | ||
152 | unsigned pad = pin & IOMUX_PADNUM_MASK; | ||
153 | unsigned gpio; | ||
154 | |||
155 | if (pad < (PIN_MAX + 1)) | ||
156 | clear_bit(pad, mxc_pin_alloc_map); | ||
157 | |||
158 | gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT; | ||
159 | if (gpio < (GPIO_PORT_MAX + 1) * 32) | ||
160 | gpio_free(gpio); | ||
161 | } | ||
162 | EXPORT_SYMBOL(mxc_iomux_release_pin); | ||
163 | |||
164 | void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count) | ||
165 | { | ||
166 | unsigned int *p = pin_list; | ||
167 | int i; | ||
168 | |||
169 | for (i = 0; i < count; i++) { | ||
170 | mxc_iomux_release_pin(*p); | ||
171 | p++; | ||
172 | } | ||
173 | } | ||
174 | EXPORT_SYMBOL(mxc_iomux_release_multiple_pins); | ||
175 | |||
176 | /* | ||
96 | * This function enables/disables the general purpose function for a particular | 177 | * This function enables/disables the general purpose function for a particular |
97 | * signal. | 178 | * signal. |
98 | */ | 179 | */ |
@@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) | |||
111 | spin_unlock(&gpio_mux_lock); | 192 | spin_unlock(&gpio_mux_lock); |
112 | } | 193 | } |
113 | EXPORT_SYMBOL(mxc_iomux_set_gpr); | 194 | EXPORT_SYMBOL(mxc_iomux_set_gpr); |
114 | |||
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c index 0589b5cd33c7..9e1459cb4b74 100644 --- a/arch/arm/mach-mx3/mm.c +++ b/arch/arm/mach-mx3/mm.c | |||
@@ -22,10 +22,14 @@ | |||
22 | 22 | ||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <mach/hardware.h> | 25 | #include <linux/err.h> |
26 | |||
26 | #include <asm/pgtable.h> | 27 | #include <asm/pgtable.h> |
27 | #include <asm/mach/map.h> | 28 | #include <asm/mach/map.h> |
29 | #include <asm/hardware/cache-l2x0.h> | ||
30 | |||
28 | #include <mach/common.h> | 31 | #include <mach/common.h> |
32 | #include <mach/hardware.h> | ||
29 | 33 | ||
30 | /*! | 34 | /*! |
31 | * @file mm.c | 35 | * @file mm.c |
@@ -50,6 +54,16 @@ static struct map_desc mxc_io_desc[] __initdata = { | |||
50 | .pfn = __phys_to_pfn(AVIC_BASE_ADDR), | 54 | .pfn = __phys_to_pfn(AVIC_BASE_ADDR), |
51 | .length = AVIC_SIZE, | 55 | .length = AVIC_SIZE, |
52 | .type = MT_DEVICE_NONSHARED | 56 | .type = MT_DEVICE_NONSHARED |
57 | }, { | ||
58 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
59 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
60 | .length = AIPS1_SIZE, | ||
61 | .type = MT_DEVICE_NONSHARED | ||
62 | }, { | ||
63 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
64 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
65 | .length = AIPS2_SIZE, | ||
66 | .type = MT_DEVICE_NONSHARED | ||
53 | }, | 67 | }, |
54 | }; | 68 | }; |
55 | 69 | ||
@@ -62,3 +76,24 @@ void __init mxc_map_io(void) | |||
62 | { | 76 | { |
63 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); | 77 | iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); |
64 | } | 78 | } |
79 | |||
80 | #ifdef CONFIG_CACHE_L2X0 | ||
81 | static int mxc_init_l2x0(void) | ||
82 | { | ||
83 | void __iomem *l2x0_base; | ||
84 | |||
85 | l2x0_base = ioremap(L2CC_BASE_ADDR, 4096); | ||
86 | if (IS_ERR(l2x0_base)) { | ||
87 | printk(KERN_ERR "remapping L2 cache area failed with %ld\n", | ||
88 | PTR_ERR(l2x0_base)); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | l2x0_init(l2x0_base, 0x00030024, 0x00000000); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | arch_initcall(mxc_init_l2x0); | ||
98 | #endif | ||
99 | |||
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index f902a7c37c31..83e5e8e1276f 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c | |||
@@ -22,6 +22,8 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <linux/serial_8250.h> | 24 | #include <linux/serial_8250.h> |
25 | #include <linux/gpio.h> | ||
26 | #include <linux/i2c.h> | ||
25 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
26 | 28 | ||
27 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
@@ -35,6 +37,12 @@ | |||
35 | #include <mach/imx-uart.h> | 37 | #include <mach/imx-uart.h> |
36 | #include <mach/iomux-mx3.h> | 38 | #include <mach/iomux-mx3.h> |
37 | 39 | ||
40 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
41 | #include <linux/mfd/wm8350/audio.h> | ||
42 | #include <linux/mfd/wm8350/core.h> | ||
43 | #include <linux/mfd/wm8350/pmic.h> | ||
44 | #endif | ||
45 | |||
38 | #include "devices.h" | 46 | #include "devices.h" |
39 | 47 | ||
40 | /*! | 48 | /*! |
@@ -94,13 +102,16 @@ static struct imxuart_platform_data uart_pdata = { | |||
94 | .flags = IMXUART_HAVE_RTSCTS, | 102 | .flags = IMXUART_HAVE_RTSCTS, |
95 | }; | 103 | }; |
96 | 104 | ||
105 | static int uart_pins[] = { | ||
106 | MX31_PIN_CTS1__CTS1, | ||
107 | MX31_PIN_RTS1__RTS1, | ||
108 | MX31_PIN_TXD1__TXD1, | ||
109 | MX31_PIN_RXD1__RXD1 | ||
110 | }; | ||
111 | |||
97 | static inline void mxc_init_imx_uart(void) | 112 | static inline void mxc_init_imx_uart(void) |
98 | { | 113 | { |
99 | mxc_iomux_mode(MX31_PIN_CTS1__CTS1); | 114 | mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0"); |
100 | mxc_iomux_mode(MX31_PIN_RTS1__RTS1); | ||
101 | mxc_iomux_mode(MX31_PIN_TXD1__TXD1); | ||
102 | mxc_iomux_mode(MX31_PIN_RXD1__RXD1); | ||
103 | |||
104 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 115 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
105 | } | 116 | } |
106 | #else /* !SERIAL_IMX */ | 117 | #else /* !SERIAL_IMX */ |
@@ -176,7 +187,7 @@ static void __init mx31ads_init_expio(void) | |||
176 | /* | 187 | /* |
177 | * Configure INT line as GPIO input | 188 | * Configure INT line as GPIO input |
178 | */ | 189 | */ |
179 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO)); | 190 | mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); |
180 | 191 | ||
181 | /* disable the interrupt and clear the status */ | 192 | /* disable the interrupt and clear the status */ |
182 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); | 193 | __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); |
@@ -191,26 +202,301 @@ static void __init mx31ads_init_expio(void) | |||
191 | set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); | 202 | set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler); |
192 | } | 203 | } |
193 | 204 | ||
205 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
206 | /* This section defines setup for the Wolfson Microelectronics | ||
207 | * 1133-EV1 PMU/audio board. When other PMU boards are supported the | ||
208 | * regulator definitions may be shared with them, but for now they can | ||
209 | * only be used with this board so would generate warnings about | ||
210 | * unused statics and some of the configuration is specific to this | ||
211 | * module. | ||
212 | */ | ||
213 | |||
214 | /* CPU */ | ||
215 | static struct regulator_consumer_supply sw1a_consumers[] = { | ||
216 | { | ||
217 | .supply = "cpu_vcc", | ||
218 | } | ||
219 | }; | ||
220 | |||
221 | static struct regulator_init_data sw1a_data = { | ||
222 | .constraints = { | ||
223 | .name = "SW1A", | ||
224 | .min_uV = 1275000, | ||
225 | .max_uV = 1600000, | ||
226 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
227 | REGULATOR_CHANGE_MODE, | ||
228 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
229 | REGULATOR_MODE_FAST, | ||
230 | .state_mem = { | ||
231 | .uV = 1400000, | ||
232 | .mode = REGULATOR_MODE_NORMAL, | ||
233 | .enabled = 1, | ||
234 | }, | ||
235 | .initial_state = PM_SUSPEND_MEM, | ||
236 | .always_on = 1, | ||
237 | .boot_on = 1, | ||
238 | }, | ||
239 | .num_consumer_supplies = ARRAY_SIZE(sw1a_consumers), | ||
240 | .consumer_supplies = sw1a_consumers, | ||
241 | }; | ||
242 | |||
243 | /* System IO - High */ | ||
244 | static struct regulator_init_data viohi_data = { | ||
245 | .constraints = { | ||
246 | .name = "VIOHO", | ||
247 | .min_uV = 2800000, | ||
248 | .max_uV = 2800000, | ||
249 | .state_mem = { | ||
250 | .uV = 2800000, | ||
251 | .mode = REGULATOR_MODE_NORMAL, | ||
252 | .enabled = 1, | ||
253 | }, | ||
254 | .initial_state = PM_SUSPEND_MEM, | ||
255 | .always_on = 1, | ||
256 | .boot_on = 1, | ||
257 | }, | ||
258 | }; | ||
259 | |||
260 | /* System IO - Low */ | ||
261 | static struct regulator_init_data violo_data = { | ||
262 | .constraints = { | ||
263 | .name = "VIOLO", | ||
264 | .min_uV = 1800000, | ||
265 | .max_uV = 1800000, | ||
266 | .state_mem = { | ||
267 | .uV = 1800000, | ||
268 | .mode = REGULATOR_MODE_NORMAL, | ||
269 | .enabled = 1, | ||
270 | }, | ||
271 | .initial_state = PM_SUSPEND_MEM, | ||
272 | .always_on = 1, | ||
273 | .boot_on = 1, | ||
274 | }, | ||
275 | }; | ||
276 | |||
277 | /* DDR RAM */ | ||
278 | static struct regulator_init_data sw2a_data = { | ||
279 | .constraints = { | ||
280 | .name = "SW2A", | ||
281 | .min_uV = 1800000, | ||
282 | .max_uV = 1800000, | ||
283 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
284 | .state_mem = { | ||
285 | .uV = 1800000, | ||
286 | .mode = REGULATOR_MODE_NORMAL, | ||
287 | .enabled = 1, | ||
288 | }, | ||
289 | .state_disk = { | ||
290 | .mode = REGULATOR_MODE_NORMAL, | ||
291 | .enabled = 0, | ||
292 | }, | ||
293 | .always_on = 1, | ||
294 | .boot_on = 1, | ||
295 | .initial_state = PM_SUSPEND_MEM, | ||
296 | }, | ||
297 | }; | ||
298 | |||
299 | static struct regulator_init_data ldo1_data = { | ||
300 | .constraints = { | ||
301 | .name = "VCAM/VMMC1/VMMC2", | ||
302 | .min_uV = 2800000, | ||
303 | .max_uV = 2800000, | ||
304 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
305 | .apply_uV = 1, | ||
306 | }, | ||
307 | }; | ||
308 | |||
309 | static struct regulator_consumer_supply ldo2_consumers[] = { | ||
310 | { | ||
311 | .supply = "AVDD", | ||
312 | }, | ||
313 | { | ||
314 | .supply = "HPVDD", | ||
315 | }, | ||
316 | }; | ||
317 | |||
318 | /* CODEC and SIM */ | ||
319 | static struct regulator_init_data ldo2_data = { | ||
320 | .constraints = { | ||
321 | .name = "VESIM/VSIM/AVDD", | ||
322 | .min_uV = 3300000, | ||
323 | .max_uV = 3300000, | ||
324 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
325 | .apply_uV = 1, | ||
326 | }, | ||
327 | .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers), | ||
328 | .consumer_supplies = ldo2_consumers, | ||
329 | }; | ||
330 | |||
331 | /* General */ | ||
332 | static struct regulator_init_data vdig_data = { | ||
333 | .constraints = { | ||
334 | .name = "VDIG", | ||
335 | .min_uV = 1500000, | ||
336 | .max_uV = 1500000, | ||
337 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
338 | .apply_uV = 1, | ||
339 | .always_on = 1, | ||
340 | .boot_on = 1, | ||
341 | }, | ||
342 | }; | ||
343 | |||
344 | /* Tranceivers */ | ||
345 | static struct regulator_init_data ldo4_data = { | ||
346 | .constraints = { | ||
347 | .name = "VRF1/CVDD_2.775", | ||
348 | .min_uV = 2500000, | ||
349 | .max_uV = 2500000, | ||
350 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
351 | .apply_uV = 1, | ||
352 | .always_on = 1, | ||
353 | .boot_on = 1, | ||
354 | }, | ||
355 | }; | ||
356 | |||
357 | static struct wm8350_led_platform_data wm8350_led_data = { | ||
358 | .name = "wm8350:white", | ||
359 | .default_trigger = "heartbeat", | ||
360 | .max_uA = 27899, | ||
361 | }; | ||
362 | |||
363 | static struct wm8350_audio_platform_data imx32ads_wm8350_setup = { | ||
364 | .vmid_discharge_msecs = 1000, | ||
365 | .drain_msecs = 30, | ||
366 | .cap_discharge_msecs = 700, | ||
367 | .vmid_charge_msecs = 700, | ||
368 | .vmid_s_curve = WM8350_S_CURVE_SLOW, | ||
369 | .dis_out4 = WM8350_DISCHARGE_SLOW, | ||
370 | .dis_out3 = WM8350_DISCHARGE_SLOW, | ||
371 | .dis_out2 = WM8350_DISCHARGE_SLOW, | ||
372 | .dis_out1 = WM8350_DISCHARGE_SLOW, | ||
373 | .vroi_out4 = WM8350_TIE_OFF_500R, | ||
374 | .vroi_out3 = WM8350_TIE_OFF_500R, | ||
375 | .vroi_out2 = WM8350_TIE_OFF_500R, | ||
376 | .vroi_out1 = WM8350_TIE_OFF_500R, | ||
377 | .vroi_enable = 0, | ||
378 | .codec_current_on = WM8350_CODEC_ISEL_1_0, | ||
379 | .codec_current_standby = WM8350_CODEC_ISEL_0_5, | ||
380 | .codec_current_charge = WM8350_CODEC_ISEL_1_5, | ||
381 | }; | ||
382 | |||
383 | static int mx31_wm8350_init(struct wm8350 *wm8350) | ||
384 | { | ||
385 | int i; | ||
386 | |||
387 | wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN, | ||
388 | WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW, | ||
389 | WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF, | ||
390 | WM8350_GPIO_DEBOUNCE_ON); | ||
391 | |||
392 | wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN, | ||
393 | WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
394 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
395 | WM8350_GPIO_DEBOUNCE_ON); | ||
396 | |||
397 | wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN, | ||
398 | WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
399 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
400 | WM8350_GPIO_DEBOUNCE_OFF); | ||
401 | |||
402 | wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, | ||
403 | WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH, | ||
404 | WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, | ||
405 | WM8350_GPIO_DEBOUNCE_OFF); | ||
406 | |||
407 | wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT, | ||
408 | WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH, | ||
409 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
410 | WM8350_GPIO_DEBOUNCE_OFF); | ||
411 | |||
412 | wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT, | ||
413 | WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, | ||
414 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
415 | WM8350_GPIO_DEBOUNCE_OFF); | ||
416 | |||
417 | wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT, | ||
418 | WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, | ||
419 | WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, | ||
420 | WM8350_GPIO_DEBOUNCE_OFF); | ||
421 | |||
422 | /* Fix up for our own supplies. */ | ||
423 | for (i = 0; i < ARRAY_SIZE(ldo2_consumers); i++) | ||
424 | ldo2_consumers[i].dev = wm8350->dev; | ||
425 | |||
426 | wm8350_register_regulator(wm8350, WM8350_DCDC_1, &sw1a_data); | ||
427 | wm8350_register_regulator(wm8350, WM8350_DCDC_3, &viohi_data); | ||
428 | wm8350_register_regulator(wm8350, WM8350_DCDC_4, &violo_data); | ||
429 | wm8350_register_regulator(wm8350, WM8350_DCDC_6, &sw2a_data); | ||
430 | wm8350_register_regulator(wm8350, WM8350_LDO_1, &ldo1_data); | ||
431 | wm8350_register_regulator(wm8350, WM8350_LDO_2, &ldo2_data); | ||
432 | wm8350_register_regulator(wm8350, WM8350_LDO_3, &vdig_data); | ||
433 | wm8350_register_regulator(wm8350, WM8350_LDO_4, &ldo4_data); | ||
434 | |||
435 | /* LEDs */ | ||
436 | wm8350_dcdc_set_slot(wm8350, WM8350_DCDC_5, 1, 1, | ||
437 | WM8350_DC5_ERRACT_SHUTDOWN_CONV); | ||
438 | wm8350_isink_set_flash(wm8350, WM8350_ISINK_A, | ||
439 | WM8350_ISINK_FLASH_DISABLE, | ||
440 | WM8350_ISINK_FLASH_TRIG_BIT, | ||
441 | WM8350_ISINK_FLASH_DUR_32MS, | ||
442 | WM8350_ISINK_FLASH_ON_INSTANT, | ||
443 | WM8350_ISINK_FLASH_OFF_INSTANT, | ||
444 | WM8350_ISINK_FLASH_MODE_EN); | ||
445 | wm8350_dcdc25_set_mode(wm8350, WM8350_DCDC_5, | ||
446 | WM8350_ISINK_MODE_BOOST, | ||
447 | WM8350_ISINK_ILIM_NORMAL, | ||
448 | WM8350_DC5_RMP_20V, | ||
449 | WM8350_DC5_FBSRC_ISINKA); | ||
450 | wm8350_register_led(wm8350, 0, WM8350_DCDC_5, WM8350_ISINK_A, | ||
451 | &wm8350_led_data); | ||
452 | |||
453 | wm8350->codec.platform_data = &imx32ads_wm8350_setup; | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static struct wm8350_platform_data __initdata mx31_wm8350_pdata = { | ||
459 | .init = mx31_wm8350_init, | ||
460 | }; | ||
461 | #endif | ||
462 | |||
463 | #if defined(CONFIG_I2C_IMX) || defined(CONFIG_I2C_IMX_MODULE) | ||
464 | static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { | ||
465 | #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 | ||
466 | { | ||
467 | I2C_BOARD_INFO("wm8350", 0x1a), | ||
468 | .platform_data = &mx31_wm8350_pdata, | ||
469 | .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3), | ||
470 | }, | ||
471 | #endif | ||
472 | }; | ||
473 | |||
474 | static void mxc_init_i2c(void) | ||
475 | { | ||
476 | i2c_register_board_info(1, mx31ads_i2c1_devices, | ||
477 | ARRAY_SIZE(mx31ads_i2c1_devices)); | ||
478 | |||
479 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1)); | ||
480 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1)); | ||
481 | |||
482 | mxc_register_device(&mxc_i2c_device1, NULL); | ||
483 | } | ||
484 | #else | ||
485 | static void mxc_init_i2c(void) | ||
486 | { | ||
487 | } | ||
488 | #endif | ||
489 | |||
194 | /*! | 490 | /*! |
195 | * This structure defines static mappings for the i.MX31ADS board. | 491 | * This structure defines static mappings for the i.MX31ADS board. |
196 | */ | 492 | */ |
197 | static struct map_desc mx31ads_io_desc[] __initdata = { | 493 | static struct map_desc mx31ads_io_desc[] __initdata = { |
198 | { | 494 | { |
199 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
200 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
201 | .length = AIPS1_SIZE, | ||
202 | .type = MT_DEVICE_NONSHARED | ||
203 | }, { | ||
204 | .virtual = SPBA0_BASE_ADDR_VIRT, | 495 | .virtual = SPBA0_BASE_ADDR_VIRT, |
205 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), | 496 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), |
206 | .length = SPBA0_SIZE, | 497 | .length = SPBA0_SIZE, |
207 | .type = MT_DEVICE_NONSHARED | 498 | .type = MT_DEVICE_NONSHARED |
208 | }, { | 499 | }, { |
209 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
210 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
211 | .length = AIPS2_SIZE, | ||
212 | .type = MT_DEVICE_NONSHARED | ||
213 | }, { | ||
214 | .virtual = CS4_BASE_ADDR_VIRT, | 500 | .virtual = CS4_BASE_ADDR_VIRT, |
215 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), | 501 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), |
216 | .length = CS4_SIZE / 2, | 502 | .length = CS4_SIZE / 2, |
@@ -221,13 +507,13 @@ static struct map_desc mx31ads_io_desc[] __initdata = { | |||
221 | /*! | 507 | /*! |
222 | * Set up static virtual mappings. | 508 | * Set up static virtual mappings. |
223 | */ | 509 | */ |
224 | void __init mx31ads_map_io(void) | 510 | static void __init mx31ads_map_io(void) |
225 | { | 511 | { |
226 | mxc_map_io(); | 512 | mxc_map_io(); |
227 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); | 513 | iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc)); |
228 | } | 514 | } |
229 | 515 | ||
230 | void __init mx31ads_init_irq(void) | 516 | static void __init mx31ads_init_irq(void) |
231 | { | 517 | { |
232 | mxc_init_irq(); | 518 | mxc_init_irq(); |
233 | mx31ads_init_expio(); | 519 | mx31ads_init_expio(); |
@@ -240,15 +526,15 @@ static void __init mxc_board_init(void) | |||
240 | { | 526 | { |
241 | mxc_init_extuart(); | 527 | mxc_init_extuart(); |
242 | mxc_init_imx_uart(); | 528 | mxc_init_imx_uart(); |
529 | mxc_init_i2c(); | ||
243 | } | 530 | } |
244 | 531 | ||
245 | static void __init mx31ads_timer_init(void) | 532 | static void __init mx31ads_timer_init(void) |
246 | { | 533 | { |
247 | mxc_clocks_init(26000000); | 534 | mx31_clocks_init(26000000); |
248 | mxc_timer_init("ipg_clk.0"); | ||
249 | } | 535 | } |
250 | 536 | ||
251 | struct sys_timer mx31ads_timer = { | 537 | static struct sys_timer mx31ads_timer = { |
252 | .init = mx31ads_timer_init, | 538 | .init = mx31ads_timer_init, |
253 | }; | 539 | }; |
254 | 540 | ||
diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index c43440070143..894d98cd9941 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c | |||
@@ -42,21 +42,11 @@ | |||
42 | */ | 42 | */ |
43 | static struct map_desc mx31lite_io_desc[] __initdata = { | 43 | static struct map_desc mx31lite_io_desc[] __initdata = { |
44 | { | 44 | { |
45 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
46 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
47 | .length = AIPS1_SIZE, | ||
48 | .type = MT_DEVICE_NONSHARED | ||
49 | }, { | ||
50 | .virtual = SPBA0_BASE_ADDR_VIRT, | 45 | .virtual = SPBA0_BASE_ADDR_VIRT, |
51 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), | 46 | .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), |
52 | .length = SPBA0_SIZE, | 47 | .length = SPBA0_SIZE, |
53 | .type = MT_DEVICE_NONSHARED | 48 | .type = MT_DEVICE_NONSHARED |
54 | }, { | 49 | }, { |
55 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
56 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
57 | .length = AIPS2_SIZE, | ||
58 | .type = MT_DEVICE_NONSHARED | ||
59 | }, { | ||
60 | .virtual = CS4_BASE_ADDR_VIRT, | 50 | .virtual = CS4_BASE_ADDR_VIRT, |
61 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), | 51 | .pfn = __phys_to_pfn(CS4_BASE_ADDR), |
62 | .length = CS4_SIZE, | 52 | .length = CS4_SIZE, |
@@ -82,8 +72,7 @@ static void __init mxc_board_init(void) | |||
82 | 72 | ||
83 | static void __init mx31lite_timer_init(void) | 73 | static void __init mx31lite_timer_init(void) |
84 | { | 74 | { |
85 | mxc_clocks_init(26000000); | 75 | mx31_clocks_init(26000000); |
86 | mxc_timer_init("ipg_clk.0"); | ||
87 | } | 76 | } |
88 | 77 | ||
89 | struct sys_timer mx31lite_timer = { | 78 | struct sys_timer mx31lite_timer = { |
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c new file mode 100644 index 000000000000..d080b4add79c --- /dev/null +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/init.h> | ||
21 | |||
22 | #include <linux/platform_device.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/common.h> | ||
26 | #include <mach/imx-uart.h> | ||
27 | #include <mach/iomux-mx3.h> | ||
28 | |||
29 | #include "devices.h" | ||
30 | |||
31 | static struct imxuart_platform_data uart_pdata = { | ||
32 | .flags = IMXUART_HAVE_RTSCTS, | ||
33 | }; | ||
34 | |||
35 | static int mxc_uart1_pins[] = { | ||
36 | MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, | ||
37 | MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, | ||
38 | }; | ||
39 | |||
40 | /* | ||
41 | * system init for baseboard usage. Will be called by mx31moboard init. | ||
42 | */ | ||
43 | void __init mx31moboard_devboard_init(void) | ||
44 | { | ||
45 | printk(KERN_INFO "Initializing mx31devboard peripherals\n"); | ||
46 | mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1"); | ||
47 | mxc_register_device(&mxc_uart_device1, &uart_pdata); | ||
48 | } | ||
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c new file mode 100644 index 000000000000..9ef9566823fb --- /dev/null +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/init.h> | ||
21 | |||
22 | #include <linux/platform_device.h> | ||
23 | |||
24 | #include <mach/hardware.h> | ||
25 | #include <mach/common.h> | ||
26 | #include <mach/imx-uart.h> | ||
27 | #include <mach/iomux-mx3.h> | ||
28 | |||
29 | #include "devices.h" | ||
30 | |||
31 | /* | ||
32 | * system init for baseboard usage. Will be called by mx31moboard init. | ||
33 | */ | ||
34 | void __init mx31moboard_marxbot_init(void) | ||
35 | { | ||
36 | printk(KERN_INFO "Initializing mx31marxbot peripherals\n"); | ||
37 | } | ||
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index c29098af7394..34c2a1b99d4f 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <mach/common.h> | 32 | #include <mach/common.h> |
33 | #include <mach/imx-uart.h> | 33 | #include <mach/imx-uart.h> |
34 | #include <mach/iomux-mx3.h> | 34 | #include <mach/iomux-mx3.h> |
35 | #include <mach/board-mx31moboard.h> | ||
35 | 36 | ||
36 | #include "devices.h" | 37 | #include "devices.h" |
37 | 38 | ||
@@ -63,6 +64,18 @@ static struct platform_device *devices[] __initdata = { | |||
63 | &mx31moboard_flash, | 64 | &mx31moboard_flash, |
64 | }; | 65 | }; |
65 | 66 | ||
67 | static int mxc_uart0_pins[] = { | ||
68 | MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1, | ||
69 | MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, | ||
70 | }; | ||
71 | static int mxc_uart4_pins[] = { | ||
72 | MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5, | ||
73 | MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5, | ||
74 | }; | ||
75 | |||
76 | static int mx31moboard_baseboard; | ||
77 | core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); | ||
78 | |||
66 | /* | 79 | /* |
67 | * Board specific initialization. | 80 | * Board specific initialization. |
68 | */ | 81 | */ |
@@ -70,58 +83,29 @@ static void __init mxc_board_init(void) | |||
70 | { | 83 | { |
71 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 84 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
72 | 85 | ||
73 | mxc_iomux_mode(MX31_PIN_CTS1__CTS1); | 86 | mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0"); |
74 | mxc_iomux_mode(MX31_PIN_RTS1__RTS1); | ||
75 | mxc_iomux_mode(MX31_PIN_TXD1__TXD1); | ||
76 | mxc_iomux_mode(MX31_PIN_RXD1__RXD1); | ||
77 | |||
78 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 87 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
79 | 88 | ||
80 | mxc_iomux_mode(MX31_PIN_CTS2__CTS2); | 89 | mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4"); |
81 | mxc_iomux_mode(MX31_PIN_RTS2__RTS2); | ||
82 | mxc_iomux_mode(MX31_PIN_TXD2__TXD2); | ||
83 | mxc_iomux_mode(MX31_PIN_RXD2__RXD2); | ||
84 | |||
85 | mxc_register_device(&mxc_uart_device1, &uart_pdata); | ||
86 | |||
87 | mxc_iomux_mode(MX31_PIN_PC_RST__CTS5); | ||
88 | mxc_iomux_mode(MX31_PIN_PC_VS2__RTS5); | ||
89 | mxc_iomux_mode(MX31_PIN_PC_BVD2__TXD5); | ||
90 | mxc_iomux_mode(MX31_PIN_PC_BVD1__RXD5); | ||
91 | |||
92 | mxc_register_device(&mxc_uart_device4, &uart_pdata); | 90 | mxc_register_device(&mxc_uart_device4, &uart_pdata); |
93 | } | ||
94 | 91 | ||
95 | /* | 92 | switch (mx31moboard_baseboard) { |
96 | * This structure defines static mappings for the mx31moboard. | 93 | case MX31NOBOARD: |
97 | */ | 94 | break; |
98 | static struct map_desc mx31moboard_io_desc[] __initdata = { | 95 | case MX31DEVBOARD: |
99 | { | 96 | mx31moboard_devboard_init(); |
100 | .virtual = AIPS1_BASE_ADDR_VIRT, | 97 | break; |
101 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | 98 | case MX31MARXBOT: |
102 | .length = AIPS1_SIZE, | 99 | mx31moboard_marxbot_init(); |
103 | .type = MT_DEVICE_NONSHARED | 100 | break; |
104 | }, { | 101 | default: |
105 | .virtual = AIPS2_BASE_ADDR_VIRT, | 102 | printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard); |
106 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | 103 | } |
107 | .length = AIPS2_SIZE, | ||
108 | .type = MT_DEVICE_NONSHARED | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | /* | ||
113 | * Set up static virtual mappings. | ||
114 | */ | ||
115 | void __init mx31moboard_map_io(void) | ||
116 | { | ||
117 | mxc_map_io(); | ||
118 | iotable_init(mx31moboard_io_desc, ARRAY_SIZE(mx31moboard_io_desc)); | ||
119 | } | 104 | } |
120 | 105 | ||
121 | static void __init mx31moboard_timer_init(void) | 106 | static void __init mx31moboard_timer_init(void) |
122 | { | 107 | { |
123 | mxc_clocks_init(26000000); | 108 | mx31_clocks_init(26000000); |
124 | mxc_timer_init("ipg_clk.0"); | ||
125 | } | 109 | } |
126 | 110 | ||
127 | struct sys_timer mx31moboard_timer = { | 111 | struct sys_timer mx31moboard_timer = { |
@@ -133,7 +117,7 @@ MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard") | |||
133 | .phys_io = AIPS1_BASE_ADDR, | 117 | .phys_io = AIPS1_BASE_ADDR, |
134 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 118 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
135 | .boot_params = PHYS_OFFSET + 0x100, | 119 | .boot_params = PHYS_OFFSET + 0x100, |
136 | .map_io = mx31moboard_map_io, | 120 | .map_io = mxc_map_io, |
137 | .init_irq = mxc_init_irq, | 121 | .init_irq = mxc_init_irq, |
138 | .init_machine = mxc_board_init, | 122 | .init_machine = mxc_board_init, |
139 | .timer = &mx31moboard_timer, | 123 | .timer = &mx31moboard_timer, |
diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c index d464d068a4a6..bc63f1785691 100644 --- a/arch/arm/mach-mx3/mx31pdk.c +++ b/arch/arm/mach-mx3/mx31pdk.c | |||
@@ -45,40 +45,17 @@ static struct imxuart_platform_data uart_pdata = { | |||
45 | .flags = IMXUART_HAVE_RTSCTS, | 45 | .flags = IMXUART_HAVE_RTSCTS, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static inline void mxc_init_imx_uart(void) | 48 | static int uart_pins[] = { |
49 | { | 49 | MX31_PIN_CTS1__CTS1, |
50 | mxc_iomux_mode(MX31_PIN_CTS1__CTS1); | 50 | MX31_PIN_RTS1__RTS1, |
51 | mxc_iomux_mode(MX31_PIN_RTS1__RTS1); | 51 | MX31_PIN_TXD1__TXD1, |
52 | mxc_iomux_mode(MX31_PIN_TXD1__TXD1); | 52 | MX31_PIN_RXD1__RXD1 |
53 | mxc_iomux_mode(MX31_PIN_RXD1__RXD1); | ||
54 | |||
55 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
56 | } | ||
57 | |||
58 | /*! | ||
59 | * This structure defines static mappings for the i.MX31PDK board. | ||
60 | */ | ||
61 | static struct map_desc mx31pdk_io_desc[] __initdata = { | ||
62 | { | ||
63 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
64 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
65 | .length = AIPS1_SIZE, | ||
66 | .type = MT_DEVICE_NONSHARED | ||
67 | }, { | ||
68 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
69 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
70 | .length = AIPS2_SIZE, | ||
71 | .type = MT_DEVICE_NONSHARED | ||
72 | }, | ||
73 | }; | 53 | }; |
74 | 54 | ||
75 | /*! | 55 | static inline void mxc_init_imx_uart(void) |
76 | * Set up static virtual mappings. | ||
77 | */ | ||
78 | static void __init mx31pdk_map_io(void) | ||
79 | { | 56 | { |
80 | mxc_map_io(); | 57 | mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0"); |
81 | iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc)); | 58 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
82 | } | 59 | } |
83 | 60 | ||
84 | /*! | 61 | /*! |
@@ -91,8 +68,7 @@ static void __init mxc_board_init(void) | |||
91 | 68 | ||
92 | static void __init mx31pdk_timer_init(void) | 69 | static void __init mx31pdk_timer_init(void) |
93 | { | 70 | { |
94 | mxc_clocks_init(26000000); | 71 | mx31_clocks_init(26000000); |
95 | mxc_timer_init("ipg_clk.0"); | ||
96 | } | 72 | } |
97 | 73 | ||
98 | static struct sys_timer mx31pdk_timer = { | 74 | static struct sys_timer mx31pdk_timer = { |
@@ -108,7 +84,7 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") | |||
108 | .phys_io = AIPS1_BASE_ADDR, | 84 | .phys_io = AIPS1_BASE_ADDR, |
109 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 85 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
110 | .boot_params = PHYS_OFFSET + 0x100, | 86 | .boot_params = PHYS_OFFSET + 0x100, |
111 | .map_io = mx31pdk_map_io, | 87 | .map_io = mxc_map_io, |
112 | .init_irq = mxc_init_irq, | 88 | .init_irq = mxc_init_irq, |
113 | .init_machine = mxc_board_init, | 89 | .init_machine = mxc_board_init, |
114 | .timer = &mx31pdk_timer, | 90 | .timer = &mx31pdk_timer, |
diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 8cea82587222..5fce022114de 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/smc911x.h> | 27 | #include <linux/smc911x.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/i2c.h> | ||
30 | #include <linux/i2c/at24.h> | ||
29 | 31 | ||
30 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
31 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
@@ -37,6 +39,10 @@ | |||
37 | #include <mach/iomux-mx3.h> | 39 | #include <mach/iomux-mx3.h> |
38 | #include <mach/board-pcm037.h> | 40 | #include <mach/board-pcm037.h> |
39 | #include <mach/mxc_nand.h> | 41 | #include <mach/mxc_nand.h> |
42 | #include <mach/mmc.h> | ||
43 | #ifdef CONFIG_I2C_IMX | ||
44 | #include <mach/i2c.h> | ||
45 | #endif | ||
40 | 46 | ||
41 | #include "devices.h" | 47 | #include "devices.h" |
42 | 48 | ||
@@ -117,12 +123,90 @@ static struct mxc_nand_platform_data pcm037_nand_board_info = { | |||
117 | .hw_ecc = 1, | 123 | .hw_ecc = 1, |
118 | }; | 124 | }; |
119 | 125 | ||
126 | #ifdef CONFIG_I2C_IMX | ||
127 | static int i2c_1_pins[] = { | ||
128 | MX31_PIN_CSPI2_MOSI__SCL, | ||
129 | MX31_PIN_CSPI2_MISO__SDA, | ||
130 | }; | ||
131 | |||
132 | static int pcm037_i2c_1_init(struct device *dev) | ||
133 | { | ||
134 | return mxc_iomux_setup_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins), | ||
135 | "i2c-1"); | ||
136 | } | ||
137 | |||
138 | static void pcm037_i2c_1_exit(struct device *dev) | ||
139 | { | ||
140 | mxc_iomux_release_multiple_pins(i2c_1_pins, ARRAY_SIZE(i2c_1_pins)); | ||
141 | } | ||
142 | |||
143 | static struct imxi2c_platform_data pcm037_i2c_1_data = { | ||
144 | .bitrate = 100000, | ||
145 | .init = pcm037_i2c_1_init, | ||
146 | .exit = pcm037_i2c_1_exit, | ||
147 | }; | ||
148 | |||
149 | static struct at24_platform_data board_eeprom = { | ||
150 | .byte_len = 4096, | ||
151 | .page_size = 32, | ||
152 | .flags = AT24_FLAG_ADDR16, | ||
153 | }; | ||
154 | |||
155 | static struct i2c_board_info pcm037_i2c_devices[] = { | ||
156 | { | ||
157 | I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */ | ||
158 | .platform_data = &board_eeprom, | ||
159 | }, { | ||
160 | I2C_BOARD_INFO("rtc-pcf8563", 0x51), | ||
161 | .type = "pcf8563", | ||
162 | } | ||
163 | }; | ||
164 | #endif | ||
165 | |||
166 | static int sdhc1_pins[] = { | ||
167 | MX31_PIN_SD1_DATA3__SD1_DATA3, | ||
168 | MX31_PIN_SD1_DATA2__SD1_DATA2, | ||
169 | MX31_PIN_SD1_DATA1__SD1_DATA1, | ||
170 | MX31_PIN_SD1_DATA0__SD1_DATA0, | ||
171 | MX31_PIN_SD1_CLK__SD1_CLK, | ||
172 | MX31_PIN_SD1_CMD__SD1_CMD, | ||
173 | }; | ||
174 | |||
175 | static int pcm970_sdhc1_init(struct device *dev, irq_handler_t h, void *data) | ||
176 | { | ||
177 | return mxc_iomux_setup_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins), | ||
178 | "sdhc-1"); | ||
179 | } | ||
180 | |||
181 | static void pcm970_sdhc1_exit(struct device *dev, void *data) | ||
182 | { | ||
183 | mxc_iomux_release_multiple_pins(sdhc1_pins, ARRAY_SIZE(sdhc1_pins)); | ||
184 | } | ||
185 | |||
186 | /* No card and rw detection at the moment */ | ||
187 | static struct imxmmc_platform_data sdhc_pdata = { | ||
188 | .init = pcm970_sdhc1_init, | ||
189 | .exit = pcm970_sdhc1_exit, | ||
190 | }; | ||
191 | |||
120 | static struct platform_device *devices[] __initdata = { | 192 | static struct platform_device *devices[] __initdata = { |
121 | &pcm037_flash, | 193 | &pcm037_flash, |
122 | &pcm037_eth, | 194 | &pcm037_eth, |
123 | &pcm037_sram_device, | 195 | &pcm037_sram_device, |
124 | }; | 196 | }; |
125 | 197 | ||
198 | static int uart0_pins[] = { | ||
199 | MX31_PIN_CTS1__CTS1, | ||
200 | MX31_PIN_RTS1__RTS1, | ||
201 | MX31_PIN_TXD1__TXD1, | ||
202 | MX31_PIN_RXD1__RXD1 | ||
203 | }; | ||
204 | |||
205 | static int uart2_pins[] = { | ||
206 | MX31_PIN_CSPI3_MOSI__RXD3, | ||
207 | MX31_PIN_CSPI3_MISO__TXD3 | ||
208 | }; | ||
209 | |||
126 | /* | 210 | /* |
127 | * Board specific initialization. | 211 | * Board specific initialization. |
128 | */ | 212 | */ |
@@ -130,59 +214,33 @@ static void __init mxc_board_init(void) | |||
130 | { | 214 | { |
131 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 215 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
132 | 216 | ||
133 | mxc_iomux_mode(MX31_PIN_CTS1__CTS1); | 217 | mxc_iomux_setup_multiple_pins(uart0_pins, ARRAY_SIZE(uart0_pins), "uart-0"); |
134 | mxc_iomux_mode(MX31_PIN_RTS1__RTS1); | ||
135 | mxc_iomux_mode(MX31_PIN_TXD1__TXD1); | ||
136 | mxc_iomux_mode(MX31_PIN_RXD1__RXD1); | ||
137 | |||
138 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 218 | mxc_register_device(&mxc_uart_device0, &uart_pdata); |
139 | 219 | ||
140 | mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3); | 220 | mxc_iomux_setup_multiple_pins(uart2_pins, ARRAY_SIZE(uart2_pins), "uart-2"); |
141 | mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3); | ||
142 | |||
143 | mxc_register_device(&mxc_uart_device2, &uart_pdata); | 221 | mxc_register_device(&mxc_uart_device2, &uart_pdata); |
144 | 222 | ||
145 | mxc_iomux_mode(MX31_PIN_BATT_LINE__OWIRE); | 223 | mxc_iomux_setup_pin(MX31_PIN_BATT_LINE__OWIRE, "batt-0wire"); |
146 | mxc_register_device(&mxc_w1_master_device, NULL); | 224 | mxc_register_device(&mxc_w1_master_device, NULL); |
147 | 225 | ||
148 | /* SMSC9215 IRQ pin */ | 226 | /* SMSC9215 IRQ pin */ |
149 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO)); | 227 | if (!mxc_iomux_setup_pin(IOMUX_MODE(MX31_PIN_GPIO3_1, IOMUX_CONFIG_GPIO), |
150 | if (!gpio_request(MX31_PIN_GPIO3_1, "pcm037-eth")) | 228 | "pcm037-eth")) |
151 | gpio_direction_input(MX31_PIN_GPIO3_1); | 229 | gpio_direction_input(MX31_PIN_GPIO3_1); |
152 | 230 | ||
153 | mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); | 231 | #ifdef CONFIG_I2C_IMX |
154 | } | 232 | i2c_register_board_info(1, pcm037_i2c_devices, |
233 | ARRAY_SIZE(pcm037_i2c_devices)); | ||
155 | 234 | ||
156 | /* | 235 | mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data); |
157 | * This structure defines static mappings for the pcm037 board. | 236 | #endif |
158 | */ | 237 | mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info); |
159 | static struct map_desc pcm037_io_desc[] __initdata = { | 238 | mxc_register_device(&mxcsdhc_device0, &sdhc_pdata); |
160 | { | ||
161 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
162 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
163 | .length = AIPS1_SIZE, | ||
164 | .type = MT_DEVICE_NONSHARED | ||
165 | }, { | ||
166 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
167 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
168 | .length = AIPS2_SIZE, | ||
169 | .type = MT_DEVICE_NONSHARED | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | /* | ||
174 | * Set up static virtual mappings. | ||
175 | */ | ||
176 | void __init pcm037_map_io(void) | ||
177 | { | ||
178 | mxc_map_io(); | ||
179 | iotable_init(pcm037_io_desc, ARRAY_SIZE(pcm037_io_desc)); | ||
180 | } | 239 | } |
181 | 240 | ||
182 | static void __init pcm037_timer_init(void) | 241 | static void __init pcm037_timer_init(void) |
183 | { | 242 | { |
184 | mxc_clocks_init(26000000); | 243 | mx31_clocks_init(26000000); |
185 | mxc_timer_init("ipg_clk.0"); | ||
186 | } | 244 | } |
187 | 245 | ||
188 | struct sys_timer pcm037_timer = { | 246 | struct sys_timer pcm037_timer = { |
@@ -194,7 +252,7 @@ MACHINE_START(PCM037, "Phytec Phycore pcm037") | |||
194 | .phys_io = AIPS1_BASE_ADDR, | 252 | .phys_io = AIPS1_BASE_ADDR, |
195 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | 253 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, |
196 | .boot_params = PHYS_OFFSET + 0x100, | 254 | .boot_params = PHYS_OFFSET + 0x100, |
197 | .map_io = pcm037_map_io, | 255 | .map_io = mxc_map_io, |
198 | .init_irq = mxc_init_irq, | 256 | .init_irq = mxc_init_irq, |
199 | .init_machine = mxc_board_init, | 257 | .init_machine = mxc_board_init, |
200 | .timer = &pcm037_timer, | 258 | .timer = &pcm037_timer, |
diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c new file mode 100644 index 000000000000..6c4283cec6f4 --- /dev/null +++ b/arch/arm/mach-mx3/qong.c | |||
@@ -0,0 +1,312 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/memory.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/mtd/physmap.h> | ||
25 | #include <linux/mtd/nand.h> | ||
26 | #include <linux/gpio.h> | ||
27 | |||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/irqs.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/time.h> | ||
33 | #include <asm/mach/map.h> | ||
34 | #include <mach/common.h> | ||
35 | #include <asm/page.h> | ||
36 | #include <asm/setup.h> | ||
37 | #include <mach/board-qong.h> | ||
38 | #include <mach/imx-uart.h> | ||
39 | #include <mach/iomux-mx3.h> | ||
40 | #include "devices.h" | ||
41 | |||
42 | /* FPGA defines */ | ||
43 | #define QONG_FPGA_VERSION(major, minor, rev) \ | ||
44 | (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF)) | ||
45 | |||
46 | #define QONG_FPGA_BASEADDR CS1_BASE_ADDR | ||
47 | #define QONG_FPGA_PERIPH_SIZE (1 << 24) | ||
48 | |||
49 | #define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR | ||
50 | #define QONG_FPGA_CTRL_SIZE 0x10 | ||
51 | /* FPGA control registers */ | ||
52 | #define QONG_FPGA_CTRL_VERSION 0x00 | ||
53 | |||
54 | #define QONG_DNET_ID 1 | ||
55 | #define QONG_DNET_BASEADDR \ | ||
56 | (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE) | ||
57 | #define QONG_DNET_SIZE 0x00001000 | ||
58 | |||
59 | #define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1) | ||
60 | |||
61 | /* | ||
62 | * This file contains the board-specific initialization routines. | ||
63 | */ | ||
64 | |||
65 | static struct imxuart_platform_data uart_pdata = { | ||
66 | .flags = IMXUART_HAVE_RTSCTS, | ||
67 | }; | ||
68 | |||
69 | static int uart_pins[] = { | ||
70 | MX31_PIN_CTS1__CTS1, | ||
71 | MX31_PIN_RTS1__RTS1, | ||
72 | MX31_PIN_TXD1__TXD1, | ||
73 | MX31_PIN_RXD1__RXD1 | ||
74 | }; | ||
75 | |||
76 | static inline void mxc_init_imx_uart(void) | ||
77 | { | ||
78 | mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), | ||
79 | "uart-0"); | ||
80 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | ||
81 | } | ||
82 | |||
83 | static struct resource dnet_resources[] = { | ||
84 | [0] = { | ||
85 | .name = "dnet-memory", | ||
86 | .start = QONG_DNET_BASEADDR, | ||
87 | .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, | ||
88 | .flags = IORESOURCE_MEM, | ||
89 | }, | ||
90 | [1] = { | ||
91 | .start = QONG_FPGA_IRQ, | ||
92 | .end = QONG_FPGA_IRQ, | ||
93 | .flags = IORESOURCE_IRQ, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct platform_device dnet_device = { | ||
98 | .name = "dnet", | ||
99 | .id = -1, | ||
100 | .num_resources = ARRAY_SIZE(dnet_resources), | ||
101 | .resource = dnet_resources, | ||
102 | }; | ||
103 | |||
104 | static int __init qong_init_dnet(void) | ||
105 | { | ||
106 | int ret; | ||
107 | |||
108 | ret = platform_device_register(&dnet_device); | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | /* MTD NOR flash */ | ||
113 | |||
114 | static struct physmap_flash_data qong_flash_data = { | ||
115 | .width = 2, | ||
116 | }; | ||
117 | |||
118 | static struct resource qong_flash_resource = { | ||
119 | .start = CS0_BASE_ADDR, | ||
120 | .end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1, | ||
121 | .flags = IORESOURCE_MEM, | ||
122 | }; | ||
123 | |||
124 | static struct platform_device qong_nor_mtd_device = { | ||
125 | .name = "physmap-flash", | ||
126 | .id = 0, | ||
127 | .dev = { | ||
128 | .platform_data = &qong_flash_data, | ||
129 | }, | ||
130 | .resource = &qong_flash_resource, | ||
131 | .num_resources = 1, | ||
132 | }; | ||
133 | |||
134 | static void qong_init_nor_mtd(void) | ||
135 | { | ||
136 | (void)platform_device_register(&qong_nor_mtd_device); | ||
137 | } | ||
138 | |||
139 | /* | ||
140 | * Hardware specific access to control-lines | ||
141 | */ | ||
142 | static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
143 | { | ||
144 | struct nand_chip *nand_chip = mtd->priv; | ||
145 | |||
146 | if (cmd == NAND_CMD_NONE) | ||
147 | return; | ||
148 | |||
149 | if (ctrl & NAND_CLE) | ||
150 | writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24)); | ||
151 | else | ||
152 | writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23)); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Read the Device Ready pin. | ||
157 | */ | ||
158 | static int qong_nand_device_ready(struct mtd_info *mtd) | ||
159 | { | ||
160 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB)); | ||
161 | } | ||
162 | |||
163 | static void qong_nand_select_chip(struct mtd_info *mtd, int chip) | ||
164 | { | ||
165 | if (chip >= 0) | ||
166 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); | ||
167 | else | ||
168 | gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1); | ||
169 | } | ||
170 | |||
171 | static struct platform_nand_data qong_nand_data = { | ||
172 | .chip = { | ||
173 | .chip_delay = 20, | ||
174 | .options = 0, | ||
175 | }, | ||
176 | .ctrl = { | ||
177 | .cmd_ctrl = qong_nand_cmd_ctrl, | ||
178 | .dev_ready = qong_nand_device_ready, | ||
179 | .select_chip = qong_nand_select_chip, | ||
180 | } | ||
181 | }; | ||
182 | |||
183 | static struct resource qong_nand_resource = { | ||
184 | .start = CS3_BASE_ADDR, | ||
185 | .end = CS3_BASE_ADDR + SZ_32M - 1, | ||
186 | .flags = IORESOURCE_MEM, | ||
187 | }; | ||
188 | |||
189 | static struct platform_device qong_nand_device = { | ||
190 | .name = "gen_nand", | ||
191 | .id = -1, | ||
192 | .dev = { | ||
193 | .platform_data = &qong_nand_data, | ||
194 | }, | ||
195 | .num_resources = 1, | ||
196 | .resource = &qong_nand_resource, | ||
197 | }; | ||
198 | |||
199 | static void __init qong_init_nand_mtd(void) | ||
200 | { | ||
201 | /* init CS */ | ||
202 | __raw_writel(0x00004f00, CSCR_U(3)); | ||
203 | __raw_writel(0x20013b31, CSCR_L(3)); | ||
204 | __raw_writel(0x00020800, CSCR_A(3)); | ||
205 | mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); | ||
206 | |||
207 | /* enable pin */ | ||
208 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO)); | ||
209 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable")) | ||
210 | gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); | ||
211 | |||
212 | /* ready/busy pin */ | ||
213 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO)); | ||
214 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy")) | ||
215 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB)); | ||
216 | |||
217 | /* write protect pin */ | ||
218 | mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO)); | ||
219 | if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp")) | ||
220 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B)); | ||
221 | |||
222 | platform_device_register(&qong_nand_device); | ||
223 | } | ||
224 | |||
225 | static void __init qong_init_fpga(void) | ||
226 | { | ||
227 | void __iomem *regs; | ||
228 | u32 fpga_ver; | ||
229 | |||
230 | regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE); | ||
231 | if (!regs) { | ||
232 | printk(KERN_ERR "%s: failed to map registers, aborting.\n", | ||
233 | __func__); | ||
234 | return; | ||
235 | } | ||
236 | |||
237 | fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION); | ||
238 | iounmap(regs); | ||
239 | printk(KERN_INFO "Qong FPGA version %d.%d.%d\n", | ||
240 | (fpga_ver & 0xF000) >> 12, | ||
241 | (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF); | ||
242 | if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) { | ||
243 | printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based " | ||
244 | "devices won't be registered!\n"); | ||
245 | return; | ||
246 | } | ||
247 | |||
248 | /* register FPGA-based devices */ | ||
249 | qong_init_nand_mtd(); | ||
250 | qong_init_dnet(); | ||
251 | } | ||
252 | |||
253 | /* | ||
254 | * This structure defines the MX31 memory map. | ||
255 | */ | ||
256 | static struct map_desc qong_io_desc[] __initdata = { | ||
257 | { | ||
258 | .virtual = AIPS1_BASE_ADDR_VIRT, | ||
259 | .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), | ||
260 | .length = AIPS1_SIZE, | ||
261 | .type = MT_DEVICE_NONSHARED | ||
262 | }, { | ||
263 | .virtual = AIPS2_BASE_ADDR_VIRT, | ||
264 | .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), | ||
265 | .length = AIPS2_SIZE, | ||
266 | .type = MT_DEVICE_NONSHARED | ||
267 | } | ||
268 | }; | ||
269 | |||
270 | /* | ||
271 | * Set up static virtual mappings. | ||
272 | */ | ||
273 | static void __init qong_map_io(void) | ||
274 | { | ||
275 | mxc_map_io(); | ||
276 | iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc)); | ||
277 | } | ||
278 | |||
279 | /* | ||
280 | * Board specific initialization. | ||
281 | */ | ||
282 | static void __init mxc_board_init(void) | ||
283 | { | ||
284 | mxc_init_imx_uart(); | ||
285 | qong_init_nor_mtd(); | ||
286 | qong_init_fpga(); | ||
287 | } | ||
288 | |||
289 | static void __init qong_timer_init(void) | ||
290 | { | ||
291 | mx31_clocks_init(26000000); | ||
292 | } | ||
293 | |||
294 | static struct sys_timer qong_timer = { | ||
295 | .init = qong_timer_init, | ||
296 | }; | ||
297 | |||
298 | /* | ||
299 | * The following uses standard kernel macros defined in arch.h in order to | ||
300 | * initialize __mach_desc_QONG data structure. | ||
301 | */ | ||
302 | |||
303 | MACHINE_START(QONG, "Dave/DENX QongEVB-LITE") | ||
304 | /* Maintainer: DENX Software Engineering GmbH */ | ||
305 | .phys_io = AIPS1_BASE_ADDR, | ||
306 | .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, | ||
307 | .boot_params = PHYS_OFFSET + 0x100, | ||
308 | .map_io = qong_map_io, | ||
309 | .init_irq = mxc_init_irq, | ||
310 | .init_machine = mxc_board_init, | ||
311 | .timer = &qong_timer, | ||
312 | MACHINE_END | ||