* [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
@ 2025-08-22 12:03 Maarten Zanders
2025-09-01 14:46 ` Pratyush Yadav
2026-06-02 13:16 ` Miquel Raynal
0 siblings, 2 replies; 6+ messages in thread
From: Maarten Zanders @ 2025-08-22 12:03 UTC (permalink / raw)
To: Tudor Ambarus, Pratyush Yadav, linux-mtd
Hi all,
On the Macronix MX25L12833F (ID 0xC22018) & others of this family/mfg,
the CR (condition register) must be read with opcode 0x15. The driver
currently uses 0x35, which the chip does not recognize.
Datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf
(p.27, RDCR).
With 0x35 the data line floats and the driver reads CR as 0xFF
(depending on previous state of the line or pull up/down). This value
is then written back in spi_nor_write_16bit_sr_and_check(), setting CR
to 0xFF. One consequence is flipping the OTP Top/Bottom protection
bit, so from then on, locking the top block actually locks the bottom
sector. This breaks bootloader updates (in my case) and similar flows.
Possible fixes:
- Make CR read opcode configurable per device.
- Force Macronix parts to 8-bit SR accesses (clear SNOR_F_HAS_16BIT_SR).
- Implement T/B bit handling for Macronix (needed for already-fielded
devices with flipped OTP bit, but complicated by non-uniform
protection blocks).
What would be the preferred approach? Other ideas? Anyone seen similar
with Macronix parts?
A quick fix which can be backported easily and the full implementation
later on would be beneficial IMHO.
Thanks,
Maarten
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
2025-08-22 12:03 [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35) Maarten Zanders
@ 2025-09-01 14:46 ` Pratyush Yadav
2025-09-02 11:18 ` Maarten Zanders
2026-06-02 13:16 ` Miquel Raynal
1 sibling, 1 reply; 6+ messages in thread
From: Pratyush Yadav @ 2025-09-01 14:46 UTC (permalink / raw)
To: Maarten Zanders; +Cc: Tudor Ambarus, Pratyush Yadav, linux-mtd
Hi,
On Fri, Aug 22 2025, Maarten Zanders wrote:
> Hi all,
>
> On the Macronix MX25L12833F (ID 0xC22018) & others of this family/mfg,
> the CR (condition register) must be read with opcode 0x15. The driver
> currently uses 0x35, which the chip does not recognize.
Is it one of those devices for which Macronix has re-used the flash IDs?
I vaguely recall reading that somewhere. If so, then we also need to be
careful of breaking the older variants of the flash.
>
> Datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf
> (p.27, RDCR).
>
> With 0x35 the data line floats and the driver reads CR as 0xFF
> (depending on previous state of the line or pull up/down). This value
> is then written back in spi_nor_write_16bit_sr_and_check(), setting CR
> to 0xFF. One consequence is flipping the OTP Top/Bottom protection
> bit, so from then on, locking the top block actually locks the bottom
> sector. This breaks bootloader updates (in my case) and similar flows.
>
> Possible fixes:
Is it at all possible to discover the opcode from the flash SFDP table
(SCCR map perhaps)? If so, I think that would be the best way forward
since it would be generic.
There is the SNOR_F_NO_READ_CR flag that seems to do what you want. In
spi_nor_write_16bit_sr_and_check(), if the flag is set it does not issue
the read CR command and either sets the second byte to 0 or to
SR2_QUAD_EN_BIT1. The flag can be discovered via BFPT (see
spi_nor_parse_bfpt()). Is the BFPT table on the flash incorrect? In that
case, perhaps we should add a post-BFPT fixup?
> - Make CR read opcode configurable per device.
> - Force Macronix parts to 8-bit SR accesses (clear SNOR_F_HAS_16BIT_SR).
> - Implement T/B bit handling for Macronix (needed for already-fielded
> devices with flipped OTP bit, but complicated by non-uniform
> protection blocks).
>
> What would be the preferred approach? Other ideas? Anyone seen similar
> with Macronix parts?
> A quick fix which can be backported easily and the full implementation
> later on would be beneficial IMHO.
>
> Thanks,
> Maarten
--
Regards,
Pratyush Yadav
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
2025-09-01 14:46 ` Pratyush Yadav
@ 2025-09-02 11:18 ` Maarten Zanders
2025-09-09 15:29 ` Pratyush Yadav
0 siblings, 1 reply; 6+ messages in thread
From: Maarten Zanders @ 2025-09-02 11:18 UTC (permalink / raw)
To: Pratyush Yadav; +Cc: Tudor Ambarus, linux-mtd
Hi,
On Mon, Sep 1, 2025 at 4:46 PM Pratyush Yadav <pratyush@kernel.org> wrote:
> > On the Macronix MX25L12833F (ID 0xC22018) & others of this family/mfg,
> > the CR (condition register) must be read with opcode 0x15. The driver
> > currently uses 0x35, which the chip does not recognize.
>
> Is it one of those devices for which Macronix has re-used the flash IDs?
> I vaguely recall reading that somewhere. If so, then we also need to be
> careful of breaking the older variants of the flash.
Yes, there is quite some flash ID reuse. This is indeed one of them.
I just went through a lot of datasheets from Macronix and for those
supporting RDCR, they are always using opcode 0x15.
Also, when inspecting patches (for older kernel, uboot,..) which add
MX spi-nor support from the Macronix website, they do something like
this:
#define SPINOR_OP_RDCR_MX 0x15 /* Read configuration register for Macronix*/
...
opcode = (nor->jedec_id == CFI_MFR_MACRONIX) ? SPINOR_OP_RDCR_MX :
SPINOR_OP_RDCR;
A cleaner/modern approach would be to add a parameter in struct
spi_nor_flash_parameter which gets defaulted to SPINOR_OP_RDCR (0x35)
and fixed up using manufacturer late_init() for Macronix?
> Is it at all possible to discover the opcode from the flash SFDP table
> (SCCR map perhaps)? If so, I think that would be the best way forward
> since it would be generic.
Unfortunately, no. I received the SFDP data for this part and there's
no SCCR map or other means to distinguish opcodes. I believe only the
more recent parts include this (SCCR was defined in 2019).
> There is the SNOR_F_NO_READ_CR flag that seems to do what you want. In
> spi_nor_write_16bit_sr_and_check(), if the flag is set it does not issue
> the read CR command and either sets the second byte to 0 or to
> SR2_QUAD_EN_BIT1. The flag can be discovered via BFPT (see
> spi_nor_parse_bfpt()). Is the BFPT table on the flash incorrect? In that
> case, perhaps we should add a post-BFPT fixup?
That flag will have similar results as reading garbage today. It will
ignore the actual contents of CR when we're actually trying to do a
read-don't-modify-write. In the case of this part, it will clear some
bits which were 1 by default, changing output driver strength.
Thanks for your feedback,
Maarten
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
2025-09-02 11:18 ` Maarten Zanders
@ 2025-09-09 15:29 ` Pratyush Yadav
2025-09-10 11:21 ` Maarten Zanders
0 siblings, 1 reply; 6+ messages in thread
From: Pratyush Yadav @ 2025-09-09 15:29 UTC (permalink / raw)
To: Maarten Zanders; +Cc: Pratyush Yadav, Tudor Ambarus, linux-mtd
On Tue, Sep 02 2025, Maarten Zanders wrote:
> Hi,
>
> On Mon, Sep 1, 2025 at 4:46 PM Pratyush Yadav <pratyush@kernel.org> wrote:
>> > On the Macronix MX25L12833F (ID 0xC22018) & others of this family/mfg,
>> > the CR (condition register) must be read with opcode 0x15. The driver
>> > currently uses 0x35, which the chip does not recognize.
>>
>> Is it one of those devices for which Macronix has re-used the flash IDs?
>> I vaguely recall reading that somewhere. If so, then we also need to be
>> careful of breaking the older variants of the flash.
>
> Yes, there is quite some flash ID reuse. This is indeed one of them.
> I just went through a lot of datasheets from Macronix and for those
> supporting RDCR, they are always using opcode 0x15.
> Also, when inspecting patches (for older kernel, uboot,..) which add
> MX spi-nor support from the Macronix website, they do something like
> this:
>
> #define SPINOR_OP_RDCR_MX 0x15 /* Read configuration register for Macronix*/
> ...
> opcode = (nor->jedec_id == CFI_MFR_MACRONIX) ? SPINOR_OP_RDCR_MX :
> SPINOR_OP_RDCR;
How do any of the flashes even work on mainline then? Won't they all
have the same problem? Does it only end up touching the OTP bits, and
those don't get noticed?
>
> A cleaner/modern approach would be to add a parameter in struct
> spi_nor_flash_parameter which gets defaulted to SPINOR_OP_RDCR (0x35)
> and fixed up using manufacturer late_init() for Macronix?
Yeah, or maybe a callback like for ready?
>
>> Is it at all possible to discover the opcode from the flash SFDP table
>> (SCCR map perhaps)? If so, I think that would be the best way forward
>> since it would be generic.
>
> Unfortunately, no. I received the SFDP data for this part and there's
> no SCCR map or other means to distinguish opcodes. I believe only the
> more recent parts include this (SCCR was defined in 2019).
>
>> There is the SNOR_F_NO_READ_CR flag that seems to do what you want. In
>> spi_nor_write_16bit_sr_and_check(), if the flag is set it does not issue
>> the read CR command and either sets the second byte to 0 or to
>> SR2_QUAD_EN_BIT1. The flag can be discovered via BFPT (see
>> spi_nor_parse_bfpt()). Is the BFPT table on the flash incorrect? In that
>> case, perhaps we should add a post-BFPT fixup?
>
> That flag will have similar results as reading garbage today. It will
> ignore the actual contents of CR when we're actually trying to do a
> read-don't-modify-write. In the case of this part, it will clear some
> bits which were 1 by default, changing output driver strength.
Hmm, makes sense. I was hoping the bits would also default to 0 so there
won't be a problem.
--
Regards,
Pratyush Yadav
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
2025-09-09 15:29 ` Pratyush Yadav
@ 2025-09-10 11:21 ` Maarten Zanders
0 siblings, 0 replies; 6+ messages in thread
From: Maarten Zanders @ 2025-09-10 11:21 UTC (permalink / raw)
To: Pratyush Yadav; +Cc: Pratyush Yadav, Tudor Ambarus, linux-mtd
Hi,
On Tue, Sep 9, 2025 at 5:29 PM Pratyush Yadav <me@yadavpratyush.com> wrote:
> How do any of the flashes even work on mainline then? Won't they all
> have the same problem? Does it only end up touching the OTP bits, and
> those don't get noticed?
For the part I mentioned, the other fields in the CR concern:
- output driver strength, this can go easily unnoted (default 1)
- dummy clock cycles, only for fast read mode, not sure if this is used
Flipping the OTP top/bottom bit only gets noted when you use (and
test..) locking for the last portion of the device as that's the only
thing which is supported by the driver - the BP mechanism at top of
flash.
Also when combined with (default) U-Boot for instance, all locking is
disabled in SR at boot which hides the issue again...
So for the most part, the driver and devices are working and you need
quite some bad luck to hit this bug.
> > > SNOR_F_NO_READ_CR
> > That flag will have similar results as reading garbage today. It will
> > ignore the actual contents of CR when we're actually trying to do a
> > read-don't-modify-write. In the case of this part, it will clear some
> > bits which were 1 by default, changing output driver strength.
>
> Hmm, makes sense. I was hoping the bits would also default to 0 so there
> won't be a problem.
Also tested with a different (& larger) flash device, MX25L25645G,
where all the CR bits do default to 0. Coincidentally, the flag
SNOR_F_NO_READ_CR is then also set so we're always writing 0's to CR
when updating SR.
This is because in SFPD BFPT_DWORD15_QER_SR2_BIT1_NO_RD is set, as
opposed to BFPT_DWORD15_QER_SR1_BIT6 on the failing part.
So for this kind of devices (which don't read CR) we're good. But it's
hard to get an overview for all devices as that requires the SFDP data
which is only available on request.
This SFDP parsing of QER is unclear/messy to me. I'd love to have a
look in the JEDEC specification but don't have access. Clearly,
somewhere something went wrong with the implementation of these
parameters. Some variable renames in the past obfuscate history a bit
too. I feel that SNOR_F_NO_READ_CR was introduced as a fix while the
actual issue was a wrong opcode...
I was told that Macronix engineers are also looking into this so I
hope they can chip in here in due time.
> > A cleaner/modern approach would be to add a parameter in struct
> > spi_nor_flash_parameter which gets defaulted to SPINOR_OP_RDCR (0x35)
> > and fixed up using manufacturer late_init() for Macronix?
>
> Yeah, or maybe a callback like for ready?
>
I have a working patch for 6.1 which my project uses today, will see
to get this to the current state & have it tested.
I also noted on the Zephyr Project that the opcode for RDCR is using
0x15 for all mfg's...
Best regards,
Maarten
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35)
2025-08-22 12:03 [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35) Maarten Zanders
2025-09-01 14:46 ` Pratyush Yadav
@ 2026-06-02 13:16 ` Miquel Raynal
1 sibling, 0 replies; 6+ messages in thread
From: Miquel Raynal @ 2026-06-02 13:16 UTC (permalink / raw)
To: Maarten Zanders; +Cc: Tudor Ambarus, Pratyush Yadav, linux-mtd
Hello,
On 22/08/2025 at 14:03:02 +02, Maarten Zanders <maarten@zanders.be> wrote:
> Hi all,
>
> On the Macronix MX25L12833F (ID 0xC22018) & others of this family/mfg,
> the CR (condition register) must be read with opcode 0x15. The driver
> currently uses 0x35, which the chip does not recognize.
>
> Datasheet: https://www.macronix.com/Lists/Datasheet/Attachments/8934/MX25L12833F,%203V,%20128Mb,%20v1.0.pdf
> (p.27, RDCR).
>
> With 0x35 the data line floats and the driver reads CR as 0xFF
> (depending on previous state of the line or pull up/down). This value
> is then written back in spi_nor_write_16bit_sr_and_check(), setting CR
> to 0xFF. One consequence is flipping the OTP Top/Bottom protection
> bit, so from then on, locking the top block actually locks the bottom
> sector. This breaks bootloader updates (in my case) and similar flows.
>
> Possible fixes:
> - Make CR read opcode configurable per device.
FYI I just proposed a series which goes into that direction, with quite
a deep rework of the QER SFDP field handling. This rework allows on a
per chip basis to indicate:
- what are the status operations supported
- what are the opcodes for these operations
Link: https://lore.kernel.org/linux-mtd/20260529-winbond-v7-1-spi-nor-rv-addition-v1-0-f3ae18502d5a@bootlin.com/T/#m0058d07965ba8c91a2438c5512e2b7b2693a6909
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-06-02 13:16 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-22 12:03 [spi-nor] Macronix MX25L requires CR read opcode 0x15 (not 0x35) Maarten Zanders
2025-09-01 14:46 ` Pratyush Yadav
2025-09-02 11:18 ` Maarten Zanders
2025-09-09 15:29 ` Pratyush Yadav
2025-09-10 11:21 ` Maarten Zanders
2026-06-02 13:16 ` Miquel Raynal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox