xref: /openbmc/qemu/hw/char/imx_serial.c (revision fb37726d)
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 "hw/char/imx_serial.h"
22 #include "sysemu/sysemu.h"
23 #include "sysemu/char.h"
24 
25 //#define DEBUG_SERIAL 1
26 #ifdef DEBUG_SERIAL
27 #define DPRINTF(fmt, args...) \
28 do { printf("%s: " fmt , TYPE_IMX_SERIAL, ##args); } while (0)
29 #else
30 #define DPRINTF(fmt, args...) do {} while (0)
31 #endif
32 
33 /*
34  * Define to 1 for messages about attempts to
35  * access unimplemented registers or similar.
36  */
37 //#define DEBUG_IMPLEMENTATION 1
38 #ifdef DEBUG_IMPLEMENTATION
39 #  define IPRINTF(fmt, args...) \
40     do  { fprintf(stderr, "%s: " fmt, TYPE_IMX_SERIAL, ##args); } while (0)
41 #else
42 #  define IPRINTF(fmt, args...) do {} while (0)
43 #endif
44 
45 static const VMStateDescription vmstate_imx_serial = {
46     .name = TYPE_IMX_SERIAL,
47     .version_id = 1,
48     .minimum_version_id = 1,
49     .fields = (VMStateField[]) {
50         VMSTATE_INT32(readbuff, IMXSerialState),
51         VMSTATE_UINT32(usr1, IMXSerialState),
52         VMSTATE_UINT32(usr2, IMXSerialState),
53         VMSTATE_UINT32(ucr1, IMXSerialState),
54         VMSTATE_UINT32(uts1, IMXSerialState),
55         VMSTATE_UINT32(onems, IMXSerialState),
56         VMSTATE_UINT32(ufcr, IMXSerialState),
57         VMSTATE_UINT32(ubmr, IMXSerialState),
58         VMSTATE_UINT32(ubrc, IMXSerialState),
59         VMSTATE_UINT32(ucr3, IMXSerialState),
60         VMSTATE_END_OF_LIST()
61     },
62 };
63 
64 static void imx_update(IMXSerialState *s)
65 {
66     uint32_t flags;
67 
68     flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
69     if (!(s->ucr1 & UCR1_TXMPTYEN)) {
70         flags &= ~USR1_TRDY;
71     }
72 
73     qemu_set_irq(s->irq, !!flags);
74 }
75 
76 static void imx_serial_reset(IMXSerialState *s)
77 {
78 
79     s->usr1 = USR1_TRDY | USR1_RXDS;
80     /*
81      * Fake attachment of a terminal: assert RTS.
82      */
83     s->usr1 |= USR1_RTSS;
84     s->usr2 = USR2_TXFE | USR2_TXDC | USR2_DCDIN;
85     s->uts1 = UTS1_RXEMPTY | UTS1_TXEMPTY;
86     s->ucr1 = 0;
87     s->ucr2 = UCR2_SRST;
88     s->ucr3 = 0x700;
89     s->ubmr = 0;
90     s->ubrc = 4;
91     s->readbuff = URXD_ERR;
92 }
93 
94 static void imx_serial_reset_at_boot(DeviceState *dev)
95 {
96     IMXSerialState *s = IMX_SERIAL(dev);
97 
98     imx_serial_reset(s);
99 
100     /*
101      * enable the uart on boot, so messages from the linux decompresser
102      * are visible.  On real hardware this is done by the boot rom
103      * before anything else is loaded.
104      */
105     s->ucr1 = UCR1_UARTEN;
106     s->ucr2 = UCR2_TXEN;
107 
108 }
109 
110 static uint64_t imx_serial_read(void *opaque, hwaddr offset,
111                                 unsigned size)
112 {
113     IMXSerialState *s = (IMXSerialState *)opaque;
114     uint32_t c;
115 
116     DPRINTF("read(offset=%x)\n", offset >> 2);
117     switch (offset >> 2) {
118     case 0x0: /* URXD */
119         c = s->readbuff;
120         if (!(s->uts1 & UTS1_RXEMPTY)) {
121             /* Character is valid */
122             c |= URXD_CHARRDY;
123             s->usr1 &= ~USR1_RRDY;
124             s->usr2 &= ~USR2_RDR;
125             s->uts1 |= UTS1_RXEMPTY;
126             imx_update(s);
127             if (s->chr) {
128                 qemu_chr_accept_input(s->chr);
129             }
130         }
131         return c;
132 
133     case 0x20: /* UCR1 */
134         return s->ucr1;
135 
136     case 0x21: /* UCR2 */
137         return s->ucr2;
138 
139     case 0x25: /* USR1 */
140         return s->usr1;
141 
142     case 0x26: /* USR2 */
143         return s->usr2;
144 
145     case 0x2A: /* BRM Modulator */
146         return s->ubmr;
147 
148     case 0x2B: /* Baud Rate Count */
149         return s->ubrc;
150 
151     case 0x2d: /* Test register */
152         return s->uts1;
153 
154     case 0x24: /* UFCR */
155         return s->ufcr;
156 
157     case 0x2c:
158         return s->onems;
159 
160     case 0x22: /* UCR3 */
161         return s->ucr3;
162 
163     case 0x23: /* UCR4 */
164     case 0x29: /* BRM Incremental */
165         return 0x0; /* TODO */
166 
167     default:
168         IPRINTF("%s: bad offset: 0x%x\n", __func__, (int)offset);
169         return 0;
170     }
171 }
172 
173 static void imx_serial_write(void *opaque, hwaddr offset,
174                              uint64_t value, unsigned size)
175 {
176     IMXSerialState *s = (IMXSerialState *)opaque;
177     unsigned char ch;
178 
179     DPRINTF("write(offset=%x, value = %x) to %s\n",
180             offset >> 2,
181             (unsigned int)value, s->chr ? s->chr->label : "NODEV");
182 
183     switch (offset >> 2) {
184     case 0x10: /* UTXD */
185         ch = value;
186         if (s->ucr2 & UCR2_TXEN) {
187             if (s->chr) {
188                 qemu_chr_fe_write(s->chr, &ch, 1);
189             }
190             s->usr1 &= ~USR1_TRDY;
191             imx_update(s);
192             s->usr1 |= USR1_TRDY;
193             imx_update(s);
194         }
195         break;
196 
197     case 0x20: /* UCR1 */
198         s->ucr1 = value & 0xffff;
199         DPRINTF("write(ucr1=%x)\n", (unsigned int)value);
200         imx_update(s);
201         break;
202 
203     case 0x21: /* UCR2 */
204         /*
205          * Only a few bits in control register 2 are implemented as yet.
206          * If it's intended to use a real serial device as a back-end, this
207          * register will have to be implemented more fully.
208          */
209         if (!(value & UCR2_SRST)) {
210             imx_serial_reset(s);
211             imx_update(s);
212             value |= UCR2_SRST;
213         }
214         if (value & UCR2_RXEN) {
215             if (!(s->ucr2 & UCR2_RXEN)) {
216                 if (s->chr) {
217                     qemu_chr_accept_input(s->chr);
218                 }
219             }
220         }
221         s->ucr2 = value & 0xffff;
222         break;
223 
224     case 0x25: /* USR1 */
225         value &= USR1_AWAKE | USR1_AIRINT | USR1_DTRD | USR1_AGTIM |
226                  USR1_FRAMERR | USR1_ESCF | USR1_RTSD | USR1_PARTYER;
227         s->usr1 &= ~value;
228         break;
229 
230     case 0x26: /* USR2 */
231         /*
232          * Writing 1 to some bits clears them; all other
233          * values are ignored
234          */
235         value &= USR2_ADET | USR2_DTRF | USR2_IDLE | USR2_ACST |
236                  USR2_RIDELT | USR2_IRINT | USR2_WAKE |
237                  USR2_DCDDELT | USR2_RTSF | USR2_BRCD | USR2_ORE;
238         s->usr2 &= ~value;
239         break;
240 
241     /*
242      * Linux expects to see what it writes to these registers
243      * We don't currently alter the baud rate
244      */
245     case 0x29: /* UBIR */
246         s->ubrc = value & 0xffff;
247         break;
248 
249     case 0x2a: /* UBMR */
250         s->ubmr = value & 0xffff;
251         break;
252 
253     case 0x2c: /* One ms reg */
254         s->onems = value & 0xffff;
255         break;
256 
257     case 0x24: /* FIFO control register */
258         s->ufcr = value & 0xffff;
259         break;
260 
261     case 0x22: /* UCR3 */
262         s->ucr3 = value & 0xffff;
263         break;
264 
265     case 0x2d: /* UTS1 */
266     case 0x23: /* UCR4 */
267         IPRINTF("Unimplemented Register %x written to\n", offset >> 2);
268         /* TODO */
269         break;
270 
271     default:
272         IPRINTF("%s: Bad offset 0x%x\n", __func__, (int)offset);
273     }
274 }
275 
276 static int imx_can_receive(void *opaque)
277 {
278     IMXSerialState *s = (IMXSerialState *)opaque;
279     return !(s->usr1 & USR1_RRDY);
280 }
281 
282 static void imx_put_data(void *opaque, uint32_t value)
283 {
284     IMXSerialState *s = (IMXSerialState *)opaque;
285     DPRINTF("received char\n");
286     s->usr1 |= USR1_RRDY;
287     s->usr2 |= USR2_RDR;
288     s->uts1 &= ~UTS1_RXEMPTY;
289     s->readbuff = value;
290     imx_update(s);
291 }
292 
293 static void imx_receive(void *opaque, const uint8_t *buf, int size)
294 {
295     imx_put_data(opaque, *buf);
296 }
297 
298 static void imx_event(void *opaque, int event)
299 {
300     if (event == CHR_EVENT_BREAK) {
301         imx_put_data(opaque, URXD_BRK);
302     }
303 }
304 
305 
306 static const struct MemoryRegionOps imx_serial_ops = {
307     .read = imx_serial_read,
308     .write = imx_serial_write,
309     .endianness = DEVICE_NATIVE_ENDIAN,
310 };
311 
312 static void imx_serial_realize(DeviceState *dev, Error **errp)
313 {
314     IMXSerialState *s = IMX_SERIAL(dev);
315 
316     if (s->chr) {
317         qemu_chr_add_handlers(s->chr, imx_can_receive, imx_receive,
318                               imx_event, s);
319     } else {
320         DPRINTF("No char dev for uart at 0x%lx\n",
321                 (unsigned long)s->iomem.ram_addr);
322     }
323 }
324 
325 static void imx_serial_init(Object *obj)
326 {
327     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
328     IMXSerialState *s = IMX_SERIAL(obj);
329 
330     memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s,
331                           TYPE_IMX_SERIAL, 0x1000);
332     sysbus_init_mmio(sbd, &s->iomem);
333     sysbus_init_irq(sbd, &s->irq);
334 }
335 
336 static Property imx_serial_properties[] = {
337     DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
338     DEFINE_PROP_END_OF_LIST(),
339 };
340 
341 static void imx_serial_class_init(ObjectClass *klass, void *data)
342 {
343     DeviceClass *dc = DEVICE_CLASS(klass);
344 
345     dc->realize = imx_serial_realize;
346     dc->vmsd = &vmstate_imx_serial;
347     dc->reset = imx_serial_reset_at_boot;
348     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
349     dc->desc = "i.MX series UART";
350     dc->props = imx_serial_properties;
351 }
352 
353 static const TypeInfo imx_serial_info = {
354     .name           = TYPE_IMX_SERIAL,
355     .parent         = TYPE_SYS_BUS_DEVICE,
356     .instance_size  = sizeof(IMXSerialState),
357     .instance_init  = imx_serial_init,
358     .class_init     = imx_serial_class_init,
359 };
360 
361 static void imx_serial_register_types(void)
362 {
363     type_register_static(&imx_serial_info);
364 }
365 
366 type_init(imx_serial_register_types)
367