1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Anup Patel <anup@brainfault.org>
7 #include <debug_uart.h>
13 #include <asm/global_data.h>
15 #include <linux/compiler.h>
17 #include <linux/err.h>
19 DECLARE_GLOBAL_DATA_PTR;
21 #define UART_TXFIFO_FULL 0x80000000
22 #define UART_RXFIFO_EMPTY 0x80000000
23 #define UART_RXFIFO_DATA 0x000000ff
24 #define UART_TXCTRL_TXEN 0x1
25 #define UART_RXCTRL_RXEN 0x1
28 #define UART_IP_RXWM 0x2
40 struct sifive_uart_plat {
42 struct uart_sifive *regs;
46 * Find minimum divisor divides in_freq to max_target_hz;
47 * Based on uart driver n SiFive FSBL.
49 * f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1
50 * The nearest integer solution requires rounding up as to not exceed
52 * div = ceil(f_in / f_baud) - 1
53 * = floor((f_in - 1 + f_baud) / f_baud) - 1
54 * This should not overflow as long as (f_in - 1 + f_baud) does not exceed
55 * 2^32 - 1, which is unlikely since we represent frequencies in kHz.
57 static inline unsigned int uart_min_clk_divisor(unsigned long in_freq,
58 unsigned long max_target_hz)
60 unsigned long quotient =
61 (in_freq + max_target_hz - 1) / (max_target_hz);
69 /* Set up the baud rate in gd struct */
70 static void _sifive_serial_setbrg(struct uart_sifive *regs,
71 unsigned long clock, unsigned long baud)
73 writel((uart_min_clk_divisor(clock, baud)), ®s->div);
76 static void _sifive_serial_init(struct uart_sifive *regs)
78 writel(UART_TXCTRL_TXEN, ®s->txctrl);
79 writel(UART_RXCTRL_RXEN, ®s->rxctrl);
83 static int _sifive_serial_putc(struct uart_sifive *regs, const char c)
85 if (readl(®s->txfifo) & UART_TXFIFO_FULL)
88 writel(c, ®s->txfifo);
93 static int _sifive_serial_getc(struct uart_sifive *regs)
95 int ch = readl(®s->rxfifo);
97 if (ch & UART_RXFIFO_EMPTY)
99 ch &= UART_RXFIFO_DATA;
104 static int sifive_serial_setbrg(struct udevice *dev, int baudrate)
108 struct sifive_uart_plat *plat = dev_get_plat(dev);
111 ret = clk_get_by_index(dev, 0, &clk);
112 if (IS_ERR_VALUE(ret)) {
113 debug("SiFive UART failed to get clock\n");
114 ret = dev_read_u32(dev, "clock-frequency", &clock);
115 if (IS_ERR_VALUE(ret)) {
116 debug("SiFive UART clock not defined\n");
120 clock = clk_get_rate(&clk);
121 if (IS_ERR_VALUE(clock)) {
122 debug("SiFive UART clock get rate failed\n");
127 _sifive_serial_setbrg(plat->regs, plat->clock, baudrate);
132 static int sifive_serial_probe(struct udevice *dev)
134 struct sifive_uart_plat *plat = dev_get_plat(dev);
136 /* No need to reinitialize the UART after relocation */
137 if (gd->flags & GD_FLG_RELOC)
140 _sifive_serial_init(plat->regs);
145 static int sifive_serial_getc(struct udevice *dev)
148 struct sifive_uart_plat *plat = dev_get_plat(dev);
149 struct uart_sifive *regs = plat->regs;
151 while ((c = _sifive_serial_getc(regs)) == -EAGAIN) ;
156 static int sifive_serial_putc(struct udevice *dev, const char ch)
159 struct sifive_uart_plat *plat = dev_get_plat(dev);
161 while ((rc = _sifive_serial_putc(plat->regs, ch)) == -EAGAIN) ;
166 static int sifive_serial_pending(struct udevice *dev, bool input)
168 struct sifive_uart_plat *plat = dev_get_plat(dev);
169 struct uart_sifive *regs = plat->regs;
172 return (readl(®s->ip) & UART_IP_RXWM);
174 return !!(readl(®s->txfifo) & UART_TXFIFO_FULL);
177 static int sifive_serial_of_to_plat(struct udevice *dev)
179 struct sifive_uart_plat *plat = dev_get_plat(dev);
181 plat->regs = (struct uart_sifive *)(uintptr_t)dev_read_addr(dev);
182 if (IS_ERR(plat->regs))
183 return PTR_ERR(plat->regs);
188 static const struct dm_serial_ops sifive_serial_ops = {
189 .putc = sifive_serial_putc,
190 .getc = sifive_serial_getc,
191 .pending = sifive_serial_pending,
192 .setbrg = sifive_serial_setbrg,
195 static const struct udevice_id sifive_serial_ids[] = {
196 { .compatible = "sifive,uart0" },
200 U_BOOT_DRIVER(serial_sifive) = {
201 .name = "serial_sifive",
203 .of_match = sifive_serial_ids,
204 .of_to_plat = sifive_serial_of_to_plat,
205 .plat_auto = sizeof(struct sifive_uart_plat),
206 .probe = sifive_serial_probe,
207 .ops = &sifive_serial_ops,
210 #ifdef CONFIG_DEBUG_UART_SIFIVE
211 static inline void _debug_uart_init(void)
213 struct uart_sifive *regs =
214 (struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE);
216 _sifive_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK,
218 _sifive_serial_init(regs);
221 static inline void _debug_uart_putc(int ch)
223 struct uart_sifive *regs =
224 (struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE);
226 while (_sifive_serial_putc(regs, ch) == -EAGAIN)