aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx2
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-03-13 17:44:51 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-03-13 17:44:51 -0400
commit97fb44eb6bc01f4ffed4300e475aa15e44877375 (patch)
tree481ed6efd0babe7185cae04f2fd295426b36411d /arch/arm/mach-mx2
parente4707dd3e9d0cb57597b6568a5e51fea5d6fca41 (diff)
parent148854c65ea8046b045672fd49f4333aefaa3ab5 (diff)
Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel
Conflicts: arch/arm/mach-at91/gpio.c
Diffstat (limited to 'arch/arm/mach-mx2')
-rw-r--r--arch/arm/mach-mx2/Kconfig20
-rw-r--r--arch/arm/mach-mx2/Makefile2
-rw-r--r--arch/arm/mach-mx2/Makefile.boot10
-rw-r--r--arch/arm/mach-mx2/clock_imx21.c984
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c1656
-rw-r--r--arch/arm/mach-mx2/cpu_imx27.c4
-rw-r--r--arch/arm/mach-mx2/crm_regs.h313
-rw-r--r--arch/arm/mach-mx2/devices.c196
-rw-r--r--arch/arm/mach-mx2/devices.h8
-rw-r--r--arch/arm/mach-mx2/generic.c1
-rw-r--r--arch/arm/mach-mx2/mx27ads.c19
-rw-r--r--arch/arm/mach-mx2/pcm038.c82
-rw-r--r--arch/arm/mach-mx2/pcm970-baseboard.c133
-rw-r--r--arch/arm/mach-mx2/serial.c3
14 files changed, 1960 insertions, 1471 deletions
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig
index 1eaa97cb716d..42a788842f49 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-mx2/Kconfig
@@ -1,14 +1,22 @@
1comment "MX2 family CPU support" 1if ARCH_MX2
2 depends on ARCH_MX2 2
3choice
4 prompt "CPUs:"
5 default MACH_MX21
6
7config MACH_MX21
8 bool "i.MX21 support"
9 help
10 This enables support for Freescale's MX2 based i.MX21 processor.
3 11
4config MACH_MX27 12config MACH_MX27
5 bool "i.MX27 support" 13 bool "i.MX27 support"
6 depends on ARCH_MX2
7 help 14 help
8 This enables support for Freescale's MX2 based i.MX27 processor. 15 This enables support for Freescale's MX2 based i.MX27 processor.
9 16
10comment "MX2 Platforms" 17endchoice
11 depends on ARCH_MX2 18
19comment "MX2 platforms:"
12 20
13config MACH_MX27ADS 21config MACH_MX27ADS
14 bool "MX27ADS platform" 22 bool "MX27ADS platform"
@@ -37,3 +45,5 @@ config MACH_PCM970_BASEBOARD
37 PCM970 evaluation board. 45 PCM970 evaluation board.
38 46
39endchoice 47endchoice
48
49endif
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile
index 382d86080e86..6e1a2bffc812 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-mx2/Makefile
@@ -6,6 +6,8 @@
6 6
7obj-y := system.o generic.o devices.o serial.o 7obj-y := system.o generic.o devices.o serial.o
8 8
9obj-$(CONFIG_MACH_MX21) += clock_imx21.o
10
9obj-$(CONFIG_MACH_MX27) += cpu_imx27.o 11obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
10obj-$(CONFIG_MACH_MX27) += clock_imx27.o 12obj-$(CONFIG_MACH_MX27) += clock_imx27.o
11 13
diff --git a/arch/arm/mach-mx2/Makefile.boot b/arch/arm/mach-mx2/Makefile.boot
index 696831dcd485..e867398a8fdb 100644
--- a/arch/arm/mach-mx2/Makefile.boot
+++ b/arch/arm/mach-mx2/Makefile.boot
@@ -1,3 +1,7 @@
1 zreladdr-y := 0xA0008000 1zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
2params_phys-y := 0xA0000100 2params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
3initrd_phys-y := 0xA0800000 3initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
4
5zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000
6params_phys-$(CONFIG_MACH_MX27) := 0xA0000100
7initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c
new file mode 100644
index 000000000000..2dee5c87614c
--- /dev/null
+++ b/arch/arm/mach-mx2/clock_imx21.c
@@ -0,0 +1,984 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/module.h>
24
25#include <mach/clock.h>
26#include <mach/common.h>
27#include <asm/clkdev.h>
28#include <asm/div64.h>
29
30#include "crm_regs.h"
31
32static int _clk_enable(struct clk *clk)
33{
34 u32 reg;
35
36 reg = __raw_readl(clk->enable_reg);
37 reg |= 1 << clk->enable_shift;
38 __raw_writel(reg, clk->enable_reg);
39 return 0;
40}
41
42static void _clk_disable(struct clk *clk)
43{
44 u32 reg;
45
46 reg = __raw_readl(clk->enable_reg);
47 reg &= ~(1 << clk->enable_shift);
48 __raw_writel(reg, clk->enable_reg);
49}
50
51static int _clk_spll_enable(struct clk *clk)
52{
53 u32 reg;
54
55 reg = __raw_readl(CCM_CSCR);
56 reg |= CCM_CSCR_SPEN;
57 __raw_writel(reg, CCM_CSCR);
58
59 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
60 ;
61 return 0;
62}
63
64static void _clk_spll_disable(struct clk *clk)
65{
66 u32 reg;
67
68 reg = __raw_readl(CCM_CSCR);
69 reg &= ~CCM_CSCR_SPEN;
70 __raw_writel(reg, CCM_CSCR);
71}
72
73
74#define CSCR() (__raw_readl(CCM_CSCR))
75#define PCDR0() (__raw_readl(CCM_PCDR0))
76#define PCDR1() (__raw_readl(CCM_PCDR1))
77
78static unsigned long _clk_perclkx_round_rate(struct clk *clk,
79 unsigned long rate)
80{
81 u32 div;
82 unsigned long parent_rate;
83
84 parent_rate = clk_get_rate(clk->parent);
85
86 div = parent_rate / rate;
87 if (parent_rate % rate)
88 div++;
89
90 if (div > 64)
91 div = 64;
92
93 return parent_rate / div;
94}
95
96static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
97{
98 u32 reg;
99 u32 div;
100 unsigned long parent_rate;
101
102 parent_rate = clk_get_rate(clk->parent);
103
104 if (clk->id < 0 || clk->id > 3)
105 return -EINVAL;
106
107 div = parent_rate / rate;
108 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
109 return -EINVAL;
110 div--;
111
112 reg =
113 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
114 (clk->id << 3));
115 reg |= div << (clk->id << 3);
116 __raw_writel(reg, CCM_PCDR1);
117
118 return 0;
119}
120
121static unsigned long _clk_usb_recalc(struct clk *clk)
122{
123 unsigned long usb_pdf;
124 unsigned long parent_rate;
125
126 parent_rate = clk_get_rate(clk->parent);
127
128 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
129
130 return parent_rate / (usb_pdf + 1U);
131}
132
133static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
134{
135 unsigned long parent_rate;
136
137 parent_rate = clk_get_rate(clk->parent);
138
139 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
140
141 return 2UL * parent_rate / pdf;
142}
143
144static unsigned long _clk_ssi1_recalc(struct clk *clk)
145{
146 return _clk_ssix_recalc(clk,
147 (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
148 >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
149}
150
151static unsigned long _clk_ssi2_recalc(struct clk *clk)
152{
153 return _clk_ssix_recalc(clk,
154 (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
155 CCM_PCDR0_SSI2BAUDDIV_OFFSET);
156}
157
158static unsigned long _clk_nfc_recalc(struct clk *clk)
159{
160 unsigned long nfc_pdf;
161 unsigned long parent_rate;
162
163 parent_rate = clk_get_rate(clk->parent);
164
165 nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
166 >> CCM_PCDR0_NFCDIV_OFFSET;
167
168 return parent_rate / (nfc_pdf + 1);
169}
170
171static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
172{
173 return clk->parent->round_rate(clk->parent, rate);
174}
175
176static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
177{
178 return clk->parent->set_rate(clk->parent, rate);
179}
180
181static unsigned long external_high_reference; /* in Hz */
182
183static unsigned long get_high_reference_clock_rate(struct clk *clk)
184{
185 return external_high_reference;
186}
187
188/*
189 * the high frequency external clock reference
190 * Default case is 26MHz.
191 */
192static struct clk ckih_clk = {
193 .get_rate = get_high_reference_clock_rate,
194};
195
196static unsigned long external_low_reference; /* in Hz */
197
198static unsigned long get_low_reference_clock_rate(struct clk *clk)
199{
200 return external_low_reference;
201}
202
203/*
204 * the low frequency external clock reference
205 * Default case is 32.768kHz.
206 */
207static struct clk ckil_clk = {
208 .get_rate = get_low_reference_clock_rate,
209};
210
211
212static unsigned long _clk_fpm_recalc(struct clk *clk)
213{
214 return clk_get_rate(clk->parent) * 512;
215}
216
217/* Output of frequency pre multiplier */
218static struct clk fpm_clk = {
219 .parent = &ckil_clk,
220 .get_rate = _clk_fpm_recalc,
221};
222
223static unsigned long get_mpll_clk(struct clk *clk)
224{
225 uint32_t reg;
226 unsigned long ref_clk;
227 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
228 unsigned long long temp;
229
230 ref_clk = clk_get_rate(clk->parent);
231
232 reg = __raw_readl(CCM_MPCTL0);
233 pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
234 mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
235 mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
236 mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
237
238 mfi = (mfi <= 5) ? 5 : mfi;
239 temp = 2LL * ref_clk * mfn;
240 do_div(temp, mfd + 1);
241 temp = 2LL * ref_clk * mfi + temp;
242 do_div(temp, pdf + 1);
243
244 return (unsigned long)temp;
245}
246
247static struct clk mpll_clk = {
248 .parent = &ckih_clk,
249 .get_rate = get_mpll_clk,
250};
251
252static unsigned long _clk_fclk_get_rate(struct clk *clk)
253{
254 unsigned long parent_rate;
255 u32 div;
256
257 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
258 parent_rate = clk_get_rate(clk->parent);
259
260 return parent_rate / (div+1);
261}
262
263static struct clk fclk_clk = {
264 .parent = &mpll_clk,
265 .get_rate = _clk_fclk_get_rate
266};
267
268static unsigned long get_spll_clk(struct clk *clk)
269{
270 uint32_t reg;
271 unsigned long ref_clk;
272 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
273 unsigned long long temp;
274
275 ref_clk = clk_get_rate(clk->parent);
276
277 reg = __raw_readl(CCM_SPCTL0);
278 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
279 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
280 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
281 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
282
283 mfi = (mfi <= 5) ? 5 : mfi;
284 temp = 2LL * ref_clk * mfn;
285 do_div(temp, mfd + 1);
286 temp = 2LL * ref_clk * mfi + temp;
287 do_div(temp, pdf + 1);
288
289 return (unsigned long)temp;
290}
291
292static struct clk spll_clk = {
293 .parent = &ckih_clk,
294 .get_rate = get_spll_clk,
295 .enable = _clk_spll_enable,
296 .disable = _clk_spll_disable,
297};
298
299static unsigned long get_hclk_clk(struct clk *clk)
300{
301 unsigned long rate;
302 unsigned long bclk_pdf;
303
304 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
305 >> CCM_CSCR_BCLK_OFFSET;
306
307 rate = clk_get_rate(clk->parent);
308 return rate / (bclk_pdf + 1);
309}
310
311static struct clk hclk_clk = {
312 .parent = &fclk_clk,
313 .get_rate = get_hclk_clk,
314};
315
316static unsigned long get_ipg_clk(struct clk *clk)
317{
318 unsigned long rate;
319 unsigned long ipg_pdf;
320
321 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
322
323 rate = clk_get_rate(clk->parent);
324 return rate / (ipg_pdf + 1);
325}
326
327static struct clk ipg_clk = {
328 .parent = &hclk_clk,
329 .get_rate = get_ipg_clk,
330};
331
332static unsigned long _clk_perclkx_recalc(struct clk *clk)
333{
334 unsigned long perclk_pdf;
335 unsigned long parent_rate;
336
337 parent_rate = clk_get_rate(clk->parent);
338
339 if (clk->id < 0 || clk->id > 3)
340 return 0;
341
342 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
343
344 return parent_rate / (perclk_pdf + 1);
345}
346
347static struct clk per_clk[] = {
348 {
349 .id = 0,
350 .parent = &mpll_clk,
351 .get_rate = _clk_perclkx_recalc,
352 }, {
353 .id = 1,
354 .parent = &mpll_clk,
355 .get_rate = _clk_perclkx_recalc,
356 }, {
357 .id = 2,
358 .parent = &mpll_clk,
359 .round_rate = _clk_perclkx_round_rate,
360 .set_rate = _clk_perclkx_set_rate,
361 .get_rate = _clk_perclkx_recalc,
362 /* Enable/Disable done via lcd_clkc[1] */
363 }, {
364 .id = 3,
365 .parent = &mpll_clk,
366 .round_rate = _clk_perclkx_round_rate,
367 .set_rate = _clk_perclkx_set_rate,
368 .get_rate = _clk_perclkx_recalc,
369 /* Enable/Disable done via csi_clk[1] */
370 },
371};
372
373static struct clk uart_ipg_clk[];
374
375static struct clk uart_clk[] = {
376 {
377 .id = 0,
378 .parent = &per_clk[0],
379 .secondary = &uart_ipg_clk[0],
380 }, {
381 .id = 1,
382 .parent = &per_clk[0],
383 .secondary = &uart_ipg_clk[1],
384 }, {
385 .id = 2,
386 .parent = &per_clk[0],
387 .secondary = &uart_ipg_clk[2],
388 }, {
389 .id = 3,
390 .parent = &per_clk[0],
391 .secondary = &uart_ipg_clk[3],
392 },
393};
394
395static struct clk uart_ipg_clk[] = {
396 {
397 .id = 0,
398 .parent = &ipg_clk,
399 .enable = _clk_enable,
400 .enable_reg = CCM_PCCR_UART1_REG,
401 .enable_shift = CCM_PCCR_UART1_OFFSET,
402 .disable = _clk_disable,
403 }, {
404 .id = 1,
405 .parent = &ipg_clk,
406 .enable = _clk_enable,
407 .enable_reg = CCM_PCCR_UART2_REG,
408 .enable_shift = CCM_PCCR_UART2_OFFSET,
409 .disable = _clk_disable,
410 }, {
411 .id = 2,
412 .parent = &ipg_clk,
413 .enable = _clk_enable,
414 .enable_reg = CCM_PCCR_UART3_REG,
415 .enable_shift = CCM_PCCR_UART3_OFFSET,
416 .disable = _clk_disable,
417 }, {
418 .id = 3,
419 .parent = &ipg_clk,
420 .enable = _clk_enable,
421 .enable_reg = CCM_PCCR_UART4_REG,
422 .enable_shift = CCM_PCCR_UART4_OFFSET,
423 .disable = _clk_disable,
424 },
425};
426
427static struct clk gpt_ipg_clk[];
428
429static struct clk gpt_clk[] = {
430 {
431 .id = 0,
432 .parent = &per_clk[0],
433 .secondary = &gpt_ipg_clk[0],
434 }, {
435 .id = 1,
436 .parent = &per_clk[0],
437 .secondary = &gpt_ipg_clk[1],
438 }, {
439 .id = 2,
440 .parent = &per_clk[0],
441 .secondary = &gpt_ipg_clk[2],
442 },
443};
444
445static struct clk gpt_ipg_clk[] = {
446 {
447 .id = 0,
448 .parent = &ipg_clk,
449 .enable = _clk_enable,
450 .enable_reg = CCM_PCCR_GPT1_REG,
451 .enable_shift = CCM_PCCR_GPT1_OFFSET,
452 .disable = _clk_disable,
453 }, {
454 .id = 1,
455 .parent = &ipg_clk,
456 .enable = _clk_enable,
457 .enable_reg = CCM_PCCR_GPT2_REG,
458 .enable_shift = CCM_PCCR_GPT2_OFFSET,
459 .disable = _clk_disable,
460 }, {
461 .id = 2,
462 .parent = &ipg_clk,
463 .enable = _clk_enable,
464 .enable_reg = CCM_PCCR_GPT3_REG,
465 .enable_shift = CCM_PCCR_GPT3_OFFSET,
466 .disable = _clk_disable,
467 },
468};
469
470static struct clk pwm_clk[] = {
471 {
472 .parent = &per_clk[0],
473 .secondary = &pwm_clk[1],
474 }, {
475 .parent = &ipg_clk,
476 .enable = _clk_enable,
477 .enable_reg = CCM_PCCR_PWM_REG,
478 .enable_shift = CCM_PCCR_PWM_OFFSET,
479 .disable = _clk_disable,
480 },
481};
482
483static struct clk sdhc_ipg_clk[];
484
485static struct clk sdhc_clk[] = {
486 {
487 .id = 0,
488 .parent = &per_clk[1],
489 .secondary = &sdhc_ipg_clk[0],
490 }, {
491 .id = 1,
492 .parent = &per_clk[1],
493 .secondary = &sdhc_ipg_clk[1],
494 },
495};
496
497static struct clk sdhc_ipg_clk[] = {
498 {
499 .id = 0,
500 .parent = &ipg_clk,
501 .enable = _clk_enable,
502 .enable_reg = CCM_PCCR_SDHC1_REG,
503 .enable_shift = CCM_PCCR_SDHC1_OFFSET,
504 .disable = _clk_disable,
505 }, {
506 .id = 1,
507 .parent = &ipg_clk,
508 .enable = _clk_enable,
509 .enable_reg = CCM_PCCR_SDHC2_REG,
510 .enable_shift = CCM_PCCR_SDHC2_OFFSET,
511 .disable = _clk_disable,
512 },
513};
514
515static struct clk cspi_ipg_clk[];
516
517static struct clk cspi_clk[] = {
518 {
519 .id = 0,
520 .parent = &per_clk[1],
521 .secondary = &cspi_ipg_clk[0],
522 }, {
523 .id = 1,
524 .parent = &per_clk[1],
525 .secondary = &cspi_ipg_clk[1],
526 }, {
527 .id = 2,
528 .parent = &per_clk[1],
529 .secondary = &cspi_ipg_clk[2],
530 },
531};
532
533static struct clk cspi_ipg_clk[] = {
534 {
535 .id = 0,
536 .parent = &ipg_clk,
537 .enable = _clk_enable,
538 .enable_reg = CCM_PCCR_CSPI1_REG,
539 .enable_shift = CCM_PCCR_CSPI1_OFFSET,
540 .disable = _clk_disable,
541 }, {
542 .id = 1,
543 .parent = &ipg_clk,
544 .enable = _clk_enable,
545 .enable_reg = CCM_PCCR_CSPI2_REG,
546 .enable_shift = CCM_PCCR_CSPI2_OFFSET,
547 .disable = _clk_disable,
548 }, {
549 .id = 3,
550 .parent = &ipg_clk,
551 .enable = _clk_enable,
552 .enable_reg = CCM_PCCR_CSPI3_REG,
553 .enable_shift = CCM_PCCR_CSPI3_OFFSET,
554 .disable = _clk_disable,
555 },
556};
557
558static struct clk lcdc_clk[] = {
559 {
560 .parent = &per_clk[2],
561 .secondary = &lcdc_clk[1],
562 .round_rate = _clk_parent_round_rate,
563 .set_rate = _clk_parent_set_rate,
564 }, {
565 .parent = &ipg_clk,
566 .secondary = &lcdc_clk[2],
567 .enable = _clk_enable,
568 .enable_reg = CCM_PCCR_LCDC_REG,
569 .enable_shift = CCM_PCCR_LCDC_OFFSET,
570 .disable = _clk_disable,
571 }, {
572 .parent = &hclk_clk,
573 .enable = _clk_enable,
574 .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
575 .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
576 .disable = _clk_disable,
577 },
578};
579
580static struct clk csi_clk[] = {
581 {
582 .parent = &per_clk[3],
583 .secondary = &csi_clk[1],
584 .round_rate = _clk_parent_round_rate,
585 .set_rate = _clk_parent_set_rate,
586 }, {
587 .parent = &hclk_clk,
588 .enable = _clk_enable,
589 .enable_reg = CCM_PCCR_HCLK_CSI_REG,
590 .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
591 .disable = _clk_disable,
592 },
593};
594
595static struct clk usb_clk[] = {
596 {
597 .parent = &spll_clk,
598 .get_rate = _clk_usb_recalc,
599 .enable = _clk_enable,
600 .enable_reg = CCM_PCCR_USBOTG_REG,
601 .enable_shift = CCM_PCCR_USBOTG_OFFSET,
602 .disable = _clk_disable,
603 }, {
604 .parent = &hclk_clk,
605 .enable = _clk_enable,
606 .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
607 .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
608 .disable = _clk_disable,
609 }
610};
611
612static struct clk ssi_ipg_clk[];
613
614static struct clk ssi_clk[] = {
615 {
616 .id = 0,
617 .parent = &mpll_clk,
618 .secondary = &ssi_ipg_clk[0],
619 .get_rate = _clk_ssi1_recalc,
620 .enable = _clk_enable,
621 .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
622 .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
623 .disable = _clk_disable,
624 }, {
625 .id = 1,
626 .parent = &mpll_clk,
627 .secondary = &ssi_ipg_clk[1],
628 .get_rate = _clk_ssi2_recalc,
629 .enable = _clk_enable,
630 .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
631 .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
632 .disable = _clk_disable,
633 },
634};
635
636static struct clk ssi_ipg_clk[] = {
637 {
638 .id = 0,
639 .parent = &ipg_clk,
640 .enable = _clk_enable,
641 .enable_reg = CCM_PCCR_SSI1_REG,
642 .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
643 .disable = _clk_disable,
644 }, {
645 .id = 1,
646 .parent = &ipg_clk,
647 .enable = _clk_enable,
648 .enable_reg = CCM_PCCR_SSI2_REG,
649 .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
650 .disable = _clk_disable,
651 },
652};
653
654
655static struct clk nfc_clk = {
656 .parent = &fclk_clk,
657 .get_rate = _clk_nfc_recalc,
658 .enable = _clk_enable,
659 .enable_reg = CCM_PCCR_NFC_REG,
660 .enable_shift = CCM_PCCR_NFC_OFFSET,
661 .disable = _clk_disable,
662};
663
664static struct clk dma_clk[] = {
665 {
666 .parent = &hclk_clk,
667 .enable = _clk_enable,
668 .enable_reg = CCM_PCCR_DMA_REG,
669 .enable_shift = CCM_PCCR_DMA_OFFSET,
670 .disable = _clk_disable,
671 .secondary = &dma_clk[1],
672 }, {
673 .enable = _clk_enable,
674 .enable_reg = CCM_PCCR_HCLK_DMA_REG,
675 .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
676 .disable = _clk_disable,
677 },
678};
679
680static struct clk brom_clk = {
681 .parent = &hclk_clk,
682 .enable = _clk_enable,
683 .enable_reg = CCM_PCCR_HCLK_BROM_REG,
684 .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
685 .disable = _clk_disable,
686};
687
688static struct clk emma_clk[] = {
689 {
690 .parent = &hclk_clk,
691 .enable = _clk_enable,
692 .enable_reg = CCM_PCCR_EMMA_REG,
693 .enable_shift = CCM_PCCR_EMMA_OFFSET,
694 .disable = _clk_disable,
695 .secondary = &emma_clk[1],
696 }, {
697 .enable = _clk_enable,
698 .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
699 .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
700 .disable = _clk_disable,
701 }
702};
703
704static struct clk slcdc_clk[] = {
705 {
706 .parent = &hclk_clk,
707 .enable = _clk_enable,
708 .enable_reg = CCM_PCCR_SLCDC_REG,
709 .enable_shift = CCM_PCCR_SLCDC_OFFSET,
710 .disable = _clk_disable,
711 .secondary = &slcdc_clk[1],
712 }, {
713 .enable = _clk_enable,
714 .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
715 .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
716 .disable = _clk_disable,
717 }
718};
719
720static struct clk wdog_clk = {
721 .parent = &ipg_clk,
722 .enable = _clk_enable,
723 .enable_reg = CCM_PCCR_WDT_REG,
724 .enable_shift = CCM_PCCR_WDT_OFFSET,
725 .disable = _clk_disable,
726};
727
728static struct clk gpio_clk = {
729 .parent = &ipg_clk,
730 .enable = _clk_enable,
731 .enable_reg = CCM_PCCR_GPIO_REG,
732 .enable_shift = CCM_PCCR_GPIO_OFFSET,
733 .disable = _clk_disable,
734};
735
736static struct clk i2c_clk = {
737 .id = 0,
738 .parent = &ipg_clk,
739 .enable = _clk_enable,
740 .enable_reg = CCM_PCCR_I2C1_REG,
741 .enable_shift = CCM_PCCR_I2C1_OFFSET,
742 .disable = _clk_disable,
743};
744
745static struct clk kpp_clk = {
746 .parent = &ipg_clk,
747 .enable = _clk_enable,
748 .enable_reg = CCM_PCCR_KPP_REG,
749 .enable_shift = CCM_PCCR_KPP_OFFSET,
750 .disable = _clk_disable,
751};
752
753static struct clk owire_clk = {
754 .parent = &ipg_clk,
755 .enable = _clk_enable,
756 .enable_reg = CCM_PCCR_OWIRE_REG,
757 .enable_shift = CCM_PCCR_OWIRE_OFFSET,
758 .disable = _clk_disable,
759};
760
761static struct clk rtc_clk = {
762 .parent = &ipg_clk,
763 .enable = _clk_enable,
764 .enable_reg = CCM_PCCR_RTC_REG,
765 .enable_shift = CCM_PCCR_RTC_OFFSET,
766 .disable = _clk_disable,
767};
768
769static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
770{
771 u32 div;
772 unsigned long parent_rate;
773
774 parent_rate = clk_get_rate(clk->parent);
775 div = parent_rate / rate;
776 if (parent_rate % rate)
777 div++;
778
779 if (div > 8)
780 div = 8;
781
782 return parent_rate / div;
783}
784
785static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
786{
787 u32 reg;
788 u32 div;
789 unsigned long parent_rate;
790
791 parent_rate = clk_get_rate(clk->parent);
792
793 div = parent_rate / rate;
794
795 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
796 return -EINVAL;
797 div--;
798
799 reg = __raw_readl(CCM_PCDR0);
800
801 if (clk->parent == &usb_clk[0]) {
802 reg &= ~CCM_PCDR0_48MDIV_MASK;
803 reg |= div << CCM_PCDR0_48MDIV_OFFSET;
804 }
805 __raw_writel(reg, CCM_PCDR0);
806
807 return 0;
808}
809
810static unsigned long _clk_clko_recalc(struct clk *clk)
811{
812 u32 div = 0;
813 unsigned long parent_rate;
814
815 parent_rate = clk_get_rate(clk->parent);
816
817 if (clk->parent == &usb_clk[0]) /* 48M */
818 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
819 >> CCM_PCDR0_48MDIV_OFFSET;
820 div++;
821
822 return parent_rate / div;
823}
824
825static struct clk clko_clk;
826
827static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
828{
829 u32 reg;
830
831 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
832
833 if (parent == &ckil_clk)
834 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
835 else if (parent == &fpm_clk)
836 reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
837 else if (parent == &ckih_clk)
838 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
839 else if (parent == mpll_clk.parent)
840 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
841 else if (parent == spll_clk.parent)
842 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
843 else if (parent == &mpll_clk)
844 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
845 else if (parent == &spll_clk)
846 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
847 else if (parent == &fclk_clk)
848 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
849 else if (parent == &hclk_clk)
850 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
851 else if (parent == &ipg_clk)
852 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
853 else if (parent == &per_clk[0])
854 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
855 else if (parent == &per_clk[1])
856 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
857 else if (parent == &per_clk[2])
858 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
859 else if (parent == &per_clk[3])
860 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
861 else if (parent == &ssi_clk[0])
862 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
863 else if (parent == &ssi_clk[1])
864 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
865 else if (parent == &nfc_clk)
866 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
867 else if (parent == &usb_clk[0])
868 reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
869 else if (parent == &clko_clk)
870 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
871 else
872 return -EINVAL;
873
874 __raw_writel(reg, CCM_CCSR);
875
876 return 0;
877}
878
879static struct clk clko_clk = {
880 .get_rate = _clk_clko_recalc,
881 .set_rate = _clk_clko_set_rate,
882 .round_rate = _clk_clko_round_rate,
883 .set_parent = _clk_clko_set_parent,
884};
885
886
887#define _REGISTER_CLOCK(d, n, c) \
888 { \
889 .dev_id = d, \
890 .con_id = n, \
891 .clk = &c, \
892 },
893static struct clk_lookup lookups[] __initdata = {
894/* It's unlikely that any driver wants one of them directly:
895 _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
896 _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
897 _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
898 _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
899 _REGISTER_CLOCK(NULL, "spll", spll_clk)
900 _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
901 _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
902 _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
903*/
904 _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
905 _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
906 _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
907 _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
908 _REGISTER_CLOCK(NULL, "clko", clko_clk)
909 _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0])
910 _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
911 _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
912 _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3])
913 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
914 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
915 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
916 _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
917 _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
918 _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
919 _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0])
920 _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1])
921 _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2])
922 _REGISTER_CLOCK(NULL, "lcdc", lcdc_clk[0])
923 _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
924 _REGISTER_CLOCK(NULL, "usb", usb_clk[0])
925 _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
926 _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
927 _REGISTER_CLOCK(NULL, "nfc", nfc_clk)
928 _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
929 _REGISTER_CLOCK(NULL, "brom", brom_clk)
930 _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
931 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
932 _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
933 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
934 _REGISTER_CLOCK(NULL, "i2c", i2c_clk)
935 _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
936 _REGISTER_CLOCK(NULL, "owire", owire_clk)
937 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
938};
939
940/*
941 * must be called very early to get information about the
942 * available clock rate when the timer framework starts
943 */
944int __init mx21_clocks_init(unsigned long lref, unsigned long href)
945{
946 int i;
947 u32 cscr;
948
949 external_low_reference = lref;
950 external_high_reference = href;
951
952 /* detect clock reference for both system PLL */
953 cscr = CSCR();
954 if (cscr & CCM_CSCR_MCU)
955 mpll_clk.parent = &ckih_clk;
956 else
957 mpll_clk.parent = &fpm_clk;
958
959 if (cscr & CCM_CSCR_SP)
960 spll_clk.parent = &ckih_clk;
961 else
962 spll_clk.parent = &fpm_clk;
963
964 for (i = 0; i < ARRAY_SIZE(lookups); i++)
965 clkdev_add(&lookups[i]);
966
967 /* Turn off all clock gates */
968 __raw_writel(0, CCM_PCCR0);
969 __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
970
971 /* This turns of the serial PLL as well */
972 spll_clk.disable(&spll_clk);
973
974 /* This will propagate to all children and init all the clock rates. */
975 clk_enable(&per_clk[0]);
976 clk_enable(&gpio_clk);
977
978#ifdef CONFIG_DEBUG_LL_CONSOLE
979 clk_enable(&uart_clk[0]);
980#endif
981
982 mxc_timer_init(&gpt_clk[0]);
983 return 0;
984}
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index c69896d011a1..3f7280c490f0 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
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
@@ -20,23 +21,60 @@
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/spinlock.h>
24 24
25#include <mach/clock.h> 25#include <asm/clkdev.h>
26#include <mach/common.h>
27#include <asm/div64.h> 26#include <asm/div64.h>
28 27
29#include "crm_regs.h" 28#include <mach/clock.h>
30 29#include <mach/common.h>
31static struct clk ckil_clk; 30#include <mach/hardware.h>
32static struct clk mpll_clk; 31
33static struct clk mpll_main_clk[]; 32/* Register offsets */
34static struct clk spll_clk; 33#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
35 34#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
36static int _clk_enable(struct clk *clk) 35#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
36#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
37#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
38#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
39#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
40#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
41#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
42#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
43#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
44#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
45#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
46#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
47
48#define CCM_CSCR_UPDATE_DIS (1 << 31)
49#define CCM_CSCR_SSI2 (1 << 23)
50#define CCM_CSCR_SSI1 (1 << 22)
51#define CCM_CSCR_VPU (1 << 21)
52#define CCM_CSCR_MSHC (1 << 20)
53#define CCM_CSCR_SPLLRES (1 << 19)
54#define CCM_CSCR_MPLLRES (1 << 18)
55#define CCM_CSCR_SP (1 << 17)
56#define CCM_CSCR_MCU (1 << 16)
57#define CCM_CSCR_OSC26MDIV (1 << 4)
58#define CCM_CSCR_OSC26M (1 << 3)
59#define CCM_CSCR_FPM (1 << 2)
60#define CCM_CSCR_SPEN (1 << 1)
61#define CCM_CSCR_MPEN (1 << 0)
62
63/* i.MX27 TO 2+ */
64#define CCM_CSCR_ARM_SRC (1 << 15)
65
66#define CCM_SPCTL1_LF (1 << 15)
67#define CCM_SPCTL1_BRMO (1 << 6)
68
69static struct clk mpll_main1_clk, mpll_main2_clk;
70
71static int clk_pccr_enable(struct clk *clk)
37{ 72{
38 unsigned long reg; 73 unsigned long reg;
39 74
75 if (!clk->enable_reg)
76 return 0;
77
40 reg = __raw_readl(clk->enable_reg); 78 reg = __raw_readl(clk->enable_reg);
41 reg |= 1 << clk->enable_shift; 79 reg |= 1 << clk->enable_shift;
42 __raw_writel(reg, clk->enable_reg); 80 __raw_writel(reg, clk->enable_reg);
@@ -44,16 +82,19 @@ static int _clk_enable(struct clk *clk)
44 return 0; 82 return 0;
45} 83}
46 84
47static void _clk_disable(struct clk *clk) 85static void clk_pccr_disable(struct clk *clk)
48{ 86{
49 unsigned long reg; 87 unsigned long reg;
50 88
89 if (!clk->enable_reg)
90 return;
91
51 reg = __raw_readl(clk->enable_reg); 92 reg = __raw_readl(clk->enable_reg);
52 reg &= ~(1 << clk->enable_shift); 93 reg &= ~(1 << clk->enable_shift);
53 __raw_writel(reg, clk->enable_reg); 94 __raw_writel(reg, clk->enable_reg);
54} 95}
55 96
56static int _clk_spll_enable(struct clk *clk) 97static int clk_spll_enable(struct clk *clk)
57{ 98{
58 unsigned long reg; 99 unsigned long reg;
59 100
@@ -61,13 +102,12 @@ static int _clk_spll_enable(struct clk *clk)
61 reg |= CCM_CSCR_SPEN; 102 reg |= CCM_CSCR_SPEN;
62 __raw_writel(reg, CCM_CSCR); 103 __raw_writel(reg, CCM_CSCR);
63 104
64 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) 105 while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
65 ;
66 106
67 return 0; 107 return 0;
68} 108}
69 109
70static void _clk_spll_disable(struct clk *clk) 110static void clk_spll_disable(struct clk *clk)
71{ 111{
72 unsigned long reg; 112 unsigned long reg;
73 113
@@ -76,192 +116,30 @@ static void _clk_spll_disable(struct clk *clk)
76 __raw_writel(reg, CCM_CSCR); 116 __raw_writel(reg, CCM_CSCR);
77} 117}
78 118
79static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1) 119static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
80{
81 unsigned long reg;
82
83 reg = __raw_readl(CCM_PCCR0);
84 reg |= mask0;
85 __raw_writel(reg, CCM_PCCR0);
86
87 reg = __raw_readl(CCM_PCCR1);
88 reg |= mask1;
89 __raw_writel(reg, CCM_PCCR1);
90
91}
92
93static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
94{
95 unsigned long reg;
96
97 reg = __raw_readl(CCM_PCCR0);
98 reg &= ~mask0;
99 __raw_writel(reg, CCM_PCCR0);
100
101 reg = __raw_readl(CCM_PCCR1);
102 reg &= ~mask1;
103 __raw_writel(reg, CCM_PCCR1);
104}
105
106static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
107{
108 unsigned long reg;
109
110 reg = __raw_readl(CCM_PCCR1);
111 reg |= mask1;
112 __raw_writel(reg, CCM_PCCR1);
113
114 reg = __raw_readl(CCM_PCCR0);
115 reg |= mask0;
116 __raw_writel(reg, CCM_PCCR0);
117}
118
119static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
120{
121 unsigned long reg;
122
123 reg = __raw_readl(CCM_PCCR1);
124 reg &= ~mask1;
125 __raw_writel(reg, CCM_PCCR1);
126
127 reg = __raw_readl(CCM_PCCR0);
128 reg &= ~mask0;
129 __raw_writel(reg, CCM_PCCR0);
130}
131
132static int _clk_dma_enable(struct clk *clk)
133{
134 _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
135
136 return 0;
137}
138
139static void _clk_dma_disable(struct clk *clk)
140{
141 _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
142}
143
144static int _clk_rtic_enable(struct clk *clk)
145{
146 _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
147
148 return 0;
149}
150
151static void _clk_rtic_disable(struct clk *clk)
152{
153 _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
154}
155
156static int _clk_emma_enable(struct clk *clk)
157{
158 _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
159
160 return 0;
161}
162
163static void _clk_emma_disable(struct clk *clk)
164{
165 _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
166}
167
168static int _clk_slcdc_enable(struct clk *clk)
169{
170 _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
171
172 return 0;
173}
174
175static void _clk_slcdc_disable(struct clk *clk)
176{
177 _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
178}
179
180static int _clk_fec_enable(struct clk *clk)
181{
182 _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
183
184 return 0;
185}
186
187static void _clk_fec_disable(struct clk *clk)
188{
189 _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
190}
191
192static int _clk_vpu_enable(struct clk *clk)
193{
194 unsigned long reg;
195
196 reg = __raw_readl(CCM_PCCR1);
197 reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
198 __raw_writel(reg, CCM_PCCR1);
199
200 return 0;
201}
202
203static void _clk_vpu_disable(struct clk *clk)
204{ 120{
205 unsigned long reg; 121 int cscr = __raw_readl(CCM_CSCR);
206
207 reg = __raw_readl(CCM_PCCR1);
208 reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
209 __raw_writel(reg, CCM_PCCR1);
210}
211
212static int _clk_sahara2_enable(struct clk *clk)
213{
214 _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
215
216 return 0;
217}
218
219static void _clk_sahara2_disable(struct clk *clk)
220{
221 _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
222}
223
224static int _clk_mstick1_enable(struct clk *clk)
225{
226 _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
227
228 return 0;
229}
230
231static void _clk_mstick1_disable(struct clk *clk)
232{
233 _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
234}
235
236#define CSCR() (__raw_readl(CCM_CSCR))
237#define PCDR0() (__raw_readl(CCM_PCDR0))
238#define PCDR1() (__raw_readl(CCM_PCDR1))
239
240static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
241{
242 int cscr = CSCR();
243 122
244 if (clk->parent == parent) 123 if (clk->parent == parent)
245 return 0; 124 return 0;
246 125
247 if (mx27_revision() >= CHIP_REV_2_0) { 126 if (mx27_revision() >= CHIP_REV_2_0) {
248 if (parent == &mpll_main_clk[0]) { 127 if (parent == &mpll_main1_clk) {
249 cscr |= CCM_CSCR_ARM_SRC; 128 cscr |= CCM_CSCR_ARM_SRC;
250 } else { 129 } else {
251 if (parent == &mpll_main_clk[1]) 130 if (parent == &mpll_main2_clk)
252 cscr &= ~CCM_CSCR_ARM_SRC; 131 cscr &= ~CCM_CSCR_ARM_SRC;
253 else 132 else
254 return -EINVAL; 133 return -EINVAL;
255 } 134 }
256 __raw_writel(cscr, CCM_CSCR); 135 __raw_writel(cscr, CCM_CSCR);
257 } else 136 clk->parent = parent;
258 return -ENODEV; 137 return 0;
259 138 }
260 clk->parent = parent; 139 return -ENODEV;
261 return 0;
262} 140}
263 141
264static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) 142static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
265{ 143{
266 int div; 144 int div;
267 unsigned long parent_rate; 145 unsigned long parent_rate;
@@ -278,7 +156,7 @@ static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
278 return parent_rate / div; 156 return parent_rate / div;
279} 157}
280 158
281static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) 159static int set_rate_cpu(struct clk *clk, unsigned long rate)
282{ 160{
283 unsigned int div; 161 unsigned int div;
284 uint32_t reg; 162 uint32_t reg;
@@ -295,19 +173,18 @@ static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
295 173
296 reg = __raw_readl(CCM_CSCR); 174 reg = __raw_readl(CCM_CSCR);
297 if (mx27_revision() >= CHIP_REV_2_0) { 175 if (mx27_revision() >= CHIP_REV_2_0) {
298 reg &= ~CCM_CSCR_ARM_MASK; 176 reg &= ~(3 << 12);
299 reg |= div << CCM_CSCR_ARM_OFFSET; 177 reg |= div << 12;
300 reg &= ~0x06; 178 reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
301 __raw_writel(reg | 0x80000000, CCM_CSCR); 179 __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
302 } else { 180 } else {
303 printk(KERN_ERR "Cant set CPU frequency!\n"); 181 printk(KERN_ERR "Can't set CPU frequency!\n");
304 } 182 }
305 183
306 return 0; 184 return 0;
307} 185}
308 186
309static unsigned long _clk_perclkx_round_rate(struct clk *clk, 187static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
310 unsigned long rate)
311{ 188{
312 u32 div; 189 u32 div;
313 unsigned long parent_rate; 190 unsigned long parent_rate;
@@ -324,7 +201,7 @@ static unsigned long _clk_perclkx_round_rate(struct clk *clk,
324 return parent_rate / div; 201 return parent_rate / div;
325} 202}
326 203
327static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) 204static int set_rate_per(struct clk *clk, unsigned long rate)
328{ 205{
329 u32 reg; 206 u32 reg;
330 u32 div; 207 u32 div;
@@ -340,84 +217,65 @@ static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
340 return -EINVAL; 217 return -EINVAL;
341 div--; 218 div--;
342 219
343 reg = 220 reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
344 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
345 (clk->id << 3));
346 reg |= div << (clk->id << 3); 221 reg |= div << (clk->id << 3);
347 __raw_writel(reg, CCM_PCDR1); 222 __raw_writel(reg, CCM_PCDR1);
348 223
349 return 0; 224 return 0;
350} 225}
351 226
352static unsigned long _clk_usb_recalc(struct clk *clk) 227static unsigned long get_rate_usb(struct clk *clk)
353{ 228{
354 unsigned long usb_pdf; 229 unsigned long usb_pdf;
355 unsigned long parent_rate; 230 unsigned long parent_rate;
356 231
357 parent_rate = clk_get_rate(clk->parent); 232 parent_rate = clk_get_rate(clk->parent);
358 233
359 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; 234 usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
360 235
361 return parent_rate / (usb_pdf + 1U); 236 return parent_rate / (usb_pdf + 1U);
362} 237}
363 238
364static unsigned long _clk_ssi1_recalc(struct clk *clk) 239static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
365{ 240{
366 unsigned long ssi1_pdf;
367 unsigned long parent_rate; 241 unsigned long parent_rate;
368 242
369 parent_rate = clk_get_rate(clk->parent); 243 parent_rate = clk_get_rate(clk->parent);
370 244
371 ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
372 CCM_PCDR0_SSI1BAUDDIV_OFFSET;
373
374 if (mx27_revision() >= CHIP_REV_2_0) 245 if (mx27_revision() >= CHIP_REV_2_0)
375 ssi1_pdf += 4; 246 pdf += 4; /* MX27 TO2+ */
376 else 247 else
377 ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf; 248 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
378 249
379 return 2UL * parent_rate / ssi1_pdf; 250 return 2UL * parent_rate / pdf;
380} 251}
381 252
382static unsigned long _clk_ssi2_recalc(struct clk *clk) 253static unsigned long get_rate_ssi1(struct clk *clk)
383{ 254{
384 unsigned long ssi2_pdf; 255 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
385 unsigned long parent_rate; 256}
386
387 parent_rate = clk_get_rate(clk->parent);
388
389 ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
390 CCM_PCDR0_SSI2BAUDDIV_OFFSET;
391
392 if (mx27_revision() >= CHIP_REV_2_0)
393 ssi2_pdf += 4;
394 else
395 ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
396 257
397 return 2UL * parent_rate / ssi2_pdf; 258static unsigned long get_rate_ssi2(struct clk *clk)
259{
260 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
398} 261}
399 262
400static unsigned long _clk_nfc_recalc(struct clk *clk) 263static unsigned long get_rate_nfc(struct clk *clk)
401{ 264{
402 unsigned long nfc_pdf; 265 unsigned long nfc_pdf;
403 unsigned long parent_rate; 266 unsigned long parent_rate;
404 267
405 parent_rate = clk_get_rate(clk->parent); 268 parent_rate = clk_get_rate(clk->parent);
406 269
407 if (mx27_revision() >= CHIP_REV_2_0) { 270 if (mx27_revision() >= CHIP_REV_2_0)
408 nfc_pdf = 271 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
409 (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >> 272 else
410 CCM_PCDR0_NFCDIV2_OFFSET; 273 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
411 } else {
412 nfc_pdf =
413 (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
414 CCM_PCDR0_NFCDIV_OFFSET;
415 }
416 274
417 return parent_rate / (nfc_pdf + 1); 275 return parent_rate / (nfc_pdf + 1);
418} 276}
419 277
420static unsigned long _clk_vpu_recalc(struct clk *clk) 278static unsigned long get_rate_vpu(struct clk *clk)
421{ 279{
422 unsigned long vpu_pdf; 280 unsigned long vpu_pdf;
423 unsigned long parent_rate; 281 unsigned long parent_rate;
@@ -425,25 +283,27 @@ static unsigned long _clk_vpu_recalc(struct clk *clk)
425 parent_rate = clk_get_rate(clk->parent); 283 parent_rate = clk_get_rate(clk->parent);
426 284
427 if (mx27_revision() >= CHIP_REV_2_0) { 285 if (mx27_revision() >= CHIP_REV_2_0) {
428 vpu_pdf = 286 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
429 (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
430 CCM_PCDR0_VPUDIV2_OFFSET;
431 vpu_pdf += 4; 287 vpu_pdf += 4;
432 } else { 288 } else {
433 vpu_pdf = 289 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
434 (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
435 CCM_PCDR0_VPUDIV_OFFSET;
436 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; 290 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
437 } 291 }
292
438 return 2UL * parent_rate / vpu_pdf; 293 return 2UL * parent_rate / vpu_pdf;
439} 294}
440 295
441static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) 296static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
442{ 297{
443 return clk->parent->round_rate(clk->parent, rate); 298 return clk->parent->round_rate(clk->parent, rate);
444} 299}
445 300
446static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) 301static unsigned long get_rate_parent(struct clk *clk)
302{
303 return clk_get_rate(clk->parent);
304}
305
306static int set_rate_parent(struct clk *clk, unsigned long rate)
447{ 307{
448 return clk->parent->set_rate(clk->parent, rate); 308 return clk->parent->set_rate(clk->parent, rate);
449} 309}
@@ -451,1112 +311,380 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
451/* in Hz */ 311/* in Hz */
452static unsigned long external_high_reference = 26000000; 312static unsigned long external_high_reference = 26000000;
453 313
454static unsigned long get_high_reference_clock_rate(struct clk *clk) 314static unsigned long get_rate_high_reference(struct clk *clk)
455{ 315{
456 return external_high_reference; 316 return external_high_reference;
457} 317}
458 318
459/*
460 * the high frequency external clock reference
461 * Default case is 26MHz. Could be changed at runtime
462 * with a call to change_external_high_reference()
463 */
464static struct clk ckih_clk = {
465 .name = "ckih",
466 .get_rate = get_high_reference_clock_rate,
467};
468
469/* in Hz */ 319/* in Hz */
470static unsigned long external_low_reference = 32768; 320static unsigned long external_low_reference = 32768;
471 321
472static unsigned long get_low_reference_clock_rate(struct clk *clk) 322static unsigned long get_rate_low_reference(struct clk *clk)
473{ 323{
474 return external_low_reference; 324 return external_low_reference;
475} 325}
476 326
477/* 327static unsigned long get_rate_fpm(struct clk *clk)
478 * the low frequency external clock reference
479 * Default case is 32.768kHz Could be changed at runtime
480 * with a call to change_external_low_reference()
481 */
482static struct clk ckil_clk = {
483 .name = "ckil",
484 .get_rate = get_low_reference_clock_rate,
485};
486
487static unsigned long get_mpll_clk(struct clk *clk)
488{ 328{
489 uint32_t reg; 329 return clk_get_rate(clk->parent) * 1024;
490 unsigned long ref_clk;
491 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
492 unsigned long long temp;
493
494 ref_clk = clk_get_rate(clk->parent);
495
496 reg = __raw_readl(CCM_MPCTL0);
497 pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
498 mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
499 mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
500 mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
501
502 mfi = (mfi <= 5) ? 5 : mfi;
503 temp = 2LL * ref_clk * mfn;
504 do_div(temp, mfd + 1);
505 temp = 2LL * ref_clk * mfi + temp;
506 do_div(temp, pdf + 1);
507
508 return (unsigned long)temp;
509} 330}
510 331
511static struct clk mpll_clk = { 332static unsigned long get_rate_mpll(struct clk *clk)
512 .name = "mpll", 333{
513 .parent = &ckih_clk, 334 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
514 .get_rate = get_mpll_clk, 335 clk_get_rate(clk->parent));
515}; 336}
516 337
517static unsigned long _clk_mpll_main_get_rate(struct clk *clk) 338static unsigned long get_rate_mpll_main(struct clk *clk)
518{ 339{
519 unsigned long parent_rate; 340 unsigned long parent_rate;
520 341
521 parent_rate = clk_get_rate(clk->parent); 342 parent_rate = clk_get_rate(clk->parent);
522 343
523 /* i.MX27 TO2: 344 /* i.MX27 TO2:
524 * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2 345 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
525 * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3 346 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
526 */ 347 */
527
528 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1) 348 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
529 return 2UL * parent_rate / 3UL; 349 return 2UL * parent_rate / 3UL;
530 350
531 return parent_rate; 351 return parent_rate;
532} 352}
533 353
534static struct clk mpll_main_clk[] = { 354static unsigned long get_rate_spll(struct clk *clk)
535 {
536 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
537 * It provide the clock source whose rate is same as MPLL
538 */
539 .name = "mpll_main",
540 .id = 0,
541 .parent = &mpll_clk,
542 .get_rate = _clk_mpll_main_get_rate
543 }, {
544 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
545 * It provide the clock source whose rate is same MPLL * 2/3
546 */
547 .name = "mpll_main",
548 .id = 1,
549 .parent = &mpll_clk,
550 .get_rate = _clk_mpll_main_get_rate
551 }
552};
553
554static unsigned long get_spll_clk(struct clk *clk)
555{ 355{
556 uint32_t reg; 356 uint32_t reg;
557 unsigned long ref_clk; 357 unsigned long rate;
558 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
559 unsigned long long temp;
560 358
561 ref_clk = clk_get_rate(clk->parent); 359 rate = clk_get_rate(clk->parent);
562 360
563 reg = __raw_readl(CCM_SPCTL0); 361 reg = __raw_readl(CCM_SPCTL0);
564 /*TODO: This is TO2 Bug */ 362
363 /* On TO2 we have to write the value back. Otherwise we
364 * read 0 from this register the next time.
365 */
565 if (mx27_revision() >= CHIP_REV_2_0) 366 if (mx27_revision() >= CHIP_REV_2_0)
566 __raw_writel(reg, CCM_SPCTL0); 367 __raw_writel(reg, CCM_SPCTL0);
567 368
568 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; 369 return mxc_decode_pll(reg, rate);
569 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
570 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
571 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
572
573 mfi = (mfi <= 5) ? 5 : mfi;
574 temp = 2LL * ref_clk * mfn;
575 do_div(temp, mfd + 1);
576 temp = 2LL * ref_clk * mfi + temp;
577 do_div(temp, pdf + 1);
578
579 return (unsigned long)temp;
580} 370}
581 371
582static struct clk spll_clk = { 372static unsigned long get_rate_cpu(struct clk *clk)
583 .name = "spll",
584 .parent = &ckih_clk,
585 .get_rate = get_spll_clk,
586 .enable = _clk_spll_enable,
587 .disable = _clk_spll_disable,
588};
589
590static unsigned long get_cpu_clk(struct clk *clk)
591{ 373{
592 u32 div; 374 u32 div;
593 unsigned long rate; 375 unsigned long rate;
594 376
595 if (mx27_revision() >= CHIP_REV_2_0) 377 if (mx27_revision() >= CHIP_REV_2_0)
596 div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET; 378 div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
597 else 379 else
598 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; 380 div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
599 381
600 rate = clk_get_rate(clk->parent); 382 rate = clk_get_rate(clk->parent);
601 return rate / (div + 1); 383 return rate / (div + 1);
602} 384}
603 385
604static struct clk cpu_clk = { 386static unsigned long get_rate_ahb(struct clk *clk)
605 .name = "cpu_clk",
606 .parent = &mpll_main_clk[1],
607 .set_parent = _clk_cpu_set_parent,
608 .round_rate = _clk_cpu_round_rate,
609 .get_rate = get_cpu_clk,
610 .set_rate = _clk_cpu_set_rate,
611};
612
613static unsigned long get_ahb_clk(struct clk *clk)
614{ 387{
615 unsigned long rate; 388 unsigned long rate, bclk_pdf;
616 unsigned long bclk_pdf;
617 389
618 if (mx27_revision() >= CHIP_REV_2_0) 390 if (mx27_revision() >= CHIP_REV_2_0)
619 bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) 391 bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
620 >> CCM_CSCR_AHB_OFFSET;
621 else 392 else
622 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) 393 bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
623 >> CCM_CSCR_BCLK_OFFSET;
624 394
625 rate = clk_get_rate(clk->parent); 395 rate = clk_get_rate(clk->parent);
626 return rate / (bclk_pdf + 1); 396 return rate / (bclk_pdf + 1);
627} 397}
628 398
629static struct clk ahb_clk = { 399static unsigned long get_rate_ipg(struct clk *clk)
630 .name = "ahb_clk",
631 .parent = &mpll_main_clk[1],
632 .get_rate = get_ahb_clk,
633};
634
635static unsigned long get_ipg_clk(struct clk *clk)
636{ 400{
637 unsigned long rate; 401 unsigned long rate, ipg_pdf;
638 unsigned long ipg_pdf;
639 402
640 if (mx27_revision() >= CHIP_REV_2_0) 403 if (mx27_revision() >= CHIP_REV_2_0)
641 return clk_get_rate(clk->parent); 404 return clk_get_rate(clk->parent);
642 else 405 else
643 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; 406 ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
644 407
645 rate = clk_get_rate(clk->parent); 408 rate = clk_get_rate(clk->parent);
646 return rate / (ipg_pdf + 1); 409 return rate / (ipg_pdf + 1);
647} 410}
648 411
649static struct clk ipg_clk = { 412static unsigned long get_rate_per(struct clk *clk)
650 .name = "ipg_clk",
651 .parent = &ahb_clk,
652 .get_rate = get_ipg_clk,
653};
654
655static unsigned long _clk_perclkx_recalc(struct clk *clk)
656{ 413{
657 unsigned long perclk_pdf; 414 unsigned long perclk_pdf, parent_rate;
658 unsigned long parent_rate;
659 415
660 parent_rate = clk_get_rate(clk->parent); 416 parent_rate = clk_get_rate(clk->parent);
661 417
662 if (clk->id < 0 || clk->id > 3) 418 if (clk->id < 0 || clk->id > 3)
663 return 0; 419 return 0;
664 420
665 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; 421 perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
666 422
667 return parent_rate / (perclk_pdf + 1); 423 return parent_rate / (perclk_pdf + 1);
668} 424}
669 425
670static struct clk per_clk[] = { 426/*
671 { 427 * the high frequency external clock reference
672 .name = "per_clk", 428 * Default case is 26MHz. Could be changed at runtime
673 .id = 0, 429 * with a call to change_external_high_reference()
674 .parent = &mpll_main_clk[1], 430 */
675 .get_rate = _clk_perclkx_recalc, 431static struct clk ckih_clk = {
676 .enable = _clk_enable, 432 .get_rate = get_rate_high_reference,
677 .enable_reg = CCM_PCCR1,
678 .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
679 .disable = _clk_disable,
680 }, {
681 .name = "per_clk",
682 .id = 1,
683 .parent = &mpll_main_clk[1],
684 .get_rate = _clk_perclkx_recalc,
685 .enable = _clk_enable,
686 .enable_reg = CCM_PCCR1,
687 .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
688 .disable = _clk_disable,
689 }, {
690 .name = "per_clk",
691 .id = 2,
692 .parent = &mpll_main_clk[1],
693 .round_rate = _clk_perclkx_round_rate,
694 .set_rate = _clk_perclkx_set_rate,
695 .get_rate = _clk_perclkx_recalc,
696 .enable = _clk_enable,
697 .enable_reg = CCM_PCCR1,
698 .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
699 .disable = _clk_disable,
700 }, {
701 .name = "per_clk",
702 .id = 3,
703 .parent = &mpll_main_clk[1],
704 .round_rate = _clk_perclkx_round_rate,
705 .set_rate = _clk_perclkx_set_rate,
706 .get_rate = _clk_perclkx_recalc,
707 .enable = _clk_enable,
708 .enable_reg = CCM_PCCR1,
709 .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
710 .disable = _clk_disable,
711 },
712};
713
714struct clk uart1_clk[] = {
715 {
716 .name = "uart_clk",
717 .id = 0,
718 .parent = &per_clk[0],
719 .secondary = &uart1_clk[1],
720 }, {
721 .name = "uart_ipg_clk",
722 .id = 0,
723 .parent = &ipg_clk,
724 .enable = _clk_enable,
725 .enable_reg = CCM_PCCR1,
726 .enable_shift = CCM_PCCR1_UART1_OFFSET,
727 .disable = _clk_disable,
728 },
729};
730
731struct clk uart2_clk[] = {
732 {
733 .name = "uart_clk",
734 .id = 1,
735 .parent = &per_clk[0],
736 .secondary = &uart2_clk[1],
737 }, {
738 .name = "uart_ipg_clk",
739 .id = 1,
740 .parent = &ipg_clk,
741 .enable = _clk_enable,
742 .enable_reg = CCM_PCCR1,
743 .enable_shift = CCM_PCCR1_UART2_OFFSET,
744 .disable = _clk_disable,
745 },
746};
747
748struct clk uart3_clk[] = {
749 {
750 .name = "uart_clk",
751 .id = 2,
752 .parent = &per_clk[0],
753 .secondary = &uart3_clk[1],
754 }, {
755 .name = "uart_ipg_clk",
756 .id = 2,
757 .parent = &ipg_clk,
758 .enable = _clk_enable,
759 .enable_reg = CCM_PCCR1,
760 .enable_shift = CCM_PCCR1_UART3_OFFSET,
761 .disable = _clk_disable,
762 },
763};
764
765struct clk uart4_clk[] = {
766 {
767 .name = "uart_clk",
768 .id = 3,
769 .parent = &per_clk[0],
770 .secondary = &uart4_clk[1],
771 }, {
772 .name = "uart_ipg_clk",
773 .id = 3,
774 .parent = &ipg_clk,
775 .enable = _clk_enable,
776 .enable_reg = CCM_PCCR1,
777 .enable_shift = CCM_PCCR1_UART4_OFFSET,
778 .disable = _clk_disable,
779 },
780};
781
782struct clk uart5_clk[] = {
783 {
784 .name = "uart_clk",
785 .id = 4,
786 .parent = &per_clk[0],
787 .secondary = &uart5_clk[1],
788 }, {
789 .name = "uart_ipg_clk",
790 .id = 4,
791 .parent = &ipg_clk,
792 .enable = _clk_enable,
793 .enable_reg = CCM_PCCR1,
794 .enable_shift = CCM_PCCR1_UART5_OFFSET,
795 .disable = _clk_disable,
796 },
797};
798
799struct clk uart6_clk[] = {
800 {
801 .name = "uart_clk",
802 .id = 5,
803 .parent = &per_clk[0],
804 .secondary = &uart6_clk[1],
805 }, {
806 .name = "uart_ipg_clk",
807 .id = 5,
808 .parent = &ipg_clk,
809 .enable = _clk_enable,
810 .enable_reg = CCM_PCCR1,
811 .enable_shift = CCM_PCCR1_UART6_OFFSET,
812 .disable = _clk_disable,
813 },
814};
815
816static struct clk gpt1_clk[] = {
817 {
818 .name = "gpt_clk",
819 .id = 0,
820 .parent = &per_clk[0],
821 .secondary = &gpt1_clk[1],
822 }, {
823 .name = "gpt_ipg_clk",
824 .id = 0,
825 .parent = &ipg_clk,
826 .enable = _clk_enable,
827 .enable_reg = CCM_PCCR0,
828 .enable_shift = CCM_PCCR0_GPT1_OFFSET,
829 .disable = _clk_disable,
830 },
831};
832
833static struct clk gpt2_clk[] = {
834 {
835 .name = "gpt_clk",
836 .id = 1,
837 .parent = &per_clk[0],
838 .secondary = &gpt2_clk[1],
839 }, {
840 .name = "gpt_ipg_clk",
841 .id = 1,
842 .parent = &ipg_clk,
843 .enable = _clk_enable,
844 .enable_reg = CCM_PCCR0,
845 .enable_shift = CCM_PCCR0_GPT2_OFFSET,
846 .disable = _clk_disable,
847 },
848};
849
850static struct clk gpt3_clk[] = {
851 {
852 .name = "gpt_clk",
853 .id = 2,
854 .parent = &per_clk[0],
855 .secondary = &gpt3_clk[1],
856 }, {
857 .name = "gpt_ipg_clk",
858 .id = 2,
859 .parent = &ipg_clk,
860 .enable = _clk_enable,
861 .enable_reg = CCM_PCCR0,
862 .enable_shift = CCM_PCCR0_GPT3_OFFSET,
863 .disable = _clk_disable,
864 },
865};
866
867static struct clk gpt4_clk[] = {
868 {
869 .name = "gpt_clk",
870 .id = 3,
871 .parent = &per_clk[0],
872 .secondary = &gpt4_clk[1],
873 }, {
874 .name = "gpt_ipg_clk",
875 .id = 3,
876 .parent = &ipg_clk,
877 .enable = _clk_enable,
878 .enable_reg = CCM_PCCR0,
879 .enable_shift = CCM_PCCR0_GPT4_OFFSET,
880 .disable = _clk_disable,
881 },
882};
883
884static struct clk gpt5_clk[] = {
885 {
886 .name = "gpt_clk",
887 .id = 4,
888 .parent = &per_clk[0],
889 .secondary = &gpt5_clk[1],
890 }, {
891 .name = "gpt_ipg_clk",
892 .id = 4,
893 .parent = &ipg_clk,
894 .enable = _clk_enable,
895 .enable_reg = CCM_PCCR0,
896 .enable_shift = CCM_PCCR0_GPT5_OFFSET,
897 .disable = _clk_disable,
898 },
899}; 433};
900 434
901static struct clk gpt6_clk[] = { 435static struct clk mpll_clk = {
902 { 436 .parent = &ckih_clk,
903 .name = "gpt_clk", 437 .get_rate = get_rate_mpll,
904 .id = 5,
905 .parent = &per_clk[0],
906 .secondary = &gpt6_clk[1],
907 }, {
908 .name = "gpt_ipg_clk",
909 .id = 5,
910 .parent = &ipg_clk,
911 .enable = _clk_enable,
912 .enable_reg = CCM_PCCR0,
913 .enable_shift = CCM_PCCR0_GPT6_OFFSET,
914 .disable = _clk_disable,
915 },
916}; 438};
917 439
918static struct clk pwm_clk[] = { 440/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
919 { 441 * It provides the clock source whose rate is same as MPLL
920 .name = "pwm_clk", 442 */
921 .parent = &per_clk[0], 443static struct clk mpll_main1_clk = {
922 .secondary = &pwm_clk[1], 444 .id = 0,
923 }, { 445 .parent = &mpll_clk,
924 .name = "pwm_clk", 446 .get_rate = get_rate_mpll_main,
925 .parent = &ipg_clk,
926 .enable = _clk_enable,
927 .enable_reg = CCM_PCCR0,
928 .enable_shift = CCM_PCCR0_PWM_OFFSET,
929 .disable = _clk_disable,
930 },
931}; 447};
932 448
933static struct clk sdhc1_clk[] = { 449/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
934 { 450 * It provides the clock source whose rate is same MPLL * 2 / 3
935 .name = "sdhc_clk", 451 */
936 .id = 0, 452static struct clk mpll_main2_clk = {
937 .parent = &per_clk[1], 453 .id = 1,
938 .secondary = &sdhc1_clk[1], 454 .parent = &mpll_clk,
939 }, { 455 .get_rate = get_rate_mpll_main,
940 .name = "sdhc_ipg_clk",
941 .id = 0,
942 .parent = &ipg_clk,
943 .enable = _clk_enable,
944 .enable_reg = CCM_PCCR0,
945 .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
946 .disable = _clk_disable,
947 },
948}; 456};
949 457
950static struct clk sdhc2_clk[] = { 458static struct clk ahb_clk = {
951 { 459 .parent = &mpll_main2_clk,
952 .name = "sdhc_clk", 460 .get_rate = get_rate_ahb,
953 .id = 1,
954 .parent = &per_clk[1],
955 .secondary = &sdhc2_clk[1],
956 }, {
957 .name = "sdhc_ipg_clk",
958 .id = 1,
959 .parent = &ipg_clk,
960 .enable = _clk_enable,
961 .enable_reg = CCM_PCCR0,
962 .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
963 .disable = _clk_disable,
964 },
965}; 461};
966 462
967static struct clk sdhc3_clk[] = { 463static struct clk ipg_clk = {
968 { 464 .parent = &ahb_clk,
969 .name = "sdhc_clk", 465 .get_rate = get_rate_ipg,
970 .id = 2,
971 .parent = &per_clk[1],
972 .secondary = &sdhc3_clk[1],
973 }, {
974 .name = "sdhc_ipg_clk",
975 .id = 2,
976 .parent = &ipg_clk,
977 .enable = _clk_enable,
978 .enable_reg = CCM_PCCR0,
979 .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
980 .disable = _clk_disable,
981 },
982}; 466};
983 467
984static struct clk cspi1_clk[] = { 468static struct clk cpu_clk = {
985 { 469 .parent = &mpll_main2_clk,
986 .name = "cspi_clk", 470 .set_parent = clk_cpu_set_parent,
987 .id = 0, 471 .round_rate = round_rate_cpu,
988 .parent = &per_clk[1], 472 .get_rate = get_rate_cpu,
989 .secondary = &cspi1_clk[1], 473 .set_rate = set_rate_cpu,
990 }, {
991 .name = "cspi_ipg_clk",
992 .id = 0,
993 .parent = &ipg_clk,
994 .enable = _clk_enable,
995 .enable_reg = CCM_PCCR0,
996 .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
997 .disable = _clk_disable,
998 },
999}; 474};
1000 475
1001static struct clk cspi2_clk[] = { 476static struct clk spll_clk = {
1002 { 477 .parent = &ckih_clk,
1003 .name = "cspi_clk", 478 .get_rate = get_rate_spll,
1004 .id = 1, 479 .enable = clk_spll_enable,
1005 .parent = &per_clk[1], 480 .disable = clk_spll_disable,
1006 .secondary = &cspi2_clk[1],
1007 }, {
1008 .name = "cspi_ipg_clk",
1009 .id = 1,
1010 .parent = &ipg_clk,
1011 .enable = _clk_enable,
1012 .enable_reg = CCM_PCCR0,
1013 .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
1014 .disable = _clk_disable,
1015 },
1016}; 481};
1017 482
1018static struct clk cspi3_clk[] = { 483/*
1019 { 484 * the low frequency external clock reference
1020 .name = "cspi_clk", 485 * Default case is 32.768kHz.
1021 .id = 2, 486 */
1022 .parent = &per_clk[1], 487static struct clk ckil_clk = {
1023 .secondary = &cspi3_clk[1], 488 .get_rate = get_rate_low_reference,
1024 }, {
1025 .name = "cspi_ipg_clk",
1026 .id = 2,
1027 .parent = &ipg_clk,
1028 .enable = _clk_enable,
1029 .enable_reg = CCM_PCCR0,
1030 .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
1031 .disable = _clk_disable,
1032 },
1033}; 489};
1034 490
1035static struct clk lcdc_clk[] = { 491/* Output of frequency pre multiplier */
1036 { 492static struct clk fpm_clk = {
1037 .name = "lcdc_clk", 493 .parent = &ckil_clk,
1038 .parent = &per_clk[2], 494 .get_rate = get_rate_fpm,
1039 .secondary = &lcdc_clk[1],
1040 .round_rate = _clk_parent_round_rate,
1041 .set_rate = _clk_parent_set_rate,
1042 }, {
1043 .name = "lcdc_ipg_clk",
1044 .parent = &ipg_clk,
1045 .secondary = &lcdc_clk[2],
1046 .enable = _clk_enable,
1047 .enable_reg = CCM_PCCR0,
1048 .enable_shift = CCM_PCCR0_LCDC_OFFSET,
1049 .disable = _clk_disable,
1050 }, {
1051 .name = "lcdc_ahb_clk",
1052 .parent = &ahb_clk,
1053 .enable = _clk_enable,
1054 .enable_reg = CCM_PCCR1,
1055 .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
1056 .disable = _clk_disable,
1057 },
1058}; 495};
1059 496
1060static struct clk csi_clk[] = { 497#define PCCR0 CCM_PCCR0
1061 { 498#define PCCR1 CCM_PCCR1
1062 .name = "csi_perclk",
1063 .parent = &per_clk[3],
1064 .secondary = &csi_clk[1],
1065 .round_rate = _clk_parent_round_rate,
1066 .set_rate = _clk_parent_set_rate,
1067 }, {
1068 .name = "csi_ahb_clk",
1069 .parent = &ahb_clk,
1070 .enable = _clk_enable,
1071 .enable_reg = CCM_PCCR1,
1072 .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
1073 .disable = _clk_disable,
1074 },
1075};
1076 499
1077static struct clk usb_clk[] = { 500#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
1078 { 501 static struct clk name = { \
1079 .name = "usb_clk", 502 .id = i, \
1080 .parent = &spll_clk, 503 .enable_reg = er, \
1081 .get_rate = _clk_usb_recalc, 504 .enable_shift = es, \
1082 .enable = _clk_enable, 505 .get_rate = gr, \
1083 .enable_reg = CCM_PCCR1, 506 .enable = clk_pccr_enable, \
1084 .enable_shift = CCM_PCCR1_USBOTG_OFFSET, 507 .disable = clk_pccr_disable, \
1085 .disable = _clk_disable, 508 .secondary = s, \
1086 }, { 509 .parent = p, \
1087 .name = "usb_ahb_clk",
1088 .parent = &ahb_clk,
1089 .enable = _clk_enable,
1090 .enable_reg = CCM_PCCR1,
1091 .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
1092 .disable = _clk_disable,
1093 } 510 }
1094};
1095 511
1096static struct clk ssi1_clk[] = { 512#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
1097 { 513 static struct clk name = { \
1098 .name = "ssi_clk", 514 .id = i, \
1099 .id = 0, 515 .enable_reg = er, \
1100 .parent = &mpll_main_clk[1], 516 .enable_shift = es, \
1101 .secondary = &ssi1_clk[1], 517 .get_rate = get_rate_##getsetround, \
1102 .get_rate = _clk_ssi1_recalc, 518 .set_rate = set_rate_##getsetround, \
1103 .enable = _clk_enable, 519 .round_rate = round_rate_##getsetround, \
1104 .enable_reg = CCM_PCCR1, 520 .enable = clk_pccr_enable, \
1105 .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET, 521 .disable = clk_pccr_disable, \
1106 .disable = _clk_disable, 522 .secondary = s, \
1107 }, { 523 .parent = p, \
1108 .name = "ssi_ipg_clk", 524 }
1109 .id = 0,
1110 .parent = &ipg_clk,
1111 .enable = _clk_enable,
1112 .enable_reg = CCM_PCCR0,
1113 .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
1114 .disable = _clk_disable,
1115 },
1116};
1117 525
1118static struct clk ssi2_clk[] = { 526/* Forward declaration to keep the following list in order */
1119 { 527static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
1120 .name = "ssi_clk", 528 dma_clk1, lcdc_clk2, vpu_clk1;
1121 .id = 1, 529
1122 .parent = &mpll_main_clk[1], 530/* All clocks we can gate through PCCRx in the order of PCCRx bits */
1123 .secondary = &ssi2_clk[1], 531DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
1124 .get_rate = _clk_ssi2_recalc, 532DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
1125 .enable = _clk_enable, 533DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
1126 .enable_reg = CCM_PCCR1, 534DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
1127 .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET, 535DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
1128 .disable = _clk_disable, 536DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
1129 }, { 537DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
1130 .name = "ssi_ipg_clk", 538DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
1131 .id = 1, 539DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
1132 .parent = &ipg_clk, 540DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
1133 .enable = _clk_enable, 541DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
1134 .enable_reg = CCM_PCCR0, 542DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
1135 .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET, 543DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
1136 .disable = _clk_disable, 544DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
545DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
546DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
547DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
548DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
549DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
550DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
551DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
552DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
553DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
554DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
555DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
556DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
557DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
558DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
559DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
560DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
561DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
562
563DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
564DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
565DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
566DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
567DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
568DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
569DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
570DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
571DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
572DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
573DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
574DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
575DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
576DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
577DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
578DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
579DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
580DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
581DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
582DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
583DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
584DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
585DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
586DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
587DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
588DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
589DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
590DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
591DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
592DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
593
594/* Clocks we cannot directly gate, but drivers need their rates */
595DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
596DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
597DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
598DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
599DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
600DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
601DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
602DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
603DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
604DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
605DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
606DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
607DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
608DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
609DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
610DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
611DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
612DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
613DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
614DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
615DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
616
617#define _REGISTER_CLOCK(d, n, c) \
618 { \
619 .dev_id = d, \
620 .con_id = n, \
621 .clk = &c, \
1137 }, 622 },
1138};
1139
1140static struct clk nfc_clk = {
1141 .name = "nfc_clk",
1142 .parent = &cpu_clk,
1143 .get_rate = _clk_nfc_recalc,
1144 .enable = _clk_enable,
1145 .enable_reg = CCM_PCCR1,
1146 .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
1147 .disable = _clk_disable,
1148};
1149
1150static struct clk vpu_clk = {
1151 .name = "vpu_clk",
1152 .parent = &mpll_main_clk[1],
1153 .get_rate = _clk_vpu_recalc,
1154 .enable = _clk_vpu_enable,
1155 .disable = _clk_vpu_disable,
1156};
1157
1158static struct clk dma_clk = {
1159 .name = "dma_clk",
1160 .parent = &ahb_clk,
1161 .enable = _clk_dma_enable,
1162 .disable = _clk_dma_disable,
1163};
1164
1165static struct clk rtic_clk = {
1166 .name = "rtic_clk",
1167 .parent = &ahb_clk,
1168 .enable = _clk_rtic_enable,
1169 .disable = _clk_rtic_disable,
1170};
1171 623
1172static struct clk brom_clk = { 624static struct clk_lookup lookups[] __initdata = {
1173 .name = "brom_clk", 625 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
1174 .parent = &ahb_clk, 626 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
1175 .enable = _clk_enable, 627 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
1176 .enable_reg = CCM_PCCR1, 628 _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
1177 .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET, 629 _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
1178 .disable = _clk_disable, 630 _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
1179}; 631 _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
1180 632 _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
1181static struct clk emma_clk = { 633 _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
1182 .name = "emma_clk", 634 _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
1183 .parent = &ahb_clk, 635 _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
1184 .enable = _clk_emma_enable, 636 _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
1185 .disable = _clk_emma_disable, 637 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
1186}; 638 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
1187 639 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
1188static struct clk slcdc_clk = { 640 _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
1189 .name = "slcdc_clk", 641 _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
1190 .parent = &ahb_clk, 642 _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
1191 .enable = _clk_slcdc_enable, 643 _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
1192 .disable = _clk_slcdc_disable, 644 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
1193}; 645 _REGISTER_CLOCK(NULL, "csi", csi_clk)
1194 646 _REGISTER_CLOCK(NULL, "usb", usb_clk)
1195static struct clk fec_clk = { 647 _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
1196 .name = "fec_clk", 648 _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
1197 .parent = &ahb_clk, 649 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1198 .enable = _clk_fec_enable, 650 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
1199 .disable = _clk_fec_disable, 651 _REGISTER_CLOCK(NULL, "dma", dma_clk)
1200}; 652 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
1201 653 _REGISTER_CLOCK(NULL, "brom", brom_clk)
1202static struct clk emi_clk = { 654 _REGISTER_CLOCK(NULL, "emma", emma_clk)
1203 .name = "emi_clk", 655 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
1204 .parent = &ahb_clk, 656 _REGISTER_CLOCK("fec.0", NULL, fec_clk)
1205 .enable = _clk_enable, 657 _REGISTER_CLOCK(NULL, "emi", emi_clk)
1206 .enable_reg = CCM_PCCR1, 658 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
1207 .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET, 659 _REGISTER_CLOCK(NULL, "ata", ata_clk)
1208 .disable = _clk_disable, 660 _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
1209}; 661 _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
1210 662 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1211static struct clk sahara2_clk = { 663 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1212 .name = "sahara_clk", 664 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1213 .parent = &ahb_clk, 665 _REGISTER_CLOCK(NULL, "iim", iim_clk)
1214 .enable = _clk_sahara2_enable, 666 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
1215 .disable = _clk_sahara2_disable, 667 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
1216}; 668 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1217 669 _REGISTER_CLOCK(NULL, "scc", scc_clk)
1218static struct clk ata_clk = { 670};
1219 .name = "ata_clk", 671
1220 .parent = &ahb_clk, 672/* Adjust the clock path for TO2 and later */
1221 .enable = _clk_enable, 673static void __init to2_adjust_clocks(void)
1222 .enable_reg = CCM_PCCR1, 674{
1223 .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET, 675 unsigned long cscr = __raw_readl(CCM_CSCR);
1224 .disable = _clk_disable,
1225};
1226
1227static struct clk mstick1_clk = {
1228 .name = "mstick1_clk",
1229 .parent = &ipg_clk,
1230 .enable = _clk_mstick1_enable,
1231 .disable = _clk_mstick1_disable,
1232};
1233
1234static struct clk wdog_clk = {
1235 .name = "wdog_clk",
1236 .parent = &ipg_clk,
1237 .enable = _clk_enable,
1238 .enable_reg = CCM_PCCR1,
1239 .enable_shift = CCM_PCCR1_WDT_OFFSET,
1240 .disable = _clk_disable,
1241};
1242
1243static struct clk gpio_clk = {
1244 .name = "gpio_clk",
1245 .parent = &ipg_clk,
1246 .enable = _clk_enable,
1247 .enable_reg = CCM_PCCR1,
1248 .enable_shift = CCM_PCCR0_GPIO_OFFSET,
1249 .disable = _clk_disable,
1250};
1251
1252static struct clk i2c_clk[] = {
1253 {
1254 .name = "i2c_clk",
1255 .id = 0,
1256 .parent = &ipg_clk,
1257 .enable = _clk_enable,
1258 .enable_reg = CCM_PCCR0,
1259 .enable_shift = CCM_PCCR0_I2C1_OFFSET,
1260 .disable = _clk_disable,
1261 }, {
1262 .name = "i2c_clk",
1263 .id = 1,
1264 .parent = &ipg_clk,
1265 .enable = _clk_enable,
1266 .enable_reg = CCM_PCCR0,
1267 .enable_shift = CCM_PCCR0_I2C2_OFFSET,
1268 .disable = _clk_disable,
1269 },
1270};
1271
1272static struct clk iim_clk = {
1273 .name = "iim_clk",
1274 .parent = &ipg_clk,
1275 .enable = _clk_enable,
1276 .enable_reg = CCM_PCCR0,
1277 .enable_shift = CCM_PCCR0_IIM_OFFSET,
1278 .disable = _clk_disable,
1279};
1280
1281static struct clk kpp_clk = {
1282 .name = "kpp_clk",
1283 .parent = &ipg_clk,
1284 .enable = _clk_enable,
1285 .enable_reg = CCM_PCCR0,
1286 .enable_shift = CCM_PCCR0_KPP_OFFSET,
1287 .disable = _clk_disable,
1288};
1289
1290static struct clk owire_clk = {
1291 .name = "owire_clk",
1292 .parent = &ipg_clk,
1293 .enable = _clk_enable,
1294 .enable_reg = CCM_PCCR0,
1295 .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
1296 .disable = _clk_disable,
1297};
1298
1299static struct clk rtc_clk = {
1300 .name = "rtc_clk",
1301 .parent = &ipg_clk,
1302 .enable = _clk_enable,
1303 .enable_reg = CCM_PCCR0,
1304 .enable_shift = CCM_PCCR0_RTC_OFFSET,
1305 .disable = _clk_disable,
1306};
1307
1308static struct clk scc_clk = {
1309 .name = "scc_clk",
1310 .parent = &ipg_clk,
1311 .enable = _clk_enable,
1312 .enable_reg = CCM_PCCR0,
1313 .enable_shift = CCM_PCCR0_SCC_OFFSET,
1314 .disable = _clk_disable,
1315};
1316
1317static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1318{
1319 u32 div;
1320 unsigned long parent_rate;
1321
1322 parent_rate = clk_get_rate(clk->parent);
1323 div = parent_rate / rate;
1324 if (parent_rate % rate)
1325 div++;
1326
1327 if (div > 8)
1328 div = 8;
1329
1330 return parent_rate / div;
1331}
1332
1333static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1334{
1335 u32 reg;
1336 u32 div;
1337 unsigned long parent_rate;
1338
1339 parent_rate = clk_get_rate(clk->parent);
1340
1341 div = parent_rate / rate;
1342
1343 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1344 return -EINVAL;
1345 div--;
1346
1347 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1348 reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1349 __raw_writel(reg, CCM_PCDR0);
1350
1351 return 0;
1352}
1353
1354static unsigned long _clk_clko_recalc(struct clk *clk)
1355{
1356 u32 div;
1357 unsigned long parent_rate;
1358
1359 parent_rate = clk_get_rate(clk->parent);
1360
1361 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1362 CCM_PCDR0_CLKODIV_OFFSET;
1363 div++;
1364
1365 return parent_rate / div;
1366}
1367
1368static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1369{
1370 u32 reg;
1371
1372 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1373
1374 if (parent == &ckil_clk)
1375 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1376 else if (parent == &ckih_clk)
1377 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1378 else if (parent == mpll_clk.parent)
1379 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1380 else if (parent == spll_clk.parent)
1381 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1382 else if (parent == &mpll_clk)
1383 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1384 else if (parent == &spll_clk)
1385 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1386 else if (parent == &cpu_clk)
1387 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1388 else if (parent == &ahb_clk)
1389 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1390 else if (parent == &ipg_clk)
1391 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1392 else if (parent == &per_clk[0])
1393 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1394 else if (parent == &per_clk[1])
1395 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1396 else if (parent == &per_clk[2])
1397 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1398 else if (parent == &per_clk[3])
1399 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1400 else if (parent == &ssi1_clk[0])
1401 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1402 else if (parent == &ssi2_clk[0])
1403 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1404 else if (parent == &nfc_clk)
1405 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1406 else if (parent == &mstick1_clk)
1407 reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
1408 else if (parent == &vpu_clk)
1409 reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
1410 else if (parent == &usb_clk[0])
1411 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1412 else
1413 return -EINVAL;
1414
1415 __raw_writel(reg, CCM_CCSR);
1416
1417 return 0;
1418}
1419
1420static int _clk_clko_enable(struct clk *clk)
1421{
1422 u32 reg;
1423
1424 reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1425 __raw_writel(reg, CCM_PCDR0);
1426
1427 return 0;
1428}
1429
1430static void _clk_clko_disable(struct clk *clk)
1431{
1432 u32 reg;
1433
1434 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1435 __raw_writel(reg, CCM_PCDR0);
1436}
1437
1438static struct clk clko_clk = {
1439 .name = "clko_clk",
1440 .get_rate = _clk_clko_recalc,
1441 .set_rate = _clk_clko_set_rate,
1442 .round_rate = _clk_clko_round_rate,
1443 .set_parent = _clk_clko_set_parent,
1444 .enable = _clk_clko_enable,
1445 .disable = _clk_clko_disable,
1446};
1447
1448static struct clk *mxc_clks[] = {
1449 &ckih_clk,
1450 &ckil_clk,
1451 &mpll_clk,
1452 &mpll_main_clk[0],
1453 &mpll_main_clk[1],
1454 &spll_clk,
1455 &cpu_clk,
1456 &ahb_clk,
1457 &ipg_clk,
1458 &per_clk[0],
1459 &per_clk[1],
1460 &per_clk[2],
1461 &per_clk[3],
1462 &clko_clk,
1463 &uart1_clk[0],
1464 &uart1_clk[1],
1465 &uart2_clk[0],
1466 &uart2_clk[1],
1467 &uart3_clk[0],
1468 &uart3_clk[1],
1469 &uart4_clk[0],
1470 &uart4_clk[1],
1471 &uart5_clk[0],
1472 &uart5_clk[1],
1473 &uart6_clk[0],
1474 &uart6_clk[1],
1475 &gpt1_clk[0],
1476 &gpt1_clk[1],
1477 &gpt2_clk[0],
1478 &gpt2_clk[1],
1479 &gpt3_clk[0],
1480 &gpt3_clk[1],
1481 &gpt4_clk[0],
1482 &gpt4_clk[1],
1483 &gpt5_clk[0],
1484 &gpt5_clk[1],
1485 &gpt6_clk[0],
1486 &gpt6_clk[1],
1487 &pwm_clk[0],
1488 &pwm_clk[1],
1489 &sdhc1_clk[0],
1490 &sdhc1_clk[1],
1491 &sdhc2_clk[0],
1492 &sdhc2_clk[1],
1493 &sdhc3_clk[0],
1494 &sdhc3_clk[1],
1495 &cspi1_clk[0],
1496 &cspi1_clk[1],
1497 &cspi2_clk[0],
1498 &cspi2_clk[1],
1499 &cspi3_clk[0],
1500 &cspi3_clk[1],
1501 &lcdc_clk[0],
1502 &lcdc_clk[1],
1503 &lcdc_clk[2],
1504 &csi_clk[0],
1505 &csi_clk[1],
1506 &usb_clk[0],
1507 &usb_clk[1],
1508 &ssi1_clk[0],
1509 &ssi1_clk[1],
1510 &ssi2_clk[0],
1511 &ssi2_clk[1],
1512 &nfc_clk,
1513 &vpu_clk,
1514 &dma_clk,
1515 &rtic_clk,
1516 &brom_clk,
1517 &emma_clk,
1518 &slcdc_clk,
1519 &fec_clk,
1520 &emi_clk,
1521 &sahara2_clk,
1522 &ata_clk,
1523 &mstick1_clk,
1524 &wdog_clk,
1525 &gpio_clk,
1526 &i2c_clk[0],
1527 &i2c_clk[1],
1528 &iim_clk,
1529 &kpp_clk,
1530 &owire_clk,
1531 &rtc_clk,
1532 &scc_clk,
1533};
1534
1535void __init change_external_low_reference(unsigned long new_ref)
1536{
1537 external_low_reference = new_ref;
1538}
1539
1540unsigned long __init clk_early_get_timer_rate(void)
1541{
1542 return clk_get_rate(&per_clk[0]);
1543}
1544
1545static void __init probe_mxc_clocks(void)
1546{
1547 int i;
1548 676
1549 if (mx27_revision() >= CHIP_REV_2_0) { 677 if (mx27_revision() >= CHIP_REV_2_0) {
1550 if (CSCR() & 0x8000) 678 if (cscr & CCM_CSCR_ARM_SRC)
1551 cpu_clk.parent = &mpll_main_clk[0]; 679 cpu_clk.parent = &mpll_main1_clk;
1552 680
1553 if (!(CSCR() & 0x00800000)) 681 if (!(cscr & CCM_CSCR_SSI2))
1554 ssi2_clk[0].parent = &spll_clk; 682 ssi1_clk.parent = &spll_clk;
1555 683
1556 if (!(CSCR() & 0x00400000)) 684 if (!(cscr & CCM_CSCR_SSI1))
1557 ssi1_clk[0].parent = &spll_clk; 685 ssi1_clk.parent = &spll_clk;
1558 686
1559 if (!(CSCR() & 0x00200000)) 687 if (!(cscr & CCM_CSCR_VPU))
1560 vpu_clk.parent = &spll_clk; 688 vpu_clk.parent = &spll_clk;
1561 } else { 689 } else {
1562 cpu_clk.parent = &mpll_clk; 690 cpu_clk.parent = &mpll_clk;
@@ -1565,11 +693,13 @@ static void __init probe_mxc_clocks(void)
1565 cpu_clk.set_rate = NULL; 693 cpu_clk.set_rate = NULL;
1566 ahb_clk.parent = &mpll_clk; 694 ahb_clk.parent = &mpll_clk;
1567 695
1568 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) 696 per1_clk.parent = &mpll_clk;
1569 per_clk[i].parent = &mpll_clk; 697 per2_clk.parent = &mpll_clk;
698 per3_clk.parent = &mpll_clk;
699 per4_clk.parent = &mpll_clk;
1570 700
1571 ssi1_clk[0].parent = &mpll_clk; 701 ssi1_clk.parent = &mpll_clk;
1572 ssi2_clk[0].parent = &mpll_clk; 702 ssi2_clk.parent = &mpll_clk;
1573 703
1574 vpu_clk.parent = &mpll_clk; 704 vpu_clk.parent = &mpll_clk;
1575 } 705 }
@@ -1579,47 +709,47 @@ static void __init probe_mxc_clocks(void)
1579 * must be called very early to get information about the 709 * must be called very early to get information about the
1580 * available clock rate when the timer framework starts 710 * available clock rate when the timer framework starts
1581 */ 711 */
1582int __init mxc_clocks_init(unsigned long fref) 712int __init mx27_clocks_init(unsigned long fref)
1583{ 713{
1584 u32 cscr; 714 u32 cscr = __raw_readl(CCM_CSCR);
1585 struct clk **clkp; 715 int i;
1586 716
1587 external_high_reference = fref; 717 external_high_reference = fref;
1588 718
1589 /* detect clock reference for both system PLL */ 719 /* detect clock reference for both system PLLs */
1590 cscr = CSCR();
1591 if (cscr & CCM_CSCR_MCU) 720 if (cscr & CCM_CSCR_MCU)
1592 mpll_clk.parent = &ckih_clk; 721 mpll_clk.parent = &ckih_clk;
1593 else 722 else
1594 mpll_clk.parent = &ckil_clk; 723 mpll_clk.parent = &fpm_clk;
1595 724
1596 if (cscr & CCM_CSCR_SP) 725 if (cscr & CCM_CSCR_SP)
1597 spll_clk.parent = &ckih_clk; 726 spll_clk.parent = &ckih_clk;
1598 else 727 else
1599 spll_clk.parent = &ckil_clk; 728 spll_clk.parent = &fpm_clk;
1600 729
1601 probe_mxc_clocks(); 730 to2_adjust_clocks();
1602 731
1603 per_clk[0].enable(&per_clk[0]); 732 for (i = 0; i < ARRAY_SIZE(lookups); i++)
1604 gpt1_clk[1].enable(&gpt1_clk[1]); 733 clkdev_add(&lookups[i]);
1605 734
1606 for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) 735 /* Turn off all clocks we do not need */
1607 clk_register(*clkp); 736 __raw_writel(0, CCM_PCCR0);
737 __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
1608 738
1609 /* Turn off all possible clocks */
1610 __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
1611 __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
1612 CCM_PCCR1);
1613 spll_clk.disable(&spll_clk); 739 spll_clk.disable(&spll_clk);
1614 740
1615 /* This will propagate to all children and init all the clock rates */ 741 /* enable basic clocks */
1616 742 clk_enable(&per1_clk);
1617 clk_enable(&emi_clk);
1618 clk_enable(&gpio_clk); 743 clk_enable(&gpio_clk);
744 clk_enable(&emi_clk);
1619 clk_enable(&iim_clk); 745 clk_enable(&iim_clk);
1620 clk_enable(&gpt1_clk[0]); 746
1621#ifdef CONFIG_DEBUG_LL_CONSOLE 747#ifdef CONFIG_DEBUG_LL_CONSOLE
1622 clk_enable(&uart1_clk[0]); 748 clk_enable(&uart1_clk);
1623#endif 749#endif
750
751 mxc_timer_init(&gpt1_clk);
752
1624 return 0; 753 return 0;
1625} 754}
755
diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c
index 239308fe6652..d9e3bf9644c9 100644
--- a/arch/arm/mach-mx2/cpu_imx27.c
+++ b/arch/arm/mach-mx2/cpu_imx27.c
@@ -26,11 +26,11 @@
26 26
27#include <mach/hardware.h> 27#include <mach/hardware.h>
28 28
29#include "crm_regs.h"
30
31static int cpu_silicon_rev = -1; 29static int cpu_silicon_rev = -1;
32static int cpu_partnumber; 30static int cpu_partnumber;
33 31
32#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
33
34static void query_silicon_parameter(void) 34static void query_silicon_parameter(void)
35{ 35{
36 u32 val; 36 u32 val;
diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h
index 94644cd0a0fc..749de76b3f95 100644
--- a/arch/arm/mach-mx2/crm_regs.h
+++ b/arch/arm/mach-mx2/crm_regs.h
@@ -38,42 +38,36 @@
38#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) 38#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
39#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) 39#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
40 40
41#define CCM_CSCR_USB_OFFSET 28 41#define CCM_CSCR_PRESC_OFFSET 29
42#define CCM_CSCR_USB_MASK (0x7 << 28) 42#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
43
44#define CCM_CSCR_USB_OFFSET 26
45#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
43#define CCM_CSCR_SD_OFFSET 24 46#define CCM_CSCR_SD_OFFSET 24
44#define CCM_CSCR_SD_MASK (0x3 << 24) 47#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
45#define CCM_CSCR_SSI2 (1 << 23) 48#define CCM_CSCR_SPLLRES (1 << 22)
46#define CCM_CSCR_SSI2_OFFSET 23 49#define CCM_CSCR_MPLLRES (1 << 21)
47#define CCM_CSCR_SSI1 (1 << 22) 50#define CCM_CSCR_SSI2_OFFSET 20
48#define CCM_CSCR_SSI1_OFFSET 22 51#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
49#define CCM_CSCR_VPU (1 << 21) 52#define CCM_CSCR_SSI1_OFFSET 19
50#define CCM_CSCR_VPU_OFFSET 21 53#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
51#define CCM_CSCR_MSHC (1 << 20) 54#define CCM_CSCR_FIR_OFFSET 18
52#define CCM_CSCR_SPLLRES (1 << 19) 55#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
53#define CCM_CSCR_MPLLRES (1 << 18)
54#define CCM_CSCR_SP (1 << 17) 56#define CCM_CSCR_SP (1 << 17)
55#define CCM_CSCR_MCU (1 << 16) 57#define CCM_CSCR_MCU (1 << 16)
56/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ 58#define CCM_CSCR_BCLK_OFFSET 10
57#define CCM_CSCR_ARM_SRC (1 << 15) 59#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
58#define CCM_CSCR_ARM_OFFSET 12 60#define CCM_CSCR_IPDIV_OFFSET 9
59#define CCM_CSCR_ARM_MASK (0x3 << 12) 61#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
60/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ 62
61#define CCM_CSCR_PRESC_OFFSET 13
62#define CCM_CSCR_PRESC_MASK (0x7 << 13)
63#define CCM_CSCR_BCLK_OFFSET 9
64#define CCM_CSCR_BCLK_MASK (0xf << 9)
65#define CCM_CSCR_IPDIV_OFFSET 8
66#define CCM_CSCR_IPDIV (1 << 8)
67/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
68#define CCM_CSCR_AHB_OFFSET 8
69#define CCM_CSCR_AHB_MASK (0x3 << 8)
70/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
71#define CCM_CSCR_OSC26MDIV (1 << 4) 63#define CCM_CSCR_OSC26MDIV (1 << 4)
72#define CCM_CSCR_OSC26M (1 << 3) 64#define CCM_CSCR_OSC26M (1 << 3)
73#define CCM_CSCR_FPM (1 << 2) 65#define CCM_CSCR_FPM (1 << 2)
74#define CCM_CSCR_SPEN (1 << 1) 66#define CCM_CSCR_SPEN (1 << 1)
75#define CCM_CSCR_MPEN 1 67#define CCM_CSCR_MPEN 1
76 68
69
70
77#define CCM_MPCTL0_CPLM (1 << 31) 71#define CCM_MPCTL0_CPLM (1 << 31)
78#define CCM_MPCTL0_PD_OFFSET 26 72#define CCM_MPCTL0_PD_OFFSET 26
79#define CCM_MPCTL0_PD_MASK (0xf << 26) 73#define CCM_MPCTL0_PD_MASK (0xf << 26)
@@ -109,25 +103,14 @@
109 103
110#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 104#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
111#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) 105#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
112#define CCM_PCDR0_CLKO_EN 25
113#define CCM_PCDR0_CLKODIV_OFFSET 22
114#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22)
115#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 106#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
116#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) 107#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
117/*The difinition for i.MX27 TO2*/
118#define CCM_PCDR0_VPUDIV2_OFFSET 10
119#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10)
120#define CCM_PCDR0_NFCDIV2_OFFSET 6
121#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6)
122#define CCM_PCDR0_MSHCDIV2_MASK 0x3f
123/*The difinition for i.MX27 TO2*/
124#define CCM_PCDR0_NFCDIV_OFFSET 12 108#define CCM_PCDR0_NFCDIV_OFFSET 12
125#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) 109#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
126#define CCM_PCDR0_VPUDIV_OFFSET 8 110#define CCM_PCDR0_48MDIV_OFFSET 5
127#define CCM_PCDR0_VPUDIV_MASK (0xf << 8) 111#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
128#define CCM_PCDR0_MSHCDIV_OFFSET 0 112#define CCM_PCDR0_FIRIDIV_OFFSET 0
129#define CCM_PCDR0_MSHCDIV_MASK 0x1f 113#define CCM_PCDR0_FIRIDIV_MASK 0x1f
130
131#define CCM_PCDR1_PERDIV4_OFFSET 24 114#define CCM_PCDR1_PERDIV4_OFFSET 24
132#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) 115#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
133#define CCM_PCDR1_PERDIV3_OFFSET 16 116#define CCM_PCDR1_PERDIV3_OFFSET 16
@@ -137,133 +120,135 @@
137#define CCM_PCDR1_PERDIV1_OFFSET 0 120#define CCM_PCDR1_PERDIV1_OFFSET 0
138#define CCM_PCDR1_PERDIV1_MASK 0x3f 121#define CCM_PCDR1_PERDIV1_MASK 0x3f
139 122
140#define CCM_PCCR0_CSPI1_OFFSET 31 123#define CCM_PCCR_HCLK_CSI_OFFSET 31
141#define CCM_PCCR0_CSPI1_MASK (1 << 31) 124#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
142#define CCM_PCCR0_CSPI2_OFFSET 30 125#define CCM_PCCR_HCLK_DMA_OFFSET 30
143#define CCM_PCCR0_CSPI2_MASK (1 << 30) 126#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
144#define CCM_PCCR0_CSPI3_OFFSET 29 127#define CCM_PCCR_HCLK_BROM_OFFSET 28
145#define CCM_PCCR0_CSPI3_MASK (1 << 29) 128#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
146#define CCM_PCCR0_DMA_OFFSET 28 129#define CCM_PCCR_HCLK_EMMA_OFFSET 27
147#define CCM_PCCR0_DMA_MASK (1 << 28) 130#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
148#define CCM_PCCR0_EMMA_OFFSET 27 131#define CCM_PCCR_HCLK_LCDC_OFFSET 26
149#define CCM_PCCR0_EMMA_MASK (1 << 27) 132#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
150#define CCM_PCCR0_FEC_OFFSET 26 133#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
151#define CCM_PCCR0_FEC_MASK (1 << 26) 134#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
152#define CCM_PCCR0_GPIO_OFFSET 25 135#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
153#define CCM_PCCR0_GPIO_MASK (1 << 25) 136#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
154#define CCM_PCCR0_GPT1_OFFSET 24 137#define CCM_PCCR_HCLK_BMI_OFFSET 23
155#define CCM_PCCR0_GPT1_MASK (1 << 24) 138#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
156#define CCM_PCCR0_GPT2_OFFSET 23 139#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
157#define CCM_PCCR0_GPT2_MASK (1 << 23) 140#define CCM_PCCR_PERCLK4_OFFSET 22
158#define CCM_PCCR0_GPT3_OFFSET 22 141#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
159#define CCM_PCCR0_GPT3_MASK (1 << 22) 142#define CCM_PCCR_SLCDC_OFFSET 21
160#define CCM_PCCR0_GPT4_OFFSET 21 143#define CCM_PCCR_SLCDC_REG CCM_PCCR0
161#define CCM_PCCR0_GPT4_MASK (1 << 21) 144#define CCM_PCCR_FIRI_BAUD_OFFSET 20
162#define CCM_PCCR0_GPT5_OFFSET 20 145#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
163#define CCM_PCCR0_GPT5_MASK (1 << 20) 146#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
164#define CCM_PCCR0_GPT6_OFFSET 19 147#define CCM_PCCR_NFC_OFFSET 19
165#define CCM_PCCR0_GPT6_MASK (1 << 19) 148#define CCM_PCCR_NFC_REG CCM_PCCR0
166#define CCM_PCCR0_I2C1_OFFSET 18 149#define CCM_PCCR_LCDC_OFFSET 18
167#define CCM_PCCR0_I2C1_MASK (1 << 18) 150#define CCM_PCCR_LCDC_REG CCM_PCCR0
168#define CCM_PCCR0_I2C2_OFFSET 17 151#define CCM_PCCR_SSI1_BAUD_OFFSET 17
169#define CCM_PCCR0_I2C2_MASK (1 << 17) 152#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
170#define CCM_PCCR0_IIM_OFFSET 16 153#define CCM_PCCR_SSI2_BAUD_OFFSET 16
171#define CCM_PCCR0_IIM_MASK (1 << 16) 154#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
172#define CCM_PCCR0_KPP_OFFSET 15 155#define CCM_PCCR_EMMA_OFFSET 15
173#define CCM_PCCR0_KPP_MASK (1 << 15) 156#define CCM_PCCR_EMMA_REG CCM_PCCR0
174#define CCM_PCCR0_LCDC_OFFSET 14 157#define CCM_PCCR_USBOTG_OFFSET 14
175#define CCM_PCCR0_LCDC_MASK (1 << 14) 158#define CCM_PCCR_USBOTG_REG CCM_PCCR0
176#define CCM_PCCR0_MSHC_OFFSET 13 159#define CCM_PCCR_DMA_OFFSET 13
177#define CCM_PCCR0_MSHC_MASK (1 << 13) 160#define CCM_PCCR_DMA_REG CCM_PCCR0
178#define CCM_PCCR0_OWIRE_OFFSET 12 161#define CCM_PCCR_I2C1_OFFSET 12
179#define CCM_PCCR0_OWIRE_MASK (1 << 12) 162#define CCM_PCCR_I2C1_REG CCM_PCCR0
180#define CCM_PCCR0_PWM_OFFSET 11 163#define CCM_PCCR_GPIO_OFFSET 11
181#define CCM_PCCR0_PWM_MASK (1 << 11) 164#define CCM_PCCR_GPIO_REG CCM_PCCR0
182#define CCM_PCCR0_RTC_OFFSET 9 165#define CCM_PCCR_SDHC2_OFFSET 10
183#define CCM_PCCR0_RTC_MASK (1 << 9) 166#define CCM_PCCR_SDHC2_REG CCM_PCCR0
184#define CCM_PCCR0_RTIC_OFFSET 8 167#define CCM_PCCR_SDHC1_OFFSET 9
185#define CCM_PCCR0_RTIC_MASK (1 << 8) 168#define CCM_PCCR_SDHC1_REG CCM_PCCR0
186#define CCM_PCCR0_SAHARA_OFFSET 7 169#define CCM_PCCR_FIRI_OFFSET 8
187#define CCM_PCCR0_SAHARA_MASK (1 << 7) 170#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
188#define CCM_PCCR0_SCC_OFFSET 6 171#define CCM_PCCR_FIRI_REG CCM_PCCR0
189#define CCM_PCCR0_SCC_MASK (1 << 6) 172#define CCM_PCCR_SSI2_IPG_OFFSET 7
190#define CCM_PCCR0_SDHC1_OFFSET 5 173#define CCM_PCCR_SSI2_REG CCM_PCCR0
191#define CCM_PCCR0_SDHC1_MASK (1 << 5) 174#define CCM_PCCR_SSI1_IPG_OFFSET 6
192#define CCM_PCCR0_SDHC2_OFFSET 4 175#define CCM_PCCR_SSI1_REG CCM_PCCR0
193#define CCM_PCCR0_SDHC2_MASK (1 << 4) 176#define CCM_PCCR_CSPI2_OFFSET 5
194#define CCM_PCCR0_SDHC3_OFFSET 3 177#define CCM_PCCR_CSPI2_REG CCM_PCCR0
195#define CCM_PCCR0_SDHC3_MASK (1 << 3) 178#define CCM_PCCR_CSPI1_OFFSET 4
196#define CCM_PCCR0_SLCDC_OFFSET 2 179#define CCM_PCCR_CSPI1_REG CCM_PCCR0
197#define CCM_PCCR0_SLCDC_MASK (1 << 2) 180#define CCM_PCCR_UART4_OFFSET 3
198#define CCM_PCCR0_SSI1_IPG_OFFSET 1 181#define CCM_PCCR_UART4_REG CCM_PCCR0
199#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1) 182#define CCM_PCCR_UART3_OFFSET 2
200#define CCM_PCCR0_SSI2_IPG_OFFSET 0 183#define CCM_PCCR_UART3_REG CCM_PCCR0
201#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0) 184#define CCM_PCCR_UART2_OFFSET 1
185#define CCM_PCCR_UART2_REG CCM_PCCR0
186#define CCM_PCCR_UART1_OFFSET 0
187#define CCM_PCCR_UART1_REG CCM_PCCR0
188
189#define CCM_PCCR_OWIRE_OFFSET 31
190#define CCM_PCCR_OWIRE_REG CCM_PCCR1
191#define CCM_PCCR_KPP_OFFSET 30
192#define CCM_PCCR_KPP_REG CCM_PCCR1
193#define CCM_PCCR_RTC_OFFSET 29
194#define CCM_PCCR_RTC_REG CCM_PCCR1
195#define CCM_PCCR_PWM_OFFSET 28
196#define CCM_PCCR_PWM_REG CCM_PCCR1
197#define CCM_PCCR_GPT3_OFFSET 27
198#define CCM_PCCR_GPT3_REG CCM_PCCR1
199#define CCM_PCCR_GPT2_OFFSET 26
200#define CCM_PCCR_GPT2_REG CCM_PCCR1
201#define CCM_PCCR_GPT1_OFFSET 25
202#define CCM_PCCR_GPT1_REG CCM_PCCR1
203#define CCM_PCCR_WDT_OFFSET 24
204#define CCM_PCCR_WDT_REG CCM_PCCR1
205#define CCM_PCCR_CSPI3_OFFSET 23
206#define CCM_PCCR_CSPI3_REG CCM_PCCR1
207
208#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
209#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
210#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
211#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
212#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
213#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
214#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
215#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
216#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
217#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
218#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
219#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
220#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
221#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
222#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
223#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
224#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
225#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
226#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
227#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
228#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
229#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
230#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
231#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
232#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
233#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
234#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
235#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
236#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
237#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
238#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
239#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
240#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
241#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
242#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
243#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
244#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
202 245
203#define CCM_PCCR1_UART1_OFFSET 31
204#define CCM_PCCR1_UART1_MASK (1 << 31)
205#define CCM_PCCR1_UART2_OFFSET 30
206#define CCM_PCCR1_UART2_MASK (1 << 30)
207#define CCM_PCCR1_UART3_OFFSET 29
208#define CCM_PCCR1_UART3_MASK (1 << 29)
209#define CCM_PCCR1_UART4_OFFSET 28
210#define CCM_PCCR1_UART4_MASK (1 << 28)
211#define CCM_PCCR1_UART5_OFFSET 27
212#define CCM_PCCR1_UART5_MASK (1 << 27)
213#define CCM_PCCR1_UART6_OFFSET 26
214#define CCM_PCCR1_UART6_MASK (1 << 26)
215#define CCM_PCCR1_USBOTG_OFFSET 25
216#define CCM_PCCR1_USBOTG_MASK (1 << 25)
217#define CCM_PCCR1_WDT_OFFSET 24
218#define CCM_PCCR1_WDT_MASK (1 << 24)
219#define CCM_PCCR1_HCLK_ATA_OFFSET 23
220#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23)
221#define CCM_PCCR1_HCLK_BROM_OFFSET 22
222#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22)
223#define CCM_PCCR1_HCLK_CSI_OFFSET 21
224#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21)
225#define CCM_PCCR1_HCLK_DMA_OFFSET 20
226#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20)
227#define CCM_PCCR1_HCLK_EMI_OFFSET 19
228#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19)
229#define CCM_PCCR1_HCLK_EMMA_OFFSET 18
230#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18)
231#define CCM_PCCR1_HCLK_FEC_OFFSET 17
232#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17)
233#define CCM_PCCR1_HCLK_VPU_OFFSET 16
234#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16)
235#define CCM_PCCR1_HCLK_LCDC_OFFSET 15
236#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15)
237#define CCM_PCCR1_HCLK_RTIC_OFFSET 14
238#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14)
239#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13
240#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13)
241#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12
242#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12)
243#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11
244#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11)
245#define CCM_PCCR1_PERCLK1_OFFSET 10
246#define CCM_PCCR1_PERCLK1_MASK (1 << 10)
247#define CCM_PCCR1_PERCLK2_OFFSET 9
248#define CCM_PCCR1_PERCLK2_MASK (1 << 9)
249#define CCM_PCCR1_PERCLK3_OFFSET 8
250#define CCM_PCCR1_PERCLK3_MASK (1 << 8)
251#define CCM_PCCR1_PERCLK4_OFFSET 7
252#define CCM_PCCR1_PERCLK4_MASK (1 << 7)
253#define CCM_PCCR1_VPU_BAUD_OFFSET 6
254#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6)
255#define CCM_PCCR1_SSI1_BAUD_OFFSET 5
256#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5)
257#define CCM_PCCR1_SSI2_BAUD_OFFSET 4
258#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4)
259#define CCM_PCCR1_NFC_BAUD_OFFSET 3
260#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3)
261#define CCM_PCCR1_MSHC_BAUD_OFFSET 2
262#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2)
263 246
264#define CCM_CCSR_32KSR (1 << 15) 247#define CCM_CCSR_32KSR (1 << 15)
248
265#define CCM_CCSR_CLKMODE1 (1 << 9) 249#define CCM_CCSR_CLKMODE1 (1 << 9)
266#define CCM_CCSR_CLKMODE0 (1 << 8) 250#define CCM_CCSR_CLKMODE0 (1 << 8)
251
267#define CCM_CCSR_CLKOSEL_OFFSET 0 252#define CCM_CCSR_CLKOSEL_OFFSET 0
268#define CCM_CCSR_CLKOSEL_MASK 0x1f 253#define CCM_CCSR_CLKOSEL_MASK 0x1f
269 254
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c
index 2f9240be1c76..f81aa8a8fbb4 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-mx2/devices.c
@@ -34,6 +34,10 @@
34 34
35#include <mach/irqs.h> 35#include <mach/irqs.h>
36#include <mach/hardware.h> 36#include <mach/hardware.h>
37#include <mach/common.h>
38#include <mach/mmc.h>
39
40#include "devices.h"
37 41
38/* 42/*
39 * Resource definition for the MXC IrDA 43 * Resource definition for the MXC IrDA
@@ -225,37 +229,217 @@ struct platform_device mxc_nand_device = {
225 .resource = mxc_nand_resources, 229 .resource = mxc_nand_resources,
226}; 230};
227 231
232#ifdef CONFIG_FB_IMX
233/*
234 * lcdc:
235 * - i.MX1: the basic controller
236 * - i.MX21: to be checked
237 * - i.MX27: like i.MX1, with slightly variations
238 */
239static struct resource mxc_fb[] = {
240 {
241 .start = LCDC_BASE_ADDR,
242 .end = LCDC_BASE_ADDR + 0xFFF,
243 .flags = IORESOURCE_MEM,
244 },
245 {
246 .start = MXC_INT_LCDC,
247 .end = MXC_INT_LCDC,
248 .flags = IORESOURCE_IRQ,
249 }
250};
251
252/* mxc lcd driver */
253struct platform_device mxc_fb_device = {
254 .name = "imx-fb",
255 .id = 0,
256 .num_resources = ARRAY_SIZE(mxc_fb),
257 .resource = mxc_fb,
258 .dev = {
259 .coherent_dma_mask = 0xFFFFFFFF,
260 },
261};
262#endif
263
264#ifdef CONFIG_MACH_MX27
265static struct resource mxc_fec_resources[] = {
266 {
267 .start = FEC_BASE_ADDR,
268 .end = FEC_BASE_ADDR + 0xfff,
269 .flags = IORESOURCE_MEM
270 }, {
271 .start = MXC_INT_FEC,
272 .end = MXC_INT_FEC,
273 .flags = IORESOURCE_IRQ
274 },
275};
276
277struct platform_device mxc_fec_device = {
278 .name = "fec",
279 .id = 0,
280 .num_resources = ARRAY_SIZE(mxc_fec_resources),
281 .resource = mxc_fec_resources,
282};
283#endif
284
285static struct resource mxc_i2c_1_resources[] = {
286 [0] = {
287 .start = I2C_BASE_ADDR,
288 .end = I2C_BASE_ADDR + 0x0fff,
289 .flags = IORESOURCE_MEM
290 },
291 [1] = {
292 .start = MXC_INT_I2C,
293 .end = MXC_INT_I2C,
294 .flags = IORESOURCE_IRQ
295 }
296};
297
298struct platform_device mxc_i2c_device0 = {
299 .name = "imx-i2c",
300 .id = 0,
301 .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
302 .resource = mxc_i2c_1_resources
303};
304
305#ifdef CONFIG_MACH_MX27
306static struct resource mxc_i2c_2_resources[] = {
307 [0] = {
308 .start = I2C2_BASE_ADDR,
309 .end = I2C2_BASE_ADDR + 0x0fff,
310 .flags = IORESOURCE_MEM
311 },
312 [1] = {
313 .start = MXC_INT_I2C2,
314 .end = MXC_INT_I2C2,
315 .flags = IORESOURCE_IRQ
316 }
317};
318
319struct platform_device mxc_i2c_device1 = {
320 .name = "imx-i2c",
321 .id = 1,
322 .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
323 .resource = mxc_i2c_2_resources
324};
325#endif
326
327static struct resource mxc_pwm_resources[] = {
328 [0] = {
329 .start = PWM_BASE_ADDR,
330 .end = PWM_BASE_ADDR + 0x0fff,
331 .flags = IORESOURCE_MEM
332 },
333 [1] = {
334 .start = MXC_INT_PWM,
335 .end = MXC_INT_PWM,
336 .flags = IORESOURCE_IRQ,
337 }
338};
339
340struct platform_device mxc_pwm_device = {
341 .name = "mxc_pwm",
342 .id = 0,
343 .num_resources = ARRAY_SIZE(mxc_pwm_resources),
344 .resource = mxc_pwm_resources
345};
346
347/*
348 * Resource definition for the MXC SDHC
349 */
350static struct resource mxc_sdhc1_resources[] = {
351 [0] = {
352 .start = SDHC1_BASE_ADDR,
353 .end = SDHC1_BASE_ADDR + SZ_4K - 1,
354 .flags = IORESOURCE_MEM,
355 },
356 [1] = {
357 .start = MXC_INT_SDHC1,
358 .end = MXC_INT_SDHC1,
359 .flags = IORESOURCE_IRQ,
360 },
361 [2] = {
362 .start = DMA_REQ_SDHC1,
363 .end = DMA_REQ_SDHC1,
364 .flags = IORESOURCE_DMA
365 },
366};
367
368static u64 mxc_sdhc1_dmamask = 0xffffffffUL;
369
370struct platform_device mxc_sdhc_device0 = {
371 .name = "mxc-mmc",
372 .id = 0,
373 .dev = {
374 .dma_mask = &mxc_sdhc1_dmamask,
375 .coherent_dma_mask = 0xffffffff,
376 },
377 .num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
378 .resource = mxc_sdhc1_resources,
379};
380
381static struct resource mxc_sdhc2_resources[] = {
382 [0] = {
383 .start = SDHC2_BASE_ADDR,
384 .end = SDHC2_BASE_ADDR + SZ_4K - 1,
385 .flags = IORESOURCE_MEM,
386 },
387 [1] = {
388 .start = MXC_INT_SDHC2,
389 .end = MXC_INT_SDHC2,
390 .flags = IORESOURCE_IRQ,
391 },
392 [2] = {
393 .start = DMA_REQ_SDHC2,
394 .end = DMA_REQ_SDHC2,
395 .flags = IORESOURCE_DMA
396 },
397};
398
399static u64 mxc_sdhc2_dmamask = 0xffffffffUL;
400
401struct platform_device mxc_sdhc_device1 = {
402 .name = "mxc-mmc",
403 .id = 1,
404 .dev = {
405 .dma_mask = &mxc_sdhc2_dmamask,
406 .coherent_dma_mask = 0xffffffff,
407 },
408 .num_resources = ARRAY_SIZE(mxc_sdhc2_resources),
409 .resource = mxc_sdhc2_resources,
410};
411
228/* GPIO port description */ 412/* GPIO port description */
229static struct mxc_gpio_port imx_gpio_ports[] = { 413static struct mxc_gpio_port imx_gpio_ports[] = {
230 [0] = { 414 [0] = {
231 .chip.label = "gpio-0", 415 .chip.label = "gpio-0",
232 .irq = MXC_INT_GPIO, 416 .irq = MXC_INT_GPIO,
233 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0), 417 .base = IO_ADDRESS(GPIO_BASE_ADDR),
234 .virtual_irq_start = MXC_GPIO_IRQ_START, 418 .virtual_irq_start = MXC_GPIO_IRQ_START,
235 }, 419 },
236 [1] = { 420 [1] = {
237 .chip.label = "gpio-1", 421 .chip.label = "gpio-1",
238 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1), 422 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
239 .virtual_irq_start = MXC_GPIO_IRQ_START + 32, 423 .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
240 }, 424 },
241 [2] = { 425 [2] = {
242 .chip.label = "gpio-2", 426 .chip.label = "gpio-2",
243 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2), 427 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
244 .virtual_irq_start = MXC_GPIO_IRQ_START + 64, 428 .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
245 }, 429 },
246 [3] = { 430 [3] = {
247 .chip.label = "gpio-3", 431 .chip.label = "gpio-3",
248 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3), 432 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
249 .virtual_irq_start = MXC_GPIO_IRQ_START + 96, 433 .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
250 }, 434 },
251 [4] = { 435 [4] = {
252 .chip.label = "gpio-4", 436 .chip.label = "gpio-4",
253 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4), 437 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400),
254 .virtual_irq_start = MXC_GPIO_IRQ_START + 128, 438 .virtual_irq_start = MXC_GPIO_IRQ_START + 128,
255 }, 439 },
256 [5] = { 440 [5] = {
257 .chip.label = "gpio-5", 441 .chip.label = "gpio-5",
258 .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5), 442 .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500),
259 .virtual_irq_start = MXC_GPIO_IRQ_START + 160, 443 .virtual_irq_start = MXC_GPIO_IRQ_START + 160,
260 } 444 }
261}; 445};
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h
index 1e8cb577a642..049005bb6aa9 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-mx2/devices.h
@@ -1,4 +1,3 @@
1
2extern struct platform_device mxc_gpt1; 1extern struct platform_device mxc_gpt1;
3extern struct platform_device mxc_gpt2; 2extern struct platform_device mxc_gpt2;
4extern struct platform_device mxc_gpt3; 3extern struct platform_device mxc_gpt3;
@@ -14,3 +13,10 @@ extern struct platform_device mxc_uart_device4;
14extern struct platform_device mxc_uart_device5; 13extern struct platform_device mxc_uart_device5;
15extern struct platform_device mxc_w1_master_device; 14extern struct platform_device mxc_w1_master_device;
16extern struct platform_device mxc_nand_device; 15extern struct platform_device mxc_nand_device;
16extern struct platform_device mxc_fb_device;
17extern struct platform_device mxc_fec_device;
18extern struct platform_device mxc_pwm_device;
19extern struct platform_device mxc_i2c_device0;
20extern struct platform_device mxc_i2c_device1;
21extern struct platform_device mxc_sdhc_device0;
22extern struct platform_device mxc_sdhc_device1;
diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c
index dea6521d4d5c..bd51dd04948e 100644
--- a/arch/arm/mach-mx2/generic.c
+++ b/arch/arm/mach-mx2/generic.c
@@ -21,6 +21,7 @@
21#include <linux/mm.h> 21#include <linux/mm.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <mach/common.h>
24#include <asm/pgtable.h> 25#include <asm/pgtable.h>
25#include <asm/mach/map.h> 26#include <asm/mach/map.h>
26 27
diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c
index 2b5c67f54571..4a3b097adc12 100644
--- a/arch/arm/mach-mx2/mx27ads.c
+++ b/arch/arm/mach-mx2/mx27ads.c
@@ -31,7 +31,7 @@
31#include <asm/mach/map.h> 31#include <asm/mach/map.h>
32#include <mach/gpio.h> 32#include <mach/gpio.h>
33#include <mach/imx-uart.h> 33#include <mach/imx-uart.h>
34#include <mach/iomux-mx1-mx2.h> 34#include <mach/iomux.h>
35#include <mach/board-mx27ads.h> 35#include <mach/board-mx27ads.h>
36 36
37#include "devices.h" 37#include "devices.h"
@@ -135,6 +135,7 @@ static int uart_mxc_port3_exit(struct platform_device *pdev)
135{ 135{
136 mxc_gpio_release_multiple_pins(mxc_uart3_pins, 136 mxc_gpio_release_multiple_pins(mxc_uart3_pins,
137 ARRAY_SIZE(mxc_uart3_pins)); 137 ARRAY_SIZE(mxc_uart3_pins));
138 return 0;
138} 139}
139 140
140static int mxc_uart4_pins[] = { 141static int mxc_uart4_pins[] = {
@@ -179,6 +180,7 @@ static int uart_mxc_port5_exit(struct platform_device *pdev)
179 180
180static struct platform_device *platform_devices[] __initdata = { 181static struct platform_device *platform_devices[] __initdata = {
181 &mx27ads_nor_mtd_device, 182 &mx27ads_nor_mtd_device,
183 &mxc_fec_device,
182}; 184};
183 185
184static int mxc_fec_pins[] = { 186static int mxc_fec_pins[] = {
@@ -196,7 +198,7 @@ static int mxc_fec_pins[] = {
196 PD11_AOUT_FEC_TX_CLK, 198 PD11_AOUT_FEC_TX_CLK,
197 PD12_AOUT_FEC_RXD0, 199 PD12_AOUT_FEC_RXD0,
198 PD13_AOUT_FEC_RX_DV, 200 PD13_AOUT_FEC_RX_DV,
199 PD14_AOUT_FEC_CLR, 201 PD14_AOUT_FEC_RX_CLK,
200 PD15_AOUT_FEC_COL, 202 PD15_AOUT_FEC_COL,
201 PD16_AIN_FEC_TX_ER, 203 PD16_AIN_FEC_TX_ER,
202 PF23_AIN_FEC_TX_EN 204 PF23_AIN_FEC_TX_EN
@@ -208,12 +210,6 @@ static void gpio_fec_active(void)
208 ARRAY_SIZE(mxc_fec_pins), "FEC"); 210 ARRAY_SIZE(mxc_fec_pins), "FEC");
209} 211}
210 212
211static void gpio_fec_inactive(void)
212{
213 mxc_gpio_release_multiple_pins(mxc_fec_pins,
214 ARRAY_SIZE(mxc_fec_pins));
215}
216
217static struct imxuart_platform_data uart_pdata[] = { 213static struct imxuart_platform_data uart_pdata[] = {
218 { 214 {
219 .init = uart_mxc_port0_init, 215 .init = uart_mxc_port0_init,
@@ -263,11 +259,10 @@ static void __init mx27ads_timer_init(void)
263 if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) 259 if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0)
264 fref = 27000000; 260 fref = 27000000;
265 261
266 mxc_clocks_init(fref); 262 mx27_clocks_init(fref);
267 mxc_timer_init("gpt_clk.0");
268} 263}
269 264
270struct sys_timer mx27ads_timer = { 265static struct sys_timer mx27ads_timer = {
271 .init = mx27ads_timer_init, 266 .init = mx27ads_timer_init,
272}; 267};
273 268
@@ -280,7 +275,7 @@ static struct map_desc mx27ads_io_desc[] __initdata = {
280 }, 275 },
281}; 276};
282 277
283void __init mx27ads_map_io(void) 278static void __init mx27ads_map_io(void)
284{ 279{
285 mxc_map_io(); 280 mxc_map_io();
286 iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); 281 iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc));
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c
index dfd4156da7d5..aa4eaa61d1b5 100644
--- a/arch/arm/mach-mx2/pcm038.c
+++ b/arch/arm/mach-mx2/pcm038.c
@@ -20,11 +20,18 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mtd/physmap.h> 21#include <linux/mtd/physmap.h>
22#include <linux/mtd/plat-ram.h> 22#include <linux/mtd/plat-ram.h>
23#include <linux/io.h>
24#include <linux/i2c.h>
25#include <linux/i2c/at24.h>
26
23#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
24#include <asm/mach-types.h> 28#include <asm/mach-types.h>
25#include <mach/common.h> 29#include <mach/common.h>
26#include <mach/hardware.h> 30#include <mach/hardware.h>
27#include <mach/iomux-mx1-mx2.h> 31#include <mach/iomux.h>
32#ifdef CONFIG_I2C_IMX
33#include <mach/i2c.h>
34#endif
28#include <asm/mach/time.h> 35#include <asm/mach/time.h>
29#include <mach/imx-uart.h> 36#include <mach/imx-uart.h>
30#include <mach/board-pcm038.h> 37#include <mach/board-pcm038.h>
@@ -121,10 +128,10 @@ static int uart_mxc_port1_exit(struct platform_device *pdev)
121 return 0; 128 return 0;
122} 129}
123 130
124static int mxc_uart2_pins[] = { PE10_PF_UART3_CTS, 131static int mxc_uart2_pins[] = { PE8_PF_UART3_TXD,
125 PE9_PF_UART3_RXD, 132 PE9_PF_UART3_RXD,
126 PE10_PF_UART3_CTS, 133 PE10_PF_UART3_CTS,
127 PE9_PF_UART3_RXD }; 134 PE11_PF_UART3_RTS };
128 135
129static int uart_mxc_port2_init(struct platform_device *pdev) 136static int uart_mxc_port2_init(struct platform_device *pdev)
130{ 137{
@@ -170,7 +177,7 @@ static int mxc_fec_pins[] = {
170 PD11_AOUT_FEC_TX_CLK, 177 PD11_AOUT_FEC_TX_CLK,
171 PD12_AOUT_FEC_RXD0, 178 PD12_AOUT_FEC_RXD0,
172 PD13_AOUT_FEC_RX_DV, 179 PD13_AOUT_FEC_RX_DV,
173 PD14_AOUT_FEC_CLR, 180 PD14_AOUT_FEC_RX_CLK,
174 PD15_AOUT_FEC_COL, 181 PD15_AOUT_FEC_COL,
175 PD16_AIN_FEC_TX_ER, 182 PD16_AIN_FEC_TX_ER,
176 PF23_AIN_FEC_TX_EN 183 PF23_AIN_FEC_TX_EN
@@ -182,12 +189,6 @@ static void gpio_fec_active(void)
182 ARRAY_SIZE(mxc_fec_pins), "FEC"); 189 ARRAY_SIZE(mxc_fec_pins), "FEC");
183} 190}
184 191
185static void gpio_fec_inactive(void)
186{
187 mxc_gpio_release_multiple_pins(mxc_fec_pins,
188 ARRAY_SIZE(mxc_fec_pins));
189}
190
191static struct mxc_nand_platform_data pcm038_nand_board_info = { 192static struct mxc_nand_platform_data pcm038_nand_board_info = {
192 .width = 1, 193 .width = 1,
193 .hw_ecc = 1, 194 .hw_ecc = 1,
@@ -196,6 +197,7 @@ static struct mxc_nand_platform_data pcm038_nand_board_info = {
196static struct platform_device *platform_devices[] __initdata = { 197static struct platform_device *platform_devices[] __initdata = {
197 &pcm038_nor_mtd_device, 198 &pcm038_nor_mtd_device,
198 &mxc_w1_master_device, 199 &mxc_w1_master_device,
200 &mxc_fec_device,
199 &pcm038_sram_mtd_device, 201 &pcm038_sram_mtd_device,
200}; 202};
201 203
@@ -208,6 +210,51 @@ static void __init pcm038_init_sram(void)
208 __raw_writel(0x22220a00, CSCR_A(1)); 210 __raw_writel(0x22220a00, CSCR_A(1));
209} 211}
210 212
213#ifdef CONFIG_I2C_IMX
214static int mxc_i2c1_pins[] = {
215 PC5_PF_I2C2_SDA,
216 PC6_PF_I2C2_SCL
217};
218
219static int pcm038_i2c_1_init(struct device *dev)
220{
221 return mxc_gpio_setup_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins),
222 "I2C1");
223}
224
225static void pcm038_i2c_1_exit(struct device *dev)
226{
227 mxc_gpio_release_multiple_pins(mxc_i2c1_pins, ARRAY_SIZE(mxc_i2c1_pins));
228}
229
230static struct imxi2c_platform_data pcm038_i2c_1_data = {
231 .bitrate = 100000,
232 .init = pcm038_i2c_1_init,
233 .exit = pcm038_i2c_1_exit,
234};
235
236static struct at24_platform_data board_eeprom = {
237 .byte_len = 4096,
238 .page_size = 32,
239 .flags = AT24_FLAG_ADDR16,
240};
241
242static struct i2c_board_info pcm038_i2c_devices[] = {
243 [0] = {
244 I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
245 .platform_data = &board_eeprom,
246 },
247 [1] = {
248 I2C_BOARD_INFO("rtc-pcf8563", 0x51),
249 .type = "pcf8563"
250 },
251 [2] = {
252 I2C_BOARD_INFO("lm75", 0x4a),
253 .type = "lm75"
254 }
255};
256#endif
257
211static void __init pcm038_init(void) 258static void __init pcm038_init(void)
212{ 259{
213 gpio_fec_active(); 260 gpio_fec_active();
@@ -217,9 +264,17 @@ static void __init pcm038_init(void)
217 mxc_register_device(&mxc_uart_device1, &uart_pdata[1]); 264 mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
218 mxc_register_device(&mxc_uart_device2, &uart_pdata[2]); 265 mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
219 266
220 mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */ 267 mxc_gpio_mode(PE16_AF_OWIRE);
221 mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info); 268 mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info);
222 269
270#ifdef CONFIG_I2C_IMX
271 /* only the i2c master 1 is used on this CPU card */
272 i2c_register_board_info(1, pcm038_i2c_devices,
273 ARRAY_SIZE(pcm038_i2c_devices));
274
275 mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
276#endif
277
223 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); 278 platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
224 279
225#ifdef CONFIG_MACH_PCM970_BASEBOARD 280#ifdef CONFIG_MACH_PCM970_BASEBOARD
@@ -229,11 +284,10 @@ static void __init pcm038_init(void)
229 284
230static void __init pcm038_timer_init(void) 285static void __init pcm038_timer_init(void)
231{ 286{
232 mxc_clocks_init(26000000); 287 mx27_clocks_init(26000000);
233 mxc_timer_init("gpt_clk.0");
234} 288}
235 289
236struct sys_timer pcm038_timer = { 290static struct sys_timer pcm038_timer = {
237 .init = pcm038_timer_init, 291 .init = pcm038_timer_init,
238}; 292};
239 293
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-mx2/pcm970-baseboard.c
index a560cd6ad23d..bf4e520bc1bc 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-mx2/pcm970-baseboard.c
@@ -17,9 +17,138 @@
17 */ 17 */
18 18
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <mach/hardware.h> 20#include <linux/gpio.h>
21#include <linux/irq.h>
22
21#include <asm/mach/arch.h> 23#include <asm/mach/arch.h>
22 24
25#include <mach/hardware.h>
26#include <mach/common.h>
27#include <mach/mmc.h>
28#include <mach/imxfb.h>
29#include <mach/iomux.h>
30
31#include "devices.h"
32
33static int pcm970_sdhc2_get_ro(struct device *dev)
34{
35 return gpio_get_value(GPIO_PORTC + 28);
36}
37
38static int pcm970_sdhc2_pins[] = {
39 PB4_PF_SD2_D0,
40 PB5_PF_SD2_D1,
41 PB6_PF_SD2_D2,
42 PB7_PF_SD2_D3,
43 PB8_PF_SD2_CMD,
44 PB9_PF_SD2_CLK,
45};
46
47static int pcm970_sdhc2_init(struct device *dev, irq_handler_t detect_irq, void *data)
48{
49 int ret;
50
51 ret = mxc_gpio_setup_multiple_pins(pcm970_sdhc2_pins,
52 ARRAY_SIZE(pcm970_sdhc2_pins), "sdhc2");
53 if(ret)
54 return ret;
55
56 ret = request_irq(IRQ_GPIOC(29), detect_irq, 0,
57 "imx-mmc-detect", data);
58 if (ret)
59 goto out_release_gpio;
60
61 set_irq_type(IRQ_GPIOC(29), IRQF_TRIGGER_FALLING);
62
63 ret = gpio_request(GPIO_PORTC + 28, "imx-mmc-ro");
64 if (ret)
65 goto out_release_gpio;
66
67 mxc_gpio_mode((GPIO_PORTC | 28) | GPIO_GPIO | GPIO_IN);
68 gpio_direction_input(GPIO_PORTC + 28);
69
70 return 0;
71
72out_release_gpio:
73 mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
74 ARRAY_SIZE(pcm970_sdhc2_pins));
75 return ret;
76}
77
78static void pcm970_sdhc2_exit(struct device *dev, void *data)
79{
80 free_irq(IRQ_GPIOC(29), data);
81 gpio_free(GPIO_PORTC + 28);
82 mxc_gpio_release_multiple_pins(pcm970_sdhc2_pins,
83 ARRAY_SIZE(pcm970_sdhc2_pins));
84}
85
86static struct imxmmc_platform_data sdhc_pdata = {
87 .get_ro = pcm970_sdhc2_get_ro,
88 .init = pcm970_sdhc2_init,
89 .exit = pcm970_sdhc2_exit,
90};
91
92static int mxc_fb_pins[] = {
93 PA5_PF_LSCLK, PA6_PF_LD0, PA7_PF_LD1, PA8_PF_LD2,
94 PA9_PF_LD3, PA10_PF_LD4, PA11_PF_LD5, PA12_PF_LD6,
95 PA13_PF_LD7, PA14_PF_LD8, PA15_PF_LD9, PA16_PF_LD10,
96 PA17_PF_LD11, PA18_PF_LD12, PA19_PF_LD13, PA20_PF_LD14,
97 PA21_PF_LD15, PA22_PF_LD16, PA23_PF_LD17, PA24_PF_REV,
98 PA25_PF_CLS, PA26_PF_PS, PA27_PF_SPL_SPR, PA28_PF_HSYNC,
99 PA29_PF_VSYNC, PA30_PF_CONTRAST, PA31_PF_OE_ACD
100};
101
102static int pcm038_fb_init(struct platform_device *pdev)
103{
104 return mxc_gpio_setup_multiple_pins(mxc_fb_pins,
105 ARRAY_SIZE(mxc_fb_pins), "FB");
106}
107
108static int pcm038_fb_exit(struct platform_device *pdev)
109{
110 mxc_gpio_release_multiple_pins(mxc_fb_pins, ARRAY_SIZE(mxc_fb_pins));
111
112 return 0;
113}
114
115/*
116 * Connected is a portrait Sharp-QVGA display
117 * of type: LQ035Q7DH06
118 */
119static struct imx_fb_platform_data pcm038_fb_data = {
120 .pixclock = 188679, /* in ps (5.3MHz) */
121 .xres = 240,
122 .yres = 320,
123
124 .bpp = 16,
125 .hsync_len = 7,
126 .left_margin = 5,
127 .right_margin = 16,
128
129 .vsync_len = 1,
130 .upper_margin = 7,
131 .lower_margin = 9,
132 .fixed_screen_cpu = 0,
133
134 /*
135 * - HSYNC active high
136 * - VSYNC active high
137 * - clk notenabled while idle
138 * - clock not inverted
139 * - data not inverted
140 * - data enable low active
141 * - enable sharp mode
142 */
143 .pcr = 0xFA0080C0,
144 .pwmr = 0x00A903FF,
145 .lscr1 = 0x00120300,
146 .dmacr = 0x00020010,
147
148 .init = pcm038_fb_init,
149 .exit = pcm038_fb_exit,
150};
151
23/* 152/*
24 * system init for baseboard usage. Will be called by pcm038 init. 153 * system init for baseboard usage. Will be called by pcm038 init.
25 * 154 *
@@ -28,4 +157,6 @@
28 */ 157 */
29void __init pcm970_baseboard_init(void) 158void __init pcm970_baseboard_init(void)
30{ 159{
160 mxc_register_device(&mxc_fb_device, &pcm038_fb_data);
161 mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
31} 162}
diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c
index 16debc296dad..40a485cdc10e 100644
--- a/arch/arm/mach-mx2/serial.c
+++ b/arch/arm/mach-mx2/serial.c
@@ -22,6 +22,7 @@
22#include <linux/serial.h> 22#include <linux/serial.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <mach/imx-uart.h> 24#include <mach/imx-uart.h>
25#include "devices.h"
25 26
26static struct resource uart0[] = { 27static struct resource uart0[] = {
27 { 28 {
@@ -99,6 +100,7 @@ struct platform_device mxc_uart_device3 = {
99 .num_resources = ARRAY_SIZE(uart3), 100 .num_resources = ARRAY_SIZE(uart3),
100}; 101};
101 102
103#ifdef CONFIG_MACH_MX27
102static struct resource uart4[] = { 104static struct resource uart4[] = {
103 { 105 {
104 .start = UART5_BASE_ADDR, 106 .start = UART5_BASE_ADDR,
@@ -136,3 +138,4 @@ struct platform_device mxc_uart_device5 = {
136 .resource = uart5, 138 .resource = uart5,
137 .num_resources = ARRAY_SIZE(uart5), 139 .num_resources = ARRAY_SIZE(uart5),
138}; 140};
141#endif