Lines Matching +full:data +full:- +full:channel

26 #include "qemu/error-report.h"
29 #include "chardev/char-fe.h"
30 #include "chardev/char-serial.h"
34 #include "hw/qdev-properties.h"
35 #include "hw/qdev-properties-system.h"
64 * 'reg' - register offset (see offsets definitions above)
137 uint8_t *data; member
161 uint32_t channel; member
184 q->data[q->sp] = ch; in fifo_store()
185 q->sp = (q->sp + 1) % q->size; in fifo_store()
190 uint8_t ret = q->data[q->rp]; in fifo_retrieve()
191 q->rp = (q->rp + 1) % q->size; in fifo_retrieve()
197 if (q->sp < q->rp) { in fifo_elements_number()
198 return q->size - q->rp + q->sp; in fifo_elements_number()
201 return q->sp - q->rp; in fifo_elements_number()
206 return q->size - fifo_elements_number(q); in fifo_empty_elements_number()
211 g_free(q->data); in fifo_reset()
212 q->data = NULL; in fifo_reset()
214 q->data = g_malloc0(q->size); in fifo_reset()
216 q->sp = 0; in fifo_reset()
217 q->rp = 0; in fifo_reset()
220 static uint32_t exynos4210_uart_FIFO_trigger_level(uint32_t channel, in exynos4210_uart_FIFO_trigger_level() argument
225 switch (channel) { in exynos4210_uart_FIFO_trigger_level()
239 trace_exynos_uart_channel_error(channel); in exynos4210_uart_FIFO_trigger_level()
250 reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >> in exynos4210_uart_Tx_FIFO_trigger_level()
253 return exynos4210_uart_FIFO_trigger_level(s->channel, reg); in exynos4210_uart_Tx_FIFO_trigger_level()
261 reg = ((s->reg[I_(UFCON)] & UFCON_Rx_FIFO_TRIGGER_LEVEL) >> in exynos4210_uart_Rx_FIFO_trigger_level()
264 return exynos4210_uart_FIFO_trigger_level(s->channel, reg); in exynos4210_uart_Rx_FIFO_trigger_level()
273 bool rx_dma_enabled = (s->reg[I_(UCON)] & 0x03) == 0x02; in exynos4210_uart_update_dmabusy()
274 uint32_t count = fifo_elements_number(&s->rx); in exynos4210_uart_update_dmabusy()
277 qemu_irq_raise(s->dmairq); in exynos4210_uart_update_dmabusy()
278 trace_exynos_uart_dmabusy(s->channel); in exynos4210_uart_update_dmabusy()
280 qemu_irq_lower(s->dmairq); in exynos4210_uart_update_dmabusy()
281 trace_exynos_uart_dmaready(s->channel); in exynos4210_uart_update_dmabusy()
288 * The Tx interrupt is always requested if the number of data in the in exynos4210_uart_update_irq()
291 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { in exynos4210_uart_update_irq()
292 uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >> in exynos4210_uart_update_irq()
296 s->reg[I_(UINTSP)] |= UINTSP_TXD; in exynos4210_uart_update_irq()
301 * interrupt is disabled and there is data in the receive buffer in exynos4210_uart_update_irq()
303 count = fifo_elements_number(&s->rx); in exynos4210_uart_update_irq()
304 if ((count && !(s->reg[I_(UCON)] & 0x80)) || in exynos4210_uart_update_irq()
307 s->reg[I_(UINTSP)] |= UINTSP_RXD; in exynos4210_uart_update_irq()
308 timer_del(s->fifo_timeout_timer); in exynos4210_uart_update_irq()
310 } else if (s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) { in exynos4210_uart_update_irq()
312 s->reg[I_(UINTSP)] |= UINTSP_RXD; in exynos4210_uart_update_irq()
315 s->reg[I_(UINTP)] = s->reg[I_(UINTSP)] & ~s->reg[I_(UINTM)]; in exynos4210_uart_update_irq()
317 if (s->reg[I_(UINTP)]) { in exynos4210_uart_update_irq()
318 qemu_irq_raise(s->irq); in exynos4210_uart_update_irq()
319 trace_exynos_uart_irq_raised(s->channel, s->reg[I_(UINTP)]); in exynos4210_uart_update_irq()
321 qemu_irq_lower(s->irq); in exynos4210_uart_update_irq()
322 trace_exynos_uart_irq_lowered(s->channel); in exynos4210_uart_update_irq()
330 trace_exynos_uart_rx_timeout(s->channel, s->reg[I_(UTRSTAT)], in exynos4210_uart_timeout_int()
331 s->reg[I_(UINTSP)]); in exynos4210_uart_timeout_int()
333 if ((s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY) || in exynos4210_uart_timeout_int()
334 (s->reg[I_(UCON)] & (1 << 11))) { in exynos4210_uart_timeout_int()
335 s->reg[I_(UINTSP)] |= UINTSP_RXD; in exynos4210_uart_timeout_int()
336 s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_TIMEOUT; in exynos4210_uart_timeout_int()
348 if (s->reg[I_(UBRDIV)] == 0) { in exynos4210_uart_update_parameters()
352 if (s->reg[I_(ULCON)] & 0x20) { in exynos4210_uart_update_parameters()
353 if (s->reg[I_(ULCON)] & 0x28) { in exynos4210_uart_update_parameters()
362 if (s->reg[I_(ULCON)] & 0x4) { in exynos4210_uart_update_parameters()
368 data_bits = (s->reg[I_(ULCON)] & 0x3) + 5; in exynos4210_uart_update_parameters()
372 speed = uclk_rate / ((16 * (s->reg[I_(UBRDIV)]) & 0xffff) + in exynos4210_uart_update_parameters()
373 (s->reg[I_(UFRACVAL)] & 0x7) + 16); in exynos4210_uart_update_parameters()
380 s->wordtime = NANOSECONDS_PER_SECOND * (data_bits + stop_bits + 1) / speed; in exynos4210_uart_update_parameters()
382 qemu_chr_fe_ioctl(&s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp); in exynos4210_uart_update_parameters()
385 s->channel, speed, parity, data_bits, stop_bits, s->wordtime); in exynos4210_uart_update_parameters()
390 if (s->reg[I_(UCON)] & 0x80) { in exynos4210_uart_rx_timeout_set()
391 uint32_t timeout = ((s->reg[I_(UCON)] >> 12) & 0x0f) * s->wordtime; in exynos4210_uart_rx_timeout_set()
393 timer_mod(s->fifo_timeout_timer, in exynos4210_uart_rx_timeout_set()
396 timer_del(s->fifo_timeout_timer); in exynos4210_uart_rx_timeout_set()
406 trace_exynos_uart_write(s->channel, offset, in exynos4210_uart_write()
413 s->reg[I_(offset)] = val; in exynos4210_uart_write()
417 s->reg[I_(UFCON)] = val; in exynos4210_uart_write()
419 fifo_reset(&s->rx); in exynos4210_uart_write()
420 s->reg[I_(UFCON)] &= ~UFCON_Rx_FIFO_RESET; in exynos4210_uart_write()
421 trace_exynos_uart_rx_fifo_reset(s->channel); in exynos4210_uart_write()
424 fifo_reset(&s->tx); in exynos4210_uart_write()
425 s->reg[I_(UFCON)] &= ~UFCON_Tx_FIFO_RESET; in exynos4210_uart_write()
426 trace_exynos_uart_tx_fifo_reset(s->channel); in exynos4210_uart_write()
431 if (qemu_chr_fe_backend_connected(&s->chr)) { in exynos4210_uart_write()
432 s->reg[I_(UTRSTAT)] &= ~(UTRSTAT_TRANSMITTER_EMPTY | in exynos4210_uart_write()
437 qemu_chr_fe_write_all(&s->chr, &ch, 1); in exynos4210_uart_write()
438 trace_exynos_uart_tx(s->channel, ch); in exynos4210_uart_write()
439 s->reg[I_(UTRSTAT)] |= UTRSTAT_TRANSMITTER_EMPTY | in exynos4210_uart_write()
441 s->reg[I_(UINTSP)] |= UINTSP_TXD; in exynos4210_uart_write()
447 s->reg[I_(UINTP)] &= ~val; in exynos4210_uart_write()
448 s->reg[I_(UINTSP)] &= ~val; in exynos4210_uart_write()
449 trace_exynos_uart_intclr(s->channel, s->reg[I_(UINTP)]); in exynos4210_uart_write()
454 s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_TIMEOUT; in exynos4210_uart_write()
462 s->channel, exynos4210_uart_regname(offset), offset); in exynos4210_uart_write()
465 s->reg[I_(UINTSP)] &= ~val; in exynos4210_uart_write()
468 s->reg[I_(UINTM)] = val; in exynos4210_uart_write()
474 s->reg[I_(offset)] = val; in exynos4210_uart_write()
487 res = s->reg[I_(UERSTAT)]; in exynos4210_uart_read()
488 s->reg[I_(UERSTAT)] = 0; in exynos4210_uart_read()
489 trace_exynos_uart_read(s->channel, offset, in exynos4210_uart_read()
493 s->reg[I_(UFSTAT)] = fifo_elements_number(&s->rx) & 0xff; in exynos4210_uart_read()
494 if (fifo_empty_elements_number(&s->rx) == 0) { in exynos4210_uart_read()
495 s->reg[I_(UFSTAT)] |= UFSTAT_Rx_FIFO_FULL; in exynos4210_uart_read()
496 s->reg[I_(UFSTAT)] &= ~0xff; in exynos4210_uart_read()
498 trace_exynos_uart_read(s->channel, offset, in exynos4210_uart_read()
500 s->reg[I_(UFSTAT)]); in exynos4210_uart_read()
501 return s->reg[I_(UFSTAT)]; in exynos4210_uart_read()
503 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { in exynos4210_uart_read()
504 if (fifo_elements_number(&s->rx)) { in exynos4210_uart_read()
505 res = fifo_retrieve(&s->rx); in exynos4210_uart_read()
506 trace_exynos_uart_rx(s->channel, res); in exynos4210_uart_read()
507 if (!fifo_elements_number(&s->rx)) { in exynos4210_uart_read()
508 s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; in exynos4210_uart_read()
510 s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; in exynos4210_uart_read()
513 trace_exynos_uart_rx_error(s->channel); in exynos4210_uart_read()
514 s->reg[I_(UINTSP)] |= UINTSP_ERROR; in exynos4210_uart_read()
519 s->reg[I_(UTRSTAT)] &= ~UTRSTAT_Rx_BUFFER_DATA_READY; in exynos4210_uart_read()
520 res = s->reg[I_(URXH)]; in exynos4210_uart_read()
522 qemu_chr_fe_accept_input(&s->chr); in exynos4210_uart_read()
524 trace_exynos_uart_read(s->channel, offset, in exynos4210_uart_read()
528 trace_exynos_uart_wo_read(s->channel, exynos4210_uart_regname(offset), in exynos4210_uart_read()
532 trace_exynos_uart_read(s->channel, offset, in exynos4210_uart_read()
534 s->reg[I_(offset)]); in exynos4210_uart_read()
535 return s->reg[I_(offset)]; in exynos4210_uart_read()
538 trace_exynos_uart_read(s->channel, offset, exynos4210_uart_regname(offset), in exynos4210_uart_read()
557 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { in exynos4210_uart_can_receive()
558 return fifo_empty_elements_number(&s->rx); in exynos4210_uart_can_receive()
560 return !(s->reg[I_(UTRSTAT)] & UTRSTAT_Rx_BUFFER_DATA_READY); in exynos4210_uart_can_receive()
569 if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) { in exynos4210_uart_receive()
570 if (fifo_empty_elements_number(&s->rx) < size) { in exynos4210_uart_receive()
571 size = fifo_empty_elements_number(&s->rx); in exynos4210_uart_receive()
572 s->reg[I_(UINTSP)] |= UINTSP_ERROR; in exynos4210_uart_receive()
575 fifo_store(&s->rx, buf[i]); in exynos4210_uart_receive()
579 s->reg[I_(URXH)] = buf[0]; in exynos4210_uart_receive()
581 s->reg[I_(UTRSTAT)] |= UTRSTAT_Rx_BUFFER_DATA_READY; in exynos4210_uart_receive()
594 fifo_store(&s->rx, '\0'); in exynos4210_uart_event()
595 s->reg[I_(UERSTAT)] |= UERSTAT_BREAK; in exynos4210_uart_event()
607 s->reg[I_(exynos4210_uart_regs[i].offset)] = in exynos4210_uart_reset()
611 fifo_reset(&s->rx); in exynos4210_uart_reset()
612 fifo_reset(&s->tx); in exynos4210_uart_reset()
614 trace_exynos_uart_rxsize(s->channel, s->rx.size); in exynos4210_uart_reset()
634 VMSTATE_VBUFFER_UINT32(data, Exynos4210UartFIFO, 1, NULL, size),
655 int channel, in exynos4210_uart_create() argument
665 qdev_prop_set_uint32(dev, "channel", channel); in exynos4210_uart_create()
666 qdev_prop_set_uint32(dev, "rx-size", fifo_size); in exynos4210_uart_create()
667 qdev_prop_set_uint32(dev, "tx-size", fifo_size); in exynos4210_uart_create()
671 if (addr != (hwaddr)-1) { in exynos4210_uart_create()
684 s->wordtime = NANOSECONDS_PER_SECOND * 10 / 9600; in exynos4210_uart_init()
687 memory_region_init_io(&s->iomem, obj, &exynos4210_uart_ops, s, in exynos4210_uart_init()
689 sysbus_init_mmio(dev, &s->iomem); in exynos4210_uart_init()
691 sysbus_init_irq(dev, &s->irq); in exynos4210_uart_init()
692 sysbus_init_irq(dev, &s->dmairq); in exynos4210_uart_init()
699 s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, in exynos4210_uart_realize()
702 qemu_chr_fe_set_handlers(&s->chr, exynos4210_uart_can_receive, in exynos4210_uart_realize()
709 DEFINE_PROP_UINT32("channel", Exynos4210UartState, channel, 0),
710 DEFINE_PROP_UINT32("rx-size", Exynos4210UartState, rx.size, 16),
711 DEFINE_PROP_UINT32("tx-size", Exynos4210UartState, tx.size, 16),
714 static void exynos4210_uart_class_init(ObjectClass *klass, const void *data) in exynos4210_uart_class_init() argument
718 dc->realize = exynos4210_uart_realize; in exynos4210_uart_class_init()
721 dc->vmsd = &vmstate_exynos4210_uart; in exynos4210_uart_class_init()