diff options
-rw-r--r-- | common/spi_nor.c | 55 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/spi_nor.h | 12 |
3 files changed, 62 insertions, 8 deletions
diff --git a/common/spi_nor.c b/common/spi_nor.c index bd8983bcd7..dd775242d3 100644 --- a/common/spi_nor.c +++ b/common/spi_nor.c @@ -125,9 +125,10 @@ static int spi_nor_wait(const struct spi_nor_device_t *spi_nor_device) /** * Read the Manufacturer bank and ID out of the JEDEC ID. */ -static int spi_nor_read_jedec_id(const struct spi_nor_device_t *spi_nor_device, - uint8_t *out_mfn_bank, - uint8_t *out_mfn_id) +static int spi_nor_read_jedec_mfn_id( + const struct spi_nor_device_t *spi_nor_device, + uint8_t *out_mfn_bank, + uint8_t *out_mfn_id) { int rv = EC_SUCCESS; uint8_t jedec_id[SPI_NOR_JEDEC_ID_BANKS]; @@ -518,6 +519,32 @@ int spi_nor_set_4b_mode(struct spi_nor_device_t *spi_nor_device, } /** + * Read JEDEC Identifier. + * + * @param spi_nor_device The Serial NOR Flash device to use. + * @param size Number of Bytes to read. + * @param data Destination buffer for data. + * @return ec_error_list (non-zero on error and timeout). + */ +int spi_nor_read_jedec_id(const struct spi_nor_device_t *spi_nor_device, + size_t size, uint8_t *data) { + int rv; + uint8_t cmd = SPI_NOR_OPCODE_JEDEC_ID; + + if (size > CONFIG_SPI_NOR_MAX_READ_SIZE) + return EC_ERROR_INVAL; + /* Claim the driver mutex. */ + mutex_lock(&driver_mutex); + /* Read the JEDEC ID. */ + rv = spi_transaction(&spi_devices[spi_nor_device->spi_master], + &cmd, 1, data, size); + /* Release the driver mutex. */ + mutex_unlock(&driver_mutex); + + return rv; +} + +/** * Read from the Serial NOR Flash device. * * @param spi_nor_device The Serial NOR Flash device to use. @@ -587,7 +614,8 @@ int spi_nor_erase(const struct spi_nor_device_t *spi_nor_device, uint32_t offset, size_t size) { int rv = EC_SUCCESS; - size_t erase_command_size; + size_t erase_command_size, erase_size; + uint8_t erase_opcode; /* Invalid input */ if ((offset % 4096 != 0) || (size % 4096 != 0) || (size < 4096)) @@ -607,8 +635,18 @@ int spi_nor_erase(const struct spi_nor_device_t *spi_nor_device, if (rv) goto err_free; + erase_opcode = SPI_NOR_DRIVER_SPECIFIED_OPCODE_4KIB_ERASE; + erase_size = 4096; + +#ifdef CONFIG_SPI_NOR_BLOCK_ERASE + if (!(offset % 65536) && size >= 65536) { + erase_opcode = + SPI_NOR_DRIVER_SPECIFIED_OPCODE_64KIB_ERASE; + erase_size = 65536; + } +#endif /* Set up the erase instruction. */ - buf[0] = SPI_NOR_DRIVER_SPECIFIED_OPCODE_4KIB_ERASE; + buf[0] = erase_opcode; if (spi_nor_device->in_4b_addressing_mode) { buf[1] = (offset & 0xFF000000) >> 24; buf[2] = (offset & 0xFF0000) >> 16; @@ -628,8 +666,8 @@ int spi_nor_erase(const struct spi_nor_device_t *spi_nor_device, if (rv) goto err_free; - offset += 4096; - size -= 4096; + offset += erase_size; + size -= erase_size; } /* Wait for the previous operation to finish. */ @@ -765,7 +803,8 @@ static int command_spi_nor_info(int argc, char **argv) spi_nor_device->page_size); /* Get JEDEC ID info. */ - rv = spi_nor_read_jedec_id(spi_nor_device, &mfn_bank, &mfn_id); + rv = spi_nor_read_jedec_mfn_id(spi_nor_device, &mfn_bank, + &mfn_id); if (rv != EC_SUCCESS) return rv; ccprintf("\tJEDEC ID bank %d manufacturing code 0x%x\n", diff --git a/include/config.h b/include/config.h index 39e7667c3c..7519fb6d58 100644 --- a/include/config.h +++ b/include/config.h @@ -1797,6 +1797,9 @@ * two. */ #undef CONFIG_SPI_NOR_MAX_WRITE_SIZE +/* If defined will enable block (64KiB) erase operations. */ +#undef CONFIG_SPI_NOR_BLOCK_ERASE + /* SPI master feature */ #undef CONFIG_SPI_MASTER diff --git a/include/spi_nor.h b/include/spi_nor.h index d6ad93f221..07be853520 100644 --- a/include/spi_nor.h +++ b/include/spi_nor.h @@ -79,6 +79,7 @@ extern const unsigned int spi_nor_devices_used; /* If needed in the future this driver can be extended to discover SFDP * advertised erase sizes and opcodes for SFDP v1.0+. */ #define SPI_NOR_DRIVER_SPECIFIED_OPCODE_4KIB_ERASE 0x20 +#define SPI_NOR_DRIVER_SPECIFIED_OPCODE_64KIB_ERASE 0xd8 /* If needed in the future this driver can be extended to discover 4B entry and * exit methods for SFDP v1.5+. */ @@ -120,6 +121,17 @@ int spi_nor_set_4b_mode(struct spi_nor_device_t *spi_nor_device, int enter_4b_addressing_mode); /** + * Read JEDEC Identifier. + * + * @param spi_nor_device The Serial NOR Flash device to use. + * @param size Number of Bytes to read. + * @param data Destination buffer for data. + * @return ec_error_list (non-zero on error and timeout). + */ +int spi_nor_read_jedec_id(const struct spi_nor_device_t *spi_nor_device, + size_t size, uint8_t *data); + +/** * Read from the Serial NOR Flash device. * * @param spi_nor_device The Serial NOR Flash device to use. |