summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllen Xu <b45815@freescale.com>2014-08-26 21:49:14 -0500
committerAllen Xu <b45815@freescale.com>2014-08-29 12:38:52 -0500
commitac62726276687242ce08ebe90ee765efb41abf3b (patch)
treed8572e149c86802efcdc142e73243699c77e73de
parent315f94ac5460bc2c06e9b4c14f2869170ce3e03e (diff)
downloadu-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.c38
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;
-
}
}