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