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+
15 DECLARE_GLOBAL_DATA_PTR;
17 static int leon3_serial_init(void)
19 ambapp_dev_apbuart *uart;
24 if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) != 1)
25 return -1; /* didn't find hardware */
27 /* found apbuart, let's init .. */
28 uart = (ambapp_dev_apbuart *) apbdev.address;
30 /* Set scaler / baud rate */
31 tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
32 writel(tmp, &uart->scaler);
34 /* Let bit 11 be unchanged (debug bit for GRMON) */
35 tmp = readl(&uart->ctrl) & LEON_REG_UART_CTRL_DBG;
36 /* Receiver & transmitter enable */
37 tmp |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
38 writel(tmp, &uart->ctrl);
44 static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
46 ambapp_dev_apbuart *uart = gd->arch.uart;
50 static void leon3_serial_putc_raw(const char c)
52 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
57 /* Wait for last character to go. */
58 while (!(readl(&uart->status) & LEON_REG_UART_STATUS_THE))
62 writel(c, &uart->data);
65 /* Wait for data to be sent */
66 while (!(readl(&uart->status) & LEON_REG_UART_STATUS_TSE))
71 static void leon3_serial_putc(const char c)
74 leon3_serial_putc_raw('\r');
76 leon3_serial_putc_raw(c);
79 static int leon3_serial_getc(void)
81 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
86 /* Wait for a character to arrive. */
87 while (!(readl(&uart->status) & LEON_REG_UART_STATUS_DR))
90 /* Read character data */
91 return readl(&uart->data);
94 static int leon3_serial_tstc(void)
96 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
101 return readl(&uart->status) & LEON_REG_UART_STATUS_DR;
104 /* set baud rate for uart */
105 static void leon3_serial_setbrg(void)
107 ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
114 gd->baudrate = CONFIG_BAUDRATE;
116 scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
118 writel(scaler, &uart->scaler);
121 static struct serial_device leon3_serial_drv = {
122 .name = "leon3_serial",
123 .start = leon3_serial_init,
125 .setbrg = leon3_serial_setbrg,
126 .putc = leon3_serial_putc,
127 .puts = default_serial_puts,
128 .getc = leon3_serial_getc,
129 .tstc = leon3_serial_tstc,
132 void leon3_serial_initialize(void)
134 serial_register(&leon3_serial_drv);
137 __weak struct serial_device *default_serial_console(void)
139 return &leon3_serial_drv;