Lines Matching +full:- +full:- +full:enable +full:- +full:trace +full:- +full:backend
7 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
10 * See the COPYING file in the top-level directory.
12 * This is a `bare-bones' implementation of the IMX series serial ports.
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
24 #include "hw/qdev-properties.h"
25 #include "hw/qdev-properties-system.h"
30 #include "trace.h"
76 usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY); in imx_update()
80 usr1 |= (s->ucr2 & UCR2_ATEN) ? (s->usr1 & USR1_AGTIM) : 0; in imx_update()
85 mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0; in imx_update()
91 mask |= s->ucr4 & (UCR4_WKEN | UCR4_TCEN | UCR4_DREN | UCR4_OREN); in imx_update()
93 usr2 = s->usr2 & mask; in imx_update()
95 qemu_set_irq(s->irq, usr1 || usr2); in imx_update()
101 if (fifo32_is_full(&s->rx_fifo)) { in imx_serial_rx_fifo_push()
103 s->usr2 |= USR2_ORE; in imx_serial_rx_fifo_push()
105 if (fifo32_num_used(&s->rx_fifo) == FIFO_SIZE - 1) { in imx_serial_rx_fifo_push()
109 fifo32_push(&s->rx_fifo, pushed_value); in imx_serial_rx_fifo_push()
115 if (fifo32_is_empty(&s->rx_fifo)) { in imx_serial_rx_fifo_pop()
118 return fifo32_pop(&s->rx_fifo); in imx_serial_rx_fifo_pop()
124 s->usr1 |= USR1_AGTIM; in imx_serial_rx_fifo_ageing_timer_int()
140 if (!(s->usr1 & USR1_RRDY) && !(s->uts1 & UTS1_RXEMPTY)) { in imx_serial_rx_fifo_ageing_timer_restart()
141 timer_mod_ns(&s->ageing_timer, in imx_serial_rx_fifo_ageing_timer_restart()
144 timer_del(&s->ageing_timer); in imx_serial_rx_fifo_ageing_timer_restart()
151 s->usr1 = USR1_TRDY | USR1_RXDS; in imx_serial_reset()
155 s->usr1 |= USR1_RTSS; in imx_serial_reset()
156 s->usr2 = USR2_TXFE | USR2_TXDC | USR2_DCDIN; in imx_serial_reset()
157 s->uts1 = UTS1_RXEMPTY | UTS1_TXEMPTY; in imx_serial_reset()
158 s->ucr1 = 0; in imx_serial_reset()
159 s->ucr2 = UCR2_SRST; in imx_serial_reset()
160 s->ucr3 = 0x700; in imx_serial_reset()
161 s->ubmr = 0; in imx_serial_reset()
162 s->ubrc = 4; in imx_serial_reset()
163 s->ufcr = BIT(11) | BIT(0); in imx_serial_reset()
165 fifo32_reset(&s->rx_fifo); in imx_serial_reset()
166 timer_del(&s->ageing_timer); in imx_serial_reset()
176 * enable the uart on boot, so messages from the linux decompressor in imx_serial_reset_at_boot()
180 s->ucr1 = UCR1_UARTEN; in imx_serial_reset_at_boot()
181 s->ucr2 = UCR2_TXEN; in imx_serial_reset_at_boot()
189 Chardev *chr = qemu_chr_fe_get_driver(&s->chr); in imx_serial_read()
191 uint8_t rxtl = s->ufcr & TL_MASK; in imx_serial_read()
197 if (!(s->uts1 & UTS1_RXEMPTY)) { in imx_serial_read()
200 rx_used = fifo32_num_used(&s->rx_fifo); in imx_serial_read()
203 s->usr1 &= ~USR1_RRDY; in imx_serial_read()
206 s->usr2 &= ~USR2_RDR; in imx_serial_read()
207 s->uts1 |= UTS1_RXEMPTY; in imx_serial_read()
211 qemu_chr_fe_accept_input(&s->chr); in imx_serial_read()
217 value = s->ucr1; in imx_serial_read()
221 value = s->ucr2; in imx_serial_read()
225 value = s->usr1; in imx_serial_read()
229 value = s->usr2; in imx_serial_read()
233 value = s->ubmr; in imx_serial_read()
237 value = s->ubrc; in imx_serial_read()
241 value = s->uts1; in imx_serial_read()
245 value = s->ufcr; in imx_serial_read()
249 value = s->onems; in imx_serial_read()
253 value = s->ucr3; in imx_serial_read()
257 value = s->ucr4; in imx_serial_read()
271 trace_imx_serial_read(chr ? chr->label : "NODEV", offset, value); in imx_serial_read()
280 Chardev *chr = qemu_chr_fe_get_driver(&s->chr); in imx_serial_write()
283 trace_imx_serial_write(chr ? chr->label : "NODEV", offset, value); in imx_serial_write()
288 if (s->ucr2 & UCR2_TXEN) { in imx_serial_write()
291 qemu_chr_fe_write_all(&s->chr, &ch, 1); in imx_serial_write()
292 s->usr1 &= ~USR1_TRDY; in imx_serial_write()
293 s->usr2 &= ~USR2_TXDC; in imx_serial_write()
295 s->usr1 |= USR1_TRDY; in imx_serial_write()
296 s->usr2 |= USR2_TXDC; in imx_serial_write()
302 s->ucr1 = value & 0xffff; in imx_serial_write()
312 * If it's intended to use a real serial device as a back-end, this in imx_serial_write()
321 if (!(s->ucr2 & UCR2_RXEN)) { in imx_serial_write()
322 qemu_chr_fe_accept_input(&s->chr); in imx_serial_write()
325 s->ucr2 = value & 0xffff; in imx_serial_write()
331 s->usr1 &= ~value; in imx_serial_write()
342 s->usr2 &= ~value; in imx_serial_write()
350 s->ubrc = value & 0xffff; in imx_serial_write()
354 s->ubmr = value & 0xffff; in imx_serial_write()
358 s->onems = value & 0xffff; in imx_serial_write()
362 s->ufcr = value & 0xffff; in imx_serial_write()
366 s->ucr3 = value & 0xffff; in imx_serial_write()
370 s->ucr4 = value & 0xffff; in imx_serial_write()
390 return s->ucr2 & UCR2_RXEN ? fifo32_num_free(&s->rx_fifo) : 0; in imx_can_receive()
396 Chardev *chr = qemu_chr_fe_get_driver(&s->chr); in imx_put_data()
397 uint8_t rxtl = s->ufcr & TL_MASK; in imx_put_data()
399 trace_imx_serial_put_data(chr ? chr->label : "NODEV", value); in imx_put_data()
402 if (fifo32_num_used(&s->rx_fifo) >= rxtl) { in imx_put_data()
403 s->usr1 |= USR1_RRDY; in imx_put_data()
405 s->usr2 |= USR2_RDR; in imx_put_data()
406 s->uts1 &= ~UTS1_RXEMPTY; in imx_put_data()
408 s->usr2 |= USR2_BRCD; in imx_put_data()
420 s->usr2 |= USR2_WAKE; in imx_receive()
445 fifo32_create(&s->rx_fifo, FIFO_SIZE); in imx_serial_realize()
446 timer_init_ns(&s->ageing_timer, QEMU_CLOCK_VIRTUAL, in imx_serial_realize()
449 DPRINTF("char dev for uart: %p\n", qemu_chr_fe_get_driver(&s->chr)); in imx_serial_realize()
451 qemu_chr_fe_set_handlers(&s->chr, imx_can_receive, imx_receive, in imx_serial_realize()
460 memory_region_init_io(&s->iomem, obj, &imx_serial_ops, s, in imx_serial_init()
462 sysbus_init_mmio(sbd, &s->iomem); in imx_serial_init()
463 sysbus_init_irq(sbd, &s->irq); in imx_serial_init()
474 dc->realize = imx_serial_realize; in imx_serial_class_init()
475 dc->vmsd = &vmstate_imx_serial; in imx_serial_class_init()
477 set_bit(DEVICE_CATEGORY_INPUT, dc->categories); in imx_serial_class_init()
478 dc->desc = "i.MX series UART"; in imx_serial_class_init()