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 	for (i = 0; i < size && !litex_read8(config->txfull_addr); i++) {
208 		litex_write8(tx_data[i], config->rxtx_addr);
209 	}
210 
211 	return i;
212 }
213 
214 /**
215  * @brief Read data from FIFO
216  *
217  * @param dev UART device struct
218  * @param rxData Data container
219  * @param size Container size
220  *
221  * @return Number of bytes read
222  */
uart_litex_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)223 static int uart_litex_fifo_read(const struct device *dev,
224 				uint8_t *rx_data, const int size)
225 {
226 	const struct uart_litex_device_config *config = dev->config;
227 	int i;
228 
229 	for (i = 0; i < size && !litex_read8(config->rxempty_addr); i++) {
230 		rx_data[i] = litex_read8(config->rxtx_addr);
231 
232 		/* refresh UART_RXEMPTY by writing UART_EV_RX
233 		 * to UART_EV_PENDING
234 		 */
235 		litex_write8(UART_EV_RX, config->ev_pending_addr);
236 	}
237 
238 	return i;
239 }
240 
uart_litex_irq_err(const struct device * dev)241 static void uart_litex_irq_err(const struct device *dev)
242 {
243 	ARG_UNUSED(dev);
244 }
245 
246 /**
247  * @brief Check if any IRQ is pending
248  *
249  * @param dev UART device struct
250  *
251  * @return 1 if an IRQ is pending, 0 otherwise
252  */
uart_litex_irq_is_pending(const struct device * dev)253 static int uart_litex_irq_is_pending(const struct device *dev)
254 {
255 	return (uart_litex_irq_tx_ready(dev) || uart_litex_irq_rx_ready(dev));
256 }
257 
uart_litex_irq_update(const struct device * dev)258 static int uart_litex_irq_update(const struct device *dev)
259 {
260 	return 1;
261 }
262 
263 /**
264  * @brief Set the callback function pointer for IRQ.
265  *
266  * @param dev UART device struct
267  * @param cb Callback function pointer.
268  */
uart_litex_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)269 static void uart_litex_irq_callback_set(const struct device *dev,
270 					uart_irq_callback_user_data_t cb,
271 					void *cb_data)
272 {
273 	struct uart_litex_data *data;
274 
275 	data = dev->data;
276 	data->callback = cb;
277 	data->cb_data = cb_data;
278 }
279 
uart_litex_irq_handler(const struct device * dev)280 static void uart_litex_irq_handler(const struct device *dev)
281 {
282 	const struct uart_litex_device_config *config = dev->config;
283 	struct uart_litex_data *data = dev->data;
284 	unsigned int key = irq_lock();
285 
286 	if (data->callback) {
287 		data->callback(dev, data->cb_data);
288 	}
289 
290 	/* Clear RX events, TX events still needed to enqueue the next transfer */
291 	litex_write8(UART_EV_RX, config->ev_pending_addr);
292 
293 	irq_unlock(key);
294 }
295 
uart_litex_tx_soft_isr(struct k_timer * timer)296 static void uart_litex_tx_soft_isr(struct k_timer *timer)
297 {
298 	const struct device *dev = k_timer_user_data_get(timer);
299 
300 	uart_litex_irq_handler(dev);
301 }
302 #endif	/* CONFIG_UART_INTERRUPT_DRIVEN */
303 
304 static DEVICE_API(uart, uart_litex_driver_api) = {
305 	.poll_in		= uart_litex_poll_in,
306 	.poll_out		= uart_litex_poll_out,
307 	.err_check		= NULL,
308 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
309 	.fifo_fill		= uart_litex_fifo_fill,
310 	.fifo_read		= uart_litex_fifo_read,
311 	.irq_tx_enable		= uart_litex_irq_tx_enable,
312 	.irq_tx_disable		= uart_litex_irq_tx_disable,
313 	.irq_tx_ready		= uart_litex_irq_tx_ready,
314 	.irq_rx_enable		= uart_litex_irq_rx_enable,
315 	.irq_rx_disable		= uart_litex_irq_rx_disable,
316 	.irq_rx_ready		= uart_litex_irq_rx_ready,
317 	.irq_err_enable		= uart_litex_irq_err,
318 	.irq_err_disable	= uart_litex_irq_err,
319 	.irq_is_pending		= uart_litex_irq_is_pending,
320 	.irq_update		= uart_litex_irq_update,
321 	.irq_callback_set	= uart_litex_irq_callback_set
322 #endif
323 };
324 
uart_litex_init(const struct device * dev)325 static int uart_litex_init(const struct device *dev)
326 {
327 	const struct uart_litex_device_config *config = dev->config;
328 
329 	litex_write8(UART_EV_TX | UART_EV_RX, config->ev_pending_addr);
330 
331 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
332 	struct uart_litex_data *data = dev->data;
333 
334 	k_timer_init(&data->timer, &uart_litex_tx_soft_isr, NULL);
335 	k_timer_user_data_set(&data->timer, (void *)dev);
336 
337 	config->config_func(dev);
338 #endif
339 
340 	return 0;
341 }
342 
343 #define LITEX_UART_IRQ_INIT(n)                                                                     \
344 	static void uart_irq_config##n(const struct device *dev)                                   \
345 	{                                                                                          \
346 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_litex_irq_handler,     \
347 			    DEVICE_DT_INST_GET(n), 0);                                             \
348                                                                                                    \
349 		irq_enable(DT_INST_IRQN(n));                                                       \
350 	}
351 
352 #define LITEX_UART_INIT(n)                                                                         \
353 	IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (LITEX_UART_IRQ_INIT(n)))                         \
354                                                                                                    \
355 	static struct uart_litex_data uart_litex_data_##n;                                         \
356                                                                                                    \
357 	static const struct uart_litex_device_config uart_litex_dev_cfg_##n = {                    \
358 		.rxtx_addr = DT_INST_REG_ADDR_BY_NAME(n, rxtx),                                    \
359 		.txfull_addr = DT_INST_REG_ADDR_BY_NAME(n, txfull),                                \
360 		.rxempty_addr = DT_INST_REG_ADDR_BY_NAME(n, rxempty),                              \
361 		.ev_status_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_status),                          \
362 		.ev_pending_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_pending),                        \
363 		.ev_enable_addr = DT_INST_REG_ADDR_BY_NAME(n, ev_enable),                          \
364 		.txempty_addr = DT_INST_REG_ADDR_BY_NAME(n, txempty),                              \
365 		.rxfull_addr = DT_INST_REG_ADDR_BY_NAME(n, rxfull),                                \
366 		.baud_rate = DT_INST_PROP(n, current_speed),                                       \
367 		IF_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN, (.config_func = uart_irq_config##n,))};   \
368                                                                                                    \
369 	DEVICE_DT_INST_DEFINE(n, uart_litex_init, NULL, &uart_litex_data_##n,                      \
370 			      &uart_litex_dev_cfg_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,  \
371 			      (void *)&uart_litex_driver_api);
372 
373 DT_INST_FOREACH_STATUS_OKAY(LITEX_UART_INIT)
374