aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/cache-l2x0.c56
-rw-r--r--arch/arm/mach-imx/clock-imx1.c636
-rw-r--r--arch/arm/mach-imx/clock-imx21.c1239
-rw-r--r--arch/arm/mach-imx/clock-imx25.c340
-rw-r--r--arch/arm/mach-imx/clock-imx27.c764
-rw-r--r--arch/arm/mach-imx/clock-imx31.c630
-rw-r--r--arch/arm/mach-imx/clock-imx35.c551
-rw-r--r--arch/arm/mach-imx/crmregs-imx31.h248
-rw-r--r--arch/arm/mach-imx/dma-v1.c846
-rw-r--r--arch/arm/mach-imx/include/mach/dma-mx1-mx2.h10
-rw-r--r--arch/arm/mach-imx/include/mach/dma-v1.h103
-rw-r--r--arch/arm/mach-imx/mm-imx31.c91
-rw-r--r--arch/arm/mach-imx/mm-imx35.c109
13 files changed, 5623 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/cache-l2x0.c b/arch/arm/mach-imx/cache-l2x0.c
new file mode 100644
index 00000000000..69d1322add3
--- /dev/null
+++ b/arch/arm/mach-imx/cache-l2x0.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (C) 2009-2010 Pengutronix
3 * Sascha Hauer <s.hauer@pengutronix.de>
4 * Juergen Beisert <j.beisert@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/err.h>
13#include <linux/kernel.h>
14
15#include <asm/hardware/cache-l2x0.h>
16
17#include <mach/hardware.h>
18
19static int mxc_init_l2x0(void)
20{
21 void __iomem *l2x0_base;
22 void __iomem *clkctl_base;
23
24 if (!cpu_is_mx31() && !cpu_is_mx35())
25 return 0;
26
27/*
28 * First of all, we must repair broken chip settings. There are some
29 * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
30 * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
31 * Workaraound is to setup the correct register setting prior enabling the
32 * L2 cache. This should not hurt already working CPUs, as they are using the
33 * same value.
34 */
35#define L2_MEM_VAL 0x10
36
37 clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
38 if (clkctl_base != NULL) {
39 writel(0x00000515, clkctl_base + L2_MEM_VAL);
40 iounmap(clkctl_base);
41 } else {
42 pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
43 }
44
45 l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
46 if (IS_ERR(l2x0_base)) {
47 printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
48 PTR_ERR(l2x0_base));
49 return 0;
50 }
51
52 l2x0_init(l2x0_base, 0x00030024, 0x00000000);
53
54 return 0;
55}
56arch_initcall(mxc_init_l2x0);
diff --git a/arch/arm/mach-imx/clock-imx1.c b/arch/arm/mach-imx/clock-imx1.c
new file mode 100644
index 00000000000..4aabeb24156
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -0,0 +1,636 @@
1/*
2 * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/list.h>
21#include <linux/math64.h>
22#include <linux/err.h>
23#include <linux/clk.h>
24#include <linux/io.h>
25#include <linux/clkdev.h>
26
27#include <mach/clock.h>
28#include <mach/hardware.h>
29#include <mach/common.h>
30
31#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
32
33/* CCM register addresses */
34#define CCM_CSCR IO_ADDR_CCM(0x0)
35#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
37#define CCM_PCDR IO_ADDR_CCM(0x20)
38
39#define CCM_CSCR_CLKO_OFFSET 29
40#define CCM_CSCR_CLKO_MASK (0x7 << 29)
41#define CCM_CSCR_USB_OFFSET 26
42#define CCM_CSCR_USB_MASK (0x7 << 26)
43#define CCM_CSCR_OSC_EN_SHIFT 17
44#define CCM_CSCR_SYSTEM_SEL (1 << 16)
45#define CCM_CSCR_BCLK_OFFSET 10
46#define CCM_CSCR_BCLK_MASK (0xf << 10)
47#define CCM_CSCR_PRESC (1 << 15)
48
49#define CCM_PCDR_PCLK3_OFFSET 16
50#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
51#define CCM_PCDR_PCLK2_OFFSET 4
52#define CCM_PCDR_PCLK2_MASK (0xf << 4)
53#define CCM_PCDR_PCLK1_OFFSET 0
54#define CCM_PCDR_PCLK1_MASK 0xf
55
56#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
57
58/* SCM register addresses */
59#define SCM_GCCR IO_ADDR_SCM(0xc)
60
61#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
62#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
63#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
64#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
65
66static int _clk_enable(struct clk *clk)
67{
68 unsigned int reg;
69
70 reg = __raw_readl(clk->enable_reg);
71 reg |= 1 << clk->enable_shift;
72 __raw_writel(reg, clk->enable_reg);
73
74 return 0;
75}
76
77static void _clk_disable(struct clk *clk)
78{
79 unsigned int reg;
80
81 reg = __raw_readl(clk->enable_reg);
82 reg &= ~(1 << clk->enable_shift);
83 __raw_writel(reg, clk->enable_reg);
84}
85
86static int _clk_can_use_parent(const struct clk *clk_arr[], unsigned int size,
87 struct clk *parent)
88{
89 int i;
90
91 for (i = 0; i < size; i++)
92 if (parent == clk_arr[i])
93 return i;
94
95 return -EINVAL;
96}
97
98static unsigned long
99_clk_simple_round_rate(struct clk *clk, unsigned long rate, unsigned int limit)
100{
101 int div;
102 unsigned long parent_rate;
103
104 parent_rate = clk_get_rate(clk->parent);
105
106 div = parent_rate / rate;
107 if (parent_rate % rate)
108 div++;
109
110 if (div > limit)
111 div = limit;
112
113 return parent_rate / div;
114}
115
116static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
117{
118 return clk->parent->round_rate(clk->parent, rate);
119}
120
121static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
122{
123 return clk->parent->set_rate(clk->parent, rate);
124}
125
126static unsigned long clk16m_get_rate(struct clk *clk)
127{
128 return 16000000;
129}
130
131static struct clk clk16m = {
132 .get_rate = clk16m_get_rate,
133 .enable = _clk_enable,
134 .enable_reg = CCM_CSCR,
135 .enable_shift = CCM_CSCR_OSC_EN_SHIFT,
136 .disable = _clk_disable,
137};
138
139/* in Hz */
140static unsigned long clk32_rate;
141
142static unsigned long clk32_get_rate(struct clk *clk)
143{
144 return clk32_rate;
145}
146
147static struct clk clk32 = {
148 .get_rate = clk32_get_rate,
149};
150
151static unsigned long clk32_premult_get_rate(struct clk *clk)
152{
153 return clk_get_rate(clk->parent) * 512;
154}
155
156static struct clk clk32_premult = {
157 .parent = &clk32,
158 .get_rate = clk32_premult_get_rate,
159};
160
161static const struct clk *prem_clk_clocks[] = {
162 &clk32_premult,
163 &clk16m,
164};
165
166static int prem_clk_set_parent(struct clk *clk, struct clk *parent)
167{
168 int i;
169 unsigned int reg = __raw_readl(CCM_CSCR);
170
171 i = _clk_can_use_parent(prem_clk_clocks, ARRAY_SIZE(prem_clk_clocks),
172 parent);
173
174 switch (i) {
175 case 0:
176 reg &= ~CCM_CSCR_SYSTEM_SEL;
177 break;
178 case 1:
179 reg |= CCM_CSCR_SYSTEM_SEL;
180 break;
181 default:
182 return i;
183 }
184
185 __raw_writel(reg, CCM_CSCR);
186
187 return 0;
188}
189
190static struct clk prem_clk = {
191 .set_parent = prem_clk_set_parent,
192};
193
194static unsigned long system_clk_get_rate(struct clk *clk)
195{
196 return mxc_decode_pll(__raw_readl(CCM_SPCTL0),
197 clk_get_rate(clk->parent));
198}
199
200static struct clk system_clk = {
201 .parent = &prem_clk,
202 .get_rate = system_clk_get_rate,
203};
204
205static unsigned long mcu_clk_get_rate(struct clk *clk)
206{
207 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
208 clk_get_rate(clk->parent));
209}
210
211static struct clk mcu_clk = {
212 .parent = &clk32_premult,
213 .get_rate = mcu_clk_get_rate,
214};
215
216static unsigned long fclk_get_rate(struct clk *clk)
217{
218 unsigned long fclk = clk_get_rate(clk->parent);
219
220 if (__raw_readl(CCM_CSCR) & CCM_CSCR_PRESC)
221 fclk /= 2;
222
223 return fclk;
224}
225
226static struct clk fclk = {
227 .parent = &mcu_clk,
228 .get_rate = fclk_get_rate,
229};
230
231/*
232 * get hclk ( SDRAM, CSI, Memory Stick, I2C, DMA )
233 */
234static unsigned long hclk_get_rate(struct clk *clk)
235{
236 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
237 CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET) + 1);
238}
239
240static unsigned long hclk_round_rate(struct clk *clk, unsigned long rate)
241{
242 return _clk_simple_round_rate(clk, rate, 16);
243}
244
245static int hclk_set_rate(struct clk *clk, unsigned long rate)
246{
247 unsigned int div;
248 unsigned int reg;
249 unsigned long parent_rate;
250
251 parent_rate = clk_get_rate(clk->parent);
252
253 div = parent_rate / rate;
254
255 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
256 return -EINVAL;
257
258 div--;
259
260 reg = __raw_readl(CCM_CSCR);
261 reg &= ~CCM_CSCR_BCLK_MASK;
262 reg |= div << CCM_CSCR_BCLK_OFFSET;
263 __raw_writel(reg, CCM_CSCR);
264
265 return 0;
266}
267
268static struct clk hclk = {
269 .parent = &system_clk,
270 .get_rate = hclk_get_rate,
271 .round_rate = hclk_round_rate,
272 .set_rate = hclk_set_rate,
273};
274
275static unsigned long clk48m_get_rate(struct clk *clk)
276{
277 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_CSCR) &
278 CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET) + 1);
279}
280
281static unsigned long clk48m_round_rate(struct clk *clk, unsigned long rate)
282{
283 return _clk_simple_round_rate(clk, rate, 8);
284}
285
286static int clk48m_set_rate(struct clk *clk, unsigned long rate)
287{
288 unsigned int div;
289 unsigned int reg;
290 unsigned long parent_rate;
291
292 parent_rate = clk_get_rate(clk->parent);
293
294 div = parent_rate / rate;
295
296 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
297 return -EINVAL;
298
299 div--;
300
301 reg = __raw_readl(CCM_CSCR);
302 reg &= ~CCM_CSCR_USB_MASK;
303 reg |= div << CCM_CSCR_USB_OFFSET;
304 __raw_writel(reg, CCM_CSCR);
305
306 return 0;
307}
308
309static struct clk clk48m = {
310 .parent = &system_clk,
311 .get_rate = clk48m_get_rate,
312 .round_rate = clk48m_round_rate,
313 .set_rate = clk48m_set_rate,
314};
315
316/*
317 * get peripheral clock 1 ( UART[12], Timer[12], PWM )
318 */
319static unsigned long perclk1_get_rate(struct clk *clk)
320{
321 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
322 CCM_PCDR_PCLK1_MASK) >> CCM_PCDR_PCLK1_OFFSET) + 1);
323}
324
325static unsigned long perclk1_round_rate(struct clk *clk, unsigned long rate)
326{
327 return _clk_simple_round_rate(clk, rate, 16);
328}
329
330static int perclk1_set_rate(struct clk *clk, unsigned long rate)
331{
332 unsigned int div;
333 unsigned int reg;
334 unsigned long parent_rate;
335
336 parent_rate = clk_get_rate(clk->parent);
337
338 div = parent_rate / rate;
339
340 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
341 return -EINVAL;
342
343 div--;
344
345 reg = __raw_readl(CCM_PCDR);
346 reg &= ~CCM_PCDR_PCLK1_MASK;
347 reg |= div << CCM_PCDR_PCLK1_OFFSET;
348 __raw_writel(reg, CCM_PCDR);
349
350 return 0;
351}
352
353/*
354 * get peripheral clock 2 ( LCD, SD, SPI[12] )
355 */
356static unsigned long perclk2_get_rate(struct clk *clk)
357{
358 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
359 CCM_PCDR_PCLK2_MASK) >> CCM_PCDR_PCLK2_OFFSET) + 1);
360}
361
362static unsigned long perclk2_round_rate(struct clk *clk, unsigned long rate)
363{
364 return _clk_simple_round_rate(clk, rate, 16);
365}
366
367static int perclk2_set_rate(struct clk *clk, unsigned long rate)
368{
369 unsigned int div;
370 unsigned int reg;
371 unsigned long parent_rate;
372
373 parent_rate = clk_get_rate(clk->parent);
374
375 div = parent_rate / rate;
376
377 if (div > 16 || div < 1 || ((parent_rate / div) != rate))
378 return -EINVAL;
379
380 div--;
381
382 reg = __raw_readl(CCM_PCDR);
383 reg &= ~CCM_PCDR_PCLK2_MASK;
384 reg |= div << CCM_PCDR_PCLK2_OFFSET;
385 __raw_writel(reg, CCM_PCDR);
386
387 return 0;
388}
389
390/*
391 * get peripheral clock 3 ( SSI )
392 */
393static unsigned long perclk3_get_rate(struct clk *clk)
394{
395 return clk_get_rate(clk->parent) / (((__raw_readl(CCM_PCDR) &
396 CCM_PCDR_PCLK3_MASK) >> CCM_PCDR_PCLK3_OFFSET) + 1);
397}
398
399static unsigned long perclk3_round_rate(struct clk *clk, unsigned long rate)
400{
401 return _clk_simple_round_rate(clk, rate, 128);
402}
403
404static int perclk3_set_rate(struct clk *clk, unsigned long rate)
405{
406 unsigned int div;
407 unsigned int reg;
408 unsigned long parent_rate;
409
410 parent_rate = clk_get_rate(clk->parent);
411
412 div = parent_rate / rate;
413
414 if (div > 128 || div < 1 || ((parent_rate / div) != rate))
415 return -EINVAL;
416
417 div--;
418
419 reg = __raw_readl(CCM_PCDR);
420 reg &= ~CCM_PCDR_PCLK3_MASK;
421 reg |= div << CCM_PCDR_PCLK3_OFFSET;
422 __raw_writel(reg, CCM_PCDR);
423
424 return 0;
425}
426
427static struct clk perclk[] = {
428 {
429 .id = 0,
430 .parent = &system_clk,
431 .get_rate = perclk1_get_rate,
432 .round_rate = perclk1_round_rate,
433 .set_rate = perclk1_set_rate,
434 }, {
435 .id = 1,
436 .parent = &system_clk,
437 .get_rate = perclk2_get_rate,
438 .round_rate = perclk2_round_rate,
439 .set_rate = perclk2_set_rate,
440 }, {
441 .id = 2,
442 .parent = &system_clk,
443 .get_rate = perclk3_get_rate,
444 .round_rate = perclk3_round_rate,
445 .set_rate = perclk3_set_rate,
446 }
447};
448
449static const struct clk *clko_clocks[] = {
450 &perclk[0],
451 &hclk,
452 &clk48m,
453 &clk16m,
454 &prem_clk,
455 &fclk,
456};
457
458static int clko_set_parent(struct clk *clk, struct clk *parent)
459{
460 int i;
461 unsigned int reg;
462
463 i = _clk_can_use_parent(clko_clocks, ARRAY_SIZE(clko_clocks), parent);
464 if (i < 0)
465 return i;
466
467 reg = __raw_readl(CCM_CSCR) & ~CCM_CSCR_CLKO_MASK;
468 reg |= i << CCM_CSCR_CLKO_OFFSET;
469 __raw_writel(reg, CCM_CSCR);
470
471 if (clko_clocks[i]->set_rate && clko_clocks[i]->round_rate) {
472 clk->set_rate = _clk_parent_set_rate;
473 clk->round_rate = _clk_parent_round_rate;
474 } else {
475 clk->set_rate = NULL;
476 clk->round_rate = NULL;
477 }
478
479 return 0;
480}
481
482static struct clk clko_clk = {
483 .set_parent = clko_set_parent,
484};
485
486static struct clk dma_clk = {
487 .parent = &hclk,
488 .round_rate = _clk_parent_round_rate,
489 .set_rate = _clk_parent_set_rate,
490 .enable = _clk_enable,
491 .enable_reg = SCM_GCCR,
492 .enable_shift = SCM_GCCR_DMA_CLK_EN_OFFSET,
493 .disable = _clk_disable,
494};
495
496static struct clk csi_clk = {
497 .parent = &hclk,
498 .round_rate = _clk_parent_round_rate,
499 .set_rate = _clk_parent_set_rate,
500 .enable = _clk_enable,
501 .enable_reg = SCM_GCCR,
502 .enable_shift = SCM_GCCR_CSI_CLK_EN_OFFSET,
503 .disable = _clk_disable,
504};
505
506static struct clk mma_clk = {
507 .parent = &hclk,
508 .round_rate = _clk_parent_round_rate,
509 .set_rate = _clk_parent_set_rate,
510 .enable = _clk_enable,
511 .enable_reg = SCM_GCCR,
512 .enable_shift = SCM_GCCR_MMA_CLK_EN_OFFSET,
513 .disable = _clk_disable,
514};
515
516static struct clk usbd_clk = {
517 .parent = &clk48m,
518 .round_rate = _clk_parent_round_rate,
519 .set_rate = _clk_parent_set_rate,
520 .enable = _clk_enable,
521 .enable_reg = SCM_GCCR,
522 .enable_shift = SCM_GCCR_USBD_CLK_EN_OFFSET,
523 .disable = _clk_disable,
524};
525
526static struct clk gpt_clk = {
527 .parent = &perclk[0],
528 .round_rate = _clk_parent_round_rate,
529 .set_rate = _clk_parent_set_rate,
530};
531
532static struct clk uart_clk = {
533 .parent = &perclk[0],
534 .round_rate = _clk_parent_round_rate,
535 .set_rate = _clk_parent_set_rate,
536};
537
538static struct clk i2c_clk = {
539 .parent = &hclk,
540 .round_rate = _clk_parent_round_rate,
541 .set_rate = _clk_parent_set_rate,
542};
543
544static struct clk spi_clk = {
545 .parent = &perclk[1],
546 .round_rate = _clk_parent_round_rate,
547 .set_rate = _clk_parent_set_rate,
548};
549
550static struct clk sdhc_clk = {
551 .parent = &perclk[1],
552 .round_rate = _clk_parent_round_rate,
553 .set_rate = _clk_parent_set_rate,
554};
555
556static struct clk lcdc_clk = {
557 .parent = &perclk[1],
558 .round_rate = _clk_parent_round_rate,
559 .set_rate = _clk_parent_set_rate,
560};
561
562static struct clk mshc_clk = {
563 .parent = &hclk,
564 .round_rate = _clk_parent_round_rate,
565 .set_rate = _clk_parent_set_rate,
566};
567
568static struct clk ssi_clk = {
569 .parent = &perclk[2],
570 .round_rate = _clk_parent_round_rate,
571 .set_rate = _clk_parent_set_rate,
572};
573
574static struct clk rtc_clk = {
575 .parent = &clk32,
576};
577
578#define _REGISTER_CLOCK(d, n, c) \
579 { \
580 .dev_id = d, \
581 .con_id = n, \
582 .clk = &c, \
583 },
584static struct clk_lookup lookups[] __initdata = {
585 _REGISTER_CLOCK(NULL, "dma", dma_clk)
586 _REGISTER_CLOCK("mx1-camera.0", NULL, csi_clk)
587 _REGISTER_CLOCK(NULL, "mma", mma_clk)
588 _REGISTER_CLOCK("imx_udc.0", NULL, usbd_clk)
589 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
590 _REGISTER_CLOCK("imx1-uart.0", NULL, uart_clk)
591 _REGISTER_CLOCK("imx1-uart.1", NULL, uart_clk)
592 _REGISTER_CLOCK("imx1-uart.2", NULL, uart_clk)
593 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
594 _REGISTER_CLOCK("imx1-cspi.0", NULL, spi_clk)
595 _REGISTER_CLOCK("imx1-cspi.1", NULL, spi_clk)
596 _REGISTER_CLOCK("imx-mmc.0", NULL, sdhc_clk)
597 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
598 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
599 _REGISTER_CLOCK(NULL, "ssi", ssi_clk)
600 _REGISTER_CLOCK("mxc_rtc.0", NULL, rtc_clk)
601};
602
603int __init mx1_clocks_init(unsigned long fref)
604{
605 unsigned int reg;
606
607 /* disable clocks we are able to */
608 __raw_writel(0, SCM_GCCR);
609
610 clk32_rate = fref;
611 reg = __raw_readl(CCM_CSCR);
612
613 /* detect clock reference for system PLL */
614 if (reg & CCM_CSCR_SYSTEM_SEL) {
615 prem_clk.parent = &clk16m;
616 } else {
617 /* ensure that oscillator is disabled */
618 reg &= ~(1 << CCM_CSCR_OSC_EN_SHIFT);
619 __raw_writel(reg, CCM_CSCR);
620 prem_clk.parent = &clk32_premult;
621 }
622
623 /* detect reference for CLKO */
624 reg = (reg & CCM_CSCR_CLKO_MASK) >> CCM_CSCR_CLKO_OFFSET;
625 clko_clk.parent = (struct clk *)clko_clocks[reg];
626
627 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
628
629 clk_enable(&hclk);
630 clk_enable(&fclk);
631
632 mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
633 MX1_TIM1_INT);
634
635 return 0;
636}
diff --git a/arch/arm/mach-imx/clock-imx21.c b/arch/arm/mach-imx/clock-imx21.c
new file mode 100644
index 00000000000..ee15d8c9db0
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx21.c
@@ -0,0 +1,1239 @@
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#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <asm/div64.h>
30
31#define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
32
33/* Register offsets */
34#define CCM_CSCR IO_ADDR_CCM(0x0)
35#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
36#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
37#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
38#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
39#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
40#define CCM_PCDR0 IO_ADDR_CCM(0x18)
41#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
42#define CCM_PCCR0 IO_ADDR_CCM(0x20)
43#define CCM_PCCR1 IO_ADDR_CCM(0x24)
44#define CCM_CCSR IO_ADDR_CCM(0x28)
45#define CCM_PMCTL IO_ADDR_CCM(0x2c)
46#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
47#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
48
49#define CCM_CSCR_PRESC_OFFSET 29
50#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
51
52#define CCM_CSCR_USB_OFFSET 26
53#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET)
54#define CCM_CSCR_SD_OFFSET 24
55#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET)
56#define CCM_CSCR_SPLLRES (1 << 22)
57#define CCM_CSCR_MPLLRES (1 << 21)
58#define CCM_CSCR_SSI2_OFFSET 20
59#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET)
60#define CCM_CSCR_SSI1_OFFSET 19
61#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET)
62#define CCM_CSCR_FIR_OFFSET 18
63#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET)
64#define CCM_CSCR_SP (1 << 17)
65#define CCM_CSCR_MCU (1 << 16)
66#define CCM_CSCR_BCLK_OFFSET 10
67#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET)
68#define CCM_CSCR_IPDIV_OFFSET 9
69#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET)
70
71#define CCM_CSCR_OSC26MDIV (1 << 4)
72#define CCM_CSCR_OSC26M (1 << 3)
73#define CCM_CSCR_FPM (1 << 2)
74#define CCM_CSCR_SPEN (1 << 1)
75#define CCM_CSCR_MPEN 1
76
77#define CCM_MPCTL0_CPLM (1 << 31)
78#define CCM_MPCTL0_PD_OFFSET 26
79#define CCM_MPCTL0_PD_MASK (0xf << 26)
80#define CCM_MPCTL0_MFD_OFFSET 16
81#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
82#define CCM_MPCTL0_MFI_OFFSET 10
83#define CCM_MPCTL0_MFI_MASK (0xf << 10)
84#define CCM_MPCTL0_MFN_OFFSET 0
85#define CCM_MPCTL0_MFN_MASK 0x3ff
86
87#define CCM_MPCTL1_LF (1 << 15)
88#define CCM_MPCTL1_BRMO (1 << 6)
89
90#define CCM_SPCTL0_CPLM (1 << 31)
91#define CCM_SPCTL0_PD_OFFSET 26
92#define CCM_SPCTL0_PD_MASK (0xf << 26)
93#define CCM_SPCTL0_MFD_OFFSET 16
94#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
95#define CCM_SPCTL0_MFI_OFFSET 10
96#define CCM_SPCTL0_MFI_MASK (0xf << 10)
97#define CCM_SPCTL0_MFN_OFFSET 0
98#define CCM_SPCTL0_MFN_MASK 0x3ff
99
100#define CCM_SPCTL1_LF (1 << 15)
101#define CCM_SPCTL1_BRMO (1 << 6)
102
103#define CCM_OSC26MCTL_PEAK_OFFSET 16
104#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
105#define CCM_OSC26MCTL_AGC_OFFSET 8
106#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
107#define CCM_OSC26MCTL_ANATEST_OFFSET 0
108#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
109
110#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
111#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
112#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
113#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
114#define CCM_PCDR0_NFCDIV_OFFSET 12
115#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
116#define CCM_PCDR0_48MDIV_OFFSET 5
117#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET)
118#define CCM_PCDR0_FIRIDIV_OFFSET 0
119#define CCM_PCDR0_FIRIDIV_MASK 0x1f
120#define CCM_PCDR1_PERDIV4_OFFSET 24
121#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
122#define CCM_PCDR1_PERDIV3_OFFSET 16
123#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
124#define CCM_PCDR1_PERDIV2_OFFSET 8
125#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
126#define CCM_PCDR1_PERDIV1_OFFSET 0
127#define CCM_PCDR1_PERDIV1_MASK 0x3f
128
129#define CCM_PCCR_HCLK_CSI_OFFSET 31
130#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0
131#define CCM_PCCR_HCLK_DMA_OFFSET 30
132#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0
133#define CCM_PCCR_HCLK_BROM_OFFSET 28
134#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0
135#define CCM_PCCR_HCLK_EMMA_OFFSET 27
136#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0
137#define CCM_PCCR_HCLK_LCDC_OFFSET 26
138#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0
139#define CCM_PCCR_HCLK_SLCDC_OFFSET 25
140#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0
141#define CCM_PCCR_HCLK_USBOTG_OFFSET 24
142#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0
143#define CCM_PCCR_HCLK_BMI_OFFSET 23
144#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK)
145#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0
146#define CCM_PCCR_PERCLK4_OFFSET 22
147#define CCM_PCCR_PERCLK4_REG CCM_PCCR0
148#define CCM_PCCR_SLCDC_OFFSET 21
149#define CCM_PCCR_SLCDC_REG CCM_PCCR0
150#define CCM_PCCR_FIRI_BAUD_OFFSET 20
151#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK)
152#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0
153#define CCM_PCCR_NFC_OFFSET 19
154#define CCM_PCCR_NFC_REG CCM_PCCR0
155#define CCM_PCCR_LCDC_OFFSET 18
156#define CCM_PCCR_LCDC_REG CCM_PCCR0
157#define CCM_PCCR_SSI1_BAUD_OFFSET 17
158#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0
159#define CCM_PCCR_SSI2_BAUD_OFFSET 16
160#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0
161#define CCM_PCCR_EMMA_OFFSET 15
162#define CCM_PCCR_EMMA_REG CCM_PCCR0
163#define CCM_PCCR_USBOTG_OFFSET 14
164#define CCM_PCCR_USBOTG_REG CCM_PCCR0
165#define CCM_PCCR_DMA_OFFSET 13
166#define CCM_PCCR_DMA_REG CCM_PCCR0
167#define CCM_PCCR_I2C1_OFFSET 12
168#define CCM_PCCR_I2C1_REG CCM_PCCR0
169#define CCM_PCCR_GPIO_OFFSET 11
170#define CCM_PCCR_GPIO_REG CCM_PCCR0
171#define CCM_PCCR_SDHC2_OFFSET 10
172#define CCM_PCCR_SDHC2_REG CCM_PCCR0
173#define CCM_PCCR_SDHC1_OFFSET 9
174#define CCM_PCCR_SDHC1_REG CCM_PCCR0
175#define CCM_PCCR_FIRI_OFFSET 8
176#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK)
177#define CCM_PCCR_FIRI_REG CCM_PCCR0
178#define CCM_PCCR_SSI2_IPG_OFFSET 7
179#define CCM_PCCR_SSI2_REG CCM_PCCR0
180#define CCM_PCCR_SSI1_IPG_OFFSET 6
181#define CCM_PCCR_SSI1_REG CCM_PCCR0
182#define CCM_PCCR_CSPI2_OFFSET 5
183#define CCM_PCCR_CSPI2_REG CCM_PCCR0
184#define CCM_PCCR_CSPI1_OFFSET 4
185#define CCM_PCCR_CSPI1_REG CCM_PCCR0
186#define CCM_PCCR_UART4_OFFSET 3
187#define CCM_PCCR_UART4_REG CCM_PCCR0
188#define CCM_PCCR_UART3_OFFSET 2
189#define CCM_PCCR_UART3_REG CCM_PCCR0
190#define CCM_PCCR_UART2_OFFSET 1
191#define CCM_PCCR_UART2_REG CCM_PCCR0
192#define CCM_PCCR_UART1_OFFSET 0
193#define CCM_PCCR_UART1_REG CCM_PCCR0
194
195#define CCM_PCCR_OWIRE_OFFSET 31
196#define CCM_PCCR_OWIRE_REG CCM_PCCR1
197#define CCM_PCCR_KPP_OFFSET 30
198#define CCM_PCCR_KPP_REG CCM_PCCR1
199#define CCM_PCCR_RTC_OFFSET 29
200#define CCM_PCCR_RTC_REG CCM_PCCR1
201#define CCM_PCCR_PWM_OFFSET 28
202#define CCM_PCCR_PWM_REG CCM_PCCR1
203#define CCM_PCCR_GPT3_OFFSET 27
204#define CCM_PCCR_GPT3_REG CCM_PCCR1
205#define CCM_PCCR_GPT2_OFFSET 26
206#define CCM_PCCR_GPT2_REG CCM_PCCR1
207#define CCM_PCCR_GPT1_OFFSET 25
208#define CCM_PCCR_GPT1_REG CCM_PCCR1
209#define CCM_PCCR_WDT_OFFSET 24
210#define CCM_PCCR_WDT_REG CCM_PCCR1
211#define CCM_PCCR_CSPI3_OFFSET 23
212#define CCM_PCCR_CSPI3_REG CCM_PCCR1
213
214#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET)
215#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET)
216#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET)
217#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET)
218#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET)
219#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET)
220#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET)
221#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET)
222#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET)
223#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET)
224#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET)
225#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET)
226#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET)
227#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET)
228#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET)
229#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET)
230#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET)
231#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET)
232#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET)
233#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET)
234#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET)
235#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET)
236#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET)
237#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET)
238#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET)
239#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET)
240#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET)
241#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET)
242#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET)
243#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET)
244#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET)
245#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET)
246#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET)
247#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET)
248#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET)
249#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET)
250#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET)
251
252#define CCM_CCSR_32KSR (1 << 15)
253
254#define CCM_CCSR_CLKMODE1 (1 << 9)
255#define CCM_CCSR_CLKMODE0 (1 << 8)
256
257#define CCM_CCSR_CLKOSEL_OFFSET 0
258#define CCM_CCSR_CLKOSEL_MASK 0x1f
259
260#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
261#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
262
263static int _clk_enable(struct clk *clk)
264{
265 u32 reg;
266
267 reg = __raw_readl(clk->enable_reg);
268 reg |= 1 << clk->enable_shift;
269 __raw_writel(reg, clk->enable_reg);
270 return 0;
271}
272
273static void _clk_disable(struct clk *clk)
274{
275 u32 reg;
276
277 reg = __raw_readl(clk->enable_reg);
278 reg &= ~(1 << clk->enable_shift);
279 __raw_writel(reg, clk->enable_reg);
280}
281
282static unsigned long _clk_generic_round_rate(struct clk *clk,
283 unsigned long rate,
284 u32 max_divisor)
285{
286 u32 div;
287 unsigned long parent_rate;
288
289 parent_rate = clk_get_rate(clk->parent);
290
291 div = parent_rate / rate;
292 if (parent_rate % rate)
293 div++;
294
295 if (div > max_divisor)
296 div = max_divisor;
297
298 return parent_rate / div;
299}
300
301static int _clk_spll_enable(struct clk *clk)
302{
303 u32 reg;
304
305 reg = __raw_readl(CCM_CSCR);
306 reg |= CCM_CSCR_SPEN;
307 __raw_writel(reg, CCM_CSCR);
308
309 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0)
310 ;
311 return 0;
312}
313
314static void _clk_spll_disable(struct clk *clk)
315{
316 u32 reg;
317
318 reg = __raw_readl(CCM_CSCR);
319 reg &= ~CCM_CSCR_SPEN;
320 __raw_writel(reg, CCM_CSCR);
321}
322
323
324#define CSCR() (__raw_readl(CCM_CSCR))
325#define PCDR0() (__raw_readl(CCM_PCDR0))
326#define PCDR1() (__raw_readl(CCM_PCDR1))
327
328static unsigned long _clk_perclkx_round_rate(struct clk *clk,
329 unsigned long rate)
330{
331 return _clk_generic_round_rate(clk, rate, 64);
332}
333
334static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
335{
336 u32 reg;
337 u32 div;
338 unsigned long parent_rate;
339
340 parent_rate = clk_get_rate(clk->parent);
341
342 if (clk->id < 0 || clk->id > 3)
343 return -EINVAL;
344
345 div = parent_rate / rate;
346 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
347 return -EINVAL;
348 div--;
349
350 reg =
351 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
352 (clk->id << 3));
353 reg |= div << (clk->id << 3);
354 __raw_writel(reg, CCM_PCDR1);
355
356 return 0;
357}
358
359static unsigned long _clk_usb_recalc(struct clk *clk)
360{
361 unsigned long usb_pdf;
362 unsigned long parent_rate;
363
364 parent_rate = clk_get_rate(clk->parent);
365
366 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
367
368 return parent_rate / (usb_pdf + 1U);
369}
370
371static unsigned long _clk_usb_round_rate(struct clk *clk,
372 unsigned long rate)
373{
374 return _clk_generic_round_rate(clk, rate, 8);
375}
376
377static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
378{
379 u32 reg;
380 u32 div;
381 unsigned long parent_rate;
382
383 parent_rate = clk_get_rate(clk->parent);
384
385 div = parent_rate / rate;
386 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
387 return -EINVAL;
388 div--;
389
390 reg = CSCR() & ~CCM_CSCR_USB_MASK;
391 reg |= div << CCM_CSCR_USB_OFFSET;
392 __raw_writel(reg, CCM_CSCR);
393
394 return 0;
395}
396
397static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf)
398{
399 unsigned long parent_rate;
400
401 parent_rate = clk_get_rate(clk->parent);
402
403 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
404
405 return 2UL * parent_rate / pdf;
406}
407
408static unsigned long _clk_ssi1_recalc(struct clk *clk)
409{
410 return _clk_ssix_recalc(clk,
411 (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK)
412 >> CCM_PCDR0_SSI1BAUDDIV_OFFSET);
413}
414
415static unsigned long _clk_ssi2_recalc(struct clk *clk)
416{
417 return _clk_ssix_recalc(clk,
418 (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
419 CCM_PCDR0_SSI2BAUDDIV_OFFSET);
420}
421
422static unsigned long _clk_nfc_recalc(struct clk *clk)
423{
424 unsigned long nfc_pdf;
425 unsigned long parent_rate;
426
427 parent_rate = clk_get_rate(clk->parent);
428
429 nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK)
430 >> CCM_PCDR0_NFCDIV_OFFSET;
431
432 return parent_rate / (nfc_pdf + 1);
433}
434
435static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
436{
437 return clk->parent->round_rate(clk->parent, rate);
438}
439
440static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
441{
442 return clk->parent->set_rate(clk->parent, rate);
443}
444
445static unsigned long external_high_reference; /* in Hz */
446
447static unsigned long get_high_reference_clock_rate(struct clk *clk)
448{
449 return external_high_reference;
450}
451
452/*
453 * the high frequency external clock reference
454 * Default case is 26MHz.
455 */
456static struct clk ckih_clk = {
457 .get_rate = get_high_reference_clock_rate,
458};
459
460static unsigned long external_low_reference; /* in Hz */
461
462static unsigned long get_low_reference_clock_rate(struct clk *clk)
463{
464 return external_low_reference;
465}
466
467/*
468 * the low frequency external clock reference
469 * Default case is 32.768kHz.
470 */
471static struct clk ckil_clk = {
472 .get_rate = get_low_reference_clock_rate,
473};
474
475
476static unsigned long _clk_fpm_recalc(struct clk *clk)
477{
478 return clk_get_rate(clk->parent) * 512;
479}
480
481/* Output of frequency pre multiplier */
482static struct clk fpm_clk = {
483 .parent = &ckil_clk,
484 .get_rate = _clk_fpm_recalc,
485};
486
487static unsigned long get_mpll_clk(struct clk *clk)
488{
489 uint32_t reg;
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}
510
511static struct clk mpll_clk = {
512 .parent = &ckih_clk,
513 .get_rate = get_mpll_clk,
514};
515
516static unsigned long _clk_fclk_get_rate(struct clk *clk)
517{
518 unsigned long parent_rate;
519 u32 div;
520
521 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
522 parent_rate = clk_get_rate(clk->parent);
523
524 return parent_rate / (div+1);
525}
526
527static struct clk fclk_clk = {
528 .parent = &mpll_clk,
529 .get_rate = _clk_fclk_get_rate
530};
531
532static unsigned long get_spll_clk(struct clk *clk)
533{
534 uint32_t reg;
535 unsigned long ref_clk;
536 unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
537 unsigned long long temp;
538
539 ref_clk = clk_get_rate(clk->parent);
540
541 reg = __raw_readl(CCM_SPCTL0);
542 pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
543 mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
544 mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
545 mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
546
547 mfi = (mfi <= 5) ? 5 : mfi;
548 temp = 2LL * ref_clk * mfn;
549 do_div(temp, mfd + 1);
550 temp = 2LL * ref_clk * mfi + temp;
551 do_div(temp, pdf + 1);
552
553 return (unsigned long)temp;
554}
555
556static struct clk spll_clk = {
557 .parent = &ckih_clk,
558 .get_rate = get_spll_clk,
559 .enable = _clk_spll_enable,
560 .disable = _clk_spll_disable,
561};
562
563static unsigned long get_hclk_clk(struct clk *clk)
564{
565 unsigned long rate;
566 unsigned long bclk_pdf;
567
568 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK)
569 >> CCM_CSCR_BCLK_OFFSET;
570
571 rate = clk_get_rate(clk->parent);
572 return rate / (bclk_pdf + 1);
573}
574
575static struct clk hclk_clk = {
576 .parent = &fclk_clk,
577 .get_rate = get_hclk_clk,
578};
579
580static unsigned long get_ipg_clk(struct clk *clk)
581{
582 unsigned long rate;
583 unsigned long ipg_pdf;
584
585 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
586
587 rate = clk_get_rate(clk->parent);
588 return rate / (ipg_pdf + 1);
589}
590
591static struct clk ipg_clk = {
592 .parent = &hclk_clk,
593 .get_rate = get_ipg_clk,
594};
595
596static unsigned long _clk_perclkx_recalc(struct clk *clk)
597{
598 unsigned long perclk_pdf;
599 unsigned long parent_rate;
600
601 parent_rate = clk_get_rate(clk->parent);
602
603 if (clk->id < 0 || clk->id > 3)
604 return 0;
605
606 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
607
608 return parent_rate / (perclk_pdf + 1);
609}
610
611static struct clk per_clk[] = {
612 {
613 .id = 0,
614 .parent = &mpll_clk,
615 .get_rate = _clk_perclkx_recalc,
616 }, {
617 .id = 1,
618 .parent = &mpll_clk,
619 .get_rate = _clk_perclkx_recalc,
620 }, {
621 .id = 2,
622 .parent = &mpll_clk,
623 .round_rate = _clk_perclkx_round_rate,
624 .set_rate = _clk_perclkx_set_rate,
625 .get_rate = _clk_perclkx_recalc,
626 /* Enable/Disable done via lcd_clkc[1] */
627 }, {
628 .id = 3,
629 .parent = &mpll_clk,
630 .round_rate = _clk_perclkx_round_rate,
631 .set_rate = _clk_perclkx_set_rate,
632 .get_rate = _clk_perclkx_recalc,
633 /* Enable/Disable done via csi_clk[1] */
634 },
635};
636
637static struct clk uart_ipg_clk[];
638
639static struct clk uart_clk[] = {
640 {
641 .id = 0,
642 .parent = &per_clk[0],
643 .secondary = &uart_ipg_clk[0],
644 }, {
645 .id = 1,
646 .parent = &per_clk[0],
647 .secondary = &uart_ipg_clk[1],
648 }, {
649 .id = 2,
650 .parent = &per_clk[0],
651 .secondary = &uart_ipg_clk[2],
652 }, {
653 .id = 3,
654 .parent = &per_clk[0],
655 .secondary = &uart_ipg_clk[3],
656 },
657};
658
659static struct clk uart_ipg_clk[] = {
660 {
661 .id = 0,
662 .parent = &ipg_clk,
663 .enable = _clk_enable,
664 .enable_reg = CCM_PCCR_UART1_REG,
665 .enable_shift = CCM_PCCR_UART1_OFFSET,
666 .disable = _clk_disable,
667 }, {
668 .id = 1,
669 .parent = &ipg_clk,
670 .enable = _clk_enable,
671 .enable_reg = CCM_PCCR_UART2_REG,
672 .enable_shift = CCM_PCCR_UART2_OFFSET,
673 .disable = _clk_disable,
674 }, {
675 .id = 2,
676 .parent = &ipg_clk,
677 .enable = _clk_enable,
678 .enable_reg = CCM_PCCR_UART3_REG,
679 .enable_shift = CCM_PCCR_UART3_OFFSET,
680 .disable = _clk_disable,
681 }, {
682 .id = 3,
683 .parent = &ipg_clk,
684 .enable = _clk_enable,
685 .enable_reg = CCM_PCCR_UART4_REG,
686 .enable_shift = CCM_PCCR_UART4_OFFSET,
687 .disable = _clk_disable,
688 },
689};
690
691static struct clk gpt_ipg_clk[];
692
693static struct clk gpt_clk[] = {
694 {
695 .id = 0,
696 .parent = &per_clk[0],
697 .secondary = &gpt_ipg_clk[0],
698 }, {
699 .id = 1,
700 .parent = &per_clk[0],
701 .secondary = &gpt_ipg_clk[1],
702 }, {
703 .id = 2,
704 .parent = &per_clk[0],
705 .secondary = &gpt_ipg_clk[2],
706 },
707};
708
709static struct clk gpt_ipg_clk[] = {
710 {
711 .id = 0,
712 .parent = &ipg_clk,
713 .enable = _clk_enable,
714 .enable_reg = CCM_PCCR_GPT1_REG,
715 .enable_shift = CCM_PCCR_GPT1_OFFSET,
716 .disable = _clk_disable,
717 }, {
718 .id = 1,
719 .parent = &ipg_clk,
720 .enable = _clk_enable,
721 .enable_reg = CCM_PCCR_GPT2_REG,
722 .enable_shift = CCM_PCCR_GPT2_OFFSET,
723 .disable = _clk_disable,
724 }, {
725 .id = 2,
726 .parent = &ipg_clk,
727 .enable = _clk_enable,
728 .enable_reg = CCM_PCCR_GPT3_REG,
729 .enable_shift = CCM_PCCR_GPT3_OFFSET,
730 .disable = _clk_disable,
731 },
732};
733
734static struct clk pwm_clk[] = {
735 {
736 .parent = &per_clk[0],
737 .secondary = &pwm_clk[1],
738 }, {
739 .parent = &ipg_clk,
740 .enable = _clk_enable,
741 .enable_reg = CCM_PCCR_PWM_REG,
742 .enable_shift = CCM_PCCR_PWM_OFFSET,
743 .disable = _clk_disable,
744 },
745};
746
747static struct clk sdhc_ipg_clk[];
748
749static struct clk sdhc_clk[] = {
750 {
751 .id = 0,
752 .parent = &per_clk[1],
753 .secondary = &sdhc_ipg_clk[0],
754 }, {
755 .id = 1,
756 .parent = &per_clk[1],
757 .secondary = &sdhc_ipg_clk[1],
758 },
759};
760
761static struct clk sdhc_ipg_clk[] = {
762 {
763 .id = 0,
764 .parent = &ipg_clk,
765 .enable = _clk_enable,
766 .enable_reg = CCM_PCCR_SDHC1_REG,
767 .enable_shift = CCM_PCCR_SDHC1_OFFSET,
768 .disable = _clk_disable,
769 }, {
770 .id = 1,
771 .parent = &ipg_clk,
772 .enable = _clk_enable,
773 .enable_reg = CCM_PCCR_SDHC2_REG,
774 .enable_shift = CCM_PCCR_SDHC2_OFFSET,
775 .disable = _clk_disable,
776 },
777};
778
779static struct clk cspi_ipg_clk[];
780
781static struct clk cspi_clk[] = {
782 {
783 .id = 0,
784 .parent = &per_clk[1],
785 .secondary = &cspi_ipg_clk[0],
786 }, {
787 .id = 1,
788 .parent = &per_clk[1],
789 .secondary = &cspi_ipg_clk[1],
790 }, {
791 .id = 2,
792 .parent = &per_clk[1],
793 .secondary = &cspi_ipg_clk[2],
794 },
795};
796
797static struct clk cspi_ipg_clk[] = {
798 {
799 .id = 0,
800 .parent = &ipg_clk,
801 .enable = _clk_enable,
802 .enable_reg = CCM_PCCR_CSPI1_REG,
803 .enable_shift = CCM_PCCR_CSPI1_OFFSET,
804 .disable = _clk_disable,
805 }, {
806 .id = 1,
807 .parent = &ipg_clk,
808 .enable = _clk_enable,
809 .enable_reg = CCM_PCCR_CSPI2_REG,
810 .enable_shift = CCM_PCCR_CSPI2_OFFSET,
811 .disable = _clk_disable,
812 }, {
813 .id = 3,
814 .parent = &ipg_clk,
815 .enable = _clk_enable,
816 .enable_reg = CCM_PCCR_CSPI3_REG,
817 .enable_shift = CCM_PCCR_CSPI3_OFFSET,
818 .disable = _clk_disable,
819 },
820};
821
822static struct clk lcdc_clk[] = {
823 {
824 .parent = &per_clk[2],
825 .secondary = &lcdc_clk[1],
826 .round_rate = _clk_parent_round_rate,
827 .set_rate = _clk_parent_set_rate,
828 }, {
829 .parent = &ipg_clk,
830 .secondary = &lcdc_clk[2],
831 .enable = _clk_enable,
832 .enable_reg = CCM_PCCR_LCDC_REG,
833 .enable_shift = CCM_PCCR_LCDC_OFFSET,
834 .disable = _clk_disable,
835 }, {
836 .parent = &hclk_clk,
837 .enable = _clk_enable,
838 .enable_reg = CCM_PCCR_HCLK_LCDC_REG,
839 .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET,
840 .disable = _clk_disable,
841 },
842};
843
844static struct clk csi_clk[] = {
845 {
846 .parent = &per_clk[3],
847 .secondary = &csi_clk[1],
848 .round_rate = _clk_parent_round_rate,
849 .set_rate = _clk_parent_set_rate,
850 }, {
851 .parent = &hclk_clk,
852 .enable = _clk_enable,
853 .enable_reg = CCM_PCCR_HCLK_CSI_REG,
854 .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET,
855 .disable = _clk_disable,
856 },
857};
858
859static struct clk usb_clk[] = {
860 {
861 .parent = &spll_clk,
862 .secondary = &usb_clk[1],
863 .get_rate = _clk_usb_recalc,
864 .enable = _clk_enable,
865 .enable_reg = CCM_PCCR_USBOTG_REG,
866 .enable_shift = CCM_PCCR_USBOTG_OFFSET,
867 .disable = _clk_disable,
868 .round_rate = _clk_usb_round_rate,
869 .set_rate = _clk_usb_set_rate,
870 }, {
871 .parent = &hclk_clk,
872 .enable = _clk_enable,
873 .enable_reg = CCM_PCCR_HCLK_USBOTG_REG,
874 .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET,
875 .disable = _clk_disable,
876 }
877};
878
879static struct clk ssi_ipg_clk[];
880
881static struct clk ssi_clk[] = {
882 {
883 .id = 0,
884 .parent = &mpll_clk,
885 .secondary = &ssi_ipg_clk[0],
886 .get_rate = _clk_ssi1_recalc,
887 .enable = _clk_enable,
888 .enable_reg = CCM_PCCR_SSI1_BAUD_REG,
889 .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET,
890 .disable = _clk_disable,
891 }, {
892 .id = 1,
893 .parent = &mpll_clk,
894 .secondary = &ssi_ipg_clk[1],
895 .get_rate = _clk_ssi2_recalc,
896 .enable = _clk_enable,
897 .enable_reg = CCM_PCCR_SSI2_BAUD_REG,
898 .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET,
899 .disable = _clk_disable,
900 },
901};
902
903static struct clk ssi_ipg_clk[] = {
904 {
905 .id = 0,
906 .parent = &ipg_clk,
907 .enable = _clk_enable,
908 .enable_reg = CCM_PCCR_SSI1_REG,
909 .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET,
910 .disable = _clk_disable,
911 }, {
912 .id = 1,
913 .parent = &ipg_clk,
914 .enable = _clk_enable,
915 .enable_reg = CCM_PCCR_SSI2_REG,
916 .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET,
917 .disable = _clk_disable,
918 },
919};
920
921
922static struct clk nfc_clk = {
923 .parent = &fclk_clk,
924 .get_rate = _clk_nfc_recalc,
925 .enable = _clk_enable,
926 .enable_reg = CCM_PCCR_NFC_REG,
927 .enable_shift = CCM_PCCR_NFC_OFFSET,
928 .disable = _clk_disable,
929};
930
931static struct clk dma_clk[] = {
932 {
933 .parent = &hclk_clk,
934 .enable = _clk_enable,
935 .enable_reg = CCM_PCCR_DMA_REG,
936 .enable_shift = CCM_PCCR_DMA_OFFSET,
937 .disable = _clk_disable,
938 .secondary = &dma_clk[1],
939 }, {
940 .enable = _clk_enable,
941 .enable_reg = CCM_PCCR_HCLK_DMA_REG,
942 .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET,
943 .disable = _clk_disable,
944 },
945};
946
947static struct clk brom_clk = {
948 .parent = &hclk_clk,
949 .enable = _clk_enable,
950 .enable_reg = CCM_PCCR_HCLK_BROM_REG,
951 .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET,
952 .disable = _clk_disable,
953};
954
955static struct clk emma_clk[] = {
956 {
957 .parent = &hclk_clk,
958 .enable = _clk_enable,
959 .enable_reg = CCM_PCCR_EMMA_REG,
960 .enable_shift = CCM_PCCR_EMMA_OFFSET,
961 .disable = _clk_disable,
962 .secondary = &emma_clk[1],
963 }, {
964 .enable = _clk_enable,
965 .enable_reg = CCM_PCCR_HCLK_EMMA_REG,
966 .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET,
967 .disable = _clk_disable,
968 }
969};
970
971static struct clk slcdc_clk[] = {
972 {
973 .parent = &hclk_clk,
974 .enable = _clk_enable,
975 .enable_reg = CCM_PCCR_SLCDC_REG,
976 .enable_shift = CCM_PCCR_SLCDC_OFFSET,
977 .disable = _clk_disable,
978 .secondary = &slcdc_clk[1],
979 }, {
980 .enable = _clk_enable,
981 .enable_reg = CCM_PCCR_HCLK_SLCDC_REG,
982 .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET,
983 .disable = _clk_disable,
984 }
985};
986
987static struct clk wdog_clk = {
988 .parent = &ipg_clk,
989 .enable = _clk_enable,
990 .enable_reg = CCM_PCCR_WDT_REG,
991 .enable_shift = CCM_PCCR_WDT_OFFSET,
992 .disable = _clk_disable,
993};
994
995static struct clk gpio_clk = {
996 .parent = &ipg_clk,
997 .enable = _clk_enable,
998 .enable_reg = CCM_PCCR_GPIO_REG,
999 .enable_shift = CCM_PCCR_GPIO_OFFSET,
1000 .disable = _clk_disable,
1001};
1002
1003static struct clk i2c_clk = {
1004 .id = 0,
1005 .parent = &ipg_clk,
1006 .enable = _clk_enable,
1007 .enable_reg = CCM_PCCR_I2C1_REG,
1008 .enable_shift = CCM_PCCR_I2C1_OFFSET,
1009 .disable = _clk_disable,
1010};
1011
1012static struct clk kpp_clk = {
1013 .parent = &ipg_clk,
1014 .enable = _clk_enable,
1015 .enable_reg = CCM_PCCR_KPP_REG,
1016 .enable_shift = CCM_PCCR_KPP_OFFSET,
1017 .disable = _clk_disable,
1018};
1019
1020static struct clk owire_clk = {
1021 .parent = &ipg_clk,
1022 .enable = _clk_enable,
1023 .enable_reg = CCM_PCCR_OWIRE_REG,
1024 .enable_shift = CCM_PCCR_OWIRE_OFFSET,
1025 .disable = _clk_disable,
1026};
1027
1028static struct clk rtc_clk = {
1029 .parent = &ipg_clk,
1030 .enable = _clk_enable,
1031 .enable_reg = CCM_PCCR_RTC_REG,
1032 .enable_shift = CCM_PCCR_RTC_OFFSET,
1033 .disable = _clk_disable,
1034};
1035
1036static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
1037{
1038 return _clk_generic_round_rate(clk, rate, 8);
1039}
1040
1041static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1042{
1043 u32 reg;
1044 u32 div;
1045 unsigned long parent_rate;
1046
1047 parent_rate = clk_get_rate(clk->parent);
1048
1049 div = parent_rate / rate;
1050
1051 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1052 return -EINVAL;
1053 div--;
1054
1055 reg = __raw_readl(CCM_PCDR0);
1056
1057 if (clk->parent == &usb_clk[0]) {
1058 reg &= ~CCM_PCDR0_48MDIV_MASK;
1059 reg |= div << CCM_PCDR0_48MDIV_OFFSET;
1060 }
1061 __raw_writel(reg, CCM_PCDR0);
1062
1063 return 0;
1064}
1065
1066static unsigned long _clk_clko_recalc(struct clk *clk)
1067{
1068 u32 div = 0;
1069 unsigned long parent_rate;
1070
1071 parent_rate = clk_get_rate(clk->parent);
1072
1073 if (clk->parent == &usb_clk[0]) /* 48M */
1074 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK
1075 >> CCM_PCDR0_48MDIV_OFFSET;
1076 div++;
1077
1078 return parent_rate / div;
1079}
1080
1081static struct clk clko_clk;
1082
1083static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1084{
1085 u32 reg;
1086
1087 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1088
1089 if (parent == &ckil_clk)
1090 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1091 else if (parent == &fpm_clk)
1092 reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET;
1093 else if (parent == &ckih_clk)
1094 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1095 else if (parent == mpll_clk.parent)
1096 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1097 else if (parent == spll_clk.parent)
1098 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1099 else if (parent == &mpll_clk)
1100 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1101 else if (parent == &spll_clk)
1102 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1103 else if (parent == &fclk_clk)
1104 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1105 else if (parent == &hclk_clk)
1106 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1107 else if (parent == &ipg_clk)
1108 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1109 else if (parent == &per_clk[0])
1110 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1111 else if (parent == &per_clk[1])
1112 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1113 else if (parent == &per_clk[2])
1114 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1115 else if (parent == &per_clk[3])
1116 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1117 else if (parent == &ssi_clk[0])
1118 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1119 else if (parent == &ssi_clk[1])
1120 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1121 else if (parent == &nfc_clk)
1122 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1123 else if (parent == &usb_clk[0])
1124 reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET;
1125 else if (parent == &clko_clk)
1126 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1127 else
1128 return -EINVAL;
1129
1130 __raw_writel(reg, CCM_CCSR);
1131
1132 return 0;
1133}
1134
1135static struct clk clko_clk = {
1136 .get_rate = _clk_clko_recalc,
1137 .set_rate = _clk_clko_set_rate,
1138 .round_rate = _clk_clko_round_rate,
1139 .set_parent = _clk_clko_set_parent,
1140};
1141
1142
1143#define _REGISTER_CLOCK(d, n, c) \
1144 { \
1145 .dev_id = d, \
1146 .con_id = n, \
1147 .clk = &c, \
1148 },
1149static struct clk_lookup lookups[] = {
1150/* It's unlikely that any driver wants one of them directly:
1151 _REGISTER_CLOCK(NULL, "ckih", ckih_clk)
1152 _REGISTER_CLOCK(NULL, "ckil", ckil_clk)
1153 _REGISTER_CLOCK(NULL, "fpm", fpm_clk)
1154 _REGISTER_CLOCK(NULL, "mpll", mpll_clk)
1155 _REGISTER_CLOCK(NULL, "spll", spll_clk)
1156 _REGISTER_CLOCK(NULL, "fclk", fclk_clk)
1157 _REGISTER_CLOCK(NULL, "hclk", hclk_clk)
1158 _REGISTER_CLOCK(NULL, "ipg", ipg_clk)
1159*/
1160 _REGISTER_CLOCK(NULL, "perclk1", per_clk[0])
1161 _REGISTER_CLOCK(NULL, "perclk2", per_clk[1])
1162 _REGISTER_CLOCK(NULL, "perclk3", per_clk[2])
1163 _REGISTER_CLOCK(NULL, "perclk4", per_clk[3])
1164 _REGISTER_CLOCK(NULL, "clko", clko_clk)
1165 _REGISTER_CLOCK("imx21-uart.0", NULL, uart_clk[0])
1166 _REGISTER_CLOCK("imx21-uart.1", NULL, uart_clk[1])
1167 _REGISTER_CLOCK("imx21-uart.2", NULL, uart_clk[2])
1168 _REGISTER_CLOCK("imx21-uart.3", NULL, uart_clk[3])
1169 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0])
1170 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1])
1171 _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2])
1172 _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0])
1173 _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0])
1174 _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1])
1175 _REGISTER_CLOCK("imx21-cspi.0", NULL, cspi_clk[0])
1176 _REGISTER_CLOCK("imx21-cspi.1", NULL, cspi_clk[1])
1177 _REGISTER_CLOCK("imx21-cspi.2", NULL, cspi_clk[2])
1178 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk[0])
1179 _REGISTER_CLOCK(NULL, "csi", csi_clk[0])
1180 _REGISTER_CLOCK("imx21-hcd.0", NULL, usb_clk[0])
1181 _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0])
1182 _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1])
1183 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1184 _REGISTER_CLOCK(NULL, "dma", dma_clk[0])
1185 _REGISTER_CLOCK(NULL, "brom", brom_clk)
1186 _REGISTER_CLOCK(NULL, "emma", emma_clk[0])
1187 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0])
1188 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
1189 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1190 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
1191 _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
1192 _REGISTER_CLOCK(NULL, "owire", owire_clk)
1193 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1194};
1195
1196/*
1197 * must be called very early to get information about the
1198 * available clock rate when the timer framework starts
1199 */
1200int __init mx21_clocks_init(unsigned long lref, unsigned long href)
1201{
1202 u32 cscr;
1203
1204 external_low_reference = lref;
1205 external_high_reference = href;
1206
1207 /* detect clock reference for both system PLL */
1208 cscr = CSCR();
1209 if (cscr & CCM_CSCR_MCU)
1210 mpll_clk.parent = &ckih_clk;
1211 else
1212 mpll_clk.parent = &fpm_clk;
1213
1214 if (cscr & CCM_CSCR_SP)
1215 spll_clk.parent = &ckih_clk;
1216 else
1217 spll_clk.parent = &fpm_clk;
1218
1219 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
1220
1221 /* Turn off all clock gates */
1222 __raw_writel(0, CCM_PCCR0);
1223 __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1);
1224
1225 /* This turns of the serial PLL as well */
1226 spll_clk.disable(&spll_clk);
1227
1228 /* This will propagate to all children and init all the clock rates. */
1229 clk_enable(&per_clk[0]);
1230 clk_enable(&gpio_clk);
1231
1232#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
1233 clk_enable(&uart_clk[0]);
1234#endif
1235
1236 mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
1237 MX21_INT_GPT1);
1238 return 0;
1239}
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
new file mode 100644
index 00000000000..e63e23504fe
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -0,0 +1,340 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29#include <mach/mx25.h>
30
31#define CRM_BASE MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
32
33#define CCM_MPCTL 0x00
34#define CCM_UPCTL 0x04
35#define CCM_CCTL 0x08
36#define CCM_CGCR0 0x0C
37#define CCM_CGCR1 0x10
38#define CCM_CGCR2 0x14
39#define CCM_PCDR0 0x18
40#define CCM_PCDR1 0x1C
41#define CCM_PCDR2 0x20
42#define CCM_PCDR3 0x24
43#define CCM_RCSR 0x28
44#define CCM_CRDR 0x2C
45#define CCM_DCVR0 0x30
46#define CCM_DCVR1 0x34
47#define CCM_DCVR2 0x38
48#define CCM_DCVR3 0x3c
49#define CCM_LTR0 0x40
50#define CCM_LTR1 0x44
51#define CCM_LTR2 0x48
52#define CCM_LTR3 0x4c
53
54static unsigned long get_rate_mpll(void)
55{
56 ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
57
58 return mxc_decode_pll(mpctl, 24000000);
59}
60
61static unsigned long get_rate_upll(void)
62{
63 ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
64
65 return mxc_decode_pll(mpctl, 24000000);
66}
67
68unsigned long get_rate_arm(struct clk *clk)
69{
70 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
71 unsigned long rate = get_rate_mpll();
72
73 if (cctl & (1 << 14))
74 rate = (rate * 3) >> 2;
75
76 return rate / ((cctl >> 30) + 1);
77}
78
79static unsigned long get_rate_ahb(struct clk *clk)
80{
81 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
82
83 return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
84}
85
86static unsigned long get_rate_ipg(struct clk *clk)
87{
88 return get_rate_ahb(NULL) >> 1;
89}
90
91static unsigned long get_rate_per(int per)
92{
93 unsigned long ofs = (per & 0x3) * 8;
94 unsigned long reg = per & ~0x3;
95 unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
96 unsigned long fref;
97
98 if (readl(CRM_BASE + 0x64) & (1 << per))
99 fref = get_rate_upll();
100 else
101 fref = get_rate_ahb(NULL);
102
103 return fref / (val + 1);
104}
105
106static unsigned long get_rate_uart(struct clk *clk)
107{
108 return get_rate_per(15);
109}
110
111static unsigned long get_rate_ssi2(struct clk *clk)
112{
113 return get_rate_per(14);
114}
115
116static unsigned long get_rate_ssi1(struct clk *clk)
117{
118 return get_rate_per(13);
119}
120
121static unsigned long get_rate_i2c(struct clk *clk)
122{
123 return get_rate_per(6);
124}
125
126static unsigned long get_rate_nfc(struct clk *clk)
127{
128 return get_rate_per(8);
129}
130
131static unsigned long get_rate_gpt(struct clk *clk)
132{
133 return get_rate_per(5);
134}
135
136static unsigned long get_rate_lcdc(struct clk *clk)
137{
138 return get_rate_per(7);
139}
140
141static unsigned long get_rate_esdhc1(struct clk *clk)
142{
143 return get_rate_per(3);
144}
145
146static unsigned long get_rate_esdhc2(struct clk *clk)
147{
148 return get_rate_per(4);
149}
150
151static unsigned long get_rate_csi(struct clk *clk)
152{
153 return get_rate_per(0);
154}
155
156static unsigned long get_rate_otg(struct clk *clk)
157{
158 unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
159 unsigned long rate = get_rate_upll();
160
161 return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
162}
163
164static int clk_cgcr_enable(struct clk *clk)
165{
166 u32 reg;
167
168 reg = __raw_readl(clk->enable_reg);
169 reg |= 1 << clk->enable_shift;
170 __raw_writel(reg, clk->enable_reg);
171
172 return 0;
173}
174
175static void clk_cgcr_disable(struct clk *clk)
176{
177 u32 reg;
178
179 reg = __raw_readl(clk->enable_reg);
180 reg &= ~(1 << clk->enable_shift);
181 __raw_writel(reg, clk->enable_reg);
182}
183
184#define DEFINE_CLOCK(name, i, er, es, gr, sr, s) \
185 static struct clk name = { \
186 .id = i, \
187 .enable_reg = CRM_BASE + er, \
188 .enable_shift = es, \
189 .get_rate = gr, \
190 .set_rate = sr, \
191 .enable = clk_cgcr_enable, \
192 .disable = clk_cgcr_disable, \
193 .secondary = s, \
194 }
195
196/*
197 * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
198 * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
199 * taken from the Freescale released BSP.
200 *
201 * bit reg offset clock
202 *
203 * 0 CGCR1 0 AUDMUX
204 * 12 CGCR1 12 ESAI
205 * 16 CGCR1 16 GPIO1
206 * 17 CGCR1 17 GPIO2
207 * 18 CGCR1 18 GPIO3
208 * 23 CGCR1 23 I2C1
209 * 24 CGCR1 24 I2C2
210 * 25 CGCR1 25 I2C3
211 * 27 CGCR1 27 IOMUXC
212 * 28 CGCR1 28 KPP
213 * 30 CGCR1 30 OWIRE
214 * 36 CGCR2 4 RTIC
215 * 51 CGCR2 19 WDOG
216 */
217
218DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
219DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
220DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
221DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
222DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
223DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
224DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
225DEFINE_CLOCK(esdhc1_ahb_clk, 0, CCM_CGCR0, 21, get_rate_esdhc1, NULL, NULL);
226DEFINE_CLOCK(esdhc1_per_clk, 0, CCM_CGCR0, 3, get_rate_esdhc1, NULL,
227 &esdhc1_ahb_clk);
228DEFINE_CLOCK(esdhc2_ahb_clk, 0, CCM_CGCR0, 22, get_rate_esdhc2, NULL, NULL);
229DEFINE_CLOCK(esdhc2_per_clk, 0, CCM_CGCR0, 4, get_rate_esdhc2, NULL,
230 &esdhc2_ahb_clk);
231DEFINE_CLOCK(sdma_ahb_clk, 0, CCM_CGCR0, 26, NULL, NULL, NULL);
232DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
233DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
234DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
235DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
236DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
237DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
238DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
239DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
240DEFINE_CLOCK(uart4_clk, 0, CCM_CGCR2, 17, get_rate_uart, NULL, &uart_per_clk);
241DEFINE_CLOCK(uart5_clk, 0, CCM_CGCR2, 18, get_rate_uart, NULL, &uart_per_clk);
242DEFINE_CLOCK(nfc_clk, 0, CCM_CGCR0, 8, get_rate_nfc, NULL, NULL);
243DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL, NULL);
244DEFINE_CLOCK(pwm1_clk, 0, CCM_CGCR1, 31, get_rate_ipg, NULL, NULL);
245DEFINE_CLOCK(pwm2_clk, 0, CCM_CGCR2, 0, get_rate_ipg, NULL, NULL);
246DEFINE_CLOCK(pwm3_clk, 0, CCM_CGCR2, 1, get_rate_ipg, NULL, NULL);
247DEFINE_CLOCK(pwm4_clk, 0, CCM_CGCR2, 2, get_rate_ipg, NULL, NULL);
248DEFINE_CLOCK(kpp_clk, 0, CCM_CGCR1, 28, get_rate_ipg, NULL, NULL);
249DEFINE_CLOCK(tsc_clk, 0, CCM_CGCR2, 13, get_rate_ipg, NULL, NULL);
250DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
251DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
252DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
253DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
254DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
255DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
256DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
257DEFINE_CLOCK(sdma_clk, 0, CCM_CGCR2, 6, get_rate_ipg, NULL, &sdma_ahb_clk);
258DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGCR1, 13, get_rate_esdhc1, NULL,
259 &esdhc1_per_clk);
260DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGCR1, 14, get_rate_esdhc2, NULL,
261 &esdhc2_per_clk);
262DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
263DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
264DEFINE_CLOCK(can1_clk, 0, CCM_CGCR1, 2, get_rate_ipg, NULL, NULL);
265DEFINE_CLOCK(can2_clk, 1, CCM_CGCR1, 3, get_rate_ipg, NULL, NULL);
266
267#define _REGISTER_CLOCK(d, n, c) \
268 { \
269 .dev_id = d, \
270 .con_id = n, \
271 .clk = &c, \
272 },
273
274static struct clk_lookup lookups[] = {
275 /* i.mx25 has the i.mx21 type uart */
276 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
277 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
278 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
279 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
280 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
281 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
282 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
283 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
284 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
285 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
286 /* i.mx25 has the i.mx35 type cspi */
287 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
288 _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
289 _REGISTER_CLOCK("imx35-cspi.2", NULL, cspi3_clk)
290 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
291 _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
292 _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
293 _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
294 _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
295 _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
296 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
297 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
298 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
299 _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
300 _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
301 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
302 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
303 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
304 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
305 _REGISTER_CLOCK("sdhci-esdhc-imx25.0", NULL, esdhc1_clk)
306 _REGISTER_CLOCK("sdhci-esdhc-imx25.1", NULL, esdhc2_clk)
307 _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
308 _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
309 _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
310 _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
311 /* i.mx25 has the i.mx35 type sdma */
312 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
313};
314
315int __init mx25_clocks_init(void)
316{
317 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
318
319 /* Turn off all clocks except the ones we need to survive, namely:
320 * EMI, GPIO1-3 (CCM_CGCR1[18:16]), GPT1, IOMUXC (CCM_CGCR1[27]), IIM,
321 * SCC
322 */
323 __raw_writel((1 << 19), CRM_BASE + CCM_CGCR0);
324 __raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
325 __raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
326#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
327 clk_enable(&uart1_clk);
328#endif
329
330 /* Clock source for lcdc and csi is upll */
331 __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
332 CRM_BASE + 0x64);
333
334 /* Clock source for gpt is ahb_div */
335 __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64);
336
337 mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
338
339 return 0;
340}
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
new file mode 100644
index 00000000000..6912b821b37
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -0,0 +1,764 @@
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#include <linux/clkdev.h>
25
26#include <asm/div64.h>
27
28#include <mach/clock.h>
29#include <mach/common.h>
30#include <mach/hardware.h>
31
32#define IO_ADDR_CCM(off) (MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR + (off)))
33
34/* Register offsets */
35#define CCM_CSCR IO_ADDR_CCM(0x0)
36#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
37#define CCM_MPCTL1 IO_ADDR_CCM(0x8)
38#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
39#define CCM_SPCTL1 IO_ADDR_CCM(0x10)
40#define CCM_OSC26MCTL IO_ADDR_CCM(0x14)
41#define CCM_PCDR0 IO_ADDR_CCM(0x18)
42#define CCM_PCDR1 IO_ADDR_CCM(0x1c)
43#define CCM_PCCR0 IO_ADDR_CCM(0x20)
44#define CCM_PCCR1 IO_ADDR_CCM(0x24)
45#define CCM_CCSR IO_ADDR_CCM(0x28)
46#define CCM_PMCTL IO_ADDR_CCM(0x2c)
47#define CCM_PMCOUNT IO_ADDR_CCM(0x30)
48#define CCM_WKGDCTL IO_ADDR_CCM(0x34)
49
50#define CCM_CSCR_UPDATE_DIS (1 << 31)
51#define CCM_CSCR_SSI2 (1 << 23)
52#define CCM_CSCR_SSI1 (1 << 22)
53#define CCM_CSCR_VPU (1 << 21)
54#define CCM_CSCR_MSHC (1 << 20)
55#define CCM_CSCR_SPLLRES (1 << 19)
56#define CCM_CSCR_MPLLRES (1 << 18)
57#define CCM_CSCR_SP (1 << 17)
58#define CCM_CSCR_MCU (1 << 16)
59#define CCM_CSCR_OSC26MDIV (1 << 4)
60#define CCM_CSCR_OSC26M (1 << 3)
61#define CCM_CSCR_FPM (1 << 2)
62#define CCM_CSCR_SPEN (1 << 1)
63#define CCM_CSCR_MPEN (1 << 0)
64
65/* i.MX27 TO 2+ */
66#define CCM_CSCR_ARM_SRC (1 << 15)
67
68#define CCM_SPCTL1_LF (1 << 15)
69#define CCM_SPCTL1_BRMO (1 << 6)
70
71static struct clk mpll_main1_clk, mpll_main2_clk;
72
73static int clk_pccr_enable(struct clk *clk)
74{
75 unsigned long reg;
76
77 if (!clk->enable_reg)
78 return 0;
79
80 reg = __raw_readl(clk->enable_reg);
81 reg |= 1 << clk->enable_shift;
82 __raw_writel(reg, clk->enable_reg);
83
84 return 0;
85}
86
87static void clk_pccr_disable(struct clk *clk)
88{
89 unsigned long reg;
90
91 if (!clk->enable_reg)
92 return;
93
94 reg = __raw_readl(clk->enable_reg);
95 reg &= ~(1 << clk->enable_shift);
96 __raw_writel(reg, clk->enable_reg);
97}
98
99static int clk_spll_enable(struct clk *clk)
100{
101 unsigned long reg;
102
103 reg = __raw_readl(CCM_CSCR);
104 reg |= CCM_CSCR_SPEN;
105 __raw_writel(reg, CCM_CSCR);
106
107 while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
108
109 return 0;
110}
111
112static void clk_spll_disable(struct clk *clk)
113{
114 unsigned long reg;
115
116 reg = __raw_readl(CCM_CSCR);
117 reg &= ~CCM_CSCR_SPEN;
118 __raw_writel(reg, CCM_CSCR);
119}
120
121static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
122{
123 int cscr = __raw_readl(CCM_CSCR);
124
125 if (clk->parent == parent)
126 return 0;
127
128 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
129 if (parent == &mpll_main1_clk) {
130 cscr |= CCM_CSCR_ARM_SRC;
131 } else {
132 if (parent == &mpll_main2_clk)
133 cscr &= ~CCM_CSCR_ARM_SRC;
134 else
135 return -EINVAL;
136 }
137 __raw_writel(cscr, CCM_CSCR);
138 clk->parent = parent;
139 return 0;
140 }
141 return -ENODEV;
142}
143
144static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
145{
146 int div;
147 unsigned long parent_rate;
148
149 parent_rate = clk_get_rate(clk->parent);
150
151 div = parent_rate / rate;
152 if (parent_rate % rate)
153 div++;
154
155 if (div > 4)
156 div = 4;
157
158 return parent_rate / div;
159}
160
161static int set_rate_cpu(struct clk *clk, unsigned long rate)
162{
163 unsigned int div;
164 uint32_t reg;
165 unsigned long parent_rate;
166
167 parent_rate = clk_get_rate(clk->parent);
168
169 div = parent_rate / rate;
170
171 if (div > 4 || div < 1 || ((parent_rate / div) != rate))
172 return -EINVAL;
173
174 div--;
175
176 reg = __raw_readl(CCM_CSCR);
177 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
178 reg &= ~(3 << 12);
179 reg |= div << 12;
180 reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
181 __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
182 } else {
183 printk(KERN_ERR "Can't set CPU frequency!\n");
184 }
185
186 return 0;
187}
188
189static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
190{
191 u32 div;
192 unsigned long parent_rate;
193
194 parent_rate = clk_get_rate(clk->parent);
195
196 div = parent_rate / rate;
197 if (parent_rate % rate)
198 div++;
199
200 if (div > 64)
201 div = 64;
202
203 return parent_rate / div;
204}
205
206static int set_rate_per(struct clk *clk, unsigned long rate)
207{
208 u32 reg;
209 u32 div;
210 unsigned long parent_rate;
211
212 parent_rate = clk_get_rate(clk->parent);
213
214 if (clk->id < 0 || clk->id > 3)
215 return -EINVAL;
216
217 div = parent_rate / rate;
218 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
219 return -EINVAL;
220 div--;
221
222 reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
223 reg |= div << (clk->id << 3);
224 __raw_writel(reg, CCM_PCDR1);
225
226 return 0;
227}
228
229static unsigned long get_rate_usb(struct clk *clk)
230{
231 unsigned long usb_pdf;
232 unsigned long parent_rate;
233
234 parent_rate = clk_get_rate(clk->parent);
235
236 usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
237
238 return parent_rate / (usb_pdf + 1U);
239}
240
241static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
242{
243 unsigned long parent_rate;
244
245 parent_rate = clk_get_rate(clk->parent);
246
247 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
248 pdf += 4; /* MX27 TO2+ */
249 else
250 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
251
252 return 2UL * parent_rate / pdf;
253}
254
255static unsigned long get_rate_ssi1(struct clk *clk)
256{
257 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
258}
259
260static unsigned long get_rate_ssi2(struct clk *clk)
261{
262 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
263}
264
265static unsigned long get_rate_nfc(struct clk *clk)
266{
267 unsigned long nfc_pdf;
268 unsigned long parent_rate;
269
270 parent_rate = clk_get_rate(clk->parent);
271
272 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
273 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
274 else
275 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
276
277 return parent_rate / (nfc_pdf + 1);
278}
279
280static unsigned long get_rate_vpu(struct clk *clk)
281{
282 unsigned long vpu_pdf;
283 unsigned long parent_rate;
284
285 parent_rate = clk_get_rate(clk->parent);
286
287 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
288 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
289 vpu_pdf += 4;
290 } else {
291 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
292 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
293 }
294
295 return 2UL * parent_rate / vpu_pdf;
296}
297
298static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
299{
300 return clk->parent->round_rate(clk->parent, rate);
301}
302
303static unsigned long get_rate_parent(struct clk *clk)
304{
305 return clk_get_rate(clk->parent);
306}
307
308static int set_rate_parent(struct clk *clk, unsigned long rate)
309{
310 return clk->parent->set_rate(clk->parent, rate);
311}
312
313/* in Hz */
314static unsigned long external_high_reference = 26000000;
315
316static unsigned long get_rate_high_reference(struct clk *clk)
317{
318 return external_high_reference;
319}
320
321/* in Hz */
322static unsigned long external_low_reference = 32768;
323
324static unsigned long get_rate_low_reference(struct clk *clk)
325{
326 return external_low_reference;
327}
328
329static unsigned long get_rate_fpm(struct clk *clk)
330{
331 return clk_get_rate(clk->parent) * 1024;
332}
333
334static unsigned long get_rate_mpll(struct clk *clk)
335{
336 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
337 clk_get_rate(clk->parent));
338}
339
340static unsigned long get_rate_mpll_main(struct clk *clk)
341{
342 unsigned long parent_rate;
343
344 parent_rate = clk_get_rate(clk->parent);
345
346 /* i.MX27 TO2:
347 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
348 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
349 */
350 if (mx27_revision() >= IMX_CHIP_REVISION_2_0 && clk->id == 1)
351 return 2UL * parent_rate / 3UL;
352
353 return parent_rate;
354}
355
356static unsigned long get_rate_spll(struct clk *clk)
357{
358 uint32_t reg;
359 unsigned long rate;
360
361 rate = clk_get_rate(clk->parent);
362
363 reg = __raw_readl(CCM_SPCTL0);
364
365 /* On TO2 we have to write the value back. Otherwise we
366 * read 0 from this register the next time.
367 */
368 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
369 __raw_writel(reg, CCM_SPCTL0);
370
371 return mxc_decode_pll(reg, rate);
372}
373
374static unsigned long get_rate_cpu(struct clk *clk)
375{
376 u32 div;
377 unsigned long rate;
378
379 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
380 div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
381 else
382 div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
383
384 rate = clk_get_rate(clk->parent);
385 return rate / (div + 1);
386}
387
388static unsigned long get_rate_ahb(struct clk *clk)
389{
390 unsigned long rate, bclk_pdf;
391
392 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
393 bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
394 else
395 bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
396
397 rate = clk_get_rate(clk->parent);
398 return rate / (bclk_pdf + 1);
399}
400
401static unsigned long get_rate_ipg(struct clk *clk)
402{
403 unsigned long rate, ipg_pdf;
404
405 if (mx27_revision() >= IMX_CHIP_REVISION_2_0)
406 return clk_get_rate(clk->parent);
407 else
408 ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
409
410 rate = clk_get_rate(clk->parent);
411 return rate / (ipg_pdf + 1);
412}
413
414static unsigned long get_rate_per(struct clk *clk)
415{
416 unsigned long perclk_pdf, parent_rate;
417
418 parent_rate = clk_get_rate(clk->parent);
419
420 if (clk->id < 0 || clk->id > 3)
421 return 0;
422
423 perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
424
425 return parent_rate / (perclk_pdf + 1);
426}
427
428/*
429 * the high frequency external clock reference
430 * Default case is 26MHz. Could be changed at runtime
431 * with a call to change_external_high_reference()
432 */
433static struct clk ckih_clk = {
434 .get_rate = get_rate_high_reference,
435};
436
437static struct clk mpll_clk = {
438 .parent = &ckih_clk,
439 .get_rate = get_rate_mpll,
440};
441
442/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
443 * It provides the clock source whose rate is same as MPLL
444 */
445static struct clk mpll_main1_clk = {
446 .id = 0,
447 .parent = &mpll_clk,
448 .get_rate = get_rate_mpll_main,
449};
450
451/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
452 * It provides the clock source whose rate is same MPLL * 2 / 3
453 */
454static struct clk mpll_main2_clk = {
455 .id = 1,
456 .parent = &mpll_clk,
457 .get_rate = get_rate_mpll_main,
458};
459
460static struct clk ahb_clk = {
461 .parent = &mpll_main2_clk,
462 .get_rate = get_rate_ahb,
463};
464
465static struct clk ipg_clk = {
466 .parent = &ahb_clk,
467 .get_rate = get_rate_ipg,
468};
469
470static struct clk cpu_clk = {
471 .parent = &mpll_main2_clk,
472 .set_parent = clk_cpu_set_parent,
473 .round_rate = round_rate_cpu,
474 .get_rate = get_rate_cpu,
475 .set_rate = set_rate_cpu,
476};
477
478static struct clk spll_clk = {
479 .parent = &ckih_clk,
480 .get_rate = get_rate_spll,
481 .enable = clk_spll_enable,
482 .disable = clk_spll_disable,
483};
484
485/*
486 * the low frequency external clock reference
487 * Default case is 32.768kHz.
488 */
489static struct clk ckil_clk = {
490 .get_rate = get_rate_low_reference,
491};
492
493/* Output of frequency pre multiplier */
494static struct clk fpm_clk = {
495 .parent = &ckil_clk,
496 .get_rate = get_rate_fpm,
497};
498
499#define PCCR0 CCM_PCCR0
500#define PCCR1 CCM_PCCR1
501
502#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
503 static struct clk name = { \
504 .id = i, \
505 .enable_reg = er, \
506 .enable_shift = es, \
507 .get_rate = gr, \
508 .enable = clk_pccr_enable, \
509 .disable = clk_pccr_disable, \
510 .secondary = s, \
511 .parent = p, \
512 }
513
514#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
515 static struct clk name = { \
516 .id = i, \
517 .enable_reg = er, \
518 .enable_shift = es, \
519 .get_rate = get_rate_##getsetround, \
520 .set_rate = set_rate_##getsetround, \
521 .round_rate = round_rate_##getsetround, \
522 .enable = clk_pccr_enable, \
523 .disable = clk_pccr_disable, \
524 .secondary = s, \
525 .parent = p, \
526 }
527
528/* Forward declaration to keep the following list in order */
529static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
530 dma_clk1, lcdc_clk2, vpu_clk1;
531
532/* All clocks we can gate through PCCRx in the order of PCCRx bits */
533DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
534DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
535DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
536DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
537DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
538DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
539DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
540DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
541DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
542DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
543DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
544DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
545DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
546DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
547DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
548DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
549DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
550DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
551DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
552DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
553DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
554DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
555DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
556DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
557DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
558DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
559DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
560DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
561DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
562DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
563DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
564
565DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
566DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
567DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
568DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
569DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
570DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
571DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
572DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
573DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
574DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
575DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
576DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
577DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
578DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
579DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
580DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
581DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
582DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
583DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
584DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
585DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
586DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
587DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
588DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
589DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
590DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
591DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
592DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
593DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
594DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
595
596/* Clocks we cannot directly gate, but drivers need their rates */
597DEFINE_CLOCK(cspi1_clk, 0, NULL, 0, NULL, &cspi1_clk1, &per2_clk);
598DEFINE_CLOCK(cspi2_clk, 1, NULL, 0, NULL, &cspi2_clk1, &per2_clk);
599DEFINE_CLOCK(cspi3_clk, 2, NULL, 0, NULL, &cspi13_clk1, &per2_clk);
600DEFINE_CLOCK(sdhc1_clk, 0, NULL, 0, NULL, &sdhc1_clk1, &per2_clk);
601DEFINE_CLOCK(sdhc2_clk, 1, NULL, 0, NULL, &sdhc2_clk1, &per2_clk);
602DEFINE_CLOCK(sdhc3_clk, 2, NULL, 0, NULL, &sdhc3_clk1, &per2_clk);
603DEFINE_CLOCK(pwm_clk, 0, NULL, 0, NULL, &pwm_clk1, &per1_clk);
604DEFINE_CLOCK(gpt1_clk, 0, NULL, 0, NULL, &gpt1_clk1, &per1_clk);
605DEFINE_CLOCK(gpt2_clk, 1, NULL, 0, NULL, &gpt2_clk1, &per1_clk);
606DEFINE_CLOCK(gpt3_clk, 2, NULL, 0, NULL, &gpt3_clk1, &per1_clk);
607DEFINE_CLOCK(gpt4_clk, 3, NULL, 0, NULL, &gpt4_clk1, &per1_clk);
608DEFINE_CLOCK(gpt5_clk, 4, NULL, 0, NULL, &gpt5_clk1, &per1_clk);
609DEFINE_CLOCK(gpt6_clk, 5, NULL, 0, NULL, &gpt6_clk1, &per1_clk);
610DEFINE_CLOCK(uart1_clk, 0, NULL, 0, NULL, &uart1_clk1, &per1_clk);
611DEFINE_CLOCK(uart2_clk, 1, NULL, 0, NULL, &uart2_clk1, &per1_clk);
612DEFINE_CLOCK(uart3_clk, 2, NULL, 0, NULL, &uart3_clk1, &per1_clk);
613DEFINE_CLOCK(uart4_clk, 3, NULL, 0, NULL, &uart4_clk1, &per1_clk);
614DEFINE_CLOCK(uart5_clk, 4, NULL, 0, NULL, &uart5_clk1, &per1_clk);
615DEFINE_CLOCK(uart6_clk, 5, NULL, 0, NULL, &uart6_clk1, &per1_clk);
616DEFINE_CLOCK1(lcdc_clk, 0, NULL, 0, parent, &lcdc_clk1, &per3_clk);
617DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);
618
619#define _REGISTER_CLOCK(d, n, c) \
620 { \
621 .dev_id = d, \
622 .con_id = n, \
623 .clk = &c, \
624 },
625
626static struct clk_lookup lookups[] = {
627 /* i.mx27 has the i.mx21 type uart */
628 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
629 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
630 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
631 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
632 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
633 _REGISTER_CLOCK("imx21-uart.5", NULL, uart6_clk)
634 _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
635 _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
636 _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
637 _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
638 _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
639 _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
640 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
641 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
642 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
643 _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
644 _REGISTER_CLOCK("imx27-cspi.0", NULL, cspi1_clk)
645 _REGISTER_CLOCK("imx27-cspi.1", NULL, cspi2_clk)
646 _REGISTER_CLOCK("imx27-cspi.2", NULL, cspi3_clk)
647 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
648 _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
649 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
650 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
651 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
652 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk1)
653 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk)
654 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk1)
655 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk)
656 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk1)
657 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
658 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
659 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
660 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
661 _REGISTER_CLOCK(NULL, "dma", dma_clk)
662 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
663 _REGISTER_CLOCK(NULL, "brom", brom_clk)
664 _REGISTER_CLOCK(NULL, "emma", emma_clk)
665 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
666 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
667 _REGISTER_CLOCK(NULL, "emi", emi_clk)
668 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
669 _REGISTER_CLOCK(NULL, "ata", ata_clk)
670 _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
671 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
672 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
673 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
674 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
675 _REGISTER_CLOCK(NULL, "iim", iim_clk)
676 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
677 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
678 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
679 _REGISTER_CLOCK(NULL, "scc", scc_clk)
680};
681
682/* Adjust the clock path for TO2 and later */
683static void __init to2_adjust_clocks(void)
684{
685 unsigned long cscr = __raw_readl(CCM_CSCR);
686
687 if (mx27_revision() >= IMX_CHIP_REVISION_2_0) {
688 if (cscr & CCM_CSCR_ARM_SRC)
689 cpu_clk.parent = &mpll_main1_clk;
690
691 if (!(cscr & CCM_CSCR_SSI2))
692 ssi1_clk.parent = &spll_clk;
693
694 if (!(cscr & CCM_CSCR_SSI1))
695 ssi1_clk.parent = &spll_clk;
696
697 if (!(cscr & CCM_CSCR_VPU))
698 vpu_clk.parent = &spll_clk;
699 } else {
700 cpu_clk.parent = &mpll_clk;
701 cpu_clk.set_parent = NULL;
702 cpu_clk.round_rate = NULL;
703 cpu_clk.set_rate = NULL;
704 ahb_clk.parent = &mpll_clk;
705
706 per1_clk.parent = &mpll_clk;
707 per2_clk.parent = &mpll_clk;
708 per3_clk.parent = &mpll_clk;
709 per4_clk.parent = &mpll_clk;
710
711 ssi1_clk.parent = &mpll_clk;
712 ssi2_clk.parent = &mpll_clk;
713
714 vpu_clk.parent = &mpll_clk;
715 }
716}
717
718/*
719 * must be called very early to get information about the
720 * available clock rate when the timer framework starts
721 */
722int __init mx27_clocks_init(unsigned long fref)
723{
724 u32 cscr = __raw_readl(CCM_CSCR);
725
726 external_high_reference = fref;
727
728 /* detect clock reference for both system PLLs */
729 if (cscr & CCM_CSCR_MCU)
730 mpll_clk.parent = &ckih_clk;
731 else
732 mpll_clk.parent = &fpm_clk;
733
734 if (cscr & CCM_CSCR_SP)
735 spll_clk.parent = &ckih_clk;
736 else
737 spll_clk.parent = &fpm_clk;
738
739 to2_adjust_clocks();
740
741 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
742
743 /* Turn off all clocks we do not need */
744 __raw_writel(0, CCM_PCCR0);
745 __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
746
747 spll_clk.disable(&spll_clk);
748
749 /* enable basic clocks */
750 clk_enable(&per1_clk);
751 clk_enable(&gpio_clk);
752 clk_enable(&emi_clk);
753 clk_enable(&iim_clk);
754
755#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
756 clk_enable(&uart1_clk);
757#endif
758
759 mxc_timer_init(&gpt1_clk, MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR),
760 MX27_INT_GPT1);
761
762 return 0;
763}
764
diff --git a/arch/arm/mach-imx/clock-imx31.c b/arch/arm/mach-imx/clock-imx31.c
new file mode 100644
index 00000000000..d973770b1f9
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx31.c
@@ -0,0 +1,630 @@
1/*
2 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/spinlock.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/io.h>
26#include <linux/clkdev.h>
27
28#include <asm/div64.h>
29
30#include <mach/clock.h>
31#include <mach/hardware.h>
32#include <mach/mx31.h>
33#include <mach/common.h>
34
35#include "crmregs-imx31.h"
36
37#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
38
39static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
40{
41 u32 min_pre, temp_pre, old_err, err;
42
43 if (div >= 512) {
44 *pre = 8;
45 *post = 64;
46 } else if (div >= 64) {
47 min_pre = (div - 1) / 64 + 1;
48 old_err = 8;
49 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
50 err = div % temp_pre;
51 if (err == 0) {
52 *pre = temp_pre;
53 break;
54 }
55 err = temp_pre - err;
56 if (err < old_err) {
57 old_err = err;
58 *pre = temp_pre;
59 }
60 }
61 *post = (div + *pre - 1) / *pre;
62 } else if (div <= 8) {
63 *pre = div;
64 *post = 1;
65 } else {
66 *pre = 1;
67 *post = div;
68 }
69}
70
71static struct clk mcu_pll_clk;
72static struct clk serial_pll_clk;
73static struct clk ipg_clk;
74static struct clk ckih_clk;
75
76static int cgr_enable(struct clk *clk)
77{
78 u32 reg;
79
80 if (!clk->enable_reg)
81 return 0;
82
83 reg = __raw_readl(clk->enable_reg);
84 reg |= 3 << clk->enable_shift;
85 __raw_writel(reg, clk->enable_reg);
86
87 return 0;
88}
89
90static void cgr_disable(struct clk *clk)
91{
92 u32 reg;
93
94 if (!clk->enable_reg)
95 return;
96
97 reg = __raw_readl(clk->enable_reg);
98 reg &= ~(3 << clk->enable_shift);
99
100 /* special case for EMI clock */
101 if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8)
102 reg |= (1 << clk->enable_shift);
103
104 __raw_writel(reg, clk->enable_reg);
105}
106
107static unsigned long pll_ref_get_rate(void)
108{
109 unsigned long ccmr;
110 unsigned int prcs;
111
112 ccmr = __raw_readl(MXC_CCM_CCMR);
113 prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET;
114 if (prcs == 0x1)
115 return CKIL_CLK_FREQ * 1024;
116 else
117 return clk_get_rate(&ckih_clk);
118}
119
120static unsigned long usb_pll_get_rate(struct clk *clk)
121{
122 unsigned long reg;
123
124 reg = __raw_readl(MXC_CCM_UPCTL);
125
126 return mxc_decode_pll(reg, pll_ref_get_rate());
127}
128
129static unsigned long serial_pll_get_rate(struct clk *clk)
130{
131 unsigned long reg;
132
133 reg = __raw_readl(MXC_CCM_SRPCTL);
134
135 return mxc_decode_pll(reg, pll_ref_get_rate());
136}
137
138static unsigned long mcu_pll_get_rate(struct clk *clk)
139{
140 unsigned long reg, ccmr;
141
142 ccmr = __raw_readl(MXC_CCM_CCMR);
143
144 if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS))
145 return clk_get_rate(&ckih_clk);
146
147 reg = __raw_readl(MXC_CCM_MPCTL);
148
149 return mxc_decode_pll(reg, pll_ref_get_rate());
150}
151
152static int usb_pll_enable(struct clk *clk)
153{
154 u32 reg;
155
156 reg = __raw_readl(MXC_CCM_CCMR);
157 reg |= MXC_CCM_CCMR_UPE;
158 __raw_writel(reg, MXC_CCM_CCMR);
159
160 /* No lock bit on MX31, so using max time from spec */
161 udelay(80);
162
163 return 0;
164}
165
166static void usb_pll_disable(struct clk *clk)
167{
168 u32 reg;
169
170 reg = __raw_readl(MXC_CCM_CCMR);
171 reg &= ~MXC_CCM_CCMR_UPE;
172 __raw_writel(reg, MXC_CCM_CCMR);
173}
174
175static int serial_pll_enable(struct clk *clk)
176{
177 u32 reg;
178
179 reg = __raw_readl(MXC_CCM_CCMR);
180 reg |= MXC_CCM_CCMR_SPE;
181 __raw_writel(reg, MXC_CCM_CCMR);
182
183 /* No lock bit on MX31, so using max time from spec */
184 udelay(80);
185
186 return 0;
187}
188
189static void serial_pll_disable(struct clk *clk)
190{
191 u32 reg;
192
193 reg = __raw_readl(MXC_CCM_CCMR);
194 reg &= ~MXC_CCM_CCMR_SPE;
195 __raw_writel(reg, MXC_CCM_CCMR);
196}
197
198#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
199#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
200#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
201
202static unsigned long mcu_main_get_rate(struct clk *clk)
203{
204 u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
205
206 if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
207 return clk_get_rate(&serial_pll_clk);
208 else
209 return clk_get_rate(&mcu_pll_clk);
210}
211
212static unsigned long ahb_get_rate(struct clk *clk)
213{
214 unsigned long max_pdf;
215
216 max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
217 MXC_CCM_PDR0_MAX_PODF_OFFSET);
218 return clk_get_rate(clk->parent) / (max_pdf + 1);
219}
220
221static unsigned long ipg_get_rate(struct clk *clk)
222{
223 unsigned long ipg_pdf;
224
225 ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
226 MXC_CCM_PDR0_IPG_PODF_OFFSET);
227 return clk_get_rate(clk->parent) / (ipg_pdf + 1);
228}
229
230static unsigned long nfc_get_rate(struct clk *clk)
231{
232 unsigned long nfc_pdf;
233
234 nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
235 MXC_CCM_PDR0_NFC_PODF_OFFSET);
236 return clk_get_rate(clk->parent) / (nfc_pdf + 1);
237}
238
239static unsigned long hsp_get_rate(struct clk *clk)
240{
241 unsigned long hsp_pdf;
242
243 hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
244 MXC_CCM_PDR0_HSP_PODF_OFFSET);
245 return clk_get_rate(clk->parent) / (hsp_pdf + 1);
246}
247
248static unsigned long usb_get_rate(struct clk *clk)
249{
250 unsigned long usb_pdf, usb_prepdf;
251
252 usb_pdf = PDR1(MXC_CCM_PDR1_USB_PODF_MASK,
253 MXC_CCM_PDR1_USB_PODF_OFFSET);
254 usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
255 MXC_CCM_PDR1_USB_PRDF_OFFSET);
256 return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
257}
258
259static unsigned long csi_get_rate(struct clk *clk)
260{
261 u32 reg, pre, post;
262
263 reg = __raw_readl(MXC_CCM_PDR0);
264 pre = (reg & MXC_CCM_PDR0_CSI_PRDF_MASK) >>
265 MXC_CCM_PDR0_CSI_PRDF_OFFSET;
266 pre++;
267 post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
268 MXC_CCM_PDR0_CSI_PODF_OFFSET;
269 post++;
270 return clk_get_rate(clk->parent) / (pre * post);
271}
272
273static unsigned long csi_round_rate(struct clk *clk, unsigned long rate)
274{
275 u32 pre, post, parent = clk_get_rate(clk->parent);
276 u32 div = parent / rate;
277
278 if (parent % rate)
279 div++;
280
281 __calc_pre_post_dividers(div, &pre, &post);
282
283 return parent / (pre * post);
284}
285
286static int csi_set_rate(struct clk *clk, unsigned long rate)
287{
288 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
289
290 div = parent / rate;
291
292 if ((parent / div) != rate)
293 return -EINVAL;
294
295 __calc_pre_post_dividers(div, &pre, &post);
296
297 /* Set CSI clock divider */
298 reg = __raw_readl(MXC_CCM_PDR0) &
299 ~(MXC_CCM_PDR0_CSI_PODF_MASK | MXC_CCM_PDR0_CSI_PRDF_MASK);
300 reg |= (post - 1) << MXC_CCM_PDR0_CSI_PODF_OFFSET;
301 reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
302 __raw_writel(reg, MXC_CCM_PDR0);
303
304 return 0;
305}
306
307static unsigned long ssi1_get_rate(struct clk *clk)
308{
309 unsigned long ssi1_pdf, ssi1_prepdf;
310
311 ssi1_pdf = PDR1(MXC_CCM_PDR1_SSI1_PODF_MASK,
312 MXC_CCM_PDR1_SSI1_PODF_OFFSET);
313 ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
314 MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
315 return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
316}
317
318static unsigned long ssi2_get_rate(struct clk *clk)
319{
320 unsigned long ssi2_pdf, ssi2_prepdf;
321
322 ssi2_pdf = PDR1(MXC_CCM_PDR1_SSI2_PODF_MASK,
323 MXC_CCM_PDR1_SSI2_PODF_OFFSET);
324 ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
325 MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
326 return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
327}
328
329static unsigned long firi_get_rate(struct clk *clk)
330{
331 unsigned long firi_pdf, firi_prepdf;
332
333 firi_pdf = PDR1(MXC_CCM_PDR1_FIRI_PODF_MASK,
334 MXC_CCM_PDR1_FIRI_PODF_OFFSET);
335 firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
336 MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
337 return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
338}
339
340static unsigned long firi_round_rate(struct clk *clk, unsigned long rate)
341{
342 u32 pre, post;
343 u32 parent = clk_get_rate(clk->parent);
344 u32 div = parent / rate;
345
346 if (parent % rate)
347 div++;
348
349 __calc_pre_post_dividers(div, &pre, &post);
350
351 return parent / (pre * post);
352
353}
354
355static int firi_set_rate(struct clk *clk, unsigned long rate)
356{
357 u32 reg, div, pre, post, parent = clk_get_rate(clk->parent);
358
359 div = parent / rate;
360
361 if ((parent / div) != rate)
362 return -EINVAL;
363
364 __calc_pre_post_dividers(div, &pre, &post);
365
366 /* Set FIRI clock divider */
367 reg = __raw_readl(MXC_CCM_PDR1) &
368 ~(MXC_CCM_PDR1_FIRI_PODF_MASK | MXC_CCM_PDR1_FIRI_PRE_PODF_MASK);
369 reg |= (pre - 1) << MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET;
370 reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
371 __raw_writel(reg, MXC_CCM_PDR1);
372
373 return 0;
374}
375
376static unsigned long mbx_get_rate(struct clk *clk)
377{
378 return clk_get_rate(clk->parent) / 2;
379}
380
381static unsigned long mstick1_get_rate(struct clk *clk)
382{
383 unsigned long msti_pdf;
384
385 msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
386 MXC_CCM_PDR2_MST1_PDF_OFFSET);
387 return clk_get_rate(clk->parent) / (msti_pdf + 1);
388}
389
390static unsigned long mstick2_get_rate(struct clk *clk)
391{
392 unsigned long msti_pdf;
393
394 msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
395 MXC_CCM_PDR2_MST2_PDF_OFFSET);
396 return clk_get_rate(clk->parent) / (msti_pdf + 1);
397}
398
399static unsigned long ckih_rate;
400
401static unsigned long clk_ckih_get_rate(struct clk *clk)
402{
403 return ckih_rate;
404}
405
406static unsigned long clk_ckil_get_rate(struct clk *clk)
407{
408 return CKIL_CLK_FREQ;
409}
410
411static struct clk ckih_clk = {
412 .get_rate = clk_ckih_get_rate,
413};
414
415static struct clk mcu_pll_clk = {
416 .parent = &ckih_clk,
417 .get_rate = mcu_pll_get_rate,
418};
419
420static struct clk mcu_main_clk = {
421 .parent = &mcu_pll_clk,
422 .get_rate = mcu_main_get_rate,
423};
424
425static struct clk serial_pll_clk = {
426 .parent = &ckih_clk,
427 .get_rate = serial_pll_get_rate,
428 .enable = serial_pll_enable,
429 .disable = serial_pll_disable,
430};
431
432static struct clk usb_pll_clk = {
433 .parent = &ckih_clk,
434 .get_rate = usb_pll_get_rate,
435 .enable = usb_pll_enable,
436 .disable = usb_pll_disable,
437};
438
439static struct clk ahb_clk = {
440 .parent = &mcu_main_clk,
441 .get_rate = ahb_get_rate,
442};
443
444#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
445 static struct clk name = { \
446 .id = i, \
447 .enable_reg = er, \
448 .enable_shift = es, \
449 .get_rate = gr, \
450 .enable = cgr_enable, \
451 .disable = cgr_disable, \
452 .secondary = s, \
453 .parent = p, \
454 }
455
456#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
457 static struct clk name = { \
458 .id = i, \
459 .enable_reg = er, \
460 .enable_shift = es, \
461 .get_rate = getsetround##_get_rate, \
462 .set_rate = getsetround##_set_rate, \
463 .round_rate = getsetround##_round_rate, \
464 .enable = cgr_enable, \
465 .disable = cgr_disable, \
466 .secondary = s, \
467 .parent = p, \
468 }
469
470DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
471DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
472
473DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
474DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
475DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk);
476DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk);
477DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk);
478DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk);
479DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk);
480DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, NULL, &ahb_clk);
481DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk);
482DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk);
483DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk);
484DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk);
485DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk);
486DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk);
487DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk);
488DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk);
489
490DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
491DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
492DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
493DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
494DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
495DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
496DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
497DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
498DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk);
499DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk);
500DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk);
501DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk);
502DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk);
503DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk);
504
505DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk);
506DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk);
507DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk);
508DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk);
509DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk);
510DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk);
511DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk);
512
513DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk);
514DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk);
515DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
516DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
517DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
518
519#define _REGISTER_CLOCK(d, n, c) \
520 { \
521 .dev_id = d, \
522 .con_id = n, \
523 .clk = &c, \
524 },
525
526static struct clk_lookup lookups[] = {
527 _REGISTER_CLOCK(NULL, "emi", emi_clk)
528 _REGISTER_CLOCK("imx31-cspi.0", NULL, cspi1_clk)
529 _REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
530 _REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
531 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
532 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
533 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
534 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
535 _REGISTER_CLOCK(NULL, "epit", epit1_clk)
536 _REGISTER_CLOCK(NULL, "epit", epit2_clk)
537 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
538 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
539 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
540 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
541 _REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk1)
542 _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_clk2)
543 _REGISTER_CLOCK("mxc-ehci.1", "usb", usb_clk1)
544 _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_clk2)
545 _REGISTER_CLOCK("mxc-ehci.2", "usb", usb_clk1)
546 _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_clk2)
547 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1)
548 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2)
549 _REGISTER_CLOCK("mx3-camera.0", NULL, csi_clk)
550 /* i.mx31 has the i.mx21 type uart */
551 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
552 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
553 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
554 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
555 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
556 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
557 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
558 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
559 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
560 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
561 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
562 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
563 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
564 _REGISTER_CLOCK(NULL, "firi", firi_clk)
565 _REGISTER_CLOCK(NULL, "ata", ata_clk)
566 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
567 _REGISTER_CLOCK(NULL, "rng", rng_clk)
568 _REGISTER_CLOCK("imx31-sdma", NULL, sdma_clk1)
569 _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2)
570 _REGISTER_CLOCK(NULL, "mstick", mstick1_clk)
571 _REGISTER_CLOCK(NULL, "mstick", mstick2_clk)
572 _REGISTER_CLOCK(NULL, "scc", scc_clk)
573 _REGISTER_CLOCK(NULL, "iim", iim_clk)
574 _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
575 _REGISTER_CLOCK(NULL, "mbx", mbx_clk)
576};
577
578int __init mx31_clocks_init(unsigned long fref)
579{
580 u32 reg;
581
582 ckih_rate = fref;
583
584 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
585
586 /* change the csi_clk parent if necessary */
587 reg = __raw_readl(MXC_CCM_CCMR);
588 if (!(reg & MXC_CCM_CCMR_CSCS))
589 if (clk_set_parent(&csi_clk, &usb_pll_clk))
590 pr_err("%s: error changing csi_clk parent\n", __func__);
591
592
593 /* Turn off all possible clocks */
594 __raw_writel((3 << 4), MXC_CCM_CGR0);
595 __raw_writel(0, MXC_CCM_CGR1);
596 __raw_writel((3 << 8) | (3 << 14) | (3 << 16)|
597 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
598 MX32, but still required to be set */
599 MXC_CCM_CGR2);
600
601 /*
602 * Before turning off usb_pll make sure ipg_per_clk is generated
603 * by ipg_clk and not usb_pll.
604 */
605 __raw_writel(__raw_readl(MXC_CCM_CCMR) | (1 << 24), MXC_CCM_CCMR);
606
607 usb_pll_disable(&usb_pll_clk);
608
609 pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
610
611 clk_enable(&gpt_clk);
612 clk_enable(&emi_clk);
613 clk_enable(&iim_clk);
614
615 clk_enable(&serial_pll_clk);
616
617 mx31_read_cpu_rev();
618
619 if (mx31_revision() >= IMX_CHIP_REVISION_2_0) {
620 reg = __raw_readl(MXC_CCM_PMCR1);
621 /* No PLL restart on DVFS switch; enable auto EMI handshake */
622 reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
623 __raw_writel(reg, MXC_CCM_PMCR1);
624 }
625
626 mxc_timer_init(&ipg_clk, MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR),
627 MX31_INT_GPT);
628
629 return 0;
630}
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
new file mode 100644
index 00000000000..88b62a071ae
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx35.c
@@ -0,0 +1,551 @@
1/*
2 * Copyright (C) 2009 by Sascha Hauer, Pengutronix
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16 * MA 02110-1301, USA.
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/list.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/clkdev.h>
25
26#include <mach/clock.h>
27#include <mach/hardware.h>
28#include <mach/common.h>
29
30#define CCM_BASE MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
31
32#define CCM_CCMR 0x00
33#define CCM_PDR0 0x04
34#define CCM_PDR1 0x08
35#define CCM_PDR2 0x0C
36#define CCM_PDR3 0x10
37#define CCM_PDR4 0x14
38#define CCM_RCSR 0x18
39#define CCM_MPCTL 0x1C
40#define CCM_PPCTL 0x20
41#define CCM_ACMR 0x24
42#define CCM_COSR 0x28
43#define CCM_CGR0 0x2C
44#define CCM_CGR1 0x30
45#define CCM_CGR2 0x34
46#define CCM_CGR3 0x38
47
48#ifdef HAVE_SET_RATE_SUPPORT
49static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
50{
51 u32 min_pre, temp_pre, old_err, err;
52
53 min_pre = (div - 1) / maxpost + 1;
54 old_err = 8;
55
56 for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
57 if (div > (temp_pre * maxpost))
58 break;
59
60 if (div < (temp_pre * temp_pre))
61 continue;
62
63 err = div % temp_pre;
64
65 if (err == 0) {
66 *pre = temp_pre;
67 break;
68 }
69
70 err = temp_pre - err;
71
72 if (err < old_err) {
73 old_err = err;
74 *pre = temp_pre;
75 }
76 }
77
78 *post = (div + *pre - 1) / *pre;
79}
80
81/* get the best values for a 3-bit divider combined with a 6-bit divider */
82static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
83{
84 if (div >= 512) {
85 *pre = 8;
86 *post = 64;
87 } else if (div >= 64) {
88 calc_dividers(div, pre, post, 64);
89 } else if (div <= 8) {
90 *pre = div;
91 *post = 1;
92 } else {
93 *pre = 1;
94 *post = div;
95 }
96}
97
98/* get the best values for two cascaded 3-bit dividers */
99static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
100{
101 if (div >= 64) {
102 *pre = *post = 8;
103 } else if (div > 8) {
104 calc_dividers(div, pre, post, 8);
105 } else {
106 *pre = 1;
107 *post = div;
108 }
109}
110#endif
111
112static unsigned long get_rate_mpll(void)
113{
114 ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
115
116 return mxc_decode_pll(mpctl, 24000000);
117}
118
119static unsigned long get_rate_ppll(void)
120{
121 ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
122
123 return mxc_decode_pll(ppctl, 24000000);
124}
125
126struct arm_ahb_div {
127 unsigned char arm, ahb, sel;
128};
129
130static struct arm_ahb_div clk_consumer[] = {
131 { .arm = 1, .ahb = 4, .sel = 0},
132 { .arm = 1, .ahb = 3, .sel = 1},
133 { .arm = 2, .ahb = 2, .sel = 0},
134 { .arm = 0, .ahb = 0, .sel = 0},
135 { .arm = 0, .ahb = 0, .sel = 0},
136 { .arm = 0, .ahb = 0, .sel = 0},
137 { .arm = 4, .ahb = 1, .sel = 0},
138 { .arm = 1, .ahb = 5, .sel = 0},
139 { .arm = 1, .ahb = 8, .sel = 0},
140 { .arm = 1, .ahb = 6, .sel = 1},
141 { .arm = 2, .ahb = 4, .sel = 0},
142 { .arm = 0, .ahb = 0, .sel = 0},
143 { .arm = 0, .ahb = 0, .sel = 0},
144 { .arm = 0, .ahb = 0, .sel = 0},
145 { .arm = 4, .ahb = 2, .sel = 0},
146 { .arm = 0, .ahb = 0, .sel = 0},
147};
148
149static unsigned long get_rate_arm(void)
150{
151 unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
152 struct arm_ahb_div *aad;
153 unsigned long fref = get_rate_mpll();
154
155 aad = &clk_consumer[(pdr0 >> 16) & 0xf];
156 if (aad->sel)
157 fref = fref * 3 / 4;
158
159 return fref / aad->arm;
160}
161
162static unsigned long get_rate_ahb(struct clk *clk)
163{
164 unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
165 struct arm_ahb_div *aad;
166 unsigned long fref = get_rate_arm();
167
168 aad = &clk_consumer[(pdr0 >> 16) & 0xf];
169
170 return fref / aad->ahb;
171}
172
173static unsigned long get_rate_ipg(struct clk *clk)
174{
175 return get_rate_ahb(NULL) >> 1;
176}
177
178static unsigned long get_rate_uart(struct clk *clk)
179{
180 unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
181 unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
182 unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
183
184 if (pdr3 & (1 << 14))
185 return get_rate_arm() / div;
186 else
187 return get_rate_ppll() / div;
188}
189
190static unsigned long get_rate_sdhc(struct clk *clk)
191{
192 unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
193 unsigned long div, rate;
194
195 if (pdr3 & (1 << 6))
196 rate = get_rate_arm();
197 else
198 rate = get_rate_ppll();
199
200 switch (clk->id) {
201 default:
202 case 0:
203 div = pdr3 & 0x3f;
204 break;
205 case 1:
206 div = (pdr3 >> 8) & 0x3f;
207 break;
208 case 2:
209 div = (pdr3 >> 16) & 0x3f;
210 break;
211 }
212
213 return rate / (div + 1);
214}
215
216static unsigned long get_rate_mshc(struct clk *clk)
217{
218 unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
219 unsigned long div1, div2, rate;
220
221 if (pdr1 & (1 << 7))
222 rate = get_rate_arm();
223 else
224 rate = get_rate_ppll();
225
226 div1 = (pdr1 >> 29) & 0x7;
227 div2 = (pdr1 >> 22) & 0x3f;
228
229 return rate / ((div1 + 1) * (div2 + 1));
230}
231
232static unsigned long get_rate_ssi(struct clk *clk)
233{
234 unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
235 unsigned long div1, div2, rate;
236
237 if (pdr2 & (1 << 6))
238 rate = get_rate_arm();
239 else
240 rate = get_rate_ppll();
241
242 switch (clk->id) {
243 default:
244 case 0:
245 div1 = pdr2 & 0x3f;
246 div2 = (pdr2 >> 24) & 0x7;
247 break;
248 case 1:
249 div1 = (pdr2 >> 8) & 0x3f;
250 div2 = (pdr2 >> 27) & 0x7;
251 break;
252 }
253
254 return rate / ((div1 + 1) * (div2 + 1));
255}
256
257static unsigned long get_rate_csi(struct clk *clk)
258{
259 unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
260 unsigned long rate;
261
262 if (pdr2 & (1 << 7))
263 rate = get_rate_arm();
264 else
265 rate = get_rate_ppll();
266
267 return rate / (((pdr2 >> 16) & 0x3f) + 1);
268}
269
270static unsigned long get_rate_otg(struct clk *clk)
271{
272 unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
273 unsigned long rate;
274
275 if (pdr4 & (1 << 9))
276 rate = get_rate_arm();
277 else
278 rate = get_rate_ppll();
279
280 return rate / (((pdr4 >> 22) & 0x3f) + 1);
281}
282
283static unsigned long get_rate_ipg_per(struct clk *clk)
284{
285 unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
286 unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
287 unsigned long div;
288
289 if (pdr0 & (1 << 26)) {
290 div = (pdr4 >> 16) & 0x3f;
291 return get_rate_arm() / (div + 1);
292 } else {
293 div = (pdr0 >> 12) & 0x7;
294 return get_rate_ahb(NULL) / (div + 1);
295 }
296}
297
298static unsigned long get_rate_hsp(struct clk *clk)
299{
300 unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
301 unsigned long fref = get_rate_mpll();
302
303 if (fref > 400 * 1000 * 1000) {
304 switch (hsp_podf) {
305 case 0:
306 return fref >> 2;
307 case 1:
308 return fref >> 3;
309 case 2:
310 return fref / 3;
311 }
312 } else {
313 switch (hsp_podf) {
314 case 0:
315 case 2:
316 return fref / 3;
317 case 1:
318 return fref / 6;
319 }
320 }
321
322 return 0;
323}
324
325static int clk_cgr_enable(struct clk *clk)
326{
327 u32 reg;
328
329 reg = __raw_readl(clk->enable_reg);
330 reg |= 3 << clk->enable_shift;
331 __raw_writel(reg, clk->enable_reg);
332
333 return 0;
334}
335
336static void clk_cgr_disable(struct clk *clk)
337{
338 u32 reg;
339
340 reg = __raw_readl(clk->enable_reg);
341 reg &= ~(3 << clk->enable_shift);
342 __raw_writel(reg, clk->enable_reg);
343}
344
345#define DEFINE_CLOCK(name, i, er, es, gr, sr) \
346 static struct clk name = { \
347 .id = i, \
348 .enable_reg = CCM_BASE + er, \
349 .enable_shift = es, \
350 .get_rate = gr, \
351 .set_rate = sr, \
352 .enable = clk_cgr_enable, \
353 .disable = clk_cgr_disable, \
354 }
355
356DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL);
357DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL);
358/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); */
359DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL);
360DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL);
361DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL);
362DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL);
363DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL);
364DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL);
365DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL);
366DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg, NULL);
367DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg, NULL);
368DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL);
369DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
370DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
371DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
372
373DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL);
374DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL);
375DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL);
376DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL);
377DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL);
378DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
379DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
380DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
381DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
382DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_hsp, NULL);
383DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL);
384DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL);
385DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL);
386DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
387DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
388DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL);
389
390DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL);
391DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL);
392DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL);
393DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL);
394DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL);
395DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL);
396DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL);
397DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL);
398DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL);
399DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL);
400DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL);
401DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
402DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL);
403DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL);
404DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
405
406DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL);
407DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL);
408DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL);
409
410DEFINE_CLOCK(usbahb_clk, 0, 0, 0, get_rate_ahb, NULL);
411
412static int clk_dummy_enable(struct clk *clk)
413{
414 return 0;
415}
416
417static void clk_dummy_disable(struct clk *clk)
418{
419}
420
421static unsigned long get_rate_nfc(struct clk *clk)
422{
423 unsigned long div1;
424
425 div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
426
427 return get_rate_ahb(NULL) / div1;
428}
429
430/* NAND Controller: It seems it can't be disabled */
431static struct clk nfc_clk = {
432 .id = 0,
433 .enable_reg = 0,
434 .enable_shift = 0,
435 .get_rate = get_rate_nfc,
436 .set_rate = NULL, /* set_rate_nfc, */
437 .enable = clk_dummy_enable,
438 .disable = clk_dummy_disable
439};
440
441#define _REGISTER_CLOCK(d, n, c) \
442 { \
443 .dev_id = d, \
444 .con_id = n, \
445 .clk = &c, \
446 },
447
448static struct clk_lookup lookups[] = {
449 _REGISTER_CLOCK(NULL, "asrc", asrc_clk)
450 _REGISTER_CLOCK(NULL, "ata", ata_clk)
451 _REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
452 _REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
453 _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
454 _REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
455 _REGISTER_CLOCK(NULL, "ect", ect_clk)
456 _REGISTER_CLOCK(NULL, "edio", edio_clk)
457 _REGISTER_CLOCK(NULL, "emi", emi_clk)
458 _REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
459 _REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
460 _REGISTER_CLOCK(NULL, "esai", esai_clk)
461 _REGISTER_CLOCK("sdhci-esdhc-imx35.0", NULL, esdhc1_clk)
462 _REGISTER_CLOCK("sdhci-esdhc-imx35.1", NULL, esdhc2_clk)
463 _REGISTER_CLOCK("sdhci-esdhc-imx35.2", NULL, esdhc3_clk)
464 /* i.mx35 has the i.mx27 type fec */
465 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
466 _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
467 _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
468 _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
469 _REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
470 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
471 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
472 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
473 _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
474 _REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
475 _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
476 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
477 _REGISTER_CLOCK(NULL, "mlb", mlb_clk)
478 _REGISTER_CLOCK(NULL, "mshc", mshc_clk)
479 _REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
480 _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
481 _REGISTER_CLOCK(NULL, "rngc", rngc_clk)
482 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
483 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
484 _REGISTER_CLOCK(NULL, "scc", scc_clk)
485 _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk)
486 _REGISTER_CLOCK(NULL, "spba", spba_clk)
487 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
488 _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
489 _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
490 /* i.mx35 has the i.mx21 type uart */
491 _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk)
492 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
493 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
494 _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
495 _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
496 _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
497 _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
498 _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
499 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
500 _REGISTER_CLOCK(NULL, "max", max_clk)
501 _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
502 _REGISTER_CLOCK(NULL, "csi", csi_clk)
503 _REGISTER_CLOCK(NULL, "iim", iim_clk)
504 _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
505 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
506};
507
508int __init mx35_clocks_init()
509{
510 unsigned int cgr2 = 3 << 26, cgr3 = 0;
511
512#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
513 cgr2 |= 3 << 16;
514#endif
515
516 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
517
518 /* Turn off all clocks except the ones we need to survive, namely:
519 * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart
520 */
521 __raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
522 __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
523 CCM_BASE + CCM_CGR1);
524
525 /*
526 * Check if we came up in internal boot mode. If yes, we need some
527 * extra clocks turned on, otherwise the MX35 boot ROM code will
528 * hang after a watchdog reset.
529 */
530 if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
531 /* Additionally turn on UART1, SCC, and IIM clocks */
532 cgr2 |= 3 << 16 | 3 << 4;
533 cgr3 |= 3 << 2;
534 }
535
536 __raw_writel(cgr2, CCM_BASE + CCM_CGR2);
537 __raw_writel(cgr3, CCM_BASE + CCM_CGR3);
538
539 clk_enable(&iim_clk);
540 mx35_read_cpu_rev();
541
542#ifdef CONFIG_MXC_USE_EPIT
543 epit_timer_init(&epit1_clk,
544 MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
545#else
546 mxc_timer_init(&gpt_clk,
547 MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
548#endif
549
550 return 0;
551}
diff --git a/arch/arm/mach-imx/crmregs-imx31.h b/arch/arm/mach-imx/crmregs-imx31.h
new file mode 100644
index 00000000000..37a8a07beda
--- /dev/null
+++ b/arch/arm/mach-imx/crmregs-imx31.h
@@ -0,0 +1,248 @@
1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301, USA.
18 */
19
20#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
21#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
22
23#define CKIH_CLK_FREQ 26000000
24#define CKIH_CLK_FREQ_27MHZ 27000000
25#define CKIL_CLK_FREQ 32768
26
27#define MXC_CCM_BASE MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
28
29/* Register addresses */
30#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
31#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04)
32#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08)
33#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x0C)
34#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x10)
35#define MXC_CCM_UPCTL (MXC_CCM_BASE + 0x14)
36#define MXC_CCM_SRPCTL (MXC_CCM_BASE + 0x18)
37#define MXC_CCM_COSR (MXC_CCM_BASE + 0x1C)
38#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x20)
39#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x24)
40#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x28)
41#define MXC_CCM_WIMR (MXC_CCM_BASE + 0x2C)
42#define MXC_CCM_LDC (MXC_CCM_BASE + 0x30)
43#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x34)
44#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x38)
45#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x3C)
46#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x40)
47#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x44)
48#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x48)
49#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x4C)
50#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x50)
51#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x54)
52#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x58)
53#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x5C)
54#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x60)
55#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64)
56
57/* Register bit definitions */
58#define MXC_CCM_CCMR_WBEN (1 << 27)
59#define MXC_CCM_CCMR_CSCS (1 << 25)
60#define MXC_CCM_CCMR_PERCS (1 << 24)
61#define MXC_CCM_CCMR_SSI1S_OFFSET 18
62#define MXC_CCM_CCMR_SSI1S_MASK (0x3 << 18)
63#define MXC_CCM_CCMR_SSI2S_OFFSET 21
64#define MXC_CCM_CCMR_SSI2S_MASK (0x3 << 21)
65#define MXC_CCM_CCMR_LPM_OFFSET 14
66#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
67#define MXC_CCM_CCMR_FIRS_OFFSET 11
68#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11)
69#define MXC_CCM_CCMR_UPE (1 << 9)
70#define MXC_CCM_CCMR_SPE (1 << 8)
71#define MXC_CCM_CCMR_MDS (1 << 7)
72#define MXC_CCM_CCMR_SBYCS (1 << 4)
73#define MXC_CCM_CCMR_MPE (1 << 3)
74#define MXC_CCM_CCMR_PRCS_OFFSET 1
75#define MXC_CCM_CCMR_PRCS_MASK (0x3 << 1)
76
77#define MXC_CCM_PDR0_CSI_PODF_OFFSET 26
78#define MXC_CCM_PDR0_CSI_PODF_MASK (0x3F << 26)
79#define MXC_CCM_PDR0_CSI_PRDF_OFFSET 23
80#define MXC_CCM_PDR0_CSI_PRDF_MASK (0x7 << 23)
81#define MXC_CCM_PDR0_PER_PODF_OFFSET 16
82#define MXC_CCM_PDR0_PER_PODF_MASK (0x1F << 16)
83#define MXC_CCM_PDR0_HSP_PODF_OFFSET 11
84#define MXC_CCM_PDR0_HSP_PODF_MASK (0x7 << 11)
85#define MXC_CCM_PDR0_NFC_PODF_OFFSET 8
86#define MXC_CCM_PDR0_NFC_PODF_MASK (0x7 << 8)
87#define MXC_CCM_PDR0_IPG_PODF_OFFSET 6
88#define MXC_CCM_PDR0_IPG_PODF_MASK (0x3 << 6)
89#define MXC_CCM_PDR0_MAX_PODF_OFFSET 3
90#define MXC_CCM_PDR0_MAX_PODF_MASK (0x7 << 3)
91#define MXC_CCM_PDR0_MCU_PODF_OFFSET 0
92#define MXC_CCM_PDR0_MCU_PODF_MASK 0x7
93
94#define MXC_CCM_PDR1_USB_PRDF_OFFSET 30
95#define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30)
96#define MXC_CCM_PDR1_USB_PODF_OFFSET 27
97#define MXC_CCM_PDR1_USB_PODF_MASK (0x7 << 27)
98#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET 24
99#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK (0x7 << 24)
100#define MXC_CCM_PDR1_FIRI_PODF_OFFSET 18
101#define MXC_CCM_PDR1_FIRI_PODF_MASK (0x3F << 18)
102#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET 15
103#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK (0x7 << 15)
104#define MXC_CCM_PDR1_SSI2_PODF_OFFSET 9
105#define MXC_CCM_PDR1_SSI2_PODF_MASK (0x3F << 9)
106#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET 6
107#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK (0x7 << 6)
108#define MXC_CCM_PDR1_SSI1_PODF_OFFSET 0
109#define MXC_CCM_PDR1_SSI1_PODF_MASK 0x3F
110
111/* Bit definitions for RCSR */
112#define MXC_CCM_RCSR_NF16B 0x80000000
113
114/*
115 * LTR0 register offsets
116 */
117#define MXC_CCM_LTR0_DIV3CK_OFFSET 1
118#define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1)
119#define MXC_CCM_LTR0_DNTHR_OFFSET 16
120#define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16)
121#define MXC_CCM_LTR0_UPTHR_OFFSET 22
122#define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22)
123
124/*
125 * LTR1 register offsets
126 */
127#define MXC_CCM_LTR1_PNCTHR_OFFSET 0
128#define MXC_CCM_LTR1_PNCTHR_MASK 0x3F
129#define MXC_CCM_LTR1_UPCNT_OFFSET 6
130#define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6)
131#define MXC_CCM_LTR1_DNCNT_OFFSET 14
132#define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14)
133#define MXC_CCM_LTR1_LTBRSR_MASK 0x400000
134#define MXC_CCM_LTR1_LTBRSR_OFFSET 22
135#define MXC_CCM_LTR1_LTBRSR 0x400000
136#define MXC_CCM_LTR1_LTBRSH 0x800000
137
138/*
139 * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
140 */
141#define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3)
142#define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << \
143 MXC_CCM_LTR2_WSW_OFFSET((x)))
144#define MXC_CCM_LTR2_EMAC_OFFSET 0
145#define MXC_CCM_LTR2_EMAC_MASK 0x1FF
146
147/*
148 * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
149 */
150#define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3)
151#define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << \
152 MXC_CCM_LTR3_WSW_OFFSET((x)))
153
154#define MXC_CCM_PMCR0_DFSUP1 0x80000000
155#define MXC_CCM_PMCR0_DFSUP1_SPLL (0 << 31)
156#define MXC_CCM_PMCR0_DFSUP1_MPLL (1 << 31)
157#define MXC_CCM_PMCR0_DFSUP0 0x40000000
158#define MXC_CCM_PMCR0_DFSUP0_PLL (0 << 30)
159#define MXC_CCM_PMCR0_DFSUP0_PDR (1 << 30)
160#define MXC_CCM_PMCR0_DFSUP_MASK (0x3 << 30)
161
162#define DVSUP_TURBO 0
163#define DVSUP_HIGH 1
164#define DVSUP_MEDIUM 2
165#define DVSUP_LOW 3
166#define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28)
167#define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28)
168#define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28)
169#define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28)
170#define MXC_CCM_PMCR0_DVSUP_OFFSET 28
171#define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28)
172#define MXC_CCM_PMCR0_UDSC 0x08000000
173#define MXC_CCM_PMCR0_UDSC_MASK (1 << 27)
174#define MXC_CCM_PMCR0_UDSC_UP (1 << 27)
175#define MXC_CCM_PMCR0_UDSC_DOWN (0 << 27)
176
177#define MXC_CCM_PMCR0_VSCNT_1 (0x0 << 24)
178#define MXC_CCM_PMCR0_VSCNT_2 (0x1 << 24)
179#define MXC_CCM_PMCR0_VSCNT_3 (0x2 << 24)
180#define MXC_CCM_PMCR0_VSCNT_4 (0x3 << 24)
181#define MXC_CCM_PMCR0_VSCNT_5 (0x4 << 24)
182#define MXC_CCM_PMCR0_VSCNT_6 (0x5 << 24)
183#define MXC_CCM_PMCR0_VSCNT_7 (0x6 << 24)
184#define MXC_CCM_PMCR0_VSCNT_8 (0x7 << 24)
185#define MXC_CCM_PMCR0_VSCNT_OFFSET 24
186#define MXC_CCM_PMCR0_VSCNT_MASK (0x7 << 24)
187#define MXC_CCM_PMCR0_DVFEV 0x00800000
188#define MXC_CCM_PMCR0_DVFIS 0x00400000
189#define MXC_CCM_PMCR0_LBMI 0x00200000
190#define MXC_CCM_PMCR0_LBFL 0x00100000
191#define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18)
192#define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18)
193#define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18)
194#define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18)
195#define MXC_CCM_PMCR0_LBCF_OFFSET 18
196#define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18)
197#define MXC_CCM_PMCR0_PTVIS 0x00020000
198#define MXC_CCM_PMCR0_UPDTEN 0x00010000
199#define MXC_CCM_PMCR0_UPDTEN_MASK (0x1 << 16)
200#define MXC_CCM_PMCR0_FSVAIM 0x00008000
201#define MXC_CCM_PMCR0_FSVAI_OFFSET 13
202#define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13)
203#define MXC_CCM_PMCR0_DPVCR 0x00001000
204#define MXC_CCM_PMCR0_DPVV 0x00000800
205#define MXC_CCM_PMCR0_WFIM 0x00000400
206#define MXC_CCM_PMCR0_DRCE3 0x00000200
207#define MXC_CCM_PMCR0_DRCE2 0x00000100
208#define MXC_CCM_PMCR0_DRCE1 0x00000080
209#define MXC_CCM_PMCR0_DRCE0 0x00000040
210#define MXC_CCM_PMCR0_DCR 0x00000020
211#define MXC_CCM_PMCR0_DVFEN 0x00000010
212#define MXC_CCM_PMCR0_PTVAIM 0x00000008
213#define MXC_CCM_PMCR0_PTVAI_OFFSET 1
214#define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1)
215#define MXC_CCM_PMCR0_DPTEN 0x00000001
216
217#define MXC_CCM_PMCR1_DVGP_OFFSET 0
218#define MXC_CCM_PMCR1_DVGP_MASK (0xF)
219
220#define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7)
221#define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8)
222
223#define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22)
224#define MXC_CCM_DCVR_ULV_OFFSET 22
225#define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12)
226#define MXC_CCM_DCVR_LLV_OFFSET 12
227#define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2)
228#define MXC_CCM_DCVR_ELV_OFFSET 2
229
230#define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7)
231#define MXC_CCM_PDR2_MST2_PDF_OFFSET 7
232#define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F
233#define MXC_CCM_PDR2_MST1_PDF_OFFSET 0
234
235#define MXC_CCM_COSR_CLKOSEL_MASK 0x0F
236#define MXC_CCM_COSR_CLKOSEL_OFFSET 0
237#define MXC_CCM_COSR_CLKOUTDIV_MASK (0x07 << 6)
238#define MXC_CCM_COSR_CLKOUTDIV_OFFSET 6
239#define MXC_CCM_COSR_CLKOEN (1 << 9)
240
241/*
242 * PMCR0 register offsets
243 */
244#define MXC_CCM_PMCR0_LBFL_OFFSET 20
245#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
246#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
247
248#endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff --git a/arch/arm/mach-imx/dma-v1.c b/arch/arm/mach-imx/dma-v1.c
new file mode 100644
index 00000000000..42afc29a7da
--- /dev/null
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -0,0 +1,846 @@
1/*
2 * linux/arch/arm/plat-mxc/dma-v1.c
3 *
4 * i.MX DMA registration and IRQ dispatching
5 *
6 * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
7 * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
8 * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/interrupt.h>
29#include <linux/err.h>
30#include <linux/errno.h>
31#include <linux/clk.h>
32#include <linux/scatterlist.h>
33#include <linux/io.h>
34
35#include <asm/system.h>
36#include <asm/irq.h>
37#include <mach/hardware.h>
38#include <mach/dma-v1.h>
39
40#define DMA_DCR 0x00 /* Control Register */
41#define DMA_DISR 0x04 /* Interrupt status Register */
42#define DMA_DIMR 0x08 /* Interrupt mask Register */
43#define DMA_DBTOSR 0x0c /* Burst timeout status Register */
44#define DMA_DRTOSR 0x10 /* Request timeout Register */
45#define DMA_DSESR 0x14 /* Transfer Error Status Register */
46#define DMA_DBOSR 0x18 /* Buffer overflow status Register */
47#define DMA_DBTOCR 0x1c /* Burst timeout control Register */
48#define DMA_WSRA 0x40 /* W-Size Register A */
49#define DMA_XSRA 0x44 /* X-Size Register A */
50#define DMA_YSRA 0x48 /* Y-Size Register A */
51#define DMA_WSRB 0x4c /* W-Size Register B */
52#define DMA_XSRB 0x50 /* X-Size Register B */
53#define DMA_YSRB 0x54 /* Y-Size Register B */
54#define DMA_SAR(x) (0x80 + ((x) << 6)) /* Source Address Registers */
55#define DMA_DAR(x) (0x84 + ((x) << 6)) /* Destination Address Registers */
56#define DMA_CNTR(x) (0x88 + ((x) << 6)) /* Count Registers */
57#define DMA_CCR(x) (0x8c + ((x) << 6)) /* Control Registers */
58#define DMA_RSSR(x) (0x90 + ((x) << 6)) /* Request source select Registers */
59#define DMA_BLR(x) (0x94 + ((x) << 6)) /* Burst length Registers */
60#define DMA_RTOR(x) (0x98 + ((x) << 6)) /* Request timeout Registers */
61#define DMA_BUCR(x) (0x98 + ((x) << 6)) /* Bus Utilization Registers */
62#define DMA_CCNR(x) (0x9C + ((x) << 6)) /* Channel counter Registers */
63
64#define DCR_DRST (1<<1)
65#define DCR_DEN (1<<0)
66#define DBTOCR_EN (1<<15)
67#define DBTOCR_CNT(x) ((x) & 0x7fff)
68#define CNTR_CNT(x) ((x) & 0xffffff)
69#define CCR_ACRPT (1<<14)
70#define CCR_DMOD_LINEAR (0x0 << 12)
71#define CCR_DMOD_2D (0x1 << 12)
72#define CCR_DMOD_FIFO (0x2 << 12)
73#define CCR_DMOD_EOBFIFO (0x3 << 12)
74#define CCR_SMOD_LINEAR (0x0 << 10)
75#define CCR_SMOD_2D (0x1 << 10)
76#define CCR_SMOD_FIFO (0x2 << 10)
77#define CCR_SMOD_EOBFIFO (0x3 << 10)
78#define CCR_MDIR_DEC (1<<9)
79#define CCR_MSEL_B (1<<8)
80#define CCR_DSIZ_32 (0x0 << 6)
81#define CCR_DSIZ_8 (0x1 << 6)
82#define CCR_DSIZ_16 (0x2 << 6)
83#define CCR_SSIZ_32 (0x0 << 4)
84#define CCR_SSIZ_8 (0x1 << 4)
85#define CCR_SSIZ_16 (0x2 << 4)
86#define CCR_REN (1<<3)
87#define CCR_RPT (1<<2)
88#define CCR_FRC (1<<1)
89#define CCR_CEN (1<<0)
90#define RTOR_EN (1<<15)
91#define RTOR_CLK (1<<14)
92#define RTOR_PSC (1<<13)
93
94/*
95 * struct imx_dma_channel - i.MX specific DMA extension
96 * @name: name specified by DMA client
97 * @irq_handler: client callback for end of transfer
98 * @err_handler: client callback for error condition
99 * @data: clients context data for callbacks
100 * @dma_mode: direction of the transfer %DMA_MODE_READ or %DMA_MODE_WRITE
101 * @sg: pointer to the actual read/written chunk for scatter-gather emulation
102 * @resbytes: total residual number of bytes to transfer
103 * (it can be lower or same as sum of SG mapped chunk sizes)
104 * @sgcount: number of chunks to be read/written
105 *
106 * Structure is used for IMX DMA processing. It would be probably good
107 * @struct dma_struct in the future for external interfacing and use
108 * @struct imx_dma_channel only as extension to it.
109 */
110
111struct imx_dma_channel {
112 const char *name;
113 void (*irq_handler) (int, void *);
114 void (*err_handler) (int, void *, int errcode);
115 void (*prog_handler) (int, void *, struct scatterlist *);
116 void *data;
117 unsigned int dma_mode;
118 struct scatterlist *sg;
119 unsigned int resbytes;
120 int dma_num;
121
122 int in_use;
123
124 u32 ccr_from_device;
125 u32 ccr_to_device;
126
127 struct timer_list watchdog;
128
129 int hw_chaining;
130};
131
132static void __iomem *imx_dmav1_baseaddr;
133
134static void imx_dmav1_writel(unsigned val, unsigned offset)
135{
136 __raw_writel(val, imx_dmav1_baseaddr + offset);
137}
138
139static unsigned imx_dmav1_readl(unsigned offset)
140{
141 return __raw_readl(imx_dmav1_baseaddr + offset);
142}
143
144static struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
145
146static struct clk *dma_clk;
147
148static int imx_dma_hw_chain(struct imx_dma_channel *imxdma)
149{
150 if (cpu_is_mx27())
151 return imxdma->hw_chaining;
152 else
153 return 0;
154}
155
156/*
157 * imx_dma_sg_next - prepare next chunk for scatter-gather DMA emulation
158 */
159static inline int imx_dma_sg_next(int channel, struct scatterlist *sg)
160{
161 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
162 unsigned long now;
163
164 if (!imxdma->name) {
165 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
166 __func__, channel);
167 return 0;
168 }
169
170 now = min(imxdma->resbytes, sg->length);
171 if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP)
172 imxdma->resbytes -= now;
173
174 if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ)
175 imx_dmav1_writel(sg->dma_address, DMA_DAR(channel));
176 else
177 imx_dmav1_writel(sg->dma_address, DMA_SAR(channel));
178
179 imx_dmav1_writel(now, DMA_CNTR(channel));
180
181 pr_debug("imxdma%d: next sg chunk dst 0x%08x, src 0x%08x, "
182 "size 0x%08x\n", channel,
183 imx_dmav1_readl(DMA_DAR(channel)),
184 imx_dmav1_readl(DMA_SAR(channel)),
185 imx_dmav1_readl(DMA_CNTR(channel)));
186
187 return now;
188}
189
190/**
191 * imx_dma_setup_single - setup i.MX DMA channel for linear memory to/from
192 * device transfer
193 *
194 * @channel: i.MX DMA channel number
195 * @dma_address: the DMA/physical memory address of the linear data block
196 * to transfer
197 * @dma_length: length of the data block in bytes
198 * @dev_addr: physical device port address
199 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
200 * or %DMA_MODE_WRITE from memory to the device
201 *
202 * Return value: if incorrect parameters are provided -%EINVAL.
203 * Zero indicates success.
204 */
205int
206imx_dma_setup_single(int channel, dma_addr_t dma_address,
207 unsigned int dma_length, unsigned int dev_addr,
208 unsigned int dmamode)
209{
210 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
211
212 imxdma->sg = NULL;
213 imxdma->dma_mode = dmamode;
214
215 if (!dma_address) {
216 printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
217 channel);
218 return -EINVAL;
219 }
220
221 if (!dma_length) {
222 printk(KERN_ERR "imxdma%d: imx_dma_setup_single zero length\n",
223 channel);
224 return -EINVAL;
225 }
226
227 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
228 pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
229 "dev_addr=0x%08x for read\n",
230 channel, __func__, (unsigned int)dma_address,
231 dma_length, dev_addr);
232
233 imx_dmav1_writel(dev_addr, DMA_SAR(channel));
234 imx_dmav1_writel(dma_address, DMA_DAR(channel));
235 imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
236 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
237 pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
238 "dev_addr=0x%08x for write\n",
239 channel, __func__, (unsigned int)dma_address,
240 dma_length, dev_addr);
241
242 imx_dmav1_writel(dma_address, DMA_SAR(channel));
243 imx_dmav1_writel(dev_addr, DMA_DAR(channel));
244 imx_dmav1_writel(imxdma->ccr_to_device,
245 DMA_CCR(channel));
246 } else {
247 printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
248 channel);
249 return -EINVAL;
250 }
251
252 imx_dmav1_writel(dma_length, DMA_CNTR(channel));
253
254 return 0;
255}
256EXPORT_SYMBOL(imx_dma_setup_single);
257
258/**
259 * imx_dma_setup_sg - setup i.MX DMA channel SG list to/from device transfer
260 * @channel: i.MX DMA channel number
261 * @sg: pointer to the scatter-gather list/vector
262 * @sgcount: scatter-gather list hungs count
263 * @dma_length: total length of the transfer request in bytes
264 * @dev_addr: physical device port address
265 * @dmamode: DMA transfer mode, %DMA_MODE_READ from the device to the memory
266 * or %DMA_MODE_WRITE from memory to the device
267 *
268 * The function sets up DMA channel state and registers to be ready for
269 * transfer specified by provided parameters. The scatter-gather emulation
270 * is set up according to the parameters.
271 *
272 * The full preparation of the transfer requires setup of more register
273 * by the caller before imx_dma_enable() can be called.
274 *
275 * %BLR(channel) holds transfer burst length in bytes, 0 means 64 bytes
276 *
277 * %RSSR(channel) has to be set to the DMA request line source %DMA_REQ_xxx
278 *
279 * %CCR(channel) has to specify transfer parameters, the next settings is
280 * typical for linear or simple scatter-gather transfers if %DMA_MODE_READ is
281 * specified
282 *
283 * %CCR_DMOD_LINEAR | %CCR_DSIZ_32 | %CCR_SMOD_FIFO | %CCR_SSIZ_x
284 *
285 * The typical setup for %DMA_MODE_WRITE is specified by next options
286 * combination
287 *
288 * %CCR_SMOD_LINEAR | %CCR_SSIZ_32 | %CCR_DMOD_FIFO | %CCR_DSIZ_x
289 *
290 * Be careful here and do not mistakenly mix source and target device
291 * port sizes constants, they are really different:
292 * %CCR_SSIZ_8, %CCR_SSIZ_16, %CCR_SSIZ_32,
293 * %CCR_DSIZ_8, %CCR_DSIZ_16, %CCR_DSIZ_32
294 *
295 * Return value: if incorrect parameters are provided -%EINVAL.
296 * Zero indicates success.
297 */
298int
299imx_dma_setup_sg(int channel,
300 struct scatterlist *sg, unsigned int sgcount,
301 unsigned int dma_length, unsigned int dev_addr,
302 unsigned int dmamode)
303{
304 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
305
306 if (imxdma->in_use)
307 return -EBUSY;
308
309 imxdma->sg = sg;
310 imxdma->dma_mode = dmamode;
311 imxdma->resbytes = dma_length;
312
313 if (!sg || !sgcount) {
314 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg empty sg list\n",
315 channel);
316 return -EINVAL;
317 }
318
319 if (!sg->length) {
320 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
321 channel);
322 return -EINVAL;
323 }
324
325 if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) {
326 pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
327 "dev_addr=0x%08x for read\n",
328 channel, __func__, sg, sgcount, dma_length, dev_addr);
329
330 imx_dmav1_writel(dev_addr, DMA_SAR(channel));
331 imx_dmav1_writel(imxdma->ccr_from_device, DMA_CCR(channel));
332 } else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) {
333 pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
334 "dev_addr=0x%08x for write\n",
335 channel, __func__, sg, sgcount, dma_length, dev_addr);
336
337 imx_dmav1_writel(dev_addr, DMA_DAR(channel));
338 imx_dmav1_writel(imxdma->ccr_to_device, DMA_CCR(channel));
339 } else {
340 printk(KERN_ERR "imxdma%d: imx_dma_setup_sg bad dmamode\n",
341 channel);
342 return -EINVAL;
343 }
344
345 imx_dma_sg_next(channel, sg);
346
347 return 0;
348}
349EXPORT_SYMBOL(imx_dma_setup_sg);
350
351int
352imx_dma_config_channel(int channel, unsigned int config_port,
353 unsigned int config_mem, unsigned int dmareq, int hw_chaining)
354{
355 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
356 u32 dreq = 0;
357
358 imxdma->hw_chaining = 0;
359
360 if (hw_chaining) {
361 imxdma->hw_chaining = 1;
362 if (!imx_dma_hw_chain(imxdma))
363 return -EINVAL;
364 }
365
366 if (dmareq)
367 dreq = CCR_REN;
368
369 imxdma->ccr_from_device = config_port | (config_mem << 2) | dreq;
370 imxdma->ccr_to_device = config_mem | (config_port << 2) | dreq;
371
372 imx_dmav1_writel(dmareq, DMA_RSSR(channel));
373
374 return 0;
375}
376EXPORT_SYMBOL(imx_dma_config_channel);
377
378void imx_dma_config_burstlen(int channel, unsigned int burstlen)
379{
380 imx_dmav1_writel(burstlen, DMA_BLR(channel));
381}
382EXPORT_SYMBOL(imx_dma_config_burstlen);
383
384/**
385 * imx_dma_setup_handlers - setup i.MX DMA channel end and error notification
386 * handlers
387 * @channel: i.MX DMA channel number
388 * @irq_handler: the pointer to the function called if the transfer
389 * ends successfully
390 * @err_handler: the pointer to the function called if the premature
391 * end caused by error occurs
392 * @data: user specified value to be passed to the handlers
393 */
394int
395imx_dma_setup_handlers(int channel,
396 void (*irq_handler) (int, void *),
397 void (*err_handler) (int, void *, int),
398 void *data)
399{
400 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
401 unsigned long flags;
402
403 if (!imxdma->name) {
404 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
405 __func__, channel);
406 return -ENODEV;
407 }
408
409 local_irq_save(flags);
410 imx_dmav1_writel(1 << channel, DMA_DISR);
411 imxdma->irq_handler = irq_handler;
412 imxdma->err_handler = err_handler;
413 imxdma->data = data;
414 local_irq_restore(flags);
415 return 0;
416}
417EXPORT_SYMBOL(imx_dma_setup_handlers);
418
419/**
420 * imx_dma_setup_progression_handler - setup i.MX DMA channel progression
421 * handlers
422 * @channel: i.MX DMA channel number
423 * @prog_handler: the pointer to the function called if the transfer progresses
424 */
425int
426imx_dma_setup_progression_handler(int channel,
427 void (*prog_handler) (int, void*, struct scatterlist*))
428{
429 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
430 unsigned long flags;
431
432 if (!imxdma->name) {
433 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
434 __func__, channel);
435 return -ENODEV;
436 }
437
438 local_irq_save(flags);
439 imxdma->prog_handler = prog_handler;
440 local_irq_restore(flags);
441 return 0;
442}
443EXPORT_SYMBOL(imx_dma_setup_progression_handler);
444
445/**
446 * imx_dma_enable - function to start i.MX DMA channel operation
447 * @channel: i.MX DMA channel number
448 *
449 * The channel has to be allocated by driver through imx_dma_request()
450 * or imx_dma_request_by_prio() function.
451 * The transfer parameters has to be set to the channel registers through
452 * call of the imx_dma_setup_single() or imx_dma_setup_sg() function
453 * and registers %BLR(channel), %RSSR(channel) and %CCR(channel) has to
454 * be set prior this function call by the channel user.
455 */
456void imx_dma_enable(int channel)
457{
458 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
459 unsigned long flags;
460
461 pr_debug("imxdma%d: imx_dma_enable\n", channel);
462
463 if (!imxdma->name) {
464 printk(KERN_CRIT "%s: called for not allocated channel %d\n",
465 __func__, channel);
466 return;
467 }
468
469 if (imxdma->in_use)
470 return;
471
472 local_irq_save(flags);
473
474 imx_dmav1_writel(1 << channel, DMA_DISR);
475 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) & ~(1 << channel), DMA_DIMR);
476 imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) | CCR_CEN |
477 CCR_ACRPT, DMA_CCR(channel));
478
479 if ((cpu_is_mx21() || cpu_is_mx27()) &&
480 imxdma->sg && imx_dma_hw_chain(imxdma)) {
481 imxdma->sg = sg_next(imxdma->sg);
482 if (imxdma->sg) {
483 u32 tmp;
484 imx_dma_sg_next(channel, imxdma->sg);
485 tmp = imx_dmav1_readl(DMA_CCR(channel));
486 imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
487 DMA_CCR(channel));
488 }
489 }
490 imxdma->in_use = 1;
491
492 local_irq_restore(flags);
493}
494EXPORT_SYMBOL(imx_dma_enable);
495
496/**
497 * imx_dma_disable - stop, finish i.MX DMA channel operatin
498 * @channel: i.MX DMA channel number
499 */
500void imx_dma_disable(int channel)
501{
502 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
503 unsigned long flags;
504
505 pr_debug("imxdma%d: imx_dma_disable\n", channel);
506
507 if (imx_dma_hw_chain(imxdma))
508 del_timer(&imxdma->watchdog);
509
510 local_irq_save(flags);
511 imx_dmav1_writel(imx_dmav1_readl(DMA_DIMR) | (1 << channel), DMA_DIMR);
512 imx_dmav1_writel(imx_dmav1_readl(DMA_CCR(channel)) & ~CCR_CEN,
513 DMA_CCR(channel));
514 imx_dmav1_writel(1 << channel, DMA_DISR);
515 imxdma->in_use = 0;
516 local_irq_restore(flags);
517}
518EXPORT_SYMBOL(imx_dma_disable);
519
520static void imx_dma_watchdog(unsigned long chno)
521{
522 struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
523
524 imx_dmav1_writel(0, DMA_CCR(chno));
525 imxdma->in_use = 0;
526 imxdma->sg = NULL;
527
528 if (imxdma->err_handler)
529 imxdma->err_handler(chno, imxdma->data, IMX_DMA_ERR_TIMEOUT);
530}
531
532static irqreturn_t dma_err_handler(int irq, void *dev_id)
533{
534 int i, disr;
535 struct imx_dma_channel *imxdma;
536 unsigned int err_mask;
537 int errcode;
538
539 disr = imx_dmav1_readl(DMA_DISR);
540
541 err_mask = imx_dmav1_readl(DMA_DBTOSR) |
542 imx_dmav1_readl(DMA_DRTOSR) |
543 imx_dmav1_readl(DMA_DSESR) |
544 imx_dmav1_readl(DMA_DBOSR);
545
546 if (!err_mask)
547 return IRQ_HANDLED;
548
549 imx_dmav1_writel(disr & err_mask, DMA_DISR);
550
551 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
552 if (!(err_mask & (1 << i)))
553 continue;
554 imxdma = &imx_dma_channels[i];
555 errcode = 0;
556
557 if (imx_dmav1_readl(DMA_DBTOSR) & (1 << i)) {
558 imx_dmav1_writel(1 << i, DMA_DBTOSR);
559 errcode |= IMX_DMA_ERR_BURST;
560 }
561 if (imx_dmav1_readl(DMA_DRTOSR) & (1 << i)) {
562 imx_dmav1_writel(1 << i, DMA_DRTOSR);
563 errcode |= IMX_DMA_ERR_REQUEST;
564 }
565 if (imx_dmav1_readl(DMA_DSESR) & (1 << i)) {
566 imx_dmav1_writel(1 << i, DMA_DSESR);
567 errcode |= IMX_DMA_ERR_TRANSFER;
568 }
569 if (imx_dmav1_readl(DMA_DBOSR) & (1 << i)) {
570 imx_dmav1_writel(1 << i, DMA_DBOSR);
571 errcode |= IMX_DMA_ERR_BUFFER;
572 }
573 if (imxdma->name && imxdma->err_handler) {
574 imxdma->err_handler(i, imxdma->data, errcode);
575 continue;
576 }
577
578 imx_dma_channels[i].sg = NULL;
579
580 printk(KERN_WARNING
581 "DMA timeout on channel %d (%s) -%s%s%s%s\n",
582 i, imxdma->name,
583 errcode & IMX_DMA_ERR_BURST ? " burst" : "",
584 errcode & IMX_DMA_ERR_REQUEST ? " request" : "",
585 errcode & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
586 errcode & IMX_DMA_ERR_BUFFER ? " buffer" : "");
587 }
588 return IRQ_HANDLED;
589}
590
591static void dma_irq_handle_channel(int chno)
592{
593 struct imx_dma_channel *imxdma = &imx_dma_channels[chno];
594
595 if (!imxdma->name) {
596 /*
597 * IRQ for an unregistered DMA channel:
598 * let's clear the interrupts and disable it.
599 */
600 printk(KERN_WARNING
601 "spurious IRQ for DMA channel %d\n", chno);
602 return;
603 }
604
605 if (imxdma->sg) {
606 u32 tmp;
607 struct scatterlist *current_sg = imxdma->sg;
608 imxdma->sg = sg_next(imxdma->sg);
609
610 if (imxdma->sg) {
611 imx_dma_sg_next(chno, imxdma->sg);
612
613 tmp = imx_dmav1_readl(DMA_CCR(chno));
614
615 if (imx_dma_hw_chain(imxdma)) {
616 /* FIXME: The timeout should probably be
617 * configurable
618 */
619 mod_timer(&imxdma->watchdog,
620 jiffies + msecs_to_jiffies(500));
621
622 tmp |= CCR_CEN | CCR_RPT | CCR_ACRPT;
623 imx_dmav1_writel(tmp, DMA_CCR(chno));
624 } else {
625 imx_dmav1_writel(tmp & ~CCR_CEN, DMA_CCR(chno));
626 tmp |= CCR_CEN;
627 }
628
629 imx_dmav1_writel(tmp, DMA_CCR(chno));
630
631 if (imxdma->prog_handler)
632 imxdma->prog_handler(chno, imxdma->data,
633 current_sg);
634
635 return;
636 }
637
638 if (imx_dma_hw_chain(imxdma)) {
639 del_timer(&imxdma->watchdog);
640 return;
641 }
642 }
643
644 imx_dmav1_writel(0, DMA_CCR(chno));
645 imxdma->in_use = 0;
646 if (imxdma->irq_handler)
647 imxdma->irq_handler(chno, imxdma->data);
648}
649
650static irqreturn_t dma_irq_handler(int irq, void *dev_id)
651{
652 int i, disr;
653
654 if (cpu_is_mx21() || cpu_is_mx27())
655 dma_err_handler(irq, dev_id);
656
657 disr = imx_dmav1_readl(DMA_DISR);
658
659 pr_debug("imxdma: dma_irq_handler called, disr=0x%08x\n",
660 disr);
661
662 imx_dmav1_writel(disr, DMA_DISR);
663 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
664 if (disr & (1 << i))
665 dma_irq_handle_channel(i);
666 }
667
668 return IRQ_HANDLED;
669}
670
671/**
672 * imx_dma_request - request/allocate specified channel number
673 * @channel: i.MX DMA channel number
674 * @name: the driver/caller own non-%NULL identification
675 */
676int imx_dma_request(int channel, const char *name)
677{
678 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
679 unsigned long flags;
680 int ret = 0;
681
682 /* basic sanity checks */
683 if (!name)
684 return -EINVAL;
685
686 if (channel >= IMX_DMA_CHANNELS) {
687 printk(KERN_CRIT "%s: called for non-existed channel %d\n",
688 __func__, channel);
689 return -EINVAL;
690 }
691
692 local_irq_save(flags);
693 if (imxdma->name) {
694 local_irq_restore(flags);
695 return -EBUSY;
696 }
697 memset(imxdma, 0, sizeof(*imxdma));
698 imxdma->name = name;
699 local_irq_restore(flags); /* request_irq() can block */
700
701 if (cpu_is_mx21() || cpu_is_mx27()) {
702 ret = request_irq(MX2x_INT_DMACH0 + channel,
703 dma_irq_handler, 0, "DMA", NULL);
704 if (ret) {
705 imxdma->name = NULL;
706 pr_crit("Can't register IRQ %d for DMA channel %d\n",
707 MX2x_INT_DMACH0 + channel, channel);
708 return ret;
709 }
710 init_timer(&imxdma->watchdog);
711 imxdma->watchdog.function = &imx_dma_watchdog;
712 imxdma->watchdog.data = channel;
713 }
714
715 return ret;
716}
717EXPORT_SYMBOL(imx_dma_request);
718
719/**
720 * imx_dma_free - release previously acquired channel
721 * @channel: i.MX DMA channel number
722 */
723void imx_dma_free(int channel)
724{
725 unsigned long flags;
726 struct imx_dma_channel *imxdma = &imx_dma_channels[channel];
727
728 if (!imxdma->name) {
729 printk(KERN_CRIT
730 "%s: trying to free free channel %d\n",
731 __func__, channel);
732 return;
733 }
734
735 local_irq_save(flags);
736 /* Disable interrupts */
737 imx_dma_disable(channel);
738 imxdma->name = NULL;
739
740 if (cpu_is_mx21() || cpu_is_mx27())
741 free_irq(MX2x_INT_DMACH0 + channel, NULL);
742
743 local_irq_restore(flags);
744}
745EXPORT_SYMBOL(imx_dma_free);
746
747/**
748 * imx_dma_request_by_prio - find and request some of free channels best
749 * suiting requested priority
750 * @channel: i.MX DMA channel number
751 * @name: the driver/caller own non-%NULL identification
752 *
753 * This function tries to find a free channel in the specified priority group
754 * if the priority cannot be achieved it tries to look for free channel
755 * in the higher and then even lower priority groups.
756 *
757 * Return value: If there is no free channel to allocate, -%ENODEV is returned.
758 * On successful allocation channel is returned.
759 */
760int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio)
761{
762 int i;
763 int best;
764
765 switch (prio) {
766 case (DMA_PRIO_HIGH):
767 best = 8;
768 break;
769 case (DMA_PRIO_MEDIUM):
770 best = 4;
771 break;
772 case (DMA_PRIO_LOW):
773 default:
774 best = 0;
775 break;
776 }
777
778 for (i = best; i < IMX_DMA_CHANNELS; i++)
779 if (!imx_dma_request(i, name))
780 return i;
781
782 for (i = best - 1; i >= 0; i--)
783 if (!imx_dma_request(i, name))
784 return i;
785
786 printk(KERN_ERR "%s: no free DMA channel found\n", __func__);
787
788 return -ENODEV;
789}
790EXPORT_SYMBOL(imx_dma_request_by_prio);
791
792static int __init imx_dma_init(void)
793{
794 int ret = 0;
795 int i;
796
797 if (cpu_is_mx1())
798 imx_dmav1_baseaddr = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
799 else if (cpu_is_mx21())
800 imx_dmav1_baseaddr = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
801 else if (cpu_is_mx27())
802 imx_dmav1_baseaddr = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
803 else
804 return 0;
805
806 dma_clk = clk_get(NULL, "dma");
807 if (IS_ERR(dma_clk))
808 return PTR_ERR(dma_clk);
809 clk_enable(dma_clk);
810
811 /* reset DMA module */
812 imx_dmav1_writel(DCR_DRST, DMA_DCR);
813
814 if (cpu_is_mx1()) {
815 ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", NULL);
816 if (ret) {
817 pr_crit("Wow! Can't register IRQ for DMA\n");
818 return ret;
819 }
820
821 ret = request_irq(MX1_DMA_ERR, dma_err_handler, 0, "DMA", NULL);
822 if (ret) {
823 pr_crit("Wow! Can't register ERRIRQ for DMA\n");
824 free_irq(MX1_DMA_INT, NULL);
825 return ret;
826 }
827 }
828
829 /* enable DMA module */
830 imx_dmav1_writel(DCR_DEN, DMA_DCR);
831
832 /* clear all interrupts */
833 imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DISR);
834
835 /* disable interrupts */
836 imx_dmav1_writel((1 << IMX_DMA_CHANNELS) - 1, DMA_DIMR);
837
838 for (i = 0; i < IMX_DMA_CHANNELS; i++) {
839 imx_dma_channels[i].sg = NULL;
840 imx_dma_channels[i].dma_num = i;
841 }
842
843 return ret;
844}
845
846arch_initcall(imx_dma_init);
diff --git a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
new file mode 100644
index 00000000000..df5f522da6b
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
@@ -0,0 +1,10 @@
1#ifndef __MACH_DMA_MX1_MX2_H__
2#define __MACH_DMA_MX1_MX2_H__
3/*
4 * Don't use this header in new code, it will go away when all users are
5 * converted to mach/dma-v1.h
6 */
7
8#include <mach/dma-v1.h>
9
10#endif /* ifndef __MACH_DMA_MX1_MX2_H__ */
diff --git a/arch/arm/mach-imx/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h
new file mode 100644
index 00000000000..ac6fd713828
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-v1.h
@@ -0,0 +1,103 @@
1/*
2 * linux/arch/arm/mach-imx/include/mach/dma-v1.h
3 *
4 * i.MX DMA registration and IRQ dispatching
5 *
6 * Copyright 2006 Pavel Pisa <pisa@cmp.felk.cvut.cz>
7 * Copyright 2008 Juergen Beisert, <kernel@pengutronix.de>
8 * Copyright 2008 Sascha Hauer, <s.hauer@pengutronix.de>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 * MA 02110-1301, USA.
23 */
24
25#ifndef __MACH_DMA_V1_H__
26#define __MACH_DMA_V1_H__
27
28#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
29
30#include <mach/dma.h>
31
32#define IMX_DMA_CHANNELS 16
33
34#define DMA_MODE_READ 0
35#define DMA_MODE_WRITE 1
36#define DMA_MODE_MASK 1
37
38#define MX1_DMA_REG(offset) MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR + (offset))
39
40/* DMA Interrupt Mask Register */
41#define MX1_DMA_DIMR MX1_DMA_REG(0x08)
42
43/* Channel Control Register */
44#define MX1_DMA_CCR(x) MX1_DMA_REG(0x8c + ((x) << 6))
45
46#define IMX_DMA_MEMSIZE_32 (0 << 4)
47#define IMX_DMA_MEMSIZE_8 (1 << 4)
48#define IMX_DMA_MEMSIZE_16 (2 << 4)
49#define IMX_DMA_TYPE_LINEAR (0 << 10)
50#define IMX_DMA_TYPE_2D (1 << 10)
51#define IMX_DMA_TYPE_FIFO (2 << 10)
52
53#define IMX_DMA_ERR_BURST (1 << 0)
54#define IMX_DMA_ERR_REQUEST (1 << 1)
55#define IMX_DMA_ERR_TRANSFER (1 << 2)
56#define IMX_DMA_ERR_BUFFER (1 << 3)
57#define IMX_DMA_ERR_TIMEOUT (1 << 4)
58
59int
60imx_dma_config_channel(int channel, unsigned int config_port,
61 unsigned int config_mem, unsigned int dmareq, int hw_chaining);
62
63void
64imx_dma_config_burstlen(int channel, unsigned int burstlen);
65
66int
67imx_dma_setup_single(int channel, dma_addr_t dma_address,
68 unsigned int dma_length, unsigned int dev_addr,
69 unsigned int dmamode);
70
71
72/*
73 * Use this flag as the dma_length argument to imx_dma_setup_sg()
74 * to create an endless running dma loop. The end of the scatterlist
75 * must be linked to the beginning for this to work.
76 */
77#define IMX_DMA_LENGTH_LOOP ((unsigned int)-1)
78
79int
80imx_dma_setup_sg(int channel, struct scatterlist *sg,
81 unsigned int sgcount, unsigned int dma_length,
82 unsigned int dev_addr, unsigned int dmamode);
83
84int
85imx_dma_setup_handlers(int channel,
86 void (*irq_handler) (int, void *),
87 void (*err_handler) (int, void *, int), void *data);
88
89int
90imx_dma_setup_progression_handler(int channel,
91 void (*prog_handler) (int, void*, struct scatterlist*));
92
93void imx_dma_enable(int channel);
94
95void imx_dma_disable(int channel);
96
97int imx_dma_request(int channel, const char *name);
98
99void imx_dma_free(int channel);
100
101int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
102
103#endif /* __MACH_DMA_V1_H__ */
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
new file mode 100644
index 00000000000..b7c55e7db00
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 1999,2000 Arm Limited
3 * Copyright (C) 2000 Deep Blue Solutions Ltd
4 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
5 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 * - add MX31 specific definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/mm.h>
20#include <linux/init.h>
21#include <linux/err.h>
22
23#include <asm/pgtable.h>
24#include <asm/mach/map.h>
25
26#include <mach/common.h>
27#include <mach/devices-common.h>
28#include <mach/hardware.h>
29#include <mach/iomux-v3.h>
30#include <mach/irqs.h>
31
32static struct map_desc mx31_io_desc[] __initdata = {
33 imx_map_entry(MX31, X_MEMC, MT_DEVICE),
34 imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
35 imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
36 imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
37 imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
38};
39
40/*
41 * This function initializes the memory map. It is called during the
42 * system startup to create static physical to virtual memory mappings
43 * for the IO modules.
44 */
45void __init mx31_map_io(void)
46{
47 iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
48}
49
50void __init imx31_init_early(void)
51{
52 mxc_set_cpu_type(MXC_CPU_MX31);
53 mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
54}
55
56void __init mx31_init_irq(void)
57{
58 mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
59}
60
61static struct sdma_script_start_addrs imx31_to1_sdma_script __initdata = {
62 .per_2_per_addr = 1677,
63};
64
65static struct sdma_script_start_addrs imx31_to2_sdma_script __initdata = {
66 .ap_2_ap_addr = 423,
67 .ap_2_bp_addr = 829,
68 .bp_2_ap_addr = 1029,
69};
70
71static struct sdma_platform_data imx31_sdma_pdata __initdata = {
72 .fw_name = "sdma-imx31-to2.bin",
73 .script_addrs = &imx31_to2_sdma_script,
74};
75
76void __init imx31_soc_init(void)
77{
78 int to_version = mx31_revision() >> 4;
79
80 mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
81 mxc_register_gpio("imx31-gpio", 1, MX31_GPIO2_BASE_ADDR, SZ_16K, MX31_INT_GPIO2, 0);
82 mxc_register_gpio("imx31-gpio", 2, MX31_GPIO3_BASE_ADDR, SZ_16K, MX31_INT_GPIO3, 0);
83
84 if (to_version == 1) {
85 strncpy(imx31_sdma_pdata.fw_name, "sdma-imx31-to1.bin",
86 strlen(imx31_sdma_pdata.fw_name));
87 imx31_sdma_pdata.script_addrs = &imx31_to1_sdma_script;
88 }
89
90 imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
91}
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
new file mode 100644
index 00000000000..f49bac7a1ed
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -0,0 +1,109 @@
1/*
2 * Copyright (C) 1999,2000 Arm Limited
3 * Copyright (C) 2000 Deep Blue Solutions Ltd
4 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
5 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
6 * - add MX31 specific definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/mm.h>
20#include <linux/init.h>
21#include <linux/err.h>
22
23#include <asm/pgtable.h>
24#include <asm/mach/map.h>
25#include <asm/hardware/cache-l2x0.h>
26
27#include <mach/common.h>
28#include <mach/devices-common.h>
29#include <mach/hardware.h>
30#include <mach/iomux-v3.h>
31#include <mach/irqs.h>
32
33static struct map_desc mx35_io_desc[] __initdata = {
34 imx_map_entry(MX35, X_MEMC, MT_DEVICE),
35 imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
36 imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
37 imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
38 imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
39};
40
41void __init mx35_map_io(void)
42{
43 iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
44}
45
46void __init imx35_init_early(void)
47{
48 mxc_set_cpu_type(MXC_CPU_MX35);
49 mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
50 mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
51}
52
53void __init mx35_init_irq(void)
54{
55 mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
56}
57
58static struct sdma_script_start_addrs imx35_to1_sdma_script __initdata = {
59 .ap_2_ap_addr = 642,
60 .uart_2_mcu_addr = 817,
61 .mcu_2_app_addr = 747,
62 .uartsh_2_mcu_addr = 1183,
63 .per_2_shp_addr = 1033,
64 .mcu_2_shp_addr = 961,
65 .ata_2_mcu_addr = 1333,
66 .mcu_2_ata_addr = 1252,
67 .app_2_mcu_addr = 683,
68 .shp_2_per_addr = 1111,
69 .shp_2_mcu_addr = 892,
70};
71
72static struct sdma_script_start_addrs imx35_to2_sdma_script __initdata = {
73 .ap_2_ap_addr = 729,
74 .uart_2_mcu_addr = 904,
75 .per_2_app_addr = 1597,
76 .mcu_2_app_addr = 834,
77 .uartsh_2_mcu_addr = 1270,
78 .per_2_shp_addr = 1120,
79 .mcu_2_shp_addr = 1048,
80 .ata_2_mcu_addr = 1429,
81 .mcu_2_ata_addr = 1339,
82 .app_2_per_addr = 1531,
83 .app_2_mcu_addr = 770,
84 .shp_2_per_addr = 1198,
85 .shp_2_mcu_addr = 979,
86};
87
88static struct sdma_platform_data imx35_sdma_pdata __initdata = {
89 .fw_name = "sdma-imx35-to2.bin",
90 .script_addrs = &imx35_to2_sdma_script,
91};
92
93void __init imx35_soc_init(void)
94{
95 int to_version = mx35_revision() >> 4;
96
97 /* i.mx35 has the i.mx31 type gpio */
98 mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
99 mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
100 mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
101
102 if (to_version == 1) {
103 strncpy(imx35_sdma_pdata.fw_name, "sdma-imx35-to1.bin",
104 strlen(imx35_sdma_pdata.fw_name));
105 imx35_sdma_pdata.script_addrs = &imx35_to1_sdma_script;
106 }
107
108 imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
109}