xref: /openbmc/qemu/hw/sd/pl181.c (revision 8fa3b702)
1 /*
2  * Arm PrimeCell PL181 MultiMedia Card Interface
3  *
4  * Copyright (c) 2007 CodeSourcery.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GPL.
8  */
9 
10 #include "qemu/osdep.h"
11 #include "sysemu/blockdev.h"
12 #include "hw/sysbus.h"
13 #include "migration/vmstate.h"
14 #include "hw/irq.h"
15 #include "hw/sd/sd.h"
16 #include "qemu/log.h"
17 #include "qemu/module.h"
18 #include "qemu/error-report.h"
19 #include "qapi/error.h"
20 #include "trace.h"
21 #include "qom/object.h"
22 
23 #define PL181_FIFO_LEN 16
24 
25 #define TYPE_PL181 "pl181"
26 typedef struct PL181State PL181State;
27 DECLARE_INSTANCE_CHECKER(PL181State, PL181,
28                          TYPE_PL181)
29 
30 #define TYPE_PL181_BUS "pl181-bus"
31 
32 struct PL181State {
33     SysBusDevice parent_obj;
34 
35     MemoryRegion iomem;
36     SDBus sdbus;
37     uint32_t clock;
38     uint32_t power;
39     uint32_t cmdarg;
40     uint32_t cmd;
41     uint32_t datatimer;
42     uint32_t datalength;
43     uint32_t respcmd;
44     uint32_t response[4];
45     uint32_t datactrl;
46     uint32_t datacnt;
47     uint32_t status;
48     uint32_t mask[2];
49     int32_t fifo_pos;
50     int32_t fifo_len;
51     /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
52        while it is reading the FIFO.  We hack around this by deferring
53        subsequent transfers until after the driver polls the status word.
54        http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
55      */
56     int32_t linux_hack;
57     uint32_t fifo[PL181_FIFO_LEN]; /* TODO use Fifo32 */
58     qemu_irq irq[2];
59     /* GPIO outputs for 'card is readonly' and 'card inserted' */
60     qemu_irq card_readonly;
61     qemu_irq card_inserted;
62 };
63 
64 static const VMStateDescription vmstate_pl181 = {
65     .name = "pl181",
66     .version_id = 1,
67     .minimum_version_id = 1,
68     .fields = (VMStateField[]) {
69         VMSTATE_UINT32(clock, PL181State),
70         VMSTATE_UINT32(power, PL181State),
71         VMSTATE_UINT32(cmdarg, PL181State),
72         VMSTATE_UINT32(cmd, PL181State),
73         VMSTATE_UINT32(datatimer, PL181State),
74         VMSTATE_UINT32(datalength, PL181State),
75         VMSTATE_UINT32(respcmd, PL181State),
76         VMSTATE_UINT32_ARRAY(response, PL181State, 4),
77         VMSTATE_UINT32(datactrl, PL181State),
78         VMSTATE_UINT32(datacnt, PL181State),
79         VMSTATE_UINT32(status, PL181State),
80         VMSTATE_UINT32_ARRAY(mask, PL181State, 2),
81         VMSTATE_INT32(fifo_pos, PL181State),
82         VMSTATE_INT32(fifo_len, PL181State),
83         VMSTATE_INT32(linux_hack, PL181State),
84         VMSTATE_UINT32_ARRAY(fifo, PL181State, PL181_FIFO_LEN),
85         VMSTATE_END_OF_LIST()
86     }
87 };
88 
89 #define PL181_CMD_INDEX     0x3f
90 #define PL181_CMD_RESPONSE  (1 << 6)
91 #define PL181_CMD_LONGRESP  (1 << 7)
92 #define PL181_CMD_INTERRUPT (1 << 8)
93 #define PL181_CMD_PENDING   (1 << 9)
94 #define PL181_CMD_ENABLE    (1 << 10)
95 
96 #define PL181_DATA_ENABLE             (1 << 0)
97 #define PL181_DATA_DIRECTION          (1 << 1)
98 #define PL181_DATA_MODE               (1 << 2)
99 #define PL181_DATA_DMAENABLE          (1 << 3)
100 
101 #define PL181_STATUS_CMDCRCFAIL       (1 << 0)
102 #define PL181_STATUS_DATACRCFAIL      (1 << 1)
103 #define PL181_STATUS_CMDTIMEOUT       (1 << 2)
104 #define PL181_STATUS_DATATIMEOUT      (1 << 3)
105 #define PL181_STATUS_TXUNDERRUN       (1 << 4)
106 #define PL181_STATUS_RXOVERRUN        (1 << 5)
107 #define PL181_STATUS_CMDRESPEND       (1 << 6)
108 #define PL181_STATUS_CMDSENT          (1 << 7)
109 #define PL181_STATUS_DATAEND          (1 << 8)
110 #define PL181_STATUS_DATABLOCKEND     (1 << 10)
111 #define PL181_STATUS_CMDACTIVE        (1 << 11)
112 #define PL181_STATUS_TXACTIVE         (1 << 12)
113 #define PL181_STATUS_RXACTIVE         (1 << 13)
114 #define PL181_STATUS_TXFIFOHALFEMPTY  (1 << 14)
115 #define PL181_STATUS_RXFIFOHALFFULL   (1 << 15)
116 #define PL181_STATUS_TXFIFOFULL       (1 << 16)
117 #define PL181_STATUS_RXFIFOFULL       (1 << 17)
118 #define PL181_STATUS_TXFIFOEMPTY      (1 << 18)
119 #define PL181_STATUS_RXFIFOEMPTY      (1 << 19)
120 #define PL181_STATUS_TXDATAAVLBL      (1 << 20)
121 #define PL181_STATUS_RXDATAAVLBL      (1 << 21)
122 
123 #define PL181_STATUS_TX_FIFO (PL181_STATUS_TXACTIVE \
124                              |PL181_STATUS_TXFIFOHALFEMPTY \
125                              |PL181_STATUS_TXFIFOFULL \
126                              |PL181_STATUS_TXFIFOEMPTY \
127                              |PL181_STATUS_TXDATAAVLBL)
128 #define PL181_STATUS_RX_FIFO (PL181_STATUS_RXACTIVE \
129                              |PL181_STATUS_RXFIFOHALFFULL \
130                              |PL181_STATUS_RXFIFOFULL \
131                              |PL181_STATUS_RXFIFOEMPTY \
132                              |PL181_STATUS_RXDATAAVLBL)
133 
134 static const unsigned char pl181_id[] =
135 { 0x81, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
136 
137 static void pl181_update(PL181State *s)
138 {
139     int i;
140     for (i = 0; i < 2; i++) {
141         qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0);
142     }
143 }
144 
145 static void pl181_fifo_push(PL181State *s, uint32_t value)
146 {
147     int n;
148 
149     if (s->fifo_len == PL181_FIFO_LEN) {
150         error_report("%s: FIFO overflow", __func__);
151         return;
152     }
153     n = (s->fifo_pos + s->fifo_len) & (PL181_FIFO_LEN - 1);
154     s->fifo_len++;
155     s->fifo[n] = value;
156     trace_pl181_fifo_push(value);
157 }
158 
159 static uint32_t pl181_fifo_pop(PL181State *s)
160 {
161     uint32_t value;
162 
163     if (s->fifo_len == 0) {
164         error_report("%s: FIFO underflow", __func__);
165         return 0;
166     }
167     value = s->fifo[s->fifo_pos];
168     s->fifo_len--;
169     s->fifo_pos = (s->fifo_pos + 1) & (PL181_FIFO_LEN - 1);
170     trace_pl181_fifo_pop(value);
171     return value;
172 }
173 
174 static void pl181_do_command(PL181State *s)
175 {
176     SDRequest request;
177     uint8_t response[16];
178     int rlen;
179 
180     request.cmd = s->cmd & PL181_CMD_INDEX;
181     request.arg = s->cmdarg;
182     trace_pl181_command_send(request.cmd, request.arg);
183     rlen = sdbus_do_command(&s->sdbus, &request, response);
184     if (rlen < 0)
185         goto error;
186     if (s->cmd & PL181_CMD_RESPONSE) {
187         if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
188             goto error;
189         if (rlen != 4 && rlen != 16)
190             goto error;
191         s->response[0] = ldl_be_p(&response[0]);
192         if (rlen == 4) {
193             s->response[1] = s->response[2] = s->response[3] = 0;
194         } else {
195             s->response[1] = ldl_be_p(&response[4]);
196             s->response[2] = ldl_be_p(&response[8]);
197             s->response[3] = ldl_be_p(&response[12]) & ~1;
198         }
199         trace_pl181_command_response_pending();
200         s->status |= PL181_STATUS_CMDRESPEND;
201     } else {
202         trace_pl181_command_sent();
203         s->status |= PL181_STATUS_CMDSENT;
204     }
205     return;
206 
207 error:
208     trace_pl181_command_timeout();
209     s->status |= PL181_STATUS_CMDTIMEOUT;
210 }
211 
212 /* Transfer data between the card and the FIFO.  This is complicated by
213    the FIFO holding 32-bit words and the card taking data in single byte
214    chunks.  FIFO bytes are transferred in little-endian order.  */
215 
216 static void pl181_fifo_run(PL181State *s)
217 {
218     uint32_t bits;
219     uint32_t value = 0;
220     int n;
221     int is_read;
222 
223     is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
224     if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))
225             && !s->linux_hack) {
226         if (is_read) {
227             n = 0;
228             while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
229                 value |= (uint32_t)sdbus_read_byte(&s->sdbus) << (n * 8);
230                 s->datacnt--;
231                 n++;
232                 if (n == 4) {
233                     pl181_fifo_push(s, value);
234                     n = 0;
235                     value = 0;
236                 }
237             }
238             if (n != 0) {
239                 pl181_fifo_push(s, value);
240             }
241         } else { /* write */
242             n = 0;
243             while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
244                 if (n == 0) {
245                     value = pl181_fifo_pop(s);
246                     n = 4;
247                 }
248                 n--;
249                 s->datacnt--;
250                 sdbus_write_byte(&s->sdbus, value & 0xff);
251                 value >>= 8;
252             }
253         }
254     }
255     s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
256     if (s->datacnt == 0) {
257         s->status |= PL181_STATUS_DATAEND;
258         /* HACK: */
259         s->status |= PL181_STATUS_DATABLOCKEND;
260         trace_pl181_fifo_transfer_complete();
261     }
262     if (s->datacnt == 0 && s->fifo_len == 0) {
263         s->datactrl &= ~PL181_DATA_ENABLE;
264         trace_pl181_data_engine_idle();
265     } else {
266         /* Update FIFO bits.  */
267         bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
268         if (s->fifo_len == 0) {
269             bits |= PL181_STATUS_TXFIFOEMPTY;
270             bits |= PL181_STATUS_RXFIFOEMPTY;
271         } else {
272             bits |= PL181_STATUS_TXDATAAVLBL;
273             bits |= PL181_STATUS_RXDATAAVLBL;
274         }
275         if (s->fifo_len == 16) {
276             bits |= PL181_STATUS_TXFIFOFULL;
277             bits |= PL181_STATUS_RXFIFOFULL;
278         }
279         if (s->fifo_len <= 8) {
280             bits |= PL181_STATUS_TXFIFOHALFEMPTY;
281         }
282         if (s->fifo_len >= 8) {
283             bits |= PL181_STATUS_RXFIFOHALFFULL;
284         }
285         if (s->datactrl & PL181_DATA_DIRECTION) {
286             bits &= PL181_STATUS_RX_FIFO;
287         } else {
288             bits &= PL181_STATUS_TX_FIFO;
289         }
290         s->status |= bits;
291     }
292 }
293 
294 static uint64_t pl181_read(void *opaque, hwaddr offset,
295                            unsigned size)
296 {
297     PL181State *s = (PL181State *)opaque;
298     uint32_t tmp;
299 
300     if (offset >= 0xfe0 && offset < 0x1000) {
301         return pl181_id[(offset - 0xfe0) >> 2];
302     }
303     switch (offset) {
304     case 0x00: /* Power */
305         return s->power;
306     case 0x04: /* Clock */
307         return s->clock;
308     case 0x08: /* Argument */
309         return s->cmdarg;
310     case 0x0c: /* Command */
311         return s->cmd;
312     case 0x10: /* RespCmd */
313         return s->respcmd;
314     case 0x14: /* Response0 */
315         return s->response[0];
316     case 0x18: /* Response1 */
317         return s->response[1];
318     case 0x1c: /* Response2 */
319         return s->response[2];
320     case 0x20: /* Response3 */
321         return s->response[3];
322     case 0x24: /* DataTimer */
323         return s->datatimer;
324     case 0x28: /* DataLength */
325         return s->datalength;
326     case 0x2c: /* DataCtrl */
327         return s->datactrl;
328     case 0x30: /* DataCnt */
329         return s->datacnt;
330     case 0x34: /* Status */
331         tmp = s->status;
332         if (s->linux_hack) {
333             s->linux_hack = 0;
334             pl181_fifo_run(s);
335             pl181_update(s);
336         }
337         return tmp;
338     case 0x3c: /* Mask0 */
339         return s->mask[0];
340     case 0x40: /* Mask1 */
341         return s->mask[1];
342     case 0x48: /* FifoCnt */
343         /* The documentation is somewhat vague about exactly what FifoCnt
344            does.  On real hardware it appears to be when decrememnted
345            when a word is transferred between the FIFO and the serial
346            data engine.  DataCnt is decremented after each byte is
347            transferred between the serial engine and the card.
348            We don't emulate this level of detail, so both can be the same.  */
349         tmp = (s->datacnt + 3) >> 2;
350         if (s->linux_hack) {
351             s->linux_hack = 0;
352             pl181_fifo_run(s);
353             pl181_update(s);
354         }
355         return tmp;
356     case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
357     case 0x90: case 0x94: case 0x98: case 0x9c:
358     case 0xa0: case 0xa4: case 0xa8: case 0xac:
359     case 0xb0: case 0xb4: case 0xb8: case 0xbc:
360         if (s->fifo_len == 0) {
361             qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n");
362             return 0;
363         } else {
364             uint32_t value;
365             value = pl181_fifo_pop(s);
366             s->linux_hack = 1;
367             pl181_fifo_run(s);
368             pl181_update(s);
369             return value;
370         }
371     default:
372         qemu_log_mask(LOG_GUEST_ERROR,
373                       "pl181_read: Bad offset %x\n", (int)offset);
374         return 0;
375     }
376 }
377 
378 static void pl181_write(void *opaque, hwaddr offset,
379                         uint64_t value, unsigned size)
380 {
381     PL181State *s = (PL181State *)opaque;
382 
383     switch (offset) {
384     case 0x00: /* Power */
385         s->power = value & 0xff;
386         break;
387     case 0x04: /* Clock */
388         s->clock = value & 0xff;
389         break;
390     case 0x08: /* Argument */
391         s->cmdarg = value;
392         break;
393     case 0x0c: /* Command */
394         s->cmd = value;
395         if (s->cmd & PL181_CMD_ENABLE) {
396             if (s->cmd & PL181_CMD_INTERRUPT) {
397                 qemu_log_mask(LOG_UNIMP,
398                               "pl181: Interrupt mode not implemented\n");
399             } if (s->cmd & PL181_CMD_PENDING) {
400                 qemu_log_mask(LOG_UNIMP,
401                               "pl181: Pending commands not implemented\n");
402             } else {
403                 pl181_do_command(s);
404                 pl181_fifo_run(s);
405             }
406             /* The command has completed one way or the other.  */
407             s->cmd &= ~PL181_CMD_ENABLE;
408         }
409         break;
410     case 0x24: /* DataTimer */
411         s->datatimer = value;
412         break;
413     case 0x28: /* DataLength */
414         s->datalength = value & 0xffff;
415         break;
416     case 0x2c: /* DataCtrl */
417         s->datactrl = value & 0xff;
418         if (value & PL181_DATA_ENABLE) {
419             s->datacnt = s->datalength;
420             pl181_fifo_run(s);
421         }
422         break;
423     case 0x38: /* Clear */
424         s->status &= ~(value & 0x7ff);
425         break;
426     case 0x3c: /* Mask0 */
427         s->mask[0] = value;
428         break;
429     case 0x40: /* Mask1 */
430         s->mask[1] = value;
431         break;
432     case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
433     case 0x90: case 0x94: case 0x98: case 0x9c:
434     case 0xa0: case 0xa4: case 0xa8: case 0xac:
435     case 0xb0: case 0xb4: case 0xb8: case 0xbc:
436         if (s->datacnt == 0) {
437             qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n");
438         } else {
439             pl181_fifo_push(s, value);
440             pl181_fifo_run(s);
441         }
442         break;
443     default:
444         qemu_log_mask(LOG_GUEST_ERROR,
445                       "pl181_write: Bad offset %x\n", (int)offset);
446     }
447     pl181_update(s);
448 }
449 
450 static const MemoryRegionOps pl181_ops = {
451     .read = pl181_read,
452     .write = pl181_write,
453     .endianness = DEVICE_NATIVE_ENDIAN,
454 };
455 
456 static void pl181_set_readonly(DeviceState *dev, bool level)
457 {
458     PL181State *s = (PL181State *)dev;
459 
460     qemu_set_irq(s->card_readonly, level);
461 }
462 
463 static void pl181_set_inserted(DeviceState *dev, bool level)
464 {
465     PL181State *s = (PL181State *)dev;
466 
467     qemu_set_irq(s->card_inserted, level);
468 }
469 
470 static void pl181_reset(DeviceState *d)
471 {
472     PL181State *s = PL181(d);
473 
474     s->power = 0;
475     s->cmdarg = 0;
476     s->cmd = 0;
477     s->datatimer = 0;
478     s->datalength = 0;
479     s->respcmd = 0;
480     s->response[0] = 0;
481     s->response[1] = 0;
482     s->response[2] = 0;
483     s->response[3] = 0;
484     s->datatimer = 0;
485     s->datalength = 0;
486     s->datactrl = 0;
487     s->datacnt = 0;
488     s->status = 0;
489     s->linux_hack = 0;
490     s->mask[0] = 0;
491     s->mask[1] = 0;
492 
493     /* Reset other state based on current card insertion/readonly status */
494     pl181_set_inserted(DEVICE(s), sdbus_get_inserted(&s->sdbus));
495     pl181_set_readonly(DEVICE(s), sdbus_get_readonly(&s->sdbus));
496 }
497 
498 static void pl181_init(Object *obj)
499 {
500     DeviceState *dev = DEVICE(obj);
501     PL181State *s = PL181(obj);
502     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
503 
504     memory_region_init_io(&s->iomem, obj, &pl181_ops, s, "pl181", 0x1000);
505     sysbus_init_mmio(sbd, &s->iomem);
506     sysbus_init_irq(sbd, &s->irq[0]);
507     sysbus_init_irq(sbd, &s->irq[1]);
508     qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1);
509     qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1);
510 
511     qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
512                         TYPE_PL181_BUS, dev, "sd-bus");
513 }
514 
515 static void pl181_class_init(ObjectClass *klass, void *data)
516 {
517     DeviceClass *k = DEVICE_CLASS(klass);
518 
519     k->vmsd = &vmstate_pl181;
520     k->reset = pl181_reset;
521     /* Reason: output IRQs should be wired up */
522     k->user_creatable = false;
523 }
524 
525 static const TypeInfo pl181_info = {
526     .name          = TYPE_PL181,
527     .parent        = TYPE_SYS_BUS_DEVICE,
528     .instance_size = sizeof(PL181State),
529     .instance_init = pl181_init,
530     .class_init    = pl181_class_init,
531 };
532 
533 static void pl181_bus_class_init(ObjectClass *klass, void *data)
534 {
535     SDBusClass *sbc = SD_BUS_CLASS(klass);
536 
537     sbc->set_inserted = pl181_set_inserted;
538     sbc->set_readonly = pl181_set_readonly;
539 }
540 
541 static const TypeInfo pl181_bus_info = {
542     .name = TYPE_PL181_BUS,
543     .parent = TYPE_SD_BUS,
544     .instance_size = sizeof(SDBus),
545     .class_init = pl181_bus_class_init,
546 };
547 
548 static void pl181_register_types(void)
549 {
550     type_register_static(&pl181_info);
551     type_register_static(&pl181_bus_info);
552 }
553 
554 type_init(pl181_register_types)
555