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