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 panic("%s: apbuart not found!\n", __func__
);
33 return -1; /* didn't find hardware */
36 /* found apbuart, let's init .. */
37 uart
= (ambapp_dev_apbuart
*) apbdev
.address
;
39 /* Set scaler / baud rate */
40 tmp
= (((CONFIG_SYS_CLK_FREQ
*10) / (CONFIG_BAUDRATE
*8)) - 5)/10;
41 writel(tmp
, &uart
->scaler
);
43 /* Let bit 11 be unchanged (debug bit for GRMON) */
44 tmp
= readl(&uart
->ctrl
) & APBUART_CTRL_DBG
;
45 /* Receiver & transmitter enable */
46 tmp
|= APBUART_CTRL_RE
| APBUART_CTRL_TE
;
47 writel(tmp
, &uart
->ctrl
);
53 static inline ambapp_dev_apbuart
*leon3_get_uart_regs(void)
55 ambapp_dev_apbuart
*uart
= gd
->arch
.uart
;
59 static void leon3_serial_putc_raw(const char c
)
61 ambapp_dev_apbuart
* const uart
= leon3_get_uart_regs();
66 /* Wait for last character to go. */
67 while (!(readl(&uart
->status
) & APBUART_STATUS_THE
))
71 writel(c
, &uart
->data
);
74 /* Wait for data to be sent */
75 while (!(readl(&uart
->status
) & APBUART_STATUS_TSE
))
80 static void leon3_serial_putc(const char c
)
83 leon3_serial_putc_raw('\r');
85 leon3_serial_putc_raw(c
);
88 static int leon3_serial_getc(void)
90 ambapp_dev_apbuart
* const uart
= leon3_get_uart_regs();
95 /* Wait for a character to arrive. */
96 while (!(readl(&uart
->status
) & APBUART_STATUS_DR
))
99 /* Read character data */
100 return readl(&uart
->data
);
103 static int leon3_serial_tstc(void)
105 ambapp_dev_apbuart
* const uart
= leon3_get_uart_regs();
110 return readl(&uart
->status
) & APBUART_STATUS_DR
;
113 /* set baud rate for uart */
114 static void leon3_serial_setbrg(void)
116 ambapp_dev_apbuart
* const uart
= leon3_get_uart_regs();
123 gd
->baudrate
= CONFIG_BAUDRATE
;
125 scaler
= (((CONFIG_SYS_CLK_FREQ
*10) / (gd
->baudrate
*8)) - 5)/10;
127 writel(scaler
, &uart
->scaler
);
130 static struct serial_device leon3_serial_drv
= {
131 .name
= "leon3_serial",
132 .start
= leon3_serial_init
,
134 .setbrg
= leon3_serial_setbrg
,
135 .putc
= leon3_serial_putc
,
136 .puts
= default_serial_puts
,
137 .getc
= leon3_serial_getc
,
138 .tstc
= leon3_serial_tstc
,
141 void leon3_serial_initialize(void)
143 serial_register(&leon3_serial_drv
);
146 __weak
struct serial_device
*default_serial_console(void)
148 return &leon3_serial_drv
;
151 #ifdef CONFIG_DEBUG_UART_APBUART
153 #include <debug_uart.h>
155 static inline void _debug_uart_init(void)
157 ambapp_dev_apbuart
*uart
= (ambapp_dev_apbuart
*)CONFIG_DEBUG_UART_BASE
;
158 uart
->scaler
= (((CONFIG_DEBUG_UART_CLOCK
*10) / (CONFIG_BAUDRATE
*8)) - 5)/10;
159 uart
->ctrl
= APBUART_CTRL_RE
| APBUART_CTRL_TE
;
162 static inline void _debug_uart_putc(int ch
)
164 ambapp_dev_apbuart
*uart
= (ambapp_dev_apbuart
*)CONFIG_DEBUG_UART_BASE
;
165 while (!(readl(&uart
->status
) & APBUART_STATUS_THE
))
167 writel(ch
, &uart
->data
);