Hi Francisco,

On 11/26/2017 08:16 PM, Francisco Iglesias wrote:
> Make tx/rx_data_bytes more generic so they can be reused (when adding
> support for the Zynqmp Generic QSPI).
> 
> Signed-off-by: Francisco Iglesias <frasse.igles...@gmail.com>
> Reviewed-by: Edgar E. Iglesias <edgar.igles...@xilinx.com>
> Tested-by: Edgar E. Iglesias <edgar.igles...@xilinx.com>
> ---
>  hw/ssi/xilinx_spips.c | 64 
> +++++++++++++++++++++++++++++----------------------
>  1 file changed, 37 insertions(+), 27 deletions(-)
> 
> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
> index 691d48d..4621dbb 100644
> --- a/hw/ssi/xilinx_spips.c
> +++ b/hw/ssi/xilinx_spips.c
> @@ -47,7 +47,7 @@
>  /* config register */
>  #define R_CONFIG            (0x00 / 4)
>  #define IFMODE              (1U << 31)
> -#define ENDIAN              (1 << 26)
> +#define R_CONFIG_ENDIAN     (1 << 26)
>  #define MODEFAIL_GEN_EN     (1 << 17)
>  #define MAN_START_COM       (1 << 16)
>  #define MAN_START_EN        (1 << 15)
> @@ -450,13 +450,28 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
>      }
>  }
>  
> -static inline void rx_data_bytes(XilinxSPIPS *s, uint8_t *value, int max)
> +static inline void tx_data_bytes(Fifo8 *fifo, uint32_t value, int num, bool 
> be)
>  {
>      int i;
> +    for (i = 0; i < num && !fifo8_is_full(fifo); ++i) {
> +        if (be) {
> +            fifo8_push(fifo, (uint8_t)(value >> 24));
> +            value <<= 8;
> +        } else {
> +            fifo8_push(fifo, (uint8_t)value);
> +            value >>= 8;
> +        }
> +    }
> +}
>  
> -    for (i = 0; i < max && !fifo8_is_empty(&s->rx_fifo); ++i) {
> -        value[i] = fifo8_pop(&s->rx_fifo);
> +static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
> +{
> +    int i;
> +
> +    for (i = 0; i < max && !fifo8_is_empty(fifo); ++i) {
> +        value[i] = fifo8_pop(fifo);
>      }
> +    return max - i;
>  }
>  
>  static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
> @@ -466,6 +481,7 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr 
> addr,
>      uint32_t mask = ~0;
>      uint32_t ret;
>      uint8_t rx_buf[4];
> +    int shortfall;
>  
>      addr >>= 2;
>      switch (addr) {
> @@ -496,9 +512,13 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr 
> addr,
>          break;
>      case R_RX_DATA:
>          memset(rx_buf, 0, sizeof(rx_buf));
> -        rx_data_bytes(s, rx_buf, s->num_txrx_bytes);
> -        ret = s->regs[R_CONFIG] & ENDIAN ? cpu_to_be32(*(uint32_t *)rx_buf)
> -                        : cpu_to_le32(*(uint32_t *)rx_buf);
> +        shortfall = rx_data_bytes(&s->rx_fifo, rx_buf, s->num_txrx_bytes);

About this part,

> +        ret = s->regs[R_CONFIG] & R_CONFIG_ENDIAN ?
> +                        cpu_to_be32(*(uint32_t *)rx_buf) :
> +                        cpu_to_le32(*(uint32_t *)rx_buf);
> +        if (!(s->regs[R_CONFIG] & R_CONFIG_ENDIAN)) {
> +            ret <<= 8 * shortfall;
> +        }

The following looks easier to read to me, probably matter of taste, but
you don't have to wonder the cpu <-> device direction and it remove the
casts:

           if (s->regs[R_CONFIG] & R_CONFIG_ENDIAN) {
               ret = ldl_be_p(rx_buf);
           } else {
               ret = ldl_le_p(rx_buf) << (8 * shortfall);
           }

What do you think? (before respining)

>          DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
>          xilinx_spips_update_ixr(s);
>          return ret;
> @@ -509,20 +529,6 @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr 
> addr,
>  
>  }
>  
> -static inline void tx_data_bytes(XilinxSPIPS *s, uint32_t value, int num)
> -{
> -    int i;
> -    for (i = 0; i < num && !fifo8_is_full(&s->tx_fifo); ++i) {
> -        if (s->regs[R_CONFIG] & ENDIAN) {
> -            fifo8_push(&s->tx_fifo, (uint8_t)(value >> 24));
> -            value <<= 8;
> -        } else {
> -            fifo8_push(&s->tx_fifo, (uint8_t)value);
> -            value >>= 8;
> -        }
> -    }
> -}
> -
>  static void xilinx_spips_write(void *opaque, hwaddr addr,
>                                          uint64_t value, unsigned size)
>  {
> @@ -563,16 +569,20 @@ static void xilinx_spips_write(void *opaque, hwaddr 
> addr,
>          mask = 0;
>          break;
>      case R_TX_DATA:
> -        tx_data_bytes(s, (uint32_t)value, s->num_txrx_bytes);
> +        tx_data_bytes(&s->tx_fifo, (uint32_t)value, s->num_txrx_bytes,
> +                      s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
>          goto no_reg_update;
>      case R_TXD1:
> -        tx_data_bytes(s, (uint32_t)value, 1);
> +        tx_data_bytes(&s->tx_fifo, (uint32_t)value, 1,
> +                      s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
>          goto no_reg_update;
>      case R_TXD2:
> -        tx_data_bytes(s, (uint32_t)value, 2);
> +        tx_data_bytes(&s->tx_fifo, (uint32_t)value, 2,
> +                      s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
>          goto no_reg_update;
>      case R_TXD3:
> -        tx_data_bytes(s, (uint32_t)value, 3);
> +        tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3,
> +                      s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
>          goto no_reg_update;
>      }
>      s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
> @@ -682,11 +692,11 @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
>  
>          while (cache_entry < LQSPI_CACHE_SIZE) {
>              for (i = 0; i < 64; ++i) {
> -                tx_data_bytes(s, 0, 1);
> +                tx_data_bytes(&s->tx_fifo, 0, 1, false);
>              }
>              xilinx_spips_flush_txfifo(s);
>              for (i = 0; i < 64; ++i) {
> -                rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 1);
> +                rx_data_bytes(&s->rx_fifo, &q->lqspi_buf[cache_entry++], 1);
>              }
>          }
>  
> 

Reply via email to