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