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