* [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s @ 2017-01-24 13:52 mark.marshall 2017-01-24 16:48 ` Marek Vasut 0 siblings, 1 reply; 12+ messages in thread From: mark.marshall @ 2017-01-24 13:52 UTC (permalink / raw) To: computersforpeace, linux-mtd Cc: markmarshall14, cyrille.pitchen, marek.vasut, dwmw2, boris.brezillon, richard, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> The s25fl512s flash from Spansion has a 512 byte write page size, which means that we can write 512 bytes at a time (instead of 256). This single change makes writing to the flash about 2x faster. Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> --- drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index da7cd69..c9ac0bf 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) .page_size = 256, \ .flags = (_flags), +/* Used to set a custom (non 256) page_size */ +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \ + .id = { \ + ((_jedec_id) >> 16) & 0xff, \ + ((_jedec_id) >> 8) & 0xff, \ + (_jedec_id) & 0xff, \ + ((_ext_id) >> 8) & 0xff, \ + (_ext_id) & 0xff, \ + }, \ + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = (_pg_sz), \ + .flags = (_flags), \ + #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ @@ -905,7 +920,7 @@ static const struct flash_info spi_nor_ids[] = { { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl512s", INFOP(0x010220, 0x4d00, 256 * 1024, 256, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, -- 2.7.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s 2017-01-24 13:52 [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s mark.marshall @ 2017-01-24 16:48 ` Marek Vasut 2017-01-26 14:58 ` Mark Marshall 0 siblings, 1 reply; 12+ messages in thread From: Marek Vasut @ 2017-01-24 16:48 UTC (permalink / raw) To: mark.marshall, computersforpeace, linux-mtd Cc: markmarshall14, cyrille.pitchen, dwmw2, boris.brezillon, richard On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote: > From: Mark Marshall <mark.marshall@omicronenergy.com> > > The s25fl512s flash from Spansion has a 512 byte write page size, > which means that we can write 512 bytes at a time (instead of 256). > > This single change makes writing to the flash about 2x faster. > > Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> > --- > drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++- > 1 file changed, 16 insertions(+), 1 deletion(-) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index da7cd69..c9ac0bf 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) > .page_size = 256, \ > .flags = (_flags), > > +/* Used to set a custom (non 256) page_size */ > +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \ > + .id = { \ > + ((_jedec_id) >> 16) & 0xff, \ > + ((_jedec_id) >> 8) & 0xff, \ > + (_jedec_id) & 0xff, \ > + ((_ext_id) >> 8) & 0xff, \ > + (_ext_id) & 0xff, \ > + }, \ > + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ > + .sector_size = (_sector_size), \ > + .n_sectors = (_n_sectors), \ > + .page_size = (_pg_sz), \ > + .flags = (_flags), \ > + Maybe it's time to introduce INFO_FULL() instead, where you could specify the page size and ID length. Adding more and more custom INFOx() doesn't scale. The INFOx() could then be easily converted over to INFO_FULL(). One minor bit which could be slightly problematic is the .id_len field, which is precomputed now, but maybe there is a way to handle that too. Thoughts ? > #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ > .sector_size = (_sector_size), \ > .n_sectors = (_n_sectors), \ > @@ -905,7 +920,7 @@ static const struct flash_info spi_nor_ids[] = { > { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, > { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl512s", INFOP(0x010220, 0x4d00, 256 * 1024, 256, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, > { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, > { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, > -- Best regards, Marek Vasut ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s 2017-01-24 16:48 ` Marek Vasut @ 2017-01-26 14:58 ` Mark Marshall 2017-02-04 22:25 ` Marek Vasut 0 siblings, 1 reply; 12+ messages in thread From: Mark Marshall @ 2017-01-26 14:58 UTC (permalink / raw) To: Marek Vasut Cc: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen, David Woodhouse, boris.brezillon, richard On 24 January 2017 at 17:48, Marek Vasut <marek.vasut@gmail.com> wrote: > On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote: >> From: Mark Marshall <mark.marshall@omicronenergy.com> >> >> The s25fl512s flash from Spansion has a 512 byte write page size, >> which means that we can write 512 bytes at a time (instead of 256). >> >> This single change makes writing to the flash about 2x faster. >> >> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> >> --- >> drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++- >> 1 file changed, 16 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c >> index da7cd69..c9ac0bf 100644 >> --- a/drivers/mtd/spi-nor/spi-nor.c >> +++ b/drivers/mtd/spi-nor/spi-nor.c >> @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) >> .page_size = 256, \ >> .flags = (_flags), >> >> +/* Used to set a custom (non 256) page_size */ >> +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \ >> + .id = { \ >> + ((_jedec_id) >> 16) & 0xff, \ >> + ((_jedec_id) >> 8) & 0xff, \ >> + (_jedec_id) & 0xff, \ >> + ((_ext_id) >> 8) & 0xff, \ >> + (_ext_id) & 0xff, \ >> + }, \ >> + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ >> + .sector_size = (_sector_size), \ >> + .n_sectors = (_n_sectors), \ >> + .page_size = (_pg_sz), \ >> + .flags = (_flags), \ >> + > > Maybe it's time to introduce INFO_FULL() instead, where you could > specify the page size and ID length. Adding more and more custom INFOx() > doesn't scale. The INFOx() could then be easily converted > over to INFO_FULL(). > > One minor bit which could be slightly problematic is the .id_len > field, which is precomputed now, but maybe there is a way to handle > that too. > > Thoughts ? I had a go at this, and my preferred method would be to use some token pasting, but I'm not sure how popular this will be? Below is the macro's I came up with and a few representative lines of the table. If no one objects I'll prepare a complete patch. (I've done this on a branch, and the table has changed slightly, where should I be basing a patch like this from?). I've checked by building the file both before and after my change, and the table doesn't change. #define _ID_NONE \ .id = {}, \ .id_len = 0 #define _ID_JEDEC(_jedec_id) \ .id = { \ ((_jedec_id) >> 16) & 0xff, \ ((_jedec_id) >> 8) & 0xff, \ (_jedec_id) & 0xff, \ }, \ .id_len = 3 #define _ID_JEDEC_EXT2(_jedec_id, _ext_id) \ .id = { \ ((_jedec_id) >> 16) & 0xff, \ ((_jedec_id) >> 8) & 0xff, \ (_jedec_id) & 0xff, \ ((_ext_id) >> 8) & 0xff, \ (_ext_id) & 0xff, \ }, \ .id_len = 5 #define _ID_JEDEC_EXT3(_jedec_id, _ext_id) \ .id = { \ ((_jedec_id) >> 16) & 0xff, \ ((_jedec_id) >> 8) & 0xff, \ (_jedec_id) & 0xff, \ ((_ext_id) >> 16) & 0xff, \ ((_ext_id) >> 8) & 0xff, \ (_ext_id) & 0xff, \ }, \ .id_len = 6 #define INFO_FULL(_id, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ _ID_ ## _id, \ .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ .page_size = (_pg_sz), \ .addr_width = (_addr_width), \ .flags = (_flags), #define INFO(_id, _sector_size, _n_sectors, _flags) \ INFO_FULL(_id, _sector_size, _n_sectors, 256, 0, _flags) static const struct flash_info spi_nor_ids[] = { { "at25fs010", INFO(JEDEC(0x1f6601), 32 * 1024, 4, SECT_4K) }, { "at25fs040", INFO(JEDEC(0x1f6604), 64 * 1024, 8, SECT_4K) }, { "mr25h256", INFO_FULL(NONE, 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "s25sl032p", INFO(JEDEC_EXT2(0x010215, 0x4d00), 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl512s", INFO_FULL(JEDEC_EXT2(0x010220, 0x4d00), 256 * 1024, 256, 256, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl128s", INFO(JEDEC_EXT3(0x012018, 0x4d0180), 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, { "cat25c11", INFO_FULL(NONE, 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, Regards, Mark ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s 2017-01-26 14:58 ` Mark Marshall @ 2017-02-04 22:25 ` Marek Vasut 2017-02-13 13:53 ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall 0 siblings, 1 reply; 12+ messages in thread From: Marek Vasut @ 2017-02-04 22:25 UTC (permalink / raw) To: Mark Marshall Cc: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen, David Woodhouse, boris.brezillon, richard On 01/26/2017 03:58 PM, Mark Marshall wrote: > On 24 January 2017 at 17:48, Marek Vasut <marek.vasut@gmail.com> wrote: >> On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote: >>> From: Mark Marshall <mark.marshall@omicronenergy.com> >>> >>> The s25fl512s flash from Spansion has a 512 byte write page size, >>> which means that we can write 512 bytes at a time (instead of 256). >>> >>> This single change makes writing to the flash about 2x faster. >>> >>> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> >>> --- >>> drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++- >>> 1 file changed, 16 insertions(+), 1 deletion(-) >>> >>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c >>> index da7cd69..c9ac0bf 100644 >>> --- a/drivers/mtd/spi-nor/spi-nor.c >>> +++ b/drivers/mtd/spi-nor/spi-nor.c >>> @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) >>> .page_size = 256, \ >>> .flags = (_flags), >>> >>> +/* Used to set a custom (non 256) page_size */ >>> +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \ >>> + .id = { \ >>> + ((_jedec_id) >> 16) & 0xff, \ >>> + ((_jedec_id) >> 8) & 0xff, \ >>> + (_jedec_id) & 0xff, \ >>> + ((_ext_id) >> 8) & 0xff, \ >>> + (_ext_id) & 0xff, \ >>> + }, \ >>> + .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ >>> + .sector_size = (_sector_size), \ >>> + .n_sectors = (_n_sectors), \ >>> + .page_size = (_pg_sz), \ >>> + .flags = (_flags), \ >>> + >> >> Maybe it's time to introduce INFO_FULL() instead, where you could >> specify the page size and ID length. Adding more and more custom INFOx() >> doesn't scale. The INFOx() could then be easily converted >> over to INFO_FULL(). >> >> One minor bit which could be slightly problematic is the .id_len >> field, which is precomputed now, but maybe there is a way to handle >> that too. >> >> Thoughts ? Sorry for the late reply, I've been traveling a lot recently. > I had a go at this, and my preferred method would be to use some token > pasting, but I'm not sure how popular this will be? IMO not much. > Below is the macro's I > came up with and a few representative lines of the table. If no one objects > I'll prepare a complete patch. (I've done this on a branch, and the table has > changed slightly, where should I be basing a patch like this from?). This makes me kinda wonder (and this might be a totally wrong idea), why don't we replace the 6-byte ID table with an u64 id and u64 mask ? _ID_JEDEC_EXT2 would then look something like: #define _ID_JEDEC_EXT2(_jedec_id, _ext_id) \ { \ .id = ((_ext_id) << 32) | (_jedec_id), \ .mask = GENMASK(47, 32) | GENMASK(23, 0), \ }, The match would then also be much easier, that is. ->id & ->mask == ->id instead of all the memcmp() tests. id_len would go away too. And the matching would allow more precise control over the test. We could even handle the n25q256(a) specialty jedec ID 0x20baxx/0x20bbxx with this. I don't think there'll ever be a SPI NOR with 8byte JEDEC ID, so u64 should be good enough. The macros below could be reworked to use a generic macro to define the ID/extID entry and it's width, ie: #define _ID_JEDEC(_jedec_id, _jedec_id_width, \ _ext_id, _ext_id_width) \ { \ .id = ((_ext_id) << 32) | (_jedec_id), \ .mask = GENMASK(32 + ((_ext_id_width * 8) - 1), 32) | \ GENMASK(((_id_width * 8) - 1), 0), \ }, > I've checked by building the file both before and after my change, and the > table doesn't change. > > #define _ID_NONE \ > .id = {}, \ > .id_len = 0 > > #define _ID_JEDEC(_jedec_id) \ > .id = { \ > ((_jedec_id) >> 16) & 0xff, \ > ((_jedec_id) >> 8) & 0xff, \ > (_jedec_id) & 0xff, \ > }, \ > .id_len = 3 > > #define _ID_JEDEC_EXT2(_jedec_id, _ext_id) \ > .id = { \ > ((_jedec_id) >> 16) & 0xff, \ > ((_jedec_id) >> 8) & 0xff, \ > (_jedec_id) & 0xff, \ > ((_ext_id) >> 8) & 0xff, \ > (_ext_id) & 0xff, \ > }, \ > .id_len = 5 > > #define _ID_JEDEC_EXT3(_jedec_id, _ext_id) \ > .id = { \ > ((_jedec_id) >> 16) & 0xff, \ > ((_jedec_id) >> 8) & 0xff, \ > (_jedec_id) & 0xff, \ > ((_ext_id) >> 16) & 0xff, \ > ((_ext_id) >> 8) & 0xff, \ > (_ext_id) & 0xff, \ > }, \ > .id_len = 6 > > #define INFO_FULL(_id, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ > _ID_ ## _id, \ > .sector_size = (_sector_size), \ > .n_sectors = (_n_sectors), \ > .page_size = (_pg_sz), \ > .addr_width = (_addr_width), \ > .flags = (_flags), > > #define INFO(_id, _sector_size, _n_sectors, _flags) \ > INFO_FULL(_id, _sector_size, _n_sectors, 256, 0, _flags) > > static const struct flash_info spi_nor_ids[] = { > { "at25fs010", INFO(JEDEC(0x1f6601), 32 * 1024, 4, SECT_4K) }, > { "at25fs040", INFO(JEDEC(0x1f6604), 64 * 1024, 8, SECT_4K) }, > { "mr25h256", INFO_FULL(NONE, 32 * 1024, 1, 256, 2, > SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > { "s25sl032p", INFO(JEDEC_EXT2(0x010215, 0x4d00), 64 * 1024, > 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s25fl512s", INFO_FULL(JEDEC_EXT2(0x010220, 0x4d00), 256 * > 1024, 256, 256, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s25fl128s", INFO(JEDEC_EXT3(0x012018, 0x4d0180), 64 * 1024, > 256, SECT_4K | SPI_NOR_QUAD_READ) }, > { "cat25c11", INFO_FULL(NONE, 16, 8, 16, 1, SPI_NOR_NO_ERASE | > SPI_NOR_NO_FR) }, > > Regards, > > Mark > -- Best regards, Marek Vasut ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID 2017-02-04 22:25 ` Marek Vasut @ 2017-02-13 13:53 ` mark.marshall 2017-02-14 5:02 ` Marek Vasut 0 siblings, 1 reply; 12+ messages in thread From: mark.marshall @ 2017-02-13 13:53 UTC (permalink / raw) To: computersforpeace, linux-mtd, marek.vasut Cc: markmarshall14, cyrille.pitchen, dwmw2, richard, boris.brezillon, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> The flash_info ID matching table is getting more complex as different chips are added. Some chips require different amounts of the response to the RDID command to be matched. Replace the current u8 array and length with a u64 id and a u64 id_mask. This allows us to simplify the macros used to generate the flash_info table without loosing the ability to generate "unusual" entries. -- This patch replaces "m25p80: Use a 512 byte page size for Spansion flash s25fl512s". It is based on for-linus-20170212, from the linux-mtd tree. Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> --- drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++--------------------- 1 file changed, 231 insertions(+), 227 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1ae872b..c7ff237 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -41,15 +41,20 @@ #define SPI_NOR_MAX_ADDR_WIDTH 4 struct flash_info { - char *name; + const char *name; /* - * This array stores the ID bytes. - * The first three bytes are the JEDIC ID. - * JEDEC ID zero means "no ID" (mostly older chips). + * This u64 stores the ID bytes. + * The bytes are stored in big-endian order. + * The upper three bytes are the JEDIC ID, the lower bytes are + * the extension. */ - u8 id[SPI_NOR_MAX_ID_LEN]; - u8 id_len; + u64 id; + + /* + * An id_mask of zero means "no ID" (mostly older chips). + */ + u64 id_mask; /* The size listed here is what works with SPINOR_OP_SE, which isn't * necessarily called a "sector" by the vendor. @@ -87,7 +92,7 @@ struct flash_info { */ }; -#define JEDEC_MFR(info) ((info)->id[0]) +#define JEDEC_MFR(info) ((u8)((info)->id >> 56) & 0xff) static const struct flash_info *spi_nor_match_id(const char *name); @@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) return ret; } -/* Used when the "_ext_id" is two bytes at most */ -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), - -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 16) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = 6, \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), - -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = (_page_size), \ - .addr_width = (_addr_width), \ - .flags = (_flags), - -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff \ - }, \ - .id_len = 3, \ - .sector_size = (8*_page_size), \ - .n_sectors = (_n_sectors), \ - .page_size = _page_size, \ - .addr_width = 3, \ - .flags = SPI_NOR_NO_FR | SPI_S3AN, +/* Used to provide the full information about a device. + */ +#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ + .id = (_id), \ + .id_mask = (_id_mask), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = (_pg_sz), \ + .addr_width = (_addr_width), \ + .flags = (_flags), + +/* Used to provide information for a standard JEDEC device. All + * devices created with this macro have a three octet JEDEC identifier + * and an optional extension identifier (normally 0, 2 or 3 octets + * long). + */ +#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \ + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) | \ + ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))), \ + GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))), \ + (_sector_size), \ + (_n_sectors), \ + 256, \ + 0, \ + (_flags)) + +#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ + INFO_FULL(0, \ + 0, \ + (_sector_size), \ + (_n_sectors), \ + (_page_size), \ + (_addr_width), \ + (_flags)) + +#define INFO_S3AN(_jedec_id, _n_sectors, _page_size) \ + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))), \ + GENMASK_ULL(63, 64 - (8 * 3)), \ + (8*_page_size), \ + (_n_sectors), \ + (_page_size), \ + 3, \ + SPI_NOR_NO_FR | SPI_S3AN) /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which @@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) */ static const struct flash_info spi_nor_ids[] = { /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, - { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, + { "at25fs010", INFO(0x1f6601, 0, 0, 32 * 1024, 4, SECT_4K) }, + { "at25fs040", INFO(0x1f6604, 0, 0, 64 * 1024, 8, SECT_4K) }, - { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, - { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, + { "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024, 8, SECT_4K) }, + { "at25df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "at25df641", INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) }, - { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, - { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, - { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, - { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, + { "at26f004", INFO(0x1f0400, 0, 0, 64 * 1024, 8, SECT_4K) }, + { "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) }, + { "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) }, + { "at26df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, + { "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) }, /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, + { "en25f32", INFO(0x1c3116, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "en25p32", INFO(0x1c2016, 0, 0, 64 * 1024, 64, 0) }, + { "en25q32b", INFO(0x1c3016, 0, 0, 64 * 1024, 64, 0) }, + { "en25p64", INFO(0x1c2017, 0, 0, 64 * 1024, 128, 0) }, + { "en25q64", INFO(0x1c3017, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "en25qh128", INFO(0x1c7018, 0, 0, 64 * 1024, 256, 0) }, + { "en25qh256", INFO(0x1c7019, 0, 0, 64 * 1024, 512, 0) }, + { "en25s64", INFO(0x1c3817, 0, 0, 64 * 1024, 128, SECT_4K) }, /* ESMT */ - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, + { "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, /* Everspin */ - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h10", INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h40", INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, /* Fujitsu */ - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, + { "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, /* GigaDevice */ { - "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, + "gd25q16", INFO(0xc84015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, + "gd25q32", INFO(0xc84016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, + "gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, + "gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, + "gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, + { "160s33b", INFO(0x898911, 0, 0, 64 * 1024, 32, 0) }, + { "320s33b", INFO(0x898912, 0, 0, 64 * 1024, 64, 0) }, + { "640s33b", INFO(0x898913, 0, 0, 64 * 1024, 128, 0) }, /* ISSI */ - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, + { "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024, 2, SECT_4K) }, /* Macronix */ - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, - { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, + { "mx25l512e", INFO(0xc22010, 0, 0, 64 * 1024, 1, SECT_4K) }, + { "mx25l2005a", INFO(0xc22012, 0, 0, 64 * 1024, 4, SECT_4K) }, + { "mx25l4005a", INFO(0xc22013, 0, 0, 64 * 1024, 8, SECT_4K) }, + { "mx25l8005", INFO(0xc22014, 0, 0, 64 * 1024, 16, 0) }, + { "mx25l1606e", INFO(0xc22015, 0, 0, 64 * 1024, 32, SECT_4K) }, + { "mx25l3205d", INFO(0xc22016, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "mx25l3255e", INFO(0xc29e16, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "mx25l6405d", INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "mx25u6435f", INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) }, + { "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) }, + { "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) }, + { "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) }, + { "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) }, + { "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, + { "mx66l1g55g", INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, /* Micron */ - { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q016a", INFO(0x20bb15, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q032", INFO(0x20ba16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, + { "n25q032a", INFO(0x20bb16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, + { "n25q064", INFO(0x20ba17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q064a", INFO(0x20bb17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q128a11", INFO(0x20bb18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q128a13", INFO(0x20ba18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q256a", INFO(0x20ba19, 0, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q512a", INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q512ax3", INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q00", INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q00a", INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, /* PMC */ - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, + { "pm25lv512", INFO_NOID(32 * 1024, 2, 256, 0, SECT_4K_PMC) }, + { "pm25lv010", INFO_NOID(32 * 1024, 4, 256, 0, SECT_4K_PMC) }, + { "pm25lq032", INFO(0x7f9d46, 0, 0, 64 * 1024, 64, SECT_4K) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, - { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, - { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, - { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, - { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, - { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, - { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, + { "s25sl032p", INFO(0x010215, 0x4d00, 2, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25sl064p", INFO(0x010216, 0x4d00, 2, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) }, + { "s25fl256s1", INFO(0x010219, 0x4d01, 2, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl512s", INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24), + 256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s70fl01gs", INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) }, + { "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(0x012018, 0x0301, 2, 64 * 1024, 256, 0) }, + { "s25fl128s", INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl129p1", INFO(0x012018, 0x4d01, 2, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25sl004a", INFO(0x010212, 0, 0, 64 * 1024, 8, 0) }, + { "s25sl008a", INFO(0x010213, 0, 0, 64 * 1024, 16, 0) }, + { "s25sl016a", INFO(0x010214, 0, 0, 64 * 1024, 32, 0) }, + { "s25sl032a", INFO(0x010215, 0, 0, 64 * 1024, 64, 0) }, + { "s25sl064a", INFO(0x010216, 0, 0, 64 * 1024, 128, 0) }, + { "s25fl004k", INFO(0xef4013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl008k", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl016k", INFO(0xef4015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl064k", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "s25fl116k", INFO(0x014015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl132k", INFO(0x014016, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "s25fl164k", INFO(0x014017, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "s25fl204k", INFO(0x014013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, + { "s25fl208k", INFO(0x014014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, - { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, - { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, - { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, - { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, - { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, - { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, - { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, - { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, - { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, + { "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, + { "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "sst25wf512", INFO(0xbf2501, 0, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, + { "sst25wf010", INFO(0xbf2502, 0, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, + { "sst25wf020", INFO(0xbf2503, 0, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, + { "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024, 4, SECT_4K) }, + { "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024, 8, SECT_4K) }, + { "sst25wf040", INFO(0xbf2504, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25wf080", INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, /* ST Microelectronics -- newer production may have feature updates */ - { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, - { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, - { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, - { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, - { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, - { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, - { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, - - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, - { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, - { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, - { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, - { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, - { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, - { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, - - { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, - { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, - { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, - - { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, - { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, - { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, - - { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, - { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, + { "m25p05", INFO(0x202010, 0, 0, 32 * 1024, 2, 0) }, + { "m25p10", INFO(0x202011, 0, 0, 32 * 1024, 4, 0) }, + { "m25p20", INFO(0x202012, 0, 0, 64 * 1024, 4, 0) }, + { "m25p40", INFO(0x202013, 0, 0, 64 * 1024, 8, 0) }, + { "m25p80", INFO(0x202014, 0, 0, 64 * 1024, 16, 0) }, + { "m25p16", INFO(0x202015, 0, 0, 64 * 1024, 32, 0) }, + { "m25p32", INFO(0x202016, 0, 0, 64 * 1024, 64, 0) }, + { "m25p64", INFO(0x202017, 0, 0, 64 * 1024, 128, 0) }, + { "m25p128", INFO(0x202018, 0, 0, 256 * 1024, 64, 0) }, + + { "m25p05-nonjedec", INFO_NOID( 32 * 1024, 2, 256, 0, 0) }, + { "m25p10-nonjedec", INFO_NOID( 32 * 1024, 4, 256, 0, 0) }, + { "m25p20-nonjedec", INFO_NOID( 64 * 1024, 4, 256, 0, 0) }, + { "m25p40-nonjedec", INFO_NOID( 64 * 1024, 8, 256, 0, 0) }, + { "m25p80-nonjedec", INFO_NOID( 64 * 1024, 16, 256, 0, 0) }, + { "m25p16-nonjedec", INFO_NOID( 64 * 1024, 32, 256, 0, 0) }, + { "m25p32-nonjedec", INFO_NOID( 64 * 1024, 64, 256, 0, 0) }, + { "m25p64-nonjedec", INFO_NOID( 64 * 1024, 128, 256, 0, 0) }, + { "m25p128-nonjedec", INFO_NOID(256 * 1024, 64, 256, 0, 0) }, + + { "m45pe10", INFO(0x204011, 0, 0, 64 * 1024, 2, 0) }, + { "m45pe80", INFO(0x204014, 0, 0, 64 * 1024, 16, 0) }, + { "m45pe16", INFO(0x204015, 0, 0, 64 * 1024, 32, 0) }, + + { "m25pe20", INFO(0x208012, 0, 0, 64 * 1024, 4, 0) }, + { "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16, 0) }, + { "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) }, + + { "m25px16", INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) }, + { "m25px32", INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "m25px64", INFO(0x207117, 0, 0, 64 * 1024, 128, 0) }, + { "m25px80", INFO(0x207114, 0, 0, 64 * 1024, 16, 0) }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, - { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, + { "w25x05", INFO(0xef3010, 0, 0, 64 * 1024, 1, SECT_4K) }, + { "w25x10", INFO(0xef3011, 0, 0, 64 * 1024, 2, SECT_4K) }, + { "w25x20", INFO(0xef3012, 0, 0, 64 * 1024, 4, SECT_4K) }, + { "w25x40", INFO(0xef3013, 0, 0, 64 * 1024, 8, SECT_4K) }, + { "w25x80", INFO(0xef3014, 0, 0, 64 * 1024, 16, SECT_4K) }, + { "w25x16", INFO(0xef3015, 0, 0, 64 * 1024, 32, SECT_4K) }, + { "w25x32", INFO(0xef3016, 0, 0, 64 * 1024, 64, SECT_4K) }, + { "w25q32", INFO(0xef4016, 0, 0, 64 * 1024, 64, SECT_4K) }, { - "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, + "w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) }, + { "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, { - "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, + "w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, + "w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, + { "w25q80", INFO(0xef5014, 0, 0, 64 * 1024, 16, SECT_4K) }, + { "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K) }, + { "w25q128", INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) }, + { "w25q256", INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) }, /* Catalyst / On Semiconductor -- non-JEDEC */ - { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c11", INFO_NOID( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c03", INFO_NOID( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, /* Xilinx S3AN Internal Flash */ - { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, - { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, - { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, + { "3S50AN", INFO_S3AN(0x1f2200, 64, 264) }, + { "3S200AN", INFO_S3AN(0x1f2400, 256, 264) }, + { "3S400AN", INFO_S3AN(0x1f2400, 256, 264) }, + { "3S700AN", INFO_S3AN(0x1f2500, 512, 264) }, + { "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) }, { }, }; static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) { int tmp; - u8 id[SPI_NOR_MAX_ID_LEN]; + u8 id_bytes[sizeof(u64)]; + u64 id; const struct flash_info *info; - tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); + BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64)); + + memset(id_bytes, 0, sizeof(id_bytes)); + tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN); if (tmp < 0) { dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); return ERR_PTR(tmp); } + id = get_unaligned_be64(id_bytes); + for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { info = &spi_nor_ids[tmp]; - if (info->id_len) { - if (!memcmp(info->id, id, info->id_len)) - return &spi_nor_ids[tmp]; - } + if (info->id_mask && (id & info->id_mask) == info->id) + return info; } - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", - id[0], id[1], id[2]); + dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", + SPI_NOR_MAX_ID_LEN, id_bytes); return ERR_PTR(-ENODEV); } @@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) * If caller has specified name of flash model that can normally be * detected using JEDEC, let's verify it. */ - if (name && info->id_len) { + if (name && info->id_mask) { const struct flash_info *jinfo; jinfo = spi_nor_read_id(nor); -- 2.7.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID 2017-02-13 13:53 ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall @ 2017-02-14 5:02 ` Marek Vasut 2017-02-14 10:22 ` Cyrille Pitchen 0 siblings, 1 reply; 12+ messages in thread From: Marek Vasut @ 2017-02-14 5:02 UTC (permalink / raw) To: mark.marshall, computersforpeace, linux-mtd Cc: markmarshall14, cyrille.pitchen, dwmw2, richard, boris.brezillon On 02/13/2017 02:53 PM, mark.marshall@omicronenergy.com wrote: > From: Mark Marshall <mark.marshall@omicronenergy.com> > > The flash_info ID matching table is getting more complex as different > chips are added. Some chips require different amounts of the response > to the RDID command to be matched. Replace the current u8 array and > length with a u64 id and a u64 id_mask. This allows us to simplify the > macros used to generate the flash_info table without loosing the ability > to generate "unusual" entries. > > -- > > This patch replaces "m25p80: Use a 512 byte page size for Spansion > flash s25fl512s". It is based on for-linus-20170212, from the > linux-mtd tree. > > > Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> Minor nits below, looks good IMO. I'd still like someone else to review this whole idea though. Cyrille ? > --- > drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++--------------------- > 1 file changed, 231 insertions(+), 227 deletions(-) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index 1ae872b..c7ff237 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -41,15 +41,20 @@ > #define SPI_NOR_MAX_ADDR_WIDTH 4 > > struct flash_info { > - char *name; > + const char *name; > > /* > - * This array stores the ID bytes. > - * The first three bytes are the JEDIC ID. > - * JEDEC ID zero means "no ID" (mostly older chips). > + * This u64 stores the ID bytes. > + * The bytes are stored in big-endian order. > + * The upper three bytes are the JEDIC ID, the lower bytes are > + * the extension. > */ > - u8 id[SPI_NOR_MAX_ID_LEN]; > - u8 id_len; > + u64 id; > + > + /* > + * An id_mask of zero means "no ID" (mostly older chips). > + */ > + u64 id_mask; > > /* The size listed here is what works with SPINOR_OP_SE, which isn't > * necessarily called a "sector" by the vendor. > @@ -87,7 +92,7 @@ struct flash_info { > */ > }; > > -#define JEDEC_MFR(info) ((info)->id[0]) > +#define JEDEC_MFR(info) ((u8)((info)->id >> 56) & 0xff) > > static const struct flash_info *spi_nor_match_id(const char *name); > > @@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) > return ret; > } > > -/* Used when the "_ext_id" is two bytes at most */ > -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ > - .id = { \ > - ((_jedec_id) >> 16) & 0xff, \ > - ((_jedec_id) >> 8) & 0xff, \ > - (_jedec_id) & 0xff, \ > - ((_ext_id) >> 8) & 0xff, \ > - (_ext_id) & 0xff, \ > - }, \ > - .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ > - .sector_size = (_sector_size), \ > - .n_sectors = (_n_sectors), \ > - .page_size = 256, \ > - .flags = (_flags), > - > -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ > - .id = { \ > - ((_jedec_id) >> 16) & 0xff, \ > - ((_jedec_id) >> 8) & 0xff, \ > - (_jedec_id) & 0xff, \ > - ((_ext_id) >> 16) & 0xff, \ > - ((_ext_id) >> 8) & 0xff, \ > - (_ext_id) & 0xff, \ > - }, \ > - .id_len = 6, \ > - .sector_size = (_sector_size), \ > - .n_sectors = (_n_sectors), \ > - .page_size = 256, \ > - .flags = (_flags), > - > -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ > - .sector_size = (_sector_size), \ > - .n_sectors = (_n_sectors), \ > - .page_size = (_page_size), \ > - .addr_width = (_addr_width), \ > - .flags = (_flags), > - > -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ > - .id = { \ > - ((_jedec_id) >> 16) & 0xff, \ > - ((_jedec_id) >> 8) & 0xff, \ > - (_jedec_id) & 0xff \ > - }, \ > - .id_len = 3, \ > - .sector_size = (8*_page_size), \ > - .n_sectors = (_n_sectors), \ > - .page_size = _page_size, \ > - .addr_width = 3, \ > - .flags = SPI_NOR_NO_FR | SPI_S3AN, > +/* Used to provide the full information about a device. > + */ Fix the comment format here , single line comment is enough ( /* comment */ ) > +#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ > + .id = (_id), \ > + .id_mask = (_id_mask), \ > + .sector_size = (_sector_size), \ > + .n_sectors = (_n_sectors), \ > + .page_size = (_pg_sz), \ > + .addr_width = (_addr_width), \ > + .flags = (_flags), > + > +/* Used to provide information for a standard JEDEC device. All > + * devices created with this macro have a three octet JEDEC identifier > + * and an optional extension identifier (normally 0, 2 or 3 octets > + * long). > + */ Multi-line comment looks like this: /* * foo * bar */ > +#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \ > + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) | \ > + ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))), \ Is the u64 cast needed ? I don't think so. > + GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))), \ You need parenthesis around _ext_len > + (_sector_size), \ > + (_n_sectors), \ > + 256, \ > + 0, \ > + (_flags)) > + > +#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ > + INFO_FULL(0, \ > + 0, \ > + (_sector_size), \ > + (_n_sectors), \ > + (_page_size), \ > + (_addr_width), \ > + (_flags)) > + > +#define INFO_S3AN(_jedec_id, _n_sectors, _page_size) \ > + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))), \ > + GENMASK_ULL(63, 64 - (8 * 3)), \ > + (8*_page_size), \ > + (_n_sectors), \ > + (_page_size), \ > + 3, \ > + SPI_NOR_NO_FR | SPI_S3AN) > > /* NOTE: double check command sets and memory organization when you add > * more nor chips. This current list focusses on newer chips, which > @@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) > */ > static const struct flash_info spi_nor_ids[] = { > /* Atmel -- some are (confusingly) marketed as "DataFlash" */ > - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, > - { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, > + { "at25fs010", INFO(0x1f6601, 0, 0, 32 * 1024, 4, SECT_4K) }, > + { "at25fs040", INFO(0x1f6604, 0, 0, 64 * 1024, 8, SECT_4K) }, > > - { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, > - { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, > - { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, > - { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, > + { "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024, 8, SECT_4K) }, > + { "at25df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "at25df641", INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) }, > > - { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, > - { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, > - { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, > - { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, > + { "at26f004", INFO(0x1f0400, 0, 0, 64 * 1024, 8, SECT_4K) }, > + { "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) }, > + { "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) }, > + { "at26df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, > > - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, > + { "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) }, > > /* EON -- en25xxx */ > - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, > - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, > - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, > - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, > - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, > - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, > - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, > - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, > + { "en25f32", INFO(0x1c3116, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "en25p32", INFO(0x1c2016, 0, 0, 64 * 1024, 64, 0) }, > + { "en25q32b", INFO(0x1c3016, 0, 0, 64 * 1024, 64, 0) }, > + { "en25p64", INFO(0x1c2017, 0, 0, 64 * 1024, 128, 0) }, > + { "en25q64", INFO(0x1c3017, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "en25qh128", INFO(0x1c7018, 0, 0, 64 * 1024, 256, 0) }, > + { "en25qh256", INFO(0x1c7019, 0, 0, 64 * 1024, 512, 0) }, > + { "en25s64", INFO(0x1c3817, 0, 0, 64 * 1024, 128, SECT_4K) }, > > /* ESMT */ > - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, > + { "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, > > /* Everspin */ > - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "mr25h10", INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "mr25h40", INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > > /* Fujitsu */ > - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, > + { "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, > > /* GigaDevice */ > { > - "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, > + "gd25q16", INFO(0xc84015, 0, 0, 64 * 1024, 32, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > { > - "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, > + "gd25q32", INFO(0xc84016, 0, 0, 64 * 1024, 64, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > { > - "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, > + "gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > { > - "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, > + "gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > { > - "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, > + "gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > > /* Intel/Numonyx -- xxxs33b */ > - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, > - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, > - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, > + { "160s33b", INFO(0x898911, 0, 0, 64 * 1024, 32, 0) }, > + { "320s33b", INFO(0x898912, 0, 0, 64 * 1024, 64, 0) }, > + { "640s33b", INFO(0x898913, 0, 0, 64 * 1024, 128, 0) }, > > /* ISSI */ > - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, > + { "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024, 2, SECT_4K) }, > > /* Macronix */ > - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, > - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, > - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, > - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, > - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, > - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, > - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, > - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, > - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, > - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, > - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, > - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, > - { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) }, > - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, > - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, > - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, > + { "mx25l512e", INFO(0xc22010, 0, 0, 64 * 1024, 1, SECT_4K) }, > + { "mx25l2005a", INFO(0xc22012, 0, 0, 64 * 1024, 4, SECT_4K) }, > + { "mx25l4005a", INFO(0xc22013, 0, 0, 64 * 1024, 8, SECT_4K) }, > + { "mx25l8005", INFO(0xc22014, 0, 0, 64 * 1024, 16, 0) }, > + { "mx25l1606e", INFO(0xc22015, 0, 0, 64 * 1024, 32, SECT_4K) }, > + { "mx25l3205d", INFO(0xc22016, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "mx25l3255e", INFO(0xc29e16, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "mx25l6405d", INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "mx25u6435f", INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) }, > + { "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) }, > + { "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) }, > + { "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) }, > + { "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) }, > + { "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, > + { "mx66l1g55g", INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, > > /* Micron */ > - { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, > - { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, > - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, > - { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > - { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > - { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > - { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > + { "n25q016a", INFO(0x20bb15, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q032", INFO(0x20ba16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, > + { "n25q032a", INFO(0x20bb16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, > + { "n25q064", INFO(0x20ba17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q064a", INFO(0x20bb17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q128a11", INFO(0x20bb18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q128a13", INFO(0x20ba18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q256a", INFO(0x20ba19, 0, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, > + { "n25q512a", INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > + { "n25q512ax3", INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > + { "n25q00", INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > + { "n25q00a", INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, > > /* PMC */ > - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, > - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, > - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, > + { "pm25lv512", INFO_NOID(32 * 1024, 2, 256, 0, SECT_4K_PMC) }, > + { "pm25lv010", INFO_NOID(32 * 1024, 4, 256, 0, SECT_4K_PMC) }, > + { "pm25lq032", INFO(0x7f9d46, 0, 0, 64 * 1024, 64, SECT_4K) }, > > /* Spansion -- single (large) sector size only, at least > * for the chips listed here (without boot sectors). > */ > - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, > - { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, > - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, > - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, > - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, > - { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, > - { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, > - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, > - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, > - { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, > - { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > - { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, > - { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, > - { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, > - { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, > + { "s25sl032p", INFO(0x010215, 0x4d00, 2, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25sl064p", INFO(0x010216, 0x4d00, 2, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) }, > + { "s25fl256s1", INFO(0x010219, 0x4d01, 2, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl512s", INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24), > + 256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, Hm, this syntax here could use some improvement ... ideas welcome. > + { "s70fl01gs", INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) }, > + { "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024, 64, 0) }, > + { "s25sl12801", INFO(0x012018, 0x0301, 2, 64 * 1024, 256, 0) }, > + { "s25fl128s", INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl129p1", INFO(0x012018, 0x4d01, 2, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25sl004a", INFO(0x010212, 0, 0, 64 * 1024, 8, 0) }, > + { "s25sl008a", INFO(0x010213, 0, 0, 64 * 1024, 16, 0) }, > + { "s25sl016a", INFO(0x010214, 0, 0, 64 * 1024, 32, 0) }, > + { "s25sl032a", INFO(0x010215, 0, 0, 64 * 1024, 64, 0) }, > + { "s25sl064a", INFO(0x010216, 0, 0, 64 * 1024, 128, 0) }, > + { "s25fl004k", INFO(0xef4013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl008k", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl016k", INFO(0xef4015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl064k", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "s25fl116k", INFO(0x014015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl132k", INFO(0x014016, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "s25fl164k", INFO(0x014017, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "s25fl204k", INFO(0x014013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, > + { "s25fl208k", INFO(0x014014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, > > /* SST -- large erase sizes are "overlays", "sectors" are 4K */ > - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, > - { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, > - { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, > - { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, > - { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, > - { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, > - { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, > - { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, > - { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, > - { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, > - { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, > - { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, > + { "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, > + { "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, > + { "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, > + { "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, > + { "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "sst25wf512", INFO(0xbf2501, 0, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, > + { "sst25wf010", INFO(0xbf2502, 0, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, > + { "sst25wf020", INFO(0xbf2503, 0, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, > + { "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024, 4, SECT_4K) }, > + { "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024, 8, SECT_4K) }, > + { "sst25wf040", INFO(0xbf2504, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, > + { "sst25wf080", INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, > > /* ST Microelectronics -- newer production may have feature updates */ > - { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, > - { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, > - { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, > - { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, > - { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, > - { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, > - { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, > - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, > - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, > - > - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, > - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, > - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, > - { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, > - { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, > - { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, > - { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, > - { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, > - { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, > - > - { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, > - { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, > - { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, > - > - { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, > - { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, > - { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, > - > - { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, > - { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, > - { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, > - { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, > - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, > - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, > + { "m25p05", INFO(0x202010, 0, 0, 32 * 1024, 2, 0) }, > + { "m25p10", INFO(0x202011, 0, 0, 32 * 1024, 4, 0) }, > + { "m25p20", INFO(0x202012, 0, 0, 64 * 1024, 4, 0) }, > + { "m25p40", INFO(0x202013, 0, 0, 64 * 1024, 8, 0) }, > + { "m25p80", INFO(0x202014, 0, 0, 64 * 1024, 16, 0) }, > + { "m25p16", INFO(0x202015, 0, 0, 64 * 1024, 32, 0) }, > + { "m25p32", INFO(0x202016, 0, 0, 64 * 1024, 64, 0) }, > + { "m25p64", INFO(0x202017, 0, 0, 64 * 1024, 128, 0) }, > + { "m25p128", INFO(0x202018, 0, 0, 256 * 1024, 64, 0) }, > + > + { "m25p05-nonjedec", INFO_NOID( 32 * 1024, 2, 256, 0, 0) }, > + { "m25p10-nonjedec", INFO_NOID( 32 * 1024, 4, 256, 0, 0) }, > + { "m25p20-nonjedec", INFO_NOID( 64 * 1024, 4, 256, 0, 0) }, > + { "m25p40-nonjedec", INFO_NOID( 64 * 1024, 8, 256, 0, 0) }, > + { "m25p80-nonjedec", INFO_NOID( 64 * 1024, 16, 256, 0, 0) }, > + { "m25p16-nonjedec", INFO_NOID( 64 * 1024, 32, 256, 0, 0) }, > + { "m25p32-nonjedec", INFO_NOID( 64 * 1024, 64, 256, 0, 0) }, > + { "m25p64-nonjedec", INFO_NOID( 64 * 1024, 128, 256, 0, 0) }, > + { "m25p128-nonjedec", INFO_NOID(256 * 1024, 64, 256, 0, 0) }, > + > + { "m45pe10", INFO(0x204011, 0, 0, 64 * 1024, 2, 0) }, > + { "m45pe80", INFO(0x204014, 0, 0, 64 * 1024, 16, 0) }, > + { "m45pe16", INFO(0x204015, 0, 0, 64 * 1024, 32, 0) }, > + > + { "m25pe20", INFO(0x208012, 0, 0, 64 * 1024, 4, 0) }, > + { "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16, 0) }, > + { "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) }, > + > + { "m25px16", INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) }, > + { "m25px32", INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "m25px64", INFO(0x207117, 0, 0, 64 * 1024, 128, 0) }, > + { "m25px80", INFO(0x207114, 0, 0, 64 * 1024, 16, 0) }, > > /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ > - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, > - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, > - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, > - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, > - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, > - { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, > - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, > - { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, > + { "w25x05", INFO(0xef3010, 0, 0, 64 * 1024, 1, SECT_4K) }, > + { "w25x10", INFO(0xef3011, 0, 0, 64 * 1024, 2, SECT_4K) }, > + { "w25x20", INFO(0xef3012, 0, 0, 64 * 1024, 4, SECT_4K) }, > + { "w25x40", INFO(0xef3013, 0, 0, 64 * 1024, 8, SECT_4K) }, > + { "w25x80", INFO(0xef3014, 0, 0, 64 * 1024, 16, SECT_4K) }, > + { "w25x16", INFO(0xef3015, 0, 0, 64 * 1024, 32, SECT_4K) }, > + { "w25x32", INFO(0xef3016, 0, 0, 64 * 1024, 64, SECT_4K) }, > + { "w25q32", INFO(0xef4016, 0, 0, 64 * 1024, 64, SECT_4K) }, > { > - "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, > + "w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024, 64, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, > - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, > + { "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) }, > + { "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, > { > - "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, > + "w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > { > - "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, > + "w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256, > SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | > SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) > }, > - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, > - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, > - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, > - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, > + { "w25q80", INFO(0xef5014, 0, 0, 64 * 1024, 16, SECT_4K) }, > + { "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K) }, > + { "w25q128", INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) }, > + { "w25q256", INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) }, > > /* Catalyst / On Semiconductor -- non-JEDEC */ > - { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > - { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "cat25c11", INFO_NOID( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "cat25c03", INFO_NOID( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > + { "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, > > /* Xilinx S3AN Internal Flash */ > - { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, > - { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, > - { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, > - { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, > - { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, > + { "3S50AN", INFO_S3AN(0x1f2200, 64, 264) }, > + { "3S200AN", INFO_S3AN(0x1f2400, 256, 264) }, > + { "3S400AN", INFO_S3AN(0x1f2400, 256, 264) }, > + { "3S700AN", INFO_S3AN(0x1f2500, 512, 264) }, > + { "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) }, > { }, > }; > > static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) > { > int tmp; > - u8 id[SPI_NOR_MAX_ID_LEN]; > + u8 id_bytes[sizeof(u64)]; > + u64 id; > const struct flash_info *info; > > - tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); > + BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64)); > + > + memset(id_bytes, 0, sizeof(id_bytes)); > + tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN); > if (tmp < 0) { > dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); > return ERR_PTR(tmp); > } > > + id = get_unaligned_be64(id_bytes); > + > for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { > info = &spi_nor_ids[tmp]; > - if (info->id_len) { > - if (!memcmp(info->id, id, info->id_len)) > - return &spi_nor_ids[tmp]; > - } > + if (info->id_mask && (id & info->id_mask) == info->id) > + return info; > } > - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", > - id[0], id[1], id[2]); > + dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", > + SPI_NOR_MAX_ID_LEN, id_bytes); > return ERR_PTR(-ENODEV); > } > > @@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) > * If caller has specified name of flash model that can normally be > * detected using JEDEC, let's verify it. > */ > - if (name && info->id_len) { > + if (name && info->id_mask) { > const struct flash_info *jinfo; > > jinfo = spi_nor_read_id(nor); > -- Best regards, Marek Vasut ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID 2017-02-14 5:02 ` Marek Vasut @ 2017-02-14 10:22 ` Cyrille Pitchen 2017-02-14 15:35 ` [PATCH v2 0/3] " mark.marshall 0 siblings, 1 reply; 12+ messages in thread From: Cyrille Pitchen @ 2017-02-14 10:22 UTC (permalink / raw) To: Marek Vasut, mark.marshall, computersforpeace, linux-mtd Cc: markmarshall14, dwmw2, richard, boris.brezillon Hi all, Le 14/02/2017 à 06:02, Marek Vasut a écrit : > On 02/13/2017 02:53 PM, mark.marshall@omicronenergy.com wrote: >> From: Mark Marshall <mark.marshall@omicronenergy.com> >> >> The flash_info ID matching table is getting more complex as different >> chips are added. Some chips require different amounts of the response >> to the RDID command to be matched. Replace the current u8 array and >> length with a u64 id and a u64 id_mask. This allows us to simplify the >> macros used to generate the flash_info table without loosing the ability >> to generate "unusual" entries. >> >> -- >> >> This patch replaces "m25p80: Use a 512 byte page size for Spansion >> flash s25fl512s". It is based on for-linus-20170212, from the >> linux-mtd tree. >> This part should not appear in the commit message hence has to be moved after the "---" line (after your Signed-off-by tag). >> >> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> > > Minor nits below, looks good IMO. I'd still like someone else to review > this whole idea though. Cyrille ? > >> --- >> drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++--------------------- >> 1 file changed, 231 insertions(+), 227 deletions(-) >> >> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c >> index 1ae872b..c7ff237 100644 >> --- a/drivers/mtd/spi-nor/spi-nor.c >> +++ b/drivers/mtd/spi-nor/spi-nor.c >> @@ -41,15 +41,20 @@ >> #define SPI_NOR_MAX_ADDR_WIDTH 4 >> >> struct flash_info { >> - char *name; >> + const char *name; >> >> /* >> - * This array stores the ID bytes. >> - * The first three bytes are the JEDIC ID. >> - * JEDEC ID zero means "no ID" (mostly older chips). >> + * This u64 stores the ID bytes. >> + * The bytes are stored in big-endian order. I don't agree with this comment: looking at the code, id stores a number in the CPU order byte, not necessarily in big-endian. Below in the patch we can find: #define JEDEC_MFR(info) ((u8)((info)->id >> 56) & 0xff) So you use the CPU order byte. Also that's why you call get_unaligned_be64(): to convert the big-endian number read from the SPI bus into a cpu-ordered u64. Or maybe I didn't understand what you meant in your comment. >> + * The upper three bytes are the JEDIC ID, the lower bytes are >> + * the extension. >> */ >> - u8 id[SPI_NOR_MAX_ID_LEN]; >> - u8 id_len; >> + u64 id; >> + >> + /* >> + * An id_mask of zero means "no ID" (mostly older chips). >> + */ >> + u64 id_mask; >> >> /* The size listed here is what works with SPINOR_OP_SE, which isn't >> * necessarily called a "sector" by the vendor. >> @@ -87,7 +92,7 @@ struct flash_info { >> */ >> }; >> >> -#define JEDEC_MFR(info) ((info)->id[0]) >> +#define JEDEC_MFR(info) ((u8)((info)->id >> 56) & 0xff) >> >> static const struct flash_info *spi_nor_match_id(const char *name); >> >> @@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) >> return ret; >> } >> >> -/* Used when the "_ext_id" is two bytes at most */ >> -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ >> - .id = { \ >> - ((_jedec_id) >> 16) & 0xff, \ >> - ((_jedec_id) >> 8) & 0xff, \ >> - (_jedec_id) & 0xff, \ >> - ((_ext_id) >> 8) & 0xff, \ >> - (_ext_id) & 0xff, \ >> - }, \ >> - .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ >> - .sector_size = (_sector_size), \ >> - .n_sectors = (_n_sectors), \ >> - .page_size = 256, \ >> - .flags = (_flags), >> - >> -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ >> - .id = { \ >> - ((_jedec_id) >> 16) & 0xff, \ >> - ((_jedec_id) >> 8) & 0xff, \ >> - (_jedec_id) & 0xff, \ >> - ((_ext_id) >> 16) & 0xff, \ >> - ((_ext_id) >> 8) & 0xff, \ >> - (_ext_id) & 0xff, \ >> - }, \ >> - .id_len = 6, \ >> - .sector_size = (_sector_size), \ >> - .n_sectors = (_n_sectors), \ >> - .page_size = 256, \ >> - .flags = (_flags), >> - >> -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ >> - .sector_size = (_sector_size), \ >> - .n_sectors = (_n_sectors), \ >> - .page_size = (_page_size), \ >> - .addr_width = (_addr_width), \ >> - .flags = (_flags), >> - >> -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ >> - .id = { \ >> - ((_jedec_id) >> 16) & 0xff, \ >> - ((_jedec_id) >> 8) & 0xff, \ >> - (_jedec_id) & 0xff \ >> - }, \ >> - .id_len = 3, \ >> - .sector_size = (8*_page_size), \ >> - .n_sectors = (_n_sectors), \ >> - .page_size = _page_size, \ >> - .addr_width = 3, \ >> - .flags = SPI_NOR_NO_FR | SPI_S3AN, >> +/* Used to provide the full information about a device. >> + */ > > Fix the comment format here , single line comment is enough > ( /* comment */ ) > >> +#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ >> + .id = (_id), \ >> + .id_mask = (_id_mask), \ >> + .sector_size = (_sector_size), \ >> + .n_sectors = (_n_sectors), \ >> + .page_size = (_pg_sz), \ >> + .addr_width = (_addr_width), \ >> + .flags = (_flags), >> + >> +/* Used to provide information for a standard JEDEC device. All >> + * devices created with this macro have a three octet JEDEC identifier >> + * and an optional extension identifier (normally 0, 2 or 3 octets >> + * long). >> + */ > > Multi-line comment looks like this: > > /* > * foo > * bar > */ > >> +#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \ >> + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) | \ >> + ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))), \ Could it be possible, in the first time at least, to keep the very same prototype for the INFO() macro as before but still defining it using your new INFO_FULL() macro? #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) so as if _ext_len is always 3. For different _ext_len values, new entries can directly use your INFO_FULL() macro. Also keep CAT25_INFO() for now and simply make it an alias for INFO_NOID(). I would like this patch not to modify any entry of the spi_nor_ids[] array for now. So if some issue is reported, it would be more easy to revert and also it would avoid, or at least reduce, conflict with other patches adding support to new memories. > > Is the u64 cast needed ? I don't think so. > Indeed, I'm pretty sure the u64 is needed. For instance long time ago on x86_64 I wrote something like that (userspace code): uint64_t v; v = 1 << 32; but it didn't provide the right result. So yesterday I tried to have a look at why it failed and whether things like (info)->id >> 56 would work on all architectures. To be confirmed but I found out that for a (var1 << var2) operation, it seems that the result as the same type as var1. Hence is var1 is a signed integer like 1 and var2 is greater than 31 the actual result is unpredictable since the expected result can't be represented with a signed int. That why I should have written something like: uint64_t v; v = 1ull << 32; That why I think that the u64 cast is actually needed since the INFO() macro is used with values such as 0x1f6601, which is a signed int too. >> + GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))), \ > > You need parenthesis around _ext_len > >> + (_sector_size), \ >> + (_n_sectors), \ >> + 256, \ >> + 0, \ >> + (_flags)) >> + >> +#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ >> + INFO_FULL(0, \ >> + 0, \ >> + (_sector_size), \ >> + (_n_sectors), \ >> + (_page_size), \ >> + (_addr_width), \ >> + (_flags)) >> + >> +#define INFO_S3AN(_jedec_id, _n_sectors, _page_size) \ >> + INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))), \ >> + GENMASK_ULL(63, 64 - (8 * 3)), \ >> + (8*_page_size), \ >> + (_n_sectors), \ >> + (_page_size), \ >> + 3, \ >> + SPI_NOR_NO_FR | SPI_S3AN) >> >> /* NOTE: double check command sets and memory organization when you add >> * more nor chips. This current list focusses on newer chips, which >> @@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) >> */ >> static const struct flash_info spi_nor_ids[] = { >> /* Atmel -- some are (confusingly) marketed as "DataFlash" */ >> - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, >> - { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, >> + { "at25fs010", INFO(0x1f6601, 0, 0, 32 * 1024, 4, SECT_4K) }, >> + { "at25fs040", INFO(0x1f6604, 0, 0, 64 * 1024, 8, SECT_4K) }, >> >> - { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, >> - { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, >> - { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, >> - { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, >> + { "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024, 8, SECT_4K) }, >> + { "at25df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "at25df641", INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) }, >> >> - { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, >> - { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, >> - { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, >> - { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, >> + { "at26f004", INFO(0x1f0400, 0, 0, 64 * 1024, 8, SECT_4K) }, >> + { "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) }, >> + { "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) }, >> + { "at26df321", INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) }, >> >> - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, >> + { "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) }, >> >> /* EON -- en25xxx */ >> - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, >> - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, >> - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, >> - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, >> - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, >> - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, >> - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, >> - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, >> + { "en25f32", INFO(0x1c3116, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "en25p32", INFO(0x1c2016, 0, 0, 64 * 1024, 64, 0) }, >> + { "en25q32b", INFO(0x1c3016, 0, 0, 64 * 1024, 64, 0) }, >> + { "en25p64", INFO(0x1c2017, 0, 0, 64 * 1024, 128, 0) }, >> + { "en25q64", INFO(0x1c3017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "en25qh128", INFO(0x1c7018, 0, 0, 64 * 1024, 256, 0) }, >> + { "en25qh256", INFO(0x1c7019, 0, 0, 64 * 1024, 512, 0) }, >> + { "en25s64", INFO(0x1c3817, 0, 0, 64 * 1024, 128, SECT_4K) }, >> >> /* ESMT */ >> - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, >> + { "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, >> >> /* Everspin */ >> - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "mr25h10", INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "mr25h40", INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> >> /* Fujitsu */ >> - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, >> + { "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, >> >> /* GigaDevice */ >> { >> - "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, >> + "gd25q16", INFO(0xc84015, 0, 0, 64 * 1024, 32, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> { >> - "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, >> + "gd25q32", INFO(0xc84016, 0, 0, 64 * 1024, 64, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> { >> - "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, >> + "gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> { >> - "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, >> + "gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> { >> - "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, >> + "gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> >> /* Intel/Numonyx -- xxxs33b */ >> - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, >> - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, >> - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, >> + { "160s33b", INFO(0x898911, 0, 0, 64 * 1024, 32, 0) }, >> + { "320s33b", INFO(0x898912, 0, 0, 64 * 1024, 64, 0) }, >> + { "640s33b", INFO(0x898913, 0, 0, 64 * 1024, 128, 0) }, >> >> /* ISSI */ >> - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, >> + { "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024, 2, SECT_4K) }, >> >> /* Macronix */ >> - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, >> - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, >> - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, >> - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, >> - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, >> - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, >> - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, >> - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, >> - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, >> - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, >> - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, >> - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, >> - { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) }, >> - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, >> - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, >> - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, >> + { "mx25l512e", INFO(0xc22010, 0, 0, 64 * 1024, 1, SECT_4K) }, >> + { "mx25l2005a", INFO(0xc22012, 0, 0, 64 * 1024, 4, SECT_4K) }, >> + { "mx25l4005a", INFO(0xc22013, 0, 0, 64 * 1024, 8, SECT_4K) }, >> + { "mx25l8005", INFO(0xc22014, 0, 0, 64 * 1024, 16, 0) }, >> + { "mx25l1606e", INFO(0xc22015, 0, 0, 64 * 1024, 32, SECT_4K) }, >> + { "mx25l3205d", INFO(0xc22016, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "mx25l3255e", INFO(0xc29e16, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "mx25l6405d", INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "mx25u6435f", INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) }, >> + { "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) }, >> + { "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) }, >> + { "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) }, >> + { "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) }, >> + { "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, >> + { "mx66l1g55g", INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, >> >> /* Micron */ >> - { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, >> - { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, >> - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, >> - { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> - { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> - { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> - { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> + { "n25q016a", INFO(0x20bb15, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q032", INFO(0x20ba16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, >> + { "n25q032a", INFO(0x20bb16, 0, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, >> + { "n25q064", INFO(0x20ba17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q064a", INFO(0x20bb17, 0, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q128a11", INFO(0x20bb18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q128a13", INFO(0x20ba18, 0, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q256a", INFO(0x20ba19, 0, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, >> + { "n25q512a", INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> + { "n25q512ax3", INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> + { "n25q00", INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> + { "n25q00a", INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, >> >> /* PMC */ >> - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, >> - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, >> - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, >> + { "pm25lv512", INFO_NOID(32 * 1024, 2, 256, 0, SECT_4K_PMC) }, >> + { "pm25lv010", INFO_NOID(32 * 1024, 4, 256, 0, SECT_4K_PMC) }, >> + { "pm25lq032", INFO(0x7f9d46, 0, 0, 64 * 1024, 64, SECT_4K) }, >> >> /* Spansion -- single (large) sector size only, at least >> * for the chips listed here (without boot sectors). >> */ >> - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, >> - { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, >> - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, >> - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, >> - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, >> - { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, >> - { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, >> - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, >> - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, >> - { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, >> - { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> - { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, >> - { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, >> - { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, >> - { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, >> + { "s25sl032p", INFO(0x010215, 0x4d00, 2, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25sl064p", INFO(0x010216, 0x4d00, 2, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) }, >> + { "s25fl256s1", INFO(0x010219, 0x4d01, 2, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl512s", INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24), >> + 256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > > Hm, this syntax here could use some improvement ... ideas welcome. > >> + { "s70fl01gs", INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) }, >> + { "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024, 64, 0) }, >> + { "s25sl12801", INFO(0x012018, 0x0301, 2, 64 * 1024, 256, 0) }, >> + { "s25fl128s", INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl129p1", INFO(0x012018, 0x4d01, 2, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25sl004a", INFO(0x010212, 0, 0, 64 * 1024, 8, 0) }, >> + { "s25sl008a", INFO(0x010213, 0, 0, 64 * 1024, 16, 0) }, >> + { "s25sl016a", INFO(0x010214, 0, 0, 64 * 1024, 32, 0) }, >> + { "s25sl032a", INFO(0x010215, 0, 0, 64 * 1024, 64, 0) }, >> + { "s25sl064a", INFO(0x010216, 0, 0, 64 * 1024, 128, 0) }, >> + { "s25fl004k", INFO(0xef4013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl008k", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl016k", INFO(0xef4015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl064k", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "s25fl116k", INFO(0x014015, 0, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, >> + { "s25fl132k", INFO(0x014016, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "s25fl164k", INFO(0x014017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "s25fl204k", INFO(0x014013, 0, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, >> + { "s25fl208k", INFO(0x014014, 0, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, >> >> /* SST -- large erase sizes are "overlays", "sectors" are 4K */ >> - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, >> - { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, >> - { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, >> - { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, >> - { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, >> - { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, >> - { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, >> - { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, >> - { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, >> - { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, >> - { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, >> - { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, >> + { "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, >> + { "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, >> + { "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, >> + { "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, >> + { "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "sst25wf512", INFO(0xbf2501, 0, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, >> + { "sst25wf010", INFO(0xbf2502, 0, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, >> + { "sst25wf020", INFO(0xbf2503, 0, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, >> + { "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024, 4, SECT_4K) }, >> + { "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024, 8, SECT_4K) }, >> + { "sst25wf040", INFO(0xbf2504, 0, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, >> + { "sst25wf080", INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, >> >> /* ST Microelectronics -- newer production may have feature updates */ >> - { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, >> - { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, >> - { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, >> - { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, >> - { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, >> - { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, >> - { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, >> - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, >> - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, >> - >> - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, >> - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, >> - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, >> - { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, >> - { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, >> - { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, >> - { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, >> - { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, >> - { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, >> - >> - { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, >> - { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, >> - { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, >> - >> - { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, >> - { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, >> - { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, >> - >> - { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, >> - { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, >> - { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, >> - { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, >> - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, >> - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, >> + { "m25p05", INFO(0x202010, 0, 0, 32 * 1024, 2, 0) }, >> + { "m25p10", INFO(0x202011, 0, 0, 32 * 1024, 4, 0) }, >> + { "m25p20", INFO(0x202012, 0, 0, 64 * 1024, 4, 0) }, >> + { "m25p40", INFO(0x202013, 0, 0, 64 * 1024, 8, 0) }, >> + { "m25p80", INFO(0x202014, 0, 0, 64 * 1024, 16, 0) }, >> + { "m25p16", INFO(0x202015, 0, 0, 64 * 1024, 32, 0) }, >> + { "m25p32", INFO(0x202016, 0, 0, 64 * 1024, 64, 0) }, >> + { "m25p64", INFO(0x202017, 0, 0, 64 * 1024, 128, 0) }, >> + { "m25p128", INFO(0x202018, 0, 0, 256 * 1024, 64, 0) }, >> + >> + { "m25p05-nonjedec", INFO_NOID( 32 * 1024, 2, 256, 0, 0) }, >> + { "m25p10-nonjedec", INFO_NOID( 32 * 1024, 4, 256, 0, 0) }, >> + { "m25p20-nonjedec", INFO_NOID( 64 * 1024, 4, 256, 0, 0) }, >> + { "m25p40-nonjedec", INFO_NOID( 64 * 1024, 8, 256, 0, 0) }, >> + { "m25p80-nonjedec", INFO_NOID( 64 * 1024, 16, 256, 0, 0) }, >> + { "m25p16-nonjedec", INFO_NOID( 64 * 1024, 32, 256, 0, 0) }, >> + { "m25p32-nonjedec", INFO_NOID( 64 * 1024, 64, 256, 0, 0) }, >> + { "m25p64-nonjedec", INFO_NOID( 64 * 1024, 128, 256, 0, 0) }, >> + { "m25p128-nonjedec", INFO_NOID(256 * 1024, 64, 256, 0, 0) }, >> + >> + { "m45pe10", INFO(0x204011, 0, 0, 64 * 1024, 2, 0) }, >> + { "m45pe80", INFO(0x204014, 0, 0, 64 * 1024, 16, 0) }, >> + { "m45pe16", INFO(0x204015, 0, 0, 64 * 1024, 32, 0) }, >> + >> + { "m25pe20", INFO(0x208012, 0, 0, 64 * 1024, 4, 0) }, >> + { "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16, 0) }, >> + { "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) }, >> + >> + { "m25px16", INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) }, >> + { "m25px32", INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "m25px64", INFO(0x207117, 0, 0, 64 * 1024, 128, 0) }, >> + { "m25px80", INFO(0x207114, 0, 0, 64 * 1024, 16, 0) }, >> >> /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ >> - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, >> - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, >> - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, >> - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, >> - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, >> - { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, >> - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, >> - { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, >> + { "w25x05", INFO(0xef3010, 0, 0, 64 * 1024, 1, SECT_4K) }, >> + { "w25x10", INFO(0xef3011, 0, 0, 64 * 1024, 2, SECT_4K) }, >> + { "w25x20", INFO(0xef3012, 0, 0, 64 * 1024, 4, SECT_4K) }, >> + { "w25x40", INFO(0xef3013, 0, 0, 64 * 1024, 8, SECT_4K) }, >> + { "w25x80", INFO(0xef3014, 0, 0, 64 * 1024, 16, SECT_4K) }, >> + { "w25x16", INFO(0xef3015, 0, 0, 64 * 1024, 32, SECT_4K) }, >> + { "w25x32", INFO(0xef3016, 0, 0, 64 * 1024, 64, SECT_4K) }, >> + { "w25q32", INFO(0xef4016, 0, 0, 64 * 1024, 64, SECT_4K) }, >> { >> - "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, >> + "w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024, 64, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, >> - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, >> + { "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> + { "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) }, >> { >> - "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, >> + "w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> { >> - "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, >> + "w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256, >> SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | >> SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) >> }, >> - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, >> - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, >> - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, >> - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, >> + { "w25q80", INFO(0xef5014, 0, 0, 64 * 1024, 16, SECT_4K) }, >> + { "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024, 16, SECT_4K) }, >> + { "w25q128", INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) }, >> + { "w25q256", INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) }, >> >> /* Catalyst / On Semiconductor -- non-JEDEC */ >> - { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> - { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "cat25c11", INFO_NOID( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "cat25c03", INFO_NOID( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> + { "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, >> >> /* Xilinx S3AN Internal Flash */ >> - { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, >> - { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, >> - { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, >> - { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, >> - { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, >> + { "3S50AN", INFO_S3AN(0x1f2200, 64, 264) }, >> + { "3S200AN", INFO_S3AN(0x1f2400, 256, 264) }, >> + { "3S400AN", INFO_S3AN(0x1f2400, 256, 264) }, >> + { "3S700AN", INFO_S3AN(0x1f2500, 512, 264) }, >> + { "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) }, >> { }, >> }; >> >> static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) >> { >> int tmp; >> - u8 id[SPI_NOR_MAX_ID_LEN]; >> + u8 id_bytes[sizeof(u64)]; >> + u64 id; >> const struct flash_info *info; >> >> - tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); >> + BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64)); >> + >> + memset(id_bytes, 0, sizeof(id_bytes)); >> + tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN); >> if (tmp < 0) { >> dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); >> return ERR_PTR(tmp); >> } >> >> + id = get_unaligned_be64(id_bytes); >> + >> for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { >> info = &spi_nor_ids[tmp]; >> - if (info->id_len) { >> - if (!memcmp(info->id, id, info->id_len)) >> - return &spi_nor_ids[tmp]; >> - } >> + if (info->id_mask && (id & info->id_mask) == info->id) >> + return info; >> } >> - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", >> - id[0], id[1], id[2]); >> + dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", >> + SPI_NOR_MAX_ID_LEN, id_bytes); >> return ERR_PTR(-ENODEV); >> } >> >> @@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) >> * If caller has specified name of flash model that can normally be >> * detected using JEDEC, let's verify it. >> */ >> - if (name && info->id_len) { >> + if (name && info->id_mask) { >> const struct flash_info *jinfo; >> >> jinfo = spi_nor_read_id(nor); >> > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 0/3] mtd: spi-nor: flash_info table, use a u64 for the ID 2017-02-14 10:22 ` Cyrille Pitchen @ 2017-02-14 15:35 ` mark.marshall 2017-02-14 15:35 ` [PATCH v2 1/3] " mark.marshall ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw) To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> This is a minor re-write of my previous patch to change the flash_info table to contain a u64 for the RDID bytes. It's now split into three patches, the first changes the flash_info structure and massages the currently named macros to generate the new table. The second replaces the macros in the table with slightly more explicit ones, and the third patch makes the actual change to the table that I wanted. I now use macro called JEDEC_ID(_jedec_id, _ext_id, _ext_len) to generate the IDs. This could be different, of course. Mark Marshall (3): mtd: spi-nor: flash_info table, use a u64 for the ID mtd: spi-nor: Use more explicit macros to generate the flash_info table mtd: spi-nor: s25fl512s: Set a page size of 512 drivers/mtd/spi-nor/spi-nor.c | 467 ++++++++++++++++++++++-------------------- 1 file changed, 240 insertions(+), 227 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] mtd: spi-nor: flash_info table, use a u64 for the ID 2017-02-14 15:35 ` [PATCH v2 0/3] " mark.marshall @ 2017-02-14 15:35 ` mark.marshall 2017-02-14 15:35 ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall 2017-02-14 15:35 ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall 2 siblings, 0 replies; 12+ messages in thread From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw) To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> The flash_info ID matching table is getting more complex as different chips are added. Some chips require different amounts of the response to the RDID command to be matched. Replace the current u8 array and length with a u64 id and a u64 id_mask. This allows us to simplify the macros used to generate the flash_info table without loosing the ability to generate "unusual" entries. Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> --- drivers/mtd/spi-nor/spi-nor.c | 119 ++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 57 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 1ae872b..ab3f380 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -41,15 +41,22 @@ #define SPI_NOR_MAX_ADDR_WIDTH 4 struct flash_info { - char *name; + const char *name; /* - * This array stores the ID bytes. - * The first three bytes are the JEDIC ID. - * JEDEC ID zero means "no ID" (mostly older chips). + * This u64 stores the ID bytes. + * The bytes are stored in big-endian order (that is, the + * first byte of the RDID result is the MSB of the value. The + * u64 is stored in host endian). + * The upper three bytes are the JEDEC ID, the lower bytes are + * the extension. */ - u8 id[SPI_NOR_MAX_ID_LEN]; - u8 id_len; + u64 id; + + /* + * An id_mask of zero means "no ID" (mostly older chips). + */ + u64 id_mask; /* The size listed here is what works with SPINOR_OP_SE, which isn't * necessarily called a "sector" by the vendor. @@ -87,7 +94,7 @@ struct flash_info { */ }; -#define JEDEC_MFR(info) ((info)->id[0]) +#define JEDEC_MFR(info) ((u8)((info)->id >> 56) & 0xff) static const struct flash_info *spi_nor_match_id(const char *name); @@ -870,55 +877,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) return ret; } +#define INFO_RAW(_id, _id_mask, _sector_size, _n_sectors, _page_size, _addr_width, _flags) \ + .id = (_id), \ + .id_mask = (_id_mask), \ + .sector_size = (_sector_size), \ + .n_sectors = (_n_sectors), \ + .page_size = (_page_size), \ + .addr_width = (_addr_width), \ + .flags = (_flags), + /* Used when the "_ext_id" is two bytes at most */ #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), + INFO_RAW(!(_jedec_id) ? 0 : \ + (((u64)(_jedec_id) << (64 - (8 * 3))) | \ + ((u64)(_ext_id) << (64 - (40)))), \ + !(_jedec_id) ? 0 : \ + GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 2 : 0)))), \ + (_sector_size), \ + (_n_sectors), \ + 256, \ + 0, \ + (_flags)) #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff, \ - ((_ext_id) >> 16) & 0xff, \ - ((_ext_id) >> 8) & 0xff, \ - (_ext_id) & 0xff, \ - }, \ - .id_len = 6, \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = 256, \ - .flags = (_flags), + INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3))) | \ + ((u64)(_ext_id) << (64 - (48)))), \ + GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 3 : 0)))), \ + (_sector_size), \ + (_n_sectors), \ + 256, \ + 0, \ + (_flags)) #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ - .sector_size = (_sector_size), \ - .n_sectors = (_n_sectors), \ - .page_size = (_page_size), \ - .addr_width = (_addr_width), \ - .flags = (_flags), + INFO_RAW(0, 0, (_sector_size), (_n_sectors), (_page_size), (_addr_width), (_flags)) #define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ - .id = { \ - ((_jedec_id) >> 16) & 0xff, \ - ((_jedec_id) >> 8) & 0xff, \ - (_jedec_id) & 0xff \ - }, \ - .id_len = 3, \ - .sector_size = (8*_page_size), \ - .n_sectors = (_n_sectors), \ - .page_size = _page_size, \ - .addr_width = 3, \ - .flags = SPI_NOR_NO_FR | SPI_S3AN, + INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3)))), \ + GENMASK_ULL(63, 64 - (8 * (3))), \ + 8 * (_page_size), \ + (_n_sectors), \ + (_page_size), \ + 3, \ + SPI_NOR_NO_FR | SPI_S3AN) /* NOTE: double check command sets and memory organization when you add * more nor chips. This current list focusses on newer chips, which @@ -1170,24 +1171,28 @@ static const struct flash_info spi_nor_ids[] = { static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) { int tmp; - u8 id[SPI_NOR_MAX_ID_LEN]; + u8 id_bytes[sizeof(u64)]; + u64 id; const struct flash_info *info; - tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); + BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64)); + + memset(id_bytes, 0, sizeof(id_bytes)); + tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN); if (tmp < 0) { dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); return ERR_PTR(tmp); } + id = get_unaligned_be64(id_bytes); + for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) { info = &spi_nor_ids[tmp]; - if (info->id_len) { - if (!memcmp(info->id, id, info->id_len)) - return &spi_nor_ids[tmp]; - } + if (info->id_mask && (id & info->id_mask) == info->id) + return info; } - dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", - id[0], id[1], id[2]); + dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", + SPI_NOR_MAX_ID_LEN, id_bytes); return ERR_PTR(-ENODEV); } @@ -1551,7 +1556,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) * If caller has specified name of flash model that can normally be * detected using JEDEC, let's verify it. */ - if (name && info->id_len) { + if (name && info->id_mask) { const struct flash_info *jinfo; jinfo = spi_nor_read_id(nor); -- 2.7.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table 2017-02-14 15:35 ` [PATCH v2 0/3] " mark.marshall 2017-02-14 15:35 ` [PATCH v2 1/3] " mark.marshall @ 2017-02-14 15:35 ` mark.marshall 2017-02-14 15:35 ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall 2 siblings, 0 replies; 12+ messages in thread From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw) To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> Now that we are storing the RDID id as a u64 we can try to reduce the number of special INFO macros that we need, but also add the possibility of setting all of the fields of the structure, if we need to. Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> --- drivers/mtd/spi-nor/spi-nor.c | 374 +++++++++++++++++++++--------------------- 1 file changed, 190 insertions(+), 184 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index ab3f380..467dc93 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -886,36 +886,42 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) .addr_width = (_addr_width), \ .flags = (_flags), -/* Used when the "_ext_id" is two bytes at most */ -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - INFO_RAW(!(_jedec_id) ? 0 : \ - (((u64)(_jedec_id) << (64 - (8 * 3))) | \ - ((u64)(_ext_id) << (64 - (40)))), \ - !(_jedec_id) ? 0 : \ - GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 2 : 0)))), \ - (_sector_size), \ - (_n_sectors), \ - 256, \ - 0, \ - (_flags)) +/* + * This is used to produce the "id" and "id_mask" fields. The + * _jedec_id is expected to be a 24 bit number containing the first + * three octets of the RDID response, in "big endian" order (that is, + * the first octet of the RDID response is in the MS position). + * + * If more of the RDID response should be checked than these octets + * should be in _ext_id, and should be _ext_len octets long, again, in + * "big endian" order. + * + * NB. This macro expands into something like "X, Z", which is + * expected to become the first two parameters to INFO_RAW. + */ +#define JEDEC_ID(_jedec_id, _ext_id, _ext_len) \ + (((u64)(_jedec_id) << (64 - (8 * 3))) | \ + ((u64)(_ext_id) << (64 - (8 * (3 + (_ext_len)))))), \ + GENMASK_ULL(63, 64 - (8 * (3 + (_ext_len)))) + +#define NONE_ID() 0, 0 -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ - INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3))) | \ - ((u64)(_ext_id) << (64 - (48)))), \ - GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 3 : 0)))), \ +/* Used to provide information for a standard JEDEC device. */ +#define INFO(_ID, _sector_size, _n_sectors, _flags) \ + INFO_RAW(_ID, \ (_sector_size), \ (_n_sectors), \ 256, \ 0, \ (_flags)) -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags) \ - INFO_RAW(0, 0, (_sector_size), (_n_sectors), (_page_size), (_addr_width), (_flags)) +/* Used to provide the full information about a device. */ +#define INFO_FULL(_ID, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \ + INFO_RAW(_ID, (_sector_size), (_n_sectors), (_pg_sz), (_addr_width), (_flags)) -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size) \ - INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3)))), \ - GENMASK_ULL(63, 64 - (8 * (3))), \ - 8 * (_page_size), \ +#define INFO_S3AN(_ID, _n_sectors, _page_size) \ + INFO_RAW(_ID, \ + 8*(_page_size), \ (_n_sectors), \ (_page_size), \ 3, \ @@ -934,237 +940,237 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) */ static const struct flash_info spi_nor_ids[] = { /* Atmel -- some are (confusingly) marketed as "DataFlash" */ - { "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4, SECT_4K) }, - { "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8, SECT_4K) }, + { "at25fs010", INFO(JEDEC_ID(0x1f6601, 0, 0), 32 * 1024, 4, SECT_4K) }, + { "at25fs040", INFO(JEDEC_ID(0x1f6604, 0, 0), 64 * 1024, 8, SECT_4K) }, - { "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8, SECT_4K) }, - { "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64, SECT_4K) }, - { "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) }, + { "at25df041a", INFO(JEDEC_ID(0x1f4401, 0, 0), 64 * 1024, 8, SECT_4K) }, + { "at25df321", INFO(JEDEC_ID(0x1f4700, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "at25df321a", INFO(JEDEC_ID(0x1f4701, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "at25df641", INFO(JEDEC_ID(0x1f4800, 0, 0), 64 * 1024, 128, SECT_4K) }, - { "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8, SECT_4K) }, - { "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) }, - { "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) }, - { "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) }, + { "at26f004", INFO(JEDEC_ID(0x1f0400, 0, 0), 64 * 1024, 8, SECT_4K) }, + { "at26df081a", INFO(JEDEC_ID(0x1f4501, 0, 0), 64 * 1024, 16, SECT_4K) }, + { "at26df161a", INFO(JEDEC_ID(0x1f4601, 0, 0), 64 * 1024, 32, SECT_4K) }, + { "at26df321", INFO(JEDEC_ID(0x1f4700, 0, 0), 64 * 1024, 64, SECT_4K) }, - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, + { "at45db081d", INFO(JEDEC_ID(0x1f2500, 0, 0), 64 * 1024, 16, SECT_4K) }, /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, - { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, - { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, + { "en25f32", INFO(JEDEC_ID(0x1c3116, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "en25p32", INFO(JEDEC_ID(0x1c2016, 0, 0), 64 * 1024, 64, 0) }, + { "en25q32b", INFO(JEDEC_ID(0x1c3016, 0, 0), 64 * 1024, 64, 0) }, + { "en25p64", INFO(JEDEC_ID(0x1c2017, 0, 0), 64 * 1024, 128, 0) }, + { "en25q64", INFO(JEDEC_ID(0x1c3017, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "en25qh128", INFO(JEDEC_ID(0x1c7018, 0, 0), 64 * 1024, 256, 0) }, + { "en25qh256", INFO(JEDEC_ID(0x1c7019, 0, 0), 64 * 1024, 512, 0) }, + { "en25s64", INFO(JEDEC_ID(0x1c3817, 0, 0), 64 * 1024, 128, SECT_4K) }, /* ESMT */ - { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, + { "f25l32pa", INFO(JEDEC_ID(0x8c2016, 0, 0), 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) }, /* Everspin */ - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h256", INFO_FULL(NONE_ID(), 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h10", INFO_FULL(NONE_ID(), 128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h40", INFO_FULL(NONE_ID(), 512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, /* Fujitsu */ - { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, + { "mb85rs1mt", INFO(JEDEC_ID(0x047f27, 0, 0), 128 * 1024, 1, SPI_NOR_NO_ERASE) }, /* GigaDevice */ { - "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, + "gd25q16", INFO(JEDEC_ID(0xc84015, 0, 0), 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, + "gd25q32", INFO(JEDEC_ID(0xc84016, 0, 0), 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, + "gd25q64", INFO(JEDEC_ID(0xc84017, 0, 0), 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128, + "gd25lq64c", INFO(JEDEC_ID(0xc86017, 0, 0), 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "gd25q128", INFO(0xc84018, 0, 64 * 1024, 256, + "gd25q128", INFO(JEDEC_ID(0xc84018, 0, 0), 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, /* Intel/Numonyx -- xxxs33b */ - { "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) }, - { "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) }, - { "640s33b", INFO(0x898913, 0, 64 * 1024, 128, 0) }, + { "160s33b", INFO(JEDEC_ID(0x898911, 0, 0), 64 * 1024, 32, 0) }, + { "320s33b", INFO(JEDEC_ID(0x898912, 0, 0), 64 * 1024, 64, 0) }, + { "640s33b", INFO(JEDEC_ID(0x898913, 0, 0), 64 * 1024, 128, 0) }, /* ISSI */ - { "is25cd512", INFO(0x7f9d20, 0, 32 * 1024, 2, SECT_4K) }, + { "is25cd512", INFO(JEDEC_ID(0x7f9d20, 0, 0), 32 * 1024, 2, SECT_4K) }, /* Macronix */ - { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, - { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, - { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, - { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, - { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, - { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, - { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, - { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, - { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, - { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, - { "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) }, - { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, - { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, - { "mx66l1g55g", INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, + { "mx25l512e", INFO(JEDEC_ID(0xc22010, 0, 0), 64 * 1024, 1, SECT_4K) }, + { "mx25l2005a", INFO(JEDEC_ID(0xc22012, 0, 0), 64 * 1024, 4, SECT_4K) }, + { "mx25l4005a", INFO(JEDEC_ID(0xc22013, 0, 0), 64 * 1024, 8, SECT_4K) }, + { "mx25l8005", INFO(JEDEC_ID(0xc22014, 0, 0), 64 * 1024, 16, 0) }, + { "mx25l1606e", INFO(JEDEC_ID(0xc22015, 0, 0), 64 * 1024, 32, SECT_4K) }, + { "mx25l3205d", INFO(JEDEC_ID(0xc22016, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "mx25l3255e", INFO(JEDEC_ID(0xc29e16, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "mx25l6405d", INFO(JEDEC_ID(0xc22017, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "mx25u6435f", INFO(JEDEC_ID(0xc22537, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "mx25l12805d", INFO(JEDEC_ID(0xc22018, 0, 0), 64 * 1024, 256, 0) }, + { "mx25l12855e", INFO(JEDEC_ID(0xc22618, 0, 0), 64 * 1024, 256, 0) }, + { "mx25l25635e", INFO(JEDEC_ID(0xc22019, 0, 0), 64 * 1024, 512, 0) }, + { "mx25u25635f", INFO(JEDEC_ID(0xc22539, 0, 0), 64 * 1024, 512, SECT_4K) }, + { "mx25l25655e", INFO(JEDEC_ID(0xc22619, 0, 0), 64 * 1024, 512, 0) }, + { "mx66l51235l", INFO(JEDEC_ID(0xc2201a, 0, 0), 64 * 1024, 1024, SPI_NOR_QUAD_READ) }, + { "mx66l1g55g", INFO(JEDEC_ID(0xc2261b, 0, 0), 64 * 1024, 2048, SPI_NOR_QUAD_READ) }, /* Micron */ - { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q032a", INFO(0x20bb16, 0, 64 * 1024, 64, SPI_NOR_QUAD_READ) }, - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q064a", INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, - { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, - { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q016a", INFO(JEDEC_ID(0x20bb15, 0, 0), 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q032", INFO(JEDEC_ID(0x20ba16, 0, 0), 64 * 1024, 64, SPI_NOR_QUAD_READ) }, + { "n25q032a", INFO(JEDEC_ID(0x20bb16, 0, 0), 64 * 1024, 64, SPI_NOR_QUAD_READ) }, + { "n25q064", INFO(JEDEC_ID(0x20ba17, 0, 0), 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q064a", INFO(JEDEC_ID(0x20bb17, 0, 0), 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q128a11", INFO(JEDEC_ID(0x20bb18, 0, 0), 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q128a13", INFO(JEDEC_ID(0x20ba18, 0, 0), 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q256a", INFO(JEDEC_ID(0x20ba19, 0, 0), 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ) }, + { "n25q512a", INFO(JEDEC_ID(0x20bb20, 0, 0), 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q512ax3", INFO(JEDEC_ID(0x20ba20, 0, 0), 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q00", INFO(JEDEC_ID(0x20ba21, 0, 0), 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + { "n25q00a", INFO(JEDEC_ID(0x20bb21, 0, 0), 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, /* PMC */ - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, + { "pm25lv512", INFO_FULL(NONE_ID(), 32 * 1024, 2, 256, 0, SECT_4K_PMC) }, + { "pm25lv010", INFO_FULL(NONE_ID(), 32 * 1024, 4, 256, 0, SECT_4K_PMC) }, + { "pm25lq032", INFO(JEDEC_ID(0x7f9d46, 0, 0), 64 * 1024, 64, SECT_4K) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ - { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, - { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, - { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, - { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, - { "s25fl128s", INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8, 0) }, - { "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16, 0) }, - { "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32, 0) }, - { "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64, 0) }, - { "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128, 0) }, - { "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64, SECT_4K) }, - { "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128, SECT_4K) }, - { "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, - { "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, + { "s25sl032p", INFO(JEDEC_ID(0x010215, 0x4d00, 2), 64 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25sl064p", INFO(JEDEC_ID(0x010216, 0x4d00, 2), 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) }, + { "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2), 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl512s", INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s70fl01gs", INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) }, + { "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024, 64, 0) }, + { "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2), 64 * 1024, 256, 0) }, + { "s25fl128s", INFO(JEDEC_ID(0x012018, 0x4d0180, 3), 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl129p0", INFO(JEDEC_ID(0x012018, 0x4d00, 2), 256 * 1024, 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl129p1", INFO(JEDEC_ID(0x012018, 0x4d01, 2), 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25sl004a", INFO(JEDEC_ID(0x010212, 0, 0), 64 * 1024, 8, 0) }, + { "s25sl008a", INFO(JEDEC_ID(0x010213, 0, 0), 64 * 1024, 16, 0) }, + { "s25sl016a", INFO(JEDEC_ID(0x010214, 0, 0), 64 * 1024, 32, 0) }, + { "s25sl032a", INFO(JEDEC_ID(0x010215, 0, 0), 64 * 1024, 64, 0) }, + { "s25sl064a", INFO(JEDEC_ID(0x010216, 0, 0), 64 * 1024, 128, 0) }, + { "s25fl004k", INFO(JEDEC_ID(0xef4013, 0, 0), 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl008k", INFO(JEDEC_ID(0xef4014, 0, 0), 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl016k", INFO(JEDEC_ID(0xef4015, 0, 0), 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl064k", INFO(JEDEC_ID(0xef4017, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "s25fl116k", INFO(JEDEC_ID(0x014015, 0, 0), 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl132k", INFO(JEDEC_ID(0x014016, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "s25fl164k", INFO(JEDEC_ID(0x014017, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "s25fl204k", INFO(JEDEC_ID(0x014013, 0, 0), 64 * 1024, 8, SECT_4K | SPI_NOR_DUAL_READ) }, + { "s25fl208k", INFO(JEDEC_ID(0x014014, 0, 0), 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ) }, /* SST -- large erase sizes are "overlays", "sectors" are 4K */ - { "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, - { "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) }, - { "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) }, - { "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) }, - { "sst25wf512", INFO(0xbf2501, 0, 64 * 1024, 1, SECT_4K | SST_WRITE) }, - { "sst25wf010", INFO(0xbf2502, 0, 64 * 1024, 2, SECT_4K | SST_WRITE) }, - { "sst25wf020", INFO(0xbf2503, 0, 64 * 1024, 4, SECT_4K | SST_WRITE) }, - { "sst25wf020a", INFO(0x621612, 0, 64 * 1024, 4, SECT_4K) }, - { "sst25wf040b", INFO(0x621613, 0, 64 * 1024, 8, SECT_4K) }, - { "sst25wf040", INFO(0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) }, - { "sst25wf080", INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { "sst25vf040b", INFO(JEDEC_ID(0xbf258d, 0, 0), 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25vf080b", INFO(JEDEC_ID(0xbf258e, 0, 0), 64 * 1024, 16, SECT_4K | SST_WRITE) }, + { "sst25vf016b", INFO(JEDEC_ID(0xbf2541, 0, 0), 64 * 1024, 32, SECT_4K | SST_WRITE) }, + { "sst25vf032b", INFO(JEDEC_ID(0xbf254a, 0, 0), 64 * 1024, 64, SECT_4K | SST_WRITE) }, + { "sst25vf064c", INFO(JEDEC_ID(0xbf254b, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "sst25wf512", INFO(JEDEC_ID(0xbf2501, 0, 0), 64 * 1024, 1, SECT_4K | SST_WRITE) }, + { "sst25wf010", INFO(JEDEC_ID(0xbf2502, 0, 0), 64 * 1024, 2, SECT_4K | SST_WRITE) }, + { "sst25wf020", INFO(JEDEC_ID(0xbf2503, 0, 0), 64 * 1024, 4, SECT_4K | SST_WRITE) }, + { "sst25wf020a", INFO(JEDEC_ID(0x621612, 0, 0), 64 * 1024, 4, SECT_4K) }, + { "sst25wf040b", INFO(JEDEC_ID(0x621613, 0, 0), 64 * 1024, 8, SECT_4K) }, + { "sst25wf040", INFO(JEDEC_ID(0xbf2504, 0, 0), 64 * 1024, 8, SECT_4K | SST_WRITE) }, + { "sst25wf080", INFO(JEDEC_ID(0xbf2505, 0, 0), 64 * 1024, 16, SECT_4K | SST_WRITE) }, /* ST Microelectronics -- newer production may have feature updates */ - { "m25p05", INFO(0x202010, 0, 32 * 1024, 2, 0) }, - { "m25p10", INFO(0x202011, 0, 32 * 1024, 4, 0) }, - { "m25p20", INFO(0x202012, 0, 64 * 1024, 4, 0) }, - { "m25p40", INFO(0x202013, 0, 64 * 1024, 8, 0) }, - { "m25p80", INFO(0x202014, 0, 64 * 1024, 16, 0) }, - { "m25p16", INFO(0x202015, 0, 64 * 1024, 32, 0) }, - { "m25p32", INFO(0x202016, 0, 64 * 1024, 64, 0) }, - { "m25p64", INFO(0x202017, 0, 64 * 1024, 128, 0) }, - { "m25p128", INFO(0x202018, 0, 256 * 1024, 64, 0) }, - - { "m25p05-nonjedec", INFO(0, 0, 32 * 1024, 2, 0) }, - { "m25p10-nonjedec", INFO(0, 0, 32 * 1024, 4, 0) }, - { "m25p20-nonjedec", INFO(0, 0, 64 * 1024, 4, 0) }, - { "m25p40-nonjedec", INFO(0, 0, 64 * 1024, 8, 0) }, - { "m25p80-nonjedec", INFO(0, 0, 64 * 1024, 16, 0) }, - { "m25p16-nonjedec", INFO(0, 0, 64 * 1024, 32, 0) }, - { "m25p32-nonjedec", INFO(0, 0, 64 * 1024, 64, 0) }, - { "m25p64-nonjedec", INFO(0, 0, 64 * 1024, 128, 0) }, - { "m25p128-nonjedec", INFO(0, 0, 256 * 1024, 64, 0) }, - - { "m45pe10", INFO(0x204011, 0, 64 * 1024, 2, 0) }, - { "m45pe80", INFO(0x204014, 0, 64 * 1024, 16, 0) }, - { "m45pe16", INFO(0x204015, 0, 64 * 1024, 32, 0) }, - - { "m25pe20", INFO(0x208012, 0, 64 * 1024, 4, 0) }, - { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, - { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, - - { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, - { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, - { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, - { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, + { "m25p05", INFO(JEDEC_ID(0x202010, 0, 0), 32 * 1024, 2, 0) }, + { "m25p10", INFO(JEDEC_ID(0x202011, 0, 0), 32 * 1024, 4, 0) }, + { "m25p20", INFO(JEDEC_ID(0x202012, 0, 0), 64 * 1024, 4, 0) }, + { "m25p40", INFO(JEDEC_ID(0x202013, 0, 0), 64 * 1024, 8, 0) }, + { "m25p80", INFO(JEDEC_ID(0x202014, 0, 0), 64 * 1024, 16, 0) }, + { "m25p16", INFO(JEDEC_ID(0x202015, 0, 0), 64 * 1024, 32, 0) }, + { "m25p32", INFO(JEDEC_ID(0x202016, 0, 0), 64 * 1024, 64, 0) }, + { "m25p64", INFO(JEDEC_ID(0x202017, 0, 0), 64 * 1024, 128, 0) }, + { "m25p128", INFO(JEDEC_ID(0x202018, 0, 0), 256 * 1024, 64, 0) }, + + { "m25p05-nonjedec", INFO_FULL(NONE_ID(), 32 * 1024, 2, 256, 0, 0) }, + { "m25p10-nonjedec", INFO_FULL(NONE_ID(), 32 * 1024, 4, 256, 0, 0) }, + { "m25p20-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 4, 256, 0, 0) }, + { "m25p40-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 8, 256, 0, 0) }, + { "m25p80-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 16, 256, 0, 0) }, + { "m25p16-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 32, 256, 0, 0) }, + { "m25p32-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 64, 256, 0, 0) }, + { "m25p64-nonjedec", INFO_FULL(NONE_ID(), 64 * 1024, 128, 256, 0, 0) }, + { "m25p128-nonjedec", INFO_FULL(NONE_ID(), 256 * 1024, 64, 256, 0, 0) }, + + { "m45pe10", INFO(JEDEC_ID(0x204011, 0, 0), 64 * 1024, 2, 0) }, + { "m45pe80", INFO(JEDEC_ID(0x204014, 0, 0), 64 * 1024, 16, 0) }, + { "m45pe16", INFO(JEDEC_ID(0x204015, 0, 0), 64 * 1024, 32, 0) }, + + { "m25pe20", INFO(JEDEC_ID(0x208012, 0, 0), 64 * 1024, 4, 0) }, + { "m25pe80", INFO(JEDEC_ID(0x208014, 0, 0), 64 * 1024, 16, 0) }, + { "m25pe16", INFO(JEDEC_ID(0x208015, 0, 0), 64 * 1024, 32, SECT_4K) }, + + { "m25px16", INFO(JEDEC_ID(0x207115, 0, 0), 64 * 1024, 32, SECT_4K) }, + { "m25px32", INFO(JEDEC_ID(0x207116, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "m25px32-s0", INFO(JEDEC_ID(0x207316, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "m25px32-s1", INFO(JEDEC_ID(0x206316, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "m25px64", INFO(JEDEC_ID(0x207117, 0, 0), 64 * 1024, 128, 0) }, + { "m25px80", INFO(JEDEC_ID(0x207114, 0, 0), 64 * 1024, 16, 0) }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ - { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, - { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, - { "w25x20", INFO(0xef3012, 0, 64 * 1024, 4, SECT_4K) }, - { "w25x40", INFO(0xef3013, 0, 64 * 1024, 8, SECT_4K) }, - { "w25x80", INFO(0xef3014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25x16", INFO(0xef3015, 0, 64 * 1024, 32, SECT_4K) }, - { "w25x32", INFO(0xef3016, 0, 64 * 1024, 64, SECT_4K) }, - { "w25q32", INFO(0xef4016, 0, 64 * 1024, 64, SECT_4K) }, + { "w25x05", INFO(JEDEC_ID(0xef3010, 0, 0), 64 * 1024, 1, SECT_4K) }, + { "w25x10", INFO(JEDEC_ID(0xef3011, 0, 0), 64 * 1024, 2, SECT_4K) }, + { "w25x20", INFO(JEDEC_ID(0xef3012, 0, 0), 64 * 1024, 4, SECT_4K) }, + { "w25x40", INFO(JEDEC_ID(0xef3013, 0, 0), 64 * 1024, 8, SECT_4K) }, + { "w25x80", INFO(JEDEC_ID(0xef3014, 0, 0), 64 * 1024, 16, SECT_4K) }, + { "w25x16", INFO(JEDEC_ID(0xef3015, 0, 0), 64 * 1024, 32, SECT_4K) }, + { "w25x32", INFO(JEDEC_ID(0xef3016, 0, 0), 64 * 1024, 64, SECT_4K) }, + { "w25q32", INFO(JEDEC_ID(0xef4016, 0, 0), 64 * 1024, 64, SECT_4K) }, { - "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, + "w25q32dw", INFO(JEDEC_ID(0xef6016, 0, 0), 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, + { "w25x64", INFO(JEDEC_ID(0xef3017, 0, 0), 64 * 1024, 128, SECT_4K) }, + { "w25q64", INFO(JEDEC_ID(0xef4017, 0, 0), 64 * 1024, 128, SECT_4K) }, { - "w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128, + "w25q64dw", INFO(JEDEC_ID(0xef6017, 0, 0), 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { - "w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256, + "w25q128fw", INFO(JEDEC_ID(0xef6018, 0, 0), 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, - { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, + { "w25q80", INFO(JEDEC_ID(0xef5014, 0, 0), 64 * 1024, 16, SECT_4K) }, + { "w25q80bl", INFO(JEDEC_ID(0xef4014, 0, 0), 64 * 1024, 16, SECT_4K) }, + { "w25q128", INFO(JEDEC_ID(0xef4018, 0, 0), 64 * 1024, 256, SECT_4K) }, + { "w25q256", INFO(JEDEC_ID(0xef4019, 0, 0), 64 * 1024, 512, SECT_4K) }, /* Catalyst / On Semiconductor -- non-JEDEC */ - { "cat25c11", CAT25_INFO( 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c03", CAT25_INFO( 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, - { "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c11", INFO_FULL(NONE_ID(), 16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c03", INFO_FULL(NONE_ID(), 32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c09", INFO_FULL(NONE_ID(), 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25c17", INFO_FULL(NONE_ID(), 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "cat25128", INFO_FULL(NONE_ID(), 2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, /* Xilinx S3AN Internal Flash */ - { "3S50AN", S3AN_INFO(0x1f2200, 64, 264) }, - { "3S200AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, - { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, - { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, + { "3S50AN", INFO_S3AN(JEDEC_ID(0x1f2200, 0, 0), 64, 264) }, + { "3S200AN", INFO_S3AN(JEDEC_ID(0x1f2400, 0, 0), 256, 264) }, + { "3S400AN", INFO_S3AN(JEDEC_ID(0x1f2400, 0, 0), 256, 264) }, + { "3S700AN", INFO_S3AN(JEDEC_ID(0x1f2500, 0, 0), 512, 264) }, + { "3S1400AN", INFO_S3AN(JEDEC_ID(0x1f2600, 0, 0), 512, 528) }, { }, }; -- 2.7.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 2017-02-14 15:35 ` [PATCH v2 0/3] " mark.marshall 2017-02-14 15:35 ` [PATCH v2 1/3] " mark.marshall 2017-02-14 15:35 ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall @ 2017-02-14 15:35 ` mark.marshall 2017-08-01 16:49 ` Cyrille Pitchen 2 siblings, 1 reply; 12+ messages in thread From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw) To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall From: Mark Marshall <mark.marshall@omicronenergy.com> This device has a write page size of 512. Changing this from 256 to 512 almost doubles the write performance of the flash. Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> --- drivers/mtd/spi-nor/spi-nor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 467dc93..ba4d7b7 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -1056,6 +1056,8 @@ static const struct flash_info spi_nor_ids[] = { { "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) }, { "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2), 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl512s", INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl512s", INFO_FULL(JEDEC_ID(0x010220, 0x4d00, 2), + 256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s70fl01gs", INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) }, { "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024, 64, 0) }, { "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2), 64 * 1024, 256, 0) }, -- 2.7.4 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 2017-02-14 15:35 ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall @ 2017-08-01 16:49 ` Cyrille Pitchen 0 siblings, 0 replies; 12+ messages in thread From: Cyrille Pitchen @ 2017-08-01 16:49 UTC (permalink / raw) To: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut Cc: richard, dwmw2, markmarshall14, boris.brezillon Hi Mark, Le 14/02/2017 à 16:35, mark.marshall@omicronenergy.com a écrit : > From: Mark Marshall <mark.marshall@omicronenergy.com> > > This device has a write page size of 512. Changing this from 256 to 512 > almost doubles the write performance of the flash. This issue should be fixed now parsing the SFDP tables of the s25fl512s memory part. Indeed bits[7:4] of DWORD11 in the Basic Flash Parameter Table encode the actual page size for Page Program operations. This value overrides the one read from info->page_size. Best regards, Cyrille > > Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com> > --- > drivers/mtd/spi-nor/spi-nor.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index 467dc93..ba4d7b7 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -1056,6 +1056,8 @@ static const struct flash_info spi_nor_ids[] = { > { "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) }, > { "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2), 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s25fl512s", INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > + { "s25fl512s", INFO_FULL(JEDEC_ID(0x010220, 0x4d00, 2), > + 256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "s70fl01gs", INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) }, > { "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024, 64, 0) }, > { "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2), 64 * 1024, 256, 0) }, > ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2017-08-01 16:49 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-01-24 13:52 [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s mark.marshall 2017-01-24 16:48 ` Marek Vasut 2017-01-26 14:58 ` Mark Marshall 2017-02-04 22:25 ` Marek Vasut 2017-02-13 13:53 ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall 2017-02-14 5:02 ` Marek Vasut 2017-02-14 10:22 ` Cyrille Pitchen 2017-02-14 15:35 ` [PATCH v2 0/3] " mark.marshall 2017-02-14 15:35 ` [PATCH v2 1/3] " mark.marshall 2017-02-14 15:35 ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall 2017-02-14 15:35 ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall 2017-08-01 16:49 ` Cyrille Pitchen
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.