aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx2/clock_imx27.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2009-02-16 09:13:43 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2009-03-13 05:33:51 -0400
commitedfcea80eb12b43680c4be0f2e31c8f5b1288edd (patch)
tree24e9c3863c1cbe9b8fb4fb2c5b6a067a7d7c0327 /arch/arm/mach-mx2/clock_imx27.c
parentd1755e3592305f8866b4d60d63a481959d5e58bf (diff)
[ARM] MX27 Clock rework
This changes MX27 to use common clkdev. It also cleans up MX27 clock support to be more readable. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx2/clock_imx27.c')
-rw-r--r--arch/arm/mach-mx2/clock_imx27.c1613
1 files changed, 384 insertions, 1229 deletions
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c
index 700a22f5ae88..3f7280c490f0 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-mx2/clock_imx27.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 3 * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
4 * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -20,23 +21,60 @@
20#include <linux/clk.h> 21#include <linux/clk.h>
21#include <linux/io.h> 22#include <linux/io.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/spinlock.h>
24 24
25#include <mach/clock.h> 25#include <asm/clkdev.h>
26#include <mach/common.h>
27#include <asm/div64.h> 26#include <asm/div64.h>
28 27
29#include "crm_regs.h" 28#include <mach/clock.h>
30 29#include <mach/common.h>
31static struct clk ckil_clk; 30#include <mach/hardware.h>
32static struct clk mpll_clk; 31
33static struct clk mpll_main_clk[]; 32/* Register offsets */
34static struct clk spll_clk; 33#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0)
35 34#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4)
36static int _clk_enable(struct clk *clk) 35#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8)
36#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC)
37#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10)
38#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14)
39#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18)
40#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c)
41#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20)
42#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24)
43#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28)
44#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c)
45#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30)
46#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34)
47
48#define CCM_CSCR_UPDATE_DIS (1 << 31)
49#define CCM_CSCR_SSI2 (1 << 23)
50#define CCM_CSCR_SSI1 (1 << 22)
51#define CCM_CSCR_VPU (1 << 21)
52#define CCM_CSCR_MSHC (1 << 20)
53#define CCM_CSCR_SPLLRES (1 << 19)
54#define CCM_CSCR_MPLLRES (1 << 18)
55#define CCM_CSCR_SP (1 << 17)
56#define CCM_CSCR_MCU (1 << 16)
57#define CCM_CSCR_OSC26MDIV (1 << 4)
58#define CCM_CSCR_OSC26M (1 << 3)
59#define CCM_CSCR_FPM (1 << 2)
60#define CCM_CSCR_SPEN (1 << 1)
61#define CCM_CSCR_MPEN (1 << 0)
62
63/* i.MX27 TO 2+ */
64#define CCM_CSCR_ARM_SRC (1 << 15)
65
66#define CCM_SPCTL1_LF (1 << 15)
67#define CCM_SPCTL1_BRMO (1 << 6)
68
69static struct clk mpll_main1_clk, mpll_main2_clk;
70
71static int clk_pccr_enable(struct clk *clk)
37{ 72{
38 unsigned long reg; 73 unsigned long reg;
39 74
75 if (!clk->enable_reg)
76 return 0;
77
40 reg = __raw_readl(clk->enable_reg); 78 reg = __raw_readl(clk->enable_reg);
41 reg |= 1 << clk->enable_shift; 79 reg |= 1 << clk->enable_shift;
42 __raw_writel(reg, clk->enable_reg); 80 __raw_writel(reg, clk->enable_reg);
@@ -44,16 +82,19 @@ static int _clk_enable(struct clk *clk)
44 return 0; 82 return 0;
45} 83}
46 84
47static void _clk_disable(struct clk *clk) 85static void clk_pccr_disable(struct clk *clk)
48{ 86{
49 unsigned long reg; 87 unsigned long reg;
50 88
89 if (!clk->enable_reg)
90 return;
91
51 reg = __raw_readl(clk->enable_reg); 92 reg = __raw_readl(clk->enable_reg);
52 reg &= ~(1 << clk->enable_shift); 93 reg &= ~(1 << clk->enable_shift);
53 __raw_writel(reg, clk->enable_reg); 94 __raw_writel(reg, clk->enable_reg);
54} 95}
55 96
56static int _clk_spll_enable(struct clk *clk) 97static int clk_spll_enable(struct clk *clk)
57{ 98{
58 unsigned long reg; 99 unsigned long reg;
59 100
@@ -61,13 +102,12 @@ static int _clk_spll_enable(struct clk *clk)
61 reg |= CCM_CSCR_SPEN; 102 reg |= CCM_CSCR_SPEN;
62 __raw_writel(reg, CCM_CSCR); 103 __raw_writel(reg, CCM_CSCR);
63 104
64 while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) 105 while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF));
65 ;
66 106
67 return 0; 107 return 0;
68} 108}
69 109
70static void _clk_spll_disable(struct clk *clk) 110static void clk_spll_disable(struct clk *clk)
71{ 111{
72 unsigned long reg; 112 unsigned long reg;
73 113
@@ -76,192 +116,30 @@ static void _clk_spll_disable(struct clk *clk)
76 __raw_writel(reg, CCM_CSCR); 116 __raw_writel(reg, CCM_CSCR);
77} 117}
78 118
79static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1) 119static int clk_cpu_set_parent(struct clk *clk, struct clk *parent)
80{
81 unsigned long reg;
82
83 reg = __raw_readl(CCM_PCCR0);
84 reg |= mask0;
85 __raw_writel(reg, CCM_PCCR0);
86
87 reg = __raw_readl(CCM_PCCR1);
88 reg |= mask1;
89 __raw_writel(reg, CCM_PCCR1);
90
91}
92
93static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
94{
95 unsigned long reg;
96
97 reg = __raw_readl(CCM_PCCR0);
98 reg &= ~mask0;
99 __raw_writel(reg, CCM_PCCR0);
100
101 reg = __raw_readl(CCM_PCCR1);
102 reg &= ~mask1;
103 __raw_writel(reg, CCM_PCCR1);
104}
105
106static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
107{
108 unsigned long reg;
109
110 reg = __raw_readl(CCM_PCCR1);
111 reg |= mask1;
112 __raw_writel(reg, CCM_PCCR1);
113
114 reg = __raw_readl(CCM_PCCR0);
115 reg |= mask0;
116 __raw_writel(reg, CCM_PCCR0);
117}
118
119static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
120{
121 unsigned long reg;
122
123 reg = __raw_readl(CCM_PCCR1);
124 reg &= ~mask1;
125 __raw_writel(reg, CCM_PCCR1);
126
127 reg = __raw_readl(CCM_PCCR0);
128 reg &= ~mask0;
129 __raw_writel(reg, CCM_PCCR0);
130}
131
132static int _clk_dma_enable(struct clk *clk)
133{
134 _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
135
136 return 0;
137}
138
139static void _clk_dma_disable(struct clk *clk)
140{
141 _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
142}
143
144static int _clk_rtic_enable(struct clk *clk)
145{
146 _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
147
148 return 0;
149}
150
151static void _clk_rtic_disable(struct clk *clk)
152{
153 _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
154}
155
156static int _clk_emma_enable(struct clk *clk)
157{
158 _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
159
160 return 0;
161}
162
163static void _clk_emma_disable(struct clk *clk)
164{
165 _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
166}
167
168static int _clk_slcdc_enable(struct clk *clk)
169{
170 _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
171
172 return 0;
173}
174
175static void _clk_slcdc_disable(struct clk *clk)
176{
177 _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
178}
179
180static int _clk_fec_enable(struct clk *clk)
181{
182 _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
183
184 return 0;
185}
186
187static void _clk_fec_disable(struct clk *clk)
188{
189 _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
190}
191
192static int _clk_vpu_enable(struct clk *clk)
193{
194 unsigned long reg;
195
196 reg = __raw_readl(CCM_PCCR1);
197 reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
198 __raw_writel(reg, CCM_PCCR1);
199
200 return 0;
201}
202
203static void _clk_vpu_disable(struct clk *clk)
204{
205 unsigned long reg;
206
207 reg = __raw_readl(CCM_PCCR1);
208 reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
209 __raw_writel(reg, CCM_PCCR1);
210}
211
212static int _clk_sahara2_enable(struct clk *clk)
213{
214 _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
215
216 return 0;
217}
218
219static void _clk_sahara2_disable(struct clk *clk)
220{
221 _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
222}
223
224static int _clk_mstick1_enable(struct clk *clk)
225{
226 _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
227
228 return 0;
229}
230
231static void _clk_mstick1_disable(struct clk *clk)
232{ 120{
233 _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); 121 int cscr = __raw_readl(CCM_CSCR);
234}
235
236#define CSCR() (__raw_readl(CCM_CSCR))
237#define PCDR0() (__raw_readl(CCM_PCDR0))
238#define PCDR1() (__raw_readl(CCM_PCDR1))
239
240static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
241{
242 int cscr = CSCR();
243 122
244 if (clk->parent == parent) 123 if (clk->parent == parent)
245 return 0; 124 return 0;
246 125
247 if (mx27_revision() >= CHIP_REV_2_0) { 126 if (mx27_revision() >= CHIP_REV_2_0) {
248 if (parent == &mpll_main_clk[0]) { 127 if (parent == &mpll_main1_clk) {
249 cscr |= CCM_CSCR_ARM_SRC; 128 cscr |= CCM_CSCR_ARM_SRC;
250 } else { 129 } else {
251 if (parent == &mpll_main_clk[1]) 130 if (parent == &mpll_main2_clk)
252 cscr &= ~CCM_CSCR_ARM_SRC; 131 cscr &= ~CCM_CSCR_ARM_SRC;
253 else 132 else
254 return -EINVAL; 133 return -EINVAL;
255 } 134 }
256 __raw_writel(cscr, CCM_CSCR); 135 __raw_writel(cscr, CCM_CSCR);
257 } else 136 clk->parent = parent;
258 return -ENODEV; 137 return 0;
259 138 }
260 clk->parent = parent; 139 return -ENODEV;
261 return 0;
262} 140}
263 141
264static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) 142static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate)
265{ 143{
266 int div; 144 int div;
267 unsigned long parent_rate; 145 unsigned long parent_rate;
@@ -278,7 +156,7 @@ static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
278 return parent_rate / div; 156 return parent_rate / div;
279} 157}
280 158
281static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) 159static int set_rate_cpu(struct clk *clk, unsigned long rate)
282{ 160{
283 unsigned int div; 161 unsigned int div;
284 uint32_t reg; 162 uint32_t reg;
@@ -295,19 +173,18 @@ static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
295 173
296 reg = __raw_readl(CCM_CSCR); 174 reg = __raw_readl(CCM_CSCR);
297 if (mx27_revision() >= CHIP_REV_2_0) { 175 if (mx27_revision() >= CHIP_REV_2_0) {
298 reg &= ~CCM_CSCR_ARM_MASK; 176 reg &= ~(3 << 12);
299 reg |= div << CCM_CSCR_ARM_OFFSET; 177 reg |= div << 12;
300 reg &= ~0x06; 178 reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN);
301 __raw_writel(reg | 0x80000000, CCM_CSCR); 179 __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR);
302 } else { 180 } else {
303 printk(KERN_ERR "Cant set CPU frequency!\n"); 181 printk(KERN_ERR "Can't set CPU frequency!\n");
304 } 182 }
305 183
306 return 0; 184 return 0;
307} 185}
308 186
309static unsigned long _clk_perclkx_round_rate(struct clk *clk, 187static unsigned long round_rate_per(struct clk *clk, unsigned long rate)
310 unsigned long rate)
311{ 188{
312 u32 div; 189 u32 div;
313 unsigned long parent_rate; 190 unsigned long parent_rate;
@@ -324,7 +201,7 @@ static unsigned long _clk_perclkx_round_rate(struct clk *clk,
324 return parent_rate / div; 201 return parent_rate / div;
325} 202}
326 203
327static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) 204static int set_rate_per(struct clk *clk, unsigned long rate)
328{ 205{
329 u32 reg; 206 u32 reg;
330 u32 div; 207 u32 div;
@@ -340,84 +217,65 @@ static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
340 return -EINVAL; 217 return -EINVAL;
341 div--; 218 div--;
342 219
343 reg = 220 reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3));
344 __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
345 (clk->id << 3));
346 reg |= div << (clk->id << 3); 221 reg |= div << (clk->id << 3);
347 __raw_writel(reg, CCM_PCDR1); 222 __raw_writel(reg, CCM_PCDR1);
348 223
349 return 0; 224 return 0;
350} 225}
351 226
352static unsigned long _clk_usb_recalc(struct clk *clk) 227static unsigned long get_rate_usb(struct clk *clk)
353{ 228{
354 unsigned long usb_pdf; 229 unsigned long usb_pdf;
355 unsigned long parent_rate; 230 unsigned long parent_rate;
356 231
357 parent_rate = clk_get_rate(clk->parent); 232 parent_rate = clk_get_rate(clk->parent);
358 233
359 usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; 234 usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7;
360 235
361 return parent_rate / (usb_pdf + 1U); 236 return parent_rate / (usb_pdf + 1U);
362} 237}
363 238
364static unsigned long _clk_ssi1_recalc(struct clk *clk) 239static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf)
365{ 240{
366 unsigned long ssi1_pdf;
367 unsigned long parent_rate; 241 unsigned long parent_rate;
368 242
369 parent_rate = clk_get_rate(clk->parent); 243 parent_rate = clk_get_rate(clk->parent);
370 244
371 ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
372 CCM_PCDR0_SSI1BAUDDIV_OFFSET;
373
374 if (mx27_revision() >= CHIP_REV_2_0) 245 if (mx27_revision() >= CHIP_REV_2_0)
375 ssi1_pdf += 4; 246 pdf += 4; /* MX27 TO2+ */
376 else 247 else
377 ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf; 248 pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */
378 249
379 return 2UL * parent_rate / ssi1_pdf; 250 return 2UL * parent_rate / pdf;
380} 251}
381 252
382static unsigned long _clk_ssi2_recalc(struct clk *clk) 253static unsigned long get_rate_ssi1(struct clk *clk)
383{ 254{
384 unsigned long ssi2_pdf; 255 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f);
385 unsigned long parent_rate; 256}
386
387 parent_rate = clk_get_rate(clk->parent);
388
389 ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
390 CCM_PCDR0_SSI2BAUDDIV_OFFSET;
391
392 if (mx27_revision() >= CHIP_REV_2_0)
393 ssi2_pdf += 4;
394 else
395 ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf;
396 257
397 return 2UL * parent_rate / ssi2_pdf; 258static unsigned long get_rate_ssi2(struct clk *clk)
259{
260 return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f);
398} 261}
399 262
400static unsigned long _clk_nfc_recalc(struct clk *clk) 263static unsigned long get_rate_nfc(struct clk *clk)
401{ 264{
402 unsigned long nfc_pdf; 265 unsigned long nfc_pdf;
403 unsigned long parent_rate; 266 unsigned long parent_rate;
404 267
405 parent_rate = clk_get_rate(clk->parent); 268 parent_rate = clk_get_rate(clk->parent);
406 269
407 if (mx27_revision() >= CHIP_REV_2_0) { 270 if (mx27_revision() >= CHIP_REV_2_0)
408 nfc_pdf = 271 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf;
409 (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >> 272 else
410 CCM_PCDR0_NFCDIV2_OFFSET; 273 nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf;
411 } else {
412 nfc_pdf =
413 (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
414 CCM_PCDR0_NFCDIV_OFFSET;
415 }
416 274
417 return parent_rate / (nfc_pdf + 1); 275 return parent_rate / (nfc_pdf + 1);
418} 276}
419 277
420static unsigned long _clk_vpu_recalc(struct clk *clk) 278static unsigned long get_rate_vpu(struct clk *clk)
421{ 279{
422 unsigned long vpu_pdf; 280 unsigned long vpu_pdf;
423 unsigned long parent_rate; 281 unsigned long parent_rate;
@@ -425,25 +283,27 @@ static unsigned long _clk_vpu_recalc(struct clk *clk)
425 parent_rate = clk_get_rate(clk->parent); 283 parent_rate = clk_get_rate(clk->parent);
426 284
427 if (mx27_revision() >= CHIP_REV_2_0) { 285 if (mx27_revision() >= CHIP_REV_2_0) {
428 vpu_pdf = 286 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f;
429 (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
430 CCM_PCDR0_VPUDIV2_OFFSET;
431 vpu_pdf += 4; 287 vpu_pdf += 4;
432 } else { 288 } else {
433 vpu_pdf = 289 vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf;
434 (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
435 CCM_PCDR0_VPUDIV_OFFSET;
436 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; 290 vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
437 } 291 }
292
438 return 2UL * parent_rate / vpu_pdf; 293 return 2UL * parent_rate / vpu_pdf;
439} 294}
440 295
441static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) 296static unsigned long round_rate_parent(struct clk *clk, unsigned long rate)
442{ 297{
443 return clk->parent->round_rate(clk->parent, rate); 298 return clk->parent->round_rate(clk->parent, rate);
444} 299}
445 300
446static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) 301static unsigned long get_rate_parent(struct clk *clk)
302{
303 return clk_get_rate(clk->parent);
304}
305
306static int set_rate_parent(struct clk *clk, unsigned long rate)
447{ 307{
448 return clk->parent->set_rate(clk->parent, rate); 308 return clk->parent->set_rate(clk->parent, rate);
449} 309}
@@ -451,94 +311,52 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
451/* in Hz */ 311/* in Hz */
452static unsigned long external_high_reference = 26000000; 312static unsigned long external_high_reference = 26000000;
453 313
454static unsigned long get_high_reference_clock_rate(struct clk *clk) 314static unsigned long get_rate_high_reference(struct clk *clk)
455{ 315{
456 return external_high_reference; 316 return external_high_reference;
457} 317}
458 318
459/*
460 * the high frequency external clock reference
461 * Default case is 26MHz. Could be changed at runtime
462 * with a call to change_external_high_reference()
463 */
464static struct clk ckih_clk = {
465 .name = "ckih",
466 .get_rate = get_high_reference_clock_rate,
467};
468
469/* in Hz */ 319/* in Hz */
470static unsigned long external_low_reference = 32768; 320static unsigned long external_low_reference = 32768;
471 321
472static unsigned long get_low_reference_clock_rate(struct clk *clk) 322static unsigned long get_rate_low_reference(struct clk *clk)
473{ 323{
474 return external_low_reference; 324 return external_low_reference;
475} 325}
476 326
477/* 327static unsigned long get_rate_fpm(struct clk *clk)
478 * the low frequency external clock reference 328{
479 * Default case is 32.768kHz Could be changed at runtime 329 return clk_get_rate(clk->parent) * 1024;
480 * with a call to change_external_low_reference() 330}
481 */
482static struct clk ckil_clk = {
483 .name = "ckil",
484 .get_rate = get_low_reference_clock_rate,
485};
486 331
487static unsigned long get_mpll_clk(struct clk *clk) 332static unsigned long get_rate_mpll(struct clk *clk)
488{ 333{
489 return mxc_decode_pll(__raw_readl(CCM_MPCTL0), 334 return mxc_decode_pll(__raw_readl(CCM_MPCTL0),
490 clk_get_rate(clk->parent)); 335 clk_get_rate(clk->parent));
491} 336}
492 337
493static struct clk mpll_clk = { 338static unsigned long get_rate_mpll_main(struct clk *clk)
494 .name = "mpll",
495 .parent = &ckih_clk,
496 .get_rate = get_mpll_clk,
497};
498
499static unsigned long _clk_mpll_main_get_rate(struct clk *clk)
500{ 339{
501 unsigned long parent_rate; 340 unsigned long parent_rate;
502 341
503 parent_rate = clk_get_rate(clk->parent); 342 parent_rate = clk_get_rate(clk->parent);
504 343
505 /* i.MX27 TO2: 344 /* i.MX27 TO2:
506 * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2 345 * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2
507 * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3 346 * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3
508 */ 347 */
509
510 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1) 348 if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1)
511 return 2UL * parent_rate / 3UL; 349 return 2UL * parent_rate / 3UL;
512 350
513 return parent_rate; 351 return parent_rate;
514} 352}
515 353
516static struct clk mpll_main_clk[] = { 354static unsigned long get_rate_spll(struct clk *clk)
517 {
518 /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
519 * It provide the clock source whose rate is same as MPLL
520 */
521 .name = "mpll_main",
522 .id = 0,
523 .parent = &mpll_clk,
524 .get_rate = _clk_mpll_main_get_rate
525 }, {
526 /* For i.MX27 TO2, it is the MPLL path 2 of ARM core
527 * It provide the clock source whose rate is same MPLL * 2/3
528 */
529 .name = "mpll_main",
530 .id = 1,
531 .parent = &mpll_clk,
532 .get_rate = _clk_mpll_main_get_rate
533 }
534};
535
536static unsigned long get_spll_clk(struct clk *clk)
537{ 355{
538 uint32_t reg; 356 uint32_t reg;
539 unsigned long ref_clk; 357 unsigned long rate;
540 358
541 ref_clk = clk_get_rate(clk->parent); 359 rate = clk_get_rate(clk->parent);
542 360
543 reg = __raw_readl(CCM_SPCTL0); 361 reg = __raw_readl(CCM_SPCTL0);
544 362
@@ -548,987 +366,325 @@ static unsigned long get_spll_clk(struct clk *clk)
548 if (mx27_revision() >= CHIP_REV_2_0) 366 if (mx27_revision() >= CHIP_REV_2_0)
549 __raw_writel(reg, CCM_SPCTL0); 367 __raw_writel(reg, CCM_SPCTL0);
550 368
551 return mxc_decode_pll(reg, ref_clk); 369 return mxc_decode_pll(reg, rate);
552} 370}
553 371
554static struct clk spll_clk = { 372static unsigned long get_rate_cpu(struct clk *clk)
555 .name = "spll",
556 .parent = &ckih_clk,
557 .get_rate = get_spll_clk,
558 .enable = _clk_spll_enable,
559 .disable = _clk_spll_disable,
560};
561
562static unsigned long get_cpu_clk(struct clk *clk)
563{ 373{
564 u32 div; 374 u32 div;
565 unsigned long rate; 375 unsigned long rate;
566 376
567 if (mx27_revision() >= CHIP_REV_2_0) 377 if (mx27_revision() >= CHIP_REV_2_0)
568 div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET; 378 div = (__raw_readl(CCM_CSCR) >> 12) & 0x3;
569 else 379 else
570 div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; 380 div = (__raw_readl(CCM_CSCR) >> 13) & 0x7;
571 381
572 rate = clk_get_rate(clk->parent); 382 rate = clk_get_rate(clk->parent);
573 return rate / (div + 1); 383 return rate / (div + 1);
574} 384}
575 385
576static struct clk cpu_clk = { 386static unsigned long get_rate_ahb(struct clk *clk)
577 .name = "cpu_clk",
578 .parent = &mpll_main_clk[1],
579 .set_parent = _clk_cpu_set_parent,
580 .round_rate = _clk_cpu_round_rate,
581 .get_rate = get_cpu_clk,
582 .set_rate = _clk_cpu_set_rate,
583};
584
585static unsigned long get_ahb_clk(struct clk *clk)
586{ 387{
587 unsigned long rate; 388 unsigned long rate, bclk_pdf;
588 unsigned long bclk_pdf;
589 389
590 if (mx27_revision() >= CHIP_REV_2_0) 390 if (mx27_revision() >= CHIP_REV_2_0)
591 bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) 391 bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3;
592 >> CCM_CSCR_AHB_OFFSET;
593 else 392 else
594 bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) 393 bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf;
595 >> CCM_CSCR_BCLK_OFFSET;
596 394
597 rate = clk_get_rate(clk->parent); 395 rate = clk_get_rate(clk->parent);
598 return rate / (bclk_pdf + 1); 396 return rate / (bclk_pdf + 1);
599} 397}
600 398
601static struct clk ahb_clk = { 399static unsigned long get_rate_ipg(struct clk *clk)
602 .name = "ahb_clk",
603 .parent = &mpll_main_clk[1],
604 .get_rate = get_ahb_clk,
605};
606
607static unsigned long get_ipg_clk(struct clk *clk)
608{ 400{
609 unsigned long rate; 401 unsigned long rate, ipg_pdf;
610 unsigned long ipg_pdf;
611 402
612 if (mx27_revision() >= CHIP_REV_2_0) 403 if (mx27_revision() >= CHIP_REV_2_0)
613 return clk_get_rate(clk->parent); 404 return clk_get_rate(clk->parent);
614 else 405 else
615 ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; 406 ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1;
616 407
617 rate = clk_get_rate(clk->parent); 408 rate = clk_get_rate(clk->parent);
618 return rate / (ipg_pdf + 1); 409 return rate / (ipg_pdf + 1);
619} 410}
620 411
621static struct clk ipg_clk = { 412static unsigned long get_rate_per(struct clk *clk)
622 .name = "ipg_clk",
623 .parent = &ahb_clk,
624 .get_rate = get_ipg_clk,
625};
626
627static unsigned long _clk_perclkx_recalc(struct clk *clk)
628{ 413{
629 unsigned long perclk_pdf; 414 unsigned long perclk_pdf, parent_rate;
630 unsigned long parent_rate;
631 415
632 parent_rate = clk_get_rate(clk->parent); 416 parent_rate = clk_get_rate(clk->parent);
633 417
634 if (clk->id < 0 || clk->id > 3) 418 if (clk->id < 0 || clk->id > 3)
635 return 0; 419 return 0;
636 420
637 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; 421 perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f;
638 422
639 return parent_rate / (perclk_pdf + 1); 423 return parent_rate / (perclk_pdf + 1);
640} 424}
641 425
642static struct clk per_clk[] = { 426/*
643 { 427 * the high frequency external clock reference
644 .name = "per_clk", 428 * Default case is 26MHz. Could be changed at runtime
645 .id = 0, 429 * with a call to change_external_high_reference()
646 .parent = &mpll_main_clk[1], 430 */
647 .get_rate = _clk_perclkx_recalc, 431static struct clk ckih_clk = {
648 .enable = _clk_enable, 432 .get_rate = get_rate_high_reference,
649 .enable_reg = CCM_PCCR1,
650 .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
651 .disable = _clk_disable,
652 }, {
653 .name = "per_clk",
654 .id = 1,
655 .parent = &mpll_main_clk[1],
656 .get_rate = _clk_perclkx_recalc,
657 .enable = _clk_enable,
658 .enable_reg = CCM_PCCR1,
659 .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
660 .disable = _clk_disable,
661 }, {
662 .name = "per_clk",
663 .id = 2,
664 .parent = &mpll_main_clk[1],
665 .round_rate = _clk_perclkx_round_rate,
666 .set_rate = _clk_perclkx_set_rate,
667 .get_rate = _clk_perclkx_recalc,
668 .enable = _clk_enable,
669 .enable_reg = CCM_PCCR1,
670 .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
671 .disable = _clk_disable,
672 }, {
673 .name = "per_clk",
674 .id = 3,
675 .parent = &mpll_main_clk[1],
676 .round_rate = _clk_perclkx_round_rate,
677 .set_rate = _clk_perclkx_set_rate,
678 .get_rate = _clk_perclkx_recalc,
679 .enable = _clk_enable,
680 .enable_reg = CCM_PCCR1,
681 .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
682 .disable = _clk_disable,
683 },
684};
685
686struct clk uart1_clk[] = {
687 {
688 .name = "uart",
689 .id = 0,
690 .parent = &per_clk[0],
691 .secondary = &uart1_clk[1],
692 }, {
693 .name = "uart_ipg_clk",
694 .id = 0,
695 .parent = &ipg_clk,
696 .enable = _clk_enable,
697 .enable_reg = CCM_PCCR1,
698 .enable_shift = CCM_PCCR1_UART1_OFFSET,
699 .disable = _clk_disable,
700 },
701};
702
703struct clk uart2_clk[] = {
704 {
705 .name = "uart",
706 .id = 1,
707 .parent = &per_clk[0],
708 .secondary = &uart2_clk[1],
709 }, {
710 .name = "uart_ipg_clk",
711 .id = 1,
712 .parent = &ipg_clk,
713 .enable = _clk_enable,
714 .enable_reg = CCM_PCCR1,
715 .enable_shift = CCM_PCCR1_UART2_OFFSET,
716 .disable = _clk_disable,
717 },
718};
719
720struct clk uart3_clk[] = {
721 {
722 .name = "uart",
723 .id = 2,
724 .parent = &per_clk[0],
725 .secondary = &uart3_clk[1],
726 }, {
727 .name = "uart_ipg_clk",
728 .id = 2,
729 .parent = &ipg_clk,
730 .enable = _clk_enable,
731 .enable_reg = CCM_PCCR1,
732 .enable_shift = CCM_PCCR1_UART3_OFFSET,
733 .disable = _clk_disable,
734 },
735};
736
737struct clk uart4_clk[] = {
738 {
739 .name = "uart",
740 .id = 3,
741 .parent = &per_clk[0],
742 .secondary = &uart4_clk[1],
743 }, {
744 .name = "uart_ipg_clk",
745 .id = 3,
746 .parent = &ipg_clk,
747 .enable = _clk_enable,
748 .enable_reg = CCM_PCCR1,
749 .enable_shift = CCM_PCCR1_UART4_OFFSET,
750 .disable = _clk_disable,
751 },
752};
753
754struct clk uart5_clk[] = {
755 {
756 .name = "uart",
757 .id = 4,
758 .parent = &per_clk[0],
759 .secondary = &uart5_clk[1],
760 }, {
761 .name = "uart_ipg_clk",
762 .id = 4,
763 .parent = &ipg_clk,
764 .enable = _clk_enable,
765 .enable_reg = CCM_PCCR1,
766 .enable_shift = CCM_PCCR1_UART5_OFFSET,
767 .disable = _clk_disable,
768 },
769};
770
771struct clk uart6_clk[] = {
772 {
773 .name = "uart",
774 .id = 5,
775 .parent = &per_clk[0],
776 .secondary = &uart6_clk[1],
777 }, {
778 .name = "uart_ipg_clk",
779 .id = 5,
780 .parent = &ipg_clk,
781 .enable = _clk_enable,
782 .enable_reg = CCM_PCCR1,
783 .enable_shift = CCM_PCCR1_UART6_OFFSET,
784 .disable = _clk_disable,
785 },
786};
787
788static struct clk gpt1_clk[] = {
789 {
790 .name = "gpt_clk",
791 .id = 0,
792 .parent = &per_clk[0],
793 .secondary = &gpt1_clk[1],
794 }, {
795 .name = "gpt_ipg_clk",
796 .id = 0,
797 .parent = &ipg_clk,
798 .enable = _clk_enable,
799 .enable_reg = CCM_PCCR0,
800 .enable_shift = CCM_PCCR0_GPT1_OFFSET,
801 .disable = _clk_disable,
802 },
803};
804
805static struct clk gpt2_clk[] = {
806 {
807 .name = "gpt_clk",
808 .id = 1,
809 .parent = &per_clk[0],
810 .secondary = &gpt2_clk[1],
811 }, {
812 .name = "gpt_ipg_clk",
813 .id = 1,
814 .parent = &ipg_clk,
815 .enable = _clk_enable,
816 .enable_reg = CCM_PCCR0,
817 .enable_shift = CCM_PCCR0_GPT2_OFFSET,
818 .disable = _clk_disable,
819 },
820};
821
822static struct clk gpt3_clk[] = {
823 {
824 .name = "gpt_clk",
825 .id = 2,
826 .parent = &per_clk[0],
827 .secondary = &gpt3_clk[1],
828 }, {
829 .name = "gpt_ipg_clk",
830 .id = 2,
831 .parent = &ipg_clk,
832 .enable = _clk_enable,
833 .enable_reg = CCM_PCCR0,
834 .enable_shift = CCM_PCCR0_GPT3_OFFSET,
835 .disable = _clk_disable,
836 },
837};
838
839static struct clk gpt4_clk[] = {
840 {
841 .name = "gpt_clk",
842 .id = 3,
843 .parent = &per_clk[0],
844 .secondary = &gpt4_clk[1],
845 }, {
846 .name = "gpt_ipg_clk",
847 .id = 3,
848 .parent = &ipg_clk,
849 .enable = _clk_enable,
850 .enable_reg = CCM_PCCR0,
851 .enable_shift = CCM_PCCR0_GPT4_OFFSET,
852 .disable = _clk_disable,
853 },
854};
855
856static struct clk gpt5_clk[] = {
857 {
858 .name = "gpt_clk",
859 .id = 4,
860 .parent = &per_clk[0],
861 .secondary = &gpt5_clk[1],
862 }, {
863 .name = "gpt_ipg_clk",
864 .id = 4,
865 .parent = &ipg_clk,
866 .enable = _clk_enable,
867 .enable_reg = CCM_PCCR0,
868 .enable_shift = CCM_PCCR0_GPT5_OFFSET,
869 .disable = _clk_disable,
870 },
871}; 433};
872 434
873static struct clk gpt6_clk[] = { 435static struct clk mpll_clk = {
874 { 436 .parent = &ckih_clk,
875 .name = "gpt_clk", 437 .get_rate = get_rate_mpll,
876 .id = 5,
877 .parent = &per_clk[0],
878 .secondary = &gpt6_clk[1],
879 }, {
880 .name = "gpt_ipg_clk",
881 .id = 5,
882 .parent = &ipg_clk,
883 .enable = _clk_enable,
884 .enable_reg = CCM_PCCR0,
885 .enable_shift = CCM_PCCR0_GPT6_OFFSET,
886 .disable = _clk_disable,
887 },
888}; 438};
889 439
890static struct clk pwm_clk[] = { 440/* For i.MX27 TO2, it is the MPLL path 1 of ARM core
891 { 441 * It provides the clock source whose rate is same as MPLL
892 .name = "pwm_clk", 442 */
893 .parent = &per_clk[0], 443static struct clk mpll_main1_clk = {
894 .secondary = &pwm_clk[1], 444 .id = 0,
895 }, { 445 .parent = &mpll_clk,
896 .name = "pwm_clk", 446 .get_rate = get_rate_mpll_main,
897 .parent = &ipg_clk,
898 .enable = _clk_enable,
899 .enable_reg = CCM_PCCR0,
900 .enable_shift = CCM_PCCR0_PWM_OFFSET,
901 .disable = _clk_disable,
902 },
903}; 447};
904 448
905static struct clk sdhc1_clk[] = { 449/* For i.MX27 TO2, it is the MPLL path 2 of ARM core
906 { 450 * It provides the clock source whose rate is same MPLL * 2 / 3
907 .name = "sdhc_clk", 451 */
908 .id = 0, 452static struct clk mpll_main2_clk = {
909 .parent = &per_clk[1], 453 .id = 1,
910 .secondary = &sdhc1_clk[1], 454 .parent = &mpll_clk,
911 }, { 455 .get_rate = get_rate_mpll_main,
912 .name = "sdhc_ipg_clk",
913 .id = 0,
914 .parent = &ipg_clk,
915 .enable = _clk_enable,
916 .enable_reg = CCM_PCCR0,
917 .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
918 .disable = _clk_disable,
919 },
920}; 456};
921 457
922static struct clk sdhc2_clk[] = { 458static struct clk ahb_clk = {
923 { 459 .parent = &mpll_main2_clk,
924 .name = "sdhc_clk", 460 .get_rate = get_rate_ahb,
925 .id = 1,
926 .parent = &per_clk[1],
927 .secondary = &sdhc2_clk[1],
928 }, {
929 .name = "sdhc_ipg_clk",
930 .id = 1,
931 .parent = &ipg_clk,
932 .enable = _clk_enable,
933 .enable_reg = CCM_PCCR0,
934 .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
935 .disable = _clk_disable,
936 },
937}; 461};
938 462
939static struct clk sdhc3_clk[] = { 463static struct clk ipg_clk = {
940 { 464 .parent = &ahb_clk,
941 .name = "sdhc_clk", 465 .get_rate = get_rate_ipg,
942 .id = 2,
943 .parent = &per_clk[1],
944 .secondary = &sdhc3_clk[1],
945 }, {
946 .name = "sdhc_ipg_clk",
947 .id = 2,
948 .parent = &ipg_clk,
949 .enable = _clk_enable,
950 .enable_reg = CCM_PCCR0,
951 .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
952 .disable = _clk_disable,
953 },
954}; 466};
955 467
956static struct clk cspi1_clk[] = { 468static struct clk cpu_clk = {
957 { 469 .parent = &mpll_main2_clk,
958 .name = "cspi_clk", 470 .set_parent = clk_cpu_set_parent,
959 .id = 0, 471 .round_rate = round_rate_cpu,
960 .parent = &per_clk[1], 472 .get_rate = get_rate_cpu,
961 .secondary = &cspi1_clk[1], 473 .set_rate = set_rate_cpu,
962 }, {
963 .name = "cspi_ipg_clk",
964 .id = 0,
965 .parent = &ipg_clk,
966 .enable = _clk_enable,
967 .enable_reg = CCM_PCCR0,
968 .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
969 .disable = _clk_disable,
970 },
971}; 474};
972 475
973static struct clk cspi2_clk[] = { 476static struct clk spll_clk = {
974 { 477 .parent = &ckih_clk,
975 .name = "cspi_clk", 478 .get_rate = get_rate_spll,
976 .id = 1, 479 .enable = clk_spll_enable,
977 .parent = &per_clk[1], 480 .disable = clk_spll_disable,
978 .secondary = &cspi2_clk[1],
979 }, {
980 .name = "cspi_ipg_clk",
981 .id = 1,
982 .parent = &ipg_clk,
983 .enable = _clk_enable,
984 .enable_reg = CCM_PCCR0,
985 .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
986 .disable = _clk_disable,
987 },
988}; 481};
989 482
990static struct clk cspi3_clk[] = { 483/*
991 { 484 * the low frequency external clock reference
992 .name = "cspi_clk", 485 * Default case is 32.768kHz.
993 .id = 2, 486 */
994 .parent = &per_clk[1], 487static struct clk ckil_clk = {
995 .secondary = &cspi3_clk[1], 488 .get_rate = get_rate_low_reference,
996 }, {
997 .name = "cspi_ipg_clk",
998 .id = 2,
999 .parent = &ipg_clk,
1000 .enable = _clk_enable,
1001 .enable_reg = CCM_PCCR0,
1002 .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
1003 .disable = _clk_disable,
1004 },
1005}; 489};
1006 490
1007static struct clk lcdc_clk[] = { 491/* Output of frequency pre multiplier */
1008 { 492static struct clk fpm_clk = {
1009 .name = "lcdc_clk", 493 .parent = &ckil_clk,
1010 .parent = &per_clk[2], 494 .get_rate = get_rate_fpm,
1011 .secondary = &lcdc_clk[1],
1012 .round_rate = _clk_parent_round_rate,
1013 .set_rate = _clk_parent_set_rate,
1014 }, {
1015 .name = "lcdc_ipg_clk",
1016 .parent = &ipg_clk,
1017 .secondary = &lcdc_clk[2],
1018 .enable = _clk_enable,
1019 .enable_reg = CCM_PCCR0,
1020 .enable_shift = CCM_PCCR0_LCDC_OFFSET,
1021 .disable = _clk_disable,
1022 }, {
1023 .name = "lcdc_ahb_clk",
1024 .parent = &ahb_clk,
1025 .enable = _clk_enable,
1026 .enable_reg = CCM_PCCR1,
1027 .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
1028 .disable = _clk_disable,
1029 },
1030}; 495};
1031 496
1032static struct clk csi_clk[] = { 497#define PCCR0 CCM_PCCR0
1033 { 498#define PCCR1 CCM_PCCR1
1034 .name = "csi_perclk",
1035 .parent = &per_clk[3],
1036 .secondary = &csi_clk[1],
1037 .round_rate = _clk_parent_round_rate,
1038 .set_rate = _clk_parent_set_rate,
1039 }, {
1040 .name = "csi_ahb_clk",
1041 .parent = &ahb_clk,
1042 .enable = _clk_enable,
1043 .enable_reg = CCM_PCCR1,
1044 .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
1045 .disable = _clk_disable,
1046 },
1047};
1048 499
1049static struct clk usb_clk[] = { 500#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \
1050 { 501 static struct clk name = { \
1051 .name = "usb_clk", 502 .id = i, \
1052 .parent = &spll_clk, 503 .enable_reg = er, \
1053 .get_rate = _clk_usb_recalc, 504 .enable_shift = es, \
1054 .enable = _clk_enable, 505 .get_rate = gr, \
1055 .enable_reg = CCM_PCCR1, 506 .enable = clk_pccr_enable, \
1056 .enable_shift = CCM_PCCR1_USBOTG_OFFSET, 507 .disable = clk_pccr_disable, \
1057 .disable = _clk_disable, 508 .secondary = s, \
1058 }, { 509 .parent = p, \
1059 .name = "usb_ahb_clk",
1060 .parent = &ahb_clk,
1061 .enable = _clk_enable,
1062 .enable_reg = CCM_PCCR1,
1063 .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
1064 .disable = _clk_disable,
1065 } 510 }
1066};
1067
1068static struct clk ssi1_clk[] = {
1069 {
1070 .name = "ssi_clk",
1071 .id = 0,
1072 .parent = &mpll_main_clk[1],
1073 .secondary = &ssi1_clk[1],
1074 .get_rate = _clk_ssi1_recalc,
1075 .enable = _clk_enable,
1076 .enable_reg = CCM_PCCR1,
1077 .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
1078 .disable = _clk_disable,
1079 }, {
1080 .name = "ssi_ipg_clk",
1081 .id = 0,
1082 .parent = &ipg_clk,
1083 .enable = _clk_enable,
1084 .enable_reg = CCM_PCCR0,
1085 .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
1086 .disable = _clk_disable,
1087 },
1088};
1089
1090static struct clk ssi2_clk[] = {
1091 {
1092 .name = "ssi_clk",
1093 .id = 1,
1094 .parent = &mpll_main_clk[1],
1095 .secondary = &ssi2_clk[1],
1096 .get_rate = _clk_ssi2_recalc,
1097 .enable = _clk_enable,
1098 .enable_reg = CCM_PCCR1,
1099 .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
1100 .disable = _clk_disable,
1101 }, {
1102 .name = "ssi_ipg_clk",
1103 .id = 1,
1104 .parent = &ipg_clk,
1105 .enable = _clk_enable,
1106 .enable_reg = CCM_PCCR0,
1107 .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
1108 .disable = _clk_disable,
1109 },
1110};
1111
1112static struct clk nfc_clk = {
1113 .name = "nfc",
1114 .parent = &cpu_clk,
1115 .get_rate = _clk_nfc_recalc,
1116 .enable = _clk_enable,
1117 .enable_reg = CCM_PCCR1,
1118 .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
1119 .disable = _clk_disable,
1120};
1121
1122static struct clk vpu_clk = {
1123 .name = "vpu_clk",
1124 .parent = &mpll_main_clk[1],
1125 .get_rate = _clk_vpu_recalc,
1126 .enable = _clk_vpu_enable,
1127 .disable = _clk_vpu_disable,
1128};
1129
1130static struct clk dma_clk = {
1131 .name = "dma",
1132 .parent = &ahb_clk,
1133 .enable = _clk_dma_enable,
1134 .disable = _clk_dma_disable,
1135};
1136
1137static struct clk rtic_clk = {
1138 .name = "rtic_clk",
1139 .parent = &ahb_clk,
1140 .enable = _clk_rtic_enable,
1141 .disable = _clk_rtic_disable,
1142};
1143 511
1144static struct clk brom_clk = { 512#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \
1145 .name = "brom_clk", 513 static struct clk name = { \
1146 .parent = &ahb_clk, 514 .id = i, \
1147 .enable = _clk_enable, 515 .enable_reg = er, \
1148 .enable_reg = CCM_PCCR1, 516 .enable_shift = es, \
1149 .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET, 517 .get_rate = get_rate_##getsetround, \
1150 .disable = _clk_disable, 518 .set_rate = set_rate_##getsetround, \
1151}; 519 .round_rate = round_rate_##getsetround, \
1152 520 .enable = clk_pccr_enable, \
1153static struct clk emma_clk = { 521 .disable = clk_pccr_disable, \
1154 .name = "emma_clk", 522 .secondary = s, \
1155 .parent = &ahb_clk, 523 .parent = p, \
1156 .enable = _clk_emma_enable, 524 }
1157 .disable = _clk_emma_disable,
1158};
1159
1160static struct clk slcdc_clk = {
1161 .name = "slcdc_clk",
1162 .parent = &ahb_clk,
1163 .enable = _clk_slcdc_enable,
1164 .disable = _clk_slcdc_disable,
1165};
1166
1167static struct clk fec_clk = {
1168 .name = "fec_clk",
1169 .parent = &ahb_clk,
1170 .enable = _clk_fec_enable,
1171 .disable = _clk_fec_disable,
1172};
1173
1174static struct clk emi_clk = {
1175 .name = "emi_clk",
1176 .parent = &ahb_clk,
1177 .enable = _clk_enable,
1178 .enable_reg = CCM_PCCR1,
1179 .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
1180 .disable = _clk_disable,
1181};
1182
1183static struct clk sahara2_clk = {
1184 .name = "sahara_clk",
1185 .parent = &ahb_clk,
1186 .enable = _clk_sahara2_enable,
1187 .disable = _clk_sahara2_disable,
1188};
1189
1190static struct clk ata_clk = {
1191 .name = "ata_clk",
1192 .parent = &ahb_clk,
1193 .enable = _clk_enable,
1194 .enable_reg = CCM_PCCR1,
1195 .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
1196 .disable = _clk_disable,
1197};
1198
1199static struct clk mstick1_clk = {
1200 .name = "mstick1_clk",
1201 .parent = &ipg_clk,
1202 .enable = _clk_mstick1_enable,
1203 .disable = _clk_mstick1_disable,
1204};
1205
1206static struct clk wdog_clk = {
1207 .name = "wdog_clk",
1208 .parent = &ipg_clk,
1209 .enable = _clk_enable,
1210 .enable_reg = CCM_PCCR1,
1211 .enable_shift = CCM_PCCR1_WDT_OFFSET,
1212 .disable = _clk_disable,
1213};
1214
1215static struct clk gpio_clk = {
1216 .name = "gpio_clk",
1217 .parent = &ipg_clk,
1218 .enable = _clk_enable,
1219 .enable_reg = CCM_PCCR1,
1220 .enable_shift = CCM_PCCR0_GPIO_OFFSET,
1221 .disable = _clk_disable,
1222};
1223 525
1224static struct clk i2c_clk[] = { 526/* Forward declaration to keep the following list in order */
1225 { 527static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1,
1226 .name = "i2c_clk", 528 dma_clk1, lcdc_clk2, vpu_clk1;
1227 .id = 0, 529
1228 .parent = &ipg_clk, 530/* All clocks we can gate through PCCRx in the order of PCCRx bits */
1229 .enable = _clk_enable, 531DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk);
1230 .enable_reg = CCM_PCCR0, 532DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk);
1231 .enable_shift = CCM_PCCR0_I2C1_OFFSET, 533DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk);
1232 .disable = _clk_disable, 534DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk);
1233 }, { 535DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk);
1234 .name = "i2c_clk", 536DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk);
1235 .id = 1, 537DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk);
1236 .parent = &ipg_clk, 538DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk);
1237 .enable = _clk_enable, 539DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk);
1238 .enable_reg = CCM_PCCR0, 540DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk);
1239 .enable_shift = CCM_PCCR0_I2C2_OFFSET, 541DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk);
1240 .disable = _clk_disable, 542DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk);
543DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk);
544DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk);
545DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk);
546DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk);
547DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk);
548DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk);
549DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
550DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk);
551DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk);
552DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk);
553DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk);
554DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk);
555DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk);
556DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk);
557DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk);
558DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk);
559DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk);
560DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk);
561DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk);
562
563DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk);
564DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk);
565DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk);
566DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk);
567DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk);
568DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk);
569DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk);
570DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk);
571DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk);
572DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk);
573DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk);
574DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk);
575DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk);
576DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk);
577DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk);
578DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk);
579DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk);
580DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk);
581DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk);
582DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk);
583DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk);
584DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk);
585DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk);
586DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk);
587DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk);
588DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk);
589DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk);
590DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk);
591DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk);
592DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk);
593
594/* Clocks we cannot directly gate, but drivers need their rates */
595DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk);
596DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk);
597DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk);
598DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk);
599DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk);
600DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk);
601DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk);
602DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk);
603DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk);
604DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk);
605DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk);
606DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk);
607DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk);
608DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk);
609DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk);
610DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk);
611DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk);
612DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk);
613DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk);
614DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk);
615DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk);
616
617#define _REGISTER_CLOCK(d, n, c) \
618 { \
619 .dev_id = d, \
620 .con_id = n, \
621 .clk = &c, \
1241 }, 622 },
1242};
1243 623
1244static struct clk iim_clk = { 624static struct clk_lookup lookups[] __initdata = {
1245 .name = "iim_clk", 625 _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
1246 .parent = &ipg_clk, 626 _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
1247 .enable = _clk_enable, 627 _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
1248 .enable_reg = CCM_PCCR0, 628 _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
1249 .enable_shift = CCM_PCCR0_IIM_OFFSET, 629 _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
1250 .disable = _clk_disable, 630 _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk)
1251}; 631 _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk)
1252 632 _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk)
1253static struct clk kpp_clk = { 633 _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk)
1254 .name = "kpp_clk", 634 _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk)
1255 .parent = &ipg_clk, 635 _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk)
1256 .enable = _clk_enable, 636 _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk)
1257 .enable_reg = CCM_PCCR0, 637 _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk)
1258 .enable_shift = CCM_PCCR0_KPP_OFFSET, 638 _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk)
1259 .disable = _clk_disable, 639 _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk)
1260}; 640 _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk)
1261 641 _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk)
1262static struct clk owire_clk = { 642 _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk)
1263 .name = "owire", 643 _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk)
1264 .parent = &ipg_clk, 644 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
1265 .enable = _clk_enable, 645 _REGISTER_CLOCK(NULL, "csi", csi_clk)
1266 .enable_reg = CCM_PCCR0, 646 _REGISTER_CLOCK(NULL, "usb", usb_clk)
1267 .enable_shift = CCM_PCCR0_OWIRE_OFFSET, 647 _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk)
1268 .disable = _clk_disable, 648 _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk)
1269}; 649 _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
1270 650 _REGISTER_CLOCK(NULL, "vpu", vpu_clk)
1271static struct clk rtc_clk = { 651 _REGISTER_CLOCK(NULL, "dma", dma_clk)
1272 .name = "rtc_clk", 652 _REGISTER_CLOCK(NULL, "rtic", rtic_clk)
1273 .parent = &ipg_clk, 653 _REGISTER_CLOCK(NULL, "brom", brom_clk)
1274 .enable = _clk_enable, 654 _REGISTER_CLOCK(NULL, "emma", emma_clk)
1275 .enable_reg = CCM_PCCR0, 655 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
1276 .enable_shift = CCM_PCCR0_RTC_OFFSET, 656 _REGISTER_CLOCK("fec.0", NULL, fec_clk)
1277 .disable = _clk_disable, 657 _REGISTER_CLOCK(NULL, "emi", emi_clk)
1278}; 658 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
1279 659 _REGISTER_CLOCK(NULL, "ata", ata_clk)
1280static struct clk scc_clk = { 660 _REGISTER_CLOCK(NULL, "mstick", mstick_clk)
1281 .name = "scc_clk", 661 _REGISTER_CLOCK(NULL, "wdog", wdog_clk)
1282 .parent = &ipg_clk, 662 _REGISTER_CLOCK(NULL, "gpio", gpio_clk)
1283 .enable = _clk_enable, 663 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1284 .enable_reg = CCM_PCCR0, 664 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
1285 .enable_shift = CCM_PCCR0_SCC_OFFSET, 665 _REGISTER_CLOCK(NULL, "iim", iim_clk)
1286 .disable = _clk_disable, 666 _REGISTER_CLOCK(NULL, "kpp", kpp_clk)
1287}; 667 _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk)
1288 668 _REGISTER_CLOCK(NULL, "rtc", rtc_clk)
1289static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) 669 _REGISTER_CLOCK(NULL, "scc", scc_clk)
1290{ 670};
1291 u32 div; 671
1292 unsigned long parent_rate; 672/* Adjust the clock path for TO2 and later */
1293 673static void __init to2_adjust_clocks(void)
1294 parent_rate = clk_get_rate(clk->parent); 674{
1295 div = parent_rate / rate; 675 unsigned long cscr = __raw_readl(CCM_CSCR);
1296 if (parent_rate % rate)
1297 div++;
1298
1299 if (div > 8)
1300 div = 8;
1301
1302 return parent_rate / div;
1303}
1304
1305static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
1306{
1307 u32 reg;
1308 u32 div;
1309 unsigned long parent_rate;
1310
1311 parent_rate = clk_get_rate(clk->parent);
1312
1313 div = parent_rate / rate;
1314
1315 if (div > 8 || div < 1 || ((parent_rate / div) != rate))
1316 return -EINVAL;
1317 div--;
1318
1319 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
1320 reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
1321 __raw_writel(reg, CCM_PCDR0);
1322
1323 return 0;
1324}
1325
1326static unsigned long _clk_clko_recalc(struct clk *clk)
1327{
1328 u32 div;
1329 unsigned long parent_rate;
1330
1331 parent_rate = clk_get_rate(clk->parent);
1332
1333 div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
1334 CCM_PCDR0_CLKODIV_OFFSET;
1335 div++;
1336
1337 return parent_rate / div;
1338}
1339
1340static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1341{
1342 u32 reg;
1343
1344 reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
1345
1346 if (parent == &ckil_clk)
1347 reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
1348 else if (parent == &ckih_clk)
1349 reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
1350 else if (parent == mpll_clk.parent)
1351 reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
1352 else if (parent == spll_clk.parent)
1353 reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
1354 else if (parent == &mpll_clk)
1355 reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
1356 else if (parent == &spll_clk)
1357 reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
1358 else if (parent == &cpu_clk)
1359 reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
1360 else if (parent == &ahb_clk)
1361 reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
1362 else if (parent == &ipg_clk)
1363 reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
1364 else if (parent == &per_clk[0])
1365 reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
1366 else if (parent == &per_clk[1])
1367 reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
1368 else if (parent == &per_clk[2])
1369 reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
1370 else if (parent == &per_clk[3])
1371 reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
1372 else if (parent == &ssi1_clk[0])
1373 reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
1374 else if (parent == &ssi2_clk[0])
1375 reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
1376 else if (parent == &nfc_clk)
1377 reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
1378 else if (parent == &mstick1_clk)
1379 reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
1380 else if (parent == &vpu_clk)
1381 reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
1382 else if (parent == &usb_clk[0])
1383 reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
1384 else
1385 return -EINVAL;
1386
1387 __raw_writel(reg, CCM_CCSR);
1388
1389 return 0;
1390}
1391
1392static int _clk_clko_enable(struct clk *clk)
1393{
1394 u32 reg;
1395
1396 reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
1397 __raw_writel(reg, CCM_PCDR0);
1398
1399 return 0;
1400}
1401
1402static void _clk_clko_disable(struct clk *clk)
1403{
1404 u32 reg;
1405
1406 reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
1407 __raw_writel(reg, CCM_PCDR0);
1408}
1409
1410static struct clk clko_clk = {
1411 .name = "clko_clk",
1412 .get_rate = _clk_clko_recalc,
1413 .set_rate = _clk_clko_set_rate,
1414 .round_rate = _clk_clko_round_rate,
1415 .set_parent = _clk_clko_set_parent,
1416 .enable = _clk_clko_enable,
1417 .disable = _clk_clko_disable,
1418};
1419
1420static struct clk *mxc_clks[] = {
1421 &ckih_clk,
1422 &ckil_clk,
1423 &mpll_clk,
1424 &mpll_main_clk[0],
1425 &mpll_main_clk[1],
1426 &spll_clk,
1427 &cpu_clk,
1428 &ahb_clk,
1429 &ipg_clk,
1430 &per_clk[0],
1431 &per_clk[1],
1432 &per_clk[2],
1433 &per_clk[3],
1434 &clko_clk,
1435 &uart1_clk[0],
1436 &uart1_clk[1],
1437 &uart2_clk[0],
1438 &uart2_clk[1],
1439 &uart3_clk[0],
1440 &uart3_clk[1],
1441 &uart4_clk[0],
1442 &uart4_clk[1],
1443 &uart5_clk[0],
1444 &uart5_clk[1],
1445 &uart6_clk[0],
1446 &uart6_clk[1],
1447 &gpt1_clk[0],
1448 &gpt1_clk[1],
1449 &gpt2_clk[0],
1450 &gpt2_clk[1],
1451 &gpt3_clk[0],
1452 &gpt3_clk[1],
1453 &gpt4_clk[0],
1454 &gpt4_clk[1],
1455 &gpt5_clk[0],
1456 &gpt5_clk[1],
1457 &gpt6_clk[0],
1458 &gpt6_clk[1],
1459 &pwm_clk[0],
1460 &pwm_clk[1],
1461 &sdhc1_clk[0],
1462 &sdhc1_clk[1],
1463 &sdhc2_clk[0],
1464 &sdhc2_clk[1],
1465 &sdhc3_clk[0],
1466 &sdhc3_clk[1],
1467 &cspi1_clk[0],
1468 &cspi1_clk[1],
1469 &cspi2_clk[0],
1470 &cspi2_clk[1],
1471 &cspi3_clk[0],
1472 &cspi3_clk[1],
1473 &lcdc_clk[0],
1474 &lcdc_clk[1],
1475 &lcdc_clk[2],
1476 &csi_clk[0],
1477 &csi_clk[1],
1478 &usb_clk[0],
1479 &usb_clk[1],
1480 &ssi1_clk[0],
1481 &ssi1_clk[1],
1482 &ssi2_clk[0],
1483 &ssi2_clk[1],
1484 &nfc_clk,
1485 &vpu_clk,
1486 &dma_clk,
1487 &rtic_clk,
1488 &brom_clk,
1489 &emma_clk,
1490 &slcdc_clk,
1491 &fec_clk,
1492 &emi_clk,
1493 &sahara2_clk,
1494 &ata_clk,
1495 &mstick1_clk,
1496 &wdog_clk,
1497 &gpio_clk,
1498 &i2c_clk[0],
1499 &i2c_clk[1],
1500 &iim_clk,
1501 &kpp_clk,
1502 &owire_clk,
1503 &rtc_clk,
1504 &scc_clk,
1505};
1506
1507void __init change_external_low_reference(unsigned long new_ref)
1508{
1509 external_low_reference = new_ref;
1510}
1511
1512unsigned long __init clk_early_get_timer_rate(void)
1513{
1514 return clk_get_rate(&per_clk[0]);
1515}
1516
1517static void __init probe_mxc_clocks(void)
1518{
1519 int i;
1520 676
1521 if (mx27_revision() >= CHIP_REV_2_0) { 677 if (mx27_revision() >= CHIP_REV_2_0) {
1522 if (CSCR() & 0x8000) 678 if (cscr & CCM_CSCR_ARM_SRC)
1523 cpu_clk.parent = &mpll_main_clk[0]; 679 cpu_clk.parent = &mpll_main1_clk;
1524 680
1525 if (!(CSCR() & 0x00800000)) 681 if (!(cscr & CCM_CSCR_SSI2))
1526 ssi2_clk[0].parent = &spll_clk; 682 ssi1_clk.parent = &spll_clk;
1527 683
1528 if (!(CSCR() & 0x00400000)) 684 if (!(cscr & CCM_CSCR_SSI1))
1529 ssi1_clk[0].parent = &spll_clk; 685 ssi1_clk.parent = &spll_clk;
1530 686
1531 if (!(CSCR() & 0x00200000)) 687 if (!(cscr & CCM_CSCR_VPU))
1532 vpu_clk.parent = &spll_clk; 688 vpu_clk.parent = &spll_clk;
1533 } else { 689 } else {
1534 cpu_clk.parent = &mpll_clk; 690 cpu_clk.parent = &mpll_clk;
@@ -1537,11 +693,13 @@ static void __init probe_mxc_clocks(void)
1537 cpu_clk.set_rate = NULL; 693 cpu_clk.set_rate = NULL;
1538 ahb_clk.parent = &mpll_clk; 694 ahb_clk.parent = &mpll_clk;
1539 695
1540 for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) 696 per1_clk.parent = &mpll_clk;
1541 per_clk[i].parent = &mpll_clk; 697 per2_clk.parent = &mpll_clk;
698 per3_clk.parent = &mpll_clk;
699 per4_clk.parent = &mpll_clk;
1542 700
1543 ssi1_clk[0].parent = &mpll_clk; 701 ssi1_clk.parent = &mpll_clk;
1544 ssi2_clk[0].parent = &mpll_clk; 702 ssi2_clk.parent = &mpll_clk;
1545 703
1546 vpu_clk.parent = &mpll_clk; 704 vpu_clk.parent = &mpll_clk;
1547 } 705 }
@@ -1553,48 +711,45 @@ static void __init probe_mxc_clocks(void)
1553 */ 711 */
1554int __init mx27_clocks_init(unsigned long fref) 712int __init mx27_clocks_init(unsigned long fref)
1555{ 713{
1556 u32 cscr; 714 u32 cscr = __raw_readl(CCM_CSCR);
1557 struct clk **clkp; 715 int i;
1558 716
1559 external_high_reference = fref; 717 external_high_reference = fref;
1560 718
1561 /* detect clock reference for both system PLL */ 719 /* detect clock reference for both system PLLs */
1562 cscr = CSCR();
1563 if (cscr & CCM_CSCR_MCU) 720 if (cscr & CCM_CSCR_MCU)
1564 mpll_clk.parent = &ckih_clk; 721 mpll_clk.parent = &ckih_clk;
1565 else 722 else
1566 mpll_clk.parent = &ckil_clk; 723 mpll_clk.parent = &fpm_clk;
1567 724
1568 if (cscr & CCM_CSCR_SP) 725 if (cscr & CCM_CSCR_SP)
1569 spll_clk.parent = &ckih_clk; 726 spll_clk.parent = &ckih_clk;
1570 else 727 else
1571 spll_clk.parent = &ckil_clk; 728 spll_clk.parent = &fpm_clk;
1572 729
1573 probe_mxc_clocks(); 730 to2_adjust_clocks();
1574 731
1575 per_clk[0].enable(&per_clk[0]); 732 for (i = 0; i < ARRAY_SIZE(lookups); i++)
1576 gpt1_clk[1].enable(&gpt1_clk[1]); 733 clkdev_add(&lookups[i]);
1577 734
1578 for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) 735 /* Turn off all clocks we do not need */
1579 clk_register(*clkp); 736 __raw_writel(0, CCM_PCCR0);
737 __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1);
1580 738
1581 /* Turn off all possible clocks */
1582 __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
1583 __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
1584 CCM_PCCR1);
1585 spll_clk.disable(&spll_clk); 739 spll_clk.disable(&spll_clk);
1586 740
1587 /* This will propagate to all children and init all the clock rates */ 741 /* enable basic clocks */
1588 742 clk_enable(&per1_clk);
1589 clk_enable(&emi_clk);
1590 clk_enable(&gpio_clk); 743 clk_enable(&gpio_clk);
744 clk_enable(&emi_clk);
1591 clk_enable(&iim_clk); 745 clk_enable(&iim_clk);
1592 clk_enable(&gpt1_clk[0]); 746
1593#ifdef CONFIG_DEBUG_LL_CONSOLE 747#ifdef CONFIG_DEBUG_LL_CONSOLE
1594 clk_enable(&uart1_clk[0]); 748 clk_enable(&uart1_clk);
1595#endif 749#endif
1596 750
1597 mxc_timer_init(&gpt1_clk[0]); 751 mxc_timer_init(&gpt1_clk);
1598 752
1599 return 0; 753 return 0;
1600} 754}
755