diff options
Diffstat (limited to 'arch/arm/mach-imx/clock-mx51-mx53.c')
-rw-r--r-- | arch/arm/mach-imx/clock-mx51-mx53.c | 1675 |
1 files changed, 1675 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/clock-mx51-mx53.c b/arch/arm/mach-imx/clock-mx51-mx53.c new file mode 100644 index 000000000000..08470504a088 --- /dev/null +++ b/arch/arm/mach-imx/clock-mx51-mx53.c | |||
@@ -0,0 +1,1675 @@ | |||
1 | /* | ||
2 | * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. | ||
3 | * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> | ||
4 | * | ||
5 | * The code contained herein is licensed under the GNU General Public | ||
6 | * License. You may obtain a copy of the GNU General Public License | ||
7 | * Version 2 or later at the following locations: | ||
8 | * | ||
9 | * http://www.opensource.org/licenses/gpl-license.html | ||
10 | * http://www.gnu.org/copyleft/gpl.html | ||
11 | */ | ||
12 | |||
13 | #include <linux/mm.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/clkdev.h> | ||
18 | #include <linux/of.h> | ||
19 | |||
20 | #include <asm/div64.h> | ||
21 | |||
22 | #include <mach/hardware.h> | ||
23 | #include <mach/common.h> | ||
24 | #include <mach/clock.h> | ||
25 | |||
26 | #include "crm-regs-imx5.h" | ||
27 | |||
28 | /* External clock values passed-in by the board code */ | ||
29 | static unsigned long external_high_reference, external_low_reference; | ||
30 | static unsigned long oscillator_reference, ckih2_reference; | ||
31 | |||
32 | static struct clk osc_clk; | ||
33 | static struct clk pll1_main_clk; | ||
34 | static struct clk pll1_sw_clk; | ||
35 | static struct clk pll2_sw_clk; | ||
36 | static struct clk pll3_sw_clk; | ||
37 | static struct clk mx53_pll4_sw_clk; | ||
38 | static struct clk lp_apm_clk; | ||
39 | static struct clk periph_apm_clk; | ||
40 | static struct clk ahb_clk; | ||
41 | static struct clk ipg_clk; | ||
42 | static struct clk usboh3_clk; | ||
43 | static struct clk emi_fast_clk; | ||
44 | static struct clk ipu_clk; | ||
45 | static struct clk mipi_hsc1_clk; | ||
46 | static struct clk esdhc1_clk; | ||
47 | static struct clk esdhc2_clk; | ||
48 | static struct clk esdhc3_mx53_clk; | ||
49 | |||
50 | #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ | ||
51 | |||
52 | /* calculate best pre and post dividers to get the required divider */ | ||
53 | static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post, | ||
54 | u32 max_pre, u32 max_post) | ||
55 | { | ||
56 | if (div >= max_pre * max_post) { | ||
57 | *pre = max_pre; | ||
58 | *post = max_post; | ||
59 | } else if (div >= max_pre) { | ||
60 | u32 min_pre, temp_pre, old_err, err; | ||
61 | min_pre = DIV_ROUND_UP(div, max_post); | ||
62 | old_err = max_pre; | ||
63 | for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) { | ||
64 | err = div % temp_pre; | ||
65 | if (err == 0) { | ||
66 | *pre = temp_pre; | ||
67 | break; | ||
68 | } | ||
69 | err = temp_pre - err; | ||
70 | if (err < old_err) { | ||
71 | old_err = err; | ||
72 | *pre = temp_pre; | ||
73 | } | ||
74 | } | ||
75 | *post = DIV_ROUND_UP(div, *pre); | ||
76 | } else { | ||
77 | *pre = div; | ||
78 | *post = 1; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) | ||
83 | { | ||
84 | u32 reg = __raw_readl(clk->enable_reg); | ||
85 | |||
86 | reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift); | ||
87 | reg |= mode << clk->enable_shift; | ||
88 | |||
89 | __raw_writel(reg, clk->enable_reg); | ||
90 | } | ||
91 | |||
92 | static int _clk_ccgr_enable(struct clk *clk) | ||
93 | { | ||
94 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON); | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static void _clk_ccgr_disable(struct clk *clk) | ||
99 | { | ||
100 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF); | ||
101 | } | ||
102 | |||
103 | static int _clk_ccgr_enable_inrun(struct clk *clk) | ||
104 | { | ||
105 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void _clk_ccgr_disable_inwait(struct clk *clk) | ||
110 | { | ||
111 | _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * For the 4-to-1 muxed input clock | ||
116 | */ | ||
117 | static inline u32 _get_mux(struct clk *parent, struct clk *m0, | ||
118 | struct clk *m1, struct clk *m2, struct clk *m3) | ||
119 | { | ||
120 | if (parent == m0) | ||
121 | return 0; | ||
122 | else if (parent == m1) | ||
123 | return 1; | ||
124 | else if (parent == m2) | ||
125 | return 2; | ||
126 | else if (parent == m3) | ||
127 | return 3; | ||
128 | else | ||
129 | BUG(); | ||
130 | |||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | static inline void __iomem *_mx51_get_pll_base(struct clk *pll) | ||
135 | { | ||
136 | if (pll == &pll1_main_clk) | ||
137 | return MX51_DPLL1_BASE; | ||
138 | else if (pll == &pll2_sw_clk) | ||
139 | return MX51_DPLL2_BASE; | ||
140 | else if (pll == &pll3_sw_clk) | ||
141 | return MX51_DPLL3_BASE; | ||
142 | else | ||
143 | BUG(); | ||
144 | |||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | static inline void __iomem *_mx53_get_pll_base(struct clk *pll) | ||
149 | { | ||
150 | if (pll == &pll1_main_clk) | ||
151 | return MX53_DPLL1_BASE; | ||
152 | else if (pll == &pll2_sw_clk) | ||
153 | return MX53_DPLL2_BASE; | ||
154 | else if (pll == &pll3_sw_clk) | ||
155 | return MX53_DPLL3_BASE; | ||
156 | else if (pll == &mx53_pll4_sw_clk) | ||
157 | return MX53_DPLL4_BASE; | ||
158 | else | ||
159 | BUG(); | ||
160 | |||
161 | return NULL; | ||
162 | } | ||
163 | |||
164 | static inline void __iomem *_get_pll_base(struct clk *pll) | ||
165 | { | ||
166 | if (cpu_is_mx51()) | ||
167 | return _mx51_get_pll_base(pll); | ||
168 | else | ||
169 | return _mx53_get_pll_base(pll); | ||
170 | } | ||
171 | |||
172 | static unsigned long clk_pll_get_rate(struct clk *clk) | ||
173 | { | ||
174 | long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; | ||
175 | unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; | ||
176 | void __iomem *pllbase; | ||
177 | s64 temp; | ||
178 | unsigned long parent_rate; | ||
179 | |||
180 | parent_rate = clk_get_rate(clk->parent); | ||
181 | |||
182 | pllbase = _get_pll_base(clk); | ||
183 | |||
184 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
185 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | ||
186 | dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; | ||
187 | |||
188 | if (pll_hfsm == 0) { | ||
189 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); | ||
190 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); | ||
191 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); | ||
192 | } else { | ||
193 | dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); | ||
194 | dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); | ||
195 | dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); | ||
196 | } | ||
197 | pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; | ||
198 | mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; | ||
199 | mfi = (mfi <= 5) ? 5 : mfi; | ||
200 | mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; | ||
201 | mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; | ||
202 | /* Sign extend to 32-bits */ | ||
203 | if (mfn >= 0x04000000) { | ||
204 | mfn |= 0xFC000000; | ||
205 | mfn_abs = -mfn; | ||
206 | } | ||
207 | |||
208 | ref_clk = 2 * parent_rate; | ||
209 | if (dbl != 0) | ||
210 | ref_clk *= 2; | ||
211 | |||
212 | ref_clk /= (pdf + 1); | ||
213 | temp = (u64) ref_clk * mfn_abs; | ||
214 | do_div(temp, mfd + 1); | ||
215 | if (mfn < 0) | ||
216 | temp = -temp; | ||
217 | temp = (ref_clk * mfi) + temp; | ||
218 | |||
219 | return temp; | ||
220 | } | ||
221 | |||
222 | static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) | ||
223 | { | ||
224 | u32 reg; | ||
225 | void __iomem *pllbase; | ||
226 | |||
227 | long mfi, pdf, mfn, mfd = 999999; | ||
228 | s64 temp64; | ||
229 | unsigned long quad_parent_rate; | ||
230 | unsigned long pll_hfsm, dp_ctl; | ||
231 | unsigned long parent_rate; | ||
232 | |||
233 | parent_rate = clk_get_rate(clk->parent); | ||
234 | |||
235 | pllbase = _get_pll_base(clk); | ||
236 | |||
237 | quad_parent_rate = 4 * parent_rate; | ||
238 | pdf = mfi = -1; | ||
239 | while (++pdf < 16 && mfi < 5) | ||
240 | mfi = rate * (pdf+1) / quad_parent_rate; | ||
241 | if (mfi > 15) | ||
242 | return -EINVAL; | ||
243 | pdf--; | ||
244 | |||
245 | temp64 = rate * (pdf+1) - quad_parent_rate * mfi; | ||
246 | do_div(temp64, quad_parent_rate/1000000); | ||
247 | mfn = (long)temp64; | ||
248 | |||
249 | dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
250 | /* use dpdck0_2 */ | ||
251 | __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); | ||
252 | pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; | ||
253 | if (pll_hfsm == 0) { | ||
254 | reg = mfi << 4 | pdf; | ||
255 | __raw_writel(reg, pllbase + MXC_PLL_DP_OP); | ||
256 | __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD); | ||
257 | __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN); | ||
258 | } else { | ||
259 | reg = mfi << 4 | pdf; | ||
260 | __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP); | ||
261 | __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD); | ||
262 | __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN); | ||
263 | } | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | static int _clk_pll_enable(struct clk *clk) | ||
269 | { | ||
270 | u32 reg; | ||
271 | void __iomem *pllbase; | ||
272 | int i = 0; | ||
273 | |||
274 | pllbase = _get_pll_base(clk); | ||
275 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
276 | if (reg & MXC_PLL_DP_CTL_UPEN) | ||
277 | return 0; | ||
278 | |||
279 | reg |= MXC_PLL_DP_CTL_UPEN; | ||
280 | __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); | ||
281 | |||
282 | /* Wait for lock */ | ||
283 | do { | ||
284 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); | ||
285 | if (reg & MXC_PLL_DP_CTL_LRF) | ||
286 | break; | ||
287 | |||
288 | udelay(1); | ||
289 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
290 | |||
291 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
292 | pr_err("MX5: pll locking failed\n"); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static void _clk_pll_disable(struct clk *clk) | ||
300 | { | ||
301 | u32 reg; | ||
302 | void __iomem *pllbase; | ||
303 | |||
304 | pllbase = _get_pll_base(clk); | ||
305 | reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; | ||
306 | __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); | ||
307 | } | ||
308 | |||
309 | static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent) | ||
310 | { | ||
311 | u32 reg, step; | ||
312 | |||
313 | reg = __raw_readl(MXC_CCM_CCSR); | ||
314 | |||
315 | /* When switching from pll_main_clk to a bypass clock, first select a | ||
316 | * multiplexed clock in 'step_sel', then shift the glitchless mux | ||
317 | * 'pll1_sw_clk_sel'. | ||
318 | * | ||
319 | * When switching back, do it in reverse order | ||
320 | */ | ||
321 | if (parent == &pll1_main_clk) { | ||
322 | /* Switch to pll1_main_clk */ | ||
323 | reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; | ||
324 | __raw_writel(reg, MXC_CCM_CCSR); | ||
325 | /* step_clk mux switched to lp_apm, to save power. */ | ||
326 | reg = __raw_readl(MXC_CCM_CCSR); | ||
327 | reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; | ||
328 | reg |= (MXC_CCM_CCSR_STEP_SEL_LP_APM << | ||
329 | MXC_CCM_CCSR_STEP_SEL_OFFSET); | ||
330 | } else { | ||
331 | if (parent == &lp_apm_clk) { | ||
332 | step = MXC_CCM_CCSR_STEP_SEL_LP_APM; | ||
333 | } else if (parent == &pll2_sw_clk) { | ||
334 | step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED; | ||
335 | } else if (parent == &pll3_sw_clk) { | ||
336 | step = MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED; | ||
337 | } else | ||
338 | return -EINVAL; | ||
339 | |||
340 | reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK; | ||
341 | reg |= (step << MXC_CCM_CCSR_STEP_SEL_OFFSET); | ||
342 | |||
343 | __raw_writel(reg, MXC_CCM_CCSR); | ||
344 | /* Switch to step_clk */ | ||
345 | reg = __raw_readl(MXC_CCM_CCSR); | ||
346 | reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; | ||
347 | } | ||
348 | __raw_writel(reg, MXC_CCM_CCSR); | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static unsigned long clk_pll1_sw_get_rate(struct clk *clk) | ||
353 | { | ||
354 | u32 reg, div; | ||
355 | unsigned long parent_rate; | ||
356 | |||
357 | parent_rate = clk_get_rate(clk->parent); | ||
358 | |||
359 | reg = __raw_readl(MXC_CCM_CCSR); | ||
360 | |||
361 | if (clk->parent == &pll2_sw_clk) { | ||
362 | div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >> | ||
363 | MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1; | ||
364 | } else if (clk->parent == &pll3_sw_clk) { | ||
365 | div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >> | ||
366 | MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1; | ||
367 | } else | ||
368 | div = 1; | ||
369 | return parent_rate / div; | ||
370 | } | ||
371 | |||
372 | static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent) | ||
373 | { | ||
374 | u32 reg; | ||
375 | |||
376 | reg = __raw_readl(MXC_CCM_CCSR); | ||
377 | |||
378 | if (parent == &pll2_sw_clk) | ||
379 | reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL; | ||
380 | else | ||
381 | reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL; | ||
382 | |||
383 | __raw_writel(reg, MXC_CCM_CCSR); | ||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent) | ||
388 | { | ||
389 | u32 reg; | ||
390 | |||
391 | if (parent == &osc_clk) | ||
392 | reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL; | ||
393 | else | ||
394 | return -EINVAL; | ||
395 | |||
396 | __raw_writel(reg, MXC_CCM_CCSR); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static unsigned long clk_cpu_get_rate(struct clk *clk) | ||
402 | { | ||
403 | u32 cacrr, div; | ||
404 | unsigned long parent_rate; | ||
405 | |||
406 | parent_rate = clk_get_rate(clk->parent); | ||
407 | cacrr = __raw_readl(MXC_CCM_CACRR); | ||
408 | div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; | ||
409 | |||
410 | return parent_rate / div; | ||
411 | } | ||
412 | |||
413 | static int clk_cpu_set_rate(struct clk *clk, unsigned long rate) | ||
414 | { | ||
415 | u32 reg, cpu_podf; | ||
416 | unsigned long parent_rate; | ||
417 | |||
418 | parent_rate = clk_get_rate(clk->parent); | ||
419 | cpu_podf = parent_rate / rate - 1; | ||
420 | /* use post divider to change freq */ | ||
421 | reg = __raw_readl(MXC_CCM_CACRR); | ||
422 | reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK; | ||
423 | reg |= cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET; | ||
424 | __raw_writel(reg, MXC_CCM_CACRR); | ||
425 | |||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) | ||
430 | { | ||
431 | u32 reg, mux; | ||
432 | int i = 0; | ||
433 | |||
434 | mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL); | ||
435 | |||
436 | reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK; | ||
437 | reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET; | ||
438 | __raw_writel(reg, MXC_CCM_CBCMR); | ||
439 | |||
440 | /* Wait for lock */ | ||
441 | do { | ||
442 | reg = __raw_readl(MXC_CCM_CDHIPR); | ||
443 | if (!(reg & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)) | ||
444 | break; | ||
445 | |||
446 | udelay(1); | ||
447 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
448 | |||
449 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
450 | pr_err("MX5: Set parent for periph_apm clock failed\n"); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) | ||
458 | { | ||
459 | u32 reg; | ||
460 | |||
461 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
462 | |||
463 | if (parent == &pll2_sw_clk) | ||
464 | reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL; | ||
465 | else if (parent == &periph_apm_clk) | ||
466 | reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL; | ||
467 | else | ||
468 | return -EINVAL; | ||
469 | |||
470 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static struct clk main_bus_clk = { | ||
476 | .parent = &pll2_sw_clk, | ||
477 | .set_parent = _clk_main_bus_set_parent, | ||
478 | }; | ||
479 | |||
480 | static unsigned long clk_ahb_get_rate(struct clk *clk) | ||
481 | { | ||
482 | u32 reg, div; | ||
483 | unsigned long parent_rate; | ||
484 | |||
485 | parent_rate = clk_get_rate(clk->parent); | ||
486 | |||
487 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
488 | div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> | ||
489 | MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; | ||
490 | return parent_rate / div; | ||
491 | } | ||
492 | |||
493 | |||
494 | static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate) | ||
495 | { | ||
496 | u32 reg, div; | ||
497 | unsigned long parent_rate; | ||
498 | int i = 0; | ||
499 | |||
500 | parent_rate = clk_get_rate(clk->parent); | ||
501 | |||
502 | div = parent_rate / rate; | ||
503 | if (div > 8 || div < 1 || ((parent_rate / div) != rate)) | ||
504 | return -EINVAL; | ||
505 | |||
506 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
507 | reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK; | ||
508 | reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET; | ||
509 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
510 | |||
511 | /* Wait for lock */ | ||
512 | do { | ||
513 | reg = __raw_readl(MXC_CCM_CDHIPR); | ||
514 | if (!(reg & MXC_CCM_CDHIPR_AHB_PODF_BUSY)) | ||
515 | break; | ||
516 | |||
517 | udelay(1); | ||
518 | } while (++i < MAX_DPLL_WAIT_TRIES); | ||
519 | |||
520 | if (i == MAX_DPLL_WAIT_TRIES) { | ||
521 | pr_err("MX5: clk_ahb_set_rate failed\n"); | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | static unsigned long _clk_ahb_round_rate(struct clk *clk, | ||
529 | unsigned long rate) | ||
530 | { | ||
531 | u32 div; | ||
532 | unsigned long parent_rate; | ||
533 | |||
534 | parent_rate = clk_get_rate(clk->parent); | ||
535 | |||
536 | div = parent_rate / rate; | ||
537 | if (div > 8) | ||
538 | div = 8; | ||
539 | else if (div == 0) | ||
540 | div++; | ||
541 | return parent_rate / div; | ||
542 | } | ||
543 | |||
544 | |||
545 | static int _clk_max_enable(struct clk *clk) | ||
546 | { | ||
547 | u32 reg; | ||
548 | |||
549 | _clk_ccgr_enable(clk); | ||
550 | |||
551 | /* Handshake with MAX when LPM is entered. */ | ||
552 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
553 | if (cpu_is_mx51()) | ||
554 | reg &= ~MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
555 | else if (cpu_is_mx53()) | ||
556 | reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
557 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static void _clk_max_disable(struct clk *clk) | ||
563 | { | ||
564 | u32 reg; | ||
565 | |||
566 | _clk_ccgr_disable_inwait(clk); | ||
567 | |||
568 | /* No Handshake with MAX when LPM is entered as its disabled. */ | ||
569 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
570 | if (cpu_is_mx51()) | ||
571 | reg |= MX51_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
572 | else if (cpu_is_mx53()) | ||
573 | reg &= ~MX53_CCM_CLPCR_BYPASS_MAX_LPM_HS; | ||
574 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
575 | } | ||
576 | |||
577 | static unsigned long clk_ipg_get_rate(struct clk *clk) | ||
578 | { | ||
579 | u32 reg, div; | ||
580 | unsigned long parent_rate; | ||
581 | |||
582 | parent_rate = clk_get_rate(clk->parent); | ||
583 | |||
584 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
585 | div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> | ||
586 | MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; | ||
587 | |||
588 | return parent_rate / div; | ||
589 | } | ||
590 | |||
591 | static unsigned long clk_ipg_per_get_rate(struct clk *clk) | ||
592 | { | ||
593 | u32 reg, prediv1, prediv2, podf; | ||
594 | unsigned long parent_rate; | ||
595 | |||
596 | parent_rate = clk_get_rate(clk->parent); | ||
597 | |||
598 | if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) { | ||
599 | /* the main_bus_clk is the one before the DVFS engine */ | ||
600 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
601 | prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> | ||
602 | MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1; | ||
603 | prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> | ||
604 | MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1; | ||
605 | podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> | ||
606 | MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1; | ||
607 | return parent_rate / (prediv1 * prediv2 * podf); | ||
608 | } else if (clk->parent == &ipg_clk) | ||
609 | return parent_rate; | ||
610 | else | ||
611 | BUG(); | ||
612 | } | ||
613 | |||
614 | static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) | ||
615 | { | ||
616 | u32 reg; | ||
617 | |||
618 | reg = __raw_readl(MXC_CCM_CBCMR); | ||
619 | |||
620 | reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; | ||
621 | reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; | ||
622 | |||
623 | if (parent == &ipg_clk) | ||
624 | reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; | ||
625 | else if (parent == &lp_apm_clk) | ||
626 | reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; | ||
627 | else if (parent != &main_bus_clk) | ||
628 | return -EINVAL; | ||
629 | |||
630 | __raw_writel(reg, MXC_CCM_CBCMR); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | #define clk_nfc_set_parent NULL | ||
636 | |||
637 | static unsigned long clk_nfc_get_rate(struct clk *clk) | ||
638 | { | ||
639 | unsigned long rate; | ||
640 | u32 reg, div; | ||
641 | |||
642 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
643 | div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >> | ||
644 | MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1; | ||
645 | rate = clk_get_rate(clk->parent) / div; | ||
646 | WARN_ON(rate == 0); | ||
647 | return rate; | ||
648 | } | ||
649 | |||
650 | static unsigned long clk_nfc_round_rate(struct clk *clk, | ||
651 | unsigned long rate) | ||
652 | { | ||
653 | u32 div; | ||
654 | unsigned long parent_rate = clk_get_rate(clk->parent); | ||
655 | |||
656 | if (!rate) | ||
657 | return -EINVAL; | ||
658 | |||
659 | div = parent_rate / rate; | ||
660 | |||
661 | if (parent_rate % rate) | ||
662 | div++; | ||
663 | |||
664 | if (div > 8) | ||
665 | return -EINVAL; | ||
666 | |||
667 | return parent_rate / div; | ||
668 | |||
669 | } | ||
670 | |||
671 | static int clk_nfc_set_rate(struct clk *clk, unsigned long rate) | ||
672 | { | ||
673 | u32 reg, div; | ||
674 | |||
675 | div = clk_get_rate(clk->parent) / rate; | ||
676 | if (div == 0) | ||
677 | div++; | ||
678 | if (((clk_get_rate(clk->parent) / div) != rate) || (div > 8)) | ||
679 | return -EINVAL; | ||
680 | |||
681 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
682 | reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK; | ||
683 | reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET; | ||
684 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
685 | |||
686 | while (__raw_readl(MXC_CCM_CDHIPR) & | ||
687 | MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY){ | ||
688 | } | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static unsigned long get_high_reference_clock_rate(struct clk *clk) | ||
694 | { | ||
695 | return external_high_reference; | ||
696 | } | ||
697 | |||
698 | static unsigned long get_low_reference_clock_rate(struct clk *clk) | ||
699 | { | ||
700 | return external_low_reference; | ||
701 | } | ||
702 | |||
703 | static unsigned long get_oscillator_reference_clock_rate(struct clk *clk) | ||
704 | { | ||
705 | return oscillator_reference; | ||
706 | } | ||
707 | |||
708 | static unsigned long get_ckih2_reference_clock_rate(struct clk *clk) | ||
709 | { | ||
710 | return ckih2_reference; | ||
711 | } | ||
712 | |||
713 | static unsigned long clk_emi_slow_get_rate(struct clk *clk) | ||
714 | { | ||
715 | u32 reg, div; | ||
716 | |||
717 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
718 | div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> | ||
719 | MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; | ||
720 | |||
721 | return clk_get_rate(clk->parent) / div; | ||
722 | } | ||
723 | |||
724 | static unsigned long _clk_ddr_hf_get_rate(struct clk *clk) | ||
725 | { | ||
726 | unsigned long rate; | ||
727 | u32 reg, div; | ||
728 | |||
729 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
730 | div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >> | ||
731 | MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1; | ||
732 | rate = clk_get_rate(clk->parent) / div; | ||
733 | |||
734 | return rate; | ||
735 | } | ||
736 | |||
737 | /* External high frequency clock */ | ||
738 | static struct clk ckih_clk = { | ||
739 | .get_rate = get_high_reference_clock_rate, | ||
740 | }; | ||
741 | |||
742 | static struct clk ckih2_clk = { | ||
743 | .get_rate = get_ckih2_reference_clock_rate, | ||
744 | }; | ||
745 | |||
746 | static struct clk osc_clk = { | ||
747 | .get_rate = get_oscillator_reference_clock_rate, | ||
748 | }; | ||
749 | |||
750 | /* External low frequency (32kHz) clock */ | ||
751 | static struct clk ckil_clk = { | ||
752 | .get_rate = get_low_reference_clock_rate, | ||
753 | }; | ||
754 | |||
755 | static struct clk pll1_main_clk = { | ||
756 | .parent = &osc_clk, | ||
757 | .get_rate = clk_pll_get_rate, | ||
758 | .enable = _clk_pll_enable, | ||
759 | .disable = _clk_pll_disable, | ||
760 | }; | ||
761 | |||
762 | /* Clock tree block diagram (WIP): | ||
763 | * CCM: Clock Controller Module | ||
764 | * | ||
765 | * PLL output -> | | ||
766 | * | CCM Switcher -> CCM_CLK_ROOT_GEN -> | ||
767 | * PLL bypass -> | | ||
768 | * | ||
769 | */ | ||
770 | |||
771 | /* PLL1 SW supplies to ARM core */ | ||
772 | static struct clk pll1_sw_clk = { | ||
773 | .parent = &pll1_main_clk, | ||
774 | .set_parent = _clk_pll1_sw_set_parent, | ||
775 | .get_rate = clk_pll1_sw_get_rate, | ||
776 | }; | ||
777 | |||
778 | /* PLL2 SW supplies to AXI/AHB/IP buses */ | ||
779 | static struct clk pll2_sw_clk = { | ||
780 | .parent = &osc_clk, | ||
781 | .get_rate = clk_pll_get_rate, | ||
782 | .set_rate = _clk_pll_set_rate, | ||
783 | .set_parent = _clk_pll2_sw_set_parent, | ||
784 | .enable = _clk_pll_enable, | ||
785 | .disable = _clk_pll_disable, | ||
786 | }; | ||
787 | |||
788 | /* PLL3 SW supplies to serial clocks like USB, SSI, etc. */ | ||
789 | static struct clk pll3_sw_clk = { | ||
790 | .parent = &osc_clk, | ||
791 | .set_rate = _clk_pll_set_rate, | ||
792 | .get_rate = clk_pll_get_rate, | ||
793 | .enable = _clk_pll_enable, | ||
794 | .disable = _clk_pll_disable, | ||
795 | }; | ||
796 | |||
797 | /* PLL4 SW supplies to LVDS Display Bridge(LDB) */ | ||
798 | static struct clk mx53_pll4_sw_clk = { | ||
799 | .parent = &osc_clk, | ||
800 | .set_rate = _clk_pll_set_rate, | ||
801 | .enable = _clk_pll_enable, | ||
802 | .disable = _clk_pll_disable, | ||
803 | }; | ||
804 | |||
805 | /* Low-power Audio Playback Mode clock */ | ||
806 | static struct clk lp_apm_clk = { | ||
807 | .parent = &osc_clk, | ||
808 | .set_parent = _clk_lp_apm_set_parent, | ||
809 | }; | ||
810 | |||
811 | static struct clk periph_apm_clk = { | ||
812 | .parent = &pll1_sw_clk, | ||
813 | .set_parent = _clk_periph_apm_set_parent, | ||
814 | }; | ||
815 | |||
816 | static struct clk cpu_clk = { | ||
817 | .parent = &pll1_sw_clk, | ||
818 | .get_rate = clk_cpu_get_rate, | ||
819 | .set_rate = clk_cpu_set_rate, | ||
820 | }; | ||
821 | |||
822 | static struct clk ahb_clk = { | ||
823 | .parent = &main_bus_clk, | ||
824 | .get_rate = clk_ahb_get_rate, | ||
825 | .set_rate = _clk_ahb_set_rate, | ||
826 | .round_rate = _clk_ahb_round_rate, | ||
827 | }; | ||
828 | |||
829 | static struct clk iim_clk = { | ||
830 | .parent = &ipg_clk, | ||
831 | .enable_reg = MXC_CCM_CCGR0, | ||
832 | .enable_shift = MXC_CCM_CCGRx_CG15_OFFSET, | ||
833 | }; | ||
834 | |||
835 | /* Main IP interface clock for access to registers */ | ||
836 | static struct clk ipg_clk = { | ||
837 | .parent = &ahb_clk, | ||
838 | .get_rate = clk_ipg_get_rate, | ||
839 | }; | ||
840 | |||
841 | static struct clk ipg_perclk = { | ||
842 | .parent = &lp_apm_clk, | ||
843 | .get_rate = clk_ipg_per_get_rate, | ||
844 | .set_parent = _clk_ipg_per_set_parent, | ||
845 | }; | ||
846 | |||
847 | static struct clk ahb_max_clk = { | ||
848 | .parent = &ahb_clk, | ||
849 | .enable_reg = MXC_CCM_CCGR0, | ||
850 | .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, | ||
851 | .enable = _clk_max_enable, | ||
852 | .disable = _clk_max_disable, | ||
853 | }; | ||
854 | |||
855 | static struct clk aips_tz1_clk = { | ||
856 | .parent = &ahb_clk, | ||
857 | .secondary = &ahb_max_clk, | ||
858 | .enable_reg = MXC_CCM_CCGR0, | ||
859 | .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, | ||
860 | .enable = _clk_ccgr_enable, | ||
861 | .disable = _clk_ccgr_disable_inwait, | ||
862 | }; | ||
863 | |||
864 | static struct clk aips_tz2_clk = { | ||
865 | .parent = &ahb_clk, | ||
866 | .secondary = &ahb_max_clk, | ||
867 | .enable_reg = MXC_CCM_CCGR0, | ||
868 | .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, | ||
869 | .enable = _clk_ccgr_enable, | ||
870 | .disable = _clk_ccgr_disable_inwait, | ||
871 | }; | ||
872 | |||
873 | static struct clk gpc_dvfs_clk = { | ||
874 | .enable_reg = MXC_CCM_CCGR5, | ||
875 | .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET, | ||
876 | .enable = _clk_ccgr_enable, | ||
877 | .disable = _clk_ccgr_disable, | ||
878 | }; | ||
879 | |||
880 | static struct clk gpt_32k_clk = { | ||
881 | .id = 0, | ||
882 | .parent = &ckil_clk, | ||
883 | }; | ||
884 | |||
885 | static struct clk dummy_clk = { | ||
886 | .id = 0, | ||
887 | }; | ||
888 | |||
889 | static struct clk emi_slow_clk = { | ||
890 | .parent = &pll2_sw_clk, | ||
891 | .enable_reg = MXC_CCM_CCGR5, | ||
892 | .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, | ||
893 | .enable = _clk_ccgr_enable, | ||
894 | .disable = _clk_ccgr_disable_inwait, | ||
895 | .get_rate = clk_emi_slow_get_rate, | ||
896 | }; | ||
897 | |||
898 | static int clk_ipu_enable(struct clk *clk) | ||
899 | { | ||
900 | u32 reg; | ||
901 | |||
902 | _clk_ccgr_enable(clk); | ||
903 | |||
904 | /* Enable handshake with IPU when certain clock rates are changed */ | ||
905 | reg = __raw_readl(MXC_CCM_CCDR); | ||
906 | reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; | ||
907 | __raw_writel(reg, MXC_CCM_CCDR); | ||
908 | |||
909 | /* Enable handshake with IPU when LPM is entered */ | ||
910 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
911 | reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; | ||
912 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
913 | |||
914 | return 0; | ||
915 | } | ||
916 | |||
917 | static void clk_ipu_disable(struct clk *clk) | ||
918 | { | ||
919 | u32 reg; | ||
920 | |||
921 | _clk_ccgr_disable(clk); | ||
922 | |||
923 | /* Disable handshake with IPU whe dividers are changed */ | ||
924 | reg = __raw_readl(MXC_CCM_CCDR); | ||
925 | reg |= MXC_CCM_CCDR_IPU_HS_MASK; | ||
926 | __raw_writel(reg, MXC_CCM_CCDR); | ||
927 | |||
928 | /* Disable handshake with IPU when LPM is entered */ | ||
929 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
930 | reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; | ||
931 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
932 | } | ||
933 | |||
934 | static struct clk ahbmux1_clk = { | ||
935 | .parent = &ahb_clk, | ||
936 | .secondary = &ahb_max_clk, | ||
937 | .enable_reg = MXC_CCM_CCGR0, | ||
938 | .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET, | ||
939 | .enable = _clk_ccgr_enable, | ||
940 | .disable = _clk_ccgr_disable_inwait, | ||
941 | }; | ||
942 | |||
943 | static struct clk ipu_sec_clk = { | ||
944 | .parent = &emi_fast_clk, | ||
945 | .secondary = &ahbmux1_clk, | ||
946 | }; | ||
947 | |||
948 | static struct clk ddr_hf_clk = { | ||
949 | .parent = &pll1_sw_clk, | ||
950 | .get_rate = _clk_ddr_hf_get_rate, | ||
951 | }; | ||
952 | |||
953 | static struct clk ddr_clk = { | ||
954 | .parent = &ddr_hf_clk, | ||
955 | }; | ||
956 | |||
957 | /* clock definitions for MIPI HSC unit which has been removed | ||
958 | * from documentation, but not from hardware | ||
959 | */ | ||
960 | static int _clk_hsc_enable(struct clk *clk) | ||
961 | { | ||
962 | u32 reg; | ||
963 | |||
964 | _clk_ccgr_enable(clk); | ||
965 | /* Handshake with IPU when certain clock rates are changed. */ | ||
966 | reg = __raw_readl(MXC_CCM_CCDR); | ||
967 | reg &= ~MXC_CCM_CCDR_HSC_HS_MASK; | ||
968 | __raw_writel(reg, MXC_CCM_CCDR); | ||
969 | |||
970 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
971 | reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; | ||
972 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
973 | |||
974 | return 0; | ||
975 | } | ||
976 | |||
977 | static void _clk_hsc_disable(struct clk *clk) | ||
978 | { | ||
979 | u32 reg; | ||
980 | |||
981 | _clk_ccgr_disable(clk); | ||
982 | /* No handshake with HSC as its not enabled. */ | ||
983 | reg = __raw_readl(MXC_CCM_CCDR); | ||
984 | reg |= MXC_CCM_CCDR_HSC_HS_MASK; | ||
985 | __raw_writel(reg, MXC_CCM_CCDR); | ||
986 | |||
987 | reg = __raw_readl(MXC_CCM_CLPCR); | ||
988 | reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; | ||
989 | __raw_writel(reg, MXC_CCM_CLPCR); | ||
990 | } | ||
991 | |||
992 | static struct clk mipi_hsp_clk = { | ||
993 | .parent = &ipu_clk, | ||
994 | .enable_reg = MXC_CCM_CCGR4, | ||
995 | .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET, | ||
996 | .enable = _clk_hsc_enable, | ||
997 | .disable = _clk_hsc_disable, | ||
998 | .secondary = &mipi_hsc1_clk, | ||
999 | }; | ||
1000 | |||
1001 | #define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ | ||
1002 | static struct clk name = { \ | ||
1003 | .id = i, \ | ||
1004 | .enable_reg = er, \ | ||
1005 | .enable_shift = es, \ | ||
1006 | .get_rate = pfx##_get_rate, \ | ||
1007 | .set_rate = pfx##_set_rate, \ | ||
1008 | .round_rate = pfx##_round_rate, \ | ||
1009 | .set_parent = pfx##_set_parent, \ | ||
1010 | .enable = _clk_ccgr_enable, \ | ||
1011 | .disable = _clk_ccgr_disable, \ | ||
1012 | .parent = p, \ | ||
1013 | .secondary = s, \ | ||
1014 | } | ||
1015 | |||
1016 | #define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \ | ||
1017 | static struct clk name = { \ | ||
1018 | .id = i, \ | ||
1019 | .enable_reg = er, \ | ||
1020 | .enable_shift = es, \ | ||
1021 | .get_rate = pfx##_get_rate, \ | ||
1022 | .set_rate = pfx##_set_rate, \ | ||
1023 | .set_parent = pfx##_set_parent, \ | ||
1024 | .enable = _clk_max_enable, \ | ||
1025 | .disable = _clk_max_disable, \ | ||
1026 | .parent = p, \ | ||
1027 | .secondary = s, \ | ||
1028 | } | ||
1029 | |||
1030 | #define CLK_GET_RATE(name, nr, bitsname) \ | ||
1031 | static unsigned long clk_##name##_get_rate(struct clk *clk) \ | ||
1032 | { \ | ||
1033 | u32 reg, pred, podf; \ | ||
1034 | \ | ||
1035 | reg = __raw_readl(MXC_CCM_CSCDR##nr); \ | ||
1036 | pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \ | ||
1037 | >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ | ||
1038 | podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \ | ||
1039 | >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ | ||
1040 | \ | ||
1041 | return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \ | ||
1042 | (pred + 1) * (podf + 1)); \ | ||
1043 | } | ||
1044 | |||
1045 | #define CLK_SET_PARENT(name, nr, bitsname) \ | ||
1046 | static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ | ||
1047 | { \ | ||
1048 | u32 reg, mux; \ | ||
1049 | \ | ||
1050 | mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \ | ||
1051 | &pll3_sw_clk, &lp_apm_clk); \ | ||
1052 | reg = __raw_readl(MXC_CCM_CSCMR##nr) & \ | ||
1053 | ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \ | ||
1054 | reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \ | ||
1055 | __raw_writel(reg, MXC_CCM_CSCMR##nr); \ | ||
1056 | \ | ||
1057 | return 0; \ | ||
1058 | } | ||
1059 | |||
1060 | #define CLK_SET_RATE(name, nr, bitsname) \ | ||
1061 | static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \ | ||
1062 | { \ | ||
1063 | u32 reg, div, parent_rate; \ | ||
1064 | u32 pre = 0, post = 0; \ | ||
1065 | \ | ||
1066 | parent_rate = clk_get_rate(clk->parent); \ | ||
1067 | div = parent_rate / rate; \ | ||
1068 | \ | ||
1069 | if ((parent_rate / div) != rate) \ | ||
1070 | return -EINVAL; \ | ||
1071 | \ | ||
1072 | __calc_pre_post_dividers(div, &pre, &post, \ | ||
1073 | (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \ | ||
1074 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \ | ||
1075 | (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \ | ||
1076 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\ | ||
1077 | \ | ||
1078 | /* Set sdhc1 clock divider */ \ | ||
1079 | reg = __raw_readl(MXC_CCM_CSCDR##nr) & \ | ||
1080 | ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \ | ||
1081 | | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \ | ||
1082 | reg |= (post - 1) << \ | ||
1083 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \ | ||
1084 | reg |= (pre - 1) << \ | ||
1085 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \ | ||
1086 | __raw_writel(reg, MXC_CCM_CSCDR##nr); \ | ||
1087 | \ | ||
1088 | return 0; \ | ||
1089 | } | ||
1090 | |||
1091 | /* UART */ | ||
1092 | CLK_GET_RATE(uart, 1, UART) | ||
1093 | CLK_SET_PARENT(uart, 1, UART) | ||
1094 | |||
1095 | static struct clk uart_root_clk = { | ||
1096 | .parent = &pll2_sw_clk, | ||
1097 | .get_rate = clk_uart_get_rate, | ||
1098 | .set_parent = clk_uart_set_parent, | ||
1099 | }; | ||
1100 | |||
1101 | /* USBOH3 */ | ||
1102 | CLK_GET_RATE(usboh3, 1, USBOH3) | ||
1103 | CLK_SET_PARENT(usboh3, 1, USBOH3) | ||
1104 | |||
1105 | static struct clk usboh3_clk = { | ||
1106 | .parent = &pll2_sw_clk, | ||
1107 | .get_rate = clk_usboh3_get_rate, | ||
1108 | .set_parent = clk_usboh3_set_parent, | ||
1109 | .enable = _clk_ccgr_enable, | ||
1110 | .disable = _clk_ccgr_disable, | ||
1111 | .enable_reg = MXC_CCM_CCGR2, | ||
1112 | .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET, | ||
1113 | }; | ||
1114 | |||
1115 | static struct clk usb_ahb_clk = { | ||
1116 | .parent = &ipg_clk, | ||
1117 | .enable = _clk_ccgr_enable, | ||
1118 | .disable = _clk_ccgr_disable, | ||
1119 | .enable_reg = MXC_CCM_CCGR2, | ||
1120 | .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET, | ||
1121 | }; | ||
1122 | |||
1123 | static int clk_usb_phy1_set_parent(struct clk *clk, struct clk *parent) | ||
1124 | { | ||
1125 | u32 reg; | ||
1126 | |||
1127 | reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; | ||
1128 | |||
1129 | if (parent == &pll3_sw_clk) | ||
1130 | reg |= 1 << MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET; | ||
1131 | |||
1132 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1133 | |||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static struct clk usb_phy1_clk = { | ||
1138 | .parent = &pll3_sw_clk, | ||
1139 | .set_parent = clk_usb_phy1_set_parent, | ||
1140 | .enable = _clk_ccgr_enable, | ||
1141 | .enable_reg = MXC_CCM_CCGR2, | ||
1142 | .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, | ||
1143 | .disable = _clk_ccgr_disable, | ||
1144 | }; | ||
1145 | |||
1146 | /* eCSPI */ | ||
1147 | CLK_GET_RATE(ecspi, 2, CSPI) | ||
1148 | CLK_SET_PARENT(ecspi, 1, CSPI) | ||
1149 | |||
1150 | static struct clk ecspi_main_clk = { | ||
1151 | .parent = &pll3_sw_clk, | ||
1152 | .get_rate = clk_ecspi_get_rate, | ||
1153 | .set_parent = clk_ecspi_set_parent, | ||
1154 | }; | ||
1155 | |||
1156 | /* eSDHC */ | ||
1157 | CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1) | ||
1158 | CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1) | ||
1159 | CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1) | ||
1160 | |||
1161 | /* mx51 specific */ | ||
1162 | CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2) | ||
1163 | CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2) | ||
1164 | CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2) | ||
1165 | |||
1166 | static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent) | ||
1167 | { | ||
1168 | u32 reg; | ||
1169 | |||
1170 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1171 | if (parent == &esdhc1_clk) | ||
1172 | reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; | ||
1173 | else if (parent == &esdhc2_clk) | ||
1174 | reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; | ||
1175 | else | ||
1176 | return -EINVAL; | ||
1177 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1178 | |||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent) | ||
1183 | { | ||
1184 | u32 reg; | ||
1185 | |||
1186 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1187 | if (parent == &esdhc1_clk) | ||
1188 | reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1189 | else if (parent == &esdhc2_clk) | ||
1190 | reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1191 | else | ||
1192 | return -EINVAL; | ||
1193 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1194 | |||
1195 | return 0; | ||
1196 | } | ||
1197 | |||
1198 | /* mx53 specific */ | ||
1199 | static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent) | ||
1200 | { | ||
1201 | u32 reg; | ||
1202 | |||
1203 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1204 | if (parent == &esdhc1_clk) | ||
1205 | reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; | ||
1206 | else if (parent == &esdhc3_mx53_clk) | ||
1207 | reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL; | ||
1208 | else | ||
1209 | return -EINVAL; | ||
1210 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1211 | |||
1212 | return 0; | ||
1213 | } | ||
1214 | |||
1215 | CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1216 | CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1217 | CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53) | ||
1218 | |||
1219 | static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent) | ||
1220 | { | ||
1221 | u32 reg; | ||
1222 | |||
1223 | reg = __raw_readl(MXC_CCM_CSCMR1); | ||
1224 | if (parent == &esdhc1_clk) | ||
1225 | reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1226 | else if (parent == &esdhc3_mx53_clk) | ||
1227 | reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; | ||
1228 | else | ||
1229 | return -EINVAL; | ||
1230 | __raw_writel(reg, MXC_CCM_CSCMR1); | ||
1231 | |||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ | ||
1236 | static struct clk name = { \ | ||
1237 | .id = i, \ | ||
1238 | .enable_reg = er, \ | ||
1239 | .enable_shift = es, \ | ||
1240 | .get_rate = gr, \ | ||
1241 | .set_rate = sr, \ | ||
1242 | .enable = e, \ | ||
1243 | .disable = d, \ | ||
1244 | .parent = p, \ | ||
1245 | .secondary = s, \ | ||
1246 | } | ||
1247 | |||
1248 | #define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) \ | ||
1249 | DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable, _clk_ccgr_disable, p, s) | ||
1250 | |||
1251 | /* Shared peripheral bus arbiter */ | ||
1252 | DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1253 | NULL, NULL, &ipg_clk, NULL); | ||
1254 | |||
1255 | /* UART */ | ||
1256 | DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET, | ||
1257 | NULL, NULL, &ipg_clk, &aips_tz1_clk); | ||
1258 | DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1259 | NULL, NULL, &ipg_clk, &aips_tz1_clk); | ||
1260 | DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1261 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1262 | DEFINE_CLOCK(uart4_ipg_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1263 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1264 | DEFINE_CLOCK(uart5_ipg_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1265 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1266 | DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1267 | NULL, NULL, &uart_root_clk, &uart1_ipg_clk); | ||
1268 | DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1269 | NULL, NULL, &uart_root_clk, &uart2_ipg_clk); | ||
1270 | DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1271 | NULL, NULL, &uart_root_clk, &uart3_ipg_clk); | ||
1272 | DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1273 | NULL, NULL, &uart_root_clk, &uart4_ipg_clk); | ||
1274 | DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CCGR7, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1275 | NULL, NULL, &uart_root_clk, &uart5_ipg_clk); | ||
1276 | |||
1277 | /* GPT */ | ||
1278 | DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1279 | NULL, NULL, &ipg_clk, NULL); | ||
1280 | DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1281 | NULL, NULL, &ipg_clk, &gpt_ipg_clk); | ||
1282 | |||
1283 | DEFINE_CLOCK(pwm1_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1284 | NULL, NULL, &ipg_perclk, NULL); | ||
1285 | DEFINE_CLOCK(pwm2_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1286 | NULL, NULL, &ipg_perclk, NULL); | ||
1287 | |||
1288 | /* I2C */ | ||
1289 | DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1290 | NULL, NULL, &ipg_perclk, NULL); | ||
1291 | DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1292 | NULL, NULL, &ipg_perclk, NULL); | ||
1293 | DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1294 | NULL, NULL, &ipg_clk, NULL); | ||
1295 | DEFINE_CLOCK(i2c3_mx53_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1296 | NULL, NULL, &ipg_perclk, NULL); | ||
1297 | |||
1298 | /* FEC */ | ||
1299 | DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1300 | NULL, NULL, &ipg_clk, NULL); | ||
1301 | |||
1302 | /* NFC */ | ||
1303 | DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1304 | clk_nfc, &emi_slow_clk, NULL); | ||
1305 | |||
1306 | /* SSI */ | ||
1307 | DEFINE_CLOCK(ssi1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG8_OFFSET, | ||
1308 | NULL, NULL, &ipg_clk, NULL); | ||
1309 | DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1310 | NULL, NULL, &pll3_sw_clk, &ssi1_ipg_clk); | ||
1311 | DEFINE_CLOCK(ssi2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1312 | NULL, NULL, &ipg_clk, NULL); | ||
1313 | DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1314 | NULL, NULL, &pll3_sw_clk, &ssi2_ipg_clk); | ||
1315 | DEFINE_CLOCK(ssi3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1316 | NULL, NULL, &ipg_clk, NULL); | ||
1317 | DEFINE_CLOCK(ssi3_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG13_OFFSET, | ||
1318 | NULL, NULL, &pll3_sw_clk, &ssi3_ipg_clk); | ||
1319 | |||
1320 | /* eCSPI */ | ||
1321 | DEFINE_CLOCK_FULL(ecspi1_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1322 | NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, | ||
1323 | &ipg_clk, &spba_clk); | ||
1324 | DEFINE_CLOCK(ecspi1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG10_OFFSET, | ||
1325 | NULL, NULL, &ecspi_main_clk, &ecspi1_ipg_clk); | ||
1326 | DEFINE_CLOCK_FULL(ecspi2_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG11_OFFSET, | ||
1327 | NULL, NULL, _clk_ccgr_enable_inrun, _clk_ccgr_disable, | ||
1328 | &ipg_clk, &aips_tz2_clk); | ||
1329 | DEFINE_CLOCK(ecspi2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG12_OFFSET, | ||
1330 | NULL, NULL, &ecspi_main_clk, &ecspi2_ipg_clk); | ||
1331 | |||
1332 | /* CSPI */ | ||
1333 | DEFINE_CLOCK(cspi_ipg_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG9_OFFSET, | ||
1334 | NULL, NULL, &ipg_clk, &aips_tz2_clk); | ||
1335 | DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, | ||
1336 | NULL, NULL, &ipg_clk, &cspi_ipg_clk); | ||
1337 | |||
1338 | /* SDMA */ | ||
1339 | DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, | ||
1340 | NULL, NULL, &ahb_clk, NULL); | ||
1341 | |||
1342 | /* eSDHC */ | ||
1343 | DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1344 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1345 | DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET, | ||
1346 | clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk); | ||
1347 | DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET, | ||
1348 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1349 | DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET, | ||
1350 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1351 | DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1352 | NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL); | ||
1353 | |||
1354 | /* mx51 specific */ | ||
1355 | DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, | ||
1356 | clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); | ||
1357 | |||
1358 | static struct clk esdhc3_clk = { | ||
1359 | .id = 2, | ||
1360 | .parent = &esdhc1_clk, | ||
1361 | .set_parent = clk_esdhc3_set_parent, | ||
1362 | .enable_reg = MXC_CCM_CCGR3, | ||
1363 | .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET, | ||
1364 | .enable = _clk_max_enable, | ||
1365 | .disable = _clk_max_disable, | ||
1366 | .secondary = &esdhc3_ipg_clk, | ||
1367 | }; | ||
1368 | static struct clk esdhc4_clk = { | ||
1369 | .id = 3, | ||
1370 | .parent = &esdhc1_clk, | ||
1371 | .set_parent = clk_esdhc4_set_parent, | ||
1372 | .enable_reg = MXC_CCM_CCGR3, | ||
1373 | .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, | ||
1374 | .enable = _clk_max_enable, | ||
1375 | .disable = _clk_max_disable, | ||
1376 | .secondary = &esdhc4_ipg_clk, | ||
1377 | }; | ||
1378 | |||
1379 | /* mx53 specific */ | ||
1380 | static struct clk esdhc2_mx53_clk = { | ||
1381 | .id = 2, | ||
1382 | .parent = &esdhc1_clk, | ||
1383 | .set_parent = clk_esdhc2_mx53_set_parent, | ||
1384 | .enable_reg = MXC_CCM_CCGR3, | ||
1385 | .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET, | ||
1386 | .enable = _clk_max_enable, | ||
1387 | .disable = _clk_max_disable, | ||
1388 | .secondary = &esdhc3_ipg_clk, | ||
1389 | }; | ||
1390 | |||
1391 | DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1392 | clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk); | ||
1393 | |||
1394 | static struct clk esdhc4_mx53_clk = { | ||
1395 | .id = 3, | ||
1396 | .parent = &esdhc1_clk, | ||
1397 | .set_parent = clk_esdhc4_mx53_set_parent, | ||
1398 | .enable_reg = MXC_CCM_CCGR3, | ||
1399 | .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET, | ||
1400 | .enable = _clk_max_enable, | ||
1401 | .disable = _clk_max_disable, | ||
1402 | .secondary = &esdhc4_ipg_clk, | ||
1403 | }; | ||
1404 | |||
1405 | static struct clk sata_clk = { | ||
1406 | .parent = &ipg_clk, | ||
1407 | .enable = _clk_max_enable, | ||
1408 | .enable_reg = MXC_CCM_CCGR4, | ||
1409 | .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, | ||
1410 | .disable = _clk_max_disable, | ||
1411 | }; | ||
1412 | |||
1413 | static struct clk ahci_phy_clk = { | ||
1414 | .parent = &usb_phy1_clk, | ||
1415 | }; | ||
1416 | |||
1417 | static struct clk ahci_dma_clk = { | ||
1418 | .parent = &ahb_clk, | ||
1419 | }; | ||
1420 | |||
1421 | DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); | ||
1422 | DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); | ||
1423 | DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); | ||
1424 | |||
1425 | /* IPU */ | ||
1426 | DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1427 | NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk); | ||
1428 | |||
1429 | DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET, | ||
1430 | NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait, | ||
1431 | &ddr_clk, NULL); | ||
1432 | |||
1433 | DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET, | ||
1434 | NULL, NULL, &pll3_sw_clk, NULL); | ||
1435 | DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET, | ||
1436 | NULL, NULL, &pll3_sw_clk, NULL); | ||
1437 | |||
1438 | /* PATA */ | ||
1439 | DEFINE_CLOCK(pata_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG0_OFFSET, | ||
1440 | NULL, NULL, &ipg_clk, &spba_clk); | ||
1441 | |||
1442 | #define _REGISTER_CLOCK(d, n, c) \ | ||
1443 | { \ | ||
1444 | .dev_id = d, \ | ||
1445 | .con_id = n, \ | ||
1446 | .clk = &c, \ | ||
1447 | }, | ||
1448 | |||
1449 | static struct clk_lookup mx51_lookups[] = { | ||
1450 | /* i.mx51 has the i.mx21 type uart */ | ||
1451 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
1452 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
1453 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
1454 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
1455 | /* i.mx51 has the i.mx27 type fec */ | ||
1456 | _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk) | ||
1457 | _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) | ||
1458 | _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) | ||
1459 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
1460 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
1461 | _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk) | ||
1462 | _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk) | ||
1463 | _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", usb_ahb_clk) | ||
1464 | _REGISTER_CLOCK("mxc-ehci.0", "usb_phy1", usb_phy1_clk) | ||
1465 | _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk) | ||
1466 | _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", usb_ahb_clk) | ||
1467 | _REGISTER_CLOCK("mxc-ehci.2", "usb", usboh3_clk) | ||
1468 | _REGISTER_CLOCK("mxc-ehci.2", "usb_ahb", usb_ahb_clk) | ||
1469 | _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk) | ||
1470 | _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk) | ||
1471 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) | ||
1472 | _REGISTER_CLOCK("mxc_nand", NULL, nfc_clk) | ||
1473 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
1474 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
1475 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) | ||
1476 | /* i.mx51 has the i.mx35 type sdma */ | ||
1477 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
1478 | _REGISTER_CLOCK(NULL, "ckih", ckih_clk) | ||
1479 | _REGISTER_CLOCK(NULL, "ckih2", ckih2_clk) | ||
1480 | _REGISTER_CLOCK(NULL, "gpt_32k", gpt_32k_clk) | ||
1481 | _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) | ||
1482 | _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) | ||
1483 | /* i.mx51 has the i.mx35 type cspi */ | ||
1484 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) | ||
1485 | _REGISTER_CLOCK("sdhci-esdhc-imx51.0", NULL, esdhc1_clk) | ||
1486 | _REGISTER_CLOCK("sdhci-esdhc-imx51.1", NULL, esdhc2_clk) | ||
1487 | _REGISTER_CLOCK("sdhci-esdhc-imx51.2", NULL, esdhc3_clk) | ||
1488 | _REGISTER_CLOCK("sdhci-esdhc-imx51.3", NULL, esdhc4_clk) | ||
1489 | _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk) | ||
1490 | _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) | ||
1491 | _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) | ||
1492 | _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) | ||
1493 | _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk) | ||
1494 | _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk) | ||
1495 | _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk) | ||
1496 | _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk) | ||
1497 | _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk) | ||
1498 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
1499 | }; | ||
1500 | |||
1501 | static struct clk_lookup mx53_lookups[] = { | ||
1502 | /* i.mx53 has the i.mx21 type uart */ | ||
1503 | _REGISTER_CLOCK("imx21-uart.0", NULL, uart1_clk) | ||
1504 | _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) | ||
1505 | _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) | ||
1506 | _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) | ||
1507 | _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) | ||
1508 | _REGISTER_CLOCK(NULL, "gpt", gpt_clk) | ||
1509 | /* i.mx53 has the i.mx25 type fec */ | ||
1510 | _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk) | ||
1511 | _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) | ||
1512 | _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) | ||
1513 | _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) | ||
1514 | _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_mx53_clk) | ||
1515 | /* i.mx53 has the i.mx51 type ecspi */ | ||
1516 | _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) | ||
1517 | _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) | ||
1518 | /* i.mx53 has the i.mx25 type cspi */ | ||
1519 | _REGISTER_CLOCK("imx35-cspi.0", NULL, cspi_clk) | ||
1520 | _REGISTER_CLOCK("sdhci-esdhc-imx53.0", NULL, esdhc1_clk) | ||
1521 | _REGISTER_CLOCK("sdhci-esdhc-imx53.1", NULL, esdhc2_mx53_clk) | ||
1522 | _REGISTER_CLOCK("sdhci-esdhc-imx53.2", NULL, esdhc3_mx53_clk) | ||
1523 | _REGISTER_CLOCK("sdhci-esdhc-imx53.3", NULL, esdhc4_mx53_clk) | ||
1524 | _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) | ||
1525 | _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) | ||
1526 | /* i.mx53 has the i.mx35 type sdma */ | ||
1527 | _REGISTER_CLOCK("imx35-sdma", NULL, sdma_clk) | ||
1528 | _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk) | ||
1529 | _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk) | ||
1530 | _REGISTER_CLOCK("imx-ssi.2", NULL, ssi3_clk) | ||
1531 | _REGISTER_CLOCK("imx-keypad", NULL, dummy_clk) | ||
1532 | _REGISTER_CLOCK("pata_imx", NULL, pata_clk) | ||
1533 | _REGISTER_CLOCK("imx53-ahci.0", "ahci", sata_clk) | ||
1534 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_phy", ahci_phy_clk) | ||
1535 | _REGISTER_CLOCK("imx53-ahci.0", "ahci_dma", ahci_dma_clk) | ||
1536 | }; | ||
1537 | |||
1538 | static void clk_tree_init(void) | ||
1539 | { | ||
1540 | u32 reg; | ||
1541 | |||
1542 | ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk); | ||
1543 | |||
1544 | /* | ||
1545 | * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at | ||
1546 | * 8MHz, its derived from lp_apm. | ||
1547 | * | ||
1548 | * FIXME: Verify if true for all boards | ||
1549 | */ | ||
1550 | reg = __raw_readl(MXC_CCM_CBCDR); | ||
1551 | reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK; | ||
1552 | reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK; | ||
1553 | reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK; | ||
1554 | reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET); | ||
1555 | __raw_writel(reg, MXC_CCM_CBCDR); | ||
1556 | } | ||
1557 | |||
1558 | int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, | ||
1559 | unsigned long ckih1, unsigned long ckih2) | ||
1560 | { | ||
1561 | int i; | ||
1562 | |||
1563 | external_low_reference = ckil; | ||
1564 | external_high_reference = ckih1; | ||
1565 | ckih2_reference = ckih2; | ||
1566 | oscillator_reference = osc; | ||
1567 | |||
1568 | for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) | ||
1569 | clkdev_add(&mx51_lookups[i]); | ||
1570 | |||
1571 | clk_tree_init(); | ||
1572 | |||
1573 | clk_enable(&cpu_clk); | ||
1574 | clk_enable(&main_bus_clk); | ||
1575 | |||
1576 | clk_enable(&iim_clk); | ||
1577 | imx_print_silicon_rev("i.MX51", mx51_revision()); | ||
1578 | clk_disable(&iim_clk); | ||
1579 | |||
1580 | /* move usb_phy_clk to 24MHz */ | ||
1581 | clk_set_parent(&usb_phy1_clk, &osc_clk); | ||
1582 | |||
1583 | /* set the usboh3_clk parent to pll2_sw_clk */ | ||
1584 | clk_set_parent(&usboh3_clk, &pll2_sw_clk); | ||
1585 | |||
1586 | /* Set SDHC parents to be PLL2 */ | ||
1587 | clk_set_parent(&esdhc1_clk, &pll2_sw_clk); | ||
1588 | clk_set_parent(&esdhc2_clk, &pll2_sw_clk); | ||
1589 | |||
1590 | /* set SDHC root clock as 166.25MHZ*/ | ||
1591 | clk_set_rate(&esdhc1_clk, 166250000); | ||
1592 | clk_set_rate(&esdhc2_clk, 166250000); | ||
1593 | |||
1594 | /* System timer */ | ||
1595 | mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), | ||
1596 | MX51_INT_GPT); | ||
1597 | return 0; | ||
1598 | } | ||
1599 | |||
1600 | int __init mx53_clocks_init(unsigned long ckil, unsigned long osc, | ||
1601 | unsigned long ckih1, unsigned long ckih2) | ||
1602 | { | ||
1603 | int i; | ||
1604 | |||
1605 | external_low_reference = ckil; | ||
1606 | external_high_reference = ckih1; | ||
1607 | ckih2_reference = ckih2; | ||
1608 | oscillator_reference = osc; | ||
1609 | |||
1610 | for (i = 0; i < ARRAY_SIZE(mx53_lookups); i++) | ||
1611 | clkdev_add(&mx53_lookups[i]); | ||
1612 | |||
1613 | clk_tree_init(); | ||
1614 | |||
1615 | clk_set_parent(&uart_root_clk, &pll3_sw_clk); | ||
1616 | clk_enable(&cpu_clk); | ||
1617 | clk_enable(&main_bus_clk); | ||
1618 | |||
1619 | clk_enable(&iim_clk); | ||
1620 | imx_print_silicon_rev("i.MX53", mx53_revision()); | ||
1621 | clk_disable(&iim_clk); | ||
1622 | |||
1623 | /* Set SDHC parents to be PLL2 */ | ||
1624 | clk_set_parent(&esdhc1_clk, &pll2_sw_clk); | ||
1625 | clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk); | ||
1626 | |||
1627 | /* set SDHC root clock as 200MHZ*/ | ||
1628 | clk_set_rate(&esdhc1_clk, 200000000); | ||
1629 | clk_set_rate(&esdhc3_mx53_clk, 200000000); | ||
1630 | |||
1631 | /* System timer */ | ||
1632 | mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR), | ||
1633 | MX53_INT_GPT); | ||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | #ifdef CONFIG_OF | ||
1638 | static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc, | ||
1639 | unsigned long *ckih1, unsigned long *ckih2) | ||
1640 | { | ||
1641 | struct device_node *np; | ||
1642 | |||
1643 | /* retrieve the freqency of fixed clocks from device tree */ | ||
1644 | for_each_compatible_node(np, NULL, "fixed-clock") { | ||
1645 | u32 rate; | ||
1646 | if (of_property_read_u32(np, "clock-frequency", &rate)) | ||
1647 | continue; | ||
1648 | |||
1649 | if (of_device_is_compatible(np, "fsl,imx-ckil")) | ||
1650 | *ckil = rate; | ||
1651 | else if (of_device_is_compatible(np, "fsl,imx-osc")) | ||
1652 | *osc = rate; | ||
1653 | else if (of_device_is_compatible(np, "fsl,imx-ckih1")) | ||
1654 | *ckih1 = rate; | ||
1655 | else if (of_device_is_compatible(np, "fsl,imx-ckih2")) | ||
1656 | *ckih2 = rate; | ||
1657 | } | ||
1658 | } | ||
1659 | |||
1660 | int __init mx51_clocks_init_dt(void) | ||
1661 | { | ||
1662 | unsigned long ckil, osc, ckih1, ckih2; | ||
1663 | |||
1664 | clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); | ||
1665 | return mx51_clocks_init(ckil, osc, ckih1, ckih2); | ||
1666 | } | ||
1667 | |||
1668 | int __init mx53_clocks_init_dt(void) | ||
1669 | { | ||
1670 | unsigned long ckil, osc, ckih1, ckih2; | ||
1671 | |||
1672 | clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2); | ||
1673 | return mx53_clocks_init(ckil, osc, ckih1, ckih2); | ||
1674 | } | ||
1675 | #endif | ||