diff options
Diffstat (limited to 'drivers/mtd/spi-nor/core.h')
-rw-r--r-- | drivers/mtd/spi-nor/core.h | 138 |
1 files changed, 61 insertions, 77 deletions
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 9217379b9c..93cd2fc360 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -10,6 +10,13 @@ #include "sfdp.h" #define SPI_NOR_MAX_ID_LEN 6 +/* + * 256 bytes is a sane default for most older flashes. Newer flashes will + * have the page size defined within their SFDP tables. + */ +#define SPI_NOR_DEFAULT_PAGE_SIZE 256 +#define SPI_NOR_DEFAULT_N_BANKS 1 +#define SPI_NOR_DEFAULT_SECTOR_SIZE SZ_64K /* Standard SPI NOR flash operations. */ #define SPI_NOR_READID_OP(naddr, ndummy, buf, len) \ @@ -353,6 +360,7 @@ struct spi_nor_otp { * in octal DTR mode. * @rdsr_addr_nbytes: dummy address bytes needed for Read Status Register * command in octal DTR mode. + * @n_banks: number of banks. * @n_dice: number of dice in the flash memory. * @vreg_offset: volatile register offset for each die. * @hwcaps: describes the read and page program hardware @@ -389,6 +397,7 @@ struct spi_nor_flash_parameter { u8 addr_mode_nbytes; u8 rdsr_dummy; u8 rdsr_addr_nbytes; + u8 n_banks; u8 n_dice; u32 *vreg_offset; @@ -438,21 +447,31 @@ struct spi_nor_fixups { }; /** + * struct spi_nor_id - SPI NOR flash ID. + * + * @bytes: the bytes returned by the flash when issuing command 9F. Typically, + * the first byte is the manufacturer ID code (see JEP106) and the next + * two bytes are a flash part specific ID. + * @len: the number of bytes of ID. + */ +struct spi_nor_id { + const u8 *bytes; + u8 len; +}; + +/** * struct flash_info - SPI NOR flash_info entry. + * @id: pointer to struct spi_nor_id or NULL, which means "no ID" (mostly + * older chips). * @name: the name of the flash. - * @id: the flash's ID bytes. The first three bytes are the - * JEDIC ID. JEDEC ID zero means "no ID" (mostly older chips). - * @id_len: the number of bytes of ID. - * @sector_size: the size listed here is what works with SPINOR_OP_SE, which - * isn't necessarily called a "sector" by the vendor. - * @n_sectors: the number of sectors. - * @n_banks: the number of banks. - * @page_size: the flash's page size. + * @size: the size of the flash in bytes. + * @sector_size: (optional) the size listed here is what works with + * SPINOR_OP_SE, which isn't necessarily called a "sector" by + * the vendor. Defaults to 64k. + * @n_banks: (optional) the number of banks. Defaults to 1. + * @page_size: (optional) the flash's page size. Defaults to 256. * @addr_nbytes: number of address bytes to send. * - * @parse_sfdp: true when flash supports SFDP tables. The false value has no - * meaning. If one wants to skip the SFDP tables, one should - * instead use the SPI_NOR_SKIP_SFDP sfdp_flag. * @flags: flags that indicate support that is not defined by the * JESD216 standard in its SFDP tables. Flag meanings: * SPI_NOR_HAS_LOCK: flash supports lock/unlock via SR @@ -503,15 +522,13 @@ struct spi_nor_fixups { */ struct flash_info { char *name; - u8 id[SPI_NOR_MAX_ID_LEN]; - u8 id_len; + const struct spi_nor_id *id; + size_t size; unsigned sector_size; - u16 n_sectors; u16 page_size; u8 n_banks; u8 addr_nbytes; - bool parse_sfdp; u16 flags; #define SPI_NOR_HAS_LOCK BIT(0) #define SPI_NOR_HAS_TB BIT(1) @@ -540,70 +557,23 @@ struct flash_info { u8 mfr_flags; - const struct spi_nor_otp_organization otp_org; + const struct spi_nor_otp_organization *otp; const struct spi_nor_fixups *fixups; }; -#define SPI_NOR_ID_2ITEMS(_id) ((_id) >> 8) & 0xff, (_id) & 0xff -#define SPI_NOR_ID_3ITEMS(_id) ((_id) >> 16) & 0xff, SPI_NOR_ID_2ITEMS(_id) - -#define SPI_NOR_ID(_jedec_id, _ext_id) \ - .id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_2ITEMS(_ext_id) }, \ - .id_len = !(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0)) - -#define SPI_NOR_ID6(_jedec_id, _ext_id) \ - .id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \ - .id_len = 6 - -#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks) \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .n_banks = (_n_banks) - -/* Used when the "_ext_id" is two bytes at most */ -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors) \ - SPI_NOR_ID((_jedec_id), (_ext_id)), \ - SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), - -#define INFOB(_jedec_id, _ext_id, _sector_size, _n_sectors, _n_banks) \ - SPI_NOR_ID((_jedec_id), (_ext_id)), \ - SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), (_n_banks)), - -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors) \ - SPI_NOR_ID6((_jedec_id), (_ext_id)), \ - SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1), +#define SNOR_ID(...) \ + (&(const struct spi_nor_id){ \ + .bytes = (const u8[]){ __VA_ARGS__ }, \ + .len = sizeof((u8[]){ __VA_ARGS__ }), \ + }) -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes) \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = (_page_size), \ - .n_banks = 1, \ - .addr_nbytes = (_addr_nbytes), \ - .flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR, \ - -#define OTP_INFO(_len, _n_regions, _base, _offset) \ - .otp_org = { \ - .len = (_len), \ - .base = (_base), \ - .offset = (_offset), \ - .n_regions = (_n_regions), \ - }, - -#define PARSE_SFDP \ - .parse_sfdp = true, \ - -#define FLAGS(_flags) \ - .flags = (_flags), \ - -#define NO_SFDP_FLAGS(_no_sfdp_flags) \ - .no_sfdp_flags = (_no_sfdp_flags), \ - -#define FIXUP_FLAGS(_fixup_flags) \ - .fixup_flags = (_fixup_flags), \ - -#define MFR_FLAGS(_mfr_flags) \ - .mfr_flags = (_mfr_flags), \ +#define SNOR_OTP(_len, _n_regions, _base, _offset) \ + (&(const struct spi_nor_otp_organization){ \ + .len = (_len), \ + .base = (_base), \ + .offset = (_offset), \ + .n_regions = (_n_regions), \ + }) /** * struct spi_nor_manufacturer - SPI NOR manufacturer object @@ -631,11 +601,9 @@ struct sfdp { /* Manufacturer drivers. */ extern const struct spi_nor_manufacturer spi_nor_atmel; -extern const struct spi_nor_manufacturer spi_nor_catalyst; extern const struct spi_nor_manufacturer spi_nor_eon; extern const struct spi_nor_manufacturer spi_nor_esmt; extern const struct spi_nor_manufacturer spi_nor_everspin; -extern const struct spi_nor_manufacturer spi_nor_fujitsu; extern const struct spi_nor_manufacturer spi_nor_gigadevice; extern const struct spi_nor_manufacturer spi_nor_intel; extern const struct spi_nor_manufacturer spi_nor_issi; @@ -734,6 +702,22 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd) return container_of(mtd, struct spi_nor, mtd); } +/** + * spi_nor_needs_sfdp() - returns true if SFDP parsing is used for this flash. + * + * Return: true if SFDP parsing is needed + */ +static inline bool spi_nor_needs_sfdp(const struct spi_nor *nor) +{ + /* + * The flash size is one property parsed by the SFDP. We use it as an + * indicator whether we need SFDP parsing for a particular flash. I.e. + * non-legacy flash entries in flash_info will have a size of zero iff + * SFDP should be used. + */ + return !nor->info->size; +} + #ifdef CONFIG_DEBUG_FS void spi_nor_debugfs_register(struct spi_nor *nor); void spi_nor_debugfs_shutdown(void); |