summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Crosthwaite <peter.crosthwaite@xilinx.com>2013-06-03 17:17:42 +0100
committerPeter Maydell <peter.maydell@linaro.org>2013-06-03 17:17:42 +0100
commitb5cd9143e78da8ea9e17fa523aacbedd267aae54 (patch)
tree38c34f524902b7c0e1f50c5bd6df450dd03454ae /hw
parent10e60b35d04359fba1d759925018204527a1b9f5 (diff)
xilinx_spips: Trash LQ page cache on mode change
Invalidate the LQSPI cached page when transitioning into LQSPI mode. Otherwise there is a possibility that the controller will return stale data to the guest when transitioning back to LQ_MODE after a page program. Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@gmail.com> Message-id: 677490a6ee1953fe5d366e599d665de645ac84db.1369117359.git.peter.crosthwaite@xilinx.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/ssi/xilinx_spips.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 86f33ef1f5..cf4c43e81d 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -165,6 +165,8 @@ typedef struct {
typedef struct XilinxSPIPSClass {
SysBusDeviceClass parent_class;
+ const MemoryRegionOps *reg_ops;
+
uint32_t rx_fifo_size;
uint32_t tx_fifo_size;
} XilinxSPIPSClass;
@@ -462,6 +464,25 @@ static const MemoryRegionOps spips_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
+static void xilinx_qspips_write(void *opaque, hwaddr addr,
+ uint64_t value, unsigned size)
+{
+ XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
+
+ xilinx_spips_write(opaque, addr, value, size);
+ addr >>= 2;
+
+ if (addr == R_LQSPI_CFG) {
+ q->lqspi_cached_addr = ~0ULL;
+ }
+}
+
+static const MemoryRegionOps qspips_ops = {
+ .read = xilinx_spips_read,
+ .write = xilinx_qspips_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
#define LQSPI_CACHE_SIZE 1024
static uint64_t
@@ -565,7 +586,7 @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(sbd, &s->cs_lines[i]);
}
- memory_region_init_io(&s->iomem, &spips_ops, s, "spi", R_MAX*4);
+ memory_region_init_io(&s->iomem, xsc->reg_ops, s, "spi", R_MAX*4);
sysbus_init_mmio(sbd, &s->iomem);
s->irqline = -1;
@@ -629,6 +650,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
dc->realize = xilinx_qspips_realize;
+ xsc->reg_ops = &qspips_ops;
xsc->rx_fifo_size = RXFF_A_Q;
xsc->tx_fifo_size = TXFF_A_Q;
}
@@ -643,6 +665,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
dc->props = xilinx_spips_properties;
dc->vmsd = &vmstate_xilinx_spips;
+ xsc->reg_ops = &spips_ops;
xsc->rx_fifo_size = RXFF_A;
xsc->tx_fifo_size = TXFF_A;
}