diff mbox

[11/12] Support for mx66u51235 and s25fl512s

Message ID 1450270635-27080-12-git-send-email-marcin.krzeminski@nokia.com
State New
Headers show

Commit Message

Krzeminski, Marcin (Nokia - PL/Wroclaw) Dec. 16, 2015, 12:57 p.m. UTC
From: Marcin Krzeminski <marcin.krzeminski@nokia.com>

Signed-off-by: Pawel Lenkow <pawel.lenkow@nokia.com>
---
 hw/block/m25p80.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 25ec666..fadd6ec 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -107,6 +107,7 @@  typedef struct FlashPartInfo {
 #define JEDEC_NUMONYX 0x20
 #define JEDEC_WINBOND 0xEF
 #define JEDEC_SPANSION 0x01
+#define JEDEC_MACRONIX 0xC2
 
 static const FlashPartInfo known_devices[] = {
     /* Atmel -- some are (confusingly) marketed as "DataFlash" */
@@ -157,6 +158,7 @@  static const FlashPartInfo known_devices[] = {
     { INFO("mx25l12855e", 0xc22618,      0,  64 << 10, 256, 0) },
     { INFO("mx25l25635e", 0xc22019,      0,  64 << 10, 512, 0) },
     { INFO("mx25l25655e", 0xc22619,      0,  64 << 10, 512, 0) },
+    { INFO("mx66u51235f", 0xc2253a,      0,  64 << 10, 1024, ER_4K | ER_32K) },
 
     /* Micron */
     { INFO("n25q032a11",  0x20bb16,      0,  64 << 10,  64, ER_4K) },
@@ -175,7 +177,7 @@  static const FlashPartInfo known_devices[] = {
     { INFO("s25sl064p",   0x010216, 0x4d00,  64 << 10, 128, ER_4K) },
     { INFO("s25fl256s0",  0x010219, 0x4d00, 256 << 10, 128, 0) },
     { INFO("s25fl256s1",  0x010219, 0x4d01,  64 << 10, 512, 0) },
-    { INFO("s25fl512s",   0x010220, 0x4d00, 256 << 10, 256, 0) },
+    { INFO6("s25fl512s",   0x010220, 0x4d0080, 256 << 10, 256, 0) },
     { INFO("s70fl01gs",   0x010221, 0x4d00, 256 << 10, 256, 0) },
     { INFO("s25sl12800",  0x012018, 0x0300, 256 << 10,  64, 0) },
     { INFO("s25sl12801",  0x012018, 0x0301,  64 << 10, 256, 0) },
@@ -189,6 +191,9 @@  static const FlashPartInfo known_devices[] = {
     { INFO("s25fl016k",   0xef4015,      0,  64 << 10,  32, ER_4K | ER_32K) },
     { INFO("s25fl064k",   0xef4017,      0,  64 << 10, 128, ER_4K | ER_32K) },
 
+    /* Spansion --  boot sectors support  */
+    { INFO6("s25fs512s",    0x010220, 0x4d0081, 256 << 10, 256, 0) },
+
     /* SST -- large erase sizes are "overlays", "sectors" are 4<< 10 */
     { INFO("sst25vf040b", 0xbf258d,      0,  64 << 10,   8, ER_4K) },
     { INFO("sst25vf080b", 0xbf258e,      0,  64 << 10,  16, ER_4K) },
@@ -283,6 +288,12 @@  typedef enum {
     RESET_ENABLE = 0x66,
     RESET_MEMORY = 0x99,
 
+    /*
+     * Micron: 0x35 - enable QPI
+     * Spansion: 0x35 - read control register
+     */
+    RDCR_QPIEN = 0x35,
+
 } FlashCMD;
 
 typedef enum {
@@ -509,6 +520,16 @@  static void complete_collecting_data(Flash *s)
         flash_erase(s, s->cur_addr, s->cmd_in_progress);
         break;
     case WRSR:
+        switch (s->pi->id[0]) {
+        case JEDEC_SPANSION:
+            s->quad_enable = !!(s->data[1] & 0x02);
+            break;
+        case JEDEC_MACRONIX:
+            s->quad_enable = !!(s->data[0] & 0x40);
+            break;
+        default:
+            break;
+        }
         if (s->write_enable) {
             s->write_enable = false;
         }
@@ -610,7 +631,19 @@  static void decode_new_cmd(Flash *s, uint32_t value)
         break;
     case WRSR:
         if (s->write_enable) {
-            s->needed_bytes = 1;
+            switch (s->pi->id[0]) {
+            case JEDEC_SPANSION:
+            /* FIXME:
+             * needed_bytes fixed to 2 because Spansion
+             * supports access to 2nd register
+             * in one WRSR command and Linux is using it.
+             * Real needed_bytes should depend on CS line.
+             */
+                s->needed_bytes = 2;
+                break;
+            default:
+                s->needed_bytes = 1;
+            }
             s->pos = 0;
             s->len = 0;
             s->state = STATE_COLLECTING_DATA;
@@ -626,6 +659,9 @@  static void decode_new_cmd(Flash *s, uint32_t value)
 
     case RDSR:
         s->data[0] = (!!s->write_enable) << 1;
+        if (s->pi->id[0] == JEDEC_MACRONIX) {
+            s->data[0] |= (!!s->quad_enable) << 6;
+        }
         s->pos = 0;
         s->len = 1;
         s->state = STATE_READING_DATA;
@@ -680,6 +716,18 @@  static void decode_new_cmd(Flash *s, uint32_t value)
             reset_memory(s);
         }
         break;
+    case RDCR_QPIEN:
+        switch (s->pi->id[0]) {
+        case JEDEC_SPANSION:
+            s->data[0] = (!!s->quad_enable) << 1;
+            s->pos = 0;
+            s->len = 1;
+            s->state = STATE_READING_DATA;
+            break;
+        default:
+            break;
+        }
+        break;
     default:
         qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
         break;