Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/uart/uart_dev_ns8250.c
| Show First 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits, | ||||
| else if (databits == 6) | else if (databits == 6) | ||||
| lcr |= LCR_6BITS; | lcr |= LCR_6BITS; | ||||
| else | else | ||||
| lcr |= LCR_5BITS; | lcr |= LCR_5BITS; | ||||
| if (stopbits > 1) | if (stopbits > 1) | ||||
| lcr |= LCR_STOPB; | lcr |= LCR_STOPB; | ||||
| lcr |= parity << 3; | lcr |= parity << 3; | ||||
| /* Set baudrate. */ | /* Set baudrate if we know a rclk and both are not 0. */ | ||||
| if (baudrate > 0) { | if (baudrate > 0 && bas->rclk > 0) { | ||||
| divisor = ns8250_divisor(bas->rclk, baudrate); | divisor = ns8250_divisor(bas->rclk, baudrate); | ||||
| if (divisor == 0) | if (divisor == 0) | ||||
| return (EINVAL); | return (EINVAL); | ||||
| uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); | uart_setreg(bas, REG_LCR, lcr | LCR_DLAB); | ||||
| uart_barrier(bas); | uart_barrier(bas); | ||||
| uart_setreg(bas, REG_DLL, divisor & 0xff); | uart_setreg(bas, REG_DLL, divisor & 0xff); | ||||
| uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); | uart_setreg(bas, REG_DLH, (divisor >> 8) & 0xff); | ||||
| uart_barrier(bas); | uart_barrier(bas); | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, | ||||
| * We use 0xe0 instead of 0xf0 as the mask because the XScale PXA | * We use 0xe0 instead of 0xf0 as the mask because the XScale PXA | ||||
| * UARTs split the receive time-out interrupt bit out separately as | * UARTs split the receive time-out interrupt bit out separately as | ||||
| * 0x10. This gets handled by ier_mask and ier_rxbits below. | * 0x10. This gets handled by ier_mask and ier_rxbits below. | ||||
| */ | */ | ||||
| ier = uart_getreg(bas, REG_IER) & 0xe0; | ier = uart_getreg(bas, REG_IER) & 0xe0; | ||||
| uart_setreg(bas, REG_IER, ier); | uart_setreg(bas, REG_IER, ier); | ||||
| uart_barrier(bas); | uart_barrier(bas); | ||||
| if (bas->rclk == 0) | /* | ||||
| * Loader tells us to infer the rclk when it sets xo to 0 in | |||||
| * hw.uart.console. We know the baudrate was set by the firmware, so | |||||
| * calculate rclk from baudrate and the divisor register. If 'div' is | |||||
| * actually 0, the resulting 0 value will have us fall back to other | |||||
| * rclk methods. | |||||
| */ | |||||
| if (bas->rclk_guess && bas->rclk == 0 && baudrate != 0) { | |||||
| uint32_t div; | |||||
| div = ns8250_get_divisor(bas); | |||||
| bas->rclk = baudrate * div * 16; | |||||
| } | |||||
| /* | |||||
| * Pick a default because we just don't know. This likely needs future | |||||
| * refinement, but that's hard outside of consoles to know what to use. | |||||
| * But defer as long as possible if there's no defined baud rate. | |||||
| */ | |||||
| if (bas->rclk == 0 && baudrate != 0) | |||||
| bas->rclk = DEFAULT_RCLK; | bas->rclk = DEFAULT_RCLK; | ||||
| ns8250_param(bas, baudrate, databits, stopbits, parity); | ns8250_param(bas, baudrate, databits, stopbits, parity); | ||||
| /* Disable the FIFO (if present). */ | /* Disable the FIFO (if present). */ | ||||
| uart_setreg(bas, REG_FCR, 0); | uart_setreg(bas, REG_FCR, 0); | ||||
| uart_barrier(bas); | uart_barrier(bas); | ||||
| /* Set RTS & DTR. */ | /* Set RTS & DTR. */ | ||||
| uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); | uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR); | ||||
| ▲ Show 20 Lines • Show All 745 Lines • Show Last 20 Lines | |||||