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