* [PATCH v3] mtd: spi-nor: micron-st: Add support for is25wx01g
@ 2026-10-13 15:58 Nuno Sá
2026-10-13 16:14 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Nuno Sá @ 2026-10-13 15:58 UTC (permalink / raw)
To: linux-mtd, linux-kernel
Cc: Pratyush Yadav, Michael Walle, Takahiro Kuwano, Miquel Raynal,
Richard Weinberger, Vignesh Raghavendra
Add support for the ISSI IS25WX01G, a 1 Gbit (128 MiB) octal NOR flash.
The part is fully described by SFDP, so only the flash ID and a small
post_bfpt fixup are needed.
WRITE STATUS REGISTER (01h) takes a single data byte and only affects
status register bits 7:2, so the default 16-bit Write Status assumption
does not hold. Clear write_sr1_and_sr2 so that the single byte write_sr1
path is taken; write_sr1 is already set to 01h by the BFPT parsing.
The flash also has no Status Register 2. Configuration registers are read
with B5h/85h and written with B1h/81h, and the 35h Read Configuration
Register command does not exist, so clear read_sr2 as well.
Software write protection is done through the block protect bits in the
status register: BP0-BP2 at bits 4:2, BP3 at bit 6 and a Top/Bottom bit at
bit 5, which is exactly what SPI_NOR_HAS_LOCK, SPI_NOR_4BIT_BP,
SPI_NOR_BP3_SR_BIT6 and SPI_NOR_HAS_TB describe, so set those flags to get
the generic locking support.
Note that given that the Flag Status Register (FSR) handling is the same
as in some micron devices, were're adding the issi chip directly on the
micron-st driver.
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
---
Add support for the ISSI IS25WX01G, a 1 Gbit (128 MiB) octal
NOR flash.
The part is fully described by SFDP, so patch 2 only needs the flash ID
plus a small post_bfpt fixup:
- The flash has no Status Register 2 and does not implement the 35h Read
Configuration Register command, so the core's default assumption of a
16-bit Write Status command does not hold and SNOR_F_HAS_16BIT_SR has
to be cleared.
- Its BFPT Quad Enable Requirement field carries a reserved value, which
makes spi_nor_parse_bfpt() keep the manufacturer default quad enable
method. As this is an octal-only part with no quad mode at all, the
quad_enable hook is cleared.
Changes in v3:
- Move the IS25WX01G support into the micron-st driver and make use of
the pre-existing FSR handling.
- Link to v2: https://patch.msgid.link/20260914-mtd-spi-nor-new-issi-chip-v2-0-3cd4d7e434b2@analog.com
---
This flash is populated on the sc846 board and was tested at 125MHz
using the cadence xspi (cdns,xspi-nor) SPI controller.
(Note that in fact the controller also needs some patches and a new sc846
compatible to integrate)
cat /sys/bus/spi/devices/spi6.0/spi-nor/jedec_id
9d5b1b
cat /sys/bus/spi/devices/spi6.0/spi-nor/manufacturer
issi
xxd -p /sys/bus/spi/devices/spi6.0/spi-nor/sfdp
53464450090103ff00070114300000ff84000102a00000ff05000105b000
00ff0a000108d00000ffffffffffffffffffe5208affffffff3f00000000
00000000eeffffffffff00ffffff00000c2011d80f5200ff4462990087ce
04e22801273d7a757a75ffbdd55c000070ff8170f8a12fcb278b00008401
0082080000000088ffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffff430effff21dc5cffffffffffffffffff000b801e
b181b58500f0ff9f500a000028d55a8cffffffffffffffffffffffff0000
060100000000000081050000e70000000601000000000000810600e70000
sha256sum /sys/bus/spi/devices/spi6.0/spi-nor/sfdp
a1fa0cab6324b45a17e6bd7fc7e581496517d558d8c7684cc85e57a5dfe5d87b /sys/bus/spi/devices/spi6.0/spi-nor/sfdp
cat /sys/kernel/debug/spi-nor/spi6.0/capabilities
Supported read modes by the flash
1S-1S-1S
opcode 0x13
mode cycles 0
dummy cycles 0
1S-1S-1S (fast read)
opcode 0x0c
mode cycles 0
dummy cycles 8
1S-1S-8S
opcode 0x7c
mode cycles 1
dummy cycles 7
1S-8S-8S
opcode 0xcc
mode cycles 1
dummy cycles 15
8D-8D-8D
opcode 0x0b
mode cycles 0
dummy cycles 20
Supported page program modes by the flash
1S-1S-1S
opcode 0x12
1S-1S-8S
opcode 0x84
1S-8S-8S
opcode 0x8e
8D-8D-8D
opcode 0x12
cat /sys/kernel/debug/spi-nor/spi6.0/params
name (null)
id 9d 5b 1b 10 01 00
size 128 MiB
write size 1
page size 256
address nbytes 4
flags HAS_SR_TB | 4B_OPCODES | HAS_4BAIT | HAS_LOCK | HAS_4BIT_BP | HAS_SR_BP3_BIT6 | SOFT_RESET | NO_WP
opcodes
read 0xcc
dummy cycles 16
erase 0xdc
program 0x8e
8D extension repeat
protocols
read 1S-8S-8S
write 1S-8S-8S
register 1S-1S-1S
erase commands
21 (4.00 KiB) [1]
5c (32.0 KiB) [2]
dc (128 KiB) [3]
c7 (128 MiB)
sector map
region (in hex) | erase mask | overlaid
------------------+------------+---------
00000000-07ffffff | [ 3] | no
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 1024
dd if=/dev/urandom of=./spi_test bs=1M count=2
2+0 records in
2+0 records out
mtd_debug erase /dev/mtd4 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
hexdump spi_read
0000000 ffff ffff ffff ffff ffff ffff ffff ffff
*
0200000
sha256sum spi_read
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
mtd_debug write /dev/mtd4 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
sha256sum spi*
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_read
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_test
mtd_debug erase /dev/mtd4 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
sha256sum spi*
4bda3a28f4ffe603c0ec1258c0034d65a1a0d35ab7bd523a834608adabf03cc5 spi_read
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_test
mtd_debug info /dev/mtd4
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size = 134217728 (128M)
mtd.erasesize = 131072 (128K)
mtd.writesize = 1
mtd.oobsize = 0
regions = 0
flash_lock -u /dev/mtd4
flash_lock -i /dev/mtd4
Device: /dev/mtd4
Start: 0
Len: 0x8000000
Lock status: unlocked
Return code: 0
mtd_debug erase /dev/mtd4 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
mtd_debug write /dev/mtd4 0 2097152 spi_test
Copied 2097152 bytes from spi_test to address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
sha256sum spi*
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_read
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_test
show_sectors
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | unlocked | 1024
flash_lock -l /dev/mtd4
flash_lock -i /dev/mtd4
Device: /dev/mtd4
Start: 0
Len: 0x8000000
Lock status: locked
Return code: 1
mtd_debug erase /dev/mtd4 0 2097152
Erased 2097152 bytes from address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read
Copied 2097152 bytes from address 0x00000000 in flash to spi_read
sha256sum spi*
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_read
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_test
dd if=/dev/urandom of=./spi_test2 bs=1M count=2
2+0 records in
2+0 records out
mtd_debug write /dev/mtd4 0 2097152 spi_test2
Copied 2097152 bytes from spi_test2 to address 0x00000000 in flash
mtd_debug read /dev/mtd4 0 2097152 spi_read2
Copied 2097152 bytes from address 0x00000000 in flash to spi_read2
sha256sum spi*
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_read
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_read2
a1230061123719295de1df8c401601e7ba2c6b163ab2d324d5d254d83ca71108 spi_test
03781ea58ffe95ed666f174f7804b84999f525516595c1ba0f99ee83eb8af22b spi_test2
show_sectors
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07ffffff | locked | 1024
flash_lock -u /dev/mtd4
flash_lock -l /dev/mtd4 $(($size - (2 * $ss))) $((2 * $bps))
show_sectors
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07fbffff | unlocked | 1022
07fc0000-07ffffff | locked | 2
flash_lock -u /dev/mtd4 $(($size - (2 * $ss))) $((1 * $bps))
show_sectors
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-07fdffff | unlocked | 1023
07fe0000-07ffffff | locked | 1
flash_lock -u /dev/mtd4
flash_lock -l /dev/mtd4 $(($size - (2**7 * $ss))) $((2**7 * $bps))
show_sectors
locked sectors
region (in hex) | status | #sectors
------------------+----------+---------
00000000-06ffffff | unlocked | 896
07000000-07ffffff | locked | 128
---
drivers/mtd/spi-nor/micron-st.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index f97f2dead8c2..eba07efdca75 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -216,9 +216,34 @@ static const struct flash_info micron_nor_parts[] = {
.size = SZ_256M,
.no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
.mfr_flags = USE_FSR,
+ }, {
+ /* is25wx01g */
+ .id = SNOR_ID(0x9d, 0x5b, 0x1b),
+ .sector_size = SZ_128K,
+ .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
+ SPI_NOR_BP3_SR_BIT6,
+ .mfr_flags = USE_FSR,
},
};
+static int is25wx01g_post_bfpt_fixup(struct spi_nor *nor,
+ const struct sfdp_parameter_header *bfpt_header,
+ const struct sfdp_bfpt *bfpt)
+{
+ /*
+ * There is no Status Register 2 and no 35h command. And WRITE STATUS
+ * REGISTER takes a single data byte.
+ */
+ nor->params->opcodes.write_sr1_and_sr2 = 0;
+ nor->params->opcodes.read_sr2 = 0;
+
+ return 0;
+}
+
+static const struct spi_nor_fixups is25wx01g_fixups = {
+ .post_bfpt = is25wx01g_post_bfpt_fixup,
+};
+
static int mt25qu512a_post_bfpt_fixup(struct spi_nor *nor,
const struct sfdp_parameter_header *bfpt_header,
const struct sfdp_bfpt *bfpt)
@@ -655,6 +680,7 @@ static const struct spi_nor_fixups micron_st_nor_fixups = {
static const struct spi_nor_fixup micron_fixups[] = {
{ .fixups = µn_st_nor_fixups },
+ { .id = SNOR_ID(0x9d, 0x5b, 0x1b), .fixups = &is25wx01g_fixups },
{ .id = SNOR_ID(0x2c, 0x5b, 0x1a), .fixups = &mt35xu512aba_fixups,
.fixup_flags = SPI_NOR_IO_MODE_EN_VOLATILE },
{ .id = SNOR_ID(0x2c, 0x5b, 0x1b), .fixups = &mt35_two_die_fixups,
---
base-commit: b1fbdc83612abc9281304e5b000b93b106eb3733
change-id: 20260911-mtd-spi-nor-new-issi-chip-ef3881bab60e
--
Thanks!
- Nuno Sá
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] mtd: spi-nor: micron-st: Add support for is25wx01g
2026-10-13 15:58 [PATCH v3] mtd: spi-nor: micron-st: Add support for is25wx01g Nuno Sá
@ 2026-10-13 16:14 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-10-13 16:14 UTC (permalink / raw)
To: Nuno Sá, linux-mtd
Cc: Pratyush Yadav, Michael Walle, Takahiro Kuwano, Miquel Raynal,
Richard Weinberger, Vignesh Raghavendra
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] mtd: spi-nor: ISSI flash sysfs manufacturer incorrectly exposed as micron
--
commit 1e03ade777f97b0b05ae670b65caa00dab47917b
Author: Nuno Sá <nuno.sa@analog.com>
mtd: spi-nor: micron-st: Add support for is25wx01g
Add support for the ISSI IS25WX01G, a 1 Gbit (128 MiB) octal NOR flash.
The part is fully described by SFDP, so only the flash ID and a small
post_bfpt fixup are needed.
> diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
> index f97f2dead8c2f..eba07efdca753 100644
> --- a/drivers/mtd/spi-nor/micron-st.c
> +++ b/drivers/mtd/spi-nor/micron-st.c
> @@ -216,9 +216,34 @@ static const struct flash_info micron_nor_parts[] = {
> .size = SZ_256M,
> .no_sfdp_flags = SECT_4K | SPI_NOR_OCTAL_READ,
> .mfr_flags = USE_FSR,
> + }, {
> + /* is25wx01g */
> + .id = SNOR_ID(0x9d, 0x5b, 0x1b),
> + .sector_size = SZ_128K,
> + .flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4BIT_BP |
> + SPI_NOR_BP3_SR_BIT6,
> + .mfr_flags = USE_FSR,
> },
> };
[Severity: Medium]
Will this incorrectly expose the ISSI flash manufacturer as "micron" in sysfs?
By placing the ISSI chip inside the micron_nor_parts[] array, it looks like its
manufacturer identity will be hardcoded to Micron.
When spi_nor_match_id() matches the ID, it unconditionally links the sysfs
manufacturer string to the array the chip resides in:
drivers/mtd/spi-nor/core.c:spi_nor_match_id() {
...
if (part->id &&
!memcmp(part->id->bytes, id, part->id->len)) {
nor->manufacturer = manufacturers[i];
return part;
}
...
}
Could this break sysfs ABI expectations for identifying the chip's true
manufacturer? This also seems to contradict the test output in the patch
notes which shows the manufacturer sysfs attribute returning "issi".
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261013-mtd-spi-nor-new-issi-chip-v3-1-099c58673142@analog.com?part=1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-13 16:14 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-13 15:58 [PATCH v3] mtd: spi-nor: micron-st: Add support for is25wx01g Nuno Sá
2026-10-13 16:14 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox