diff options
author | Allen Xu <b45815@freescale.com> | 2014-08-26 21:49:14 -0500 |
---|---|---|
committer | Allen Xu <b45815@freescale.com> | 2014-08-29 12:38:52 -0500 |
commit | ac62726276687242ce08ebe90ee765efb41abf3b (patch) | |
tree | d8572e149c86802efcdc142e73243699c77e73de | |
parent | 315f94ac5460bc2c06e9b4c14f2869170ce3e03e (diff) | |
download | u-boot-imx-ac62726276687242ce08ebe90ee765efb41abf3b.zip u-boot-imx-ac62726276687242ce08ebe90ee765efb41abf3b.tar.gz u-boot-imx-ac62726276687242ce08ebe90ee765efb41abf3b.tar.bz2 |
ENGR00323255 Fixed QSPI randomly access timeout issue
The QSPI clock rate was set without disabling the clock gate, the
randomly glitch may mess up the clock and there will be no clock output,
when kernel boot up the QSPI access will fail.
To debug this issueon i.MX6SX SDB, changed the u-boot bootscript to 'sf probe; reset'
to keep rebooting, the issue can be reproduced in 20 mins, set clock out
register in CCM and measured TP86, found there is no clock ouput.
To fix this bug, disable clock gate before changing clock rate.
NOTICE: QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate, need
to disable both of them.
Signed-off-by: Allen Xu <b45815@freescale.com>
-rw-r--r-- | arch/arm/cpu/armv7/mx6/clock.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 700d190..af92a17 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -530,35 +530,41 @@ void enable_qspi_clk(int qspi_num) /* Enable QuadSPI clock */ switch (qspi_num) { case 0: - reg = readl(&imx_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_QSPI1_OFFSET; - writel(reg, &imx_ccm->CCGR3); + /*disable the clock gate*/ + clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); /* set 50M : (50 = 396 / 2 / 4) */ - reg = readl(&imx_ccm->cscmr1); - reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK | + reg = readl(&imx_ccm->cscmr1); + reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK | MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK); - reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) | + reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) | (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET)); - writel(reg, &imx_ccm->cscmr1); + writel(reg, &imx_ccm->cscmr1); + + /*enable the clock gate*/ + setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); break; case 1: - reg = readl(&imx_ccm->CCGR4); - reg |= MXC_CCM_CCGR4_QSPI2_ENFC_OFFSET; - writel(reg, &imx_ccm->CCGR4); + /*disable the clock gatei*/ + /*QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate, disable both of them*/ + clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK + | MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); - /* set 50M : (50 = 396 / 2 / 4) */ - reg = readl(&imx_ccm->cs2cdr); - reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | + /* set 50M : (50 = 396 / 2 / 4) */ + reg = readl(&imx_ccm->cs2cdr); + reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK); - reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) | + reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) | MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3)); - writel(reg, &imx_ccm->cs2cdr); + writel(reg, &imx_ccm->cs2cdr); + + /*enable the clock gate*/ + setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK + | MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); break; default: break; - } } |