Lines Matching +full:rclk +full:-
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
102 while ((inb(stat) & LSR_THRE) == 0 && --limit > 0) in uart_ns8250_early_putc()
160 return (16000000 * divisor / bas->rclk); in ns8250_delay()
161 return (16000 * divisor / (bas->rclk / 1000)); in ns8250_delay()
165 ns8250_divisor(int rclk, int baudrate) in ns8250_divisor() argument
173 divisor = (rclk / (baudrate << 3) + 1) >> 1; in ns8250_divisor()
176 actual_baud = rclk / (divisor << 4); in ns8250_divisor()
179 error = ((actual_baud - baudrate) * 2000 / baudrate + 1) / 2; in ns8250_divisor()
182 if (error < -UART_DEV_TOLERANCE_PCT || error > UART_DEV_TOLERANCE_PCT) in ns8250_divisor()
202 while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit) in ns8250_drain()
224 while (limit && (uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) { in ns8250_drain()
228 } while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit); in ns8250_drain()
264 * Firecracker VMM, aka. the rust-vmm/vm-superio emulation code: in ns8250_flush()
265 * https://github.com/rust-vmm/vm-superio/issues/83 in ns8250_flush()
285 /* Don't change settings when running on Hyper-V */ in ns8250_param()
302 /* Set baudrate if we know a rclk and both are not 0. */ in ns8250_param()
303 if (baudrate > 0 && bas->rclk > 0) { in ns8250_param()
304 divisor = ns8250_divisor(bas->rclk, baudrate); in ns8250_param()
321 * Low-level UART interface.
370 * UARTs split the receive time-out interrupt bit out separately as in ns8250_init()
378 * Loader tells us to infer the rclk when it sets xo to 0 in in ns8250_init()
380 * calculate rclk from baudrate and the divisor register. If 'div' is in ns8250_init()
382 * rclk methods. in ns8250_init()
384 if (bas->rclk_guess && bas->rclk == 0 && baudrate != 0) { in ns8250_init()
388 bas->rclk = baudrate * div * 16; in ns8250_init()
396 if (bas->rclk == 0 && baudrate != 0) in ns8250_init()
397 bas->rclk = DEFAULT_RCLK; in ns8250_init()
428 while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit) in ns8250_putc()
492 * XXX -- refactor out ACPI and FDT ifdefs
505 {"PNP0501", &uart_ns8250_class, 0, 0, 0, 0, 0, "16550A-compatible COM port"},
506 {"PNP0502", &uart_ns8250_class, 0, 0, 0, 0, 0, "Multiport serial device (non-intelligent 16550)"},
507 {"PNP0510", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
508 {"PNP0511", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"},
526 /* Use token-pasting to form SER_ and MSR_ named constants. */
575 node = ofw_bus_get_node(sc->sc_dev); in ns8250_bus_attach()
576 if ((OF_getencprop(node, "broken-txfifo", &cell, sizeof(cell))) > 0) in ns8250_bus_attach()
580 bas = &sc->sc_bas; in ns8250_bus_attach()
582 ns8250->busy_detect = bas->busy_detect; in ns8250_bus_attach()
583 ns8250->mcr = uart_getreg(bas, REG_MCR); in ns8250_bus_attach()
584 ns8250->fcr = FCR_ENABLE; in ns8250_bus_attach()
585 if (!resource_int_value("uart", device_get_unit(sc->sc_dev), "flags", in ns8250_bus_attach()
588 ns8250->fcr |= FCR_RX_LOW; in ns8250_bus_attach()
590 ns8250->fcr |= FCR_RX_MEDL; in ns8250_bus_attach()
592 ns8250->fcr |= FCR_RX_HIGH; in ns8250_bus_attach()
594 ns8250->fcr |= FCR_RX_MEDH; in ns8250_bus_attach()
596 ns8250->fcr |= FCR_RX_MEDH; in ns8250_bus_attach()
600 resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_mask", in ns8250_bus_attach()
602 ns8250->ier_mask = (uint8_t)(ivar & 0xff); in ns8250_bus_attach()
606 resource_int_value("uart", device_get_unit(sc->sc_dev), "ier_rxbits", in ns8250_bus_attach()
608 ns8250->ier_rxbits = (uint8_t)(ivar & 0xff); in ns8250_bus_attach()
610 uart_setreg(bas, REG_FCR, ns8250->fcr); in ns8250_bus_attach()
614 if (ns8250->mcr & MCR_DTR) in ns8250_bus_attach()
615 sc->sc_hwsig |= SER_DTR; in ns8250_bus_attach()
616 if (ns8250->mcr & MCR_RTS) in ns8250_bus_attach()
617 sc->sc_hwsig |= SER_RTS; in ns8250_bus_attach()
621 ns8250->ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; in ns8250_bus_attach()
622 ns8250->ier |= ns8250->ier_rxbits; in ns8250_bus_attach()
623 uart_setreg(bas, REG_IER, ns8250->ier); in ns8250_bus_attach()
631 * ns8250_bus_ipend() -- which it accidentally had before r253161. in ns8250_bus_attach()
649 bas = &sc->sc_bas; in ns8250_bus_detach()
650 ier = uart_getreg(bas, REG_IER) & ns8250->ier_mask; in ns8250_bus_detach()
664 bas = &sc->sc_bas; in ns8250_bus_flush()
665 uart_lock(sc->sc_hwmtx); in ns8250_bus_flush()
666 if (sc->sc_rxfifosz > 1) { in ns8250_bus_flush()
668 uart_setreg(bas, REG_FCR, ns8250->fcr); in ns8250_bus_flush()
673 uart_unlock(sc->sc_hwmtx); in ns8250_bus_flush()
689 * other (non-MSR) bits in sc_hwsig, so loop until it can successfully in ns8250_bus_getsig()
695 old = sc->sc_hwsig; in ns8250_bus_getsig()
697 uart_lock(sc->sc_hwmtx); in ns8250_bus_getsig()
698 msr = uart_getreg(&sc->sc_bas, REG_MSR); in ns8250_bus_getsig()
699 uart_unlock(sc->sc_hwmtx); in ns8250_bus_getsig()
700 if (sc->sc_pps_mode & UART_PPS_NARROW_PULSE) { in ns8250_bus_getsig()
710 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, sig & ~SER_MASK_DELTA)); in ns8250_bus_getsig()
721 bas = &sc->sc_bas; in ns8250_bus_ioctl()
723 uart_lock(sc->sc_hwmtx); in ns8250_bus_ioctl()
766 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0; in ns8250_bus_ioctl()
776 uart_unlock(sc->sc_hwmtx); in ns8250_bus_ioctl()
789 bas = &sc->sc_bas; in ns8250_bus_ipend()
790 uart_lock(sc->sc_hwmtx); in ns8250_bus_ipend()
793 if (ns8250->busy_detect && (iir & IIR_BUSY) == IIR_BUSY) { in ns8250_bus_ipend()
795 uart_unlock(sc->sc_hwmtx); in ns8250_bus_ipend()
799 uart_unlock(sc->sc_hwmtx); in ns8250_bus_ipend()
814 ns8250->ier &= ~IER_ETXRDY; in ns8250_bus_ipend()
815 uart_setreg(bas, REG_IER, ns8250->ier); in ns8250_bus_ipend()
822 uart_unlock(sc->sc_hwmtx); in ns8250_bus_ipend()
835 bas = &sc->sc_bas; in ns8250_bus_param()
836 uart_lock(sc->sc_hwmtx); in ns8250_bus_param()
842 if (ns8250->busy_detect != 0) { in ns8250_bus_param()
849 --limit) in ns8250_bus_param()
854 uart_unlock(sc->sc_hwmtx); in ns8250_bus_param()
860 uart_unlock(sc->sc_hwmtx); in ns8250_bus_param()
871 bas = &sc->sc_bas; in ns8250_bus_probe()
878 if (sc->sc_sysdev == NULL) { in ns8250_bus_probe()
891 * avoid the possibility that automatic flow-control prevents in ns8250_bus_probe()
911 sc->sc_rxfifosz = sc->sc_txfifosz = 1; in ns8250_bus_probe()
912 device_set_desc(sc->sc_dev, "8250 or 16450 or compatible"); in ns8250_bus_probe()
950 --limit) in ns8250_bus_probe()
963 count--; in ns8250_bus_probe()
972 sc->sc_rxfifosz = 16; in ns8250_bus_probe()
973 device_set_desc(sc->sc_dev, "16550 or compatible"); in ns8250_bus_probe()
975 sc->sc_rxfifosz = 32; in ns8250_bus_probe()
976 device_set_desc(sc->sc_dev, "16650 or compatible"); in ns8250_bus_probe()
978 sc->sc_rxfifosz = 64; in ns8250_bus_probe()
979 device_set_desc(sc->sc_dev, "16750 or compatible"); in ns8250_bus_probe()
981 sc->sc_rxfifosz = 128; in ns8250_bus_probe()
982 device_set_desc(sc->sc_dev, "16950 or compatible"); in ns8250_bus_probe()
984 sc->sc_rxfifosz = 256; in ns8250_bus_probe()
985 device_set_desc(sc->sc_dev, "16x50 with 256 byte FIFO"); in ns8250_bus_probe()
987 sc->sc_rxfifosz = 16; in ns8250_bus_probe()
988 device_set_desc(sc->sc_dev, in ns8250_bus_probe()
989 "Non-standard ns8250 class UART with FIFOs"); in ns8250_bus_probe()
997 sc->sc_txfifosz = 16; in ns8250_bus_probe()
1007 if (sc->sc_rxfifosz > 16) { in ns8250_bus_probe()
1008 sc->sc_hwiflow = 1; in ns8250_bus_probe()
1009 sc->sc_hwoflow = 1; in ns8250_bus_probe()
1024 bas = &sc->sc_bas; in ns8250_bus_receive()
1025 uart_lock(sc->sc_hwmtx); in ns8250_bus_receive()
1029 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; in ns8250_bus_receive()
1039 if (++ns8250->noise_count >= uart_noise_threshold) in ns8250_bus_receive()
1042 ns8250->noise_count = 0; in ns8250_bus_receive()
1057 uart_unlock(sc->sc_hwmtx); in ns8250_bus_receive()
1068 bas = &sc->sc_bas; in ns8250_bus_setsig()
1070 old = sc->sc_hwsig; in ns8250_bus_setsig()
1078 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); in ns8250_bus_setsig()
1079 uart_lock(sc->sc_hwmtx); in ns8250_bus_setsig()
1080 ns8250->mcr &= ~(MCR_DTR|MCR_RTS); in ns8250_bus_setsig()
1082 ns8250->mcr |= MCR_DTR; in ns8250_bus_setsig()
1084 ns8250->mcr |= MCR_RTS; in ns8250_bus_setsig()
1085 uart_setreg(bas, REG_MCR, ns8250->mcr); in ns8250_bus_setsig()
1087 uart_unlock(sc->sc_hwmtx); in ns8250_bus_setsig()
1098 bas = &sc->sc_bas; in ns8250_bus_transmit()
1099 uart_lock(sc->sc_hwmtx); in ns8250_bus_transmit()
1102 for (i = 0; i < sc->sc_txdatasz; i++) { in ns8250_bus_transmit()
1103 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); in ns8250_bus_transmit()
1107 ns8250->ier |= IER_ETXRDY; in ns8250_bus_transmit()
1108 uart_setreg(bas, REG_IER, ns8250->ier); in ns8250_bus_transmit()
1113 sc->sc_txbusy = 1; in ns8250_bus_transmit()
1114 uart_unlock(sc->sc_hwmtx); in ns8250_bus_transmit()
1123 struct uart_bas *bas = &sc->sc_bas; in ns8250_bus_txbusy()
1134 struct uart_bas *bas = &sc->sc_bas; in ns8250_bus_grab()
1143 uart_lock(sc->sc_hwmtx); in ns8250_bus_grab()
1145 uart_setreg(bas, REG_IER, ier & ns8250->ier_mask); in ns8250_bus_grab()
1147 uart_unlock(sc->sc_hwmtx); in ns8250_bus_grab()
1154 struct uart_bas *bas = &sc->sc_bas; in ns8250_bus_ungrab()
1159 uart_lock(sc->sc_hwmtx); in ns8250_bus_ungrab()
1160 uart_setreg(bas, REG_IER, ns8250->ier); in ns8250_bus_ungrab()
1162 uart_unlock(sc->sc_hwmtx); in ns8250_bus_ungrab()