1 /*
2  * Copyright (c) 2017 Jean-Paul Etienne <fractalclone@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief UART driver for the SiFive Freedom Processor
9  */
10 
11 #define DT_DRV_COMPAT sifive_uart0
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/drivers/uart.h>
16 #include <zephyr/drivers/pinctrl.h>
17 #include <soc.h>
18 #include <zephyr/irq.h>
19 
20 #define RXDATA_EMPTY   (1 << 31)   /* Receive FIFO Empty */
21 #define RXDATA_MASK    0xFF        /* Receive Data Mask */
22 
23 #define TXDATA_FULL    (1 << 31)   /* Transmit FIFO Full */
24 
25 #define TXCTRL_TXEN    (1 << 0)    /* Activate Tx Channel */
26 
27 #define RXCTRL_RXEN    (1 << 0)    /* Activate Rx Channel */
28 
29 #define IE_TXWM        (1 << 0)    /* TX Interrupt Enable/Pending */
30 #define IE_RXWM        (1 << 1)    /* RX Interrupt Enable/Pending */
31 
32 /*
33  * RX/TX Threshold count to generate TX/RX Interrupts.
34  * Used by txctrl and rxctrl registers
35  */
36 #define CTRL_CNT(x)    (((x) & 0x07) << 16)
37 
38 struct uart_sifive_regs_t {
39 	uint32_t tx;
40 	uint32_t rx;
41 	uint32_t txctrl;
42 	uint32_t rxctrl;
43 	uint32_t ie;
44 	uint32_t ip;
45 	uint32_t div;
46 };
47 
48 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
49 typedef void (*irq_cfg_func_t)(void);
50 #endif
51 
52 struct uart_sifive_device_config {
53 	uintptr_t	port;
54 	uint32_t	sys_clk_freq;
55 	uint32_t	baud_rate;
56 	uint32_t	rxcnt_irq;
57 	uint32_t	txcnt_irq;
58 	const struct	pinctrl_dev_config *pcfg;
59 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
60 	irq_cfg_func_t	cfg_func;
61 #endif
62 };
63 
64 struct uart_sifive_data {
65 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
66 	uart_irq_callback_user_data_t callback;
67 	void *cb_data;
68 #endif
69 };
70 
71 #define DEV_UART(dev)						\
72 	((struct uart_sifive_regs_t *)				\
73 	 ((const struct uart_sifive_device_config * const)(dev)->config)->port)
74 
75 /**
76  * @brief Output a character in polled mode.
77  *
78  * Writes data to tx register if transmitter is not full.
79  *
80  * @param dev UART device struct
81  * @param c Character to send
82  */
uart_sifive_poll_out(const struct device * dev,unsigned char c)83 static void uart_sifive_poll_out(const struct device *dev,
84 					 unsigned char c)
85 {
86 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
87 
88 	/* Wait while TX FIFO is full */
89 	while (uart->tx & TXDATA_FULL) {
90 	}
91 
92 	uart->tx = (int)c;
93 }
94 
95 /**
96  * @brief Poll the device for input.
97  *
98  * @param dev UART device struct
99  * @param c Pointer to character
100  *
101  * @return 0 if a character arrived, -1 if the input buffer if empty.
102  */
uart_sifive_poll_in(const struct device * dev,unsigned char * c)103 static int uart_sifive_poll_in(const struct device *dev, unsigned char *c)
104 {
105 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
106 	uint32_t val = uart->rx;
107 
108 	if (val & RXDATA_EMPTY) {
109 		return -1;
110 	}
111 
112 	*c = (unsigned char)(val & RXDATA_MASK);
113 
114 	return 0;
115 }
116 
117 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
118 
119 /**
120  * @brief Fill FIFO with data
121  *
122  * @param dev UART device struct
123  * @param tx_data Data to transmit
124  * @param size Number of bytes to send
125  *
126  * @return Number of bytes sent
127  */
uart_sifive_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)128 static int uart_sifive_fifo_fill(const struct device *dev,
129 				 const uint8_t *tx_data,
130 				 int size)
131 {
132 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
133 	int i;
134 
135 	for (i = 0; i < size && !(uart->tx & TXDATA_FULL); i++) {
136 		uart->tx = (int)tx_data[i];
137 	}
138 
139 	return i;
140 }
141 
142 /**
143  * @brief Read data from FIFO
144  *
145  * @param dev UART device struct
146  * @param rxData Data container
147  * @param size Container size
148  *
149  * @return Number of bytes read
150  */
uart_sifive_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)151 static int uart_sifive_fifo_read(const struct device *dev,
152 				 uint8_t *rx_data,
153 				 const int size)
154 {
155 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
156 	int i;
157 	uint32_t val;
158 
159 	for (i = 0; i < size; i++) {
160 		val = uart->rx;
161 
162 		if (val & RXDATA_EMPTY) {
163 			break;
164 		}
165 
166 		rx_data[i] = (uint8_t)(val & RXDATA_MASK);
167 	}
168 
169 	return i;
170 }
171 
172 /**
173  * @brief Enable TX interrupt in ie register
174  *
175  * @param dev UART device struct
176  */
uart_sifive_irq_tx_enable(const struct device * dev)177 static void uart_sifive_irq_tx_enable(const struct device *dev)
178 {
179 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
180 
181 	uart->ie |= IE_TXWM;
182 }
183 
184 /**
185  * @brief Disable TX interrupt in ie register
186  *
187  * @param dev UART device struct
188  */
uart_sifive_irq_tx_disable(const struct device * dev)189 static void uart_sifive_irq_tx_disable(const struct device *dev)
190 {
191 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
192 
193 	uart->ie &= ~IE_TXWM;
194 }
195 
196 /**
197  * @brief Check if Tx IRQ has been raised
198  *
199  * @param dev UART device struct
200  *
201  * @return 1 if an IRQ is ready, 0 otherwise
202  */
uart_sifive_irq_tx_ready(const struct device * dev)203 static int uart_sifive_irq_tx_ready(const struct device *dev)
204 {
205 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
206 
207 	return !!(uart->ip & IE_TXWM);
208 }
209 
210 /**
211  * @brief Check if nothing remains to be transmitted
212  *
213  * @param dev UART device struct
214  *
215  * @return 1 if nothing remains to be transmitted, 0 otherwise
216  */
uart_sifive_irq_tx_complete(const struct device * dev)217 static int uart_sifive_irq_tx_complete(const struct device *dev)
218 {
219 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
220 
221 	/*
222 	 * No TX EMPTY flag for this controller,
223 	 * just check if TX FIFO is not full
224 	 */
225 	return !(uart->tx & TXDATA_FULL);
226 }
227 
228 /**
229  * @brief Enable RX interrupt in ie register
230  *
231  * @param dev UART device struct
232  */
uart_sifive_irq_rx_enable(const struct device * dev)233 static void uart_sifive_irq_rx_enable(const struct device *dev)
234 {
235 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
236 
237 	uart->ie |= IE_RXWM;
238 }
239 
240 /**
241  * @brief Disable RX interrupt in ie register
242  *
243  * @param dev UART device struct
244  */
uart_sifive_irq_rx_disable(const struct device * dev)245 static void uart_sifive_irq_rx_disable(const struct device *dev)
246 {
247 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
248 
249 	uart->ie &= ~IE_RXWM;
250 }
251 
252 /**
253  * @brief Check if Rx IRQ has been raised
254  *
255  * @param dev UART device struct
256  *
257  * @return 1 if an IRQ is ready, 0 otherwise
258  */
uart_sifive_irq_rx_ready(const struct device * dev)259 static int uart_sifive_irq_rx_ready(const struct device *dev)
260 {
261 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
262 
263 	return !!(uart->ip & IE_RXWM);
264 }
265 
266 /* No error interrupt for this controller */
uart_sifive_irq_err_enable(const struct device * dev)267 static void uart_sifive_irq_err_enable(const struct device *dev)
268 {
269 	ARG_UNUSED(dev);
270 }
271 
uart_sifive_irq_err_disable(const struct device * dev)272 static void uart_sifive_irq_err_disable(const struct device *dev)
273 {
274 	ARG_UNUSED(dev);
275 }
276 
277 /**
278  * @brief Check if any IRQ is pending
279  *
280  * @param dev UART device struct
281  *
282  * @return 1 if an IRQ is pending, 0 otherwise
283  */
uart_sifive_irq_is_pending(const struct device * dev)284 static int uart_sifive_irq_is_pending(const struct device *dev)
285 {
286 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
287 
288 	return !!(uart->ip & (IE_RXWM | IE_TXWM));
289 }
290 
uart_sifive_irq_update(const struct device * dev)291 static int uart_sifive_irq_update(const struct device *dev)
292 {
293 	return 1;
294 }
295 
296 /**
297  * @brief Set the callback function pointer for IRQ.
298  *
299  * @param dev UART device struct
300  * @param cb Callback function pointer.
301  */
uart_sifive_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)302 static void uart_sifive_irq_callback_set(const struct device *dev,
303 					 uart_irq_callback_user_data_t cb,
304 					 void *cb_data)
305 {
306 	struct uart_sifive_data *data = dev->data;
307 
308 	data->callback = cb;
309 	data->cb_data = cb_data;
310 }
311 
uart_sifive_irq_handler(const struct device * dev)312 static void uart_sifive_irq_handler(const struct device *dev)
313 {
314 	struct uart_sifive_data *data = dev->data;
315 
316 	if (data->callback) {
317 		data->callback(dev, data->cb_data);
318 	}
319 }
320 
321 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
322 
323 
uart_sifive_init(const struct device * dev)324 static int uart_sifive_init(const struct device *dev)
325 {
326 	const struct uart_sifive_device_config * const cfg = dev->config;
327 	volatile struct uart_sifive_regs_t *uart = DEV_UART(dev);
328 #ifdef CONFIG_PINCTRL
329 	int ret;
330 #endif
331 
332 	/* Enable TX and RX channels */
333 	uart->txctrl = TXCTRL_TXEN | CTRL_CNT(cfg->txcnt_irq);
334 	uart->rxctrl = RXCTRL_RXEN | CTRL_CNT(cfg->rxcnt_irq);
335 
336 	/* Set baud rate */
337 	uart->div = cfg->sys_clk_freq / cfg->baud_rate - 1;
338 
339 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
340 	/* Ensure that uart IRQ is disabled initially */
341 	uart->ie = 0U;
342 
343 	/* Setup IRQ handler */
344 	cfg->cfg_func();
345 #endif
346 
347 #ifdef CONFIG_PINCTRL
348 	ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
349 	if (ret < 0) {
350 		return ret;
351 	}
352 #endif
353 
354 	return 0;
355 }
356 
357 static DEVICE_API(uart, uart_sifive_driver_api) = {
358 	.poll_in          = uart_sifive_poll_in,
359 	.poll_out         = uart_sifive_poll_out,
360 	.err_check        = NULL,
361 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
362 	.fifo_fill        = uart_sifive_fifo_fill,
363 	.fifo_read        = uart_sifive_fifo_read,
364 	.irq_tx_enable    = uart_sifive_irq_tx_enable,
365 	.irq_tx_disable   = uart_sifive_irq_tx_disable,
366 	.irq_tx_ready     = uart_sifive_irq_tx_ready,
367 	.irq_tx_complete  = uart_sifive_irq_tx_complete,
368 	.irq_rx_enable    = uart_sifive_irq_rx_enable,
369 	.irq_rx_disable   = uart_sifive_irq_rx_disable,
370 	.irq_rx_ready     = uart_sifive_irq_rx_ready,
371 	.irq_err_enable   = uart_sifive_irq_err_enable,
372 	.irq_err_disable  = uart_sifive_irq_err_disable,
373 	.irq_is_pending   = uart_sifive_irq_is_pending,
374 	.irq_update       = uart_sifive_irq_update,
375 	.irq_callback_set = uart_sifive_irq_callback_set,
376 #endif
377 };
378 
379 #ifdef CONFIG_UART_SIFIVE_PORT_0
380 
381 static struct uart_sifive_data uart_sifive_data_0;
382 
383 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
384 static void uart_sifive_irq_cfg_func_0(void);
385 #endif
386 
387 PINCTRL_DT_INST_DEFINE(0);
388 
389 static const struct uart_sifive_device_config uart_sifive_dev_cfg_0 = {
390 	.port         = DT_INST_REG_ADDR(0),
391 	.sys_clk_freq = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY,
392 	.baud_rate    = DT_INST_PROP(0, current_speed),
393 	.rxcnt_irq    = CONFIG_UART_SIFIVE_PORT_0_RXCNT_IRQ,
394 	.txcnt_irq    = CONFIG_UART_SIFIVE_PORT_0_TXCNT_IRQ,
395 	.pcfg	      = PINCTRL_DT_INST_DEV_CONFIG_GET(0),
396 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
397 	.cfg_func     = uart_sifive_irq_cfg_func_0,
398 #endif
399 };
400 
401 DEVICE_DT_INST_DEFINE(0,
402 		    uart_sifive_init,
403 		    NULL,
404 		    &uart_sifive_data_0, &uart_sifive_dev_cfg_0,
405 		    PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,
406 		    (void *)&uart_sifive_driver_api);
407 
408 
409 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_sifive_irq_cfg_func_0(void)410 static void uart_sifive_irq_cfg_func_0(void)
411 {
412 	IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
413 		    uart_sifive_irq_handler, DEVICE_DT_INST_GET(0),
414 		    0);
415 
416 	irq_enable(DT_INST_IRQN(0));
417 }
418 #endif
419 
420 #endif /* CONFIG_UART_SIFIVE_PORT_0 */
421 
422 #ifdef CONFIG_UART_SIFIVE_PORT_1
423 
424 static struct uart_sifive_data uart_sifive_data_1;
425 
426 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
427 static void uart_sifive_irq_cfg_func_1(void);
428 #endif
429 
430 PINCTRL_DT_INST_DEFINE(1);
431 
432 static const struct uart_sifive_device_config uart_sifive_dev_cfg_1 = {
433 	.port         = DT_INST_REG_ADDR(1),
434 	.sys_clk_freq = SIFIVE_PERIPHERAL_CLOCK_FREQUENCY,
435 	.baud_rate    = DT_INST_PROP(1, current_speed),
436 	.rxcnt_irq    = CONFIG_UART_SIFIVE_PORT_1_RXCNT_IRQ,
437 	.txcnt_irq    = CONFIG_UART_SIFIVE_PORT_1_TXCNT_IRQ,
438 	.pcfg	      = PINCTRL_DT_INST_DEV_CONFIG_GET(1),
439 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
440 	.cfg_func     = uart_sifive_irq_cfg_func_1,
441 #endif
442 };
443 
444 DEVICE_DT_INST_DEFINE(1,
445 		    uart_sifive_init,
446 		    NULL,
447 		    &uart_sifive_data_1, &uart_sifive_dev_cfg_1,
448 		    PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,
449 		    (void *)&uart_sifive_driver_api);
450 
451 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_sifive_irq_cfg_func_1(void)452 static void uart_sifive_irq_cfg_func_1(void)
453 {
454 	IRQ_CONNECT(DT_INST_IRQN(1), DT_INST_IRQ(1, priority),
455 		    uart_sifive_irq_handler, DEVICE_DT_INST_GET(1),
456 		    0);
457 
458 	irq_enable(DT_INST_IRQN(1));
459 }
460 #endif
461 
462 #endif /* CONFIG_UART_SIFIVE_PORT_1 */
463