Message ID | 0890ab958dbecc05faeae7bcdb4a5051f0625875.1366335998.git.peter.crosthwaite@xilinx.com |
---|---|
State | New |
Headers | show |
On 19 April 2013 03:06, <peter.crosthwaite@xilinx.com> wrote: > From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> > > 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> > --- > changed from v1: > Re-implemented using separate SPI/QSPI write handlers. > > hw/ssi/xilinx_spips.c | 26 +++++++++++++++++++++++++- > 1 files changed, 25 insertions(+), 1 deletions(-) > > diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c > index e351cb2..6d38111 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; > @@ -446,6 +448,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr, > case R_TXD3: > tx_data_bytes(s, (uint32_t)value, 3); > goto no_reg_update; > + break; Why insert code after a goto? > } > s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); > no_reg_update: -- PMM
On Fri, Apr 19, 2013 at 8:23 PM, Peter Maydell <peter.maydell@linaro.org> wrote: > On 19 April 2013 03:06, <peter.crosthwaite@xilinx.com> wrote: >> From: Peter Crosthwaite <peter.crosthwaite@xilinx.com> >> >> 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> >> --- >> changed from v1: >> Re-implemented using separate SPI/QSPI write handlers. >> >> hw/ssi/xilinx_spips.c | 26 +++++++++++++++++++++++++- >> 1 files changed, 25 insertions(+), 1 deletions(-) >> >> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c >> index e351cb2..6d38111 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; >> @@ -446,6 +448,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr, >> case R_TXD3: >> tx_data_bytes(s, (uint32_t)value, 3); >> goto no_reg_update; >> + break; > > Why insert code after a goto? > Removed. Thanks, Peter >> } >> s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); >> no_reg_update: > > -- PMM >
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index e351cb2..6d38111 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; @@ -446,6 +448,7 @@ static void xilinx_spips_write(void *opaque, hwaddr addr, case R_TXD3: tx_data_bytes(s, (uint32_t)value, 3); goto no_reg_update; + break; } s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); no_reg_update: @@ -462,6 +465,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 +587,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 +651,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 +666,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; }