From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vipin KUMAR Date: Wed, 14 Jul 2010 10:39:38 +0530 Subject: [U-Boot] [PATCH 02/28] SPEAr : SMI erase and write timeouts increased In-Reply-To: <1279084204-3263-2-git-send-email-vipin.kumar@st.com> References: <1279084204-3263-1-git-send-email-vipin.kumar@st.com> <1279084204-3263-2-git-send-email-vipin.kumar@st.com> Message-ID: <1279084204-3263-3-git-send-email-vipin.kumar@st.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Vipin KUMAR SMI driver fails because of low timeout values. Increasing the write mode timeout and transfer timeouts to 15 ms Signed-off-by: Vipin Kumar --- arch/arm/include/asm/arch-spear/spr_smi.h | 4 +- drivers/mtd/spr_smi.c | 57 ++++++++++++++++++----------- 2 files changed, 38 insertions(+), 23 deletions(-) diff --git a/arch/arm/include/asm/arch-spear/spr_smi.h b/arch/arm/include/asm/arch-spear/spr_smi.h index 06df745..0cca000 100644 --- a/arch/arm/include/asm/arch-spear/spr_smi.h +++ b/arch/arm/include/asm/arch-spear/spr_smi.h @@ -109,7 +109,7 @@ struct flash_dev { }; #define SFLASH_PAGE_SIZE 0x100 /* flash page size */ -#define XFER_FINISH_TOUT 2 /* xfer finish timeout */ -#define WMODE_TOUT 2 /* write enable timeout */ +#define XFER_FINISH_TOUT 15 /* xfer finish timeout(in ms) */ +#define WMODE_TOUT 15 /* write enable timeout(in ms) */ #endif diff --git a/drivers/mtd/spr_smi.c b/drivers/mtd/spr_smi.c index 9a70a19..c6ba951 100644 --- a/drivers/mtd/spr_smi.c +++ b/drivers/mtd/spr_smi.c @@ -58,13 +58,15 @@ static struct flash_dev flash_ids[] = { * * Wait until TFF is set in status register */ -static void smi_wait_xfer_finish(int timeout) +static int smi_wait_xfer_finish(int timeout) { - while (timeout--) { + do { if (readl(&smicntl->smi_sr) & TFF) - break; + return 0; udelay(1000); - } + } while (timeout--); + + return -1; } /* @@ -82,7 +84,9 @@ static unsigned int smi_read_id(flash_info_t *info, int banknum) writel(READ_ID, &smicntl->smi_tr); writel((banknum << BANKSEL_SHIFT) | SEND | TX_LEN_1 | RX_LEN_3, &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); + + if (smi_wait_xfer_finish(XFER_FINISH_TOUT)) + return -EIO; value = (readl(&smicntl->smi_rr) & 0x00FFFFFF); @@ -104,11 +108,17 @@ static ulong flash_get_size(ulong base, int banknum) { flash_info_t *info = &flash_info[banknum]; struct flash_dev *dev; - unsigned int value; + int value; unsigned int density; int i; value = smi_read_id(info, banknum); + + if (value < 0) { + printf("Flash id could not be read\n"); + return 0; + } + density = (value >> 16) & 0xff; for (i = 0, dev = &flash_ids[0]; dev->density != 0x0; @@ -136,7 +146,7 @@ static ulong flash_get_size(ulong base, int banknum) * This routine will get the status register of the flash chip present at the * given bank */ -static unsigned int smi_read_sr(int bank) +static int smi_read_sr(int bank) { u32 ctrlreg1; @@ -150,7 +160,8 @@ static unsigned int smi_read_sr(int bank) /* Performing a RSR instruction in HW mode */ writel((bank << BANKSEL_SHIFT) | RD_STATUS_REG, &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); + if (smi_wait_xfer_finish(XFER_FINISH_TOUT)) + return -1; /* Restore the CTRL REG1 state */ writel(ctrlreg1, &smicntl->smi_cr1); @@ -169,13 +180,11 @@ static unsigned int smi_read_sr(int bank) */ static int smi_wait_till_ready(int bank, int timeout) { - int count; - unsigned int sr; + int sr; /* One chip guarantees max 5 msec wait here after page writes, but potentially three seconds (!) after page erase. */ - for (count = 0; count < timeout; count++) { - + do { sr = smi_read_sr(bank); if (sr < 0) break; @@ -184,7 +193,8 @@ static int smi_wait_till_ready(int bank, int timeout) /* Try again after 1m-sec */ udelay(1000); - } + } while (timeout--); + printf("SMI controller is still in wait, timeout=%d\n", timeout); return -EIO; } @@ -200,6 +210,7 @@ static int smi_write_enable(int bank) { u32 ctrlreg1; int timeout = WMODE_TOUT; + int sr; /* Store the CTRL REG1 state */ ctrlreg1 = readl(&smicntl->smi_cr1); @@ -210,19 +221,22 @@ static int smi_write_enable(int bank) /* Give the Flash, Write Enable command */ writel((bank << BANKSEL_SHIFT) | WE, &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); + if (smi_wait_xfer_finish(XFER_FINISH_TOUT)) + return -1; /* Restore the CTRL REG1 state */ writel(ctrlreg1, &smicntl->smi_cr1); - while (timeout--) { - if (smi_read_sr(bank) & (1 << (bank + WM_SHIFT))) + do { + sr = smi_read_sr(bank); + if (sr < 0) break; - udelay(1000); - } + else if (sr & (1 << (bank + WM_SHIFT))) + return 0; - if (timeout) - return 0; + /* Try again after 1m-sec */ + udelay(1000); + } while (timeout--); return -1; } @@ -291,7 +305,8 @@ static int smi_sector_erase(flash_info_t *info, unsigned int sector) writel(instruction, &smicntl->smi_tr); writel((bank << BANKSEL_SHIFT) | SEND | TX_LEN_4, &smicntl->smi_cr2); - smi_wait_xfer_finish(XFER_FINISH_TOUT); + if (smi_wait_xfer_finish(XFER_FINISH_TOUT)) + return -EIO; if (smi_wait_till_ready(bank, CONFIG_SYS_FLASH_ERASE_TOUT)) return -EBUSY; -- 1.6.0.2