]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/sparc/cpu/leon2/serial.c
Merge git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / arch / sparc / cpu / leon2 / serial.c
1 /* GRLIB APBUART Serial controller driver
2  *
3  * (C) Copyright 2008
4  * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <asm/processor.h>
11 #include <asm/leon.h>
12 #include <serial.h>
13 #include <linux/compiler.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
17 static int leon2_serial_init(void)
18 {
19         LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
20         LEON2_Uart_regs *regs;
21         unsigned int tmp;
22
23         /* Init LEON2 UART
24          *
25          * Set scaler / baud rate
26          *
27          * Receiver & transmitter enable
28          */
29 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
30         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
31 #else
32         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
33 #endif
34
35         regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER;
36
37         /* Let bit 11 be unchanged (debug bit for GRMON) */
38         tmp = READ_WORD(regs->UART_Control);
39
40         regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) |
41                               (LEON2_UART1_LOOPBACK_ENABLE << 7) |
42                               (LEON2_UART1_FLOWCTRL_ENABLE << 6) |
43                               (LEON2_UART1_PARITY_ENABLE << 5) |
44                               (LEON2_UART1_ODDPAR_ENABLE << 4) |
45                               LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
46
47         return 0;
48 }
49
50 static void leon2_serial_putc_raw(const char c)
51 {
52         LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
53         LEON2_Uart_regs *regs;
54
55 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
56         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
57 #else
58         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
59 #endif
60
61         /* Wait for last character to go. */
62         while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ;
63
64         /* Send data */
65         regs->UART_Channel = c;
66
67 #ifdef LEON_DEBUG
68         /* Wait for data to be sent */
69         while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ;
70 #endif
71 }
72
73 static void leon2_serial_putc(const char c)
74 {
75         if (c == '\n')
76                 leon2_serial_putc_raw('\r');
77
78         leon2_serial_putc_raw(c);
79 }
80
81 static int leon2_serial_getc(void)
82 {
83         LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
84         LEON2_Uart_regs *regs;
85
86 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
87         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
88 #else
89         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
90 #endif
91
92         /* Wait for a character to arrive. */
93         while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ;
94
95         /* read data */
96         return READ_WORD(regs->UART_Channel);
97 }
98
99 static int leon2_serial_tstc(void)
100 {
101         LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
102         LEON2_Uart_regs *regs;
103
104 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
105         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
106 #else
107         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
108 #endif
109
110         return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR);
111 }
112
113 /* set baud rate for uart */
114 static void leon2_serial_setbrg(void)
115 {
116         /* update baud rate settings, read it from gd->baudrate */
117         unsigned int scaler;
118         LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
119         LEON2_Uart_regs *regs;
120
121 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
122         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
123 #else
124         regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
125 #endif
126
127         if (gd->baudrate > 0) {
128                 scaler =
129                     (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
130                      5) / 10;
131                 regs->UART_Scaler = scaler;
132         }
133 }
134
135 static struct serial_device leon2_serial_drv = {
136         .name   = "leon2_serial",
137         .start  = leon2_serial_init,
138         .stop   = NULL,
139         .setbrg = leon2_serial_setbrg,
140         .putc   = leon2_serial_putc,
141         .puts   = default_serial_puts,
142         .getc   = leon2_serial_getc,
143         .tstc   = leon2_serial_tstc,
144 };
145
146 void leon2_serial_initialize(void)
147 {
148         serial_register(&leon2_serial_drv);
149 }
150
151 __weak struct serial_device *default_serial_console(void)
152 {
153         return &leon2_serial_drv;
154 }