Skip to content

Commit

Permalink
drivers: flash: npcx: Update erase function to allow 0x1000 byte eras…
Browse files Browse the repository at this point in the history
…e size

Modify the NPCX driver erase method to allow 0x1000 byte size erases
along with 0x10000 byte size erases based on input parameters

Signed-off-by: Madhurima Paruchuri <mparuchuri@google.com>
  • Loading branch information
madhurimaparuchuri authored and Umar Nisar committed Aug 15, 2023
1 parent 1168f6e commit fffaf73
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 24 deletions.
36 changes: 19 additions & 17 deletions drivers/flash/flash_npcx_fiu_nor.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(flash_npcx_fiu_nor, CONFIG_FLASH_LOG_LEVEL);

#define BLOCK_64K_SIZE KB(64)
#define BLOCK_4K_SIZE KB(4)

/* Device config */
struct flash_npcx_nor_config {
/* QSPI bus device for mutex control and bus configuration */
Expand All @@ -31,8 +34,6 @@ struct flash_npcx_nor_config {
uintptr_t mapped_addr;
/* Size of nor device in bytes, from size property */
uint32_t flash_size;
/* Minimum size for flash erase */
uint32_t min_erase_size;
/* Maximum chip erase time-out in ms */
uint32_t max_timeout;
/* SPI Nor device configuration on QSPI bus */
Expand Down Expand Up @@ -253,12 +254,12 @@ static int flash_npcx_nor_read(const struct device *dev, off_t addr,
return 0;
}

static int flash_npcx_nor_erase(const struct device *dev, off_t addr,
size_t size)
static int flash_npcx_nor_erase(const struct device *dev, off_t addr, size_t size)
{
const struct flash_npcx_nor_config *config = dev->config;
int ret = 0;
uint8_t opcode;
bool offset_4k_aligned = SPI_NOR_IS_SECTOR_ALIGNED(addr);
bool offset_64k_aligned = SPI_NOR_IS_64K_ALIGNED(addr);

/* Out of the region of nor flash device? */
if (!is_within_region(addr, size, 0, config->flash_size)) {
Expand All @@ -267,13 +268,13 @@ static int flash_npcx_nor_erase(const struct device *dev, off_t addr,
}

/* address must be sector-aligned */
if (!SPI_NOR_IS_SECTOR_ALIGNED(addr)) {
if (!offset_4k_aligned) {
LOG_ERR("Addr %ld is not sector-aligned", addr);
return -EINVAL;
}

/* size must be a multiple of sectors */
if ((size % config->min_erase_size) != 0) {
if ((size % BLOCK_4K_SIZE) != 0) {
LOG_ERR("Size %d is not a multiple of sectors", size);
return -EINVAL;
}
Expand All @@ -284,20 +285,22 @@ static int flash_npcx_nor_erase(const struct device *dev, off_t addr,
/* Send chip erase command */
flash_npcx_uma_cmd_only(dev, SPI_NOR_CMD_CE);
return flash_npcx_nor_wait_until_ready(dev);
} else if (config->min_erase_size == KB(4)) {
opcode = SPI_NOR_CMD_SE;
} else if (config->min_erase_size == KB(64)) {
opcode = SPI_NOR_CMD_BE;
} else {
return -EINVAL;
}

while (size > 0) {
flash_npcx_uma_cmd_only(dev, SPI_NOR_CMD_WREN);
/* Send page/block erase command with addr */
flash_npcx_uma_cmd_by_addr(dev, opcode, addr);
addr += config->min_erase_size;
size -= config->min_erase_size;
if ((size >= BLOCK_64K_SIZE) && offset_64k_aligned) {
flash_npcx_uma_cmd_by_addr(dev, SPI_NOR_CMD_BE, addr);
addr += BLOCK_64K_SIZE;
size -= BLOCK_64K_SIZE;
} else if ((size >= BLOCK_4K_SIZE) && offset_4k_aligned) {
flash_npcx_uma_cmd_by_addr(dev, SPI_NOR_CMD_SE, addr);
addr += BLOCK_4K_SIZE;
size -= BLOCK_4K_SIZE;
} else {
return -EINVAL;
}
ret = flash_npcx_nor_wait_until_ready(dev);
if (ret != 0) {
break;
Expand Down Expand Up @@ -600,7 +603,6 @@ static const struct flash_npcx_nor_config flash_npcx_nor_config_##n = { \
.qspi_bus = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(n))), \
.mapped_addr = DT_INST_PROP(n, mapped_addr), \
.flash_size = DT_INST_PROP(n, size) / 8, \
.min_erase_size = DT_INST_PROP(n, min_erase_size), \
.max_timeout = DT_INST_PROP(n, max_timeout), \
.qspi_cfg = { \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
Expand Down
2 changes: 2 additions & 0 deletions drivers/flash/spi_nor.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,7 @@
/* Test whether offset is aligned to a given number of bits. */
#define SPI_NOR_IS_ALIGNED(_ofs, _bits) (((_ofs) & BIT_MASK(_bits)) == 0)
#define SPI_NOR_IS_SECTOR_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 12)
#define SPI_NOR_IS_32K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 15)
#define SPI_NOR_IS_64K_ALIGNED(_ofs) SPI_NOR_IS_ALIGNED(_ofs, 16)

#endif /*__SPI_NOR_H__*/
7 changes: 0 additions & 7 deletions dts/bindings/flash_controller/nuvoton,npcx-fiu-nor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,6 @@ properties:
type: int
required: true
description: Mapped memory address of direct read access for spi nor flash.
min-erase-size:
type: int
default: 0x10000
description: Minimum erase size of spi nor flash.
enum:
- 0x1000 # 4KB (Sector Erase)
- 0x10000 # 64KB (Block Erase)
max-timeout:
type: int
default: 10000
Expand Down

0 comments on commit fffaf73

Please sign in to comment.