1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- From 307744a359bddf354711e54836e4757788c9dfc4 Mon Sep 17 00:00:00 2001
- From: Phil Elwell <[email protected]>
- Date: Wed, 1 Mar 2017 16:07:39 +0000
- Subject: [PATCH] amba_pl011: Round input clock up
- The UART clock is initialised to be as close to the requested
- frequency as possible without exceeding it. Now that there is a
- clock manager that returns the actual frequencies, an expected
- 48MHz clock is reported as 47999625. If the requested baudrate
- == requested clock/16, there is no headroom and the slight
- reduction in actual clock rate results in failure.
- Detect cases where it looks like a "round" clock was chosen and
- adjust the reported clock to match that "round" value. As the
- code comment says:
- /*
- * If increasing a clock by less than 0.1% changes it
- * from ..999.. to ..000.., round up.
- */
- Signed-off-by: Phil Elwell <[email protected]>
- ---
- drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++--
- 1 file changed, 21 insertions(+), 2 deletions(-)
- --- a/drivers/tty/serial/amba-pl011.c
- +++ b/drivers/tty/serial/amba-pl011.c
- @@ -1718,6 +1718,23 @@ static void pl011_put_poll_char(struct u
-
- #endif /* CONFIG_CONSOLE_POLL */
-
- +unsigned long pl011_clk_round(unsigned long clk)
- +{
- + unsigned long scaler;
- +
- + /*
- + * If increasing a clock by less than 0.1% changes it
- + * from ..999.. to ..000.., round up.
- + */
- + scaler = 1;
- + while (scaler * 100000 < clk)
- + scaler *= 10;
- + if ((clk + scaler - 1)/scaler % 1000 == 0)
- + clk = (clk/scaler + 1) * scaler;
- +
- + return clk;
- +}
- +
- static int pl011_hwinit(struct uart_port *port)
- {
- struct uart_amba_port *uap =
- @@ -1734,7 +1751,7 @@ static int pl011_hwinit(struct uart_port
- if (retval)
- return retval;
-
- - uap->port.uartclk = clk_get_rate(uap->clk);
- + uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
-
- /* Clear pending error and receive interrupts */
- pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
- @@ -2421,7 +2438,7 @@ static int pl011_console_setup(struct co
- plat->init();
- }
-
- - uap->port.uartclk = clk_get_rate(uap->clk);
- + uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
-
- if (uap->vendor->fixed_options) {
- baud = uap->fixed_baud;
- @@ -2638,6 +2655,7 @@ static struct uart_driver amba_reg = {
- .cons = AMBA_CONSOLE,
- };
-
- +#if 0
- static int pl011_probe_dt_alias(int index, struct device *dev)
- {
- struct device_node *np;
- @@ -2669,6 +2687,7 @@ static int pl011_probe_dt_alias(int inde
-
- return ret;
- }
- +#endif
-
- /* unregisters the driver also if no more ports are left */
- static void pl011_unregister_port(struct uart_amba_port *uap)
|