]> git.sur5r.net Git - u-boot/blob - arch/sparc/cpu/leon3/serial.c
sparc: leon3: Added memory controller initialization using new AMBA PnP routines.
[u-boot] / arch / sparc / cpu / leon3 / serial.c
1 /* GRLIB APBUART Serial controller driver
2  *
3  * (C) Copyright 2007, 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 <ambapp.h>
12 #include <serial.h>
13 #include <watchdog.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
17 /* Select which UART that will become u-boot console */
18 #ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
19 #define CONFIG_SYS_GRLIB_APBUART_INDEX 0
20 #endif
21
22 static int leon3_serial_init(void)
23 {
24         ambapp_dev_apbuart *uart;
25         ambapp_apbdev apbdev;
26         unsigned int tmp;
27
28         /* find UART */
29         if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
30                 CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1)
31                 return -1; /* didn't find hardware */
32
33         /* found apbuart, let's init .. */
34         uart = (ambapp_dev_apbuart *) apbdev.address;
35
36         /* Set scaler / baud rate */
37         tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
38         writel(tmp, &uart->scaler);
39
40         /* Let bit 11 be unchanged (debug bit for GRMON) */
41         tmp = readl(&uart->ctrl) & LEON_REG_UART_CTRL_DBG;
42         /* Receiver & transmitter enable */
43         tmp |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
44         writel(tmp, &uart->ctrl);
45
46         gd->arch.uart = uart;
47         return 0;
48 }
49
50 static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
51 {
52         ambapp_dev_apbuart *uart = gd->arch.uart;
53         return uart;
54 }
55
56 static void leon3_serial_putc_raw(const char c)
57 {
58         ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
59
60         if (!uart)
61                 return;
62
63         /* Wait for last character to go. */
64         while (!(readl(&uart->status) & LEON_REG_UART_STATUS_THE))
65                 WATCHDOG_RESET();
66
67         /* Send data */
68         writel(c, &uart->data);
69
70 #ifdef LEON_DEBUG
71         /* Wait for data to be sent */
72         while (!(readl(&uart->status) & LEON_REG_UART_STATUS_TSE))
73                 WATCHDOG_RESET();
74 #endif
75 }
76
77 static void leon3_serial_putc(const char c)
78 {
79         if (c == '\n')
80                 leon3_serial_putc_raw('\r');
81
82         leon3_serial_putc_raw(c);
83 }
84
85 static int leon3_serial_getc(void)
86 {
87         ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
88
89         if (!uart)
90                 return 0;
91
92         /* Wait for a character to arrive. */
93         while (!(readl(&uart->status) & LEON_REG_UART_STATUS_DR))
94                 WATCHDOG_RESET();
95
96         /* Read character data */
97         return readl(&uart->data);
98 }
99
100 static int leon3_serial_tstc(void)
101 {
102         ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
103
104         if (!uart)
105                 return 0;
106
107         return readl(&uart->status) & LEON_REG_UART_STATUS_DR;
108 }
109
110 /* set baud rate for uart */
111 static void leon3_serial_setbrg(void)
112 {
113         ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
114         unsigned int scaler;
115
116         if (!uart)
117                 return;
118
119         if (!gd->baudrate)
120                 gd->baudrate = CONFIG_BAUDRATE;
121
122         scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
123
124         writel(scaler, &uart->scaler);
125 }
126
127 static struct serial_device leon3_serial_drv = {
128         .name   = "leon3_serial",
129         .start  = leon3_serial_init,
130         .stop   = NULL,
131         .setbrg = leon3_serial_setbrg,
132         .putc   = leon3_serial_putc,
133         .puts   = default_serial_puts,
134         .getc   = leon3_serial_getc,
135         .tstc   = leon3_serial_tstc,
136 };
137
138 void leon3_serial_initialize(void)
139 {
140         serial_register(&leon3_serial_drv);
141 }
142
143 __weak struct serial_device *default_serial_console(void)
144 {
145         return &leon3_serial_drv;
146 }