Skip to content

Commit 6032671

Browse files
committed
QSPIFBlockDevice: Add quirk for inconsistent CR3NV register value
Cypress S25FS512S's SFDP table suggests that bit-1 of the register CR3NV on 25FS512S should equal 1. But it is a known issue that the value is actually 0 on hardware. So if we query the value of CR3NV during configuration detection, we can't find a configuration that matches the SFDP data. This issue has been discussed in the Linux MTD (Memory Technology Devices) mailing list: https://linux-mtd.infradead.narkive.com/ylHK6CyT/spi-nor-fs512s-incorrect-cr3nv-1-value This commit adds a quirk to report bit-1 of CR3NV as 1. Note: In Mbed OS, vendor-specific quirks can only be handled in block devices. The SFDP functions assume data from hardware to be correct. So this quirk is in the block device.
1 parent 8dfad16 commit 6032671

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

storage/blockdevice/COMPONENT_QSPIF/include/QSPIF/QSPIFBlockDevice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
376376

377377
bool _needs_fast_mode;
378378

379+
// S25FS512S needs a quirk
380+
bool _S25FS512S_quirk;
381+
379382
// Clear block protection
380383
qspif_clear_protection_method_t _clear_protection_method;
381384

storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
176176
// Set default 4-byte addressing extension register write instruction
177177
_attempt_4_byte_addressing = true;
178178
_4byte_msb_reg_write_inst = QSPIF_INST_4BYTE_REG_WRITE_DEFAULT;
179+
180+
// Quirk for Cypress S25FS512S
181+
_S25FS512S_quirk = false;
179182
}
180183

181184
int QSPIFBlockDevice::init()
@@ -1099,6 +1102,16 @@ int QSPIFBlockDevice::_handle_vendor_quirks()
10991102
tr_debug("Applying quirks for ISSI");
11001103
_num_status_registers = 1;
11011104
break;
1105+
case 0x01:
1106+
if (vendor_device_ids[1] == 0x02 && vendor_device_ids[2] == 0x20) {
1107+
tr_debug("Applying quirks for Cypress S25FS512S");
1108+
// On a Cypress S25FS512S flash chip
1109+
// * The SFDP table expects the register bitfield CR3NV[1] to be 1
1110+
// but its actual value on the hardware is 0. In order for SFDP parsing
1111+
// to work, the quirk reports CR3NV[1] as 1.
1112+
_S25FS512S_quirk = true;
1113+
}
1114+
break;
11021115
}
11031116

11041117
return 0;
@@ -1469,6 +1482,16 @@ int QSPIFBlockDevice::_qspi_send_read_sfdp_command(mbed::bd_addr_t addr, mbed::s
14691482
return status;
14701483
}
14711484

1485+
// Handle S25FS512S quirk.
1486+
const mbed::bd_addr_t S25FS512S_CR3NV = 0x4;
1487+
if (_S25FS512S_quirk) {
1488+
if (addr == S25FS512S_CR3NV) {
1489+
// If we reach here, rx_buffer is guaranteed to be non-null
1490+
// because it's been checked by _qspi.read() above.
1491+
static_cast<uint8_t *>(rx_buffer)[0] |= (1 << 1);
1492+
}
1493+
}
1494+
14721495
return QSPI_STATUS_OK;
14731496
}
14741497

0 commit comments

Comments
 (0)