1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018 Anup Patel <anup@brainfault.org>
4  */
5 
6 #include <clk.h>
7 #include <debug_uart.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <fdtdec.h>
11 #include <log.h>
12 #include <watchdog.h>
13 #include <asm/global_data.h>
14 #include <asm/io.h>
15 #include <linux/compiler.h>
16 #include <serial.h>
17 #include <linux/err.h>
18 
19 DECLARE_GLOBAL_DATA_PTR;
20 
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
26 
27 /* IP register */
28 #define UART_IP_RXWM            0x2
29 
30 struct uart_sifive {
31 	u32 txfifo;
32 	u32 rxfifo;
33 	u32 txctrl;
34 	u32 rxctrl;
35 	u32 ie;
36 	u32 ip;
37 	u32 div;
38 };
39 
40 struct sifive_uart_plat {
41 	unsigned long clock;
42 	struct uart_sifive *regs;
43 };
44 
45 /**
46  * Find minimum divisor divides in_freq to max_target_hz;
47  * Based on uart driver n SiFive FSBL.
48  *
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
51  * max_target_hz.
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.
56  */
uart_min_clk_divisor(unsigned long in_freq,unsigned long max_target_hz)57 static inline unsigned int uart_min_clk_divisor(unsigned long in_freq,
58 						unsigned long max_target_hz)
59 {
60 	unsigned long quotient =
61 			(in_freq + max_target_hz - 1) / (max_target_hz);
62 	/* Avoid underflow */
63 	if (quotient == 0)
64 		return 0;
65 	else
66 		return quotient - 1;
67 }
68 
69 /* Set up the baud rate in gd struct */
_sifive_serial_setbrg(struct uart_sifive * regs,unsigned long clock,unsigned long baud)70 static void _sifive_serial_setbrg(struct uart_sifive *regs,
71 				  unsigned long clock, unsigned long baud)
72 {
73 	writel((uart_min_clk_divisor(clock, baud)), &regs->div);
74 }
75 
_sifive_serial_init(struct uart_sifive * regs)76 static void _sifive_serial_init(struct uart_sifive *regs)
77 {
78 	writel(UART_TXCTRL_TXEN, &regs->txctrl);
79 	writel(UART_RXCTRL_RXEN, &regs->rxctrl);
80 	writel(0, &regs->ie);
81 }
82 
_sifive_serial_putc(struct uart_sifive * regs,const char c)83 static int _sifive_serial_putc(struct uart_sifive *regs, const char c)
84 {
85 	if (readl(&regs->txfifo) & UART_TXFIFO_FULL)
86 		return -EAGAIN;
87 
88 	writel(c, &regs->txfifo);
89 
90 	return 0;
91 }
92 
_sifive_serial_getc(struct uart_sifive * regs)93 static int _sifive_serial_getc(struct uart_sifive *regs)
94 {
95 	int ch = readl(&regs->rxfifo);
96 
97 	if (ch & UART_RXFIFO_EMPTY)
98 		return -EAGAIN;
99 	ch &= UART_RXFIFO_DATA;
100 
101 	return ch;
102 }
103 
sifive_serial_setbrg(struct udevice * dev,int baudrate)104 static int sifive_serial_setbrg(struct udevice *dev, int baudrate)
105 {
106 	int ret;
107 	struct clk clk;
108 	struct sifive_uart_plat *plat = dev_get_plat(dev);
109 	u32 clock = 0;
110 
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");
117 			return 0;
118 		}
119 	} else {
120 		clock = clk_get_rate(&clk);
121 		if (IS_ERR_VALUE(clock)) {
122 			debug("SiFive UART clock get rate failed\n");
123 			return 0;
124 		}
125 	}
126 	plat->clock = clock;
127 	_sifive_serial_setbrg(plat->regs, plat->clock, baudrate);
128 
129 	return 0;
130 }
131 
sifive_serial_probe(struct udevice * dev)132 static int sifive_serial_probe(struct udevice *dev)
133 {
134 	struct sifive_uart_plat *plat = dev_get_plat(dev);
135 
136 	/* No need to reinitialize the UART after relocation */
137 	if (gd->flags & GD_FLG_RELOC)
138 		return 0;
139 
140 	_sifive_serial_init(plat->regs);
141 
142 	return 0;
143 }
144 
sifive_serial_getc(struct udevice * dev)145 static int sifive_serial_getc(struct udevice *dev)
146 {
147 	int c;
148 	struct sifive_uart_plat *plat = dev_get_plat(dev);
149 	struct uart_sifive *regs = plat->regs;
150 
151 	while ((c = _sifive_serial_getc(regs)) == -EAGAIN) ;
152 
153 	return c;
154 }
155 
sifive_serial_putc(struct udevice * dev,const char ch)156 static int sifive_serial_putc(struct udevice *dev, const char ch)
157 {
158 	int rc;
159 	struct sifive_uart_plat *plat = dev_get_plat(dev);
160 
161 	while ((rc = _sifive_serial_putc(plat->regs, ch)) == -EAGAIN) ;
162 
163 	return rc;
164 }
165 
sifive_serial_pending(struct udevice * dev,bool input)166 static int sifive_serial_pending(struct udevice *dev, bool input)
167 {
168 	struct sifive_uart_plat *plat = dev_get_plat(dev);
169 	struct uart_sifive *regs = plat->regs;
170 
171 	if (input)
172 		return (readl(&regs->ip) & UART_IP_RXWM);
173 	else
174 		return !!(readl(&regs->txfifo) & UART_TXFIFO_FULL);
175 }
176 
sifive_serial_of_to_plat(struct udevice * dev)177 static int sifive_serial_of_to_plat(struct udevice *dev)
178 {
179 	struct sifive_uart_plat *plat = dev_get_plat(dev);
180 
181 	plat->regs = (struct uart_sifive *)(uintptr_t)dev_read_addr(dev);
182 	if (IS_ERR(plat->regs))
183 		return PTR_ERR(plat->regs);
184 
185 	return 0;
186 }
187 
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,
193 };
194 
195 static const struct udevice_id sifive_serial_ids[] = {
196 	{ .compatible = "sifive,uart0" },
197 	{ }
198 };
199 
200 U_BOOT_DRIVER(serial_sifive) = {
201 	.name	= "serial_sifive",
202 	.id	= UCLASS_SERIAL,
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,
208 };
209 
210 #ifdef CONFIG_DEBUG_UART_SIFIVE
_debug_uart_init(void)211 static inline void _debug_uart_init(void)
212 {
213 	struct uart_sifive *regs =
214 			(struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE);
215 
216 	_sifive_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK,
217 			      CONFIG_BAUDRATE);
218 	_sifive_serial_init(regs);
219 }
220 
_debug_uart_putc(int ch)221 static inline void _debug_uart_putc(int ch)
222 {
223 	struct uart_sifive *regs =
224 			(struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE);
225 
226 	while (_sifive_serial_putc(regs, ch) == -EAGAIN)
227 		schedule();
228 }
229 
230 DEBUG_UART_FUNCS
231 
232 #endif
233