Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / hw / char / imx_serial.c
blob22c9080b1c7b203689e9f83bd1c7117d4283ba3c
1 /*
2 * IMX31 UARTS
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>
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.
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.
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"
31 #ifndef DEBUG_IMX_UART
32 #define DEBUG_IMX_UART 0
33 #endif
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)
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()
64 static void imx_update(IMXSerialState *s)
66 uint32_t usr1;
67 uint32_t usr2;
68 uint32_t mask;
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:
75 usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
77 * Interrupt if AGTIM is set (ageing timer interrupt in RxFIFO)
79 usr1 |= (s->ucr2 & UCR2_ATEN) ? (s->usr1 & USR1_AGTIM) : 0;
81 * Bits that we want in USR2 are not as conveniently laid out,
82 * unfortunately.
84 mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
86 * TCEN and TXDC are both bit 3
87 * ORE and OREN are both bit 1
88 * RDR and DREN are both bit 0
90 mask |= s->ucr4 & (UCR4_WKEN | UCR4_TCEN | UCR4_DREN | UCR4_OREN);
92 usr2 = s->usr2 & mask;
94 qemu_set_irq(s->irq, usr1 || usr2);
97 static void imx_serial_rx_fifo_push(IMXSerialState *s, uint32_t value)
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;
108 fifo32_push(&s->rx_fifo, pushed_value);
112 static uint32_t imx_serial_rx_fifo_pop(IMXSerialState *s)
114 if (fifo32_is_empty(&s->rx_fifo)) {
115 return 0;
117 return fifo32_pop(&s->rx_fifo);
120 static void imx_serial_rx_fifo_ageing_timer_int(void *opaque)
122 IMXSerialState *s = (IMXSerialState *) opaque;
123 s->usr1 |= USR1_AGTIM;
124 imx_update(s);
127 static void imx_serial_rx_fifo_ageing_timer_restart(void *opaque)
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).
137 IMXSerialState *s = (IMXSerialState *) opaque;
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);
147 static void imx_serial_reset(IMXSerialState *s)
150 s->usr1 = USR1_TRDY | USR1_RXDS;
152 * Fake attachment of a terminal: assert RTS.
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;
163 fifo32_reset(&s->rx_fifo);
164 timer_del(&s->ageing_timer);
167 static void imx_serial_reset_at_boot(DeviceState *dev)
169 IMXSerialState *s = IMX_SERIAL(dev);
171 imx_serial_reset(s);
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.
178 s->ucr1 = UCR1_UARTEN;
179 s->ucr2 = UCR2_TXEN;
183 static uint64_t imx_serial_read(void *opaque, hwaddr offset,
184 unsigned size)
186 IMXSerialState *s = (IMXSerialState *)opaque;
187 uint32_t c, rx_used;
188 uint8_t rxtl = s->ufcr & TL_MASK;
190 DPRINTF("read(offset=0x%" HWADDR_PRIx ")\n", offset);
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;
203 if (rx_used == 0) {
204 s->usr2 &= ~USR2_RDR;
205 s->uts1 |= UTS1_RXEMPTY;
207 imx_update(s);
208 imx_serial_rx_fifo_ageing_timer_restart(s);
209 qemu_chr_fe_accept_input(&s->chr);
211 return c;
213 case 0x20: /* UCR1 */
214 return s->ucr1;
216 case 0x21: /* UCR2 */
217 return s->ucr2;
219 case 0x25: /* USR1 */
220 return s->usr1;
222 case 0x26: /* USR2 */
223 return s->usr2;
225 case 0x2A: /* BRM Modulator */
226 return s->ubmr;
228 case 0x2B: /* Baud Rate Count */
229 return s->ubrc;
231 case 0x2d: /* Test register */
232 return s->uts1;
234 case 0x24: /* UFCR */
235 return s->ufcr;
237 case 0x2c:
238 return s->onems;
240 case 0x22: /* UCR3 */
241 return s->ucr3;
243 case 0x23: /* UCR4 */
244 return s->ucr4;
246 case 0x29: /* BRM Incremental */
247 return 0x0; /* TODO */
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;
256 static void imx_serial_write(void *opaque, hwaddr offset,
257 uint64_t value, unsigned size)
259 IMXSerialState *s = (IMXSerialState *)opaque;
260 Chardev *chr = qemu_chr_fe_get_driver(&s->chr);
261 unsigned char ch;
263 DPRINTF("write(offset=0x%" HWADDR_PRIx ", value = 0x%x) to %s\n",
264 offset, (unsigned int)value, chr ? chr->label : "NODEV");
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);
280 break;
282 case 0x20: /* UCR1 */
283 s->ucr1 = value & 0xffff;
285 DPRINTF("write(ucr1=%x)\n", (unsigned int)value);
287 imx_update(s);
288 break;
290 case 0x21: /* UCR2 */
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.
296 if (!(value & UCR2_SRST)) {
297 imx_serial_reset(s);
298 imx_update(s);
299 value |= UCR2_SRST;
301 if (value & UCR2_RXEN) {
302 if (!(s->ucr2 & UCR2_RXEN)) {
303 qemu_chr_fe_accept_input(&s->chr);
306 s->ucr2 = value & 0xffff;
307 break;
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;
315 case 0x26: /* USR2 */
317 * Writing 1 to some bits clears them; all other
318 * values are ignored
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;
327 * Linux expects to see what it writes to these registers
328 * We don't currently alter the baud rate
330 case 0x29: /* UBIR */
331 s->ubrc = value & 0xffff;
332 break;
334 case 0x2a: /* UBMR */
335 s->ubmr = value & 0xffff;
336 break;
338 case 0x2c: /* One ms reg */
339 s->onems = value & 0xffff;
340 break;
342 case 0x24: /* FIFO control register */
343 s->ufcr = value & 0xffff;
344 break;
346 case 0x22: /* UCR3 */
347 s->ucr3 = value & 0xffff;
348 break;
350 case 0x23: /* UCR4 */
351 s->ucr4 = value & 0xffff;
352 imx_update(s);
353 break;
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;
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);
367 static int imx_can_receive(void *opaque)
369 IMXSerialState *s = (IMXSerialState *)opaque;
370 return s->ucr2 & UCR2_RXEN && fifo32_num_used(&s->rx_fifo) < FIFO_SIZE;
373 static void imx_put_data(void *opaque, uint32_t value)
375 IMXSerialState *s = (IMXSerialState *)opaque;
376 uint8_t rxtl = s->ufcr & TL_MASK;
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;
384 imx_serial_rx_fifo_ageing_timer_restart(s);
386 s->usr2 |= USR2_RDR;
387 s->uts1 &= ~UTS1_RXEMPTY;
388 if (value & URXD_BRK) {
389 s->usr2 |= USR2_BRCD;
391 imx_update(s);
394 static void imx_receive(void *opaque, const uint8_t *buf, int size)
396 IMXSerialState *s = (IMXSerialState *)opaque;
398 s->usr2 |= USR2_WAKE;
399 imx_put_data(opaque, *buf);
402 static void imx_event(void *opaque, QEMUChrEvent event)
404 if (event == CHR_EVENT_BREAK) {
405 imx_put_data(opaque, URXD_BRK | URXD_FRMERR | URXD_ERR);
410 static const struct MemoryRegionOps imx_serial_ops = {
411 .read = imx_serial_read,
412 .write = imx_serial_write,
413 .endianness = DEVICE_NATIVE_ENDIAN,
416 static void imx_serial_realize(DeviceState *dev, Error **errp)
418 IMXSerialState *s = IMX_SERIAL(dev);
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);
424 DPRINTF("char dev for uart: %p\n", qemu_chr_fe_get_driver(&s->chr));
426 qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive,
427 imx_event, NULL, s, NULL, true);
430 static void imx_serial_init(Object *obj)
432 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
433 IMXSerialState *s = IMX_SERIAL(obj);
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);
441 static Property imx_serial_properties[] = {
442 DEFINE_PROP_CHR("chardev", IMXSerialState, chr),
443 DEFINE_PROP_END_OF_LIST(),
446 static void imx_serial_class_init(ObjectClass *klass, void *data)
448 DeviceClass *dc = DEVICE_CLASS(klass);
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);
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,
466 static void imx_serial_register_types(void)
468 type_register_static(&imx_serial_info);
471 type_init(imx_serial_register_types)