1 /*
2  * Copyright (c) 2025 Aesc Silicon
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT aesc_uart
8 
9 #include <errno.h>
10 #include <ip_identification.h>
11 #include <soc.h>
12 
13 #include <zephyr/device.h>
14 #include <zephyr/devicetree.h>
15 #include <zephyr/drivers/uart.h>
16 #include <zephyr/init.h>
17 #include <zephyr/kernel.h>
18 
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(aesc_uart, CONFIG_UART_LOG_LEVEL);
21 
22 struct uart_aesc_data {
23 	DEVICE_MMIO_NAMED_RAM(regs);
24 };
25 
26 struct uart_aesc_config {
27 	DEVICE_MMIO_NAMED_ROM(regs);
28 	uint64_t sys_clk_freq;
29 	uint32_t current_speed;
30 };
31 
32 struct uart_aesc_regs {
33 	uint32_t data_width;
34 	uint32_t sampling_sizes;
35 	uint32_t fifo_depths;
36 	uint32_t permissions;
37 	uint32_t read_write;
38 	uint32_t fifo_status;
39 	uint32_t clock_div;
40 	uint32_t frame_cfg;
41 	uint32_t ip;
42 	uint32_t ie;
43 };
44 
45 #define DEV_CFG(dev) ((struct uart_aesc_config *)(dev)->config)
46 #define DEV_DATA(dev) ((struct uart_aesc_data *)(dev)->data)
47 #define DEV_UART(dev)							     \
48 	((struct uart_aesc_regs *)DEVICE_MMIO_NAMED_GET(dev, regs))
49 
50 #define AESC_UART_IRQ_TX_EN			BIT(0)
51 #define AESC_UART_IRQ_RX_EN			BIT(1)
52 #define AESC_UART_FIFO_TX_COUNT_MASK		GENMASK(23, 16)
53 #define AESC_UART_READ_FIFO_VALID_BIT		BIT(16)
54 
uart_aesc_poll_out(const struct device * dev,unsigned char c)55 static void uart_aesc_poll_out(const struct device *dev, unsigned char c)
56 {
57 	struct uart_aesc_regs *uart = DEV_UART(dev);
58 
59 	while ((uart->fifo_status & AESC_UART_FIFO_TX_COUNT_MASK) == 0) {
60 		/* Wait until transmit fifo is empty */
61 	}
62 	uart->read_write = c;
63 }
64 
uart_aesc_poll_in(const struct device * dev,unsigned char * c)65 static int uart_aesc_poll_in(const struct device *dev, unsigned char *c)
66 {
67 	const struct uart_aesc_regs *uart = DEV_UART(dev);
68 	int val;
69 
70 	val = uart->read_write;
71 	if (val & AESC_UART_READ_FIFO_VALID_BIT) {
72 		*c = val & 0xFF;
73 		return 0;
74 	}
75 
76 	return -1;
77 }
78 
uart_aesc_init(const struct device * dev)79 static int uart_aesc_init(const struct device *dev)
80 {
81 	const struct uart_aesc_config *cfg = DEV_CFG(dev);
82 	volatile uintptr_t *base_addr = (volatile uintptr_t *)DEV_UART(dev);
83 	volatile struct uart_aesc_regs *uart;
84 
85 	DEVICE_MMIO_NAMED_MAP(dev, regs, K_MEM_CACHE_NONE);
86 	LOG_DBG("IP core version: %i.%i.%i.",
87 		ip_id_get_major_version(base_addr),
88 		ip_id_get_minor_version(base_addr),
89 		ip_id_get_patchlevel(base_addr)
90 	);
91 	DEVICE_MMIO_NAMED_GET(dev, regs) = ip_id_relocate_driver(base_addr);
92 	LOG_DBG("Relocate driver to address 0x%lx.", DEVICE_MMIO_NAMED_GET(dev, regs));
93 	uart = DEV_UART(dev);
94 
95 	uart->clock_div = cfg->sys_clk_freq / cfg->current_speed / 8;
96 	uart->frame_cfg = 7;
97 
98 	return 0;
99 }
100 
101 static DEVICE_API(uart, uart_aesc_driver_api) = {
102 	.poll_in          = uart_aesc_poll_in,
103 	.poll_out         = uart_aesc_poll_out,
104 	.err_check        = NULL,
105 };
106 
107 #define AESC_UART_INIT(no)						     \
108 	static struct uart_aesc_data uart_aesc_dev_data_##no;		     \
109 	static struct uart_aesc_config uart_aesc_dev_cfg_##no = {	     \
110 		DEVICE_MMIO_NAMED_ROM_INIT(regs,			     \
111 					   DT_INST(no, aesc_uart)),	     \
112 		.sys_clk_freq =						     \
113 			DT_PROP(DT_INST(no, aesc_uart), clock_frequency),    \
114 		.current_speed =					     \
115 			DT_PROP(DT_INST(no, aesc_uart), current_speed),	     \
116 	};								     \
117 	DEVICE_DT_INST_DEFINE(no,					     \
118 			      uart_aesc_init,				     \
119 			      NULL,					     \
120 			      &uart_aesc_dev_data_##no,			     \
121 			      &uart_aesc_dev_cfg_##no,			     \
122 			      PRE_KERNEL_1,				     \
123 			      CONFIG_KERNEL_INIT_PRIORITY_DEVICE,	     \
124 			      (void *)&uart_aesc_driver_api);
125 
126 DT_INST_FOREACH_STATUS_OKAY(AESC_UART_INIT)
127