From 2a590d3fa5e2b15b88df70a17cd6d2d630a2c933 Mon Sep 17 00:00:00 2001 From: "Peter A. Bigot" Date: Sat, 20 Jul 2019 14:09:10 -0500 Subject: [PATCH] drivers/spi_nor: remove configurability of page/sector/block sizes The JEDEC API defines the hardware page, sector, and block sizes. Deprecate the Kconfig settings, remove the `erase-size-block` property, and add `has-be32k` to indicate that 32K-byte erase is supported. Rework the driver to use the constants instead of configured values. Signed-off-by: Peter A. Bigot --- .../nrf52840_pca10056/nrf52840_pca10056.dts | 1 + .../xtensa/intel_s1000_crb/Kconfig.defconfig | 6 -- .../intel_s1000_crb/intel_s1000_crb.dts | 1 - drivers/flash/Kconfig.nor | 6 +- drivers/flash/spi_nor.c | 79 +++++++------------ drivers/flash/spi_nor.h | 26 +++++- dts/bindings/mtd/jedec,spi-nor.yaml | 8 +- 7 files changed, 59 insertions(+), 68 deletions(-) diff --git a/boards/arm/nrf52840_pca10056/nrf52840_pca10056.dts b/boards/arm/nrf52840_pca10056/nrf52840_pca10056.dts index 5ead5a540ae..ae6653fe665 100644 --- a/boards/arm/nrf52840_pca10056/nrf52840_pca10056.dts +++ b/boards/arm/nrf52840_pca10056/nrf52840_pca10056.dts @@ -183,6 +183,7 @@ arduino_i2c: &i2c0 { label = "MX25R64"; jedec-id = <0xc2 0x28 0x17>; size = <67108864>; + has-be32k; wp-gpios = <&gpio0 22 0>; hold-gpios = <&gpio0 23 0>; }; diff --git a/boards/xtensa/intel_s1000_crb/Kconfig.defconfig b/boards/xtensa/intel_s1000_crb/Kconfig.defconfig index a7965ca428d..1bc6c144df2 100644 --- a/boards/xtensa/intel_s1000_crb/Kconfig.defconfig +++ b/boards/xtensa/intel_s1000_crb/Kconfig.defconfig @@ -174,12 +174,6 @@ config SPI config SPI_NOR default y -config SPI_NOR_PAGE_SIZE - default 256 - -config SPI_NOR_SECTOR_SIZE - default 4096 - config FLASH_HAS_PAGE_LAYOUT default y diff --git a/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts b/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts index f93d5dd6ba1..163c1ec20ec 100644 --- a/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts +++ b/boards/xtensa/intel_s1000_crb/intel_s1000_crb.dts @@ -55,7 +55,6 @@ label = "MX25UM512"; jedec-id = <0xc2 0x80 0x3a>; size = <0x2000000>; - erase-block-size = <0x10000>; write-block-size = <1>; }; }; diff --git a/drivers/flash/Kconfig.nor b/drivers/flash/Kconfig.nor index 6309dfa262a..2f732d9ac4c 100644 --- a/drivers/flash/Kconfig.nor +++ b/drivers/flash/Kconfig.nor @@ -30,12 +30,14 @@ config SPI_NOR_PAGE_SIZE int "Page size of SPI flash" default 0 help - This option specifies page size of SPI flash + Note: This option is deprecated and is ignored. Page size is + always 256. config SPI_NOR_SECTOR_SIZE int "Sector size of SPI flash" default 0 help - This option specifies sector size of SPI flash + Note: This option is deprecated and is ignored. Sector size + is always 4096. endif # SPI_NOR diff --git a/drivers/flash/spi_nor.c b/drivers/flash/spi_nor.c index db5f292e265..e1072b93a60 100644 --- a/drivers/flash/spi_nor.c +++ b/drivers/flash/spi_nor.c @@ -14,28 +14,7 @@ #include "spi_nor.h" #include "flash_priv.h" -#define SZ_256 0x100 -#define SZ_512 0x200 -#define SZ_1024 0x400 -#define SZ_4K 0x1000 -#define SZ_32K 0x8000 -#define SZ_64K 0x10000 - -#define MASK_256 0xFF -#define MASK_4K 0xFFF -#define MASK_32K 0x7FFF -#define MASK_64K 0xFFFF - #define SPI_NOR_MAX_ADDR_WIDTH 4 -#define SECTORS_COUNT ((DT_INST_0_JEDEC_SPI_NOR_SIZE / 8) \ - / CONFIG_SPI_NOR_SECTOR_SIZE) - -#define JEDEC_ID(x) \ - { \ - ((x) >> 16) & 0xFF, \ - ((x) >> 8) & 0xFF, \ - (x) & 0xFF, \ - } /** * struct spi_nor_data - Structure for defining the SPI NOR access @@ -178,8 +157,7 @@ static int spi_nor_read(struct device *dev, off_t addr, void *dest, int to_read; /* should be between 0 and flash size */ - if ((addr < 0) || (addr + size) > (params->sector_size - * params->n_sectors)) { + if ((addr < 0) || ((addr + size) > params->size)) { return -EINVAL; } @@ -189,8 +167,8 @@ static int spi_nor_read(struct device *dev, off_t addr, void *dest, while (size) { to_read = size; - if (size > params->page_size) { - to_read = params->page_size; + if (size > SPI_NOR_PAGE_SIZE) { + to_read = SPI_NOR_PAGE_SIZE; } ret = spi_nor_cmd_addr_read(dev, SPI_NOR_CMD_READ, addr, @@ -218,8 +196,7 @@ static int spi_nor_write(struct device *dev, off_t addr, const void *src, size_t to_write; /* should be between 0 and flash size */ - if ((addr < 0) || ((size + addr) > (params->sector_size * - params->n_sectors))) { + if ((addr < 0) || ((size + addr) > params->size)) { return -EINVAL; } @@ -230,8 +207,8 @@ static int spi_nor_write(struct device *dev, off_t addr, const void *src, spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); to_write = size; - if (size >= params->page_size) { - to_write = params->page_size; + if (size >= SPI_NOR_PAGE_SIZE) { + to_write = SPI_NOR_PAGE_SIZE; } ret = spi_nor_cmd_addr_write(dev, SPI_NOR_CMD_PP, addr, @@ -258,8 +235,7 @@ static int spi_nor_erase(struct device *dev, off_t addr, size_t size) const struct spi_nor_config *params = dev->config->config_info; /* should be between 0 and flash size */ - if ((addr < 0) || ((size + addr) > - (params->sector_size * params->n_sectors))) { + if ((addr < 0) || ((size + addr) > params->size)) { return -ENODEV; } @@ -269,33 +245,31 @@ static int spi_nor_erase(struct device *dev, off_t addr, size_t size) /* write enable */ spi_nor_cmd_write(dev, SPI_NOR_CMD_WREN); - if (size == (params->sector_size * params->n_sectors)) { + if (size == params->size) { /* chip erase */ spi_nor_cmd_write(dev, SPI_NOR_CMD_CE); - size -= (params->sector_size * params->n_sectors); - } else if ((DT_JEDEC_SPI_NOR_0_ERASE_BLOCK_SIZE == SZ_64K) - && (size >= SZ_64K) - && ((addr & MASK_64K) == 0)) { + size -= params->size; + } else if ((size >= SPI_NOR_BLOCK_SIZE) + && SPI_NOR_IS_BLOCK_ALIGNED(addr)) { /* 64 KiB block erase */ spi_nor_cmd_addr_write(dev, SPI_NOR_CMD_BE, addr, NULL, 0); - addr += SZ_64K; - size -= SZ_64K; - } else if ((DT_JEDEC_SPI_NOR_0_ERASE_BLOCK_SIZE == SZ_32K) - && (size >= SZ_32K) - && ((addr & MASK_32K) == 0)) { + addr += SPI_NOR_BLOCK_SIZE; + size -= SPI_NOR_BLOCK_SIZE; + } else if ((size >= SPI_NOR_BLOCK32_SIZE) + && SPI_NOR_IS_BLOCK32_ALIGNED(addr)) { /* 32 KiB block erase */ spi_nor_cmd_addr_write(dev, SPI_NOR_CMD_BE_32K, addr, NULL, 0); - addr += SZ_32K; - size -= SZ_32K; - } else if ((size >= params->sector_size) && - ((addr & (params->sector_size - 1)) == 0)) { + addr += SPI_NOR_BLOCK32_SIZE; + size -= SPI_NOR_BLOCK32_SIZE; + } else if ((size >= SPI_NOR_SECTOR_SIZE) + && SPI_NOR_IS_SECTOR_ALIGNED(addr)) { /* sector erase */ spi_nor_cmd_addr_write(dev, SPI_NOR_CMD_SE, addr, NULL, 0); - addr += params->sector_size; - size -= params->sector_size; + addr += SPI_NOR_SECTOR_SIZE; + size -= SPI_NOR_SECTOR_SIZE; } else { /* minimal erase size is at least a sector size */ SYNC_UNLOCK(); @@ -385,8 +359,8 @@ static int spi_nor_init(struct device *dev) #if defined(CONFIG_FLASH_PAGE_LAYOUT) static const struct flash_pages_layout dev_layout = { - .pages_count = DT_INST_0_JEDEC_SPI_NOR_SIZE / 8 / DT_JEDEC_SPI_NOR_0_ERASE_BLOCK_SIZE, - .pages_size = DT_JEDEC_SPI_NOR_0_ERASE_BLOCK_SIZE, + .pages_count = DT_INST_0_JEDEC_SPI_NOR_SIZE / 8 / SPI_NOR_BLOCK_SIZE, + .pages_size = SPI_NOR_BLOCK_SIZE, }; static void spi_nor_pages_layout(struct device *dev, @@ -415,9 +389,10 @@ static const struct spi_nor_config flash_id = { DT_INST_0_JEDEC_SPI_NOR_JEDEC_ID_1, DT_INST_0_JEDEC_SPI_NOR_JEDEC_ID_2, }, - .page_size = CONFIG_SPI_NOR_PAGE_SIZE, - .sector_size = CONFIG_SPI_NOR_SECTOR_SIZE, - .n_sectors = SECTORS_COUNT, +#ifdef DT_INST_0_JEDEC_SPI_NOR_HAS_BE32K + .has_be32k = true, +#endif /* DT_INST_0_JEDEC_SPI_NOR_HAS_BE32K */ + .size = DT_INST_0_JEDEC_SPI_NOR_SIZE / 8, }; static struct spi_nor_data spi_nor_memory_data; diff --git a/drivers/flash/spi_nor.h b/drivers/flash/spi_nor.h index 6343c64cece..801784551f7 100644 --- a/drivers/flash/spi_nor.h +++ b/drivers/flash/spi_nor.h @@ -12,10 +12,14 @@ #define SPI_NOR_MAX_ID_LEN 3 struct spi_nor_config { + /* JEDEC id from devicetree */ u8_t id[SPI_NOR_MAX_ID_LEN]; - u32_t page_size; - u32_t sector_size; - u32_t n_sectors; + + /* Indicates support for BE32K */ + bool has_be32k; + + /* Size from devicetree, in bytes */ + u32_t size; }; /* Status register bits */ @@ -35,4 +39,20 @@ struct spi_nor_config { #define SPI_NOR_CMD_CE 0xC7 /* Chip erase */ #define SPI_NOR_CMD_RDID 0x9F /* Read JEDEC ID */ +/* Page, sector, and block size are standard, not configurable. */ +#define SPI_NOR_PAGE_SIZE 0x0100U +#define SPI_NOR_SECTOR_SIZE 0x1000U +#define SPI_NOR_BLOCK_SIZE 0x10000U + +/* Some devices support erase operations on 32 KiBy blocks. + * Support is indicated by the has-be32k property. + */ +#define SPI_NOR_BLOCK32_SIZE 0x8000 + +/* Test whether offset is aligned. */ +#define SPI_NOR_IS_PAGE_ALIGNED(_ofs) (((_ofs) & (SPI_NOR_PAGE_SIZE - 1U)) == 0) +#define SPI_NOR_IS_SECTOR_ALIGNED(_ofs) (((_ofs) & (SPI_NOR_SECTOR_SIZE - 1U)) == 0) +#define SPI_NOR_IS_BLOCK_ALIGNED(_ofs) (((_ofs) & (SPI_NOR_BLOCK_SIZE - 1U)) == 0) +#define SPI_NOR_IS_BLOCK32_ALIGNED(_ofs) (((_ofs) & (SPI_NOR_BLOCK32_SIZE - 1U)) == 0) + #endif /*__SPI_NOR_H__*/ diff --git a/dts/bindings/mtd/jedec,spi-nor.yaml b/dts/bindings/mtd/jedec,spi-nor.yaml index e79faff8994..05fdb2546e8 100644 --- a/dts/bindings/mtd/jedec,spi-nor.yaml +++ b/dts/bindings/mtd/jedec,spi-nor.yaml @@ -21,10 +21,10 @@ properties: category: required description: JEDEC ID as manufacturer ID, memory type, memory density - erase-block-size: - type: int - description: address alignment required by flash erase operations - category: optional + has-be32k: + type: boolean + category: optional + description: Indicates the device supports the BE32K command write-block-size: type: int