From: Bin Meng <bin.m...@windriver.com> The m25p80 model uses s->needed_bytes to indicate how many follow-up bytes are expected to be received after it receives a command. For example, depending on the address mode, either 3-byte address or 4-byte address is needed.
For fast read family commands, some dummy cycles are required after sending the address bytes, and the dummy cycles need to be counted in s->needed_bytes. This is where the mess began. As the variable name (needed_bytes) indicates, the unit is in byte. It is not in bit, or cycle. However for some reason the model has been using the number of dummy cycles for s->needed_bytes. The right approach is to convert the number of dummy cycles to bytes based on the SPI protocol, for example, 6 dummy cycles for the Fast Read Quad I/O (EBh) should be converted to 3 bytes per the formula (6 * 4 / 8). Things get complicated when interacting with different SPI or QSPI flash controllers. There are major two cases: - Dummy bytes prepared by drivers, and wrote to the controller fifo. For such case, driver will calculate the correct number of dummy bytes and write them into the tx fifo. Fixing the m25p80 model will fix flashes working with such controllers. - Dummy bytes not prepared by drivers. Drivers just tell the hardware the dummy cycle configuration via some registers, and hardware will automatically generate dummy cycles for us. Fixing the m25p80 model is not enough, and we will need to fix the SPI/QSPI models for such controllers. Let's fix the mess from the flash side first. We start from a easy one, the Winbond flashes. Per the Windbond W25Q256JV datasheet [1] instrunction set table (chapter 8.1.2, 8.1.3, 8.1.4, 8.1.5), fix the wrong number of dummy bytes needed for fast read commands. [1] https://www.winbond.com/resource-files/w25q256jv%20spi%20revb%2009202016.pdf Fixes: fe8477052831 ("m25p80: Fix QIOR/DIOR handling for Winbond") Fixes: 3830c7a460b8 ("m25p80: Fix WINBOND fast read command handling") Fixes: cf6f1efe0b57 ("m25p80: Fast read commands family changes") Signed-off-by: Bin Meng <bin.m...@windriver.com> --- hw/block/m25p80.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index b744a58d1c..c947716f99 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -875,9 +875,22 @@ static void decode_fast_read_cmd(Flash *s) { s->needed_bytes = get_addr_length(s); switch (get_man(s)) { - /* Dummy cycles - modeled with bytes writes instead of bits */ + /* Dummy cycles - modeled with bytes writes */ case MAN_WINBOND: - s->needed_bytes += 8; + switch (s->cmd_in_progress) { + case FAST_READ: + case FAST_READ4: + s->needed_bytes += 1; + break; + case DOR: + case DOR4: + s->needed_bytes += 2; + break; + case QOR: + case QOR4: + s->needed_bytes += 4; + break; + } break; case MAN_NUMONYX: s->needed_bytes += numonyx_extract_cfg_num_dummies(s); @@ -906,7 +919,7 @@ static void decode_fast_read_cmd(Flash *s) static void decode_dio_read_cmd(Flash *s) { s->needed_bytes = get_addr_length(s); - /* Dummy cycles modeled with bytes writes instead of bits */ + /* Dummy cycles modeled with bytes writes */ switch (get_man(s)) { case MAN_WINBOND: s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN; @@ -945,11 +958,10 @@ static void decode_dio_read_cmd(Flash *s) static void decode_qio_read_cmd(Flash *s) { s->needed_bytes = get_addr_length(s); - /* Dummy cycles modeled with bytes writes instead of bits */ + /* Dummy cycles modeled with bytes writes */ switch (get_man(s)) { case MAN_WINBOND: - s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN; - s->needed_bytes += 4; + s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN + 2; break; case MAN_SPANSION: s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN; -- 2.25.1