bcm27xx: update patches from RPi foundation
[oweals/openwrt.git] / target / linux / bcm27xx / patches-5.4 / 950-0032-amba_pl011-Round-input-clock-up.patch
1 From 409f4b56de7611d703790c54a70fad9a6e2bb161 Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.org>
3 Date: Wed, 1 Mar 2017 16:07:39 +0000
4 Subject: [PATCH] amba_pl011: Round input clock up
5
6 The UART clock is initialised to be as close to the requested
7 frequency as possible without exceeding it. Now that there is a
8 clock manager that returns the actual frequencies, an expected
9 48MHz clock is reported as 47999625. If the requested baudrate
10 == requested clock/16, there is no headroom and the slight
11 reduction in actual clock rate results in failure.
12
13 Detect cases where it looks like a "round" clock was chosen and
14 adjust the reported clock to match that "round" value. As the
15 code comment says:
16
17 /*
18  * If increasing a clock by less than 0.1% changes it
19  * from ..999.. to ..000.., round up.
20  */
21
22 Signed-off-by: Phil Elwell <phil@raspberrypi.org>
23 ---
24  drivers/tty/serial/amba-pl011.c | 23 +++++++++++++++++++++--
25  1 file changed, 21 insertions(+), 2 deletions(-)
26
27 --- a/drivers/tty/serial/amba-pl011.c
28 +++ b/drivers/tty/serial/amba-pl011.c
29 @@ -1650,6 +1650,23 @@ static void pl011_put_poll_char(struct u
30  
31  #endif /* CONFIG_CONSOLE_POLL */
32  
33 +unsigned long pl011_clk_round(unsigned long clk)
34 +{
35 +       unsigned long scaler;
36 +
37 +       /*
38 +        * If increasing a clock by less than 0.1% changes it
39 +        * from ..999.. to ..000.., round up.
40 +        */
41 +       scaler = 1;
42 +       while (scaler * 100000 < clk)
43 +               scaler *= 10;
44 +       if ((clk + scaler - 1)/scaler % 1000 == 0)
45 +               clk = (clk/scaler + 1) * scaler;
46 +
47 +       return clk;
48 +}
49 +
50  static int pl011_hwinit(struct uart_port *port)
51  {
52         struct uart_amba_port *uap =
53 @@ -1666,7 +1683,7 @@ static int pl011_hwinit(struct uart_port
54         if (retval)
55                 return retval;
56  
57 -       uap->port.uartclk = clk_get_rate(uap->clk);
58 +       uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
59  
60         /* Clear pending error and receive interrupts */
61         pl011_write(UART011_OEIS | UART011_BEIS | UART011_PEIS |
62 @@ -2322,7 +2339,7 @@ static int __init pl011_console_setup(st
63                         plat->init();
64         }
65  
66 -       uap->port.uartclk = clk_get_rate(uap->clk);
67 +       uap->port.uartclk = pl011_clk_round(clk_get_rate(uap->clk));
68  
69         if (uap->vendor->fixed_options) {
70                 baud = uap->fixed_baud;
71 @@ -2507,6 +2524,7 @@ static struct uart_driver amba_reg = {
72         .cons                   = AMBA_CONSOLE,
73  };
74  
75 +#if 0
76  static int pl011_probe_dt_alias(int index, struct device *dev)
77  {
78         struct device_node *np;
79 @@ -2538,6 +2556,7 @@ static int pl011_probe_dt_alias(int inde
80  
81         return ret;
82  }
83 +#endif
84  
85  /* unregisters the driver also if no more ports are left */
86  static void pl011_unregister_port(struct uart_amba_port *uap)