[U-Boot] [PATCH v3 03/19] SPEAr : SMI erase and write timeouts increased
Vipin KUMAR
vipin.kumar at st.com
Thu May 6 13:18:45 CEST 2010
SMI driver fails because of low timeout values. Increasing the write mode
timeout and transfer timeouts to 15 ms
Signed-off-by: Vipin Kumar <vipin.kumar at st.com>
---
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
More information about the U-Boot
mailing list