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