summaryrefslogtreecommitdiffstats
path: root/hw/xilinx_spips.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xilinx_spips.c')
-rw-r--r--hw/xilinx_spips.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/hw/xilinx_spips.c b/hw/xilinx_spips.c
index 6c21b9668b..b2397f4a42 100644
--- a/hw/xilinx_spips.c
+++ b/hw/xilinx_spips.c
@@ -115,6 +115,19 @@
#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,