i.MX53 sometimes hangs during boot

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

i.MX53 sometimes hangs during boot

跳至解决方案
2,783 次查看
mogenslauridsen
Contributor III

Hi,

We are using the iMX53 (iMX538). Some of the boards we manufacture have problems booting. This might be something like 5% of the boards. After one or more reset caused by watchdog the board finally boots. This can delay the startup from 6 sec to 1-2 minutes.

I have tried to find where it stops/hangs, and it happens while initializing the PLL's.

We use barebox but I have found the same sequence in u-boot:

First PLL3 is set to 400 MHz, then some peripheral is switched to PLL3 and finally PLL3 is changed to 216 MHz.
Does anyone know why PLL3 first is set to 400MHz and later to 216MHz?

See "imx5_setup_pll_400((void __iomem *)MX53_PLL2_BASE_ADDR);" and

"imx5_setup_pll_216((void __iomem *)MX53_PLL3_BASE_ADDR);" in the barebox code below.

Our boards seem to boot fine if I change the code to set PLL3 to 216 MHz in the first place and don't change PLL3 later.
But does this have any side effects?

Since this is only seen on some of the boards, I am guessing that something in some of the iMX53's doesn't run reliable at 400MHz, and hangs the boot process.

barebox: arch/arm/mach-imx/imx53.c:

void imx53_init_lowlevel_early(unsigned int cpufreq_mhz)
{
    void __iomem *ccm = (void __iomem *)MX53_CCM_BASE_ADDR;
    u32 r;

    imx5_init_lowlevel();

    /*
     * AIPS setup - Only setup MPROTx registers.
     * The PACR default values are good.
     * Set all MPROTx to be non-bufferable, trusted for R/W,
     * not forced to user-mode.
     */
    writel(0x77777777, MX53_AIPS1_BASE_ADDR + 0);
    writel(0x77777777, MX53_AIPS1_BASE_ADDR + 4);
    writel(0x77777777, MX53_AIPS2_BASE_ADDR + 0);
    writel(0x77777777, MX53_AIPS2_BASE_ADDR + 4);

    /* Gate of clocks to the peripherals first */
    writel(0x3fffffff, ccm + MX5_CCM_CCGR0);
    writel(0x00000000, ccm + MX5_CCM_CCGR1);
    writel(0x00000000, ccm + MX5_CCM_CCGR2);
    writel(0x00000000, ccm + MX5_CCM_CCGR3);
    writel(0x00030000, ccm + MX5_CCM_CCGR4);
    writel(0x00fff030, ccm + MX5_CCM_CCGR5);
    writel(0x0f00030f, ccm + MX5_CCM_CCGR6);
    writel(0x00000000, ccm + MX53_CCM_CCGR7);

    /* Switch ARM to step clock */
    writel(0x4, ccm + MX5_CCM_CCSR);

    if (cpufreq_mhz == 1000)
        imx5_setup_pll_1000((void __iomem *)MX53_PLL1_BASE_ADDR);
    else
        imx5_setup_pll_800((void __iomem *)MX53_PLL1_BASE_ADDR);

    imx5_setup_pll_400((void __iomem *)MX53_PLL3_BASE_ADDR);

        /* Switch peripheral to PLL3 */
    writel(0x00015154, ccm + MX5_CCM_CBCMR);
    writel(0x02888945 | (1<<16), ccm + MX5_CCM_CBCDR);

    /* make sure change is effective */
    while (readl(ccm + MX5_CCM_CDHIPR));

    imx5_setup_pll_400((void __iomem *)MX53_PLL2_BASE_ADDR);  <------------ 400MHz

    /* Switch peripheral to PLL2 */
    r = 0x00808145 |
        (2 << 10) |
        (0 << 16) |
        (1 << 19);

    writel(r, ccm + MX5_CCM_CBCDR);

    writel(0x00016154, ccm + MX5_CCM_CBCMR);

    r = readl(ccm + MX5_CCM_CSCMR1);

    /* change uart clk parent to pll2 */
    r &= ~MX5_CCM_CSCMR1_UART_CLK_SEL_MASK;
    r |= 1 << MX5_CCM_CSCMR1_UART_CLK_SEL_OFFSET;

    /* USB phy clock from osc */
    r &= ~(1 << MX5_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET);

    writel(r, ccm + MX5_CCM_CSCMR1);

    /* make sure change is effective */
    while (readl(ccm + MX5_CCM_CDHIPR));

    imx5_setup_pll_216((void __iomem *)MX53_PLL3_BASE_ADDR);  <------------ 216MHz
    imx5_setup_pll_455((void __iomem *)MX53_PLL4_BASE_ADDR);

    /* Set the platform clock dividers */
    writel(0x00000124, MX53_ARM_BASE_ADDR + 0x14);

    writel(0, ccm + MX5_CCM_CACRR);

    /* Switch ARM back to PLL 1. */
    writel(0, ccm + MX5_CCM_CCSR);

    /* make uart div = 6*/
    r = readl(ccm + MX5_CCM_CSCDR1);
    r &= ~0x3f;
    r |= 0x0a;

    r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK;
    r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK;
    r |= 1 << MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET;

    r &= ~MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PRED_MASK;
    r &= ~MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_MASK;
    r |= 1 << MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_OFFSET;

    r &= ~MX5_CCM_CSCDR1_USBOH3_CLK_PRED_MASK;
    r &= ~MX5_CCM_CSCDR1_USBOH3_CLK_PODF_MASK;

    r |= 3 << MX5_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET;
    r |= 1 << MX5_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET;

    writel(r, ccm + MX5_CCM_CSCDR1);

    /* Restore the default values in the Gate registers */
    writel(0xffffffff, ccm + MX5_CCM_CCGR0);
    writel(0xffffffff, ccm + MX5_CCM_CCGR1);
    writel(0xffffffff, ccm + MX5_CCM_CCGR2);
    writel(0xffffffff, ccm + MX5_CCM_CCGR3);
    writel(0xffffffff, ccm + MX5_CCM_CCGR4);
    writel(0xffffffff, ccm + MX5_CCM_CCGR5);
    writel(0xffffffff, ccm + MX5_CCM_CCGR6);
    writel(0xffffffff, ccm + MX53_CCM_CCGR7);

    writel(0, ccm + MX5_CCM_CCDR);
}

