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
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.
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,
21 #include <linux/clk.h>
23 #include <linux/module.h>
24 #include <linux/clkdev.h>
26 #include <mach/clock.h>
27 #include <mach/hardware.h>
28 #include <mach/common.h>
29 #include <asm/div64.h>
31 #define IO_ADDR_CCM(off) (MX21_IO_ADDRESS(MX21_CCM_BASE_ADDR + (off)))
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)
49 #define CCM_CSCR_PRESC_OFFSET 29
50 #define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET)
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)
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
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
87 #define CCM_MPCTL1_LF (1 << 15)
88 #define CCM_MPCTL1_BRMO (1 << 6)
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
100 #define CCM_SPCTL1_LF (1 << 15)
101 #define CCM_SPCTL1_BRMO (1 << 6)
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
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
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
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
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)
252 #define CCM_CCSR_32KSR (1 << 15)
254 #define CCM_CCSR_CLKMODE1 (1 << 9)
255 #define CCM_CCSR_CLKMODE0 (1 << 8)
257 #define CCM_CCSR_CLKOSEL_OFFSET 0
258 #define CCM_CCSR_CLKOSEL_MASK 0x1f
260 #define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
261 #define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
263 static int _clk_enable(struct clk
*clk
)
267 reg
= __raw_readl(clk
->enable_reg
);
268 reg
|= 1 << clk
->enable_shift
;
269 __raw_writel(reg
, clk
->enable_reg
);
273 static void _clk_disable(struct clk
*clk
)
277 reg
= __raw_readl(clk
->enable_reg
);
278 reg
&= ~(1 << clk
->enable_shift
);
279 __raw_writel(reg
, clk
->enable_reg
);
282 static unsigned long _clk_generic_round_rate(struct clk
*clk
,
287 unsigned long parent_rate
;
289 parent_rate
= clk_get_rate(clk
->parent
);
291 div
= parent_rate
/ rate
;
292 if (parent_rate
% rate
)
295 if (div
> max_divisor
)
298 return parent_rate
/ div
;
301 static int _clk_spll_enable(struct clk
*clk
)
305 reg
= __raw_readl(CCM_CSCR
);
306 reg
|= CCM_CSCR_SPEN
;
307 __raw_writel(reg
, CCM_CSCR
);
309 while ((__raw_readl(CCM_SPCTL1
) & CCM_SPCTL1_LF
) == 0)
314 static void _clk_spll_disable(struct clk
*clk
)
318 reg
= __raw_readl(CCM_CSCR
);
319 reg
&= ~CCM_CSCR_SPEN
;
320 __raw_writel(reg
, CCM_CSCR
);
324 #define CSCR() (__raw_readl(CCM_CSCR))
325 #define PCDR0() (__raw_readl(CCM_PCDR0))
326 #define PCDR1() (__raw_readl(CCM_PCDR1))
328 static unsigned long _clk_perclkx_round_rate(struct clk
*clk
,
331 return _clk_generic_round_rate(clk
, rate
, 64);
334 static int _clk_perclkx_set_rate(struct clk
*clk
, unsigned long rate
)
338 unsigned long parent_rate
;
340 parent_rate
= clk_get_rate(clk
->parent
);
342 if (clk
->id
< 0 || clk
->id
> 3)
345 div
= parent_rate
/ rate
;
346 if (div
> 64 || div
< 1 || ((parent_rate
/ div
) != rate
))
351 __raw_readl(CCM_PCDR1
) & ~(CCM_PCDR1_PERDIV1_MASK
<<
353 reg
|= div
<< (clk
->id
<< 3);
354 __raw_writel(reg
, CCM_PCDR1
);
359 static unsigned long _clk_usb_recalc(struct clk
*clk
)
361 unsigned long usb_pdf
;
362 unsigned long parent_rate
;
364 parent_rate
= clk_get_rate(clk
->parent
);
366 usb_pdf
= (CSCR() & CCM_CSCR_USB_MASK
) >> CCM_CSCR_USB_OFFSET
;
368 return parent_rate
/ (usb_pdf
+ 1U);
371 static unsigned long _clk_usb_round_rate(struct clk
*clk
,
374 return _clk_generic_round_rate(clk
, rate
, 8);
377 static int _clk_usb_set_rate(struct clk
*clk
, unsigned long rate
)
381 unsigned long parent_rate
;
383 parent_rate
= clk_get_rate(clk
->parent
);
385 div
= parent_rate
/ rate
;
386 if (div
> 8 || div
< 1 || ((parent_rate
/ div
) != rate
))
390 reg
= CSCR() & ~CCM_CSCR_USB_MASK
;
391 reg
|= div
<< CCM_CSCR_USB_OFFSET
;
392 __raw_writel(reg
, CCM_CSCR
);
397 static unsigned long _clk_ssix_recalc(struct clk
*clk
, unsigned long pdf
)
399 unsigned long parent_rate
;
401 parent_rate
= clk_get_rate(clk
->parent
);
403 pdf
= (pdf
< 2) ? 124UL : pdf
; /* MX21 & MX27 TO1 */
405 return 2UL * parent_rate
/ pdf
;
408 static unsigned long _clk_ssi1_recalc(struct clk
*clk
)
410 return _clk_ssix_recalc(clk
,
411 (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK
)
412 >> CCM_PCDR0_SSI1BAUDDIV_OFFSET
);
415 static unsigned long _clk_ssi2_recalc(struct clk
*clk
)
417 return _clk_ssix_recalc(clk
,
418 (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK
) >>
419 CCM_PCDR0_SSI2BAUDDIV_OFFSET
);
422 static unsigned long _clk_nfc_recalc(struct clk
*clk
)
424 unsigned long nfc_pdf
;
425 unsigned long parent_rate
;
427 parent_rate
= clk_get_rate(clk
->parent
);
429 nfc_pdf
= (PCDR0() & CCM_PCDR0_NFCDIV_MASK
)
430 >> CCM_PCDR0_NFCDIV_OFFSET
;
432 return parent_rate
/ (nfc_pdf
+ 1);
435 static unsigned long _clk_parent_round_rate(struct clk
*clk
, unsigned long rate
)
437 return clk
->parent
->round_rate(clk
->parent
, rate
);
440 static int _clk_parent_set_rate(struct clk
*clk
, unsigned long rate
)
442 return clk
->parent
->set_rate(clk
->parent
, rate
);
445 static unsigned long external_high_reference
; /* in Hz */
447 static unsigned long get_high_reference_clock_rate(struct clk
*clk
)
449 return external_high_reference
;
453 * the high frequency external clock reference
454 * Default case is 26MHz.
456 static struct clk ckih_clk
= {
457 .get_rate
= get_high_reference_clock_rate
,
460 static unsigned long external_low_reference
; /* in Hz */
462 static unsigned long get_low_reference_clock_rate(struct clk
*clk
)
464 return external_low_reference
;
468 * the low frequency external clock reference
469 * Default case is 32.768kHz.
471 static struct clk ckil_clk
= {
472 .get_rate
= get_low_reference_clock_rate
,
476 static unsigned long _clk_fpm_recalc(struct clk
*clk
)
478 return clk_get_rate(clk
->parent
) * 512;
481 /* Output of frequency pre multiplier */
482 static struct clk fpm_clk
= {
484 .get_rate
= _clk_fpm_recalc
,
487 static unsigned long get_mpll_clk(struct clk
*clk
)
490 unsigned long ref_clk
;
491 unsigned long mfi
= 0, mfn
= 0, mfd
= 0, pdf
= 0;
492 unsigned long long temp
;
494 ref_clk
= clk_get_rate(clk
->parent
);
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
;
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);
508 return (unsigned long)temp
;
511 static struct clk mpll_clk
= {
513 .get_rate
= get_mpll_clk
,
516 static unsigned long _clk_fclk_get_rate(struct clk
*clk
)
518 unsigned long parent_rate
;
521 div
= (CSCR() & CCM_CSCR_PRESC_MASK
) >> CCM_CSCR_PRESC_OFFSET
;
522 parent_rate
= clk_get_rate(clk
->parent
);
524 return parent_rate
/ (div
+1);
527 static struct clk fclk_clk
= {
529 .get_rate
= _clk_fclk_get_rate
532 static unsigned long get_spll_clk(struct clk
*clk
)
535 unsigned long ref_clk
;
536 unsigned long mfi
= 0, mfn
= 0, mfd
= 0, pdf
= 0;
537 unsigned long long temp
;
539 ref_clk
= clk_get_rate(clk
->parent
);
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
;
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);
553 return (unsigned long)temp
;
556 static struct clk spll_clk
= {
558 .get_rate
= get_spll_clk
,
559 .enable
= _clk_spll_enable
,
560 .disable
= _clk_spll_disable
,
563 static unsigned long get_hclk_clk(struct clk
*clk
)
566 unsigned long bclk_pdf
;
568 bclk_pdf
= (CSCR() & CCM_CSCR_BCLK_MASK
)
569 >> CCM_CSCR_BCLK_OFFSET
;
571 rate
= clk_get_rate(clk
->parent
);
572 return rate
/ (bclk_pdf
+ 1);
575 static struct clk hclk_clk
= {
577 .get_rate
= get_hclk_clk
,
580 static unsigned long get_ipg_clk(struct clk
*clk
)
583 unsigned long ipg_pdf
;
585 ipg_pdf
= (CSCR() & CCM_CSCR_IPDIV
) >> CCM_CSCR_IPDIV_OFFSET
;
587 rate
= clk_get_rate(clk
->parent
);
588 return rate
/ (ipg_pdf
+ 1);
591 static struct clk ipg_clk
= {
593 .get_rate
= get_ipg_clk
,
596 static unsigned long _clk_perclkx_recalc(struct clk
*clk
)
598 unsigned long perclk_pdf
;
599 unsigned long parent_rate
;
601 parent_rate
= clk_get_rate(clk
->parent
);
603 if (clk
->id
< 0 || clk
->id
> 3)
606 perclk_pdf
= (PCDR1() >> (clk
->id
<< 3)) & CCM_PCDR1_PERDIV1_MASK
;
608 return parent_rate
/ (perclk_pdf
+ 1);
611 static struct clk per_clk
[] = {
615 .get_rate
= _clk_perclkx_recalc
,
619 .get_rate
= _clk_perclkx_recalc
,
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] */
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] */
637 static struct clk uart_ipg_clk
[];
639 static struct clk uart_clk
[] = {
642 .parent
= &per_clk
[0],
643 .secondary
= &uart_ipg_clk
[0],
646 .parent
= &per_clk
[0],
647 .secondary
= &uart_ipg_clk
[1],
650 .parent
= &per_clk
[0],
651 .secondary
= &uart_ipg_clk
[2],
654 .parent
= &per_clk
[0],
655 .secondary
= &uart_ipg_clk
[3],
659 static struct clk uart_ipg_clk
[] = {
663 .enable
= _clk_enable
,
664 .enable_reg
= CCM_PCCR_UART1_REG
,
665 .enable_shift
= CCM_PCCR_UART1_OFFSET
,
666 .disable
= _clk_disable
,
670 .enable
= _clk_enable
,
671 .enable_reg
= CCM_PCCR_UART2_REG
,
672 .enable_shift
= CCM_PCCR_UART2_OFFSET
,
673 .disable
= _clk_disable
,
677 .enable
= _clk_enable
,
678 .enable_reg
= CCM_PCCR_UART3_REG
,
679 .enable_shift
= CCM_PCCR_UART3_OFFSET
,
680 .disable
= _clk_disable
,
684 .enable
= _clk_enable
,
685 .enable_reg
= CCM_PCCR_UART4_REG
,
686 .enable_shift
= CCM_PCCR_UART4_OFFSET
,
687 .disable
= _clk_disable
,
691 static struct clk gpt_ipg_clk
[];
693 static struct clk gpt_clk
[] = {
696 .parent
= &per_clk
[0],
697 .secondary
= &gpt_ipg_clk
[0],
700 .parent
= &per_clk
[0],
701 .secondary
= &gpt_ipg_clk
[1],
704 .parent
= &per_clk
[0],
705 .secondary
= &gpt_ipg_clk
[2],
709 static struct clk gpt_ipg_clk
[] = {
713 .enable
= _clk_enable
,
714 .enable_reg
= CCM_PCCR_GPT1_REG
,
715 .enable_shift
= CCM_PCCR_GPT1_OFFSET
,
716 .disable
= _clk_disable
,
720 .enable
= _clk_enable
,
721 .enable_reg
= CCM_PCCR_GPT2_REG
,
722 .enable_shift
= CCM_PCCR_GPT2_OFFSET
,
723 .disable
= _clk_disable
,
727 .enable
= _clk_enable
,
728 .enable_reg
= CCM_PCCR_GPT3_REG
,
729 .enable_shift
= CCM_PCCR_GPT3_OFFSET
,
730 .disable
= _clk_disable
,
734 static struct clk pwm_clk
[] = {
736 .parent
= &per_clk
[0],
737 .secondary
= &pwm_clk
[1],
740 .enable
= _clk_enable
,
741 .enable_reg
= CCM_PCCR_PWM_REG
,
742 .enable_shift
= CCM_PCCR_PWM_OFFSET
,
743 .disable
= _clk_disable
,
747 static struct clk sdhc_ipg_clk
[];
749 static struct clk sdhc_clk
[] = {
752 .parent
= &per_clk
[1],
753 .secondary
= &sdhc_ipg_clk
[0],
756 .parent
= &per_clk
[1],
757 .secondary
= &sdhc_ipg_clk
[1],
761 static struct clk sdhc_ipg_clk
[] = {
765 .enable
= _clk_enable
,
766 .enable_reg
= CCM_PCCR_SDHC1_REG
,
767 .enable_shift
= CCM_PCCR_SDHC1_OFFSET
,
768 .disable
= _clk_disable
,
772 .enable
= _clk_enable
,
773 .enable_reg
= CCM_PCCR_SDHC2_REG
,
774 .enable_shift
= CCM_PCCR_SDHC2_OFFSET
,
775 .disable
= _clk_disable
,
779 static struct clk cspi_ipg_clk
[];
781 static struct clk cspi_clk
[] = {
784 .parent
= &per_clk
[1],
785 .secondary
= &cspi_ipg_clk
[0],
788 .parent
= &per_clk
[1],
789 .secondary
= &cspi_ipg_clk
[1],
792 .parent
= &per_clk
[1],
793 .secondary
= &cspi_ipg_clk
[2],
797 static struct clk cspi_ipg_clk
[] = {
801 .enable
= _clk_enable
,
802 .enable_reg
= CCM_PCCR_CSPI1_REG
,
803 .enable_shift
= CCM_PCCR_CSPI1_OFFSET
,
804 .disable
= _clk_disable
,
808 .enable
= _clk_enable
,
809 .enable_reg
= CCM_PCCR_CSPI2_REG
,
810 .enable_shift
= CCM_PCCR_CSPI2_OFFSET
,
811 .disable
= _clk_disable
,
815 .enable
= _clk_enable
,
816 .enable_reg
= CCM_PCCR_CSPI3_REG
,
817 .enable_shift
= CCM_PCCR_CSPI3_OFFSET
,
818 .disable
= _clk_disable
,
822 static struct clk lcdc_clk
[] = {
824 .parent
= &per_clk
[2],
825 .secondary
= &lcdc_clk
[1],
826 .round_rate
= _clk_parent_round_rate
,
827 .set_rate
= _clk_parent_set_rate
,
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
,
837 .enable
= _clk_enable
,
838 .enable_reg
= CCM_PCCR_HCLK_LCDC_REG
,
839 .enable_shift
= CCM_PCCR_HCLK_LCDC_OFFSET
,
840 .disable
= _clk_disable
,
844 static struct clk csi_clk
[] = {
846 .parent
= &per_clk
[3],
847 .secondary
= &csi_clk
[1],
848 .round_rate
= _clk_parent_round_rate
,
849 .set_rate
= _clk_parent_set_rate
,
852 .enable
= _clk_enable
,
853 .enable_reg
= CCM_PCCR_HCLK_CSI_REG
,
854 .enable_shift
= CCM_PCCR_HCLK_CSI_OFFSET
,
855 .disable
= _clk_disable
,
859 static struct clk usb_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
,
872 .enable
= _clk_enable
,
873 .enable_reg
= CCM_PCCR_HCLK_USBOTG_REG
,
874 .enable_shift
= CCM_PCCR_HCLK_USBOTG_OFFSET
,
875 .disable
= _clk_disable
,
879 static struct clk ssi_ipg_clk
[];
881 static struct clk ssi_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
,
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
,
903 static struct clk ssi_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
,
914 .enable
= _clk_enable
,
915 .enable_reg
= CCM_PCCR_SSI2_REG
,
916 .enable_shift
= CCM_PCCR_SSI2_IPG_OFFSET
,
917 .disable
= _clk_disable
,
922 static struct clk nfc_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
,
931 static struct clk dma_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],
940 .enable
= _clk_enable
,
941 .enable_reg
= CCM_PCCR_HCLK_DMA_REG
,
942 .enable_shift
= CCM_PCCR_HCLK_DMA_OFFSET
,
943 .disable
= _clk_disable
,
947 static struct clk brom_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
,
955 static struct clk emma_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],
964 .enable
= _clk_enable
,
965 .enable_reg
= CCM_PCCR_HCLK_EMMA_REG
,
966 .enable_shift
= CCM_PCCR_HCLK_EMMA_OFFSET
,
967 .disable
= _clk_disable
,
971 static struct clk slcdc_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],
980 .enable
= _clk_enable
,
981 .enable_reg
= CCM_PCCR_HCLK_SLCDC_REG
,
982 .enable_shift
= CCM_PCCR_HCLK_SLCDC_OFFSET
,
983 .disable
= _clk_disable
,
987 static struct clk wdog_clk
= {
989 .enable
= _clk_enable
,
990 .enable_reg
= CCM_PCCR_WDT_REG
,
991 .enable_shift
= CCM_PCCR_WDT_OFFSET
,
992 .disable
= _clk_disable
,
995 static struct clk gpio_clk
= {
997 .enable
= _clk_enable
,
998 .enable_reg
= CCM_PCCR_GPIO_REG
,
999 .enable_shift
= CCM_PCCR_GPIO_OFFSET
,
1000 .disable
= _clk_disable
,
1003 static struct clk i2c_clk
= {
1006 .enable
= _clk_enable
,
1007 .enable_reg
= CCM_PCCR_I2C1_REG
,
1008 .enable_shift
= CCM_PCCR_I2C1_OFFSET
,
1009 .disable
= _clk_disable
,
1012 static struct clk kpp_clk
= {
1014 .enable
= _clk_enable
,
1015 .enable_reg
= CCM_PCCR_KPP_REG
,
1016 .enable_shift
= CCM_PCCR_KPP_OFFSET
,
1017 .disable
= _clk_disable
,
1020 static struct clk owire_clk
= {
1022 .enable
= _clk_enable
,
1023 .enable_reg
= CCM_PCCR_OWIRE_REG
,
1024 .enable_shift
= CCM_PCCR_OWIRE_OFFSET
,
1025 .disable
= _clk_disable
,
1028 static struct clk rtc_clk
= {
1030 .enable
= _clk_enable
,
1031 .enable_reg
= CCM_PCCR_RTC_REG
,
1032 .enable_shift
= CCM_PCCR_RTC_OFFSET
,
1033 .disable
= _clk_disable
,
1036 static unsigned long _clk_clko_round_rate(struct clk
*clk
, unsigned long rate
)
1038 return _clk_generic_round_rate(clk
, rate
, 8);
1041 static int _clk_clko_set_rate(struct clk
*clk
, unsigned long rate
)
1045 unsigned long parent_rate
;
1047 parent_rate
= clk_get_rate(clk
->parent
);
1049 div
= parent_rate
/ rate
;
1051 if (div
> 8 || div
< 1 || ((parent_rate
/ div
) != rate
))
1055 reg
= __raw_readl(CCM_PCDR0
);
1057 if (clk
->parent
== &usb_clk
[0]) {
1058 reg
&= ~CCM_PCDR0_48MDIV_MASK
;
1059 reg
|= div
<< CCM_PCDR0_48MDIV_OFFSET
;
1061 __raw_writel(reg
, CCM_PCDR0
);
1066 static unsigned long _clk_clko_recalc(struct clk
*clk
)
1069 unsigned long parent_rate
;
1071 parent_rate
= clk_get_rate(clk
->parent
);
1073 if (clk
->parent
== &usb_clk
[0]) /* 48M */
1074 div
= __raw_readl(CCM_PCDR0
) & CCM_PCDR0_48MDIV_MASK
1075 >> CCM_PCDR0_48MDIV_OFFSET
;
1078 return parent_rate
/ div
;
1081 static struct clk clko_clk
;
1083 static int _clk_clko_set_parent(struct clk
*clk
, struct clk
*parent
)
1087 reg
= __raw_readl(CCM_CCSR
) & ~CCM_CCSR_CLKOSEL_MASK
;
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
;
1130 __raw_writel(reg
, CCM_CCSR
);
1135 static 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
,
1143 #define _REGISTER_CLOCK(d, n, c) \
1149 static 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)
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
)
1197 * must be called very early to get information about the
1198 * available clock rate when the timer framework starts
1200 int __init
mx21_clocks_init(unsigned long lref
, unsigned long href
)
1204 external_low_reference
= lref
;
1205 external_high_reference
= href
;
1207 /* detect clock reference for both system PLL */
1209 if (cscr
& CCM_CSCR_MCU
)
1210 mpll_clk
.parent
= &ckih_clk
;
1212 mpll_clk
.parent
= &fpm_clk
;
1214 if (cscr
& CCM_CSCR_SP
)
1215 spll_clk
.parent
= &ckih_clk
;
1217 spll_clk
.parent
= &fpm_clk
;
1219 clkdev_add_table(lookups
, ARRAY_SIZE(lookups
));
1221 /* Turn off all clock gates */
1222 __raw_writel(0, CCM_PCCR0
);
1223 __raw_writel(CCM_PCCR_GPT1_MASK
, CCM_PCCR1
);
1225 /* This turns of the serial PLL as well */
1226 spll_clk
.disable(&spll_clk
);
1228 /* This will propagate to all children and init all the clock rates. */
1229 clk_enable(&per_clk
[0]);
1230 clk_enable(&gpio_clk
);
1232 #if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
1233 clk_enable(&uart_clk
[0]);
1236 mxc_timer_init(&gpt_clk
[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR
),