xref: /qemu/hw/ssi/xilinx_spi.c (revision b14d0649628cbe88ac0ef35fcf58cd1fc22735b8)
1  /*
2   * QEMU model of the Xilinx SPI Controller
3   *
4   * Copyright (C) 2010 Edgar E. Iglesias.
5   * Copyright (C) 2012 Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
6   * Copyright (C) 2012 PetaLogix
7   *
8   * Permission is hereby granted, free of charge, to any person obtaining a copy
9   * of this software and associated documentation files (the "Software"), to deal
10   * in the Software without restriction, including without limitation the rights
11   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12   * copies of the Software, and to permit persons to whom the Software is
13   * furnished to do so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in
16   * all copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21   * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24   * THE SOFTWARE.
25   */
26  
27  #include "qemu/osdep.h"
28  #include "hw/sysbus.h"
29  #include "migration/vmstate.h"
30  #include "qemu/module.h"
31  #include "qemu/fifo8.h"
32  
33  #include "hw/irq.h"
34  #include "hw/qdev-properties.h"
35  #include "hw/ssi/ssi.h"
36  #include "qom/object.h"
37  
38  #ifdef XILINX_SPI_ERR_DEBUG
39  #define DB_PRINT(...) do { \
40      fprintf(stderr,  ": %s: ", __func__); \
41      fprintf(stderr, ## __VA_ARGS__); \
42      } while (0)
43  #else
44      #define DB_PRINT(...)
45  #endif
46  
47  #define R_DGIER     (0x1c / 4)
48  #define R_DGIER_IE  (1 << 31)
49  
50  #define R_IPISR     (0x20 / 4)
51  #define IRQ_DRR_NOT_EMPTY    (1 << (31 - 23))
52  #define IRQ_DRR_OVERRUN      (1 << (31 - 26))
53  #define IRQ_DRR_FULL         (1 << (31 - 27))
54  #define IRQ_TX_FF_HALF_EMPTY (1 << 6)
55  #define IRQ_DTR_UNDERRUN     (1 << 3)
56  #define IRQ_DTR_EMPTY        (1 << (31 - 29))
57  
58  #define R_IPIER     (0x28 / 4)
59  #define R_SRR       (0x40 / 4)
60  #define R_SPICR     (0x60 / 4)
61  #define R_SPICR_TXFF_RST     (1 << 5)
62  #define R_SPICR_RXFF_RST     (1 << 6)
63  #define R_SPICR_MTI          (1 << 8)
64  
65  #define R_SPISR     (0x64 / 4)
66  #define SR_TX_FULL    (1 << 3)
67  #define SR_TX_EMPTY   (1 << 2)
68  #define SR_RX_FULL    (1 << 1)
69  #define SR_RX_EMPTY   (1 << 0)
70  
71  #define R_SPIDTR    (0x68 / 4)
72  #define R_SPIDRR    (0x6C / 4)
73  #define R_SPISSR    (0x70 / 4)
74  #define R_TX_FF_OCY (0x74 / 4)
75  #define R_RX_FF_OCY (0x78 / 4)
76  #define R_MAX       (0x7C / 4)
77  
78  #define FIFO_CAPACITY 256
79  
80  #define TYPE_XILINX_SPI "xlnx.xps-spi"
81  OBJECT_DECLARE_SIMPLE_TYPE(XilinxSPI, XILINX_SPI)
82  
83  struct XilinxSPI {
84      SysBusDevice parent_obj;
85  
86      MemoryRegion mmio;
87  
88      qemu_irq irq;
89      int irqline;
90  
91      uint8_t num_cs;
92      qemu_irq *cs_lines;
93  
94      SSIBus *spi;
95  
96      Fifo8 rx_fifo;
97      Fifo8 tx_fifo;
98  
99      uint32_t regs[R_MAX];
100  };
101  
102  static void txfifo_reset(XilinxSPI *s)
103  {
104      fifo8_reset(&s->tx_fifo);
105  
106      s->regs[R_SPISR] &= ~SR_TX_FULL;
107      s->regs[R_SPISR] |= SR_TX_EMPTY;
108  }
109  
110  static void rxfifo_reset(XilinxSPI *s)
111  {
112      fifo8_reset(&s->rx_fifo);
113  
114      s->regs[R_SPISR] |= SR_RX_EMPTY;
115      s->regs[R_SPISR] &= ~SR_RX_FULL;
116  }
117  
118  static void xlx_spi_update_cs(XilinxSPI *s)
119  {
120      int i;
121  
122      for (i = 0; i < s->num_cs; ++i) {
123          qemu_set_irq(s->cs_lines[i], !(~s->regs[R_SPISSR] & 1 << i));
124      }
125  }
126  
127  static void xlx_spi_update_irq(XilinxSPI *s)
128  {
129      uint32_t pending;
130  
131      s->regs[R_IPISR] |=
132              (!fifo8_is_empty(&s->rx_fifo) ? IRQ_DRR_NOT_EMPTY : 0) |
133              (fifo8_is_full(&s->rx_fifo) ? IRQ_DRR_FULL : 0);
134  
135      pending = s->regs[R_IPISR] & s->regs[R_IPIER];
136  
137      pending = pending && (s->regs[R_DGIER] & R_DGIER_IE);
138      pending = !!pending;
139  
140      /* This call lies right in the data paths so don't call the
141         irq chain unless things really changed.  */
142      if (pending != s->irqline) {
143          s->irqline = pending;
144          DB_PRINT("irq_change of state %u ISR:%x IER:%X\n",
145                      pending, s->regs[R_IPISR], s->regs[R_IPIER]);
146          qemu_set_irq(s->irq, pending);
147      }
148  
149  }
150  
151  static void xlx_spi_do_reset(XilinxSPI *s)
152  {
153      memset(s->regs, 0, sizeof s->regs);
154  
155      rxfifo_reset(s);
156      txfifo_reset(s);
157  
158      s->regs[R_SPISSR] = ~0;
159      s->regs[R_SPICR] = R_SPICR_MTI;
160      xlx_spi_update_irq(s);
161      xlx_spi_update_cs(s);
162  }
163  
164  static void xlx_spi_reset(DeviceState *d)
165  {
166      xlx_spi_do_reset(XILINX_SPI(d));
167  }
168  
169  static inline int spi_master_enabled(XilinxSPI *s)
170  {
171      return !(s->regs[R_SPICR] & R_SPICR_MTI);
172  }
173  
174  static void spi_flush_txfifo(XilinxSPI *s)
175  {
176      uint32_t tx;
177      uint32_t rx;
178  
179      while (!fifo8_is_empty(&s->tx_fifo)) {
180          tx = (uint32_t)fifo8_pop(&s->tx_fifo);
181          DB_PRINT("data tx:%x\n", tx);
182          rx = ssi_transfer(s->spi, tx);
183          DB_PRINT("data rx:%x\n", rx);
184          if (fifo8_is_full(&s->rx_fifo)) {
185              s->regs[R_IPISR] |= IRQ_DRR_OVERRUN;
186          } else {
187              fifo8_push(&s->rx_fifo, (uint8_t)rx);
188              if (fifo8_is_full(&s->rx_fifo)) {
189                  s->regs[R_SPISR] |= SR_RX_FULL;
190                  s->regs[R_IPISR] |= IRQ_DRR_FULL;
191              }
192          }
193  
194          s->regs[R_SPISR] &= ~SR_RX_EMPTY;
195          s->regs[R_SPISR] &= ~SR_TX_FULL;
196          s->regs[R_SPISR] |= SR_TX_EMPTY;
197  
198          s->regs[R_IPISR] |= IRQ_DTR_EMPTY;
199          s->regs[R_IPISR] |= IRQ_DRR_NOT_EMPTY;
200      }
201  
202  }
203  
204  static uint64_t
205  spi_read(void *opaque, hwaddr addr, unsigned int size)
206  {
207      XilinxSPI *s = opaque;
208      uint32_t r = 0;
209  
210      addr >>= 2;
211      switch (addr) {
212      case R_SPIDRR:
213          if (fifo8_is_empty(&s->rx_fifo)) {
214              DB_PRINT("Read from empty FIFO!\n");
215              return 0xdeadbeef;
216          }
217  
218          s->regs[R_SPISR] &= ~SR_RX_FULL;
219          r = fifo8_pop(&s->rx_fifo);
220          if (fifo8_is_empty(&s->rx_fifo)) {
221              s->regs[R_SPISR] |= SR_RX_EMPTY;
222          }
223          break;
224  
225      case R_SPISR:
226          r = s->regs[addr];
227          break;
228  
229      default:
230          if (addr < ARRAY_SIZE(s->regs)) {
231              r = s->regs[addr];
232          }
233          break;
234  
235      }
236      DB_PRINT("addr=" HWADDR_FMT_plx " = %x\n", addr * 4, r);
237      xlx_spi_update_irq(s);
238      return r;
239  }
240  
241  static void
242  spi_write(void *opaque, hwaddr addr,
243              uint64_t val64, unsigned int size)
244  {
245      XilinxSPI *s = opaque;
246      uint32_t value = val64;
247  
248      DB_PRINT("addr=" HWADDR_FMT_plx " = %x\n", addr, value);
249      addr >>= 2;
250      switch (addr) {
251      case R_SRR:
252          if (value != 0xa) {
253              DB_PRINT("Invalid write to SRR %x\n", value);
254          } else {
255              xlx_spi_do_reset(s);
256          }
257          break;
258  
259      case R_SPIDTR:
260          s->regs[R_SPISR] &= ~SR_TX_EMPTY;
261          fifo8_push(&s->tx_fifo, (uint8_t)value);
262          if (fifo8_is_full(&s->tx_fifo)) {
263              s->regs[R_SPISR] |= SR_TX_FULL;
264          }
265          if (!spi_master_enabled(s)) {
266              goto done;
267          } else {
268              DB_PRINT("DTR and master enabled\n");
269          }
270          spi_flush_txfifo(s);
271          break;
272  
273      case R_SPISR:
274          DB_PRINT("Invalid write to SPISR %x\n", value);
275          break;
276  
277      case R_IPISR:
278          /* Toggle the bits.  */
279          s->regs[addr] ^= value;
280          break;
281  
282      /* Slave Select Register.  */
283      case R_SPISSR:
284          s->regs[addr] = value;
285          xlx_spi_update_cs(s);
286          break;
287  
288      case R_SPICR:
289          /* FIXME: reset irq and sr state to empty queues.  */
290          if (value & R_SPICR_RXFF_RST) {
291              rxfifo_reset(s);
292          }
293  
294          if (value & R_SPICR_TXFF_RST) {
295              txfifo_reset(s);
296          }
297          value &= ~(R_SPICR_RXFF_RST | R_SPICR_TXFF_RST);
298          s->regs[addr] = value;
299  
300          if (!(value & R_SPICR_MTI)) {
301              spi_flush_txfifo(s);
302          }
303          break;
304  
305      default:
306          if (addr < ARRAY_SIZE(s->regs)) {
307              s->regs[addr] = value;
308          }
309          break;
310      }
311  
312  done:
313      xlx_spi_update_irq(s);
314  }
315  
316  static const MemoryRegionOps spi_ops = {
317      .read = spi_read,
318      .write = spi_write,
319      .endianness = DEVICE_NATIVE_ENDIAN,
320      .valid = {
321          .min_access_size = 4,
322          .max_access_size = 4
323      }
324  };
325  
326  static void xilinx_spi_realize(DeviceState *dev, Error **errp)
327  {
328      SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
329      XilinxSPI *s = XILINX_SPI(dev);
330      int i;
331  
332      DB_PRINT("\n");
333  
334      s->spi = ssi_create_bus(dev, "spi");
335  
336      sysbus_init_irq(sbd, &s->irq);
337      s->cs_lines = g_new0(qemu_irq, s->num_cs);
338      for (i = 0; i < s->num_cs; ++i) {
339          sysbus_init_irq(sbd, &s->cs_lines[i]);
340      }
341  
342      memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
343                            "xilinx-spi", R_MAX * 4);
344      sysbus_init_mmio(sbd, &s->mmio);
345  
346      s->irqline = -1;
347  
348      fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
349      fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
350  }
351  
352  static const VMStateDescription vmstate_xilinx_spi = {
353      .name = "xilinx_spi",
354      .version_id = 1,
355      .minimum_version_id = 1,
356      .fields = (const VMStateField[]) {
357          VMSTATE_FIFO8(tx_fifo, XilinxSPI),
358          VMSTATE_FIFO8(rx_fifo, XilinxSPI),
359          VMSTATE_UINT32_ARRAY(regs, XilinxSPI, R_MAX),
360          VMSTATE_END_OF_LIST()
361      }
362  };
363  
364  static Property xilinx_spi_properties[] = {
365      DEFINE_PROP_UINT8("num-ss-bits", XilinxSPI, num_cs, 1),
366      DEFINE_PROP_END_OF_LIST(),
367  };
368  
369  static void xilinx_spi_class_init(ObjectClass *klass, void *data)
370  {
371      DeviceClass *dc = DEVICE_CLASS(klass);
372  
373      dc->realize = xilinx_spi_realize;
374      device_class_set_legacy_reset(dc, xlx_spi_reset);
375      device_class_set_props(dc, xilinx_spi_properties);
376      dc->vmsd = &vmstate_xilinx_spi;
377  }
378  
379  static const TypeInfo xilinx_spi_info = {
380      .name           = TYPE_XILINX_SPI,
381      .parent         = TYPE_SYS_BUS_DEVICE,
382      .instance_size  = sizeof(XilinxSPI),
383      .class_init     = xilinx_spi_class_init,
384  };
385  
386  static void xilinx_spi_register_types(void)
387  {
388      type_register_static(&xilinx_spi_info);
389  }
390  
391  type_init(xilinx_spi_register_types)
392