1 /*
2  * Copyright (c) 2023 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <zephyr/device.h>
9 #include <zephyr/drivers/uart.h>
10 #include <zephyr/pm/device.h>
11 #include "sedi_driver_uart.h"
12 
13 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
14 static void uart_sedi_isr(void *arg);
15 static void uart_sedi_cb(struct device *port);
16 #endif
17 
18 #define DT_DRV_COMPAT intel_sedi_uart
19 
20 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
21 /*  UART IRQ handler declaration.  */
22 #define  UART_IRQ_HANDLER_DECL(n) \
23 	static void irq_config_uart_##n(const struct device *dev)
24 
25 /* Setting configuration function. */
26 #define UART_CONFIG_IRQ_HANDLER_SET(n) \
27 	.uart_irq_config_func = irq_config_uart_##n
28 #define UART_IRQ_HANDLER_DEFINE(n)				       \
29 	static void irq_config_uart_##n(const struct device *dev)      \
30 	{							       \
31 		ARG_UNUSED(dev);				       \
32 		IRQ_CONNECT(DT_INST_IRQN(n),			       \
33 			    DT_INST_IRQ(n, priority), uart_sedi_isr,   \
34 			    DEVICE_DT_GET(DT_NODELABEL(uart##n)),      \
35 			    DT_INST_IRQ(n, sense));		       \
36 		irq_enable(DT_INST_IRQN(n));			       \
37 	}
38 #else /*CONFIG_UART_INTERRUPT_DRIVEN */
39 #define UART_IRQ_HANDLER_DECL(n)
40 #define UART_CONFIG_IRQ_HANDLER_SET(n) (0)
41 
42 #define UART_IRQ_HANDLER_DEFINE(n)
43 #endif  /* !CONFIG_UART_INTERRUPT_DRIVEN */
44 
45 /* Device init macro for UART instance. As multiple uart instances follow a
46  * similar definition of data structures differing only in the instance
47  * number.This macro makes adding instances simpler.
48  */
49 #define UART_SEDI_DEVICE_INIT(n)				      \
50 	UART_IRQ_HANDLER_DECL(n);				      \
51 	static K_MUTEX_DEFINE(uart_##n##_mutex);		      \
52 	static K_SEM_DEFINE(uart_##n##_tx_sem, 1, 1);		      \
53 	static K_SEM_DEFINE(uart_##n##_rx_sem, 1, 1);		      \
54 	static K_SEM_DEFINE(uart_##n##_sync_read_sem, 0, 1);	      \
55 	static const struct uart_sedi_config_info config_info_##n = { \
56 		DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),		      \
57 		.instance = DT_INST_PROP(n, peripheral_id),	      \
58 		.baud_rate = DT_INST_PROP(n, current_speed),	      \
59 		.hw_fc = DT_INST_PROP(n, hw_flow_control),	      \
60 		.line_ctrl = SEDI_UART_LC_8N1,			      \
61 		.mutex = &uart_##n##_mutex,			      \
62 		UART_CONFIG_IRQ_HANDLER_SET(n)			      \
63 	};							      \
64 								      \
65 	static struct uart_sedi_drv_data drv_data_##n;		      \
66 	PM_DEVICE_DT_DEFINE(DT_NODELABEL(uart##n),                    \
67 			    uart_sedi_pm_action);		      \
68 	DEVICE_DT_DEFINE(DT_NODELABEL(uart##n),		              \
69 		      &uart_sedi_init,				      \
70 		      PM_DEVICE_DT_GET(DT_NODELABEL(uart##n)),        \
71 		      &drv_data_##n, &config_info_##n,		      \
72 		      PRE_KERNEL_1,				      \
73 		      CONFIG_SERIAL_INIT_PRIORITY, &api);	      \
74 	UART_IRQ_HANDLER_DEFINE(n)
75 
76 
77 
78 /* Convenient macro to get the controller instance. */
79 #define GET_CONTROLLER_INSTANCE(dev)		 \
80 	(((const struct uart_sedi_config_info *) \
81 	  dev->config)->instance)
82 
83 #define GET_MUTEX(dev)				 \
84 	(((const struct uart_sedi_config_info *) \
85 	  dev->config)->mutex)
86 
87 struct uart_sedi_config_info {
88 	DEVICE_MMIO_ROM;
89 	/* Specifies the uart instance for configuration. */
90 	sedi_uart_t instance;
91 
92 	/* Specifies the baudrate for the uart instance. */
93 	uint32_t baud_rate;
94 
95 	/* Specifies the port line control settings */
96 	sedi_uart_lc_t line_ctrl;
97 
98 	struct k_mutex *mutex;
99 
100 	/* Enable / disable hardware flow control for UART. */
101 	bool hw_fc;
102 
103 	/* UART irq configuration function when supporting interrupt
104 	 * mode.
105 	 */
106 	uart_irq_config_func_t uart_irq_config_func;
107 };
108 
109 
110 static int uart_sedi_init(const struct device *dev);
111 
112 struct uart_sedi_drv_data {
113 	DEVICE_MMIO_RAM;
114 	uart_irq_callback_user_data_t user_cb;
115 	void *unsol_rx_usr_cb_param;
116 	uint32_t sync_rx_len;
117 	uint32_t sync_rx_status;
118 	void *user_data;
119 	void *usr_rx_buff;
120 	uint32_t usr_rx_size;
121 	uint8_t iir_cache;
122 	uint8_t busy_count;
123 };
124 
125 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_busy_set(const struct device * dev)126 static void uart_busy_set(const struct device *dev)
127 {
128 
129 	struct uart_sedi_drv_data *context = dev->data;
130 
131 	context->busy_count++;
132 
133 	if (context->busy_count == 1) {
134 		pm_device_busy_set(dev);
135 	}
136 }
137 
uart_busy_clear(const struct device * dev)138 static void uart_busy_clear(const struct device *dev)
139 {
140 
141 	struct uart_sedi_drv_data *context = dev->data;
142 
143 	context->busy_count--;
144 
145 	if (context->busy_count == 0) {
146 		pm_device_busy_clear(dev);
147 	}
148 }
149 #endif
150 
151 #ifdef CONFIG_PM_DEVICE
152 
153 #ifndef CONFIG_UART_CONSOLE
154 
uart_suspend_device(const struct device * dev)155 static int uart_suspend_device(const struct device *dev)
156 {
157 	const struct uart_sedi_config_info *config = dev->config;
158 
159 	if (pm_device_is_busy(dev)) {
160 		return -EBUSY;
161 	}
162 
163 	int ret = sedi_uart_set_power(config->instance, SEDI_POWER_SUSPEND);
164 
165 	if (ret != SEDI_DRIVER_OK) {
166 		return -EIO;
167 	}
168 
169 	return 0;
170 }
171 
uart_resume_device_from_suspend(const struct device * dev)172 static int uart_resume_device_from_suspend(const struct device *dev)
173 {
174 	const struct uart_sedi_config_info *config = dev->config;
175 	int ret;
176 
177 	ret = sedi_uart_set_power(config->instance, SEDI_POWER_FULL);
178 	if (ret != SEDI_DRIVER_OK) {
179 		return -EIO;
180 	}
181 
182 	return 0;
183 }
184 
uart_sedi_pm_action(const struct device * dev,enum pm_device_action action)185 static int uart_sedi_pm_action(const struct device *dev,
186 		enum pm_device_action action)
187 {
188 	int ret = 0;
189 
190 	switch (action) {
191 	case PM_DEVICE_ACTION_SUSPEND:
192 		ret = uart_suspend_device(dev);
193 		break;
194 	case PM_DEVICE_ACTION_RESUME:
195 		ret = uart_resume_device_from_suspend(dev);
196 		break;
197 
198 	default:
199 		ret = -ENOTSUP;
200 	}
201 	return ret;
202 }
203 
204 #else
205 
uart_sedi_pm_action(const struct device * dev,enum pm_device_action action)206 static int uart_sedi_pm_action(const struct device *dev,
207 		enum pm_device_action action)
208 {
209 	/* do nothing if using UART print log to avoid clock gating
210 	 * pm driver already handled power management for uart.
211 	 */
212 	return 0;
213 }
214 
215 #endif /* CONFIG_UART_CONSOLE */
216 
217 #endif /* CONFIG_PM_DEVICE */
218 
uart_sedi_poll_in(const struct device * dev,unsigned char * data)219 static int uart_sedi_poll_in(const struct device *dev, unsigned char *data)
220 {
221 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
222 	uint32_t status;
223 	int ret = 0;
224 
225 	sedi_uart_get_status(instance, (uint32_t *) &status);
226 
227 	/* In order to check if there is any data to read from UART
228 	 * controller we should check if the SEDI_UART_RX_BUSY bit from
229 	 * 'status' is not set. This bit is set only if there is any
230 	 * pending character to read.
231 	 */
232 	if (!(status & SEDI_UART_RX_BUSY)) {
233 		ret = -1;
234 	} else {
235 		if (sedi_uart_read(instance, data, (uint32_t *)&status)) {
236 			ret = -1;
237 		}
238 	}
239 	return ret;
240 }
241 
uart_sedi_poll_out(const struct device * dev,unsigned char data)242 static void uart_sedi_poll_out(const struct device *dev,
243 			       unsigned char data)
244 {
245 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
246 
247 	sedi_uart_write(instance, data);
248 }
249 
250 #ifdef CONFIG_UART_LINE_CTRL
get_xfer_error(int bsp_err)251 static int get_xfer_error(int bsp_err)
252 {
253 	int err;
254 
255 	switch (bsp_err) {
256 	case SEDI_DRIVER_OK:
257 		err = 0;
258 		break;
259 	case SEDI_USART_ERROR_CANCELED:
260 		err = -ECANCELED;
261 		break;
262 	case SEDI_DRIVER_ERROR:
263 		err = -EIO;
264 		break;
265 	case SEDI_DRIVER_ERROR_PARAMETER:
266 		err = -EINVAL;
267 		break;
268 	case SEDI_DRIVER_ERROR_UNSUPPORTED:
269 		err = -ENOTSUP;
270 		break;
271 	default:
272 		err = -EFAULT;
273 	}
274 	return err;
275 }
276 #endif  /* CONFIG_UART_LINE_CTRL */
277 
uart_sedi_err_check(const struct device * dev)278 static int uart_sedi_err_check(const struct device *dev)
279 {
280 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
281 	uint32_t status;
282 	int ret_status = 0;
283 
284 	sedi_uart_get_status(instance, (uint32_t *const)&status);
285 	if (status &  SEDI_UART_RX_OE) {
286 		ret_status = UART_ERROR_OVERRUN;
287 	}
288 
289 	if (status & SEDI_UART_RX_PE) {
290 		ret_status = UART_ERROR_PARITY;
291 	}
292 
293 	if (status & SEDI_UART_RX_FE) {
294 		ret_status = UART_ERROR_FRAMING;
295 	}
296 
297 	if (status & SEDI_UART_RX_BI) {
298 		ret_status = UART_BREAK;
299 	}
300 
301 	return ret_status;
302 }
303 
304 
305 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
306 
uart_sedi_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)307 static int uart_sedi_fifo_fill(const struct device *dev, const uint8_t *tx_data,
308 			       int size)
309 {
310 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
311 
312 	return sedi_uart_fifo_fill(instance, tx_data, size);
313 }
314 
uart_sedi_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)315 static int uart_sedi_fifo_read(const struct device *dev, uint8_t *rx_data,
316 			       const int size)
317 {
318 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
319 
320 	return sedi_uart_fifo_read(instance, rx_data, size);
321 }
322 
uart_sedi_irq_tx_enable(const struct device * dev)323 static void uart_sedi_irq_tx_enable(const struct device *dev)
324 {
325 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
326 
327 	sedi_uart_irq_tx_enable(instance);
328 }
329 
uart_sedi_irq_tx_disable(const struct device * dev)330 static void uart_sedi_irq_tx_disable(const struct device *dev)
331 {
332 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
333 
334 	sedi_uart_irq_tx_disable(instance);
335 }
336 
uart_sedi_irq_tx_ready(const struct device * dev)337 static int uart_sedi_irq_tx_ready(const struct device *dev)
338 {
339 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
340 
341 	return sedi_uart_irq_tx_ready(instance);
342 }
343 
uart_sedi_irq_tx_complete(const struct device * dev)344 static int uart_sedi_irq_tx_complete(const struct device *dev)
345 {
346 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
347 
348 	return sedi_uart_is_tx_complete(instance);
349 }
350 
uart_sedi_irq_rx_enable(const struct device * dev)351 static void uart_sedi_irq_rx_enable(const struct device *dev)
352 {
353 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
354 
355 	uart_busy_set(dev);
356 	sedi_uart_irq_rx_enable(instance);
357 }
358 
uart_sedi_irq_rx_disable(const struct device * dev)359 static void uart_sedi_irq_rx_disable(const struct device *dev)
360 {
361 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
362 
363 	sedi_uart_irq_rx_disable(instance);
364 	uart_busy_clear(dev);
365 }
366 
uart_sedi_irq_rx_ready(const struct device * dev)367 static int uart_sedi_irq_rx_ready(const struct device *dev)
368 {
369 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
370 
371 	return sedi_uart_is_irq_rx_ready(instance);
372 }
373 
uart_sedi_irq_err_enable(const struct device * dev)374 static void uart_sedi_irq_err_enable(const struct device *dev)
375 {
376 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
377 
378 	sedi_uart_irq_err_enable(instance);
379 }
380 
uart_sedi_irq_err_disable(const struct device * dev)381 static void uart_sedi_irq_err_disable(const struct device *dev)
382 {
383 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
384 
385 	sedi_uart_irq_err_disable(instance);
386 }
387 
uart_sedi_irq_is_pending(const struct device * dev)388 static int uart_sedi_irq_is_pending(const struct device *dev)
389 {
390 
391 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
392 
393 	return sedi_uart_is_irq_pending(instance);
394 }
395 
uart_sedi_irq_update(const struct device * dev)396 static int uart_sedi_irq_update(const struct device *dev)
397 {
398 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
399 
400 	sedi_uart_update_irq_cache(instance);
401 	return 1;
402 }
403 
uart_sedi_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * user_data)404 static void uart_sedi_irq_callback_set(const struct device *dev,
405 				       uart_irq_callback_user_data_t cb,
406 				       void *user_data)
407 {
408 	struct uart_sedi_drv_data *drv_data = dev->data;
409 
410 	drv_data->user_cb = cb;
411 	drv_data->user_data = user_data;
412 
413 }
414 
uart_sedi_isr(void * arg)415 static void uart_sedi_isr(void *arg)
416 {
417 	struct device *dev = arg;
418 	struct uart_sedi_drv_data *drv_data = dev->data;
419 
420 	if (drv_data->user_cb) {
421 		drv_data->user_cb(dev, drv_data->user_data);
422 	} else {
423 		uart_sedi_cb(dev);
424 	}
425 }
426 
427 /* Called from generic callback of zephyr , set by set_cb. */
uart_sedi_cb(struct device * port)428 static void uart_sedi_cb(struct device *port)
429 {
430 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(port);
431 
432 	sedi_uart_isr_handler(instance);
433 }
434 
435 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
436 
437 #ifdef CONFIG_UART_LINE_CTRL
uart_sedi_line_ctrl_set(struct device * dev,uint32_t ctrl,uint32_t val)438 static int uart_sedi_line_ctrl_set(struct device *dev,
439 		uint32_t ctrl, uint32_t val)
440 {
441 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
442 	sedi_uart_config_t cfg;
443 	uint32_t mask;
444 	int ret;
445 
446 	k_mutex_lock(GET_MUTEX(dev), K_FOREVER);
447 	switch (ctrl) {
448 	case UART_LINE_CTRL_BAUD_RATE:
449 		sedi_uart_get_config(instance, &cfg);
450 		cfg.baud_rate = val;
451 		ret = sedi_uart_set_config(instance, &cfg);
452 		break;
453 
454 	default:
455 		ret = -ENODEV;
456 	}
457 	k_mutex_unlock(GET_MUTEX(dev));
458 	ret = get_xfer_error(ret);
459 	return ret;
460 }
461 
uart_sedi_line_ctrl_get(struct device * dev,uint32_t ctrl,uint32_t * val)462 static int uart_sedi_line_ctrl_get(struct device *dev,
463 		uint32_t ctrl, uint32_t *val)
464 {
465 	sedi_uart_t instance = GET_CONTROLLER_INSTANCE(dev);
466 	sedi_uart_config_t cfg;
467 	uint32_t mask;
468 	int ret;
469 
470 	k_mutex_lock(GET_MUTEX(dev), K_FOREVER);
471 	switch (ctrl) {
472 	case UART_LINE_CTRL_BAUD_RATE:
473 		ret = sedi_uart_get_config(instance, &cfg);
474 		*val = cfg.baud_rate;
475 		break;
476 
477 	case UART_LINE_CTRL_LOOPBACK:
478 		ret = sedi_uart_get_loopback_mode(instance, (uint32_t *)val);
479 		break;
480 
481 	case UART_LINE_CTRL_AFCE:
482 		ret = sedi_uart_get_config(instance, &cfg);
483 		*val = cfg.hw_fc;
484 		break;
485 
486 	case UART_LINE_CTRL_LINE_STATUS_REPORT_MASK:
487 		mask = 0;
488 		*val = 0;
489 		ret = sedi_get_ln_status_report_mask(instance,
490 						     (uint32_t *)&mask);
491 		*val |= ((mask & SEDI_UART_RX_OE) ? UART_ERROR_OVERRUN : 0);
492 		*val |= ((mask & SEDI_UART_RX_PE) ? UART_ERROR_PARITY : 0);
493 		*val |= ((mask & SEDI_UART_RX_FE) ? UART_ERROR_FRAMING : 0);
494 		*val |= ((mask & SEDI_UART_RX_BI) ? UART_BREAK : 0);
495 		break;
496 
497 	case UART_LINE_CTRL_RTS:
498 		ret = sedi_uart_read_rts(instance, (uint32_t *)val);
499 		break;
500 
501 	case UART_LINE_CTRL_CTS:
502 		ret = sedi_uart_read_cts(instance, (uint32_t *)val);
503 		break;
504 
505 
506 	default:
507 		ret = -ENODEV;
508 	}
509 	k_mutex_unlock(GET_MUTEX(dev));
510 	ret = get_xfer_error(ret);
511 	return ret;
512 }
513 
514 #endif /* CONFIG_UART_LINE_CTRL */
515 
516 static DEVICE_API(uart, api) = {
517 	.poll_in = uart_sedi_poll_in,
518 	.poll_out = uart_sedi_poll_out,
519 	.err_check = uart_sedi_err_check,
520 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
521 	.fifo_fill = uart_sedi_fifo_fill,
522 	.fifo_read = uart_sedi_fifo_read,
523 	.irq_tx_enable = uart_sedi_irq_tx_enable,
524 	.irq_tx_disable = uart_sedi_irq_tx_disable,
525 	.irq_tx_ready = uart_sedi_irq_tx_ready,
526 	.irq_tx_complete = uart_sedi_irq_tx_complete,
527 	.irq_rx_enable = uart_sedi_irq_rx_enable,
528 	.irq_rx_disable = uart_sedi_irq_rx_disable,
529 	.irq_rx_ready = uart_sedi_irq_rx_ready,
530 	.irq_err_enable = uart_sedi_irq_err_enable,
531 	.irq_err_disable = uart_sedi_irq_err_disable,
532 	.irq_is_pending = uart_sedi_irq_is_pending,
533 	.irq_update = uart_sedi_irq_update,
534 	.irq_callback_set = uart_sedi_irq_callback_set,
535 #endif  /* CONFIG_UART_INTERRUPT_DRIVEN */
536 #ifdef CONFIG_UART_LINE_CTRL
537 	.line_ctrl_set = uart_sedi_line_ctrl_set,
538 	.line_ctrl_get = uart_sedi_line_ctrl_get,
539 #endif  /* CONFIG_UART_LINE_CTRL */
540 
541 };
542 
uart_sedi_init(const struct device * dev)543 static int uart_sedi_init(const struct device *dev)
544 {
545 
546 	const struct uart_sedi_config_info *config = dev->config;
547 	sedi_uart_config_t cfg;
548 
549 	DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
550 	sedi_uart_init(config->instance, (void *)DEVICE_MMIO_GET(dev));
551 
552 	cfg.line_control = config->line_ctrl;
553 	cfg.baud_rate = config->baud_rate;
554 	cfg.hw_fc = config->hw_fc;
555 
556 	/* Setting to full power and enabling clk. */
557 	sedi_uart_set_power(config->instance, SEDI_POWER_FULL);
558 
559 	sedi_uart_set_config(config->instance, &cfg);
560 
561 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
562 	config->uart_irq_config_func(dev);
563 #endif  /* CONFIG_UART_INTERRUPT_DRIVEN */
564 
565 	return 0;
566 }
567 
568 DT_INST_FOREACH_STATUS_OKAY(UART_SEDI_DEVICE_INIT)
569