标签 (1)
0 项奖励
回复
1 解答
2,611 次查看
fabio_estevam
NXP Employee
NXP Employee

Hi Mogens,

I think it is safer to setup the PLL3 only once to 216MHz.

Could you please prepare such patch and submit it to the Barebox list?

Regards,

Fabio Estevam

在原帖中查看解决方案

0 项奖励
回复
4 回复数
2,612 次查看
fabio_estevam
NXP Employee
NXP Employee

Hi Mogens,

I think it is safer to setup the PLL3 only once to 216MHz.

Could you please prepare such patch and submit it to the Barebox list?

Regards,

Fabio Estevam

0 项奖励
回复
2,611 次查看
mogenslauridsen
Contributor III

Hi Fabio,

Thanks for your reply.

I have tested the solution (use 216 MHz instead of 400MHz and only setting it once) on 10 boards. This seem to fix the problem.

I will submit a patch to the barebox list.

Best regards,

Mogens

0 项奖励
回复
2,611 次查看
igorpadykov
NXP Employee
NXP Employee

Hi Mogens

to narrow down issue one can test ddr memory

Lab and Test Software (1)
DDR Stress tester kit for the i.MX51 and i.MX53

i.MX53 Quick Start Board|NXP 

and prolong POR up to 1 sec., to check if issue not caused by

clocks instability. Also may be useful to check ERR007080 erratum:

https://www.nxp.com/docs/en/errata/IMX53CE.pdf 

Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 项奖励
回复
2,611 次查看
mogenslauridsen
Contributor III

Hi Igor,

Thanks for your reply.

I don't think that the DDR is used at this stage of the boot process. And after 1 or more watchdog resets the board is finally booted then it runs perfectly. So the DDR seems to be OK.

erratum ERR007080: Good point. Luckly our hw design takes care of this problem.

Best regards,

Mogens

0 项奖励
回复