NVIDIA: SAUCE: serial: amba-pl011: Do not use IBRD
Tegra UART controllers does not support FBRD register, which cause it to not support various standard baudrates that HW supports. Use clk_set_rate to program UART clock rate instead. Bug 5406304 Change-Id: I6fcf14b0186e54a6f418287791d80e12d17600a0 Signed-off-by: Kartik Rajput <kkartik@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/3rdparty/canonical/linux-noble/+/3441884 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> (cherry picked from commit daa72589899560fb3570b165163bd8e35cf704e1) Reviewed-on: https://git-master.nvidia.com/r/c/3rdparty/canonical/linux-noble/+/3447941 GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
Amulya Yarlagadda
parent
0d9eaffac7
commit
b37c423627
@@ -2173,11 +2173,15 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||||||
else
|
else
|
||||||
clkdiv = 16;
|
clkdiv = 16;
|
||||||
|
|
||||||
/*
|
if (uap->vendor->enable_car) {
|
||||||
* Ask the core to calculate the divisor for us.
|
baud = tty_termios_baud_rate(termios);
|
||||||
*/
|
clk_set_rate(uap->clk, baud * clkdiv);
|
||||||
baud = uart_get_baud_rate(port, termios, old, 0,
|
}
|
||||||
port->uartclk / clkdiv);
|
else {
|
||||||
|
baud = uart_get_baud_rate(port, termios, old, 0,
|
||||||
|
port->uartclk / clkdiv);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DMA_ENGINE
|
#ifdef CONFIG_DMA_ENGINE
|
||||||
/*
|
/*
|
||||||
* Adjust RX DMA polling rate with baud rate if not specified.
|
* Adjust RX DMA polling rate with baud rate if not specified.
|
||||||
@@ -2186,10 +2190,12 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||||||
uap->dmarx.poll_rate = DIV_ROUND_UP(10000000, baud);
|
uap->dmarx.poll_rate = DIV_ROUND_UP(10000000, baud);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (baud > port->uartclk / 16)
|
if (!uap->vendor->enable_car) {
|
||||||
quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
|
if (baud > port->uartclk / 16)
|
||||||
else
|
quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud);
|
||||||
quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud);
|
else
|
||||||
|
quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud);
|
||||||
|
}
|
||||||
|
|
||||||
switch (termios->c_cflag & CSIZE) {
|
switch (termios->c_cflag & CSIZE) {
|
||||||
case CS5:
|
case CS5:
|
||||||
@@ -2261,22 +2267,23 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||||||
old_cr &= ~ST_UART011_CR_OVSFACT;
|
old_cr &= ~ST_UART011_CR_OVSFACT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (!uap->vendor->enable_car) {
|
||||||
* Workaround for the ST Micro oversampling variants to
|
/*
|
||||||
* increase the bitrate slightly, by lowering the divisor,
|
* Workaround for the ST Micro oversampling variants to
|
||||||
* to avoid delayed sampling of start bit at high speeds,
|
* increase the bitrate slightly, by lowering the divisor,
|
||||||
* else we see data corruption.
|
* to avoid delayed sampling of start bit at high speeds,
|
||||||
*/
|
* else we see data corruption.
|
||||||
if (uap->vendor->oversampling) {
|
*/
|
||||||
if (baud >= 3000000 && baud < 3250000 && quot > 1)
|
if (uap->vendor->oversampling) {
|
||||||
quot -= 1;
|
if (baud >= 3000000 && baud < 3250000 && quot > 1)
|
||||||
else if (baud > 3250000 && quot > 2)
|
quot -= 1;
|
||||||
quot -= 2;
|
else if (baud > 3250000 && quot > 2)
|
||||||
|
quot -= 2;
|
||||||
|
}
|
||||||
|
/* Set baud rate */
|
||||||
|
pl011_write(quot & 0x3f, uap, REG_FBRD);
|
||||||
|
pl011_write(quot >> 6, uap, REG_IBRD);
|
||||||
}
|
}
|
||||||
/* Set baud rate */
|
|
||||||
pl011_write(quot & 0x3f, uap, REG_FBRD);
|
|
||||||
pl011_write(quot >> 6, uap, REG_IBRD);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------v----------v----------v----------v-----
|
* ----------v----------v----------v----------v-----
|
||||||
* NOTE: REG_LCRH_TX and REG_LCRH_RX MUST BE WRITTEN AFTER
|
* NOTE: REG_LCRH_TX and REG_LCRH_RX MUST BE WRITTEN AFTER
|
||||||
|
|||||||
Reference in New Issue
Block a user