1 /* GRLIB APBUART Serial controller driver
3 * (C) Copyright 2007, 2015
4 * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
6 * SPDX-License-Identifier: GPL-2.0+
12 #include <grlib/apbuart.h>
16 DECLARE_GLOBAL_DATA_PTR;
18 /* Select which UART that will become u-boot console */
19 #ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
20 #define CONFIG_SYS_GRLIB_APBUART_INDEX 0
23 static int leon3_serial_init(void)
25 ambapp_dev_apbuart *uart;
30 if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
31 CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) != 1)
32 return -1; /* didn't find hardware */
34 /* found apbuart, let's init .. */
35 uart = (ambapp_dev_apbuart *) apbdev.address;
37 /* Set scaler / baud rate */
38 tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
39 writel(tmp, &uart->scaler);
41 /* Let bit 11 be unchanged (debug bit for GRMON) */
42 tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG;
43 /* Receiver & transmitter enable */
44 tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE;
45 writel(tmp, &uart->ctrl);
51 static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
53 ambapp_dev_apbuart *uart = gd->arch.uart;
57 static void leon3_serial_putc_raw(const char c)
59 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
64 /* Wait for last character to go. */
65 while (!(readl(&uart->status) & APBUART_STATUS_THE))
69 writel(c, &uart->data);
72 /* Wait for data to be sent */
73 while (!(readl(&uart->status) & APBUART_STATUS_TSE))
78 static void leon3_serial_putc(const char c)
81 leon3_serial_putc_raw('\r');
83 leon3_serial_putc_raw(c);
86 static int leon3_serial_getc(void)
88 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
93 /* Wait for a character to arrive. */
94 while (!(readl(&uart->status) & APBUART_STATUS_DR))
97 /* Read character data */
98 return readl(&uart->data);
101 static int leon3_serial_tstc(void)
103 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
108 return readl(&uart->status) & APBUART_STATUS_DR;
111 /* set baud rate for uart */
112 static void leon3_serial_setbrg(void)
114 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
121 gd->baudrate = CONFIG_BAUDRATE;
123 scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
125 writel(scaler, &uart->scaler);
128 static struct serial_device leon3_serial_drv = {
129 .name = "leon3_serial",
130 .start = leon3_serial_init,
132 .setbrg = leon3_serial_setbrg,
133 .putc = leon3_serial_putc,
134 .puts = default_serial_puts,
135 .getc = leon3_serial_getc,
136 .tstc = leon3_serial_tstc,
139 void leon3_serial_initialize(void)
141 serial_register(&leon3_serial_drv);
144 __weak struct serial_device *default_serial_console(void)
146 return &leon3_serial_drv;