1 /*
2  * Copyright (c) 2018 - 2019 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT litex_uart
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/arch/cpu.h>
11 #include <zephyr/init.h>
12 #include <zephyr/irq.h>
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/uart.h>
15 #include <zephyr/types.h>
16 
17 #include <soc.h>
18 
19 #define UART_EV_TX		BIT(0)
20 #define UART_EV_RX		BIT(1)
21 
22 struct uart_litex_device_config {
23 	uint32_t rxtx_addr;
24 	uint32_t txfull_addr;
25 	uint32_t rxempty_addr;
26 	uint32_t ev_status_addr;
27 	uint32_t ev_pending_addr;
28 	uint32_t ev_enable_addr;
29 	uint32_t txempty_addr;
30 	uint32_t rxfull_addr;
31 	uint32_t baud_rate;
32 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
33 	void (*config_func)(const struct device *dev);
34 #endif
35 };
36 
37 struct uart_litex_data {
38 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
39 	struct k_timer timer;
40 	uart_irq_callback_user_data_t callback;
41 	void *cb_data;
42 #endif
43 };
44 
45 /**
46  * @brief Output a character in polled mode.
47  *
48  * Writes data to tx register. Waits for space if transmitter is full.
49  *
50  * @param dev UART device struct
51  * @param c Character to send
52  */
uart_litex_poll_out(const struct device * dev,unsigned char c)53 static void uart_litex_poll_out(const struct device *dev, unsigned char c)
54 {
55 	const struct uart_litex_device_config *config = dev->config;
56 	/* wait for space */
57 	while (litex_read8(config->txfull_addr)) {
58 	}
59 
60 	litex_write8(c, config->rxtx_addr);
61 }
62 
63 /**
64  * @brief Poll the device for input.
65  *
66  * @param dev UART device struct
67  * @param c Pointer to character
68  *
69  * @return 0 if a character arrived, -1 if the input buffer if empty.
70  */
uart_litex_poll_in(const struct device * dev,unsigned char * c)71 static int uart_litex_poll_in(const struct device *dev, unsigned char *c)
72 {
73 	const struct uart_litex_device_config *config = dev->config;
74 
75 	if (!litex_read8(config->rxempty_addr)) {
76 		*c = litex_read8(config->rxtx_addr);
77 
78 		/* refresh UART_RXEMPTY by writing UART_EV_RX
79 		 * to UART_EV_PENDING
80 		 */
81 		litex_write8(UART_EV_RX, config->ev_pending_addr);
82 		return 0;
83 	} else {
84 		return -1;
85 	}
86 }
87 
88 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
89 /**
90  * @brief Enable TX interrupt in event register
91  *
92  * @param dev UART device struct
93  */
uart_litex_irq_tx_enable(const struct device * dev)94 static void uart_litex_irq_tx_enable(const struct device *dev)
95 {
96 	const struct uart_litex_device_config *config = dev->config;
97 	struct uart_litex_data *data = dev->data;
98 
99 	uint8_t enable = litex_read8(config->ev_enable_addr);
100 
101 	litex_write8(enable | UART_EV_TX, config->ev_enable_addr);
102 
103 	if (!litex_read8(config->txfull_addr)) {
104 		/*
105 		 * TX done event already generated an edge interrupt. Generate a
106 		 * soft interrupt and have it call the callback function in
107 		 * timer isr context.
108 		 */
109 		k_timer_start(&data->timer, K_NO_WAIT, K_NO_WAIT);
110 	}
111 }
112 
113 /**
114  * @brief Disable TX interrupt in event register
115  *
116  * @param dev UART device struct
117  */
uart_litex_irq_tx_disable(const struct device * dev)118 static void uart_litex_irq_tx_disable(const struct device *dev)
119 {
120 	const struct uart_litex_device_config *config = dev->config;
121 
122 	uint8_t enable = litex_read8(config->ev_enable_addr);
123 
124 	litex_write8(enable & ~(UART_EV_TX), config->ev_enable_addr);
125 }
126 
127 /**
128  * @brief Enable RX interrupt in event register
129  *
130  * @param dev UART device struct
131  */
uart_litex_irq_rx_enable(const struct device * dev)132 static void uart_litex_irq_rx_enable(const struct device *dev)
133 {
134 	const struct uart_litex_device_config *config = dev->config;
135 
136 	uint8_t enable = litex_read8(config->ev_enable_addr);
137 
138 	litex_write8(enable | UART_EV_RX, config->ev_enable_addr);
139 }
140 
141 /**
142  * @brief Disable RX interrupt in event register
143  *
144  * @param dev UART device struct
145  */
uart_litex_irq_rx_disable(const struct device * dev)146 static void uart_litex_irq_rx_disable(const struct device *dev)
147 {
148 	const struct uart_litex_device_config *config = dev->config;
149 
150 	uint8_t enable = litex_read8(config->ev_enable_addr);
151 
152 	litex_write8(enable & ~(UART_EV_RX), config->ev_enable_addr);
153 }
154 
155 /**
156  * @brief Check if Tx IRQ has been raised and UART is ready to accept new data
157  *
158  * @param dev UART device struct
159  *
160  * @return 1 if an IRQ has been raised, 0 otherwise
161  */
uart_litex_irq_tx_ready(const struct device * dev)162 static int uart_litex_irq_tx_ready(const struct device *dev)
163 {
164 	const struct uart_litex_device_config *config = dev->config;
165 
166 	uint8_t val = litex_read8(config->txfull_addr);
167 
168 	return !val;
169 }
170 
171 /**
172  * @brief Check if Rx IRQ has been raised and there's data to be read from UART
173  *
174  * @param dev UART device struct
175  *
176  * @return 1 if an IRQ has been raised, 0 otherwise
177  */
uart_litex_irq_rx_ready(const struct device * dev)178 static int uart_litex_irq_rx_ready(const struct device *dev)
179 {
180 	const struct uart_litex_device_config *config = dev->config;
181 	uint8_t pending;
182 
183 	pending = litex_read8(config->ev_pending_addr);
184 
185 	if (pending & UART_EV_RX) {
186 		return 1;
187 	} else {
188 		return 0;
189 	}
190 }
191 
192 /**
193  * @brief Fill FIFO with data
194  *
195  * @param dev UART device struct
196  * @param tx_data Data to transmit
197  * @param size Number of bytes to send
198  *
199  * @return Number of bytes sent
200  */
uart_litex_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)201 static int uart_litex_fifo_fill(const struct device *dev,
202 				const uint8_t *tx_data, int size)
203 {
204 	const struct uart_litex_device_config *config = dev->config;
205 	int i;
206 
207 	litex_write8(UART_EV_RX, config->ev_pending_addr);
208 	for (i = 0; i < size && !litex_read8(config->txfull_addr); i++) {
209 		litex_write8(tx_data[i], config->rxtx_addr);
210 	}
211 	while (!litex_read8(config->txfull_addr)) {
212 		litex_write8(0, config->rxtx_addr);
213 	}
214 
215 	return i;
216 }
217 
218 /**
219  * @brief Read data from FIFO
220  *
221  * @param dev UART device struct
222  * @param rxData Data container
223  * @param size Container size
224  *
225  * @return Number of bytes read
226  */
uart_litex_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)227 static int uart_litex_fifo_read(const struct device *dev,
228 				uint8_t *rx_data, const int size)
229 {
230 	const struct uart_litex_device_config *config = dev->config;
231 	int i;
232 
233 	for (i = 0; i < size && !litex_read8(config->rxempty_addr); i++) {
234 		rx_data[i] = litex_read8(config->rxtx_addr);
235 
236 		/* refresh UART_RXEMPTY by writing UART_EV_RX
237 		 * to UART_EV_PENDING
238 		 */
239 		litex_write8(UART_EV_RX, config->ev_pending_addr);
240 	}
241 
242 	return i;
243 }
244 
uart_litex_irq_err(const struct device * dev)245 static void uart_litex_irq_err(const struct device *dev)
246 {
247 	ARG_UNUSED(dev);
248 }
249 
250 /**
251  * @brief Check if any IRQ is pending
252  *
253  * @param dev UART device struct
254  *
255  * @return 1 if an IRQ is pending, 0 otherwise
256  */
uart_litex_irq_is_pending(const struct device * dev)257 static int uart_litex_irq_is_pending(const struct device *dev)
258 {
259 	return (uart_litex_irq_tx_ready(dev) || uart_litex_irq_rx_ready(dev));
260 }
261 
uart_litex_irq_update(const struct device * dev)262 static int uart_litex_irq_update(const struct device *dev)
263 {
264 	return 1;
265 }
266 
267 /**
268  * @brief Set the callback function pointer for IRQ.
269  *
270  * @param dev UART device struct
271  * @param cb Callback function pointer.
272  */
uart_litex_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)273 static void uart_litex_irq_callback_set(const struct device *dev,
274 					uart_irq_callback_user_data_t cb,
275 					void *cb_data)
276 {
277 	struct uart_litex_data *data;
278 
279 	data = dev->data;
280 	data->callback = cb;
281 	data->cb_data = cb_data;
282 }
283 
uart_litex_irq_handler(const struct device * dev)284 static void uart_litex_irq_handler(const struct device *dev)
285 {
286 	const struct uart_litex_device_config *config = dev->config;
287 	struct uart_litex_data *data = dev->data;
288 	unsigned int key = irq_lock();
289 
290 	if (data->callback) {
291 		data->callback(dev, data->cb_data);
292 	}
293 
294 	/* Clear RX events, TX events still needed to enqueue the next transfer */
295 	if (litex_read8(config->rxempty_addr)) {
296 		litex_write8(UART_EV_RX, config->ev_pending_addr);
297 	}
298 
299 	irq_unlock(key);
300 }
301 
uart_litex_tx_soft_isr(struct k_timer * timer)302 static void uart_litex_tx_soft_isr(struct k_timer *timer)
303 {
304 	const struct device *dev = k_timer_user_data_get(timer);
305 
306 	uart_litex_irq_handler(dev);
307 }
308 #endif	/* CONFIG_UART_INTERRUPT_DRIVEN */
309 
310 static DEVICE_API(uart, uart_litex_driver_api) = {
311 	.poll_in		= uart_litex_poll_in,
312 	.poll_out		= uart_litex_poll_out,
313 	.err_check		= NULL,
314 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
315 	.fifo_fill		= uart_litex_fifo_fill,
316 	.fifo_read		= uart_litex_fifo_read,
317 	.irq_tx_enable		= uart_litex_irq_tx_enable,
318 	.irq_tx_disable		= uart_litex_irq_tx_disable,
319 	.irq_tx_ready		= uart_litex_irq_tx_ready,
320 	.irq_rx_enable		= uart_litex_irq_rx_enable,
321 	.irq_rx_disable		= uart_litex_irq_rx_disable,
322 	.irq_rx_ready		= uart_litex_irq_rx_ready,
323 	.irq_err_enable		= uart_litex_irq_err,
324 	.irq_err_disable	= uart_litex_irq_err,
325 	.irq_is_pending		= uart_litex_irq_is_pending,
326 	.irq_update		= uart_litex_irq_update,
327 	.irq_callback_set	= uart_litex_irq_callback_set
328 #endif
329 };
330 
uart_litex_init(const struct device * dev)331 static int uart_litex_init(const struct device *dev)
332 {
333 	const struct uart_litex_device_config *config = dev->config;
334 
335 	litex_write8(UART_EV_TX | UART_EV_RX, config->ev_pending_addr);
336 
337 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
338 	struct uart_litex_data *data = dev->data;
339 
340 	k_timer_init(&data->timer, &uart_litex_tx_soft_isr, NULL);
341 	k_timer_user_data_set(&data->timer, (void *)dev);
342 
343 	config->config_func(dev);
344 #endif
345 
346 	return 0;
347 }
348 
349 #define LITEX_UART_IRQ_INIT(n)                                                                     \
350 	static void uart_irq_config##n(const struct device *dev)                                   \
351 	{                                                                                          \
352 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_litex_irq_handler,     \
353 			    DEVICE_DT_INST_GET(n), 0);                                             \
354                                                                                                    \
355 		irq_enable(DT_INST_IRQN(n));                                                       \
356 	}
357 
358 #define LITEX_UART_INIT(n)                                                                         \
359 	IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (LITEX_UART_IRQ_INIT(n)))                         \
360                                                                                                    \
361 	static struct uart_litex_data uart_litex_data_##n;                                         \
362                                                                                                    \
363 	static const struct uart_litex_device_config uart_litex_dev_cfg_##n = {                    \
364 		.rxtx_addr = DT_INST_REG_ADDR_BY_NAME(n, rxtx),                                    \
365 		.txfull_addr = DT_INST_REG_ADDR_BY_NAME(n, txfull),                                \
366 		.rxempty_addr = DT_INST_REG_ADDR_BY_NAME(n, rxempty),                              \
367 		.ev_status_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_status),                          \
368 		.ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_pending),                        \
369 		.ev_enable_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_enable),                          \
370 		.txempty_addr = DT_INST_REG_ADDR_BY_NAME(n, txempty),                              \
371 		.rxfull_addr = DT_INST_REG_ADDR_BY_NAME(n, rxfull),                                \
372 		.baud_rate = DT_INST_PROP(n, current_speed),                                       \
373 		IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (.config_func = uart_irq_config##n,))};   \
374                                                                                                    \
375 	DEVICE_DT_INST_DEFINE(n, uart_litex_init, NULL, &uart_litex_data_##n,                      \
376 			      &uart_litex_dev_cfg_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,  \
377 			      (void *)&uart_litex_driver_api);
378 
379 DT_INST_FOREACH_STATUS_OKAY(LITEX_UART_INIT)
380