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);
}
Solved! Go to Solution.
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
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
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
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
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!
-----------------------------------------------------------------------------------------------------------------------
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