5 #include "microwatt_soc.h"
8 #define UART_BAUDS 115200
11 * Core UART functions to implement for a port
16 static uint64_t uart_base
;
18 static unsigned long uart_divisor(unsigned long uart_freq
, unsigned long bauds
)
20 return uart_freq
/ (bauds
* 16);
23 static uint64_t potato_uart_reg_read(int offset
)
25 return readq(uart_base
+ offset
);
28 static void potato_uart_reg_write(int offset
, uint64_t val
)
30 writeq(val
, uart_base
+ offset
);
33 static int potato_uart_rx_empty(void)
37 val
= potato_uart_reg_read(POTATO_CONSOLE_STATUS
);
39 if (val
& POTATO_CONSOLE_STATUS_RX_EMPTY
)
45 static int potato_uart_tx_full(void)
49 val
= potato_uart_reg_read(POTATO_CONSOLE_STATUS
);
51 if (val
& POTATO_CONSOLE_STATUS_TX_FULL
)
57 static char potato_uart_read(void)
61 val
= potato_uart_reg_read(POTATO_CONSOLE_RX
);
63 return (char)(val
& 0x000000ff);
66 static void potato_uart_write(char c
)
72 potato_uart_reg_write(POTATO_CONSOLE_TX
, val
);
75 static void potato_uart_init(uint64_t uart_freq
)
77 unsigned long div
= uart_divisor(uart_freq
, UART_BAUDS
) - 1;
78 potato_uart_reg_write(POTATO_CONSOLE_CLOCK_DIV
, div
);
81 static void potato_uart_set_irq_en(bool rx_irq
, bool tx_irq
)
86 en
|= POTATO_CONSOLE_IRQ_RX
;
88 en
|= POTATO_CONSOLE_IRQ_TX
;
89 potato_uart_reg_write(POTATO_CONSOLE_IRQ_EN
, en
);
92 static bool std_uart_rx_empty(void)
94 return !(readb(uart_base
+ UART_REG_LSR
) & UART_REG_LSR_DR
);
97 static uint8_t std_uart_read(void)
99 return readb(uart_base
+ UART_REG_RX
);
102 static bool std_uart_tx_full(void)
104 return !(readb(uart_base
+ UART_REG_LSR
) & UART_REG_LSR_THRE
);
107 static void std_uart_write(uint8_t c
)
109 writeb(c
, uart_base
+ UART_REG_TX
);
112 static void std_uart_set_irq_en(bool rx_irq
, bool tx_irq
)
117 ier
|= UART_REG_IER_THRI
;
119 ier
|= UART_REG_IER_RDI
;
120 writeb(ier
, uart_base
+ UART_REG_IER
);
123 static void std_uart_init(uint64_t uart_freq
)
125 unsigned long div
= uart_divisor(uart_freq
, UART_BAUDS
);
127 writeb(UART_REG_LCR_DLAB
, uart_base
+ UART_REG_LCR
);
128 writeb(div
& 0xff, uart_base
+ UART_REG_DLL
);
129 writeb(div
>> 8, uart_base
+ UART_REG_DLM
);
130 writeb(UART_REG_LCR_8BIT
, uart_base
+ UART_REG_LCR
);
131 writeb(UART_REG_MCR_DTR
|
132 UART_REG_MCR_RTS
, uart_base
+ UART_REG_MCR
);
133 writeb(UART_REG_FCR_EN_FIFO
|
134 UART_REG_FCR_CLR_RCVR
|
135 UART_REG_FCR_CLR_XMIT
, uart_base
+ UART_REG_FCR
);
141 while (std_uart_rx_empty())
143 return std_uart_read();
145 while (potato_uart_rx_empty())
147 return potato_uart_read();
154 while(std_uart_tx_full())
158 while (potato_uart_tx_full())
160 potato_uart_write(c
);
165 int puts(const char *str
)
169 for (i
= 0; *str
; i
++) {
179 size_t strlen(const char *s
)
190 void console_init(void)
194 uint64_t uart_info
= 0;
195 uint64_t uart_freq
= 0;
197 proc_freq
= readq(SYSCON_BASE
+ SYS_REG_CLKINFO
) & SYS_REG_CLKINFO_FREQ_MASK
;
198 sys_info
= readq(SYSCON_BASE
+ SYS_REG_INFO
);
200 if (sys_info
& SYS_REG_INFO_HAS_LARGE_SYSCON
) {
201 uart_info
= readq(SYSCON_BASE
+ SYS_REG_UART0_INFO
);
202 uart_freq
= uart_info
& 0xffffffff;
205 uart_freq
= proc_freq
;
207 uart_base
= UART_BASE
;
208 if (uart_info
& SYS_REG_UART_IS_16550
) {
210 std_uart_init(proc_freq
);
213 potato_uart_init(proc_freq
);
217 void console_set_irq_en(bool rx_irq
, bool tx_irq
)
220 std_uart_set_irq_en(rx_irq
, tx_irq
);
222 potato_uart_set_irq_en(rx_irq
, tx_irq
);