1 /* uart_xlnx_ps.c - Xilinx Zynq family serial driver */
2 
3 /*
4  * Copyright (c) 2018 Xilinx, Inc.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define DT_DRV_COMPAT xlnx_xuartps
10 
11 /**
12  * @brief Xilinx Zynq Family Serial Driver
13  *
14  * This is the driver for the Xilinx Zynq family cadence serial device.
15  *
16  * Before individual UART port can be used, uart_xlnx_ps_init() has to be
17  * called to setup the port.
18  *
19  * - the following macro for the number of bytes between register addresses:
20  *
21  *  UART_REG_ADDR_INTERVAL
22  */
23 
24 #include <errno.h>
25 #include <zephyr/kernel.h>
26 #include <zephyr/arch/cpu.h>
27 #include <zephyr/types.h>
28 #include <soc.h>
29 
30 #include <zephyr/init.h>
31 #include <zephyr/toolchain.h>
32 #include <zephyr/linker/sections.h>
33 #include <zephyr/drivers/uart.h>
34 #include <zephyr/sys/sys_io.h>
35 #include <zephyr/irq.h>
36 
37 #ifdef CONFIG_PINCTRL
38 #include <zephyr/drivers/pinctrl.h>
39 #endif
40 
41 /* For all register offsets and bits / bit masks:
42  * Comp. Xilinx Zynq-7000 Technical Reference Manual (ug585), chap. B.33
43  */
44 
45 /* Register offsets within the UART device's register space */
46 #define XUARTPS_CR_OFFSET      0x0000U /**< Control Register [8:0] */
47 #define XUARTPS_MR_OFFSET      0x0004U /**< Mode Register [9:0] */
48 #define XUARTPS_IER_OFFSET     0x0008U /**< Interrupt Enable [12:0] */
49 #define XUARTPS_IDR_OFFSET     0x000CU /**< Interrupt Disable [12:0] */
50 #define XUARTPS_IMR_OFFSET     0x0010U /**< Interrupt Mask [12:0] */
51 #define XUARTPS_ISR_OFFSET     0x0014U /**< Interrupt Status [12:0]*/
52 #define XUARTPS_BAUDGEN_OFFSET 0x0018U /**< Baud Rate Generator [15:0] */
53 #define XUARTPS_RXTOUT_OFFSET  0x001CU /**< RX Timeout [7:0] */
54 #define XUARTPS_RXWM_OFFSET    0x0020U /**< RX FIFO Trigger Level [5:0] */
55 #define XUARTPS_MODEMCR_OFFSET 0x0024U /**< Modem Control [5:0] */
56 #define XUARTPS_MODEMSR_OFFSET 0x0028U /**< Modem Status [8:0] */
57 #define XUARTPS_SR_OFFSET      0x002CU /**< Channel Status [14:0] */
58 #define XUARTPS_FIFO_OFFSET    0x0030U /**< FIFO [7:0] */
59 #define XUARTPS_BAUDDIV_OFFSET 0x0034U /**< Baud Rate Divider [7:0] */
60 #define XUARTPS_FLOWDEL_OFFSET 0x0038U /**< Flow Delay [5:0] */
61 #define XUARTPS_TXWM_OFFSET    0x0044U /**< TX FIFO Trigger Level [5:0] */
62 #define XUARTPS_RXBS_OFFSET    0x0048U /**< RX FIFO Byte Status [11:0] */
63 
64 /* Control Register Bits Definition */
65 #define XUARTPS_CR_STOPBRK     0x00000100U /**< Stop transmission of break */
66 #define XUARTPS_CR_STARTBRK    0x00000080U /**< Set break */
67 #define XUARTPS_CR_TORST       0x00000040U /**< RX timeout counter restart */
68 #define XUARTPS_CR_TX_DIS      0x00000020U /**< TX disabled. */
69 #define XUARTPS_CR_TX_EN       0x00000010U /**< TX enabled */
70 #define XUARTPS_CR_RX_DIS      0x00000008U /**< RX disabled. */
71 #define XUARTPS_CR_RX_EN       0x00000004U /**< RX enabled */
72 #define XUARTPS_CR_EN_DIS_MASK 0x0000003CU /**< Enable/disable Mask */
73 #define XUARTPS_CR_TXRST       0x00000002U /**< TX logic reset */
74 #define XUARTPS_CR_RXRST       0x00000001U /**< RX logic reset */
75 
76 /* Mode Register Bits Definition */
77 #define XUARTPS_MR_CCLK             0x00000400U /**< Input clock select */
78 #define XUARTPS_MR_CHMODE_R_LOOP    0x00000300U /**< Remote loopback mode */
79 #define XUARTPS_MR_CHMODE_L_LOOP    0x00000200U /**< Local loopback mode */
80 #define XUARTPS_MR_CHMODE_ECHO      0x00000100U /**< Auto echo mode */
81 #define XUARTPS_MR_CHMODE_NORM      0x00000000U /**< Normal mode */
82 #define XUARTPS_MR_CHMODE_SHIFT     8U          /**< Mode shift */
83 #define XUARTPS_MR_CHMODE_MASK      0x00000300U /**< Mode mask */
84 #define XUARTPS_MR_STOPMODE_2_BIT   0x00000080U /**< 2 stop bits */
85 #define XUARTPS_MR_STOPMODE_1_5_BIT 0x00000040U /**< 1.5 stop bits */
86 #define XUARTPS_MR_STOPMODE_1_BIT   0x00000000U /**< 1 stop bit */
87 #define XUARTPS_MR_STOPMODE_SHIFT   6U          /**< Stop bits shift */
88 #define XUARTPS_MR_STOPMODE_MASK    0x000000A0U /**< Stop bits mask */
89 #define XUARTPS_MR_PARITY_NONE      0x00000020U /**< No parity mode */
90 #define XUARTPS_MR_PARITY_MARK      0x00000018U /**< Mark parity mode */
91 #define XUARTPS_MR_PARITY_SPACE     0x00000010U /**< Space parity mode */
92 #define XUARTPS_MR_PARITY_ODD       0x00000008U /**< Odd parity mode */
93 #define XUARTPS_MR_PARITY_EVEN      0x00000000U /**< Even parity mode */
94 #define XUARTPS_MR_PARITY_SHIFT     3U          /**< Parity setting shift */
95 #define XUARTPS_MR_PARITY_MASK      0x00000038U /**< Parity mask */
96 #define XUARTPS_MR_CHARLEN_6_BIT    0x00000006U /**< 6 bits data */
97 #define XUARTPS_MR_CHARLEN_7_BIT    0x00000004U /**< 7 bits data */
98 #define XUARTPS_MR_CHARLEN_8_BIT    0x00000000U /**< 8 bits data */
99 #define XUARTPS_MR_CHARLEN_SHIFT    1U          /**< Data Length shift */
100 #define XUARTPS_MR_CHARLEN_MASK     0x00000006U /**< Data length mask */
101 #define XUARTPS_MR_CLKSEL           0x00000001U /**< Input clock select */
102 
103 /* Interrupt Register Bits Definition */
104 #define XUARTPS_IXR_RBRK    0x00002000U /**< Rx FIFO break detect interrupt */
105 #define XUARTPS_IXR_TOVR    0x00001000U /**< Tx FIFO Overflow interrupt */
106 #define XUARTPS_IXR_TNFUL   0x00000800U /**< Tx FIFO Nearly Full interrupt */
107 #define XUARTPS_IXR_TTRIG   0x00000400U /**< Tx Trig interrupt */
108 #define XUARTPS_IXR_DMS     0x00000200U /**< Modem status change interrupt */
109 #define XUARTPS_IXR_TOUT    0x00000100U /**< Timeout error interrupt */
110 #define XUARTPS_IXR_PARITY  0x00000080U /**< Parity error interrupt */
111 #define XUARTPS_IXR_FRAMING 0x00000040U /**< Framing error interrupt */
112 #define XUARTPS_IXR_RXOVR   0x00000020U /**< Overrun error interrupt */
113 #define XUARTPS_IXR_TXFULL  0x00000010U /**< TX FIFO full interrupt. */
114 #define XUARTPS_IXR_TXEMPTY 0x00000008U /**< TX FIFO empty interrupt. */
115 #define XUARTPS_IXR_RXFULL  0x00000004U /**< RX FIFO full interrupt. */
116 #define XUARTPS_IXR_RXEMPTY 0x00000002U /**< RX FIFO empty interrupt. */
117 #define XUARTPS_IXR_RTRIG   0x00000001U /**< RX FIFO trigger interrupt. */
118 #define XUARTPS_IXR_MASK    0x00003FFFU /**< Valid bit mask */
119 
120 /* Modem Control Register Bits Definition */
121 #define XUARTPS_MODEMCR_FCM_RTS_CTS 0x00000020 /**< RTS/CTS hardware flow control. */
122 #define XUARTPS_MODEMCR_FCM_NONE    0x00000000 /**< No hardware flow control. */
123 #define XUARTPS_MODEMCR_FCM_MASK    0x00000020 /**< Hardware flow control mask. */
124 #define XUARTPS_MODEMCR_RTS_SHIFT   1U         /**< RTS bit shift */
125 #define XUARTPS_MODEMCR_DTR_SHIFT   0U         /**< DTR bit shift */
126 
127 /* Channel Status Register */
128 #define XUARTPS_SR_TNFUL   0x00004000U /**< TX FIFO Nearly Full Status */
129 #define XUARTPS_SR_TTRIG   0x00002000U /**< TX FIFO Trigger Status */
130 #define XUARTPS_SR_FLOWDEL 0x00001000U /**< RX FIFO fill over flow delay */
131 #define XUARTPS_SR_TACTIVE 0x00000800U /**< TX active */
132 #define XUARTPS_SR_RACTIVE 0x00000400U /**< RX active */
133 #define XUARTPS_SR_TXFULL  0x00000010U /**< TX FIFO full */
134 #define XUARTPS_SR_TXEMPTY 0x00000008U /**< TX FIFO empty */
135 #define XUARTPS_SR_RXFULL  0x00000004U /**< RX FIFO full */
136 #define XUARTPS_SR_RXEMPTY 0x00000002U /**< RX FIFO empty */
137 #define XUARTPS_SR_RTRIG   0x00000001U /**< RX FIFO fill over trigger */
138 
139 /** Device configuration structure */
140 struct uart_xlnx_ps_dev_config {
141 	DEVICE_MMIO_ROM;
142 	uint32_t sys_clk_freq;
143 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
144 	uart_irq_config_func_t irq_config_func;
145 #endif
146 #ifdef CONFIG_PINCTRL
147 	const struct pinctrl_dev_config *pincfg;
148 #endif
149 	uint32_t baud_rate;
150 };
151 
152 /** Device data structure */
153 struct uart_xlnx_ps_dev_data_t {
154 	DEVICE_MMIO_RAM;
155 	uint32_t parity;
156 	uint32_t stopbits;
157 	uint32_t databits;
158 	uint32_t flowctrl;
159 
160 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
161 	const struct device *dev;
162 	struct k_timer timer;
163 	uart_irq_callback_user_data_t user_cb;
164 	void *user_data;
165 #endif
166 };
167 
168 /**
169  * @brief Disables the UART's RX and TX function.
170  *
171  * Writes 'Disable RX' and 'Disable TX' command bits into the respective
172  * UART's Command Register, thus disabling the operation of the UART.
173  *
174  * While writing the disable command bits, the opposing enable command
175  * bits, which are set when enabling the UART, are cleared.
176  *
177  * This function must be called before any configuration parameters
178  * of the UART are modified at run-time.
179  *
180  * @param reg_base Base address of the respective UART's register space.
181  */
xlnx_ps_disable_uart(uintptr_t reg_base)182 static void xlnx_ps_disable_uart(uintptr_t reg_base)
183 {
184 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_CR_OFFSET);
185 
186 	reg_val &= (~XUARTPS_CR_EN_DIS_MASK);
187 	/* Set control register bits [5]: TX_DIS and [3]: RX_DIS */
188 	reg_val |= XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS;
189 	sys_write32(reg_val, reg_base + XUARTPS_CR_OFFSET);
190 }
191 
192 /**
193  * @brief Enables the UART's RX and TX function.
194  *
195  * Writes 'Enable RX' and 'Enable TX' command bits into the respective
196  * UART's Command Register, thus enabling the operation of the UART.
197  *
198  * While writing the enable command bits, the opposing disable command
199  * bits, which are set when disabling the UART, are cleared.
200  *
201  * This function must not be called while any configuration parameters
202  * of the UART are being modified at run-time.
203  *
204  * @param reg_base Base address of the respective UART's register space.
205  */
xlnx_ps_enable_uart(uintptr_t reg_base)206 static void xlnx_ps_enable_uart(uintptr_t reg_base)
207 {
208 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_CR_OFFSET);
209 
210 	reg_val &= (~XUARTPS_CR_EN_DIS_MASK);
211 	/* Set control register bits [4]: TX_EN and [2]: RX_EN */
212 	reg_val |= XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN;
213 	sys_write32(reg_val, reg_base + XUARTPS_CR_OFFSET);
214 }
215 
216 /**
217  * @brief Calculates and sets the values of the BAUDDIV and BAUDGEN registers.
218  *
219  * Calculates and sets the values of the BAUDDIV and BAUDGEN registers, which
220  * determine the prescaler applied to the clock driving the UART, based on
221  * the target baud rate, which is provided as a decimal value.
222  *
223  * The calculation of the values to be written to the BAUDDIV and BAUDGEN
224  * registers is described in the Zynq-7000 TRM, chapter 19.2.3 'Baud Rate
225  * Generator'.
226  *
227  * @param dev UART device struct
228  * @param baud_rate The desired baud rate as a decimal value
229  */
set_baudrate(const struct device * dev,uint32_t baud_rate)230 static void set_baudrate(const struct device *dev, uint32_t baud_rate)
231 {
232 	const struct uart_xlnx_ps_dev_config *dev_cfg = dev->config;
233 	uint32_t baud = dev_cfg->baud_rate;
234 	uint32_t clk_freq = dev_cfg->sys_clk_freq;
235 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
236 	uint32_t divisor, generator;
237 
238 	/* Calculate divisor and baud rate generator value */
239 	if ((baud != 0) && (clk_freq != 0)) {
240 		/* Covering case where input clock is so slow */
241 		if (clk_freq < 1000000U && baud > 4800U) {
242 			baud = 4800;
243 		}
244 
245 		for (divisor = 4; divisor < 255; divisor++) {
246 			uint32_t tmpbaud, bauderr;
247 
248 			generator = clk_freq / (baud * (divisor + 1));
249 			if (generator < 2 || generator > 65535) {
250 				continue;
251 			}
252 			tmpbaud = clk_freq / (generator * (divisor + 1));
253 
254 			if (baud > tmpbaud) {
255 				bauderr = baud - tmpbaud;
256 			} else {
257 				bauderr = tmpbaud - baud;
258 			}
259 			if (((bauderr * 100) / baud) < 3) {
260 				break;
261 			}
262 		}
263 
264 		/*
265 		 * Set baud rate divisor and generator.
266 		 * -> This function is always called from a context in which
267 		 * the receiver/transmitter is disabled, the baud rate can
268 		 * be changed safely at this time.
269 		 */
270 		sys_write32(divisor, reg_base + XUARTPS_BAUDDIV_OFFSET);
271 		sys_write32(generator, reg_base + XUARTPS_BAUDGEN_OFFSET);
272 	}
273 }
274 
275 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
276 
277 /**
278  * @brief Trigger a UART callback based on a timer.
279  *
280  * @param timer Timer that triggered the callback
281  */
uart_xlnx_ps_soft_isr(struct k_timer * timer)282 static void uart_xlnx_ps_soft_isr(struct k_timer *timer)
283 {
284 	struct uart_xlnx_ps_dev_data_t *data =
285 		CONTAINER_OF(timer, struct uart_xlnx_ps_dev_data_t, timer);
286 
287 	if (data->user_cb) {
288 		data->user_cb(data->dev, data->user_data);
289 	}
290 }
291 
292 #endif
293 
294 /**
295  * @brief Initialize individual UART port
296  *
297  * This routine is called to reset the chip in a quiescent state.
298  *
299  * @param dev UART device struct
300  *
301  * @return 0 if successful, failed otherwise
302  */
uart_xlnx_ps_init(const struct device * dev)303 static int uart_xlnx_ps_init(const struct device *dev)
304 {
305 	const struct uart_xlnx_ps_dev_config *dev_cfg = dev->config;
306 	uint32_t reg_val;
307 #ifdef CONFIG_PINCTRL
308 	int err;
309 #endif
310 
311 	DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
312 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
313 
314 #ifdef CONFIG_PINCTRL
315 	err = pinctrl_apply_state(dev_cfg->pincfg, PINCTRL_STATE_DEFAULT);
316 	if (err < 0) {
317 		return err;
318 	}
319 #endif
320 
321 	/* Set RX/TX reset and disable RX/TX */
322 	sys_write32(XUARTPS_CR_STOPBRK | XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS | XUARTPS_CR_TXRST |
323 			    XUARTPS_CR_RXRST,
324 		    reg_base + XUARTPS_CR_OFFSET);
325 
326 	/* Set initial character length / start/stop bit / parity configuration */
327 	reg_val = sys_read32(reg_base + XUARTPS_MR_OFFSET);
328 	reg_val &= (~(XUARTPS_MR_CHARLEN_MASK | XUARTPS_MR_STOPMODE_MASK | XUARTPS_MR_PARITY_MASK));
329 	reg_val |= XUARTPS_MR_CHARLEN_8_BIT | XUARTPS_MR_STOPMODE_1_BIT | XUARTPS_MR_PARITY_NONE;
330 	sys_write32(reg_val, reg_base + XUARTPS_MR_OFFSET);
331 
332 	/* Set RX FIFO trigger at 1 data bytes. */
333 	sys_write32(0x01U, reg_base + XUARTPS_RXWM_OFFSET);
334 
335 	/* Disable all interrupts, polling mode is default */
336 	sys_write32(XUARTPS_IXR_MASK, reg_base + XUARTPS_IDR_OFFSET);
337 
338 	/* Set the baud rate */
339 	set_baudrate(dev, dev_cfg->baud_rate);
340 
341 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
342 	struct uart_xlnx_ps_dev_data_t *dev_data = dev->data;
343 
344 	/* Clear any pending interrupt flags */
345 	sys_write32(XUARTPS_IXR_MASK, reg_base + XUARTPS_ISR_OFFSET);
346 
347 	dev_data->dev = dev;
348 	k_timer_init(&dev_data->timer, &uart_xlnx_ps_soft_isr, NULL);
349 
350 	/* Attach to & unmask the corresponding interrupt vector */
351 	dev_cfg->irq_config_func(dev);
352 
353 #endif
354 
355 	xlnx_ps_enable_uart(reg_base);
356 
357 	return 0;
358 }
359 
360 /**
361  * @brief Poll the device for input.
362  *
363  * @param dev UART device struct
364  * @param c Pointer to character
365  *
366  * @return 0 if a character arrived, -1 if the input buffer if empty.
367  */
uart_xlnx_ps_poll_in(const struct device * dev,unsigned char * c)368 static int uart_xlnx_ps_poll_in(const struct device *dev, unsigned char *c)
369 {
370 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
371 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
372 
373 	if ((reg_val & XUARTPS_SR_RXEMPTY) == 0) {
374 		*c = (unsigned char)sys_read32(reg_base + XUARTPS_FIFO_OFFSET);
375 		return 0;
376 	} else {
377 		return -1;
378 	}
379 }
380 
381 /**
382  * @brief Output a character in polled mode.
383  *
384  * Checks if the transmitter has available TX FIFO space. If so, a character is written to
385  * the data register.
386  *
387  * If the hardware flow control is enabled then the handshake signal CTS has to
388  * be asserted in order to send a character.
389  *
390  * @param dev UART device struct
391  * @param c Character to send
392  *
393  * @return Sent character
394  */
uart_xlnx_ps_poll_out(const struct device * dev,unsigned char c)395 static void uart_xlnx_ps_poll_out(const struct device *dev, unsigned char c)
396 {
397 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
398 
399 	/* wait for transmitter to be ready to accept a character */
400 	while ((sys_read32(reg_base + XUARTPS_SR_OFFSET) & XUARTPS_SR_TXFULL) != 0) {
401 	}
402 
403 	sys_write32((uint32_t)(c & 0xFF), reg_base + XUARTPS_FIFO_OFFSET);
404 }
405 
406 /**
407  * Check for pending TX/TX errors on the port.
408  *
409  * @param dev UART device struct
410  * @return 0 if no errors, UART_ERROR_* flags otherwise
411  */
uart_xlnx_ps_err_check(const struct device * dev)412 static int uart_xlnx_ps_err_check(const struct device *dev)
413 {
414 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
415 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_ISR_OFFSET);
416 	int err = 0;
417 
418 	if (reg_val & XUARTPS_IXR_RBRK) {
419 		err |= UART_BREAK;
420 	}
421 
422 	if (reg_val & XUARTPS_IXR_TOVR) {
423 		err |= UART_ERROR_OVERRUN;
424 	}
425 
426 	if (reg_val & XUARTPS_IXR_TOUT) {
427 		err |= UART_ERROR_NOISE;
428 	}
429 
430 	if (reg_val & XUARTPS_IXR_PARITY) {
431 		err |= UART_ERROR_PARITY;
432 	}
433 
434 	if (reg_val & XUARTPS_IXR_FRAMING) {
435 		err |= UART_ERROR_FRAMING;
436 	}
437 
438 	if (reg_val & XUARTPS_IXR_RXOVR) {
439 		err |= UART_ERROR_OVERRUN;
440 	}
441 	sys_write32(reg_val & (XUARTPS_IXR_RBRK | XUARTPS_IXR_TOVR | XUARTPS_IXR_TOUT |
442 			       XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING | XUARTPS_IXR_RXOVR),
443 		    reg_base + XUARTPS_ISR_OFFSET);
444 
445 	return err;
446 }
447 
448 /**
449  * @brief Converts a parity enum value to a Mode Register bit mask.
450  *
451  * Converts a value of an enumeration type provided by the driver
452  * framework for the configuration of the UART's parity setting
453  * into a bit mask within the Mode Register.
454  *
455  * It is assumed that the Mode Register contents that are being
456  * modified within this function come with the bits modified by
457  * this function already masked out by the caller.
458  *
459  * @param mode_reg Pointer to the Mode Register contents to which
460  *                 the parity configuration shall be added.
461  * @param parity   Enumeration value to be converted to a bit mask.
462  *
463  * @return Indication of success, always true for this function
464  *         as all parity modes supported by the API are also supported
465  *         by the hardware.
466  */
uart_xlnx_ps_cfg2ll_parity(uint32_t * mode_reg,enum uart_config_parity parity)467 static inline bool uart_xlnx_ps_cfg2ll_parity(uint32_t *mode_reg, enum uart_config_parity parity)
468 {
469 	/*
470 	 * Translate the new parity configuration to the mode register's
471 	 * bits [5..3] (PAR):
472 	 *  000b : even
473 	 *  001b : odd
474 	 *  010b : space
475 	 *  011b : mark
476 	 *  1xxb : none
477 	 */
478 
479 	switch (parity) {
480 	default:
481 	case UART_CFG_PARITY_EVEN:
482 		*mode_reg |= XUARTPS_MR_PARITY_EVEN;
483 		break;
484 	case UART_CFG_PARITY_ODD:
485 		*mode_reg |= XUARTPS_MR_PARITY_ODD;
486 		break;
487 	case UART_CFG_PARITY_SPACE:
488 		*mode_reg |= XUARTPS_MR_PARITY_SPACE;
489 		break;
490 	case UART_CFG_PARITY_MARK:
491 		*mode_reg |= XUARTPS_MR_PARITY_MARK;
492 		break;
493 	case UART_CFG_PARITY_NONE:
494 		*mode_reg |= XUARTPS_MR_PARITY_NONE;
495 		break;
496 	}
497 
498 	return true;
499 }
500 
501 /**
502  * @brief Converts a stop bit enum value to a Mode Register bit mask.
503  *
504  * Converts a value of an enumeration type provided by the driver
505  * framework for the configuration of the UART's stop bit setting
506  * into a bit mask within the Mode Register.
507  *
508  * It is assumed that the Mode Register contents that are being
509  * modified within this function come with the bits modified by
510  * this function already masked out by the caller.
511  *
512  * @param mode_reg Pointer to the Mode Register contents to which
513  *                 the stop bit configuration shall be added.
514  * @param stopbits Enumeration value to be converted to a bit mask.
515  *
516  * @return Indication of success or failure in case of an unsupported
517  *         stop bit configuration being provided by the caller.
518  */
uart_xlnx_ps_cfg2ll_stopbits(uint32_t * mode_reg,enum uart_config_stop_bits stopbits)519 static inline bool uart_xlnx_ps_cfg2ll_stopbits(uint32_t *mode_reg,
520 						enum uart_config_stop_bits stopbits)
521 {
522 	/*
523 	 * Translate the new stop bit configuration to the mode register's
524 	 * bits [7..6] (NBSTOP):
525 	 *  00b : 1 stop bit
526 	 *  01b : 1.5 stop bits
527 	 *  10b : 2 stop bits
528 	 *  11b : reserved
529 	 */
530 
531 	switch (stopbits) {
532 	case UART_CFG_STOP_BITS_0_5:
533 		/* Controller doesn't support 0.5 stop bits */
534 		return false;
535 	default:
536 	case UART_CFG_STOP_BITS_1:
537 		*mode_reg |= XUARTPS_MR_STOPMODE_1_BIT;
538 		break;
539 	case UART_CFG_STOP_BITS_1_5:
540 		*mode_reg |= XUARTPS_MR_STOPMODE_1_5_BIT;
541 		break;
542 	case UART_CFG_STOP_BITS_2:
543 		*mode_reg |= XUARTPS_MR_STOPMODE_2_BIT;
544 		break;
545 	}
546 
547 	return true;
548 }
549 
550 /**
551  * @brief Converts a data bit enum value to a Mode Register bit mask.
552  *
553  * Converts a value of an enumeration type provided by the driver
554  * framework for the configuration of the UART's data bit setting
555  * into a bit mask within the Mode Register.
556  *
557  * It is assumed that the Mode Register contents that are being
558  * modified within this function come with the bits modified by
559  * this function already masked out by the caller.
560  *
561  * @param mode_reg Pointer to the Mode Register contents to which
562  *                 the data bit configuration shall be added.
563  * @param databits Enumeration value to be converted to a bit mask.
564  *
565  * @return Indication of success or failure in case of an unsupported
566  *         data bit configuration being provided by the caller.
567  */
uart_xlnx_ps_cfg2ll_databits(uint32_t * mode_reg,enum uart_config_data_bits databits)568 static inline bool uart_xlnx_ps_cfg2ll_databits(uint32_t *mode_reg,
569 						enum uart_config_data_bits databits)
570 {
571 	/*
572 	 * Translate the new data bit configuration to the mode register's
573 	 * bits [2..1] (CHRL):
574 	 *  0xb : 8 data bits
575 	 *  10b : 7 data bits
576 	 *  11b : 6 data bits
577 	 */
578 
579 	switch (databits) {
580 	case UART_CFG_DATA_BITS_5:
581 	case UART_CFG_DATA_BITS_9:
582 		/* Controller doesn't support 5 or 9 data bits */
583 		return false;
584 	default:
585 	case UART_CFG_DATA_BITS_8:
586 		*mode_reg |= XUARTPS_MR_CHARLEN_8_BIT;
587 		break;
588 	case UART_CFG_DATA_BITS_7:
589 		*mode_reg |= XUARTPS_MR_CHARLEN_7_BIT;
590 		break;
591 	case UART_CFG_DATA_BITS_6:
592 		*mode_reg |= XUARTPS_MR_CHARLEN_6_BIT;
593 		break;
594 	}
595 
596 	return true;
597 }
598 
599 /**
600  * @brief Converts a flow control enum value to a Modem Control
601  *        Register bit mask.
602  *
603  * Converts a value of an enumeration type provided by the driver
604  * framework for the configuration of the UART's flow control
605  * setting into a bit mask within the Modem Control Register.
606  *
607  * It is assumed that the Modem Control Register contents that are
608  * being modified within this function come with the bits modified
609  * by this function already masked out by the caller.
610  *
611  * @param modemcr_reg Pointer to the Modem Control Register contents
612  *                    to which the flow control configuration shall
613  *                    be added.
614  * @param hwctrl Enumeration value to be converted to a bit mask.
615  *
616  * @return Indication of success or failure in case of an unsupported
617  *         flow control configuration being provided by the caller.
618  */
uart_xlnx_ps_cfg2ll_hwctrl(uint32_t * modemcr_reg,enum uart_config_flow_control hwctrl)619 static inline bool uart_xlnx_ps_cfg2ll_hwctrl(uint32_t *modemcr_reg,
620 					      enum uart_config_flow_control hwctrl)
621 {
622 	/*
623 	 * Translate the new flow control configuration to the modem
624 	 * control register's bit [5] (FCM):
625 	 *  0b : no flow control
626 	 *  1b : RTS/CTS
627 	 */
628 
629 	if (hwctrl == UART_CFG_FLOW_CTRL_RTS_CTS) {
630 		*modemcr_reg |= XUARTPS_MODEMCR_FCM_RTS_CTS;
631 	} else if (hwctrl == UART_CFG_FLOW_CTRL_NONE) {
632 		*modemcr_reg |= XUARTPS_MODEMCR_FCM_NONE;
633 	} else {
634 		/* Only no flow control or RTS/CTS is supported. */
635 		return false;
636 	}
637 
638 	return true;
639 }
640 
641 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
642 /**
643  * @brief Configures the UART device at run-time.
644  *
645  * Configures the UART device at run-time according to the
646  * configuration data provided by the caller.
647  *
648  * @param dev UART device struct
649  * @param cfg The configuration parameters to be applied.
650  *
651  * @return 0 if the configuration completed successfully, ENOTSUP
652  *         error if an unsupported configuration parameter is detected.
653  */
uart_xlnx_ps_configure(const struct device * dev,const struct uart_config * cfg)654 static int uart_xlnx_ps_configure(const struct device *dev, const struct uart_config *cfg)
655 {
656 	struct uart_xlnx_ps_dev_config *dev_cfg = (struct uart_xlnx_ps_dev_config *)dev->config;
657 
658 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
659 	uint32_t mode_reg = 0;
660 	uint32_t modemcr_reg = 0;
661 
662 	/* Read the current mode register & modem control register values */
663 	mode_reg = sys_read32(reg_base + XUARTPS_MR_OFFSET);
664 	modemcr_reg = sys_read32(reg_base + XUARTPS_MODEMCR_OFFSET);
665 
666 	/* Mask out all items that might be re-configured */
667 	mode_reg &= (~XUARTPS_MR_PARITY_MASK);
668 	mode_reg &= (~XUARTPS_MR_STOPMODE_MASK);
669 	mode_reg &= (~XUARTPS_MR_CHARLEN_MASK);
670 	modemcr_reg &= (~XUARTPS_MODEMCR_FCM_MASK);
671 
672 	/* Assemble the updated registers, validity checks contained within */
673 	if ((!uart_xlnx_ps_cfg2ll_parity(&mode_reg, cfg->parity)) ||
674 	    (!uart_xlnx_ps_cfg2ll_stopbits(&mode_reg, cfg->stop_bits)) ||
675 	    (!uart_xlnx_ps_cfg2ll_databits(&mode_reg, cfg->data_bits)) ||
676 	    (!uart_xlnx_ps_cfg2ll_hwctrl(&modemcr_reg, cfg->flow_ctrl))) {
677 		return -ENOTSUP;
678 	}
679 
680 	/* Disable the controller before modifying any config registers */
681 	xlnx_ps_disable_uart(reg_base);
682 
683 	/* Set the baud rate */
684 	set_baudrate(dev, cfg->baudrate);
685 	dev_cfg->baud_rate = cfg->baudrate;
686 
687 	/* Write the two control registers */
688 	sys_write32(mode_reg, reg_base + XUARTPS_MR_OFFSET);
689 	sys_write32(modemcr_reg, reg_base + XUARTPS_MODEMCR_OFFSET);
690 
691 	/* Re-enable the controller */
692 	xlnx_ps_enable_uart(reg_base);
693 
694 	return 0;
695 };
696 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
697 
698 /**
699  * @brief Converts a Mode Register bit mask to a parity configuration
700  *        enum value.
701  *
702  * Converts a bit mask representing the UART's parity setting within
703  * the UART's Mode Register into a value of an enumeration type provided
704  * by the UART driver API.
705  *
706  * @param mode_reg The current Mode Register contents from which the
707  *                 parity setting shall be extracted.
708  *
709  * @return The current parity setting mapped to the UART driver API's
710  *         enum type.
711  */
uart_xlnx_ps_ll2cfg_parity(uint32_t mode_reg)712 static inline enum uart_config_parity uart_xlnx_ps_ll2cfg_parity(uint32_t mode_reg)
713 {
714 	/*
715 	 * Obtain the current parity configuration from the mode register's
716 	 * bits [5..3] (PAR):
717 	 *  000b : even -> reset value
718 	 *  001b : odd
719 	 *  010b : space
720 	 *  011b : mark
721 	 *  1xxb : none
722 	 */
723 
724 	switch ((mode_reg & XUARTPS_MR_PARITY_MASK)) {
725 	case XUARTPS_MR_PARITY_EVEN:
726 	default:
727 		return UART_CFG_PARITY_EVEN;
728 	case XUARTPS_MR_PARITY_ODD:
729 		return UART_CFG_PARITY_ODD;
730 	case XUARTPS_MR_PARITY_SPACE:
731 		return UART_CFG_PARITY_SPACE;
732 	case XUARTPS_MR_PARITY_MARK:
733 		return UART_CFG_PARITY_MARK;
734 	case XUARTPS_MR_PARITY_NONE:
735 		return UART_CFG_PARITY_NONE;
736 	}
737 }
738 
739 /**
740  * @brief Converts a Mode Register bit mask to a stop bit configuration
741  *        enum value.
742  *
743  * Converts a bit mask representing the UART's stop bit setting within
744  * the UART's Mode Register into a value of an enumeration type provided
745  * by the UART driver API.
746  *
747  * @param mode_reg The current Mode Register contents from which the
748  *                 stop bit setting shall be extracted.
749  *
750  * @return The current stop bit setting mapped to the UART driver API's
751  *         enum type.
752  */
uart_xlnx_ps_ll2cfg_stopbits(uint32_t mode_reg)753 static inline enum uart_config_stop_bits uart_xlnx_ps_ll2cfg_stopbits(uint32_t mode_reg)
754 {
755 	/*
756 	 * Obtain the current stop bit configuration from the mode register's
757 	 * bits [7..6] (NBSTOP):
758 	 *  00b : 1 stop bit -> reset value
759 	 *  01b : 1.5 stop bits
760 	 *  10b : 2 stop bits
761 	 *  11b : reserved
762 	 */
763 
764 	switch ((mode_reg & XUARTPS_MR_STOPMODE_MASK)) {
765 	case XUARTPS_MR_STOPMODE_1_BIT:
766 	default:
767 		return UART_CFG_STOP_BITS_1;
768 	case XUARTPS_MR_STOPMODE_1_5_BIT:
769 		return UART_CFG_STOP_BITS_1_5;
770 	case XUARTPS_MR_STOPMODE_2_BIT:
771 		return UART_CFG_STOP_BITS_2;
772 	}
773 }
774 
775 /**
776  * @brief Converts a Mode Register bit mask to a data bit configuration
777  *        enum value.
778  *
779  * Converts a bit mask representing the UART's data bit setting within
780  * the UART's Mode Register into a value of an enumeration type provided
781  * by the UART driver API.
782  *
783  * @param mode_reg The current Mode Register contents from which the
784  *                 data bit setting shall be extracted.
785  *
786  * @return The current data bit setting mapped to the UART driver API's
787  *         enum type.
788  */
uart_xlnx_ps_ll2cfg_databits(uint32_t mode_reg)789 static inline enum uart_config_data_bits uart_xlnx_ps_ll2cfg_databits(uint32_t mode_reg)
790 {
791 	/*
792 	 * Obtain the current data bit configuration from the mode register's
793 	 * bits [2..1] (CHRL):
794 	 *  0xb : 8 data bits -> reset value
795 	 *  10b : 7 data bits
796 	 *  11b : 6 data bits
797 	 */
798 
799 	switch ((mode_reg & XUARTPS_MR_CHARLEN_MASK)) {
800 	case XUARTPS_MR_CHARLEN_8_BIT:
801 	default:
802 		return UART_CFG_DATA_BITS_8;
803 	case XUARTPS_MR_CHARLEN_7_BIT:
804 		return UART_CFG_DATA_BITS_7;
805 	case XUARTPS_MR_CHARLEN_6_BIT:
806 		return UART_CFG_DATA_BITS_6;
807 	}
808 }
809 
810 /**
811  * @brief Converts a Modem Control Register bit mask to a flow control
812  *        configuration enum value.
813  *
814  * Converts a bit mask representing the UART's flow control setting within
815  * the UART's Modem Control Register into a value of an enumeration type
816  * provided by the UART driver API.
817  *
818  * @param modemcr_reg The current Modem Control Register contents from
819  *                    which the parity setting shall be extracted.
820  *
821  * @return The current flow control setting mapped to the UART driver API's
822  *         enum type.
823  */
uart_xlnx_ps_ll2cfg_hwctrl(uint32_t modemcr_reg)824 static inline enum uart_config_flow_control uart_xlnx_ps_ll2cfg_hwctrl(uint32_t modemcr_reg)
825 {
826 	/*
827 	 * Obtain the current flow control configuration from the modem
828 	 * control register's bit [5] (FCM):
829 	 *  0b : no flow control -> reset value
830 	 *  1b : RTS/CTS
831 	 */
832 
833 	if ((modemcr_reg & XUARTPS_MODEMCR_FCM_MASK) == XUARTPS_MODEMCR_FCM_RTS_CTS) {
834 		return UART_CFG_FLOW_CTRL_RTS_CTS;
835 	}
836 
837 	return UART_CFG_FLOW_CTRL_NONE;
838 }
839 
840 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
841 /**
842  * @brief Returns the current configuration of the UART at run-time.
843  *
844  * Returns the current configuration of the UART at run-time by obtaining
845  * the current configuration from the UART's Mode and Modem Control Registers
846  * (exception: baud rate).
847  *
848  * @param dev UART device struct
849  * @param cfg Pointer to the data structure to which the current configuration
850  *            shall be written.
851  *
852  * @return always 0.
853  */
uart_xlnx_ps_config_get(const struct device * dev,struct uart_config * cfg)854 static int uart_xlnx_ps_config_get(const struct device *dev, struct uart_config *cfg)
855 {
856 	const struct uart_xlnx_ps_dev_config *dev_cfg = dev->config;
857 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
858 
859 	/*
860 	 * Read the Mode & Modem control registers - they contain
861 	 * the current data / stop bit and parity settings (Mode
862 	 * Register) and the current flow control setting (Modem
863 	 * Control register).
864 	 */
865 	uint32_t mode_reg = sys_read32(reg_base + XUARTPS_MR_OFFSET);
866 	uint32_t modemcr_reg = sys_read32(reg_base + XUARTPS_MODEMCR_OFFSET);
867 
868 	cfg->baudrate = dev_cfg->baud_rate;
869 	cfg->parity = uart_xlnx_ps_ll2cfg_parity(mode_reg);
870 	cfg->stop_bits = uart_xlnx_ps_ll2cfg_stopbits(mode_reg);
871 	cfg->data_bits = uart_xlnx_ps_ll2cfg_databits(mode_reg);
872 	cfg->flow_ctrl = uart_xlnx_ps_ll2cfg_hwctrl(modemcr_reg);
873 
874 	return 0;
875 }
876 #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
877 
878 #if CONFIG_UART_INTERRUPT_DRIVEN
879 
880 /**
881  * @brief Fill FIFO with data
882  *
883  * @param dev UART device struct
884  * @param tx_data Data to transmit
885  * @param size Number of bytes to send
886  *
887  * @return Number of bytes sent
888  */
uart_xlnx_ps_fifo_fill(const struct device * dev,const uint8_t * tx_data,int size)889 static int uart_xlnx_ps_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size)
890 {
891 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
892 	int count = 0;
893 
894 	while (count < size &&
895 	       (sys_read32(reg_base + XUARTPS_SR_OFFSET) & XUARTPS_SR_TXFULL) == 0) {
896 		sys_write32((uint32_t)tx_data[count++], reg_base + XUARTPS_FIFO_OFFSET);
897 	}
898 
899 	return count;
900 }
901 
902 /**
903  * @brief Read data from FIFO
904  *
905  * @param dev UART device struct
906  * @param rxData Data container
907  * @param size Container size
908  *
909  * @return Number of bytes read
910  */
uart_xlnx_ps_fifo_read(const struct device * dev,uint8_t * rx_data,const int size)911 static int uart_xlnx_ps_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
912 {
913 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
914 	int count = 0;
915 
916 	while (count < size &&
917 	       (sys_read32(reg_base + XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY) == 0) {
918 		rx_data[count++] = (uint8_t)sys_read32(reg_base + XUARTPS_FIFO_OFFSET);
919 	}
920 
921 	return count;
922 }
923 
924 /**
925  * @brief Enable TX interrupt in IER
926  *
927  * @param dev UART device struct
928  */
uart_xlnx_ps_irq_tx_enable(const struct device * dev)929 static void uart_xlnx_ps_irq_tx_enable(const struct device *dev)
930 {
931 	struct uart_xlnx_ps_dev_data_t *dev_data = dev->data;
932 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
933 
934 	sys_write32((XUARTPS_IXR_TTRIG | XUARTPS_IXR_TXEMPTY), reg_base + XUARTPS_IER_OFFSET);
935 	if ((sys_read32(reg_base + XUARTPS_SR_OFFSET) & (XUARTPS_SR_TTRIG | XUARTPS_SR_TXEMPTY)) !=
936 	    0) {
937 		/*
938 		 * Enabling TX empty interrupts does not cause an interrupt
939 		 * if the FIFO is already empty.
940 		 * Generate a soft interrupt and have it call the
941 		 * callback function in timer isr context.
942 		 */
943 		k_timer_start(&dev_data->timer, K_NO_WAIT, K_NO_WAIT);
944 	}
945 }
946 
947 /**
948  * @brief Disable TX interrupt in IER
949  *
950  * @param dev UART device struct
951  */
uart_xlnx_ps_irq_tx_disable(const struct device * dev)952 static void uart_xlnx_ps_irq_tx_disable(const struct device *dev)
953 {
954 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
955 
956 	sys_write32((XUARTPS_IXR_TTRIG | XUARTPS_IXR_TXEMPTY), reg_base + XUARTPS_IDR_OFFSET);
957 }
958 
959 /**
960  * @brief Check if Tx IRQ has been raised
961  *
962  * @param dev UART device struct
963  *
964  * @return 1 if an IRQ is ready, 0 otherwise
965  */
uart_xlnx_ps_irq_tx_ready(const struct device * dev)966 static int uart_xlnx_ps_irq_tx_ready(const struct device *dev)
967 {
968 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
969 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
970 
971 	if ((reg_val & (XUARTPS_SR_TTRIG | XUARTPS_SR_TXEMPTY)) == 0) {
972 		return 0;
973 	} else {
974 		return 1;
975 	}
976 }
977 
978 /**
979  * @brief Check if nothing remains to be transmitted
980  *
981  * @param dev UART device struct
982  *
983  * @return 1 if nothing remains to be transmitted, 0 otherwise
984  */
uart_xlnx_ps_irq_tx_complete(const struct device * dev)985 static int uart_xlnx_ps_irq_tx_complete(const struct device *dev)
986 {
987 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
988 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
989 
990 	return (reg_val & XUARTPS_SR_TXEMPTY) != 0;
991 }
992 
993 /**
994  * @brief Enable RX interrupt in IER
995  *
996  * @param dev UART device struct
997  */
uart_xlnx_ps_irq_rx_enable(const struct device * dev)998 static void uart_xlnx_ps_irq_rx_enable(const struct device *dev)
999 {
1000 	struct uart_xlnx_ps_dev_data_t *dev_data = dev->data;
1001 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1002 
1003 	sys_write32(XUARTPS_IXR_RTRIG, reg_base + XUARTPS_IER_OFFSET);
1004 	if ((sys_read32(reg_base + XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY) == 0) {
1005 		/*
1006 		 * Enabling RX trigger interrupts does not cause an interrupt
1007 		 * if the FIFO already contains RX data.
1008 		 * Generate a soft interrupt and have it call the
1009 		 * callback function in timer isr context.
1010 		 */
1011 		k_timer_start(&dev_data->timer, K_NO_WAIT, K_NO_WAIT);
1012 	}
1013 }
1014 
1015 /**
1016  * @brief Disable RX interrupt in IER
1017  *
1018  * @param dev UART device struct
1019  */
uart_xlnx_ps_irq_rx_disable(const struct device * dev)1020 static void uart_xlnx_ps_irq_rx_disable(const struct device *dev)
1021 {
1022 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1023 
1024 	sys_write32(XUARTPS_IXR_RTRIG, reg_base + XUARTPS_IDR_OFFSET);
1025 }
1026 
1027 /**
1028  * @brief Check if Rx IRQ has been raised
1029  *
1030  * @param dev UART device struct
1031  *
1032  * @return 1 if an IRQ is ready, 0 otherwise
1033  */
uart_xlnx_ps_irq_rx_ready(const struct device * dev)1034 static int uart_xlnx_ps_irq_rx_ready(const struct device *dev)
1035 {
1036 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1037 	uint32_t reg_val = sys_read32(reg_base + XUARTPS_SR_OFFSET);
1038 
1039 	return (reg_val & XUARTPS_SR_RXEMPTY) == 0;
1040 }
1041 
1042 /**
1043  * @brief Enable error interrupt in IER
1044  *
1045  * @param dev UART device struct
1046  */
uart_xlnx_ps_irq_err_enable(const struct device * dev)1047 static void uart_xlnx_ps_irq_err_enable(const struct device *dev)
1048 {
1049 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1050 
1051 	sys_write32(XUARTPS_IXR_RBRK              /* [13] Receiver Break */
1052 			    | XUARTPS_IXR_TOVR    /* [12] Transmitter FIFO Overflow */
1053 			    | XUARTPS_IXR_TOUT    /* [8]  Receiver Timerout */
1054 			    | XUARTPS_IXR_PARITY  /* [7]  Parity Error */
1055 			    | XUARTPS_IXR_FRAMING /* [6]  Receiver Framing Error */
1056 			    | XUARTPS_IXR_RXOVR,  /* [5]  Receiver Overflow Error */
1057 		    reg_base + XUARTPS_IER_OFFSET);
1058 }
1059 
1060 /**
1061  * @brief Disable error interrupt in IER
1062  *
1063  * @param dev UART device struct
1064  *
1065  * @return 1 if an IRQ is ready, 0 otherwise
1066  */
uart_xlnx_ps_irq_err_disable(const struct device * dev)1067 static void uart_xlnx_ps_irq_err_disable(const struct device *dev)
1068 {
1069 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1070 
1071 	sys_write32(XUARTPS_IXR_RBRK              /* [13] Receiver Break */
1072 			    | XUARTPS_IXR_TOVR    /* [12] Transmitter FIFO Overflow */
1073 			    | XUARTPS_IXR_TOUT    /* [8]  Receiver Timerout */
1074 			    | XUARTPS_IXR_PARITY  /* [7]  Parity Error */
1075 			    | XUARTPS_IXR_FRAMING /* [6]  Receiver Framing Error */
1076 			    | XUARTPS_IXR_RXOVR,  /* [5]  Receiver Overflow Error */
1077 		    reg_base + XUARTPS_IDR_OFFSET);
1078 }
1079 
1080 /**
1081  * @brief Check if any IRQ is pending
1082  *
1083  * @param dev UART device struct
1084  *
1085  * @return 1 if an IRQ is pending, 0 otherwise
1086  */
uart_xlnx_ps_irq_is_pending(const struct device * dev)1087 static int uart_xlnx_ps_irq_is_pending(const struct device *dev)
1088 {
1089 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1090 	uint32_t reg_imr = sys_read32(reg_base + XUARTPS_IMR_OFFSET);
1091 	uint32_t reg_isr = sys_read32(reg_base + XUARTPS_ISR_OFFSET);
1092 
1093 	if ((reg_imr & reg_isr) != 0) {
1094 		return 1;
1095 	} else {
1096 		return 0;
1097 	}
1098 }
1099 
1100 /**
1101  * @brief Update cached contents of IIR
1102  *
1103  * @param dev UART device struct
1104  *
1105  * @return Always 1
1106  */
uart_xlnx_ps_irq_update(const struct device * dev)1107 static int uart_xlnx_ps_irq_update(const struct device *dev)
1108 {
1109 	uintptr_t reg_base = DEVICE_MMIO_GET(dev);
1110 
1111 	/* Clear RX/TX interrupts */
1112 	sys_write32(XUARTPS_IXR_TTRIG | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RTRIG,
1113 		    reg_base + XUARTPS_ISR_OFFSET);
1114 	return 1;
1115 }
1116 
1117 /**
1118  * @brief Set the callback function pointer for IRQ.
1119  *
1120  * @param dev UART device struct
1121  * @param cb Callback function pointer.
1122  */
uart_xlnx_ps_irq_callback_set(const struct device * dev,uart_irq_callback_user_data_t cb,void * cb_data)1123 static void uart_xlnx_ps_irq_callback_set(const struct device *dev,
1124 					  uart_irq_callback_user_data_t cb, void *cb_data)
1125 {
1126 	struct uart_xlnx_ps_dev_data_t *dev_data = dev->data;
1127 
1128 	dev_data->user_cb = cb;
1129 	dev_data->user_data = cb_data;
1130 }
1131 
1132 /**
1133  * @brief Interrupt ce routine.
1134  *
1135  * This simply calls the callback function, if one exists.
1136  *
1137  * @param arg Argument to ISR.
1138  */
uart_xlnx_ps_isr(const struct device * dev)1139 static void uart_xlnx_ps_isr(const struct device *dev)
1140 {
1141 	const struct uart_xlnx_ps_dev_data_t *data = dev->data;
1142 
1143 	if (data->user_cb) {
1144 		data->user_cb(dev, data->user_data);
1145 	}
1146 }
1147 #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
1148 
1149 static DEVICE_API(uart, uart_xlnx_ps_driver_api) = {
1150 	.poll_in = uart_xlnx_ps_poll_in,
1151 	.poll_out = uart_xlnx_ps_poll_out,
1152 	.err_check = uart_xlnx_ps_err_check,
1153 #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
1154 	.configure = uart_xlnx_ps_configure,
1155 	.config_get = uart_xlnx_ps_config_get,
1156 #endif
1157 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
1158 	.fifo_fill = uart_xlnx_ps_fifo_fill,
1159 	.fifo_read = uart_xlnx_ps_fifo_read,
1160 	.irq_tx_enable = uart_xlnx_ps_irq_tx_enable,
1161 	.irq_tx_disable = uart_xlnx_ps_irq_tx_disable,
1162 	.irq_tx_ready = uart_xlnx_ps_irq_tx_ready,
1163 	.irq_tx_complete = uart_xlnx_ps_irq_tx_complete,
1164 	.irq_rx_enable = uart_xlnx_ps_irq_rx_enable,
1165 	.irq_rx_disable = uart_xlnx_ps_irq_rx_disable,
1166 	.irq_rx_ready = uart_xlnx_ps_irq_rx_ready,
1167 	.irq_err_enable = uart_xlnx_ps_irq_err_enable,
1168 	.irq_err_disable = uart_xlnx_ps_irq_err_disable,
1169 	.irq_is_pending = uart_xlnx_ps_irq_is_pending,
1170 	.irq_update = uart_xlnx_ps_irq_update,
1171 	.irq_callback_set = uart_xlnx_ps_irq_callback_set,
1172 #endif
1173 };
1174 
1175 #ifdef CONFIG_UART_INTERRUPT_DRIVEN
1176 
1177 #define UART_XLNX_PS_IRQ_CONF_FUNC_SET(port) .irq_config_func = uart_xlnx_ps_irq_config_##port,
1178 
1179 #define UART_XLNX_PS_IRQ_CONF_FUNC(port)                                                           \
1180 	static void uart_xlnx_ps_irq_config_##port(const struct device *dev)                       \
1181 	{                                                                                          \
1182 		IRQ_CONNECT(DT_INST_IRQN(port), DT_INST_IRQ(port, priority), uart_xlnx_ps_isr,     \
1183 			    DEVICE_DT_INST_GET(port), 0);                                          \
1184 		irq_enable(DT_INST_IRQN(port));                                                    \
1185 	}
1186 
1187 #else
1188 
1189 #define UART_XLNX_PS_IRQ_CONF_FUNC_SET(port)
1190 #define UART_XLNX_PS_IRQ_CONF_FUNC(port)
1191 
1192 #endif /*CONFIG_UART_INTERRUPT_DRIVEN */
1193 
1194 #define UART_XLNX_PS_DEV_DATA(port)                                                                \
1195 	static struct uart_xlnx_ps_dev_data_t uart_xlnx_ps_dev_data_##port
1196 
1197 #if CONFIG_PINCTRL
1198 #define UART_XLNX_PS_PINCTRL_DEFINE(port) PINCTRL_DT_INST_DEFINE(port);
1199 #define UART_XLNX_PS_PINCTRL_INIT(port)   .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(port),
1200 #else
1201 #define UART_XLNX_PS_PINCTRL_DEFINE(port)
1202 #define UART_XLNX_PS_PINCTRL_INIT(port)
1203 #endif /* CONFIG_PINCTRL */
1204 
1205 #define UART_XLNX_PS_DEV_CFG(port)                                                                 \
1206 	static struct uart_xlnx_ps_dev_config uart_xlnx_ps_dev_cfg_##port = {                      \
1207 		DEVICE_MMIO_ROM_INIT(DT_DRV_INST(port)),                                           \
1208 		.sys_clk_freq = DT_INST_PROP(port, clock_frequency),                               \
1209 		.baud_rate = DT_INST_PROP(port, current_speed),                                    \
1210 		UART_XLNX_PS_IRQ_CONF_FUNC_SET(port) UART_XLNX_PS_PINCTRL_INIT(port)}
1211 
1212 #define UART_XLNX_PS_INIT(port)                                                                    \
1213 	DEVICE_DT_INST_DEFINE(port, uart_xlnx_ps_init, NULL, &uart_xlnx_ps_dev_data_##port,        \
1214 			      &uart_xlnx_ps_dev_cfg_##port, PRE_KERNEL_1,                          \
1215 			      CONFIG_SERIAL_INIT_PRIORITY, &uart_xlnx_ps_driver_api)
1216 
1217 #define UART_XLNX_INSTANTIATE(inst)                                                                \
1218 	UART_XLNX_PS_PINCTRL_DEFINE(inst)                                                          \
1219 	UART_XLNX_PS_IRQ_CONF_FUNC(inst);                                                          \
1220 	UART_XLNX_PS_DEV_DATA(inst);                                                               \
1221 	UART_XLNX_PS_DEV_CFG(inst);                                                                \
1222 	UART_XLNX_PS_INIT(inst);
1223 
1224 DT_INST_FOREACH_STATUS_OKAY(UART_XLNX_INSTANTIATE)
1225