1 /*
2  * Copyright (c) 2018 Antmicro <www.antmicro.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT microchip_coreuart
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/arch/cpu.h>
11 #include <zephyr/drivers/uart.h>
12 
13 
14 /* UART REGISTERS DEFINITIONS */
15 
16 /* TX register */
17 #define TXDATA_REG_OFFSET   0x0
18 
19 #define TXDATA_OFFSET   0x0
20 #define TXDATA_MASK     0xFF
21 #define TXDATA_SHIFT    0
22 
23 /* RX register */
24 #define RXDATA_REG_OFFSET   0x4
25 
26 #define RXDATA_OFFSET   0x4
27 #define RXDATA_MASK     0xFF
28 #define RXDATA_SHIFT    0
29 
30 /* Control1 register */
31 #define CTRL1_REG_OFFSET        0x8
32 
33 /* Baud value lower 8 bits */
34 #define CTRL1_BAUDVALUE_OFFSET   0x8
35 #define CTRL1_BAUDVALUE_MASK     0xFF
36 #define CTRL1_BAUDVALUE_SHIFT    0
37 
38 /* Control2 register */
39 #define CTRL2_REG_OFFSET          0xC
40 
41 /* Bit length */
42 #define CTRL2_BIT_LENGTH_OFFSET   0xC
43 #define CTRL2_BIT_LENGTH_MASK     0x01
44 #define CTRL2_BIT_LENGTH_SHIFT    0
45 
46 /* Parity enable */
47 #define CTRL2_PARITY_EN_OFFSET    0xC
48 #define CTRL2_PARITY_EN_MASK      0x02
49 #define CTRL2_PARITY_EN_SHIFT     1
50 
51 /* Odd/even parity configuration */
52 #define CTRL2_ODD_EVEN_OFFSET     0xC
53 #define CTRL2_ODD_EVEN_MASK       0x04
54 #define CTRL2_ODD_EVEN_SHIFT      2
55 
56 /* Baud value higher 5 bits */
57 #define CTRL2_BAUDVALUE_OFFSET    0xC
58 #define CTRL2_BAUDVALUE_MASK      0xF8
59 #define CTRL2_BAUDVALUE_SHIFT     3
60 
61 /* Status register */
62 #define StatusReg_REG_OFFSET    0x10
63 
64 #define STATUS_REG_OFFSET       0x10
65 
66 /* TX ready */
67 #define STATUS_TXRDY_OFFSET   0x10
68 #define STATUS_TXRDY_MASK     0x01
69 #define STATUS_TXRDY_SHIFT    0
70 
71 /* Receive full - raised even when 1 char arrived */
72 #define STATUS_RXFULL_OFFSET   0x10
73 #define STATUS_RXFULL_MASK     0x02
74 #define STATUS_RXFULL_SHIFT    1
75 
76 /* Parity error */
77 #define STATUS_PARITYERR_OFFSET   0x10
78 #define STATUS_PARITYERR_MASK     0x04
79 #define STATUS_PARITYERR_SHIFT    2
80 
81 /* Overflow */
82 #define STATUS_OVERFLOW_OFFSET   0x10
83 #define STATUS_OVERFLOW_MASK     0x08
84 #define STATUS_OVERFLOW_SHIFT    3
85 
86 /* Frame error */
87 #define STATUS_FRAMERR_OFFSET   0x10
88 #define STATUS_FRAMERR_MASK     0x10
89 #define STATUS_FRAMERR_SHIFT    4
90 
91 /* Data bits length defines */
92 #define DATA_7_BITS     0x00
93 #define DATA_8_BITS     0x01
94 
95 /* Parity defines */
96 #define NO_PARITY       0x00
97 #define EVEN_PARITY     0x02
98 #define ODD_PARITY      0x06
99 
100 /* Error Status definitions */
101 #define UART_PARITY_ERROR    0x01
102 #define UART_OVERFLOW_ERROR  0x02
103 #define UART_FRAMING_ERROR   0x04
104 
105 #define BAUDVALUE_LSB ((uint16_t)(0x00FF))
106 #define BAUDVALUE_MSB ((uint16_t)(0xFF00))
107 #define BAUDVALUE_SHIFT ((uint8_t)(5))
108 
109 #define MIV_UART_0_LINECFG 0x1
110 
111 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
112 static struct k_thread rx_thread;
113 static K_KERNEL_STACK_DEFINE(rx_stack, 512);
114 #endif
115 
116 struct uart_miv_regs_t {
117 	uint8_t tx;
118 	uint8_t reserved0[3];
119 	uint8_t rx;
120 	uint8_t reserved1[3];
121 	uint8_t ctrlreg1;
122 	uint8_t reserved2[3];
123 	uint8_t ctrlreg2;
124 	uint8_t reserved3[3];
125 	uint8_t status;
126 };
127 
128 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
129 typedef void (*irq_cfg_func_t)(const struct device *dev);
130 #endif
131 
132 struct uart_miv_device_config {
133 	uint32_t       uart_addr;
134 	uint32_t       sys_clk_freq;
135 	uint32_t       line_config;
136 	uint32_t       baud_rate;
137 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
138 	irq_cfg_func_t cfg_func;
139 #endif
140 };
141 
142 struct uart_miv_data {
143 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
144 	const struct device *dev;
145 	uart_irq_callback_user_data_t callback;
146 	void *cb_data;
147 #endif
148 };
149 
150 #define DEV_UART(dev)						\
151 	((struct uart_miv_regs_t *)				\
152 	 ((const struct uart_miv_device_config * const)(dev)->config)->uart_addr)
153 
uart_miv_poll_out(const struct device * dev,unsigned char c)154 static void uart_miv_poll_out(const struct device *dev,
155 				       unsigned char c)
156 {
157 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
158 
159 	while (!(uart->status & STATUS_TXRDY_MASK)) {
160 	}
161 
162 	uart->tx = c;
163 }
164 
uart_miv_poll_in(const struct device * dev,unsigned char * c)165 static int uart_miv_poll_in(const struct device *dev, unsigned char *c)
166 {
167 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
168 
169 	if (uart->status & STATUS_RXFULL_MASK) {
170 		*c = (unsigned char)(uart->rx & RXDATA_MASK);
171 		return 0;
172 	}
173 
174 	return -1;
175 }
176 
uart_miv_err_check(const struct device * dev)177 static int uart_miv_err_check(const struct device *dev)
178 {
179 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
180 	uint32_t flags = uart->status;
181 	int err = 0;
182 
183 	if (flags & STATUS_PARITYERR_MASK) {
184 		err |= UART_PARITY_ERROR;
185 	}
186 
187 	if (flags & STATUS_OVERFLOW_MASK) {
188 		err |= UART_OVERFLOW_ERROR;
189 	}
190 
191 	if (flags & STATUS_FRAMERR_MASK) {
192 		err |= UART_FRAMING_ERROR;
193 	}
194 
195 	return err;
196 }
197 
198 
199 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
200 
uart_miv_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)201 static int uart_miv_fifo_fill(const struct device *dev,
202 			      const uint8_t *tx_data,
203 			      int size)
204 {
205 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
206 	int i;
207 
208 	for (i = 0; i < size && (uart->status & STATUS_TXRDY_MASK); i++) {
209 		uart->tx = tx_data[i];
210 	}
211 
212 	return i;
213 }
214 
uart_miv_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)215 static int uart_miv_fifo_read(const struct device *dev,
216 			      uint8_t *rx_data,
217 			      const int size)
218 {
219 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
220 	int i;
221 
222 	for (i = 0; i < size; i++) {
223 		if (uart->status & STATUS_RXFULL_MASK) {
224 			rx_data[i] = (unsigned char)(uart->rx & RXDATA_MASK);
225 		} else {
226 			break;
227 		}
228 	}
229 
230 	return i;
231 }
232 
uart_miv_irq_tx_enable(const struct device * dev)233 static void uart_miv_irq_tx_enable(const struct device *dev)
234 {
235 	ARG_UNUSED(dev);
236 }
237 
uart_miv_irq_tx_disable(const struct device * dev)238 static void uart_miv_irq_tx_disable(const struct device *dev)
239 {
240 	ARG_UNUSED(dev);
241 }
242 
uart_miv_irq_tx_ready(const struct device * dev)243 static int uart_miv_irq_tx_ready(const struct device *dev)
244 {
245 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
246 
247 	return !(uart->status & STATUS_TXRDY_MASK);
248 }
249 
uart_miv_irq_tx_complete(const struct device * dev)250 static int uart_miv_irq_tx_complete(const struct device *dev)
251 {
252 	ARG_UNUSED(dev);
253 
254 	return 1;
255 }
256 
uart_miv_irq_rx_enable(const struct device * dev)257 static void uart_miv_irq_rx_enable(const struct device *dev)
258 {
259 	ARG_UNUSED(dev);
260 }
261 
uart_miv_irq_rx_disable(const struct device * dev)262 static void uart_miv_irq_rx_disable(const struct device *dev)
263 {
264 	ARG_UNUSED(dev);
265 }
266 
uart_miv_irq_rx_ready(const struct device * dev)267 static int uart_miv_irq_rx_ready(const struct device *dev)
268 {
269 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
270 
271 	return !!(uart->status & STATUS_RXFULL_MASK);
272 }
273 
uart_miv_irq_err_enable(const struct device * dev)274 static void uart_miv_irq_err_enable(const struct device *dev)
275 {
276 	ARG_UNUSED(dev);
277 }
278 
uart_miv_irq_err_disable(const struct device * dev)279 static void uart_miv_irq_err_disable(const struct device *dev)
280 {
281 	ARG_UNUSED(dev);
282 }
283 
uart_miv_irq_is_pending(const struct device * dev)284 static int uart_miv_irq_is_pending(const struct device *dev)
285 {
286 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
287 
288 	return !!(uart->status & STATUS_RXFULL_MASK);
289 }
290 
uart_miv_irq_update(const struct device * dev)291 static int uart_miv_irq_update(const struct device *dev)
292 {
293 	return 1;
294 }
295 
uart_miv_irq_handler(const struct device * dev)296 static void uart_miv_irq_handler(const struct device *dev)
297 {
298 	struct uart_miv_data *data = dev->data;
299 
300 	if (data->callback) {
301 		data->callback(dev, data->cb_data);
302 	}
303 }
304 
305 /*
306  * This thread is a workaround for IRQs that are not connected in Mi-V.
307  * Since we cannot rely on IRQs, the rx_thread is working instead and
308  * polling for data. The thread calls the registered callback when data
309  * arrives.
310  */
uart_miv_rx_thread(void * arg1,void * arg2,void * arg3)311 void uart_miv_rx_thread(void *arg1, void *arg2, void *arg3)
312 {
313 	struct uart_miv_data *data = (struct uart_miv_data *)arg1;
314 	const struct device *dev = data->dev;
315 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
316 	const struct uart_miv_device_config *const cfg = dev->config;
317 	/* Make it go to sleep for a period no longer than
318 	 * time to receive next character.
319 	 */
320 	uint32_t delay = 1000000 / cfg->baud_rate;
321 
322 	ARG_UNUSED(arg2);
323 	ARG_UNUSED(arg3);
324 
325 	while (1) {
326 		if (uart->status & STATUS_RXFULL_MASK) {
327 			uart_miv_irq_handler(dev);
328 		}
329 		k_sleep(K_USEC(delay));
330 	}
331 }
332 
uart_miv_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)333 static void uart_miv_irq_callback_set(const struct device *dev,
334 				      uart_irq_callback_user_data_t cb,
335 				      void *cb_data)
336 {
337 	struct uart_miv_data *data = dev->data;
338 
339 	data->callback = cb;
340 	data->cb_data = cb_data;
341 }
342 
343 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
344 
uart_miv_init(const struct device * dev)345 static int uart_miv_init(const struct device *dev)
346 {
347 	const struct uart_miv_device_config *const cfg = dev->config;
348 	volatile struct uart_miv_regs_t *uart = DEV_UART(dev);
349 	/* Calculate divider value to set baudrate */
350 	uint16_t baud_value = (cfg->sys_clk_freq / (cfg->baud_rate * 16U)) - 1;
351 
352 	/* Set baud rate */
353 	uart->ctrlreg1 = (uint8_t)(baud_value & BAUDVALUE_LSB);
354 	uart->ctrlreg2 = (uint8_t)(cfg->line_config) |
355 			 (uint8_t)((baud_value & BAUDVALUE_MSB) >> BAUDVALUE_SHIFT);
356 
357 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
358 	/* Setup thread polling for data */
359 	cfg->cfg_func(dev);
360 #endif
361 	return 0;
362 }
363 
364 static DEVICE_API(uart, uart_miv_driver_api) = {
365 	.poll_in          = uart_miv_poll_in,
366 	.poll_out         = uart_miv_poll_out,
367 	.err_check        = uart_miv_err_check,
368 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
369 	.fifo_fill        = uart_miv_fifo_fill,
370 	.fifo_read        = uart_miv_fifo_read,
371 	.irq_tx_enable    = uart_miv_irq_tx_enable,
372 	.irq_tx_disable   = uart_miv_irq_tx_disable,
373 	.irq_tx_ready     = uart_miv_irq_tx_ready,
374 	.irq_tx_complete  = uart_miv_irq_tx_complete,
375 	.irq_rx_enable    = uart_miv_irq_rx_enable,
376 	.irq_rx_disable   = uart_miv_irq_rx_disable,
377 	.irq_rx_ready     = uart_miv_irq_rx_ready,
378 	.irq_err_enable   = uart_miv_irq_err_enable,
379 	.irq_err_disable  = uart_miv_irq_err_disable,
380 	.irq_is_pending   = uart_miv_irq_is_pending,
381 	.irq_update       = uart_miv_irq_update,
382 	.irq_callback_set = uart_miv_irq_callback_set,
383 #endif
384 };
385 
386 /* This driver is single-instance. */
387 BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) <= 1,
388 	     "unsupported uart_miv instance");
389 
390 #if DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0))
391 
392 static struct uart_miv_data uart_miv_data_0;
393 
394 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
395 static void uart_miv_irq_cfg_func_0(const struct device *dev);
396 #endif
397 
398 static const struct uart_miv_device_config uart_miv_dev_cfg_0 = {
399 	.uart_addr    = DT_INST_REG_ADDR(0),
400 	.sys_clk_freq = DT_INST_PROP(0, clock_frequency),
401 	.line_config  = MIV_UART_0_LINECFG,
402 	.baud_rate    = DT_INST_PROP(0, current_speed),
403 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
404 	.cfg_func     = uart_miv_irq_cfg_func_0,
405 #endif
406 };
407 
408 DEVICE_DT_INST_DEFINE(0, uart_miv_init, NULL,
409 		    &uart_miv_data_0, &uart_miv_dev_cfg_0,
410 		    PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY,
411 		    (void *)&uart_miv_driver_api);
412 
413 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
uart_miv_irq_cfg_func_0(const struct device * dev)414 static void uart_miv_irq_cfg_func_0(const struct device *dev)
415 {
416 	struct uart_miv_data *data = dev->data;
417 
418 	data->dev = dev;
419 
420 	/* Create a thread which will poll for data - replacement for IRQ */
421 	k_thread_create(&rx_thread, rx_stack, 500,
422 			uart_miv_rx_thread, data, NULL, NULL, K_PRIO_COOP(2),
423 			0, K_NO_WAIT);
424 }
425 #endif
426 
427 #endif /* DT_NODE_HAS_STATUS_OKAY(DT_DRV_INST(0)) */
428