diff options
author | Anson Huang <b20788@freescale.com> | 2011-12-13 14:48:51 +0800 |
---|---|---|
committer | Anson Huang <b20788@freescale.com> | 2011-12-20 20:14:54 +0800 |
commit | 3568732ec72b2d792aeb3f780b0d1f32d86f36ec (patch) | |
tree | 6627be5c2a0b4baa04f79c4a9cf7932b8eaccf3f | |
parent | 14dab831e8e93a7ee03de2c7cca00d4b81e00cdc (diff) | |
download | u-boot-imx-3568732ec72b2d792aeb3f780b0d1f32d86f36ec.zip u-boot-imx-3568732ec72b2d792aeb3f780b0d1f32d86f36ec.tar.gz u-boot-imx-3568732ec72b2d792aeb3f780b0d1f32d86f36ec.tar.bz2 |
ENGR00160621 [MX6]Workaround for reset issue
Add workaround for POR/wdog reset issue, we need to
do a CORE LDO reset everytime POR/wdog reset, otherwise
kernel will crash or hang when we booting more than 2
cores. Root cause is still under investigation, it is
analog/power related issue, may take long time to
identify the root cause, we need to add workaround to make
function ready first. The flow of workaround is as below:
1. Check CORE LDO reset flag, currently stored in SNVS_LPGPR[0];
2. If it is there, clear it, go on boot up system; If not,
Set the flag, configure wdog to timeout in 0.5 seconds, then
disable CORE LDO and wait for wdog timeout;
This workaround will bring 0.5~1 seconds delay of booting.
Signed-off-by: Anson Huang <b20788@freescale.com>
-rw-r--r-- | cpu/arm_cortexa8/mx6/generic.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/cpu/arm_cortexa8/mx6/generic.c b/cpu/arm_cortexa8/mx6/generic.c index 47b9cd1..216308b 100644 --- a/cpu/arm_cortexa8/mx6/generic.c +++ b/cpu/arm_cortexa8/mx6/generic.c @@ -82,6 +82,8 @@ enum pll_clocks { #define NFC_CLK_MAX PLL2_FREQ_MAX #endif +#define SNVS_LPGPR_OFFSET 0x68 + static u32 __decode_pll(enum pll_clocks pll, u32 infreq) { u32 div; @@ -843,6 +845,29 @@ int cpu_eth_init(bd_t *bis) int arch_cpu_init(void) { int val; + unsigned int reg; + + /* Check the flag of SNVS_LPGPR[0], SRC register will not reset + when we do a wdog reset, so we keep flag in SNVS_LPGPR[0], + when we finish this workaround, we will clear it */ + reg = readl(SNVS_BASE_ADDR + SNVS_LPGPR_OFFSET); + /* If flagg is not set */ + if (!(reg & 0x1)) { + /* Set flag in SNVS_LPGPR[0] */ + writel(readl(SNVS_BASE_ADDR + SNVS_LPGPR_OFFSET) | 0x1, + SNVS_BASE_ADDR + SNVS_LPGPR_OFFSET); + /* Set wdog to timeout in 0.5 second */ + writew(0x34, WDOG1_BASE_ADDR); + /* Disable CORE LDO */ + writel(0x0, ANATOP_BASE_ADDR + HW_ANADIG_REG_CORE); + /* Wait for wdog timeout */ + while (1) + ; + } else { + /* Clear flag */ + writel(readl(SNVS_BASE_ADDR + SNVS_LPGPR_OFFSET) & (~0x1), + SNVS_BASE_ADDR + SNVS_LPGPR_OFFSET); + } icache_enable(); dcache_enable(); |