From: John Jacques <john.jacq...@lsi.com>

Added code to support the UART on the 3500 board

Signed-off-by: John Jacques <john.jacq...@lsi.com>
---
 drivers/tty/serial/lsi_acp_serial.c |   94 +++++++++++++++++++----------------
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/drivers/tty/serial/lsi_acp_serial.c 
b/drivers/tty/serial/lsi_acp_serial.c
index a41eab2..0f9f7ce 100644
--- a/drivers/tty/serial/lsi_acp_serial.c
+++ b/drivers/tty/serial/lsi_acp_serial.c
@@ -81,9 +81,8 @@ struct uart_acp_port {
        unsigned int interrupt_mask;
        unsigned int old_status;
        void *timer_base;
-       unsigned long divisor;
-       unsigned char ibrd;
-       unsigned char fbrd;
+       unsigned short ibrd;
+       unsigned short fbrd;
 };
 
 /*
@@ -119,25 +118,10 @@ struct uart_acp_port {
 static int
 get_clock_stuff(struct uart_acp_port *port, int baud_rate)
 {
-       unsigned long divisor;
        unsigned long ibrd;
        unsigned long fbrd;
 
-       /*
-         Since the IBDR (integer part of the baud rate
-         divisor) is a 16 bit quatity, find the minimum load
-         value that will let the IBDR/FBDR result in the
-         desired baud rate.
-       */
-
-       if (1000000 < per_clock) {
-               divisor = per_clock / 25000000;
-               ibrd = 25000000 / (16 * baud_rate);
-       } else {
-               /* Emulation is much slower... */
-               divisor = per_clock / 3250000;
-               ibrd = 3250000 / (16 * baud_rate);
-       }
+       ibrd = per_clock / (16 * baud_rate);
 
        /*
         * The following formula is from the ARM document (ARM DDI 0183E).
@@ -164,36 +148,15 @@ get_clock_stuff(struct uart_acp_port *port, int baud_rate)
         *                     2 * (16 * baud_rate)
         */
 
-       port->port.uartclk = (per_clock / divisor);
+       port->port.uartclk = per_clock;
 
        fbrd = port->port.uartclk % (16 * baud_rate);
        fbrd *= 128;
        fbrd += (16 * baud_rate);
        fbrd /= (2 * (16 * baud_rate));
 
-       port->divisor = (divisor - 1);
-       port->ibrd = (unsigned char) ibrd;
-       port->fbrd = (unsigned char) fbrd;
-
-       if (port->divisor != in_le32(port->timer_base + TIMER_LOAD)) {
-               while (0 ==
-                      (in_le32((const volatile unsigned *)
-                               (port->port.membase + UART01x_FR)) &
-                       UART011_FR_TXFE))
-                       ;
-
-               while (0 !=
-                      (in_le32((const volatile unsigned *)
-                               (port->port.membase + UART01x_FR)) &
-                       UART01x_FR_BUSY))
-                       ;
-
-               out_le32((port->timer_base + TIMER_CONTROL), 0);
-               out_le32((port->timer_base + TIMER_LOAD), port->divisor);
-               out_le32((port->timer_base + TIMER_CONTROL),
-                        (TIMER_CONTROL_ENABLE |
-                         TIMER_CONTROL_MODE));
-       }
+       port->ibrd = (unsigned short) ibrd;
+       port->fbrd = (unsigned short) fbrd;
 
        return 0;
 }
@@ -1135,6 +1098,51 @@ acp_serial_add_ports(struct uart_driver *driver)
                ret = -ENOMEM;
        }
 
+       np = of_find_compatible_node(NULL, NULL, "lsi,acp3500");
+
+       if (NULL == np) {
+               unsigned long divisor;
+
+               /*
+                 In the 3500 case, the peripheral clock is connected
+                 directly to the UART.  If this isn't 3500, set up
+                 the second timer (which is in between the peripheral
+                 clock and the UART) and adjust per_clock
+                 accordingly.
+               */
+
+               if (1000000 < per_clock) {
+                       divisor = per_clock / 25000000;
+                       per_clock = 25000000;
+               } else {
+                       /* Emulation is much slower... */
+                       divisor = per_clock / 3250000;
+                       per_clock = 3250000;
+               }
+
+               --divisor;
+
+               if (divisor != in_le32(uap->timer_base + TIMER_LOAD)) {
+                       while (0 ==
+                              (in_le32((const volatile unsigned *)
+                                       (uap->port.membase + UART01x_FR)) &
+                               UART011_FR_TXFE))
+                               ;
+
+                       while (0 !=
+                              (in_le32((const volatile unsigned *)
+                                       (uap->port.membase + UART01x_FR)) &
+                               UART01x_FR_BUSY))
+                               ;
+
+                       out_le32((uap->timer_base + TIMER_CONTROL), 0);
+                       out_le32((uap->timer_base + TIMER_LOAD), divisor);
+                       out_le32((uap->timer_base + TIMER_CONTROL),
+                                (TIMER_CONTROL_ENABLE |
+                                 TIMER_CONTROL_MODE));
+               }
+       }
+
        dt_baud_rate = baud_rate;
        uap->port.iotype = UPIO_MEM;
        uap->port.fifosize = 16;
-- 
1.7.9.5

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to