2 * Copyright (C) 2010 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 #include <asm/arch/mx53.h>
25 #include <asm/errno.h>
28 #ifdef CONFIG_CMD_CLOCK
29 #include <asm/clock.h>
32 #ifdef CONFIG_ARCH_CPU_INIT
33 #include <asm/cache-cp15.h>
37 PLL1_CLK = MXC_DPLL1_BASE,
38 PLL2_CLK = MXC_DPLL2_BASE,
39 PLL3_CLK = MXC_DPLL3_BASE,
40 PLL4_CLK = MXC_DPLL4_BASE,
50 #define AHB_CLK_ROOT 133333333
51 #define IPG_CLK_ROOT 66666666
52 #define IPG_PER_CLK_ROOT 40000000
54 #ifdef CONFIG_CMD_CLOCK
55 #define SZ_DEC_1M 1000000
56 #define PLL_PD_MAX 16 /* Actual pd+1 */
57 #define PLL_MFI_MAX 15
65 struct fixed_pll_mfd {
70 const struct fixed_pll_mfd fixed_mfd[4] = {
71 {0, 0}, /* reserved */
72 {0, 0}, /* reserved */
73 {CONFIG_MX53_HCLK_FREQ, 24 * 16}, /* 384 */
74 {0, 0}, /* reserved */
84 #define PLL_FREQ_MAX(_ref_clk_) \
85 (4 * _ref_clk_ * PLL_MFI_MAX)
86 #define PLL_FREQ_MIN(_ref_clk_) \
87 ((2 * _ref_clk_ * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
88 #define MAX_DDR_CLK 420000000
89 #define AHB_CLK_MAX 133333333
90 #define IPG_CLK_MAX (AHB_CLK_MAX / 2)
91 #define NFC_CLK_MAX 25000000
92 #define HSP_CLK_MAX 133333333
95 static u32 __decode_pll(enum pll_clocks pll, u32 infreq)
97 u32 mfi, mfn, mfd, pd;
99 mfn = __REG(pll + MXC_PLL_DP_MFN);
100 mfd = __REG(pll + MXC_PLL_DP_MFD) + 1;
101 mfi = __REG(pll + MXC_PLL_DP_OP);
102 pd = (mfi & 0xF) + 1;
103 mfi = (mfi >> 4) & 0xF;
104 mfi = (mfi >= 5) ? mfi : 5;
106 return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000;
109 static u32 __get_mcu_main_clk(void)
112 reg = (__REG(MXC_CCM_CACRR) & MXC_CCM_CACRR_ARM_PODF_MASK) >>
113 MXC_CCM_CACRR_ARM_PODF_OFFSET;
114 freq = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
115 return freq / (reg + 1);
118 static u32 __get_periph_clk(void)
121 reg = __REG(MXC_CCM_CBCDR);
122 if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
123 reg = __REG(MXC_CCM_CBCMR);
124 switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >>
125 MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
127 return __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
129 return __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
134 return __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
137 static u32 __get_ipg_clk(void)
139 u32 ahb_podf, ipg_podf;
141 ahb_podf = __REG(MXC_CCM_CBCDR);
142 ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
143 MXC_CCM_CBCDR_IPG_PODF_OFFSET;
144 ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
145 MXC_CCM_CBCDR_AHB_PODF_OFFSET;
146 return __get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1));
149 static u32 __get_ipg_per_clk(void)
151 u32 pred1, pred2, podf;
152 if (__REG(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL)
153 return __get_ipg_clk();
154 /* Fixme: not handle what about lpm */
155 podf = __REG(MXC_CCM_CBCDR);
156 pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
157 MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET;
158 pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
159 MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET;
160 podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
161 MXC_CCM_CBCDR_PERCLK_PODF_OFFSET;
163 return __get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1));
167 * This function returns the low power audio clock.
169 static u32 __get_lp_apm(void)
172 u32 ccsr = __REG(MXC_CCM_CCSR);
174 if (((ccsr >> MXC_CCM_CCSR_LP_APM_SEL_OFFSET) & 1) == 0)
175 ret_val = CONFIG_MX53_HCLK_FREQ;
177 ret_val = ((32768 * 1024));
183 static u32 __get_perclk_lp_apm(void)
186 u32 cbcmr = __REG(MXC_CCM_CBCMR);
187 u32 clk_sel = (cbcmr & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) \
188 >> MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL_OFFSET;
192 ret_val = __get_periph_clk();
195 ret_val = __get_lp_apm();
205 static u32 __get_uart_clk(void)
207 u32 freq = 0, reg, pred, podf;
208 reg = __REG(MXC_CCM_CSCMR1);
209 switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >>
210 MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) {
212 freq = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
215 freq = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
218 freq = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
221 freq = __get_lp_apm();
227 reg = __REG(MXC_CCM_CSCDR1);
229 pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
230 MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET;
232 podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
233 MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
234 freq /= (pred + 1) * (podf + 1);
240 static u32 __get_cspi_clk(void)
242 u32 ret_val = 0, pdf, pre_pdf, clk_sel, div;
243 u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
244 u32 cscdr2 = __REG(MXC_CCM_CSCDR2);
246 pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \
247 >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET;
248 pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \
249 >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET;
250 clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \
251 >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
253 div = (pre_pdf + 1) * (pdf + 1);
257 ret_val = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ) / div;
260 ret_val = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ) / div;
263 ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ) / div;
266 ret_val = __get_lp_apm() / div;
273 static u32 __get_axi_a_clk(void)
275 u32 cbcdr = __REG(MXC_CCM_CBCDR);
276 u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_A_PODF_MASK) \
277 >> MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
279 return __get_periph_clk() / (pdf + 1);
282 static u32 __get_axi_b_clk(void)
284 u32 cbcdr = __REG(MXC_CCM_CBCDR);
285 u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_B_PODF_MASK) \
286 >> MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
288 return __get_periph_clk() / (pdf + 1);
291 static u32 __get_ahb_clk(void)
293 u32 cbcdr = __REG(MXC_CCM_CBCDR);
294 u32 pdf = (cbcdr & MXC_CCM_CBCDR_AHB_PODF_MASK) \
295 >> MXC_CCM_CBCDR_AHB_PODF_OFFSET;
297 return __get_periph_clk() / (pdf + 1);
301 static u32 __get_emi_slow_clk(void)
303 u32 cbcdr = __REG(MXC_CCM_CBCDR);
304 u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
305 u32 pdf = (cbcdr & MXC_CCM_CBCDR_EMI_PODF_MASK) \
306 >> MXC_CCM_CBCDR_EMI_PODF_OFFSET;
309 return __get_ahb_clk() / (pdf + 1);
311 return __get_periph_clk() / (pdf + 1);
315 static u32 __get_nfc_clk(void)
317 u32 cbcdr = __REG(MXC_CCM_CBCDR);
318 u32 pdf = (cbcdr & MXC_CCM_CBCDR_NFC_PODF_MASK) \
319 >> MXC_CCM_CBCDR_NFC_PODF_OFFSET;
321 return __get_emi_slow_clk() / (pdf + 1);
325 static u32 __get_ddr_clk(void)
328 u32 cbcmr = __REG(MXC_CCM_CBCMR);
329 u32 ddr_clk_sel = (cbcmr & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) \
330 >> MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
332 switch (ddr_clk_sel) {
334 ret_val = __get_axi_a_clk();
337 ret_val = __get_axi_b_clk();
340 ret_val = __get_emi_slow_clk();
343 ret_val = __get_ahb_clk();
352 static u32 __get_esdhc1_clk(void)
354 u32 ret_val = 0, div, pre_pdf, pdf;
355 u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
356 u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
359 esdh1_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK) \
360 >> MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET;
361 pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) \
362 >> MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET;
363 pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) \
364 >> MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET ;
366 div = (pre_pdf + 1) * (pdf + 1);
368 switch (esdh1_clk_sel) {
370 ret_val = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
373 ret_val = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
376 ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
379 ret_val = __get_lp_apm();
390 static u32 __get_esdhc3_clk(void)
392 u32 ret_val = 0, div, pre_pdf, pdf;
394 u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
395 u32 cscdr1 = __REG(MXC_CCM_CSCDR1);
396 esdh3_clk_sel = (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_MASK) \
397 >> MXC_CCM_CSCMR1_ESDHC3_MSHC2_CLK_SEL_OFFSET;
398 pre_pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_MASK) \
399 >> MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PRED_OFFSET;
400 pdf = (cscdr1 & MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_MASK) \
401 >> MXC_CCM_CSCDR1_ESDHC3_MSHC2_CLK_PODF_OFFSET ;
403 div = (pre_pdf + 1) * (pdf + 1);
405 switch (esdh3_clk_sel) {
407 ret_val = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
410 ret_val = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
413 ret_val = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
416 ret_val = __get_lp_apm();
427 static u32 __get_esdhc2_clk(void)
429 u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
430 u32 esdh2_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC2_CLK_SEL;
432 return __get_esdhc3_clk();
434 return __get_esdhc1_clk();
437 static u32 __get_esdhc4_clk(void)
439 u32 cscmr1 = __REG(MXC_CCM_CSCMR1);
440 u32 esdh4_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
442 return __get_esdhc3_clk();
444 return __get_esdhc1_clk();
447 unsigned int mxc_get_clock(enum mxc_clock clk)
451 return __get_mcu_main_clk();
453 return __get_periph_clk();
455 return __get_ahb_clk();
457 return __get_ipg_clk();
459 return __get_ipg_per_clk();
461 return __get_uart_clk();
463 return __get_cspi_clk();
465 return __get_axi_a_clk();
467 return __get_axi_b_clk();
468 case MXC_EMI_SLOW_CLK:
469 return __get_emi_slow_clk();
471 return __get_ddr_clk();
473 return __get_esdhc1_clk();
475 return __get_esdhc2_clk();
477 return __get_esdhc3_clk();
479 return __get_esdhc4_clk();
481 return __get_ahb_clk();
488 void mxc_dump_clocks(void)
491 freq = __decode_pll(PLL1_CLK, CONFIG_MX53_HCLK_FREQ);
492 printf("mx53 pll1: %dMHz\n", freq / 1000000);
493 freq = __decode_pll(PLL2_CLK, CONFIG_MX53_HCLK_FREQ);
494 printf("mx53 pll2: %dMHz\n", freq / 1000000);
495 freq = __decode_pll(PLL3_CLK, CONFIG_MX53_HCLK_FREQ);
496 printf("mx53 pll3: %dMHz\n", freq / 1000000);
497 printf("ipg clock : %dHz\n", mxc_get_clock(MXC_IPG_CLK));
498 printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK));
499 printf("uart clock : %dHz\n", mxc_get_clock(MXC_UART_CLK));
500 printf("cspi clock : %dHz\n", mxc_get_clock(MXC_CSPI_CLK));
501 printf("ahb clock : %dHz\n", mxc_get_clock(MXC_AHB_CLK));
502 printf("axi_a clock : %dHz\n", mxc_get_clock(MXC_AXI_A_CLK));
503 printf("axi_b clock : %dHz\n", mxc_get_clock(MXC_AXI_B_CLK));
504 printf("emi_slow clock: %dHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK));
505 printf("ddr clock : %dHz\n", mxc_get_clock(MXC_DDR_CLK));
506 printf("esdhc1 clock : %dHz\n", mxc_get_clock(MXC_ESDHC_CLK));
507 printf("esdhc2 clock : %dHz\n", mxc_get_clock(MXC_ESDHC2_CLK));
508 printf("esdhc3 clock : %dHz\n", mxc_get_clock(MXC_ESDHC3_CLK));
509 printf("esdhc4 clock : %dHz\n", mxc_get_clock(MXC_ESDHC4_CLK));
512 #ifdef CONFIG_CMD_CLOCK
513 /* precondition: m>0 and n>0. Let g=gcd(m,n). */
514 static int gcd(int m, int n)
529 * This is to calculate various parameters based on reference clock and
530 * targeted clock based on the equation:
531 * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
532 * This calculation is based on a fixed MFD value for simplicity.
534 * @param ref reference clock freq in Hz
535 * @param target targeted clock in Hz
536 * @param pll pll_param structure.
538 * @return 0 if successful; non-zero otherwise.
540 static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
542 u64 pd, mfi = 1, mfn, mfd, t1;
543 u32 n_target = target;
547 * Make sure targeted freq is in the valid range.
548 * Otherwise the following calculation might be wrong!!!
550 if (n_target < PLL_FREQ_MIN(ref) ||
551 n_target > PLL_FREQ_MAX(ref)) {
552 printf("Targeted peripheral clock should be"
553 "within [%d - %d]\n",
554 PLL_FREQ_MIN(ref) / SZ_DEC_1M,
555 PLL_FREQ_MAX(ref) / SZ_DEC_1M);
559 for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) {
560 if (fixed_mfd[i].ref_clk_hz == ref) {
561 mfd = fixed_mfd[i].mfd;
566 if (i == ARRAY_SIZE(fixed_mfd))
569 /* Use n_target and n_ref to avoid overflow */
570 for (pd = 1; pd <= PLL_PD_MAX; pd++) {
572 do_div(t1, (4 * n_ref));
574 if (mfi > PLL_MFI_MAX)
580 /* Now got pd and mfi already */
582 mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
590 #ifdef CMD_CLOCK_DEBUG
591 printf("%d: ref=%d, target=%d, pd=%d,"
592 "mfi=%d,mfn=%d, mfd=%d\n",
593 __LINE__, ref, (u32)n_target,
594 (u32)pd, (u32)mfi, (u32)mfn,
610 int clk_info(u32 clk_type)
614 printf("CPU Clock: %dHz\n",
615 mxc_get_clock(MXC_ARM_CLK));
618 printf("Peripheral Clock: %dHz\n",
619 mxc_get_clock(MXC_PER_CLK));
622 printf("AHB Clock: %dHz\n",
623 mxc_get_clock(MXC_AHB_CLK));
626 printf("IPG Clock: %dHz\n",
627 mxc_get_clock(MXC_IPG_CLK));
630 printf("IPG_PER Clock: %dHz\n",
631 mxc_get_clock(MXC_IPG_PERCLK));
634 printf("UART Clock: %dHz\n",
635 mxc_get_clock(MXC_UART_CLK));
638 printf("CSPI Clock: %dHz\n",
639 mxc_get_clock(MXC_CSPI_CLK));
642 printf("DDR Clock: %dHz\n",
643 mxc_get_clock(MXC_DDR_CLK));
646 printf("cpu clock: %dMHz\n",
647 mxc_get_clock(MXC_ARM_CLK) / SZ_DEC_1M);
651 printf("Unsupported clock type! :(\n");
657 #define calc_div(target_clk, src_clk, limit) ({ \
659 if ((src_clk % target_clk) <= 100) \
660 tmp = src_clk / target_clk; \
662 tmp = (src_clk / target_clk) + 1; \
668 u32 calc_per_cbcdr_val(u32 per_clk, u32 cbcmr)
670 u32 cbcdr = __REG(MXC_CCM_CBCDR);
671 u32 tmp_clk = 0, div = 0, clk_sel = 0;
673 cbcdr &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
675 /* emi_slow_podf divider */
676 tmp_clk = __get_emi_slow_clk();
677 clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
679 div = calc_div(tmp_clk, per_clk, 8);
680 cbcdr &= ~MXC_CCM_CBCDR_EMI_PODF_MASK;
681 cbcdr |= (div << MXC_CCM_CBCDR_EMI_PODF_OFFSET);
684 /* axi_b_podf divider */
685 tmp_clk = __get_axi_b_clk();
686 div = calc_div(tmp_clk, per_clk, 8);
687 cbcdr &= ~MXC_CCM_CBCDR_AXI_B_PODF_MASK;
688 cbcdr |= (div << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET);
690 /* axi_b_podf divider */
691 tmp_clk = __get_axi_a_clk();
692 div = calc_div(tmp_clk, per_clk, 8);
693 cbcdr &= ~MXC_CCM_CBCDR_AXI_A_PODF_MASK;
694 cbcdr |= (div << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET);
696 /* ahb podf divider */
697 tmp_clk = AHB_CLK_ROOT;
698 div = calc_div(tmp_clk, per_clk, 8);
699 cbcdr &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
700 cbcdr |= (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET);
705 #define CHANGE_PLL_SETTINGS(base, pd, mfi, mfn, mfd) \
707 writel(0x1232, base + PLL_DP_CTL); \
708 writel(0x2, base + PLL_DP_CONFIG); \
709 writel(((pd - 1) << 0) | (mfi << 4), \
711 writel(mfn, base + PLL_DP_MFN); \
712 writel(mfd - 1, base + PLL_DP_MFD); \
713 writel(((pd - 1) << 0) | (mfi << 4), \
714 base + PLL_DP_HFS_OP); \
715 writel(mfn, base + PLL_DP_HFS_MFN); \
716 writel(mfd - 1, base + PLL_DP_HFS_MFD); \
717 writel(0x1232, base + PLL_DP_CTL); \
718 while (!readl(base + PLL_DP_CTL) & 0x1) \
722 int config_pll_clk(enum pll_clocks pll, struct pll_param *pll_param)
724 u32 ccsr = readl(CCM_BASE_ADDR + CLKCTL_CCSR);
729 /* Switch ARM to PLL2 clock */
730 writel(ccsr | 0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
731 CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
732 pll_param->mfi, pll_param->mfn,
735 writel(ccsr & ~0x4, CCM_BASE_ADDR + CLKCTL_CCSR);
738 /* Switch to pll2 bypass clock */
739 writel(ccsr | 0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
740 CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
741 pll_param->mfi, pll_param->mfn,
744 writel(ccsr & ~0x2, CCM_BASE_ADDR + CLKCTL_CCSR);
747 /* Switch to pll3 bypass clock */
748 writel(ccsr | 0x1, CCM_BASE_ADDR + CLKCTL_CCSR);
749 CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
750 pll_param->mfi, pll_param->mfn,
753 writel(ccsr & ~0x1, CCM_BASE_ADDR + CLKCTL_CCSR);
756 /* Switch to pll4 bypass clock */
757 writel(ccsr | 0x20, CCM_BASE_ADDR + CLKCTL_CCSR);
758 CHANGE_PLL_SETTINGS(pll_base, pll_param->pd,
759 pll_param->mfi, pll_param->mfn,
762 writel(ccsr & ~0x20, CCM_BASE_ADDR + CLKCTL_CCSR);
771 int config_core_clk(u32 ref, u32 freq)
775 struct pll_param pll_param;
777 memset(&pll_param, 0, sizeof(struct pll_param));
779 /* The case that periph uses PLL1 is not considered here */
781 ret = calc_pll_params(ref, pll, &pll_param);
783 printf("Can't find pll parameters: %d\n",
788 return config_pll_clk(PLL1_CLK, &pll_param);
791 int config_periph_clk(u32 ref, u32 freq)
795 struct pll_param pll_param;
797 memset(&pll_param, 0, sizeof(struct pll_param));
799 if (__REG(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
800 /* Actually this case is not considered here */
801 ret = calc_pll_params(ref, pll, &pll_param);
803 printf("Can't find pll parameters: %d\n",
807 switch ((__REG(MXC_CCM_CBCMR) & \
808 MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >>
809 MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
811 return config_pll_clk(PLL1_CLK, &pll_param);
814 return config_pll_clk(PLL3_CLK, &pll_param);
820 u32 old_cbcmr = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
821 u32 new_cbcdr = calc_per_cbcdr_val(pll, old_cbcmr);
823 /* Switch peripheral to PLL3 */
824 writel(0x00015154, CCM_BASE_ADDR + CLKCTL_CBCMR);
825 writel(0x02888945, CCM_BASE_ADDR + CLKCTL_CBCDR);
827 /* Make sure change is effective */
828 while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
832 ret = calc_pll_params(ref, pll, &pll_param);
834 printf("Can't find pll parameters: %d\n",
838 config_pll_clk(PLL2_CLK, &pll_param);
840 /* Switch peripheral back */
841 writel(new_cbcdr, CCM_BASE_ADDR + CLKCTL_CBCDR);
842 writel(old_cbcmr, CCM_BASE_ADDR + CLKCTL_CBCMR);
844 /* Make sure change is effective */
845 while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
853 int config_ddr_clk(u32 emi_clk)
856 s32 shift = 0, clk_sel, div = 1;
857 u32 cbcmr = readl(CCM_BASE_ADDR + CLKCTL_CBCMR);
858 u32 cbcdr = readl(CCM_BASE_ADDR + CLKCTL_CBCDR);
860 if (emi_clk > MAX_DDR_CLK) {
861 printf("DDR clock should be less than"
862 "%d MHz, assuming max value \n",
863 (MAX_DDR_CLK / SZ_DEC_1M));
864 emi_clk = MAX_DDR_CLK;
867 clk_src = __get_periph_clk();
868 /* Find DDR clock input */
869 clk_sel = (cbcmr >> 10) & 0x3;
887 if ((clk_src % emi_clk) == 0)
888 div = clk_src / emi_clk;
890 div = (clk_src / emi_clk) + 1;
894 cbcdr = cbcdr & ~(0x7 << shift);
895 cbcdr |= ((div - 1) << shift);
896 writel(cbcdr, CCM_BASE_ADDR + CLKCTL_CBCDR);
897 while (readl(CCM_BASE_ADDR + CLKCTL_CDHIPR) != 0)
899 writel(0x0, CCM_BASE_ADDR + CLKCTL_CCDR);
905 * This function assumes the expected core clock has to be changed by
906 * modifying the PLL. This is NOT true always but for most of the times,
907 * it is. So it assumes the PLL output freq is the same as the expected
908 * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
909 * In the latter case, it will try to increase the presc value until
910 * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
911 * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
912 * on the targeted PLL and reference input clock to the PLL. Lastly,
913 * it sets the register based on these values along with the dividers.
914 * Note 1) There is no value checking for the passed-in divider values
915 * so the caller has to make sure those values are sensible.
916 * 2) Also adjust the NFC divider such that the NFC clock doesn't
917 * exceed NFC_CLK_MAX.
918 * 3) IPU HSP clock is independent of AHB clock. Even it can go up to
919 * 177MHz for higher voltage, this function fixes the max to 133MHz.
920 * 4) This function should not have allowed diag_printf() calls since
921 * the serial driver has been stoped. But leave then here to allow
922 * easy debugging by NOT calling the cyg_hal_plf_serial_stop().
924 * @param ref pll input reference clock (24MHz)
925 * @param freq core clock in Hz
926 * @param clk_type clock type, e.g CPU_CLK, DDR_CLK, etc.
927 * @return 0 if successful; non-zero otherwise
929 int clk_config(u32 ref, u32 freq, u32 clk_type)
935 if (config_core_clk(ref, freq))
939 if (config_periph_clk(ref, freq))
943 if (config_ddr_clk(freq))
947 printf("Unsupported or invalid clock type! :(\n");
954 #if defined(CONFIG_DISPLAY_CPUINFO)
955 int print_cpuinfo(void)
957 printf("CPU: Freescale i.MX53 family %d.%dV at %d MHz\n",
958 (get_board_rev() & 0xFF) >> 4,
959 (get_board_rev() & 0xF),
960 __get_mcu_main_clk() / 1000000);
965 #if defined(CONFIG_MXC_FEC)
966 extern int mxc_fec_initialize(bd_t *bis);
967 extern void mxc_fec_set_mac_from_env(char *mac_addr);
970 int cpu_eth_init(bd_t *bis)
973 #if defined(CONFIG_MXC_FEC)
974 rc = mxc_fec_initialize(bis);
979 #if defined(CONFIG_ARCH_CPU_INIT)
980 int arch_cpu_init(void)