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