On 12/06/2012 07:21 AM, Vipin Kumar wrote: > The write loop is checking for dest_addr alignment with page size. This > sometimes leads to smi controller coming out of write mode and eventually the > next write failing with ERF1 being set. > > To avoid this, write to flash in a tight loop and write bytewise to also > support > not word aligned data bytes to be written. Additionally, enable burst mode > before this loop so that the controller does not deselect the chip if the > transfer is finished. > > Signed-off-by: Vipin Kumar <vipin.ku...@st.com> > --- > drivers/mtd/st_smi.c | 30 +++++++++++++----------------- > 1 file changed, 13 insertions(+), 17 deletions(-) > > diff --git a/drivers/mtd/st_smi.c b/drivers/mtd/st_smi.c > index a84802a..998bacb 100644 > --- a/drivers/mtd/st_smi.c > +++ b/drivers/mtd/st_smi.c > @@ -368,13 +368,11 @@ static int smi_sector_erase(flash_info_t *info, > unsigned int sector) > * > * Write to SMI flash > */ > -static int smi_write(unsigned int *src_addr, unsigned int *dst_addr, > +static int smi_write(unsigned char *src_addr, unsigned char *dst_addr, > unsigned int length, ulong bank_addr) > { > - u8 *src_addr8 = (u8 *)src_addr; > - u8 *dst_addr8 = (u8 *)dst_addr; > int banknum; > - int i, issue_we; > + int issue_we; > > switch (bank_addr) { > case SMIBANK0_BASE: > @@ -400,7 +398,10 @@ static int smi_write(unsigned int *src_addr, unsigned > int *dst_addr, > writel(readl(&smicntl->smi_cr1) & ~SW_MODE, &smicntl->smi_cr1); > > /* Perform the write command */ > - for (i = 0; i < length; i += 4) { > + while (length) { > + int k; > + unsigned int wlen = min(SFLASH_PAGE_SIZE, length); > + > if (issue_we || (((ulong)(dst_addr) % SFLASH_PAGE_SIZE) == 0)) { > issue_we = 0; > > @@ -412,19 +413,14 @@ static int smi_write(unsigned int *src_addr, unsigned > int *dst_addr, > return -EIO; > } > > - if (length < 4) { > - int k; > + writel(readl(&smicntl->smi_cr1) | WB_MODE, &smicntl->smi_cr1);
Use setbits_le32() please. > - /* > - * Handle special case, where length < 4 (redundant env) > - */ > - for (k = 0; k < length; k++) > - *dst_addr8++ = *src_addr8++; > - } else { > - /* Normal 32bit write */ > + for (k = 0; k < wlen; k++) > *dst_addr++ = *src_addr++; > - } > > + writel(readl(&smicntl->smi_cr1) & ~WB_MODE, &smicntl->smi_cr1); clrbits_le32() Thanks, Stefan _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot