coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
sifive.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <boot/coreboot_tables.h>
5 #include <console/uart.h>
6 #include <types.h>
7 
8 /*
9  * This is a driver for SiFive's own UART, documented in the FU540 manual:
10  * https://www.sifive.com/documentation/chips/freedom-u540-c000-manual/
11  */
12 
14  uint32_t txdata; /* Transmit data register */
15  uint32_t rxdata; /* Receive data register */
16  uint32_t txctrl; /* Transmit control register */
17  uint32_t rxctrl; /* Receive control register */
18  uint32_t ie; /* UART interrupt enable */
19  uint32_t ip; /* UART interrupt pending */
20  uint32_t div; /* Baud rate divisor */
22 
23 #define TXDATA_FULL BIT(31)
24 #define RXDATA_EMPTY BIT(31)
25 #define TXCTRL_TXEN BIT(0)
26 #define TXCTRL_NSTOP_SHIFT 1
27 #define TXCTRL_NSTOP(x) (((x)-1) << TXCTRL_NSTOP_SHIFT)
28 #define TXCTRL_TXCNT_SHIFT 16
29 #define TXCTRL_TXCNT(x) ((x) << TXCTRL_TXCNT_SHIFT)
30 #define RXCTRL_RXEN BIT(0)
31 #define RXCTRL_RXCNT_SHIFT 16
32 #define RXCTRL_RXCNT(x) ((x) << RXCTRL_RXCNT_SHIFT)
33 #define IP_TXWM BIT(0)
34 #define IP_RXWM BIT(1)
35 
36 static void sifive_uart_init(struct sifive_uart_registers *regs, int div)
37 {
38  /* Configure the divisor */
39  write32(&regs->div, div);
40 
41  /* Enable transmission, one stop bit, transmit watermark at 1 */
43 
44  /* Enable reception, receive watermark at 0 */
45  write32(&regs->rxctrl, RXCTRL_RXEN|RXCTRL_RXCNT(0));
46 }
47 
48 void uart_init(unsigned int idx)
49 {
50  unsigned int div;
54 }
55 
57 {
58  return !(read32(&regs->txdata) & TXDATA_FULL);
59 }
60 
61 void uart_tx_byte(unsigned int idx, unsigned char data)
62 {
64 
65  while (!uart_can_tx(regs))
66  ; /* TODO: implement a timeout */
67 
68  write32(&regs->txdata, data);
69 }
70 
71 void uart_tx_flush(unsigned int idx)
72 {
74  uint32_t ip;
75 
76  /* Use the TX watermark bit to find out if the TX FIFO is empty */
77  do {
78  ip = read32(&regs->ip);
79  } while (!(ip & IP_TXWM));
80 }
81 
82 unsigned char uart_rx_byte(unsigned int idx)
83 {
86 
87  do {
88  rxdata = read32(&regs->rxdata);
89  } while (rxdata & RXDATA_EMPTY);
90 
91  return rxdata & 0xff;
92 }
93 
94 unsigned int uart_input_clock_divider(void)
95 {
96  /*
97  * The SiFive UART handles oversampling internally. The divided clock
98  * is the baud clock.
99  */
100  return 1;
101 }
102 
103 void uart_fill_lb(void *data)
104 {
105  /* TODO */
106 }
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
unsigned int get_uart_baudrate(void)
Definition: bmcinfo.c:167
unsigned int uart_baudrate_divisor(unsigned int baudrate, unsigned int refclk, unsigned int oversample)
Definition: util.c:8
static void * uart_platform_baseptr(unsigned int idx)
Definition: uart.h:57
unsigned int uart_platform_refclk(void)
Definition: oxpcie_early.c:72
#define IP_TXWM
Definition: sifive.c:33
#define TXCTRL_NSTOP(x)
Definition: sifive.c:27
void uart_init(unsigned int idx)
Definition: sifive.c:48
static bool uart_can_tx(struct sifive_uart_registers *regs)
Definition: sifive.c:56
#define TXDATA_FULL
Definition: sifive.c:23
void uart_tx_flush(unsigned int idx)
Definition: sifive.c:71
#define RXCTRL_RXEN
Definition: sifive.c:30
unsigned int uart_input_clock_divider(void)
Definition: sifive.c:94
unsigned char uart_rx_byte(unsigned int idx)
Definition: sifive.c:82
#define RXCTRL_RXCNT(x)
Definition: sifive.c:32
static void sifive_uart_init(struct sifive_uart_registers *regs, int div)
Definition: sifive.c:36
#define RXDATA_EMPTY
Definition: sifive.c:24
struct sifive_uart_registers __packed
#define TXCTRL_TXCNT(x)
Definition: sifive.c:29
#define TXCTRL_TXEN
Definition: sifive.c:25
void uart_fill_lb(void *data)
Definition: sifive.c:103
void uart_tx_byte(unsigned int idx, unsigned char data)
Definition: sifive.c:61
unsigned int uint32_t
Definition: stdint.h:14
uint32_t txctrl
Definition: sifive.c:16
uint32_t rxdata
Definition: sifive.c:15
uint32_t txdata
Definition: sifive.c:14
uint32_t rxctrl
Definition: sifive.c:17