1 /*
2 * Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT neorv32_uart
8
9 #include <zephyr/device.h>
10 #include <zephyr/drivers/syscon.h>
11 #include <zephyr/drivers/uart.h>
12 #include <zephyr/pm/device.h>
13 #include <zephyr/sys/sys_io.h>
14 #include <zephyr/logging/log.h>
15 #include <zephyr/irq.h>
16
17 #include <soc.h>
18
19 LOG_MODULE_REGISTER(uart_neorv32, CONFIG_UART_LOG_LEVEL);
20
21 /* NEORV32 UART registers offsets */
22 #define NEORV32_UART_CTRL_OFFSET 0x00
23 #define NEORV32_UART_DATA_OFFSET 0x04
24
25 /* UART_CTRL register bits */
26 #define NEORV32_UART_CTRL_EN BIT(0)
27 #define NEORV32_UART_CTRL_SIM_MODE BIT(1)
28 #define NEORV32_UART_CTRL_HWFC_EN BIT(2)
29 #define NEORV32_UART_CTRL_PRSC_POS 3U
30 #define NEORV32_UART_CTRL_PRSC_MASK BIT_MASK(3)
31 #define NEORV32_UART_CTRL_BAUD_POS 6U
32 #define NEORV32_UART_CTRL_BAUD_MASK BIT_MASK(10)
33 #define NEORV32_UART_CTRL_RX_NEMPTY BIT(16)
34 #define NEORV32_UART_CTRL_RX_HALF BIT(17)
35 #define NEORV32_UART_CTRL_RX_FULL BIT(18)
36 #define NEORV32_UART_CTRL_TX_NEMPTY BIT(19)
37 #define NEORV32_UART_CTRL_TX_HALF BIT(20)
38 #define NEORV32_UART_CTRL_TX_FULL BIT(21)
39 #define NEORV32_UART_CTRL_IRQ_RX_NEMPTY BIT(22)
40 #define NEORV32_UART_CTRL_IRQ_RX_HALF BIT(23)
41 #define NEORV32_UART_CTRL_IRQ_RX_FULL BIT(24)
42 #define NEORV32_UART_CTRL_IRQ_TX_EMPTY BIT(25)
43 #define NEORV32_UART_CTRL_IRQ_TX_NHALF BIT(26)
44 #define NEORV32_UART_CTRL_RX_OVER BIT(30)
45 #define NEORV32_UART_CTRL_TX_BUSY BIT(31)
46
47 struct neorv32_uart_config {
48 const struct device *syscon;
49 uint32_t feature_mask;
50 mm_reg_t base;
51 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
52 void (*irq_config_func)(const struct device *dev);
53 unsigned int tx_irq;
54 unsigned int rx_irq;
55 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
56 };
57
58 struct neorv32_uart_data {
59 struct uart_config uart_cfg;
60 uint32_t last_data;
61 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
62 struct k_timer timer;
63 uart_irq_callback_user_data_t callback;
64 void *callback_data;
65 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
66 };
67
neorv32_uart_read_ctrl(const struct device * dev)68 static inline uint32_t neorv32_uart_read_ctrl(const struct device *dev)
69 {
70 const struct neorv32_uart_config *config = dev->config;
71
72 return sys_read32(config->base + NEORV32_UART_CTRL_OFFSET);
73 }
74
neorv32_uart_write_ctrl(const struct device * dev,uint32_t ctrl)75 static inline void neorv32_uart_write_ctrl(const struct device *dev, uint32_t ctrl)
76 {
77 const struct neorv32_uart_config *config = dev->config;
78
79 sys_write32(ctrl, config->base + NEORV32_UART_CTRL_OFFSET);
80 }
81
neorv32_uart_read_data(const struct device * dev)82 static inline uint32_t neorv32_uart_read_data(const struct device *dev)
83 {
84 const struct neorv32_uart_config *config = dev->config;
85 struct neorv32_uart_data *data = dev->data;
86 uint32_t reg;
87
88 /* Cache status bits as they are cleared upon read */
89 reg = sys_read32(config->base + NEORV32_UART_DATA_OFFSET);
90 data->last_data = reg;
91
92 return reg;
93 }
94
neorv32_uart_write_data(const struct device * dev,uint32_t data)95 static inline void neorv32_uart_write_data(const struct device *dev, uint32_t data)
96 {
97 const struct neorv32_uart_config *config = dev->config;
98
99 sys_write32(data, config->base + NEORV32_UART_DATA_OFFSET);
100 }
101
neorv32_uart_poll_in(const struct device * dev,unsigned char * c)102 static int neorv32_uart_poll_in(const struct device *dev, unsigned char *c)
103 {
104 uint32_t data;
105
106 data = neorv32_uart_read_data(dev);
107
108 if ((data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
109 *c = data & BIT_MASK(8);
110 return 0;
111 }
112
113 return -1;
114 }
115
neorv32_uart_poll_out(const struct device * dev,unsigned char c)116 static void neorv32_uart_poll_out(const struct device *dev, unsigned char c)
117 {
118 while ((neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_TX_BUSY) != 0) {
119 }
120
121 neorv32_uart_write_data(dev, c);
122 }
123
neorv32_uart_configure(const struct device * dev,const struct uart_config * cfg)124 static int neorv32_uart_configure(const struct device *dev, const struct uart_config *cfg)
125 {
126 const struct neorv32_uart_config *config = dev->config;
127 struct neorv32_uart_data *data = dev->data;
128 uint32_t ctrl = NEORV32_UART_CTRL_EN;
129 uint16_t baudxx = 0;
130 uint8_t prscx = 0;
131 uint32_t clk;
132 int err;
133
134 __ASSERT_NO_MSG(cfg != NULL);
135
136 if (cfg->stop_bits != UART_CFG_STOP_BITS_1) {
137 LOG_ERR("hardware only supports one stop bit");
138 return -ENOTSUP;
139 }
140
141 if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
142 LOG_ERR("hardware only supports 8 data bits");
143 return -ENOTSUP;
144 }
145
146 switch (cfg->parity) {
147 case UART_CFG_PARITY_NONE:
148 break;
149 default:
150 LOG_ERR("unsupported parity mode %d", cfg->parity);
151 return -ENOTSUP;
152 }
153
154 switch (cfg->flow_ctrl) {
155 case UART_CFG_FLOW_CTRL_NONE:
156 ctrl |= 0;
157 break;
158 case UART_CFG_FLOW_CTRL_RTS_CTS:
159 ctrl |= NEORV32_UART_CTRL_HWFC_EN;
160 break;
161 default:
162 LOG_ERR("unsupported flow control mode %d", cfg->flow_ctrl);
163 return -ENOTSUP;
164 }
165
166 err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_CLK, &clk);
167 if (err < 0) {
168 LOG_ERR("failed to determine clock rate (err %d)", err);
169 return -EIO;
170 }
171
172 if (cfg->baudrate == 0) {
173 LOG_ERR("invalid baud rate 0");
174 return -EINVAL;
175 }
176
177 /*
178 * Calculate clock prescaler and baud prescaler. Initial prscx = 0 is
179 * clock / 2.
180 */
181 baudxx = clk / (2 * cfg->baudrate);
182 while (baudxx >= NEORV32_UART_CTRL_BAUD_MASK) {
183 if ((prscx == 2) || (prscx == 4)) {
184 baudxx >>= 3;
185 } else {
186 baudxx >>= 1;
187 }
188
189 prscx++;
190 }
191
192 if (prscx > NEORV32_UART_CTRL_PRSC_MASK) {
193 LOG_ERR("unsupported baud rate %d", cfg->baudrate);
194 return -ENOTSUP;
195 }
196
197 ctrl |= (baudxx - 1) << NEORV32_UART_CTRL_BAUD_POS;
198 ctrl |= prscx << NEORV32_UART_CTRL_PRSC_POS;
199
200 data->uart_cfg = *cfg;
201 neorv32_uart_write_ctrl(dev, ctrl);
202
203 return 0;
204 }
205
neorv32_uart_config_get(const struct device * dev,struct uart_config * cfg)206 static int neorv32_uart_config_get(const struct device *dev, struct uart_config *cfg)
207 {
208 struct neorv32_uart_data *data = dev->data;
209
210 __ASSERT_NO_MSG(cfg != NULL);
211
212 *cfg = data->uart_cfg;
213
214 return 0;
215 }
216
217 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
neorv32_uart_fifo_fill(const struct device * dev,const uint8_t * tx_data,int len)218 static int neorv32_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
219 {
220 uint32_t ctrl;
221
222 if (len <= 0) {
223 return 0;
224 }
225
226 __ASSERT_NO_MSG(tx_data != NULL);
227
228 ctrl = neorv32_uart_read_ctrl(dev);
229 if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
230 neorv32_uart_write_data(dev, *tx_data);
231 return 1;
232 }
233
234 return 0;
235 }
236
neorv32_uart_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)237 static int neorv32_uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
238 {
239 struct neorv32_uart_data *data = dev->data;
240 int count = 0;
241
242 if (size <= 0) {
243 return 0;
244 }
245
246 __ASSERT_NO_MSG(rx_data != NULL);
247
248 while ((data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0) {
249 rx_data[count++] = data->last_data & BIT_MASK(8);
250 data->last_data &= ~(NEORV32_UART_CTRL_RX_NEMPTY);
251
252 if (count >= size) {
253 break;
254 }
255
256 (void)neorv32_uart_read_data(dev);
257 }
258
259 return count;
260 }
261
neorv32_uart_tx_soft_isr(struct k_timer * timer)262 static void neorv32_uart_tx_soft_isr(struct k_timer *timer)
263 {
264 const struct device *dev = k_timer_user_data_get(timer);
265 struct neorv32_uart_data *data = dev->data;
266 uart_irq_callback_user_data_t callback = data->callback;
267
268 if (callback) {
269 callback(dev, data->callback_data);
270 }
271 }
272
neorv32_uart_irq_tx_enable(const struct device * dev)273 static void neorv32_uart_irq_tx_enable(const struct device *dev)
274 {
275 const struct neorv32_uart_config *config = dev->config;
276 struct neorv32_uart_data *data = dev->data;
277 uint32_t ctrl;
278
279 irq_enable(config->tx_irq);
280
281 ctrl = neorv32_uart_read_ctrl(dev);
282 if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
283 /*
284 * TX done event already generated an edge interrupt. Generate a
285 * soft interrupt and have it call the callback function in
286 * timer isr context.
287 */
288 k_timer_start(&data->timer, K_NO_WAIT, K_NO_WAIT);
289 }
290 }
291
neorv32_uart_irq_tx_disable(const struct device * dev)292 static void neorv32_uart_irq_tx_disable(const struct device *dev)
293 {
294 const struct neorv32_uart_config *config = dev->config;
295
296 irq_disable(config->tx_irq);
297 }
298
neorv32_uart_irq_tx_ready(const struct device * dev)299 static int neorv32_uart_irq_tx_ready(const struct device *dev)
300 {
301 const struct neorv32_uart_config *config = dev->config;
302 uint32_t ctrl;
303
304 if (!irq_is_enabled(config->tx_irq)) {
305 return 0;
306 }
307
308 ctrl = neorv32_uart_read_ctrl(dev);
309
310 return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
311 }
312
neorv32_uart_irq_rx_enable(const struct device * dev)313 static void neorv32_uart_irq_rx_enable(const struct device *dev)
314 {
315 const struct neorv32_uart_config *config = dev->config;
316
317 irq_enable(config->rx_irq);
318 }
319
neorv32_uart_irq_rx_disable(const struct device * dev)320 static void neorv32_uart_irq_rx_disable(const struct device *dev)
321 {
322 const struct neorv32_uart_config *config = dev->config;
323
324 irq_disable(config->rx_irq);
325 }
326
neorv32_uart_irq_tx_complete(const struct device * dev)327 static int neorv32_uart_irq_tx_complete(const struct device *dev)
328 {
329 uint32_t ctrl;
330
331 ctrl = neorv32_uart_read_ctrl(dev);
332
333 return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
334 }
335
neorv32_uart_irq_rx_ready(const struct device * dev)336 static int neorv32_uart_irq_rx_ready(const struct device *dev)
337 {
338 const struct neorv32_uart_config *config = dev->config;
339 struct neorv32_uart_data *data = dev->data;
340
341 if (!irq_is_enabled(config->rx_irq)) {
342 return 0;
343 }
344
345 return (data->last_data & NEORV32_UART_CTRL_RX_NEMPTY) != 0;
346 }
347
neorv32_uart_irq_is_pending(const struct device * dev)348 static int neorv32_uart_irq_is_pending(const struct device *dev)
349 {
350 return (neorv32_uart_irq_tx_ready(dev) ||
351 neorv32_uart_irq_rx_ready(dev));
352 }
353
neorv32_uart_irq_update(const struct device * dev)354 static int neorv32_uart_irq_update(const struct device *dev)
355 {
356 const struct neorv32_uart_config *config = dev->config;
357
358 if (irq_is_enabled(config->rx_irq)) {
359 /* Cache data for use by rx_ready() and fifo_read() */
360 (void)neorv32_uart_read_data(dev);
361 }
362
363 return 1;
364 }
365
neorv32_uart_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * user_data)366 static void neorv32_uart_irq_callback_set(const struct device *dev,
367 uart_irq_callback_user_data_t cb, void *user_data)
368 {
369 struct neorv32_uart_data *data = dev->data;
370
371 data->callback = cb;
372 data->callback_data = user_data;
373 }
374
neorv32_uart_isr(const struct device * dev)375 static void neorv32_uart_isr(const struct device *dev)
376 {
377 struct neorv32_uart_data *data = dev->data;
378 uart_irq_callback_user_data_t callback = data->callback;
379
380 if (callback) {
381 callback(dev, data->callback_data);
382 }
383 }
384 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
385
neorv32_uart_init(const struct device * dev)386 static int neorv32_uart_init(const struct device *dev)
387 {
388 const struct neorv32_uart_config *config = dev->config;
389 struct neorv32_uart_data *data = dev->data;
390 uint32_t features;
391 int err;
392
393 if (!device_is_ready(config->syscon)) {
394 LOG_ERR("syscon device not ready");
395 return -EINVAL;
396 }
397
398 err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
399 if (err < 0) {
400 LOG_ERR("failed to determine implemented features (err %d)", err);
401 return -EIO;
402 }
403
404 if ((features & config->feature_mask) == 0) {
405 LOG_ERR("neorv32 uart instance not supported");
406 return -ENODEV;
407 }
408
409 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
410 k_timer_init(&data->timer, &neorv32_uart_tx_soft_isr, NULL);
411 k_timer_user_data_set(&data->timer, (void *)dev);
412
413 config->irq_config_func(dev);
414 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
415
416 return neorv32_uart_configure(dev, &data->uart_cfg);
417 }
418
419 #ifdef CONFIG_PM_DEVICE
neorv32_uart_pm_action(const struct device * dev,enum pm_device_action action)420 static int neorv32_uart_pm_action(const struct device *dev,
421 enum pm_device_action action)
422 {
423 uint32_t ctrl = neorv32_uart_read_ctrl(dev);
424
425 switch (action) {
426 case PM_DEVICE_ACTION_SUSPEND:
427 ctrl &= ~(NEORV32_UART_CTRL_EN);
428 break;
429 case PM_DEVICE_ACTION_RESUME:
430 ctrl |= NEORV32_UART_CTRL_EN;
431 break;
432 default:
433 return -ENOTSUP;
434 }
435
436 neorv32_uart_write_ctrl(dev, ctrl);
437
438 return 0;
439 }
440 #endif /* CONFIG_PM_DEVICE */
441
442 static const struct uart_driver_api neorv32_uart_driver_api = {
443 .poll_in = neorv32_uart_poll_in,
444 .poll_out = neorv32_uart_poll_out,
445 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
446 .configure = neorv32_uart_configure,
447 .config_get = neorv32_uart_config_get,
448 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
449 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
450 .fifo_fill = neorv32_uart_fifo_fill,
451 .fifo_read = neorv32_uart_fifo_read,
452 .irq_tx_enable = neorv32_uart_irq_tx_enable,
453 .irq_tx_disable = neorv32_uart_irq_tx_disable,
454 .irq_tx_ready = neorv32_uart_irq_tx_ready,
455 .irq_rx_enable = neorv32_uart_irq_rx_enable,
456 .irq_rx_disable = neorv32_uart_irq_rx_disable,
457 .irq_tx_complete = neorv32_uart_irq_tx_complete,
458 .irq_rx_ready = neorv32_uart_irq_rx_ready,
459 .irq_is_pending = neorv32_uart_irq_is_pending,
460 .irq_update = neorv32_uart_irq_update,
461 .irq_callback_set = neorv32_uart_irq_callback_set,
462 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
463 };
464
465 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
466 #define NEORV32_UART_CONFIG_FUNC(node_id, n) \
467 static void neorv32_uart_config_func_##n(const struct device *dev) \
468 { \
469 IRQ_CONNECT(DT_IRQ_BY_NAME(node_id, tx, irq), \
470 DT_IRQ_BY_NAME(node_id, tx, priority), \
471 neorv32_uart_isr, \
472 DEVICE_DT_GET(node_id), 0); \
473 \
474 IRQ_CONNECT(DT_IRQ_BY_NAME(node_id, rx, irq), \
475 DT_IRQ_BY_NAME(node_id, rx, priority), \
476 neorv32_uart_isr, \
477 DEVICE_DT_GET(node_id), 0); \
478 }
479 #define NEORV32_UART_CONFIG_INIT(node_id, n) \
480 .irq_config_func = neorv32_uart_config_func_##n, \
481 .tx_irq = DT_IRQ_BY_NAME(node_id, tx, irq), \
482 .rx_irq = DT_IRQ_BY_NAME(node_id, rx, irq),
483 #else
484 #define NEORV32_UART_CONFIG_FUNC(node_id, n)
485 #define NEORV32_UART_CONFIG_INIT(node_id, n)
486 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
487
488 #define NEORV32_UART_INIT(node_id, n) \
489 NEORV32_UART_CONFIG_FUNC(node_id, n) \
490 \
491 static struct neorv32_uart_data neorv32_uart_##n##_data = { \
492 .uart_cfg = { \
493 .baudrate = DT_PROP(node_id, current_speed), \
494 .parity = DT_ENUM_IDX_OR(node_id, parity, \
495 UART_CFG_PARITY_NONE), \
496 .stop_bits = UART_CFG_STOP_BITS_1, \
497 .data_bits = UART_CFG_DATA_BITS_8, \
498 .flow_ctrl = DT_PROP(node_id, hw_flow_control) ? \
499 UART_CFG_FLOW_CTRL_RTS_CTS : \
500 UART_CFG_FLOW_CTRL_NONE, \
501 }, \
502 }; \
503 \
504 static const struct neorv32_uart_config neorv32_uart_##n##_config = { \
505 .syscon = DEVICE_DT_GET(DT_PHANDLE(node_id, syscon)), \
506 .feature_mask = NEORV32_SYSINFO_FEATURES_IO_UART##n, \
507 .base = DT_REG_ADDR(node_id), \
508 NEORV32_UART_CONFIG_INIT(node_id, n) \
509 }; \
510 \
511 PM_DEVICE_DT_DEFINE(node_id, neorv32_uart_pm_action); \
512 \
513 DEVICE_DT_DEFINE(node_id, &neorv32_uart_init, \
514 PM_DEVICE_DT_GET(node_id), \
515 &neorv32_uart_##n##_data, \
516 &neorv32_uart_##n##_config, \
517 PRE_KERNEL_1, \
518 CONFIG_SERIAL_INIT_PRIORITY, \
519 &neorv32_uart_driver_api)
520
521 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(uart0), DT_DRV_COMPAT, okay)
522 NEORV32_UART_INIT(DT_NODELABEL(uart0), 0);
523 #endif
524
525 #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(uart1), DT_DRV_COMPAT, okay)
526 NEORV32_UART_INIT(DT_NODELABEL(uart1), 1);
527 #endif
528