Message ID | 1304284220-15215-3-git-send-email-sguinot@lacie.com |
---|---|
State | Changes Requested |
Headers | show |
this needs to be rewritten to use the common spi flash code. please see the sst_unlock func for an example of how to do this. -mike
> -----Original Message----- > From: Simon Guinot [mailto:sguinot@lacie.com] > Sent: Monday, May 02, 2011 2:40 AM > To: Prafulla Wadaskar; Albert ARIBAUD; Wolfgang Denk > Cc: u-boot@lists.denx.de; Simon Guinot > Subject: [PATCH v2 2/6] sf: disable write protection for Macronix flash > > Signed-off-by: Simon Guinot <sguinot@lacie.com> > --- > drivers/mtd/spi/macronix.c | 87 > ++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 87 insertions(+), 0 deletions(-) > > diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c > index 8e4d71c..b587ac9 100644 > --- a/drivers/mtd/spi/macronix.c > +++ b/drivers/mtd/spi/macronix.c > @@ -49,6 +49,10 @@ > #define CMD_MX25XX_DP 0xb9 /* Deep Power-down */ > #define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature > */ > > +/* Status registers */ > +#define MX25XX_SR_BP (0xF << 2) /* Block Protect */ > +#define MX25XX_SR_SRWP (1 << 7) /* Write Protect */ > + > struct macronix_spi_flash_params { > u16 idcode; > u16 page_size; > @@ -120,6 +124,86 @@ static const struct macronix_spi_flash_params > macronix_spi_flash_table[] = { > }, > }; > > +static int macronix_write_status(struct spi_flash *flash, u8 sr) > +{ > + u8 cmd[2]; > + int ret; > + > + ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0); > + if (ret < 0) { > + debug("SF: Enabling Write failed\n"); > + return ret; > + } > + > + cmd[0] = CMD_MX25XX_WRSR; > + cmd[1] = sr; > + ret = spi_xfer(flash->spi, 16, cmd, NULL, SPI_XFER_BEGIN); > + if (ret) { > + debug("SF: fail to write status register\n"); > + return ret; > + } > + > + spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_END); > + > + ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); > + if (ret < 0) { > + debug("SF: write status register timed out\n"); > + return ret; > + } > + > + return 0; > +} > + > +static int macronix_read_status(struct spi_flash *flash, u8 *sr) > +{ > + u8 cmd = CMD_MX25XX_RDSR; > + int ret; > + > + ret = spi_xfer(flash->spi, 8, &cmd, NULL, SPI_XFER_BEGIN); > + if (ret) { > + debug("SF: Failed to send command %02x: %d\n", cmd, ret); > + return ret; > + } > + ret = spi_xfer(flash->spi, 8, NULL, sr, 0); > + if (ret) { > + debug("SF: fail to read status register: %d\n", ret); > + return ret; > + } > + > + spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_END); > + > + return 0; > +} > + > +static int macronix_disable_protect(struct spi_flash *flash) > +{ > + int ret; > + u8 sr; > + > + ret = macronix_read_status(flash, &sr); > + if (ret) > + return ret; > + > + if ((sr & MX25XX_SR_BP) == 0) > + return ret; > + > + /* Disable status register write protection. */ > + sr &= ~MX25XX_SR_SRWP; > + ret = macronix_write_status(flash, sr); > + if (ret) > + return ret; > + > + /* Disable block protection. */ > + sr &= ~MX25XX_SR_BP; > + ret = macronix_write_status(flash, sr); > + if (ret) > + return ret; > + > + printf("SF: disable write protection\n"); > + > + return 0; > +} > + > static int macronix_write(struct spi_flash *flash, > u32 offset, size_t len, const void *buf) > { > @@ -223,5 +307,8 @@ struct spi_flash *spi_flash_probe_macronix(struct > spi_slave *spi, u8 *idcode) > * params->sectors_per_block; > mcx->flash.size = mcx->flash.sector_size * params->nr_blocks; > > + if (macronix_disable_protect(&mcx->flash)) > + printf("SF: disable write protection failed\n"); > + This will forced disable the flash being written. What if some one has purposely protected certain flash sectors? This feature should be addressed through protect CLI Regards.. Prafulla . . > return &mcx->flash; > } > -- > 1.6.3.1
Hi Prafulla, On Mon, May 02, 2011 at 01:53:29AM -0700, Prafulla Wadaskar wrote: > > static int macronix_write(struct spi_flash *flash, > > u32 offset, size_t len, const void *buf) > > { > > @@ -223,5 +307,8 @@ struct spi_flash *spi_flash_probe_macronix(struct > > spi_slave *spi, u8 *idcode) > > * params->sectors_per_block; > > mcx->flash.size = mcx->flash.sector_size * params->nr_blocks; > > > > + if (macronix_disable_protect(&mcx->flash)) > > + printf("SF: disable write protection failed\n"); > > + > > This will forced disable the flash being written. Yes, as the SST driver do. Maybe it is good enough for the Macronix driver too ? > What if some one has purposely protected certain flash sectors? Honestly, I don't know. Block protection for SPI flashes is not supported either by u-boot (except for SST which only disable it) nor by Linux. So, I am not sure this feature is really used. > > This feature should be addressed through protect CLI I could add an unlock method to the SPI flash operation structure. And then, I could bind this method to a CLI command "sf unlock"... Do you want me to do that ? Regards, Simon
> -----Original Message----- > From: Simon Guinot [mailto:simon.guinot@sequanux.org] > Sent: Monday, May 02, 2011 3:28 PM > To: Prafulla Wadaskar > Cc: Simon Guinot; Albert ARIBAUD; Wolfgang Denk; u-boot@lists.denx.de; > Prabhanjan Sarnaik; Ashish Karkare; Mike Frysinger > Subject: Re: [U-Boot] [PATCH v2 2/6] sf: disable write protection for > Macronix flash > > Hi Prafulla, > > On Mon, May 02, 2011 at 01:53:29AM -0700, Prafulla Wadaskar wrote: > > > static int macronix_write(struct spi_flash *flash, > > > u32 offset, size_t len, const void *buf) > > > { > > > @@ -223,5 +307,8 @@ struct spi_flash > *spi_flash_probe_macronix(struct > > > spi_slave *spi, u8 *idcode) > > > * params->sectors_per_block; > > > mcx->flash.size = mcx->flash.sector_size * params->nr_blocks; > > > > > > + if (macronix_disable_protect(&mcx->flash)) > > > + printf("SF: disable write protection failed\n"); > > > + > > > > This will forced disable the flash being written. > > Yes, as the SST driver do. Maybe it is good enough for the Macronix > driver too ? > > > What if some one has purposely protected certain flash sectors? > > Honestly, I don't know. Block protection for SPI flashes is not > supported either by u-boot (except for SST which only disable it) > nor by Linux. So, I am not sure this feature is really used. > > > > > This feature should be addressed through protect CLI > > I could add an unlock method to the SPI flash operation structure. > And then, I could bind this method to a CLI command "sf unlock"... > > Do you want me to do that ? Let's get Mike's opinion on this. Regards.. Prafulla . .
On Mon, May 2, 2011 at 04:53, Prafulla Wadaskar wrote: > From: Simon Guinot [mailto:sguinot@lacie.com] >> --- a/drivers/mtd/spi/macronix.c >> +++ b/drivers/mtd/spi/macronix.c >> + if (macronix_disable_protect(&mcx->flash)) >> + printf("SF: disable write protection failed\n"); > > This will forced disable the flash being written. > What if some one has purposely protected certain flash sectors? > > This feature should be addressed through protect CLI there is no spi flash protect api today, so until that happens, what Simon is proposing is correct -mike
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c index 8e4d71c..b587ac9 100644 --- a/drivers/mtd/spi/macronix.c +++ b/drivers/mtd/spi/macronix.c @@ -49,6 +49,10 @@ #define CMD_MX25XX_DP 0xb9 /* Deep Power-down */ #define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature */ +/* Status registers */ +#define MX25XX_SR_BP (0xF << 2) /* Block Protect */ +#define MX25XX_SR_SRWP (1 << 7) /* Write Protect */ + struct macronix_spi_flash_params { u16 idcode; u16 page_size; @@ -120,6 +124,86 @@ static const struct macronix_spi_flash_params macronix_spi_flash_table[] = { }, }; +static int macronix_write_status(struct spi_flash *flash, u8 sr) +{ + u8 cmd[2]; + int ret; + + ret = spi_flash_cmd(flash->spi, CMD_MX25XX_WREN, NULL, 0); + if (ret < 0) { + debug("SF: Enabling Write failed\n"); + return ret; + } + + cmd[0] = CMD_MX25XX_WRSR; + cmd[1] = sr; + ret = spi_xfer(flash->spi, 16, cmd, NULL, SPI_XFER_BEGIN); + if (ret) { + debug("SF: fail to write status register\n"); + return ret; + } + + spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_END); + + ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); + if (ret < 0) { + debug("SF: write status register timed out\n"); + return ret; + } + + return 0; +} + +static int macronix_read_status(struct spi_flash *flash, u8 *sr) +{ + u8 cmd = CMD_MX25XX_RDSR; + int ret; + + ret = spi_xfer(flash->spi, 8, &cmd, NULL, SPI_XFER_BEGIN); + if (ret) { + debug("SF: Failed to send command %02x: %d\n", cmd, ret); + return ret; + } + ret = spi_xfer(flash->spi, 8, NULL, sr, 0); + if (ret) { + debug("SF: fail to read status register: %d\n", ret); + return ret; + } + + spi_xfer(flash->spi, 0, NULL, NULL, SPI_XFER_END); + + return 0; +} + +static int macronix_disable_protect(struct spi_flash *flash) +{ + int ret; + u8 sr; + + ret = macronix_read_status(flash, &sr); + if (ret) + return ret; + + if ((sr & MX25XX_SR_BP) == 0) + return ret; + + /* Disable status register write protection. */ + sr &= ~MX25XX_SR_SRWP; + ret = macronix_write_status(flash, sr); + if (ret) + return ret; + + /* Disable block protection. */ + sr &= ~MX25XX_SR_BP; + ret = macronix_write_status(flash, sr); + if (ret) + return ret; + + printf("SF: disable write protection\n"); + + return 0; +} + static int macronix_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf) { @@ -223,5 +307,8 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode) * params->sectors_per_block; mcx->flash.size = mcx->flash.sector_size * params->nr_blocks; + if (macronix_disable_protect(&mcx->flash)) + printf("SF: disable write protection failed\n"); + return &mcx->flash; }
Signed-off-by: Simon Guinot <sguinot@lacie.com> --- drivers/mtd/spi/macronix.c | 87 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 87 insertions(+), 0 deletions(-)