qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/9] hw/block: m25p80: Fix the number of dummy bytes needed for N


From: Bin Meng
Subject: [PATCH 2/9] hw/block: m25p80: Fix the number of dummy bytes needed for Numonyx/Micron flashes
Date: Thu, 14 Jan 2021 23:08:55 +0800

From: Bin Meng <bin.meng@windriver.com>

Unfortunately the dummy cycle/bytes calculation for Numonyx/Micron
flashes is still wrong, even though there were fixes before that
tried to fix it.

First of all, the default number of dummy cycles is only related to
the SPI protocol mode. For QSPI it is 10, otherwise it is 8.

Secondly, per the datasheet [1], it's clear that in Quad I/O or Dual
I/O mode, the dummy bits show up on 4 or 2 lines.

The tricky part is the standard mode (extended mode). For such mode,
the dummy bits are not like other flashes that they show up on the
same lines as the address bits, but on the same lines as the data
bits, so for a Quad Output Fast Read command (6Bh), the dummy bits
must be sent on all the 4 IO lines. IOW, the total number of dummy
bits depend on the command.

The datasheet does not state crystal clearly how many lines are used
for 6Bh in the standard mode. We may only tell from figure 19 that is
showing the command sequence and interpret that dummy cycles need to
be on 4 lines for 6Bh.

Note as of today, both spi-nor drivers in U-Boot v2021.01 and Linux
v5.10 has the wrong assumption for all flashes that dummy cycle bus
width is the same as the address bits bus width, which is not true
for the Numonyx/Micron flash in the standard mode.

Last if the total number of dummy bits is not multiple of 8, log an
unimplemented message to notify user, and round it up. Right now the
QEMU ssi_transfer() API transfers one byte each time to the flash.
Leaving such as unimplemented will not cause any issue because as of
today both spi-nor drivers in U-Boot and Linux have the assumption
that the total number of dummy bits must be multiple of 8.

[1] https://media-www.micron.com/-/media/client/global/documents/products/
    data-sheet/nor-flash/serial-nor/n25q/n25q_512mb_1ce_3v_65nm.pdf

Fixes: 23af26856606 ("hw/block/m25p80: Fix Numonyx fast read dummy cycle count")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
---

 hw/block/m25p80.c | 62 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index c947716f99..c8cd12a6d3 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -856,19 +856,71 @@ static uint8_t numonyx_extract_cfg_num_dummies(Flash *s)
     mode = numonyx_mode(s);
     num_dummies = extract32(s->volatile_cfg, 4, 4);
 
+    /*
+     * The default nubmer of dummy cycles is only related to the SPI
+     * protocol mode. For QSPI it is 10, otherwise it is 8.
+     */
     if (num_dummies == 0x0 || num_dummies == 0xf) {
+        num_dummies = (mode == MODE_QIO) ? 10 : 8;
+    }
+
+    /*
+     * Convert the number of dummy cycles to bytes
+     *
+     * Per the datasheet, it's clear that in Quad I/O or Dual I/O mode,
+     * the dummy bits show up on 4 or 2 lines.
+     *
+     * The tricky part is the standard mode (extended mode). For such
+     * mode, the dummy bits are not like other flashes that they show up
+     * on the same lines as the address bits, but on the same lines as
+     * the data bits, so for a Quad Output Fast Read command (6Bh), the
+     * dummy bits must be sent on all the 4 IO lines. IOW, the total
+     * number of dummy bits depend on the command.
+     *
+     * The datasheet does not state crystal clearly how many lines are
+     * used for 6Bh in the standard mode. We may only tell from figure 19
+     * that is showing the command sequence and interpret that dummy cycles
+     * need to be on 4 lines for 6Bh.
+     *
+     * Note as of today, both spi-nor drivers in U-Boot v2021.01 and Linux
+     * v5.10 has the wrong assumption for all flashes that dummy cycle bus
+     * width is the same as the address bits bus width, which is not true
+     * for the Numonyx/Micron flash in the standard mode.
+     */
+
+    if (mode == MODE_QIO) {
+        num_dummies *= 4;
+    } else if (mode == MODE_DIO) {
+        num_dummies *= 2;
+    } else {
         switch (s->cmd_in_progress) {
+        case QOR:
+        case QOR4:
         case QIOR:
         case QIOR4:
-            num_dummies = 10;
+            num_dummies *= 4;
             break;
-        default:
-            num_dummies = (mode == MODE_QIO) ? 10 : 8;
+        case DOR:
+        case DOR4:
+        case DIOR:
+        case DIOR4:
+            num_dummies *= 2;
             break;
-        }
+         }
+    }
+
+    /*
+     * If the total number of dummy bits is not multiple of 8, log an
+     * unimplemented message to notify user, and round it up.
+     */
+    if (num_dummies % 8) {
+        qemu_log_mask(LOG_UNIMP,
+                      "M25P80: the number of dummy bits is not multiple of 8");
+        num_dummies = ROUND_UP(num_dummies, 8);
     }
 
-    return num_dummies;
+    /* return the number of dummy bytes */
+    return num_dummies / 8;
 }
 
 static void decode_fast_read_cmd(Flash *s)
-- 
2.25.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]