xref: /openbmc/qemu/hw/ssi/imx_spi.c (revision daa76aa416b1e18ab1fac650ff53d966d8f21f68)
1  /*
2   * IMX SPI Controller
3   *
4   * Copyright (c) 2016 Jean-Christophe Dubois <jcd@tribudubois.net>
5   *
6   * This work is licensed under the terms of the GNU GPL, version 2 or later.
7   * See the COPYING file in the top-level directory.
8   *
9   */
10  
11  #include "qemu/osdep.h"
12  #include "hw/ssi/imx_spi.h"
13  #include "sysemu/sysemu.h"
14  #include "qemu/log.h"
15  
16  #ifndef DEBUG_IMX_SPI
17  #define DEBUG_IMX_SPI 0
18  #endif
19  
20  #define DPRINTF(fmt, args...) \
21      do { \
22          if (DEBUG_IMX_SPI) { \
23              fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_SPI, \
24                                               __func__, ##args); \
25          } \
26      } while (0)
27  
28  static char const *imx_spi_reg_name(uint32_t reg)
29  {
30      static char unknown[20];
31  
32      switch (reg) {
33      case ECSPI_RXDATA:
34          return  "ECSPI_RXDATA";
35      case ECSPI_TXDATA:
36          return  "ECSPI_TXDATA";
37      case ECSPI_CONREG:
38          return  "ECSPI_CONREG";
39      case ECSPI_CONFIGREG:
40          return  "ECSPI_CONFIGREG";
41      case ECSPI_INTREG:
42          return  "ECSPI_INTREG";
43      case ECSPI_DMAREG:
44          return  "ECSPI_DMAREG";
45      case ECSPI_STATREG:
46          return  "ECSPI_STATREG";
47      case ECSPI_PERIODREG:
48          return  "ECSPI_PERIODREG";
49      case ECSPI_TESTREG:
50          return  "ECSPI_TESTREG";
51      case ECSPI_MSGDATA:
52          return  "ECSPI_MSGDATA";
53      default:
54          sprintf(unknown, "%d ?", reg);
55          return unknown;
56      }
57  }
58  
59  static const VMStateDescription vmstate_imx_spi = {
60      .name = TYPE_IMX_SPI,
61      .version_id = 1,
62      .minimum_version_id = 1,
63      .fields = (VMStateField[]) {
64          VMSTATE_FIFO32(tx_fifo, IMXSPIState),
65          VMSTATE_FIFO32(rx_fifo, IMXSPIState),
66          VMSTATE_INT16(burst_length, IMXSPIState),
67          VMSTATE_UINT32_ARRAY(regs, IMXSPIState, ECSPI_MAX),
68          VMSTATE_END_OF_LIST()
69      },
70  };
71  
72  static void imx_spi_txfifo_reset(IMXSPIState *s)
73  {
74      fifo32_reset(&s->tx_fifo);
75      s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
76      s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
77  }
78  
79  static void imx_spi_rxfifo_reset(IMXSPIState *s)
80  {
81      fifo32_reset(&s->rx_fifo);
82      s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
83      s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
84      s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RO;
85  }
86  
87  static void imx_spi_update_irq(IMXSPIState *s)
88  {
89      int level;
90  
91      if (fifo32_is_empty(&s->rx_fifo)) {
92          s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RR;
93      } else {
94          s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RR;
95      }
96  
97      if (fifo32_is_full(&s->rx_fifo)) {
98          s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RF;
99      } else {
100          s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_RF;
101      }
102  
103      if (fifo32_is_empty(&s->tx_fifo)) {
104          s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TE;
105      } else {
106          s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TE;
107      }
108  
109      if (fifo32_is_full(&s->tx_fifo)) {
110          s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TF;
111      } else {
112          s->regs[ECSPI_STATREG] &= ~ECSPI_STATREG_TF;
113      }
114  
115      level = s->regs[ECSPI_STATREG] & s->regs[ECSPI_INTREG] ? 1 : 0;
116  
117      qemu_set_irq(s->irq, level);
118  
119      DPRINTF("IRQ level is %d\n", level);
120  }
121  
122  static uint8_t imx_spi_selected_channel(IMXSPIState *s)
123  {
124      return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_SELECT);
125  }
126  
127  static uint32_t imx_spi_burst_length(IMXSPIState *s)
128  {
129      return EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_BURST_LENGTH) + 1;
130  }
131  
132  static bool imx_spi_is_enabled(IMXSPIState *s)
133  {
134      return s->regs[ECSPI_CONREG] & ECSPI_CONREG_EN;
135  }
136  
137  static bool imx_spi_channel_is_master(IMXSPIState *s)
138  {
139      uint8_t mode = EXTRACT(s->regs[ECSPI_CONREG], ECSPI_CONREG_CHANNEL_MODE);
140  
141      return (mode & (1 << imx_spi_selected_channel(s))) ? true : false;
142  }
143  
144  static bool imx_spi_is_multiple_master_burst(IMXSPIState *s)
145  {
146      uint8_t wave = EXTRACT(s->regs[ECSPI_CONFIGREG], ECSPI_CONFIGREG_SS_CTL);
147  
148      return imx_spi_channel_is_master(s) &&
149             !(s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC) &&
150             ((wave & (1 << imx_spi_selected_channel(s))) ? true : false);
151  }
152  
153  static void imx_spi_flush_txfifo(IMXSPIState *s)
154  {
155      uint32_t tx;
156      uint32_t rx;
157  
158      DPRINTF("Begin: TX Fifo Size = %d, RX Fifo Size = %d\n",
159              fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
160  
161      while (!fifo32_is_empty(&s->tx_fifo)) {
162          int tx_burst = 0;
163          int index = 0;
164  
165          if (s->burst_length <= 0) {
166              s->burst_length = imx_spi_burst_length(s);
167  
168              DPRINTF("Burst length = %d\n", s->burst_length);
169  
170              if (imx_spi_is_multiple_master_burst(s)) {
171                  s->regs[ECSPI_CONREG] |= ECSPI_CONREG_XCH;
172              }
173          }
174  
175          tx = fifo32_pop(&s->tx_fifo);
176  
177          DPRINTF("data tx:0x%08x\n", tx);
178  
179          tx_burst = MIN(s->burst_length, 32);
180  
181          rx = 0;
182  
183          while (tx_burst) {
184              uint8_t byte = tx & 0xff;
185  
186              DPRINTF("writing 0x%02x\n", (uint32_t)byte);
187  
188              /* We need to write one byte at a time */
189              byte = ssi_transfer(s->bus, byte);
190  
191              DPRINTF("0x%02x read\n", (uint32_t)byte);
192  
193              tx = tx >> 8;
194              rx |= (byte << (index * 8));
195  
196              /* Remove 8 bits from the actual burst */
197              tx_burst -= 8;
198              s->burst_length -= 8;
199              index++;
200          }
201  
202          DPRINTF("data rx:0x%08x\n", rx);
203  
204          if (fifo32_is_full(&s->rx_fifo)) {
205              s->regs[ECSPI_STATREG] |= ECSPI_STATREG_RO;
206          } else {
207              fifo32_push(&s->rx_fifo, (uint8_t)rx);
208          }
209  
210          if (s->burst_length <= 0) {
211              s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
212  
213              if (!imx_spi_is_multiple_master_burst(s)) {
214                  s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
215                  break;
216              }
217          }
218      }
219  
220      if (fifo32_is_empty(&s->tx_fifo)) {
221          s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
222      }
223  
224      /* TODO: We should also use TDR and RDR bits */
225  
226      DPRINTF("End: TX Fifo Size = %d, RX Fifo Size = %d\n",
227              fifo32_num_used(&s->tx_fifo), fifo32_num_used(&s->rx_fifo));
228  }
229  
230  static void imx_spi_reset(DeviceState *dev)
231  {
232      IMXSPIState *s = IMX_SPI(dev);
233  
234      DPRINTF("\n");
235  
236      memset(s->regs, 0, sizeof(s->regs));
237  
238      s->regs[ECSPI_STATREG] = 0x00000003;
239  
240      imx_spi_rxfifo_reset(s);
241      imx_spi_txfifo_reset(s);
242  
243      imx_spi_update_irq(s);
244  
245      s->burst_length = 0;
246  }
247  
248  static uint64_t imx_spi_read(void *opaque, hwaddr offset, unsigned size)
249  {
250      uint32_t value = 0;
251      IMXSPIState *s = opaque;
252      uint32_t index = offset >> 2;
253  
254      if (index >=  ECSPI_MAX) {
255          qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
256                        HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
257          return 0;
258      }
259  
260      switch (index) {
261      case ECSPI_RXDATA:
262          if (!imx_spi_is_enabled(s)) {
263              value = 0;
264          } else if (fifo32_is_empty(&s->rx_fifo)) {
265              /* value is undefined */
266              value = 0xdeadbeef;
267          } else {
268              /* read from the RX FIFO */
269              value = fifo32_pop(&s->rx_fifo);
270          }
271  
272          break;
273      case ECSPI_TXDATA:
274          qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from TX FIFO\n",
275                        TYPE_IMX_SPI, __func__);
276  
277          /* Reading from TXDATA gives 0 */
278  
279          break;
280      case ECSPI_MSGDATA:
281          qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read from MSG FIFO\n",
282                        TYPE_IMX_SPI, __func__);
283  
284          /* Reading from MSGDATA gives 0 */
285  
286          break;
287      default:
288          value = s->regs[index];
289          break;
290      }
291  
292      DPRINTF("reg[%s] => 0x%" PRIx32 "\n", imx_spi_reg_name(index), value);
293  
294      imx_spi_update_irq(s);
295  
296      return (uint64_t)value;
297  }
298  
299  static void imx_spi_write(void *opaque, hwaddr offset, uint64_t value,
300                             unsigned size)
301  {
302      IMXSPIState *s = opaque;
303      uint32_t index = offset >> 2;
304      uint32_t change_mask;
305  
306      if (index >=  ECSPI_MAX) {
307          qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
308                        HWADDR_PRIx "\n", TYPE_IMX_SPI, __func__, offset);
309          return;
310      }
311  
312      DPRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_spi_reg_name(index),
313              (uint32_t)value);
314  
315      change_mask = s->regs[index] ^ value;
316  
317      switch (index) {
318      case ECSPI_RXDATA:
319          qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to write to RX FIFO\n",
320                        TYPE_IMX_SPI, __func__);
321          break;
322      case ECSPI_TXDATA:
323      case ECSPI_MSGDATA:
324          /* Is there any difference between TXDATA and MSGDATA ? */
325          /* I'll have to look in the linux driver */
326          if (!imx_spi_is_enabled(s)) {
327              /* Ignore writes if device is disabled */
328              break;
329          } else if (fifo32_is_full(&s->tx_fifo)) {
330              /* Ignore writes if queue is full */
331              break;
332          }
333  
334          fifo32_push(&s->tx_fifo, (uint32_t)value);
335  
336          if (imx_spi_channel_is_master(s) &&
337              (s->regs[ECSPI_CONREG] & ECSPI_CONREG_SMC)) {
338              /*
339               * Start emitting if current channel is master and SMC bit is
340               * set.
341               */
342              imx_spi_flush_txfifo(s);
343          }
344  
345          break;
346      case ECSPI_STATREG:
347          /* the RO and TC bits are write-one-to-clear */
348          value &= ECSPI_STATREG_RO | ECSPI_STATREG_TC;
349          s->regs[ECSPI_STATREG] &= ~value;
350  
351          break;
352      case ECSPI_CONREG:
353          s->regs[ECSPI_CONREG] = value;
354  
355          if (!imx_spi_is_enabled(s)) {
356              /* device is disabled, so this is a reset */
357              imx_spi_reset(DEVICE(s));
358              return;
359          }
360  
361          if (imx_spi_channel_is_master(s)) {
362              int i;
363  
364              /* We are in master mode */
365  
366              for (i = 0; i < 4; i++) {
367                  qemu_set_irq(s->cs_lines[i],
368                               i == imx_spi_selected_channel(s) ? 0 : 1);
369              }
370  
371              if ((value & change_mask & ECSPI_CONREG_SMC) &&
372                  !fifo32_is_empty(&s->tx_fifo)) {
373                  /* SMC bit is set and TX FIFO has some slots filled in */
374                  imx_spi_flush_txfifo(s);
375              } else if ((value & change_mask & ECSPI_CONREG_XCH) &&
376                  !(value & ECSPI_CONREG_SMC)) {
377                  /* This is a request to start emitting */
378                  imx_spi_flush_txfifo(s);
379              }
380          }
381  
382          break;
383      default:
384          s->regs[index] = value;
385  
386          break;
387      }
388  
389      imx_spi_update_irq(s);
390  }
391  
392  static const struct MemoryRegionOps imx_spi_ops = {
393      .read = imx_spi_read,
394      .write = imx_spi_write,
395      .endianness = DEVICE_NATIVE_ENDIAN,
396      .valid = {
397          /*
398           * Our device would not work correctly if the guest was doing
399           * unaligned access. This might not be a limitation on the real
400           * device but in practice there is no reason for a guest to access
401           * this device unaligned.
402           */
403          .min_access_size = 4,
404          .max_access_size = 4,
405          .unaligned = false,
406      },
407  };
408  
409  static void imx_spi_realize(DeviceState *dev, Error **errp)
410  {
411      IMXSPIState *s = IMX_SPI(dev);
412      int i;
413  
414      s->bus = ssi_create_bus(dev, "spi");
415  
416      memory_region_init_io(&s->iomem, OBJECT(dev), &imx_spi_ops, s,
417                            TYPE_IMX_SPI, 0x1000);
418      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
419      sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
420  
421      ssi_auto_connect_slaves(dev, s->cs_lines, s->bus);
422  
423      for (i = 0; i < 4; ++i) {
424          sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]);
425      }
426  
427      s->burst_length = 0;
428  
429      fifo32_create(&s->tx_fifo, ECSPI_FIFO_SIZE);
430      fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE);
431  }
432  
433  static void imx_spi_class_init(ObjectClass *klass, void *data)
434  {
435      DeviceClass *dc = DEVICE_CLASS(klass);
436  
437      dc->realize = imx_spi_realize;
438      dc->vmsd = &vmstate_imx_spi;
439      dc->reset = imx_spi_reset;
440      dc->desc = "i.MX SPI Controller";
441  }
442  
443  static const TypeInfo imx_spi_info = {
444      .name          = TYPE_IMX_SPI,
445      .parent        = TYPE_SYS_BUS_DEVICE,
446      .instance_size = sizeof(IMXSPIState),
447      .class_init    = imx_spi_class_init,
448  };
449  
450  static void imx_spi_register_types(void)
451  {
452      type_register_static(&imx_spi_info);
453  }
454  
455  type_init(imx_spi_register_types)
456