Merge remote-tracking branch 'moduleh/module.h-split'
[linux-2.6/next.git] / arch / arm / mach-imx / clock-imx21.c
blobee15d8c9db08ecaa60153925bc986cc7d9aec020
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
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,
18 * MA 02110-1301, USA.
21 #include <linux/clk.h>
22 #include <linux/io.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)
265 u32 reg;
267 reg = __raw_readl(clk->enable_reg);
268 reg |= 1 << clk->enable_shift;
269 __raw_writel(reg, clk->enable_reg);
270 return 0;
273 static void _clk_disable(struct clk *clk)
275 u32 reg;
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,
283 unsigned long rate,
284 u32 max_divisor)
286 u32 div;
287 unsigned long parent_rate;
289 parent_rate = clk_get_rate(clk->parent);
291 div = parent_rate / rate;
292 if (parent_rate % rate)
293 div++;
295 if (div > max_divisor)
296 div = max_divisor;
298 return parent_rate / div;
301 static int _clk_spll_enable(struct clk *clk)
303 u32 reg;
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)
311 return 0;
314 static void _clk_spll_disable(struct clk *clk)
316 u32 reg;
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,
329 unsigned long rate)
331 return _clk_generic_round_rate(clk, rate, 64);
334 static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
336 u32 reg;
337 u32 div;
338 unsigned long parent_rate;
340 parent_rate = clk_get_rate(clk->parent);
342 if (clk->id < 0 || clk->id > 3)
343 return -EINVAL;
345 div = parent_rate / rate;
346 if (div > 64 || div < 1 || ((parent_rate / div) != rate))
347 return -EINVAL;
348 div--;
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);
356 return 0;
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,
372 unsigned long rate)
374 return _clk_generic_round_rate(clk, rate, 8);
377 static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
379 u32 reg;
380 u32 div;
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))
387 return -EINVAL;
388 div--;
390 reg = CSCR() & ~CCM_CSCR_USB_MASK;
391 reg |= div << CCM_CSCR_USB_OFFSET;
392 __raw_writel(reg, CCM_CSCR);
394 return 0;
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 = {
483 .parent = &ckil_clk,
484 .get_rate = _clk_fpm_recalc,
487 static unsigned long get_mpll_clk(struct clk *clk)
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;
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 = {
512 .parent = &ckih_clk,
513 .get_rate = get_mpll_clk,
516 static unsigned long _clk_fclk_get_rate(struct clk *clk)
518 unsigned long parent_rate;
519 u32 div;
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 = {
528 .parent = &mpll_clk,
529 .get_rate = _clk_fclk_get_rate
532 static unsigned long get_spll_clk(struct clk *clk)
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;
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 = {
557 .parent = &ckih_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)
565 unsigned long rate;
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 = {
576 .parent = &fclk_clk,
577 .get_rate = get_hclk_clk,
580 static unsigned long get_ipg_clk(struct clk *clk)
582 unsigned long rate;
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 = {
592 .parent = &hclk_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)
604 return 0;
606 perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
608 return parent_rate / (perclk_pdf + 1);
611 static struct clk per_clk[] = {
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] */
637 static struct clk uart_ipg_clk[];
639 static struct clk uart_clk[] = {
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],
659 static struct clk uart_ipg_clk[] = {
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,
691 static struct clk gpt_ipg_clk[];
693 static struct clk gpt_clk[] = {
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],
709 static struct clk gpt_ipg_clk[] = {
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,
734 static struct clk pwm_clk[] = {
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,
747 static struct clk sdhc_ipg_clk[];
749 static struct clk sdhc_clk[] = {
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],
761 static struct clk sdhc_ipg_clk[] = {
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,
779 static struct clk cspi_ipg_clk[];
781 static struct clk cspi_clk[] = {
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],
797 static struct clk cspi_ipg_clk[] = {
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,
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,
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,
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,
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,
859 static struct clk usb_clk[] = {
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,
879 static struct clk ssi_ipg_clk[];
881 static struct clk ssi_clk[] = {
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,
903 static struct clk ssi_ipg_clk[] = {
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,
922 static 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,
931 static struct clk dma_clk[] = {
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,
947 static 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,
955 static struct clk emma_clk[] = {
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,
971 static struct clk slcdc_clk[] = {
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,
987 static 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,
995 static 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,
1003 static 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,
1012 static 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,
1020 static 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,
1028 static 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,
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)
1043 u32 reg;
1044 u32 div;
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))
1052 return -EINVAL;
1053 div--;
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);
1063 return 0;
1066 static unsigned long _clk_clko_recalc(struct clk *clk)
1068 u32 div = 0;
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;
1076 div++;
1078 return parent_rate / div;
1081 static struct clk clko_clk;
1083 static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
1085 u32 reg;
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;
1127 else
1128 return -EINVAL;
1130 __raw_writel(reg, CCM_CCSR);
1132 return 0;
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) \
1145 .dev_id = d, \
1146 .con_id = n, \
1147 .clk = &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)
1202 u32 cscr;
1204 external_low_reference = lref;
1205 external_high_reference = href;
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;
1214 if (cscr & CCM_CSCR_SP)
1215 spll_clk.parent = &ckih_clk;
1216 else
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]);
1234 #endif
1236 mxc_timer_init(&gpt_clk[0], MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR),
1237 MX21_INT_GPT1);
1238 return 0;