Patchwork [for-1.5,v3,08/15] xilinx_spips: Implement automatic CS

login
register
mail settings
Submitter Peter Crosthwaite
Date April 22, 2013, 5:16 a.m.
Message ID <325c8316b51c4c0d7835bea7adf87df40337abf3.1366606958.git.peter.crosthwaite@xilinx.com>
Download mbox | patch
Permalink /patch/238327/
State New
Headers show

Comments

Peter Crosthwaite - April 22, 2013, 5:16 a.m.
From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

Implement the automatic CS control feature. If the MANUAL_CS bit is
cleared then the chip select stay de-asserted as long as the tx FIFO
is empty.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
changed from v1:
Refresh CS on entry and exit from flush routine as needed.

 hw/ssi/xilinx_spips.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)
Peter Maydell - April 29, 2013, 12:14 p.m.
On 22 April 2013 06:16,  <peter.crosthwaite@xilinx.com> wrote:
> From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>
> Implement the automatic CS control feature. If the MANUAL_CS bit is
> cleared then the chip select stay de-asserted as long as the tx FIFO
> is empty.
>
> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

Doesn't compile:

hw/ssi/xilinx_spips.c: In function ‘xilinx_spips_update_cs_lines’:
hw/ssi/xilinx_spips.c:215:17: error: implicit declaration of function
‘DB_PRINT_L’ [-Werror=implicit-function-declaration]
hw/ssi/xilinx_spips.c:215:17: error: nested extern declaration of
‘DB_PRINT_L’ [-Werror=nested-externs]
cc1: all warnings being treated as errors

(you don't introduce that macro until later).

-- PMM
Peter Crosthwaite - April 30, 2013, 12:29 a.m.
Hi Peter,

On Mon, Apr 29, 2013 at 10:14 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> On 22 April 2013 06:16,  <peter.crosthwaite@xilinx.com> wrote:
>> From: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>>
>> Implement the automatic CS control feature. If the MANUAL_CS bit is
>> cleared then the chip select stay de-asserted as long as the tx FIFO
>> is empty.
>>
>> Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
>> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
>
> Doesn't compile:
>
> hw/ssi/xilinx_spips.c: In function ‘xilinx_spips_update_cs_lines’:
> hw/ssi/xilinx_spips.c:215:17: error: implicit declaration of function
> ‘DB_PRINT_L’ [-Werror=implicit-function-declaration]
> hw/ssi/xilinx_spips.c:215:17: error: nested extern declaration of
> ‘DB_PRINT_L’ [-Werror=nested-externs]
> cc1: all warnings being treated as errors
>
> (you don't introduce that macro until later).
>

Nice catch. Thanks. I have now added individual patch compile testing
to my format-patch wrapper script to catch these. Will fix.

Regards,
Peter

> -- PMM
>

Patch

diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index 5580e67..3f31a32 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -190,6 +190,12 @@  static inline int num_effective_busses(XilinxSPIPS *s)
             s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
 }
 
+static inline bool xilinx_spips_cs_is_set(XilinxSPIPS *s, int i, int field)
+{
+    return ~field & (1 << i) && (s->regs[R_CONFIG] & MANUAL_CS
+                    || !fifo8_is_empty(&s->tx_fifo));
+}
+
 static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
 {
     int i, j;
@@ -202,14 +208,15 @@  static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
             int cs_to_set = (j * s->num_cs + i + upage) %
                                 (s->num_cs * s->num_busses);
 
-            if (~field & (1 << i) && !found) {
+            if (xilinx_spips_cs_is_set(s, i, field) && !found) {
                 DB_PRINT("selecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 0);
             } else {
+                DB_PRINT_L(0, "deselecting slave %d\n", i);
                 qemu_set_irq(s->cs_lines[cs_to_set], 1);
             }
         }
-        if (~field & (1 << i)) {
+        if (xilinx_spips_cs_is_set(s, i, field)) {
             found = true;
         }
     }
@@ -451,12 +458,13 @@  static void xilinx_spips_write(void *opaque, hwaddr addr,
     }
     s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
 no_reg_update:
+    xilinx_spips_update_cs_lines(s);
     if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
             (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
         xilinx_spips_flush_txfifo(s);
     }
-    xilinx_spips_update_ixr(s);
     xilinx_spips_update_cs_lines(s);
+    xilinx_spips_update_ixr(s);
 }
 
 static const MemoryRegionOps spips_ops = {
@@ -510,7 +518,7 @@  lqspi_read(void *opaque, hwaddr addr, unsigned int size)
         fifo8_reset(&s->rx_fifo);
 
         s->regs[R_CONFIG] &= ~CS;
-        s->regs[R_CONFIG] |= (~(1 << slave) << CS_SHIFT) & CS;
+        s->regs[R_CONFIG] |= ((~(1 << slave) << CS_SHIFT) & CS) | MANUAL_CS;
         xilinx_spips_update_cs_lines(s);
 
         /* instruction */
@@ -534,6 +542,7 @@  lqspi_read(void *opaque, hwaddr addr, unsigned int size)
             DB_PRINT("pushing dummy byte\n");
             fifo8_push(&s->tx_fifo, 0);
         }
+        xilinx_spips_update_cs_lines(s);
         xilinx_spips_flush_txfifo(s);
         fifo8_reset(&s->rx_fifo);
 
@@ -545,6 +554,7 @@  lqspi_read(void *opaque, hwaddr addr, unsigned int size)
             rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4);
             cache_entry++;
         }
+        xilinx_spips_update_cs_lines(s);
 
         s->regs[R_CONFIG] |= CS;
         xilinx_spips_update_cs_lines(s);