1 //==========================================================================
5 // SoC [platform] specific RedBoot commands
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
42 #include <cyg/hal/hal_intr.h>
43 #include <cyg/hal/plf_mmap.h>
44 #include <cyg/hal/hal_soc.h> // Hardware definitions
45 #include <cyg/hal/hal_cache.h>
47 int gcd(int m, int n);
49 typedef unsigned long long u64;
50 typedef unsigned int u32;
51 typedef unsigned short u16;
52 typedef unsigned char u8;
54 #define SZ_DEC_1M 1000000
55 #define PLL_PD_MAX 16 //actual pd+1
56 #define PLL_MFI_MAX 15
64 #define REF_IN_CLK_NUM 4
65 struct fixed_pll_mfd {
69 const struct fixed_pll_mfd fixed_mfd[REF_IN_CLK_NUM] = {
72 {FREQ_24MHZ, 24 * 16}, // 384
83 #define PLL_FREQ_MAX(_ref_clk_) (2 * _ref_clk_ * PLL_MFI_MAX)
84 #define PLL_FREQ_MIN(_ref_clk_) ((2 * _ref_clk_ * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
85 #define AHB_CLK_MAX 133333333
86 #define IPG_CLK_MAX (AHB_CLK_MAX / 2)
87 #define NFC_CLK_MAX 25000000
88 // IPU-HSP clock is independent of the HCLK and can go up to 177MHz but requires
89 // higher voltage support. For simplicity, limit it to 133MHz
90 #define HSP_CLK_MAX 133333333
92 #define ERR_WRONG_CLK -1
96 #define ERR_NO_PRESC -5
97 #define ERR_NO_AHB_DIV -6
99 u32 pll_clock(enum plls pll);
100 u32 get_main_clock(enum main_clocks clk);
101 u32 get_peri_clock(enum peri_clocks clk);
103 static volatile u32 *pll_base[] =
105 REG32_PTR(PLL1_BASE_ADDR),
106 REG32_PTR(PLL2_BASE_ADDR),
107 REG32_PTR(PLL3_BASE_ADDR),
110 #define NOT_ON_VAL 0xDEADBEEF
112 static void clock_setup(int argc, char *argv[]);
113 static void clko(int argc, char *argv[]);
116 "Setup/Display clock (max AHB=133MHz, max IPG=66.5MHz)\nSyntax:",
117 "[<core clock in MHz> [:<AHB-to-core divider>[:<IPG-to-AHB divider>]]] \n\n\
118 If a divider is zero or no divider is specified, the optimal divider values \n\
119 will be chosen. Examples:\n\
120 [clock] -> Show various clocks\n\
121 [clock 532] -> Core=532 AHB=133 IPG=66.5\n\
122 [clock 399] -> Core=399 AHB=133 IPG=66.5\n\
123 [clock 532:8] -> Core=532 AHB=66.5(Core/8) IPG=66.5\n\
124 [clock 532:8:2] -> Core=532 AHB=66.5(Core/8) IPG=33.25(AHB/2)\n",
129 * This is to calculate various parameters based on reference clock and
130 * targeted clock based on the equation:
131 * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
132 * This calculation is based on a fixed MFD value for simplicity.
134 * @param ref reference clock freq in Hz
135 * @param target targeted clock in Hz
136 * @param p_pd calculated pd value (pd value from register + 1) upon return
137 * @param p_mfi calculated actual mfi value upon return
138 * @param p_mfn calculated actual mfn value upon return
139 * @param p_mfd fixed mfd value (mfd value from register + 1) upon return
141 * @return 0 if successful; non-zero otherwise.
143 int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
145 u64 pd, mfi = 1, mfn, mfd, n_target = target, n_ref = ref, i;
147 // make sure targeted freq is in the valid range. Otherwise the
148 // following calculation might be wrong!!!
149 if (n_target < PLL_FREQ_MIN(ref) || n_target > PLL_FREQ_MAX(ref))
150 return ERR_WRONG_CLK;
152 if (i == REF_IN_CLK_NUM)
153 return ERR_WRONG_CLK;
154 if (fixed_mfd[i].ref_clk_hz == ref) {
155 mfd = fixed_mfd[i].mfd;
159 // Use n_target and n_ref to avoid overflow
160 for (pd = 1; pd <= PLL_PD_MAX; pd++) {
161 mfi = (n_target * pd) / (2 * n_ref);
162 if (mfi > PLL_MFI_MAX) {
164 } else if (mfi < 5) {
169 // Now got pd and mfi already
170 mfn = (((n_target * pd) / 2 - n_ref * mfi) * mfd) / n_ref;
171 #ifdef CMD_CLOCK_DEBUG
172 diag_printf("%d: ref=%d, target=%d, pd=%d, mfi=%d,mfn=%d, mfd=%d\n",
173 __LINE__, ref, (u32)n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
180 pll->mfn = (u32)(mfn / i);
181 pll->mfd = (u32)(mfd / i);
186 * This function assumes the expected core clock has to be changed by
187 * modifying the PLL. This is NOT true always but for most of the times,
188 * it is. So it assumes the PLL output freq is the same as the expected
189 * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
190 * In the latter case, it will try to increase the presc value until
191 * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
192 * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
193 * on the targeted PLL and reference input clock to the PLL. Lastly,
194 * it sets the register based on these values along with the dividers.
195 * Note 1) There is no value checking for the passed-in divider values
196 * so the caller has to make sure those values are sensible.
197 * 2) Also adjust the NFC divider such that the NFC clock doesn't
198 * exceed NFC_CLK_MAX.
199 * 3) IPU HSP clock is independent of AHB clock. Even it can go up to
200 * 177MHz for higher voltage, this function fixes the max to 133MHz.
201 * 4) This function should not have allowed diag_printf() calls since
202 * the serial driver has been stoped. But leave then here to allow
203 * easy debugging by NOT calling the cyg_hal_plf_serial_stop().
205 * @param ref pll input reference clock (32KHz or 26MHz)
206 * @param core_clk core clock in Hz
207 * @param emi_clk emi clock in Hz
208 * @param ahb_div ahb divider to divide the core clock to get ahb clock
209 * (ahb_div - 1) needs to be set in the register
210 * @param ipg_div ipg divider to divide the core clock to get ipg clock
211 * (ipg_div - 1) needs to be set in the register
212 # @return 0 if successful; non-zero otherwise
214 int configure_clock(u32 ref, u32 core_clk, u32 emi_clk, u32 ahb_div, u32 ipg_div)
217 u32 pll, arm_div = 1, emi_div = 0, nfc_div, ascsr, acdr, acder2;
218 struct pll_param pll_param;
221 // assume pll default to core clock first
223 // when core_clk >= PLL_FREQ_MIN, the presc can be 1.
224 // Otherwise, need to calculate presc value below and adjust the targeted pll
225 if (core_clk < PLL_FREQ_MIN) {
226 for (presc = 1; presc <= PRESC_MAX; presc++) {
227 if ((core_clk * presc) > PLL_FREQ_MIN) {
231 if (presc == (PRESC_MAX + 1)) {
232 diag_printf("can't make presc=%d\n", presc);
235 pll = core_clk * presc;
238 for (hsp_div = 1; hsp_div <= HSP_PODF_MAX; hsp_div++) {
239 if ((pll / hsp_div) <= HSP_CLK_MAX) {
243 if (hsp_div == (HSP_PODF_MAX + 1)) {
244 diag_printf("can't make hsp_div=%d\n", hsp_div);
248 // get nfc_div - make sure optimal NFC clock but less than NFC_CLK_MAX
249 for (nfc_div = 1; nfc_div <= NFC_PODF_MAX; nfc_div++) {
250 if ((pll / (ahb_div * nfc_div)) <= NFC_CLK_MAX) {
255 // pll is now the targeted pll output. Use it along with ref input clock
256 // to get pd, mfi, mfn, mfd
257 if ((ret = calc_pll_params(ref, pll, &pd, &mfi, &mfn, &mfd)) != 0) {
258 diag_printf("can't find pll parameters: %d\n", ret);
261 #ifdef CMD_CLOCK_DEBUG
262 diag_printf("ref=%d, pll=%d, pd=%d, mfi=%d,mfn=%d, mfd=%d\n",
263 ref, pll, pd, mfi, mfn, mfd);
266 // blindly increase divider first to avoid too fast ahbclk and ipgclk
267 // in case the core clock increases too much
268 pdr0 = readl(CCM_BASE_ADDR + CLKCTL_PDR0);
270 // increase the dividers. should work even when core clock is 832 (26*2*16)MHz
271 // which is unlikely true.
272 pdr0 |= (1 << 6) | (6 << 3) | (0 << 0);
273 writel(pdr0, CCM_BASE_ADDR + CLKCTL_PDR0);
274 // calculate new pdr0
276 pdr0 |= ((hsp_div - 1) << 11) | ((nfc_div - 1) << 8) | ((ipg_div - 1) << 6) |
277 ((ahb_div - 1) << 3) | ((presc - 1) << 0);
279 // update PLL register
280 if ((mfd >= (10 * mfn)) || ((10 * mfn) >= (9 * mfd)))
283 mpctl0 = readl(CCM_BASE_ADDR + CLKCTL_MPCTL);
284 mpctl0 = (mpctl0 & 0x4000C000) |
290 writel(mpctl0, CCM_BASE_ADDR + CLKCTL_MPCTL);
291 writel(pdr0, CCM_BASE_ADDR + CLKCTL_PDR0);
292 // add some delay for new values to take effect
293 for (i = 0; i < 10000; i++);
298 static void clock_setup(int argc,char *argv[])
301 u32 i, core_clk, ipg_div, data[3], temp, ahb_div, ahb_clk, ipg_clk;
307 for (i = 0; i < 3; i++) {
308 if (!parse_num(*(&argv[1]), (unsigned long *)&temp, &argv[1], ":")) {
309 diag_printf("Error: Invalid parameter\n");
315 core_clk = data[0] * SZ_DEC_1M;
316 ahb_div = data[1]; // actual register field + 1
317 ipg_div = data[2]; // actual register field + 1
319 if (core_clk < (PLL_FREQ_MIN / PRESC_MAX) || core_clk > PLL_FREQ_MAX) {
320 diag_printf("Targeted core clock should be within [%d - %d]\n",
321 PLL_FREQ_MIN / PRESC_MAX, PLL_FREQ_MAX);
325 // find the ahb divider
326 if (ahb_div > AHB_DIV_MAX) {
327 diag_printf("Invalid AHB divider: %d. Maximum value is %d\n",
328 ahb_div, AHB_DIV_MAX);
332 // no HCLK divider specified
333 for (ahb_div = 1; ; ahb_div++) {
334 if ((core_clk / ahb_div) <= AHB_CLK_MAX) {
339 if (ahb_div > AHB_DIV_MAX || (core_clk / ahb_div) > AHB_CLK_MAX) {
340 diag_printf("Can't make AHB=%d since max=%d\n",
341 core_clk / ahb_div, AHB_CLK_MAX);
345 // find the ipg divider
346 ahb_clk = core_clk / ahb_div;
347 if (ipg_div > IPG_DIV_MAX) {
348 diag_printf("Invalid IPG divider: %d. Maximum value is %d\n",
349 ipg_div, IPG_DIV_MAX);
353 ipg_div++; // At least =1
354 if (ahb_clk > IPG_CLK_MAX)
355 ipg_div++; // Make it =2
357 if (ipg_div > IPG_DIV_MAX || (ahb_clk / ipg_div) > IPG_CLK_MAX) {
358 diag_printf("Can't make IPG=%d since max=%d\n",
359 (ahb_clk / ipg_div), IPG_CLK_MAX);
362 ipg_clk = ahb_clk / ipg_div;
364 diag_printf("Trying to set core=%d ahb=%d ipg=%d...\n",
365 core_clk, ahb_clk, ipg_clk);
367 // stop the serial to be ready to adjust the clock
368 hal_delay_us(100000);
369 cyg_hal_plf_serial_stop();
371 ret = configure_clock(PLL_REF_CLK, core_clk, ahb_div, ipg_div);
372 // restart the serial driver
373 cyg_hal_plf_serial_init();
374 hal_delay_us(100000);
377 diag_printf("Failed to setup clock: %d\n", ret);
380 diag_printf("\n<<<New clock setting>>>\n");
382 // Now printing clocks
385 diag_printf("\nPLL1\t\tPLL2\t\tPLL3\n");
386 diag_printf("========================================\n");
387 diag_printf("%-16d%-16d%-16d\n\n", pll_clock(PLL1), pll_clock(PLL2),
389 diag_printf("CPU\t\tAHB\t\tIPG\t\tEMI_CLK\n");
390 diag_printf("========================================================\n");
391 diag_printf("%-16d%-16d%-16d%-16d\n\n",
392 get_main_clock(CPU_CLK),
393 get_main_clock(AHB_CLK),
394 get_main_clock(IPG_CLK),
395 get_main_clock(DDR_CLK));
397 diag_printf("NFC\t\tUSB\n");
398 diag_printf("========================================\n");
399 diag_printf("%-16d%-16d\n\n",
400 get_main_clock(NFC_CLK),
401 get_main_clock(USB_CLK));
403 diag_printf("UART1-3\t\tSSI1\t\tSSI2\t\tCSI\n");
404 diag_printf("===========================================");
405 diag_printf("=============\n");
407 diag_printf("%-16d%-16d%-16d%-16d\n\n",
408 get_peri_clock(UART1_BAUD),
409 get_peri_clock(SSI1_BAUD),
410 get_peri_clock(SSI2_BAUD),
411 get_peri_clock(CSI_BAUD));
413 diag_printf("MSTICK1\t\tMSTICK2\t\tSPI\n");
414 diag_printf("===========================================");
415 diag_printf("=============\n");
417 diag_printf("%-16d%-16d%-16d\n\n",
418 get_peri_clock(MSTICK1_CLK),
419 get_peri_clock(MSTICK2_CLK),
420 get_peri_clock(SPI1_CLK));
422 diag_printf("IPG_PERCLK as baud clock for: UART1-5, I2C, OWIRE, SDHC");
423 if (((readl(EPIT1_BASE_ADDR) >> 24) & 0x3) == 0x2) {
424 diag_printf(", EPIT");
426 if (((readl(GPT1_BASE_ADDR) >> 6) & 0x7) == 0x2) {
435 * This function returns the PLL output value in Hz based on pll.
437 u32 pll_clock(enum plls pll)
439 u64 mfi, mfn, mfd, pdf, ref_clk, pll_out, sign;
440 u64 dp_ctrl, dp_op, dp_mfd, dp_mfn, clk_sel;
443 dp_ctrl = pll_base[pll][PLL_DP_CTL >> 2];
444 clk_sel = MXC_GET_FIELD(dp_ctrl, 2, 8);
445 ref_clk = fixed_mfd[clk_sel].ref_clk_hz;
447 if ((pll_base[pll][PLL_DP_CTL >> 2] & 0x80) == 0) {
448 dp_op = pll_base[pll][PLL_DP_OP >> 2];
449 dp_mfd = pll_base[pll][PLL_DP_MFD >> 2];
450 dp_mfn = pll_base[pll][PLL_DP_MFN >> 2];
452 dp_op = pll_base[pll][PLL_DP_HFS_OP >> 2];
453 dp_mfd = pll_base[pll][PLL_DP_HFS_MFD >> 2];
454 dp_mfn = pll_base[pll][PLL_DP_HFS_MFN >> 2];
457 mfi = (dp_op >> 4) & 0xF;
458 mfi = (mfi <= 5) ? 5: mfi;
459 mfd = dp_mfd & 0x07FFFFFF;
460 mfn = dp_mfn & 0x07FFFFFF;
462 sign = (mfn < 0x4000000) ? 0: 1;
463 mfn = (mfn <= 0x4000000) ? mfn: (0x8000000 - mfn);
465 dbl = ((dp_ctrl >> 12) & 0x1) + 1;
469 pll_out = (dbl * ref_clk * mfi + ((dbl * ref_clk * mfn) / (mfd + 1))) /
472 pll_out = (dbl * ref_clk * mfi - ((dbl * ref_clk * mfn) / (mfd + 1))) /
479 // The clocks are on by default. But need to setup the IOMUX
480 void clock_spi_enable(unsigned int spi_clk)
483 writel(0x0, IOMUXC_BASE_ADDR + 0x14C);
484 writel(0x1, IOMUXC_BASE_ADDR + 0x3AC);
485 writel(0x100, IOMUXC_BASE_ADDR + 0x494);
486 writel(0x0, IOMUXC_BASE_ADDR + 0x148);
487 writel(0x1, IOMUXC_BASE_ADDR + 0x3A8);
488 writel(0x3, IOMUXC_BASE_ADDR + 0x168);
489 writel(0x180, IOMUXC_BASE_ADDR + 0x3C8);
490 writel(0x0, IOMUXC_BASE_ADDR + 0x158);
491 writel(0x101, IOMUXC_BASE_ADDR + 0x3B8);
492 writel(0x0, IOMUXC_BASE_ADDR + 0x150);
493 writel(0x1, IOMUXC_BASE_ADDR + 0x3B0);
494 writel(0x100, IOMUXC_BASE_ADDR + 0x490);
498 * This function returns the low power audio clock.
503 u32 ccsr = readl(CCM_BASE_ADDR + CLKCTL_CCSR);
505 if (((ccsr >> 9) & 1) == 0) {
506 ret_val = FREQ_24MHZ;
508 ret_val = FREQ_32000HZ;
514 * This function returns the periph_clk.
516 u32 get_periph_clk(void)
518 u32 cbcdr6 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR6);
519 u32 camr = readl(CCM_BASE_ADDR + CLKCTL_CAMR);
520 u32 ret_val = 0, clk_sel;
522 if (((cbcdr6 >> 4) & 1) == 0) {
523 ret_val = pll_clock(PLL2);
525 clk_sel = (camr >> 12) & 3;
527 ret_val = pll_clock(PLL1);
528 } else if (clk_sel == 1) {
529 ret_val = pll_clock(PLL3);
530 } else if (clk_sel == 2) {
531 ret_val = get_lp_apm();
539 * This function returns the emi_core_clk_root clock.
541 u32 get_emi_core_clk(void)
543 u32 cbcdr6 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR6);
544 u32 cbcdr2 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR2);
545 u32 clk_sel = 0, pdf = 0, max_pdf = 0, peri_clk = 0, ahb_clk = 0;
548 max_pdf = (cbcdr2 >> 10) & 0x7;
549 peri_clk = get_periph_clk();
550 ahb_clk = peri_clk / (max_pdf + 1);
553 clk_sel = (cbcdr6 >> 3) & 1;
555 ret_val = peri_clk / (pdf + 1);
557 ret_val = ahb_clk / (pdf + 1);
562 // The clocks are on by default. But need to setup the IOMUX
563 void mxc_i2c_init(unsigned int module_base)
565 unsigned int val, reg;
567 switch (module_base) {
569 writel(0x0, IOMUXC_BASE_ADDR + 0x104);
570 writel(0x1, IOMUXC_BASE_ADDR + 0x5C0);
571 writel(0xA8, IOMUXC_BASE_ADDR + 0x364);
573 writel(0x0, IOMUXC_BASE_ADDR + 0x108);
574 writel(0x1, IOMUXC_BASE_ADDR + 0x5C4);
575 writel(0xA8, IOMUXC_BASE_ADDR + 0x368);
577 writel(0x100, IOMUXC_BASE_ADDR + 0x4D0);
581 writel(0x2, IOMUXC_BASE_ADDR + 0x210);
582 writel(0x1EC, IOMUXC_BASE_ADDR + 0x468);
583 writel(0x1, IOMUXC_BASE_ADDR + 0x5C8);
585 writel(0x2, IOMUXC_BASE_ADDR + 0x214);
586 writel(0x1EC, IOMUXC_BASE_ADDR + 0x46C);
587 writel(0x1, IOMUXC_BASE_ADDR + 0x5CC);
590 reg = IOMUXC_BASE_ADDR + 0x84;
591 val = (readl(reg) & 0xFFFFFF00) | 0x24; // alt mode 1
593 reg = IOMUXC_BASE_ADDR + 0x80;
594 val = (readl(reg) & 0x00FFFFFF) | 0x24000000; // alt mode 1
598 diag_printf("Invalid I2C base: 0x%x\n", module_base);
604 * This function returns the main clock value in Hz.
606 u32 get_main_clock(enum main_clocks clk)
608 u32 mcu_podf, max_pdf, ipg_pdf, nfc_pdf, clk_sel;
609 u32 pll, ret_val = 0;
610 u32 cacrr = readl(CCM_BASE_ADDR + CLKCTL_CACRR);
611 u32 cbcdr2 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR2);
612 u32 cbcdr3 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR3);
613 u32 cbcdr4 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR4);
614 u32 cbcdr5 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR5);
615 u32 cbcdr7 = readl(CCM_BASE_ADDR + CLKCTL_CBCDR7);
616 u32 camr = readl(CCM_BASE_ADDR + CLKCTL_CAMR);
620 mcu_podf = cacrr & 0x7;
621 pll = pll_clock(PLL1);
622 ret_val = pll / (mcu_podf + 1);
625 max_pdf = (cbcdr2 >> 10) & 0x7;
626 pll = get_periph_clk();
627 ret_val = pll / (max_pdf + 1);
630 max_pdf = (cbcdr2 >> 10) & 0x7;
631 ipg_pdf = (cbcdr2 >> 8) & 0x3;
632 pll = get_periph_clk();
633 ret_val = pll / ((max_pdf + 1) * (ipg_pdf + 1));
637 clk_sel = ccmr & (1 << 24);
638 pdf = (mpdr0 >> 16) & 0x1F;
641 max_pdf = (reg >> 3) & 0x7;
642 ipg_pdf = (reg >> 6) & 0x3;
643 pll = pll_clock(PLL1);
644 ret_val = pll / ((max_pdf + 1) * (ipg_pdf + 1));
646 ret_val = pll_clock(PLL2) / (pdf + 1);
651 clk_sel = (camr >> 10) & 3;
653 ret_val = get_periph_clk() / ((cbcdr3 & 7) + 1);
654 } else if (clk_sel == 1) {
655 ret_val = get_periph_clk() / ((cbcdr4 & 7) + 1);
656 } else if (clk_sel == 2) {
657 ret_val = get_periph_clk() / ((cbcdr5 & 7) + 1);
658 } else if (clk_sel == 3) {
659 ret_val = get_emi_core_clk();
663 nfc_pdf = cbcdr7 & 0x7;
664 pll = get_emi_core_clk();
666 ret_val = pll / (nfc_pdf + 1);
670 usb_prdf = reg1 >> 30;
671 usb_podf = (reg1 >> 27) & 0x7;
672 pll = pll_clock(PLL2);
673 ret_val = pll / ((usb_prdf + 1) * (usb_podf + 1));
677 diag_printf("Unknown clock: %d\n", clk);
685 * This function returns the peripheral clock value in Hz.
687 u32 get_peri_clock(enum peri_clocks clk)
689 u32 ret_val = 0, pdf, pre_pdf, clk_sel;
690 u32 cscmr1 = readl(CCM_BASE_ADDR + CLKCTL_CSCMR1);
691 u32 cscdr1 = readl(CCM_BASE_ADDR + CLKCTL_CSCDR1);
692 u32 cscdr2 = readl(CCM_BASE_ADDR + CLKCTL_CSCDR2);
693 u32 cs1cdr = readl(CCM_BASE_ADDR + CLKCTL_CS1CDR);
694 u32 cs2cdr = readl(CCM_BASE_ADDR + CLKCTL_CS2CDR);
700 pre_pdf = (cscdr1 >> 3) & 0x7;
702 clk_sel = (cscmr1 >> 24) & 3;
704 ret_val = pll_clock(PLL1) / ((pre_pdf + 1) * (pdf + 1));
705 } else if (clk_sel == 1) {
706 ret_val = pll_clock(PLL2) / ((pre_pdf + 1) * (pdf + 1));
707 } else if (clk_sel == 2) {
708 ret_val = pll_clock(PLL3) / ((pre_pdf + 1) * (pdf + 1));
712 pre_pdf = (cs1cdr >> 6) & 0x7;
714 clk_sel = (cscmr1 >> 14) & 3;
716 ret_val = pll_clock(PLL1) / ((pre_pdf + 1) * (pdf + 1));
717 } else if (clk_sel == 0x1) {
718 ret_val = pll_clock(PLL2) / ((pre_pdf + 1) * (pdf + 1));
719 } else if (clk_sel == 0x2) {
720 ret_val = pll_clock(PLL3) / ((pre_pdf + 1) * (pdf + 1));
722 diag_printf("Error: Use reserved value for SSI1!\n");
727 pre_pdf = (cs2cdr >> 6) & 0x7;
729 clk_sel = (cscmr1 >> 12) & 3;
731 ret_val = pll_clock(PLL1) / ((pre_pdf + 1) * (pdf + 1));
732 } else if (clk_sel == 0x1) {
733 ret_val = pll_clock(PLL2) / ((pre_pdf + 1) * (pdf + 1));
734 } else if (clk_sel == 0x2) {
735 ret_val = pll_clock(PLL3) / ((pre_pdf + 1) * (pdf + 1));
737 diag_printf("Error: Use reserved value for SSI2!\n");
743 clk_sel = ccmr & (1 << 25);
744 pdf = (mpdr0 >> 23) & 0x1FF;
745 ret_val = (clk_sel != 0) ? (pll_clock(PLL3) / (pdf + 1)) :
746 (pll_clock(PLL2) / (pdf + 1));
752 ret_val = pll_clock(PLL2) / (pdf + 1);
757 pdf = (mpdr2 >> 7) & 0x3F;
758 ret_val = pll_clock(PLL2) / (pdf + 1);
763 pre_pdf = (cscdr2 >> 25) & 0x7;
764 pdf = (cscdr2 >> 19) & 0x3F;
765 clk_sel = (cscmr1 >> 4) & 3;
767 ret_val = pll_clock(PLL1) / ((pre_pdf + 1) * (pdf + 1));
768 } else if (clk_sel == 1) {
769 ret_val = pll_clock(PLL2) / ((pre_pdf + 1) * (pdf + 1));
770 } else if (clk_sel == 2) {
771 ret_val = pll_clock(PLL3) / ((pre_pdf + 1) * (pdf + 1));
775 diag_printf("%s(): This clock: %d not supported yet \n",
784 "Select clock source for CLKO (J11 on the CPU daughter card)",
785 " Default is 1/8 of ARM core\n\
786 <0> - display current clko selection \n\
787 <1> - mpl_dpdgck_clk (MPLL) \n\
788 <2> - ipg_clk_ccm (IPG) \n\
789 <3> - upl_dpdgck_clk (UPLL) \n\
790 <4> - pll_ref_clk \n\
791 <5> - fpm_ckil512_clk \n\
792 <6> - ipg_clk_ahb_arm (AHB) \n\
793 <7> - ipg_clk_arm (ARM) \n\
794 <8> - spl_dpdgck_clk (SPLL) \n\
796 <10> - ipg_clk_ahb_emi_clk \n\
797 <11> - ipg_clk_ipu_hsp \n\
798 <12> - ipg_clk_nfc_20m \n\
799 <13> - ipg_clk_perclk_uart1 (IPG_PER)",
803 static u8* clko_name[] ={
805 "1/8 of mpl_dpdgck_clk (MPLL)",
807 "1/8 of upl_dpdgck_clk (UPLL)",
810 "ipg_clk_ahb_arm (AHB)",
811 "1/8 of ipg_clk_arm (ARM)",
812 "1/8 of spl_dpdgck_clk (SPLL)",
814 "ipg_clk_ahb_emi_clk",
817 "ipg_clk_perclk_uart1 (IPG_PER)",
820 #define CLKO_MAX_INDEX (sizeof(clko_name) / sizeof(u8*))
822 static void clko(int argc,char *argv[])
824 u32 action = 0, cosr;
826 if (!scan_opts(argc, argv, 1, 0, 0, (void*) &action,
827 OPTION_ARG_TYPE_NUM, "action"))
830 if (action >= CLKO_MAX_INDEX) {
831 diag_printf("%d is not supported\n\n", action);
835 cosr = readl(CCM_BASE_ADDR + CLKCTL_COSR);
838 cosr = (cosr & (~0x1FF)) + action - 1;
839 if (action == 1 || action == 3 || action == 7 || action == 8) {
840 cosr |= (0x3 << 6); // make it divided by 8
842 writel(cosr, CCM_BASE_ADDR + CLKCTL_COSR);
843 diag_printf("Set clko to ");
846 cosr = readl(CCM_BASE_ADDR + CLKCTL_COSR);
847 diag_printf("%s\n", clko_name[(cosr & 0xF) + 1]);
848 diag_printf("COSR register[0x%x] = 0x%x\n",
849 (CCM_BASE_ADDR + CLKCTL_COSR), cosr);
854 * This command is added for some simple testing only. It turns on/off
855 * L2 cache regardless of L1 cache state. The side effect of this is
856 * when doing any flash operations such as "fis init", the L2
857 * will be turned back on along with L1 caches even though it is off
858 * by using this command.
866 void do_L2_caches(int argc, char *argv[])
872 if (strcasecmp(argv[1], "on") == 0) {
873 HAL_DISABLE_INTERRUPTS(oldints);
875 HAL_RESTORE_INTERRUPTS(oldints);
876 } else if (strcasecmp(argv[1], "off") == 0) {
877 HAL_DISABLE_INTERRUPTS(oldints);
878 HAL_CLEAN_INVALIDATE_L2();
880 HAL_RESTORE_INTERRUPTS(oldints);
882 diag_printf("Invalid L2 cache mode: %s\n", argv[1]);
885 HAL_L2CACHE_IS_ENABLED(L2cache_on);
886 diag_printf("L2 cache: %s\n", L2cache_on?"On":"Off");
889 #endif //L2CC_ENABLED
891 #define IIM_ERR_SHIFT 8
892 #define POLL_FUSE_PRGD (IIM_STAT_PRGD | (IIM_ERR_PRGE << IIM_ERR_SHIFT))
893 #define POLL_FUSE_SNSD (IIM_STAT_SNSD | (IIM_ERR_SNSE << IIM_ERR_SHIFT))
895 static void fuse_op_start(void)
897 /* Do not generate interrupt */
898 writel(0, IIM_BASE_ADDR + IIM_STATM_OFF);
899 // clear the status bits and error bits
900 writel(0x3, IIM_BASE_ADDR + IIM_STAT_OFF);
901 writel(0xFE, IIM_BASE_ADDR + IIM_ERR_OFF);
905 * The action should be either:
910 static int poll_fuse_op_done(int action)
915 if (action != POLL_FUSE_PRGD && action != POLL_FUSE_SNSD) {
916 diag_printf("%s(%d) invalid operation\n", __FUNCTION__, action);
920 /* Poll busy bit till it is NOT set */
921 while ((readl(IIM_BASE_ADDR + IIM_STAT_OFF) & IIM_STAT_BUSY) != 0 ) {
924 /* Test for successful write */
925 status = readl(IIM_BASE_ADDR + IIM_STAT_OFF);
926 error = readl(IIM_BASE_ADDR + IIM_ERR_OFF);
928 if ((status & action) != 0 && (error & (action >> IIM_ERR_SHIFT)) == 0) {
930 diag_printf("Even though the operation seems successful...\n");
931 diag_printf("There are some error(s) at addr=0x%x: 0x%x\n",
932 (IIM_BASE_ADDR + IIM_ERR_OFF), error);
936 diag_printf("%s(%d) failed\n", __FUNCTION__, action);
937 diag_printf("status address=0x%x, value=0x%x\n",
938 (IIM_BASE_ADDR + IIM_STAT_OFF), status);
939 diag_printf("There are some error(s) at addr=0x%x: 0x%x\n",
940 (IIM_BASE_ADDR + IIM_ERR_OFF), error);
944 static void sense_fuse(int bank, int row, int bit)
946 int addr, addr_l, addr_h, reg_addr;
950 addr = ((bank << 11) | (row << 3) | (bit & 0x7));
951 /* Set IIM Program Upper Address */
952 addr_h = (addr >> 8) & 0x000000FF;
953 /* Set IIM Program Lower Address */
954 addr_l = (addr & 0x000000FF);
956 #ifdef IIM_FUSE_DEBUG
957 diag_printf("%s: addr_h=0x%x, addr_l=0x%x\n",
958 __FUNCTION__, addr_h, addr_l);
960 writel(addr_h, IIM_BASE_ADDR + IIM_UA_OFF);
961 writel(addr_l, IIM_BASE_ADDR + IIM_LA_OFF);
963 writel(0x8, IIM_BASE_ADDR + IIM_FCTL_OFF);
964 if (poll_fuse_op_done(POLL_FUSE_SNSD) != 0) {
965 diag_printf("%s(bank: %d, row: %d, bit: %d failed\n",
966 __FUNCTION__, bank, row, bit);
968 reg_addr = IIM_BASE_ADDR + IIM_SDAT_OFF;
969 diag_printf("fuses at (bank:%d, row:%d) = 0x%x\n", bank, row, readl(reg_addr));
972 void do_fuse_read(int argc, char *argv[])
977 diag_printf("Useage: fuse_read <bank> <row>\n");
979 } else if (argc == 3) {
980 if (!parse_num(*(&argv[1]), (unsigned long *)&bank, &argv[1], " ")) {
981 diag_printf("Error: Invalid parameter\n");
984 if (!parse_num(*(&argv[2]), (unsigned long *)&row, &argv[2], " ")) {
985 diag_printf("Error: Invalid parameter\n");
989 diag_printf("Read fuse at bank:%d row:%d\n", bank, row);
990 sense_fuse(bank, row, 0);
993 diag_printf("Passing in wrong arguments: %d\n", argc);
994 diag_printf("Useage: fuse_read <bank> <row>\n");
998 /* Blow fuses based on the bank, row and bit positions (all 0-based)
1000 static int fuse_blow(int bank,int row,int bit)
1002 int addr, addr_l, addr_h, ret = -1;
1006 /* Disable IIM Program Protect */
1007 writel(0xAA, IIM_BASE_ADDR + IIM_PREG_P_OFF);
1009 addr = ((bank << 11) | (row << 3) | (bit & 0x7));
1010 /* Set IIM Program Upper Address */
1011 addr_h = (addr >> 8) & 0x000000FF;
1012 /* Set IIM Program Lower Address */
1013 addr_l = (addr & 0x000000FF);
1015 #ifdef IIM_FUSE_DEBUG
1016 diag_printf("blowing addr_h=0x%x, addr_l=0x%x\n", addr_h, addr_l);
1019 writel(addr_h, IIM_BASE_ADDR + IIM_UA_OFF);
1020 writel(addr_l, IIM_BASE_ADDR + IIM_LA_OFF);
1021 /* Start Programming */
1022 writel(0x31, IIM_BASE_ADDR + IIM_FCTL_OFF);
1023 if (poll_fuse_op_done(POLL_FUSE_PRGD) == 0) {
1027 /* Enable IIM Program Protect */
1028 writel(0x0, IIM_BASE_ADDR + IIM_PREG_P_OFF);
1033 * This command is added for burning IIM fuses
1035 RedBoot_cmd("fuse_read",
1041 RedBoot_cmd("fuse_blow",
1043 "<bank> <row> <value>",
1047 #define INIT_STRING "12345678"
1048 static char ready_to_blow[] = INIT_STRING;
1050 void quick_itoa(u32 num, char *a)
1053 for (i = 0; i <= 7; i++) {
1054 j = (num >> (4 * i)) & 0xF;
1055 k = (j < 10) ? '0' : ('a' - 0xa);
1060 void do_fuse_blow(int argc, char *argv[])
1062 int bank, row, value, i;
1065 diag_printf("It is too dangeous for you to use this command.\n");
1067 } else if (argc == 2) {
1068 if (strcasecmp(argv[1], "nandboot") == 0) {
1069 quick_itoa(readl(EPIT_BASE_ADDR + EPITCNR), ready_to_blow);
1070 diag_printf("%s\n", ready_to_blow);
1073 } else if (argc == 3) {
1074 if (strcasecmp(argv[1], "nandboot") == 0 &&
1075 strcasecmp(argv[2], ready_to_blow) == 0) {
1076 #if defined(CYGPKG_HAL_ARM_MXC91131) || defined(CYGPKG_HAL_ARM_MX21) || defined(CYGPKG_HAL_ARM_MX27) || defined(CYGPKG_HAL_ARM_MX31)
1077 diag_printf("No need to blow any fuses for NAND boot on this platform\n\n");
1079 diag_printf("Ready to burn NAND boot fuses\n");
1080 if (fuse_blow(0, 16, 1) != 0 || fuse_blow(0, 16, 7) != 0) {
1081 diag_printf("NAND BOOT fuse blown failed miserably ...\n");
1083 diag_printf("NAND BOOT fuse blown successfully ...\n");
1086 diag_printf("Not ready: %s, %s\n", argv[1], argv[2]);
1089 } else if (argc == 4) {
1090 if (!parse_num(*(&argv[1]), (unsigned long *)&bank, &argv[1], " ")) {
1091 diag_printf("Error: Invalid parameter\n");
1094 if (!parse_num(*(&argv[2]), (unsigned long *)&row, &argv[2], " ")) {
1095 diag_printf("Error: Invalid parameter\n");
1098 if (!parse_num(*(&argv[3]), (unsigned long *)&value, &argv[3], " ")) {
1099 diag_printf("Error: Invalid parameter\n");
1103 diag_printf("Blowing fuse at bank:%d row:%d value:%d\n",
1105 for (i = 0; i < 8; i++) {
1106 if (((value >> i) & 0x1) == 0) {
1109 if (fuse_blow(bank, row, i) != 0) {
1110 diag_printf("fuse_blow(bank: %d, row: %d, bit: %d failed\n",
1113 diag_printf("fuse_blow(bank: %d, row: %d, bit: %d successful\n",
1117 sense_fuse(bank, row, 0);
1120 diag_printf("Passing in wrong arguments: %d\n", argc);
1122 /* Reset to default string */
1123 strcpy(ready_to_blow, INIT_STRING);;
1126 /* precondition: m>0 and n>0. Let g=gcd(m,n). */
1127 int gcd(int m, int n)
1131 if(n > m) {t = m; m = n; n = t;} /* swap */
1137 #define CLOCK_SRC_DETECT_MS 100
1138 #define CLOCK_IPG_DEFAULT 66500000
1139 #define CLOCK_SRC_DETECT_MARGIN 500000
1140 void mxc_show_clk_input(void)
1142 // u32 c1, c2, diff, ipg_real, num = 0;
1148 diag_printf("FPM enabled --> 32KHz input source\n");
1153 diag_printf("Error %d: unknown clock source %d\n", __LINE__, prcs);
1157 // enable GPT with IPG clock input
1158 writel(0x241, GPT_BASE_ADDR + GPTCR);
1160 writel(0, GPT_BASE_ADDR + GPTPR);
1162 c1 = readl(GPT_BASE_ADDR + GPTCNT);
1163 // use 32KHz input clock to get the delay
1164 hal_delay_us(CLOCK_SRC_DETECT_MS * 1000);
1165 c2 = readl(GPT_BASE_ADDR + GPTCNT);
1166 diff = (c2 > c1) ? (c2 - c1) : (0xFFFFFFFF - c1 + c2);
1168 ipg_real = diff * (1000 / CLOCK_SRC_DETECT_MS);
1171 diag_printf("Error: Actural clock input is %d MHz\n", num);
1172 diag_printf(" ipg_real=%d CLOCK_IPG_DEFAULT - CLOCK_SRC_DETECT_MARGIN=%d\n\n",
1173 ipg_real, CLOCK_IPG_DEFAULT - CLOCK_SRC_DETECT_MARGIN);
1174 hal_delay_us(2000000);
1176 diag_printf("ipg_real=%d CLOCK_IPG_DEFAULT - CLOCK_SRC_DETECT_MARGIN=%d\n\n",
1177 ipg_real, CLOCK_IPG_DEFAULT - CLOCK_SRC_DETECT_MARGIN);
1182 RedBoot_init(mxc_show_clk_input, RedBoot_INIT_LAST);
1184 void imx_power_mode(int mode)
1186 volatile unsigned int val;
1189 diag_printf("WFI only\n");
1192 diag_printf("Entering WAIT mode\n");
1193 // wait mode - from validation code
1194 // Set DSM_INT_HOLDOFF bit in TZIC
1195 // If the TZIC didn't write the bit then there was interrupt pending
1196 // It will be serviced while we're in the loop
1197 // So we write to this bit again
1198 while (readl(INTC_BASE_ADDR + 0x14) == 0) {
1199 writel(1, INTC_BASE_ADDR + 0x14);
1209 val = readl(CCM_BASE_ADDR + 0x74);
1210 val = (val & 0xfffffffc) | 0x1; // set WAIT mode
1211 writel(val, CCM_BASE_ADDR + 0x74);
1212 val = readl(PLATFORM_LPC_REG);
1213 writel(val | (1 << 16), PLATFORM_LPC_REG);// ENABLE DSM in ELBOW submodule of ARM platform
1214 val = readl(PLATFORM_LPC_REG);
1215 writel(val | (1 << 17), PLATFORM_LPC_REG);// ENABLE DSM in ELBOW submodule of ARM platform
1218 diag_printf("Entering stop mode\n");
1220 // stop mode - from validation code
1221 // Set DSM_INT_HOLDOFF bit in TZIC
1222 // If the TZIC didn't write the bit then there was interrupt pending
1223 // It will be serviced while we're in the loop
1224 // So we write to this bit again
1225 while (readl(INTC_BASE_ADDR + 0x14) == 0) {
1226 writel(1, INTC_BASE_ADDR + 0x14);
1236 val = readl(CCM_BASE_ADDR + 0x74);
1237 val = (val & 0xfffffffc) | 0x2; // set STOP mode
1238 writel(val, CCM_BASE_ADDR + 0x74);
1239 val = readl(PLATFORM_LPC_REG);
1240 writel(val | (3 << 16), PLATFORM_LPC_REG);// ENABLE DSM in ELBOW submodule of ARM platform
1242 // power gating these peripherals
1243 writel(0x0000030f, GPC_PGR);
1244 writel(0x1, SRPGCR_EMI);
1245 writel(0x1, SRPGCR_ARM);
1246 writel(0x1, PGC_PGCR_VPU);
1247 writel(0x1, PGC_PGCR_IPU);
1250 diag_printf("Unknown low power mode: %d\n", mode);
1255 asm("mcr p15, 0, r1, c7, c0, 4");
1258 void do_power_mode(int argc, char *argv[])
1263 diag_printf("Useage: power_mode <mode>\n");
1265 } else if (argc == 2) {
1266 if (!parse_num(*(&argv[1]), (unsigned long *)&mode, &argv[1], " ")) {
1267 diag_printf("Error: Invalid parameter\n");
1270 imx_power_mode(mode);
1273 diag_printf("Passing in wrong arguments: %d\n", argc);
1274 diag_printf("Useage: power_mode <mode>\n");
1279 * This command is added for burning IIM fuses
1281 RedBoot_cmd("power_mode",
1282 "Enter various power modes:",
1287 <3> - STOP with Power-Gating\n\
1288 -- need reset after issuing the command",