xref: /openbmc/qemu/hw/char/imx_serial.c (revision 990d2c18)
1 /*
2  * IMX31 UARTS
3  *
4  * Copyright (c) 2008 OKL
5  * Originally Written by Hans Jiang
6  * Copyright (c) 2011 NICTA Pty Ltd.
7  * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  * This is a `bare-bones' implementation of the IMX series serial ports.
13  * TODO:
14  *  -- implement FIFOs.  The real hardware has 32 word transmit
15  *                       and receive FIFOs; we currently use a 1-char buffer
16  *  -- implement DMA
17  *  -- implement BAUD-rate and modem lines, for when the backend
18  *     is a real serial device.
19  */
20 
21 #include "qemu/osdep.h"
22 #include "hw/char/imx_serial.h"
23 #include "hw/irq.h"
24 #include "hw/qdev-properties.h"
25 #include "hw/qdev-properties-system.h"
26 #include "migration/vmstate.h"
27 #include "qemu/log.h"
28 #include "qemu/module.h"
29 #include "qemu/fifo32.h"
30 
31 #ifndef DEBUG_IMX_UART
32 #define DEBUG_IMX_UART 0
33 #endif
34 
35 #define DPRINTF(fmt, args...) \
36     do { \
37         if (DEBUG_IMX_UART) { \
38             fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_SERIAL, \
39                                              __func__, ##args); \
40         } \
41     } while (0)
42 
43 static const VMStateDescription vmstate_imx_serial = {
44     .name = TYPE_IMX_SERIAL,
45     .version_id = 3,
46     .minimum_version_id = 3,
47     .fields = (const VMStateField[]) {
48         VMSTATE_FIFO32(rx_fifo, IMXSerialState),
49         VMSTATE_TIMER(ageing_timer, IMXSerialState),
50         VMSTATE_UINT32(usr1, IMXSerialState),
51         VMSTATE_UINT32(usr2, IMXSerialState),
52         VMSTATE_UINT32(ucr1, IMXSerialState),
53         VMSTATE_UINT32(uts1, IMXSerialState),
54         VMSTATE_UINT32(onems, IMXSerialState),
55         VMSTATE_UINT32(ufcr, IMXSerialState),
56         VMSTATE_UINT32(ubmr, IMXSerialState),
57         VMSTATE_UINT32(ubrc, IMXSerialState),
58         VMSTATE_UINT32(ucr3, IMXSerialState),
59         VMSTATE_UINT32(ucr4, IMXSerialState),
60         VMSTATE_END_OF_LIST()
61     },
62 };
63 
64 static void imx_update(IMXSerialState *s)
65 {
66     uint32_t usr1;
67     uint32_t usr2;
68     uint32_t mask;
69 
70     /*
71      * Lucky for us TRDY and RRDY has the same offset in both USR1 and
72      * UCR1, so we can get away with something as simple as the
73      * following:
74      */
75     usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
76     /*
77      * Interrupt if AGTIM is set (ageing timer interrupt in RxFIFO)
78      */
79     usr1 |= (s->ucr2 & UCR2_ATEN) ? (s->usr1 & USR1_AGTIM) : 0;
80     /*
81      * Bits that we want in USR2 are not as conveniently laid out,
82      * unfortunately.
83      */
84     mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
85     /*
86      * TCEN and TXDC are both bit 3
87      * ORE and OREN are both bit 1
88      * RDR and DREN are both bit 0
89      */
90     mask |= s->ucr4 & (UCR4_WKEN | UCR4_TCEN | UCR4_DREN | UCR4_OREN);
91 
92     usr2 = s->usr2 & mask;
93 
94     qemu_set_irq(s->irq, usr1 || usr2);
95 }
96 
97 static void imx_serial_rx_fifo_push(IMXSerialState *s, uint32_t value)
98 {
99     uint32_t pushed_value = value;
100     if (fifo32_is_full(&s->rx_fifo)) {
101         /* Set ORE if FIFO is already full */
102         s->usr2 |= USR2_ORE;
103     } else {
104         if (fifo32_num_used(&s->rx_fifo) == FIFO_SIZE - 1) {
105             /* Set OVRRUN on 32nd character in FIFO */
106             pushed_value |= URXD_ERR | URXD_OVRRUN;
107         }
108         fifo32_push(&s->rx_fifo, pushed_value);
109     }
110 }
111 
112 static uint32_t imx_serial_rx_fifo_pop(IMXSerialState *s)
113 {
114     if (fifo32_is_empty(&s->rx_fifo)) {
115         return 0;
116     }
117     return fifo32_pop(&s->rx_fifo);
118 }
119 
120 static void imx_serial_rx_fifo_ageing_timer_int(void *opaque)
121 {
122     IMXSerialState *s = (IMXSerialState *) opaque;
123     s->usr1 |= USR1_AGTIM;
124     imx_update(s);
125 }
126 
127 static void imx_serial_rx_fifo_ageing_timer_restart(void *opaque)
128 {
129     /*
130      * Ageing timer starts ticking when
131      * RX FIFO is non empty and below trigger level.
132      * Timer is reset if new character is received or
133      * a FIFO read occurs.
134      * Timer triggers an interrupt when duration of
135      * 8 characters has passed (assuming 115200 baudrate).
136      */
137     IMXSerialState *s = (IMXSerialState *) opaque;
138 
139     if (!(s->usr1 & USR1_RRDY) && !(s->uts1 & UTS1_RXEMPTY)) {
140         timer_mod_ns(&s->ageing_timer,
141                      qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + AGE_DURATION_NS);
142     } else {
143         timer_del(&s->ageing_timer);
144     }
145 }
146 
147 static void imx_serial_reset(IMXSerialState *s)
148 {
149 
150     s->usr1 = USR1_TRDY | USR1_RXDS;
151     /*
152      * Fake attachment of a terminal: assert RTS.
153      */
154     s->usr1 |= USR1_RTSS;
155     s->usr2 = USR2_TXFE | USR2_TXDC | USR2_DCDIN;
156     s->uts1 = UTS1_RXEMPTY | UTS1_TXEMPTY;
157     s->ucr1 = 0;
158     s->ucr2 = UCR2_SRST;
159     s->ucr3 = 0x700;
160     s->ubmr = 0;
161     s->ubrc = 4;
162 
163     fifo32_reset(&s->rx_fifo);
164     timer_del(&s->ageing_timer);
165 }
166 
167 static void imx_serial_reset_at_boot(DeviceState *dev)
168 {
169     IMXSerialState *s = IMX_SERIAL(dev);
170 
171     imx_serial_reset(s);
172 
173     /*
174      * enable the uart on boot, so messages from the linux decompressor
175      * are visible.  On real hardware this is done by the boot rom
176      * before anything else is loaded.
177      */
178     s->ucr1 = UCR1_UARTEN;
179     s->ucr2 = UCR2_TXEN;
180 
181 }
182 
183 static uint64_t imx_serial_read(void *opaque, hwaddr offset,
184                                 unsigned size)
185 {
186     IMXSerialState *s = (IMXSerialState *)opaque;
187     uint32_t c, rx_used;
188     uint8_t rxtl = s->ufcr & TL_MASK;
189 
190     DPRINTF("read(offset=0x%" HWADDR_PRIx ")\n", offset);
191 
192     switch (offset >> 2) {
193     case 0x0: /* URXD */
194         c = imx_serial_rx_fifo_pop(s);
195         if (!(s->uts1 & UTS1_RXEMPTY)) {
196             /* Character is valid */
197             c |= URXD_CHARRDY;
198             rx_used = fifo32_num_used(&s->rx_fifo);
199             /* Clear RRDY if below threshold */
200             if (rx_used < rxtl) {
201                 s->usr1 &= ~USR1_RRDY;
202             }
203             if (rx_used == 0) {
204                 s->usr2 &= ~USR2_RDR;
205                 s->uts1 |= UTS1_RXEMPTY;
206             }
207             imx_update(s);
208             imx_serial_rx_fifo_ageing_timer_restart(s);
209             qemu_chr_fe_accept_input(&s->chr);
210         }
211         return c;
212 
213     case 0x20: /* UCR1 */
214         return s->ucr1;
215 
216     case 0x21: /* UCR2 */
217         return s->ucr2;
218 
219     case 0x25: /* USR1 */
220         return s->usr1;
221 
222     case 0x26: /* USR2 */
223         return s->usr2;
224 
225     case 0x2A: /* BRM Modulator */
226         return s->ubmr;
227 
228     case 0x2B: /* Baud Rate Count */
229         return s->ubrc;
230 
231     case 0x2d: /* Test register */
232         return s->uts1;
233 
234     case 0x24: /* UFCR */
235         return s->ufcr;
236 
237     case 0x2c:
238         return s->onems;
239 
240     case 0x22: /* UCR3 */
241         return s->ucr3;
242 
243     case 0x23: /* UCR4 */
244         return s->ucr4;
245 
246     case 0x29: /* BRM Incremental */
247         return 0x0; /* TODO */
248 
249     default:
250         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
251                       HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
252         return 0;
253     }
254 }
255 
256 static void imx_serial_write(void *opaque, hwaddr offset,
257                              uint64_t value, unsigned size)
258 {
259     IMXSerialState *s = (IMXSerialState *)opaque;
260     Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
261     unsigned char ch;
262 
263     DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
264             offset, (unsigned int)value, chr ? chr->label : "NODEV");
265 
266     switch (offset >> 2) {
267     case 0x10: /* UTXD */
268         ch = value;
269         if (s->ucr2 & UCR2_TXEN) {
270             /* XXX this blocks entire thread. Rewrite to use
271              * qemu_chr_fe_write and background I/O callbacks */
272             qemu_chr_fe_write_all(&s->chr, &ch, 1);
273             s->usr1 &= ~USR1_TRDY;
274             s->usr2 &= ~USR2_TXDC;
275             imx_update(s);
276             s->usr1 |= USR1_TRDY;
277             s->usr2 |= USR2_TXDC;
278             imx_update(s);
279         }
280         break;
281 
282     case 0x20: /* UCR1 */
283         s->ucr1 = value & 0xffff;
284 
285         DPRINTF("write(ucr1=%x)\n", (unsigned int)value);
286 
287         imx_update(s);
288         break;
289 
290     case 0x21: /* UCR2 */
291         /*
292          * Only a few bits in control register 2 are implemented as yet.
293          * If it's intended to use a real serial device as a back-end, this
294          * register will have to be implemented more fully.
295          */
296         if (!(value & UCR2_SRST)) {
297             imx_serial_reset(s);
298             imx_update(s);
299             value |= UCR2_SRST;
300         }
301         if (value & UCR2_RXEN) {
302             if (!(s->ucr2 & UCR2_RXEN)) {
303                 qemu_chr_fe_accept_input(&s->chr);
304             }
305         }
306         s->ucr2 = value & 0xffff;
307         break;
308 
309     case 0x25: /* USR1 */
310         value &= USR1_AWAKE | USR1_AIRINT | USR1_DTRD | USR1_AGTIM |
311                  USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
312         s->usr1 &= ~value;
313         break;
314 
315     case 0x26: /* USR2 */
316         /*
317          * Writing 1 to some bits clears them; all other
318          * values are ignored
319          */
320         value &= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_ACST |
321                  USR2_RIDELT | USR2_IRINT | USR2_WAKE |
322                  USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
323         s->usr2 &= ~value;
324         break;
325 
326     /*
327      * Linux expects to see what it writes to these registers
328      * We don't currently alter the baud rate
329      */
330     case 0x29: /* UBIR */
331         s->ubrc = value & 0xffff;
332         break;
333 
334     case 0x2a: /* UBMR */
335         s->ubmr = value & 0xffff;
336         break;
337 
338     case 0x2c: /* One ms reg */
339         s->onems = value & 0xffff;
340         break;
341 
342     case 0x24: /* FIFO control register */
343         s->ufcr = value & 0xffff;
344         break;
345 
346     case 0x22: /* UCR3 */
347         s->ucr3 = value & 0xffff;
348         break;
349 
350     case 0x23: /* UCR4 */
351         s->ucr4 = value & 0xffff;
352         imx_update(s);
353         break;
354 
355     case 0x2d: /* UTS1 */
356         qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
357                       HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
358         /* TODO */
359         break;
360 
361     default:
362         qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
363                       HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
364     }
365 }
366 
367 static int imx_can_receive(void *opaque)
368 {
369     IMXSerialState *s = (IMXSerialState *)opaque;
370     return s->ucr2 & UCR2_RXEN && fifo32_num_used(&s->rx_fifo) < FIFO_SIZE;
371 }
372 
373 static void imx_put_data(void *opaque, uint32_t value)
374 {
375     IMXSerialState *s = (IMXSerialState *)opaque;
376     uint8_t rxtl = s->ufcr & TL_MASK;
377 
378     DPRINTF("received char\n");
379     imx_serial_rx_fifo_push(s, value);
380     if (fifo32_num_used(&s->rx_fifo) >= rxtl) {
381         s->usr1 |= USR1_RRDY;
382     }
383 
384     imx_serial_rx_fifo_ageing_timer_restart(s);
385 
386     s->usr2 |= USR2_RDR;
387     s->uts1 &= ~UTS1_RXEMPTY;
388     if (value & URXD_BRK) {
389         s->usr2 |= USR2_BRCD;
390     }
391     imx_update(s);
392 }
393 
394 static void imx_receive(void *opaque, const uint8_t *buf, int size)
395 {
396     IMXSerialState *s = (IMXSerialState *)opaque;
397 
398     s->usr2 |= USR2_WAKE;
399     imx_put_data(opaque, *buf);
400 }
401 
402 static void imx_event(void *opaque, QEMUChrEvent event)
403 {
404     if (event == CHR_EVENT_BREAK) {
405         imx_put_data(opaque, URXD_BRK | URXD_FRMERR | URXD_ERR);
406     }
407 }
408 
409 
410 static const struct MemoryRegionOps imx_serial_ops = {
411     .read = imx_serial_read,
412     .write = imx_serial_write,
413     .endianness = DEVICE_NATIVE_ENDIAN,
414 };
415 
416 static void imx_serial_realize(DeviceState *dev, Error **errp)
417 {
418     IMXSerialState *s = IMX_SERIAL(dev);
419 
420     fifo32_create(&s->rx_fifo, FIFO_SIZE);
421     timer_init_ns(&s->ageing_timer, QEMU_CLOCK_VIRTUAL,
422                   imx_serial_rx_fifo_ageing_timer_int, s);
423 
424     DPRINTF("char dev for uart: %p\n", qemu_chr_fe_get_driver(&s->chr));
425 
426     qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive,
427                              imx_event, NULL, s, NULL, true);
428 }
429 
430 static void imx_serial_init(Object *obj)
431 {
432     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
433     IMXSerialState *s = IMX_SERIAL(obj);
434 
435     memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
436                           TYPE_IMX_SERIAL, 0x1000);
437     sysbus_init_mmio(sbd, &s->iomem);
438     sysbus_init_irq(sbd, &s->irq);
439 }
440 
441 static Property imx_serial_properties[] = {
442     DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
443     DEFINE_PROP_END_OF_LIST(),
444 };
445 
446 static void imx_serial_class_init(ObjectClass *klass, void *data)
447 {
448     DeviceClass *dc = DEVICE_CLASS(klass);
449 
450     dc->realize = imx_serial_realize;
451     dc->vmsd = &vmstate_imx_serial;
452     device_class_set_legacy_reset(dc, imx_serial_reset_at_boot);
453     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
454     dc->desc = "i.MX series UART";
455     device_class_set_props(dc, imx_serial_properties);
456 }
457 
458 static const TypeInfo imx_serial_info = {
459     .name           = TYPE_IMX_SERIAL,
460     .parent         = TYPE_SYS_BUS_DEVICE,
461     .instance_size  = sizeof(IMXSerialState),
462     .instance_init  = imx_serial_init,
463     .class_init     = imx_serial_class_init,
464 };
465 
466 static void imx_serial_register_types(void)
467 {
468     type_register_static(&imx_serial_info);
469 }
470 
471 type_init(imx_serial_register_types)
472