]> git.proxmox.com Git - qemu.git/blobdiff - hw/xilinx_spips.c
hw: move I2C controllers to hw/i2c/, configure via default-configs/
[qemu.git] / hw / xilinx_spips.c
index 42e019dc057ceaf60735c09e2e44b456152a1773..b2397f4a42496fd382d7c97bb9beb8b363ebd2b6 100644 (file)
  * THE SOFTWARE.
  */
 
-#include "sysbus.h"
+#include "hw/sysbus.h"
 #include "sysemu/sysemu.h"
-#include "ptimer.h"
+#include "hw/ptimer.h"
 #include "qemu/log.h"
-#include "fifo.h"
-#include "ssi.h"
+#include "qemu/fifo8.h"
+#include "hw/ssi.h"
 #include "qemu/bitops.h"
 
 #ifdef XILINX_SPIPS_ERR_DEBUG
 #define SNOOP_NONE 0xFE
 #define SNOOP_STRIPING 0
 
+typedef enum {
+    READ = 0x3,
+    FAST_READ = 0xb,
+    DOR = 0x3b,
+    QOR = 0x6b,
+    DIOR = 0xbb,
+    QIOR = 0xeb,
+
+    PP = 0x2,
+    DPP = 0xa2,
+    QPP = 0x32,
+} FlashCMD;
+
 typedef struct {
     SysBusDevice busdev;
     MemoryRegion iomem;
@@ -141,10 +154,15 @@ typedef struct {
     hwaddr lqspi_cached_addr;
 } XilinxSPIPS;
 
+#define TYPE_XILINX_SPIPS "xilinx,spips"
+
+#define XILINX_SPIPS(obj) \
+     OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS)
+
 static inline int num_effective_busses(XilinxSPIPS *s)
 {
-    return (s->regs[R_LQSPI_STS] & LQSPI_CFG_SEP_BUS &&
-            s->regs[R_LQSPI_STS] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
+    return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
+            s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
 }
 
 static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
@@ -197,7 +215,7 @@ static void xilinx_spips_update_ixr(XilinxSPIPS *s)
 
 static void xilinx_spips_reset(DeviceState *d)
 {
-    XilinxSPIPS *s = DO_UPCAST(XilinxSPIPS, busdev.qdev, d);
+    XilinxSPIPS *s = XILINX_SPIPS(d);
 
     int i;
     for (i = 0; i < R_MAX; i++) {
@@ -251,15 +269,19 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
         switch (s->snoop_state) {
         case (SNOOP_CHECKING):
             switch (tx) { /* new instruction code */
-            case 0x0b: /* dual/quad output read DOR/QOR */
-            case 0x6b:
-                s->snoop_state = 4;
+            case READ: /* 3 address bytes, no dummy bytes/cycles */
+            case PP:
+            case DPP:
+            case QPP:
+                s->snoop_state = 3;
                 break;
-            /* FIXME: these vary between vendor - set to spansion */
-            case 0xbb: /* high performance dual read DIOR */
+            case FAST_READ: /* 3 address bytes, 1 dummy byte */
+            case DOR:
+            case QOR:
+            case DIOR: /* FIXME: these vary between vendor - set to spansion */
                 s->snoop_state = 4;
                 break;
-            case 0xeb: /* high performance quad read QIOR */
+            case QIOR: /* 3 address bytes, 2 dummy bytes */
                 s->snoop_state = 6;
                 break;
             default:
@@ -483,9 +505,10 @@ static const MemoryRegionOps lqspi_ops = {
     }
 };
 
-static int xilinx_spips_init(SysBusDevice *dev)
+static void xilinx_spips_realize(DeviceState *dev, Error **errp)
 {
-    XilinxSPIPS *s = FROM_SYSBUS(typeof(*s), dev);
+    XilinxSPIPS *s = XILINX_SPIPS(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
     int i;
 
     DB_PRINT("inited device model\n");
@@ -494,31 +517,29 @@ static int xilinx_spips_init(SysBusDevice *dev)
     for (i = 0; i < s->num_busses; ++i) {
         char bus_name[16];
         snprintf(bus_name, 16, "spi%d", i);
-        s->spi[i] = ssi_create_bus(&dev->qdev, bus_name);
+        s->spi[i] = ssi_create_bus(dev, bus_name);
     }
 
-    s->cs_lines = g_new(qemu_irq, s->num_cs * s->num_busses);
+    s->cs_lines = g_new0(qemu_irq, s->num_cs * s->num_busses);
     ssi_auto_connect_slaves(DEVICE(s), s->cs_lines, s->spi[0]);
     ssi_auto_connect_slaves(DEVICE(s), s->cs_lines, s->spi[1]);
-    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_irq(sbd, &s->irq);
     for (i = 0; i < s->num_cs * s->num_busses; ++i) {
-        sysbus_init_irq(dev, &s->cs_lines[i]);
+        sysbus_init_irq(sbd, &s->cs_lines[i]);
     }
 
     memory_region_init_io(&s->iomem, &spips_ops, s, "spi", R_MAX*4);
-    sysbus_init_mmio(dev, &s->iomem);
+    sysbus_init_mmio(sbd, &s->iomem);
 
     memory_region_init_io(&s->mmlqspi, &lqspi_ops, s, "lqspi",
                           (1 << LQSPI_ADDRESS_BITS) * 2);
-    sysbus_init_mmio(dev, &s->mmlqspi);
+    sysbus_init_mmio(sbd, &s->mmlqspi);
 
     s->irqline = -1;
     s->lqspi_cached_addr = ~0ULL;
 
     fifo8_create(&s->rx_fifo, RXFF_A);
     fifo8_create(&s->tx_fifo, TXFF_A);
-
-    return 0;
 }
 
 static int xilinx_spips_post_load(void *opaque, int version_id)
@@ -552,16 +573,15 @@ static Property xilinx_spips_properties[] = {
 static void xilinx_spips_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
-    sdc->init = xilinx_spips_init;
+    dc->realize = xilinx_spips_realize;
     dc->reset = xilinx_spips_reset;
     dc->props = xilinx_spips_properties;
     dc->vmsd = &vmstate_xilinx_spips;
 }
 
 static const TypeInfo xilinx_spips_info = {
-    .name  = "xilinx,spips",
+    .name  = TYPE_XILINX_SPIPS,
     .parent = TYPE_SYS_BUS_DEVICE,
     .instance_size  = sizeof(XilinxSPIPS),
     .class_init = xilinx_spips_class_init,