mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
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 <phil@raspberrypi.org>
This commit is contained in:
@@ -1725,6 +1725,23 @@ static void pl011_put_poll_char(struct uart_port *port,
|
||||
|
||||
#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 =
|
||||
@@ -1741,7 +1758,7 @@ static int pl011_hwinit(struct uart_port *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 |
|
||||
@@ -2432,7 +2449,7 @@ static int pl011_console_setup(struct console *co, char *options)
|
||||
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;
|
||||
@@ -2649,6 +2666,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;
|
||||
@@ -2680,6 +2698,7 @@ static int pl011_probe_dt_alias(int index, struct device *dev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* unregisters the driver also if no more ports are left */
|
||||
static void pl011_unregister_port(struct uart_amba_port *uap)
|
||||
|
||||
Reference in New Issue
Block a user