summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Crosthwaite <peter.crosthwaite@xilinx.com>2012-10-15 14:34:37 +1000
committerPeter Crosthwaite <peter.crosthwaite@xilinx.com>2012-10-29 16:38:26 +1000
commit419336a9f934d6a6c7098648bc833137a5db2015 (patch)
treecf1f1d86ad75d144013d5f83b424486434649a18
parent50cd72148211c5e5f22ea2519d19ce024226e61f (diff)
downloadfocaccia-qemu-419336a9f934d6a6c7098648bc833137a5db2015.tar.gz
focaccia-qemu-419336a9f934d6a6c7098648bc833137a5db2015.zip
m25p80: Support for Quad SPI
Added the Quad mode read and write commands. Data remains serialized on a
single wire, i.e. the quad mode instructions just behave the same as single
mode, with the expection of modelling the varying number of dummy/mode bytes
between the address bytes and the first data word.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
-rw-r--r--hw/m25p80.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/hw/m25p80.c b/hw/m25p80.c
index 9a56de8023..3895e73957 100644
--- a/hw/m25p80.c
+++ b/hw/m25p80.c
@@ -72,6 +72,10 @@ typedef struct FlashPartInfo {
     .page_size = 256,\
     .flags = (_flags),\
 
+#define JEDEC_NUMONYX 0x20
+#define JEDEC_WINBOND 0xEF
+#define JEDEC_SPANSION 0x01
+
 static const FlashPartInfo known_devices[] = {
     /* Atmel -- some are (confusingly) marketed as "DataFlash" */
     { INFO("at25fs010",   0x1f6601,      0,  32 << 10,   4, ER_4K) },
@@ -180,17 +184,26 @@ static const FlashPartInfo known_devices[] = {
 
 typedef enum {
     NOP = 0,
-    PP = 0x2,
-    READ = 0x3,
     WRDI = 0x4,
     RDSR = 0x5,
     WREN = 0x6,
+    JEDEC_READ = 0x9f,
+    BULK_ERASE = 0xc7,
+
+    READ = 0x3,
     FAST_READ = 0xb,
+    DOR = 0x3b,
+    QOR = 0x6b,
+    DIOR = 0xbb,
+    QIOR = 0xeb,
+
+    PP = 0x2,
+    DPP = 0xa2,
+    QPP = 0x32,
+
     ERASE_4K = 0x20,
     ERASE_32K = 0x52,
     ERASE_SECTOR = 0xd8,
-    JEDEC_READ = 0x9f,
-    BULK_ERASE = 0xc7,
 } FlashCMD;
 
 typedef enum {
@@ -346,11 +359,17 @@ static void complete_collecting_data(Flash *s)
     s->cur_addr |= s->data[2];
 
     switch (s->cmd_in_progress) {
+    case DPP:
+    case QPP:
     case PP:
         s->state = STATE_PAGE_PROGRAM;
         break;
     case READ:
     case FAST_READ:
+    case DOR:
+    case QOR:
+    case DIOR:
+    case QIOR:
         s->state = STATE_READ;
         break;
     case ERASE_4K:
@@ -374,6 +393,8 @@ static void decode_new_cmd(Flash *s, uint32_t value)
     case ERASE_32K:
     case ERASE_SECTOR:
     case READ:
+    case DPP:
+    case QPP:
     case PP:
         s->needed_bytes = 3;
         s->pos = 0;
@@ -382,12 +403,44 @@ static void decode_new_cmd(Flash *s, uint32_t value)
         break;
 
     case FAST_READ:
+    case DOR:
+    case QOR:
         s->needed_bytes = 4;
         s->pos = 0;
         s->len = 0;
         s->state = STATE_COLLECTING_DATA;
         break;
 
+    case DIOR:
+        switch ((s->pi->jedec >> 16) & 0xFF) {
+        case JEDEC_WINBOND:
+        case JEDEC_SPANSION:
+            s->needed_bytes = 4;
+            break;
+        case JEDEC_NUMONYX:
+        default:
+            s->needed_bytes = 5;
+        }
+        s->pos = 0;
+        s->len = 0;
+        s->state = STATE_COLLECTING_DATA;
+        break;
+
+    case QIOR:
+        switch ((s->pi->jedec >> 16) & 0xFF) {
+        case JEDEC_WINBOND:
+        case JEDEC_SPANSION:
+            s->needed_bytes = 6;
+            break;
+        case JEDEC_NUMONYX:
+        default:
+            s->needed_bytes = 8;
+        }
+        s->pos = 0;
+        s->len = 0;
+        s->state = STATE_COLLECTING_DATA;
+        break;
+
     case WRDI:
         s->write_enable = false;
         break;