Branch data Line data Source code
1 : : /* ns16550.c - NS16550D serial driver */
2 : :
3 : : #define DT_DRV_COMPAT ns16550
4 : :
5 : : /*
6 : : * Copyright (c) 2010, 2012-2015 Wind River Systems, Inc.
7 : : * Copyright (c) 2020-2023 Intel Corp.
8 : : *
9 : : * SPDX-License-Identifier: Apache-2.0
10 : : */
11 : :
12 : : /**
13 : : * @brief NS16550 Serial Driver
14 : : *
15 : : * This is the driver for the Intel NS16550 UART Chip used on the PC 386.
16 : : * It uses the SCCs in asynchronous mode only.
17 : : *
18 : : * Before individual UART port can be used, uart_ns16550_port_init() has to be
19 : : * called to setup the port.
20 : : */
21 : :
22 : : #include <errno.h>
23 : : #include <zephyr/kernel.h>
24 : : #include <zephyr/arch/cpu.h>
25 : : #include <zephyr/types.h>
26 : :
27 : : #include <zephyr/init.h>
28 : : #include <zephyr/toolchain.h>
29 : : #include <zephyr/linker/sections.h>
30 : : #include <zephyr/drivers/uart.h>
31 : : #include <zephyr/drivers/clock_control.h>
32 : : #include <zephyr/pm/policy.h>
33 : : #include <zephyr/sys/sys_io.h>
34 : : #include <zephyr/spinlock.h>
35 : : #include <zephyr/irq.h>
36 : :
37 : : #if defined(CONFIG_PINCTRL)
38 : : #include <zephyr/drivers/pinctrl.h>
39 : : #endif
40 : :
41 : : #include <zephyr/drivers/serial/uart_ns16550.h>
42 : : #include <zephyr/logging/log.h>
43 : :
44 : : LOG_MODULE_REGISTER(uart_ns16550, CONFIG_UART_LOG_LEVEL);
45 : :
46 : : #define UART_NS16550_PCP_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(pcp)
47 : : #define UART_NS16550_DLF_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(dlf)
48 : : #define UART_NS16550_DMAS_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(dmas)
49 : :
50 : : #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
51 : : BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
52 : : #include <zephyr/drivers/pcie/pcie.h>
53 : : #endif
54 : :
55 : : /* Is UART module 'resets' line property defined */
56 : : #define UART_NS16550_RESET_ENABLED DT_ANY_INST_HAS_PROP_STATUS_OKAY(resets)
57 : :
58 : : #if UART_NS16550_RESET_ENABLED
59 : : #include <zephyr/drivers/reset.h>
60 : : #endif
61 : :
62 : : #if defined(CONFIG_UART_ASYNC_API)
63 : : #include <zephyr/drivers/dma.h>
64 : : #include <assert.h>
65 : :
66 : : #if defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA)
67 : : #include <zephyr/drivers/dma/dma_intel_lpss.h>
68 : : #endif
69 : :
70 : : #endif
71 : :
72 : : /* If any node has property io-mapped set, we need to support IO port
73 : : * access in the code and device config struct.
74 : : *
75 : : * Note that DT_ANY_INST_HAS_PROP_STATUS_OKAY() always returns true
76 : : * as io-mapped property is considered always exists and present,
77 : : * even if its value is zero. Therefore we cannot use it, and has to
78 : : * resort to the follow helper to see if any okay nodes have io-mapped
79 : : * as 1.
80 : : */
81 : : #define UART_NS16550_DT_PROP_IOMAPPED_HELPER(inst, prop, def) \
82 : : DT_INST_PROP_OR(inst, prop, def) ||
83 : :
84 : : #define UART_NS16550_IOPORT_ENABLED \
85 : : (DT_INST_FOREACH_STATUS_OKAY_VARGS(UART_NS16550_DT_PROP_IOMAPPED_HELPER, io_mapped, 0) 0)
86 : :
87 : : /* register definitions */
88 : :
89 : : #define REG_THR 0x00 /* Transmitter holding reg. */
90 : : #define REG_RDR 0x00 /* Receiver data reg. */
91 : : #define REG_BRDL 0x00 /* Baud rate divisor (LSB) */
92 : : #define REG_BRDH 0x01 /* Baud rate divisor (MSB) */
93 : : #define REG_IER 0x01 /* Interrupt enable reg. */
94 : : #define REG_IIR 0x02 /* Interrupt ID reg. */
95 : : #define REG_FCR 0x02 /* FIFO control reg. */
96 : : #define REG_LCR 0x03 /* Line control reg. */
97 : : #define REG_MDC 0x04 /* Modem control reg. */
98 : : #define REG_LSR 0x05 /* Line status reg. */
99 : : #define REG_MSR 0x06 /* Modem status reg. */
100 : : #define REG_DLF 0xC0 /* Divisor Latch Fraction */
101 : : #define REG_PCP 0x200 /* PRV_CLOCK_PARAMS (Apollo Lake) */
102 : : #define REG_MDR1 0x08 /* Mode control reg. (TI_K3) */
103 : :
104 : : #if defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA)
105 : : #define REG_LPSS_SRC_TRAN 0xAF8 /* SRC Transfer LPSS DMA */
106 : : #define REG_LPSS_CLR_SRC_TRAN 0xB48 /* Clear SRC Tran LPSS DMA */
107 : : #define REG_LPSS_MST 0xB20 /* Mask SRC Transfer LPSS DMA */
108 : : #endif
109 : :
110 : : /* equates for interrupt enable register */
111 : :
112 : : #define IER_RXRDY 0x01 /* receiver data ready */
113 : : #define IER_TBE 0x02 /* transmit bit enable */
114 : : #define IER_LSR 0x04 /* line status interrupts */
115 : : #define IER_MSI 0x08 /* modem status interrupts */
116 : :
117 : : /* equates for interrupt identification register */
118 : :
119 : : #define IIR_MSTAT 0x00 /* modem status interrupt */
120 : : #define IIR_NIP 0x01 /* no interrupt pending */
121 : : #define IIR_THRE 0x02 /* transmit holding register empty interrupt */
122 : : #define IIR_RBRF 0x04 /* receiver buffer register full interrupt */
123 : : #define IIR_LS 0x06 /* receiver line status interrupt */
124 : : #define IIR_MASK 0x07 /* interrupt id bits mask */
125 : : #define IIR_ID 0x06 /* interrupt ID mask without NIP */
126 : : #define IIR_FE 0xC0 /* FIFO mode enabled */
127 : : #define IIR_CH 0x0C /* Character timeout*/
128 : :
129 : : /* equates for FIFO control register */
130 : :
131 : : #define FCR_FIFO 0x01 /* enable XMIT and RCVR FIFO */
132 : : #define FCR_RCVRCLR 0x02 /* clear RCVR FIFO */
133 : : #define FCR_XMITCLR 0x04 /* clear XMIT FIFO */
134 : :
135 : : /* equates for Apollo Lake clock control register (PRV_CLOCK_PARAMS) */
136 : :
137 : : #define PCP_UPDATE 0x80000000 /* update clock */
138 : : #define PCP_EN 0x00000001 /* enable clock output */
139 : :
140 : : /* Fields for TI K3 UART module */
141 : :
142 : : #define MDR1_MODE_SELECT_FIELD_MASK BIT_MASK(3)
143 : : #define MDR1_MODE_SELECT_FIELD_SHIFT BIT_MASK(0)
144 : :
145 : : /* Modes available for TI K3 UART module */
146 : :
147 : : #define MDR1_STD_MODE (0)
148 : : #define MDR1_SIR_MODE (1)
149 : : #define MDR1_UART_16X (2)
150 : : #define MDR1_UART_13X (3)
151 : : #define MDR1_MIR_MODE (4)
152 : : #define MDR1_FIR_MODE (5)
153 : : #define MDR1_CIR_MODE (6)
154 : : #define MDR1_DISABLE (7)
155 : :
156 : : /*
157 : : * Per PC16550D (Literature Number: SNLS378B):
158 : : *
159 : : * RXRDY, Mode 0: When in the 16450 Mode (FCR0 = 0) or in
160 : : * the FIFO Mode (FCR0 = 1, FCR3 = 0) and there is at least 1
161 : : * character in the RCVR FIFO or RCVR holding register, the
162 : : * RXRDY pin (29) will be low active. Once it is activated the
163 : : * RXRDY pin will go inactive when there are no more charac-
164 : : * ters in the FIFO or holding register.
165 : : *
166 : : * RXRDY, Mode 1: In the FIFO Mode (FCR0 = 1) when the
167 : : * FCR3 = 1 and the trigger level or the timeout has been
168 : : * reached, the RXRDY pin will go low active. Once it is acti-
169 : : * vated it will go inactive when there are no more characters
170 : : * in the FIFO or holding register.
171 : : *
172 : : * TXRDY, Mode 0: In the 16450 Mode (FCR0 = 0) or in the
173 : : * FIFO Mode (FCR0 = 1, FCR3 = 0) and there are no charac-
174 : : * ters in the XMIT FIFO or XMIT holding register, the TXRDY
175 : : * pin (24) will be low active. Once it is activated the TXRDY
176 : : * pin will go inactive after the first character is loaded into the
177 : : * XMIT FIFO or holding register.
178 : : *
179 : : * TXRDY, Mode 1: In the FIFO Mode (FCR0 = 1) when
180 : : * FCR3 = 1 and there are no characters in the XMIT FIFO, the
181 : : * TXRDY pin will go low active. This pin will become inactive
182 : : * when the XMIT FIFO is completely full.
183 : : */
184 : : #define FCR_MODE0 0x00 /* set receiver in mode 0 */
185 : : #define FCR_MODE1 0x08 /* set receiver in mode 1 */
186 : :
187 : : /* RCVR FIFO interrupt levels: trigger interrupt with this bytes in FIFO */
188 : : #define FCR_FIFO_1 0x00 /* 1 byte in RCVR FIFO */
189 : : #define FCR_FIFO_4 0x40 /* 4 bytes in RCVR FIFO */
190 : : #define FCR_FIFO_8 0x80 /* 8 bytes in RCVR FIFO */
191 : : #define FCR_FIFO_14 0xC0 /* 14 bytes in RCVR FIFO */
192 : :
193 : : /*
194 : : * UART NS16750 supports 64 bytes FIFO, which can be enabled
195 : : * via the FCR register
196 : : */
197 : : #define FCR_FIFO_64 0x20 /* Enable 64 bytes FIFO */
198 : :
199 : : /* constants for line control register */
200 : :
201 : : #define LCR_CS5 0x00 /* 5 bits data size */
202 : : #define LCR_CS6 0x01 /* 6 bits data size */
203 : : #define LCR_CS7 0x02 /* 7 bits data size */
204 : : #define LCR_CS8 0x03 /* 8 bits data size */
205 : : #define LCR_2_STB 0x04 /* 2 stop bits */
206 : : #define LCR_1_STB 0x00 /* 1 stop bit */
207 : : #define LCR_PEN 0x08 /* parity enable */
208 : : #define LCR_PDIS 0x00 /* parity disable */
209 : : #define LCR_EPS 0x10 /* even parity select */
210 : : #define LCR_SP 0x20 /* stick parity select */
211 : : #define LCR_SBRK 0x40 /* break control bit */
212 : : #define LCR_DLAB 0x80 /* divisor latch access enable */
213 : :
214 : : /* constants for the modem control register */
215 : :
216 : : #define MCR_DTR 0x01 /* dtr output */
217 : : #define MCR_RTS 0x02 /* rts output */
218 : : #define MCR_OUT1 0x04 /* output #1 */
219 : : #define MCR_OUT2 0x08 /* output #2 */
220 : : #define MCR_LOOP 0x10 /* loop back */
221 : : #define MCR_AFCE 0x20 /* auto flow control enable */
222 : :
223 : : /* constants for line status register */
224 : :
225 : : #define LSR_RXRDY 0x01 /* receiver data available */
226 : : #define LSR_OE 0x02 /* overrun error */
227 : : #define LSR_PE 0x04 /* parity error */
228 : : #define LSR_FE 0x08 /* framing error */
229 : : #define LSR_BI 0x10 /* break interrupt */
230 : : #define LSR_EOB_MASK 0x1E /* Error or Break mask */
231 : : #define LSR_THRE 0x20 /* transmit holding register empty */
232 : : #define LSR_TEMT 0x40 /* transmitter empty */
233 : :
234 : : /* constants for modem status register */
235 : :
236 : : #define MSR_DCTS 0x01 /* cts change */
237 : : #define MSR_DDSR 0x02 /* dsr change */
238 : : #define MSR_DRI 0x04 /* ring change */
239 : : #define MSR_DDCD 0x08 /* data carrier change */
240 : : #define MSR_CTS 0x10 /* complement of cts */
241 : : #define MSR_DSR 0x20 /* complement of dsr */
242 : : #define MSR_RI 0x40 /* complement of ring signal */
243 : : #define MSR_DCD 0x80 /* complement of dcd */
244 : :
245 : : #define THR(dev) (get_port(dev) + (REG_THR * reg_interval(dev)))
246 : : #define RDR(dev) (get_port(dev) + (REG_RDR * reg_interval(dev)))
247 : : #define BRDL(dev) (get_port(dev) + (REG_BRDL * reg_interval(dev)))
248 : : #define BRDH(dev) (get_port(dev) + (REG_BRDH * reg_interval(dev)))
249 : : #define IER(dev) (get_port(dev) + (REG_IER * reg_interval(dev)))
250 : : #define IIR(dev) (get_port(dev) + (REG_IIR * reg_interval(dev)))
251 : : #define FCR(dev) (get_port(dev) + (REG_FCR * reg_interval(dev)))
252 : : #define LCR(dev) (get_port(dev) + (REG_LCR * reg_interval(dev)))
253 : : #define MDC(dev) (get_port(dev) + (REG_MDC * reg_interval(dev)))
254 : : #define LSR(dev) (get_port(dev) + (REG_LSR * reg_interval(dev)))
255 : : #define MSR(dev) (get_port(dev) + (REG_MSR * reg_interval(dev)))
256 : : #define MDR1(dev) (get_port(dev) + (REG_MDR1 * reg_interval(dev)))
257 : : #define DLF(dev) (get_port(dev) + REG_DLF)
258 : : #define PCP(dev) (get_port(dev) + REG_PCP)
259 : :
260 : : #if defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA)
261 : : #define SRC_TRAN(dev) (get_port(dev) + REG_LPSS_SRC_TRAN)
262 : : #define CLR_SRC_TRAN(dev) (get_port(dev) + REG_LPSS_CLR_SRC_TRAN)
263 : : #define MST(dev) (get_port(dev) + REG_LPSS_MST)
264 : :
265 : : #define UNMASK_LPSS_INT(chan) (BIT(chan) | (BIT(8) << chan)) /* unmask LPSS DMA Interrupt */
266 : : #endif
267 : :
268 : : #define IIRC(dev) (((struct uart_ns16550_dev_data *)(dev)->data)->iir_cache)
269 : :
270 : : #ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE
271 : : /* Register definitions (ITE_IT8XXX2) */
272 : : #define REG_ECSPMR 0x08 /* EC Serial port mode reg */
273 : :
274 : : /* Fields for ITE IT8XXX2 UART module */
275 : : #define ECSPMR_ECHS 0x02 /* EC high speed select */
276 : :
277 : : /* IT8XXX2 UART high speed baud rate settings */
278 : : #define UART_BAUDRATE_115200 115200
279 : : #define UART_BAUDRATE_230400 230400
280 : : #define UART_BAUDRATE_460800 460800
281 : : #define IT8XXX2_230400_DIVISOR 32770
282 : : #define IT8XXX2_460800_DIVISOR 32769
283 : :
284 : : #define ECSPMR(dev) (get_port(dev) + REG_ECSPMR * reg_interval(dev))
285 : : #endif
286 : :
287 : : #if defined(CONFIG_UART_ASYNC_API)
288 : : struct uart_ns16550_rx_dma_params {
289 : : const struct device *dma_dev;
290 : : uint8_t dma_channel;
291 : : struct dma_config dma_cfg;
292 : : struct dma_block_config active_dma_block;
293 : : uint8_t *buf;
294 : : size_t buf_len;
295 : : size_t offset;
296 : : size_t counter;
297 : : struct k_work_delayable timeout_work;
298 : : size_t timeout_us;
299 : : };
300 : :
301 : : struct uart_ns16550_tx_dma_params {
302 : : const struct device *dma_dev;
303 : : uint8_t dma_channel;
304 : : struct dma_config dma_cfg;
305 : : struct dma_block_config active_dma_block;
306 : : const uint8_t *buf;
307 : : size_t buf_len;
308 : : struct k_work_delayable timeout_work;
309 : : size_t timeout_us;
310 : : };
311 : :
312 : : struct uart_ns16550_async_data {
313 : : const struct device *uart_dev;
314 : : struct uart_ns16550_tx_dma_params tx_dma_params;
315 : : struct uart_ns16550_rx_dma_params rx_dma_params;
316 : : uint8_t *next_rx_buffer;
317 : : size_t next_rx_buffer_len;
318 : : uart_callback_t user_callback;
319 : : void *user_data;
320 : : };
321 : :
322 : : static void uart_ns16550_async_rx_timeout(struct k_work *work);
323 : : static void uart_ns16550_async_tx_timeout(struct k_work *work);
324 : : #endif
325 : :
326 : : /* device config */
327 : : struct uart_ns16550_device_config {
328 : : union {
329 : : DEVICE_MMIO_ROM;
330 : : uint32_t port;
331 : : };
332 : : uint32_t sys_clk_freq;
333 : : const struct device *clock_dev;
334 : : clock_control_subsys_t clock_subsys;
335 : : #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API)
336 : : uart_irq_config_func_t irq_config_func;
337 : : #endif
338 : : #if UART_NS16550_PCP_ENABLED
339 : : uint32_t pcp;
340 : : #endif
341 : : uint8_t reg_interval;
342 : : #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
343 : : struct pcie_dev *pcie;
344 : : #endif
345 : : #if defined(CONFIG_PINCTRL)
346 : : const struct pinctrl_dev_config *pincfg;
347 : : #endif
348 : : #if UART_NS16550_IOPORT_ENABLED
349 : : bool io_map;
350 : : #endif
351 : : #if UART_NS16550_RESET_ENABLED
352 : : struct reset_dt_spec reset_spec;
353 : : #endif
354 : : };
355 : :
356 : : /** Device data structure */
357 : : struct uart_ns16550_dev_data {
358 : : DEVICE_MMIO_RAM;
359 : : struct uart_config uart_config;
360 : : struct k_spinlock lock;
361 : : uint8_t fifo_size;
362 : :
363 : : #ifdef CONFIG_UART_INTERRUPT_DRIVEN
364 : : uint8_t iir_cache; /**< cache of IIR since it clears when read */
365 : : uart_irq_callback_user_data_t cb; /**< Callback function pointer */
366 : : void *cb_data; /**< Callback function arg */
367 : : #endif
368 : :
369 : : #if UART_NS16550_DLF_ENABLED
370 : : uint8_t dlf; /**< DLF value */
371 : : #endif
372 : :
373 : : #if defined(CONFIG_UART_INTERRUPT_DRIVEN) && defined(CONFIG_PM)
374 : : bool tx_stream_on;
375 : : #endif
376 : :
377 : : #if defined(CONFIG_UART_ASYNC_API)
378 : : uint64_t phys_addr;
379 : : struct uart_ns16550_async_data async;
380 : : #endif
381 : : };
382 : :
383 : 91012 : static void ns16550_outbyte(const struct uart_ns16550_device_config *cfg,
384 : : uintptr_t port, uint8_t val)
385 : : {
386 : : #if UART_NS16550_IOPORT_ENABLED
387 : : if (cfg->io_map) {
388 : : if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) {
389 : : sys_out32(val, port);
390 : : } else {
391 : : sys_out8(val, port);
392 : : }
393 : : } else {
394 : : #else
395 : : {
396 : : #endif
397 : : /* MMIO mapped */
398 : : if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) {
399 : : sys_write32(val, port);
400 : : } else {
401 : 91012 : sys_write8(val, port);
402 : : }
403 : : }
404 : 91012 : }
405 : :
406 : 1023608 : static uint8_t ns16550_inbyte(const struct uart_ns16550_device_config *cfg,
407 : : uintptr_t port)
408 : : {
409 : : #if UART_NS16550_IOPORT_ENABLED
410 : : if (cfg->io_map) {
411 : : if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) {
412 : : return sys_in32(port);
413 : : } else {
414 : : return sys_in8(port);
415 : : }
416 : : } else {
417 : : #else
418 : : {
419 : : #endif
420 : : /* MMIO mapped */
421 : : if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) {
422 : : return sys_read32(port);
423 : : } else {
424 : 1023608 : return sys_read8(port);
425 : : }
426 : : }
427 : : return 0;
428 : : }
429 : :
430 : : #if (defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA) & (defined(CONFIG_UART_ASYNC_API)))\
431 : : | UART_NS16550_PCP_ENABLED
432 : : static void ns16550_outword(const struct uart_ns16550_device_config *cfg,
433 : : uintptr_t port, uint32_t val)
434 : : {
435 : : #if UART_NS16550_IOPORT_ENABLED
436 : : if (cfg->io_map) {
437 : : sys_out32(val, port);
438 : : } else {
439 : : #else
440 : : {
441 : : #endif
442 : : /* MMIO mapped */
443 : : sys_write32(val, port);
444 : : }
445 : : }
446 : :
447 : : static uint32_t ns16550_inword(const struct uart_ns16550_device_config *cfg,
448 : : uintptr_t port)
449 : : {
450 : : #if UART_NS16550_IOPORT_ENABLED
451 : : if (cfg->io_map) {
452 : : return sys_in32(port);
453 : : }
454 : : #endif
455 : : /* MMIO mapped */
456 : : return sys_read32(port);
457 : : }
458 : : #endif
459 : :
460 : 1114620 : static inline uint8_t reg_interval(const struct device *dev)
461 : : {
462 : 1114620 : const struct uart_ns16550_device_config *config = dev->config;
463 : :
464 : 1114620 : return config->reg_interval;
465 : : }
466 : :
467 : 1114620 : static inline uintptr_t get_port(const struct device *dev)
468 : : {
469 : : uintptr_t port;
470 : : #if UART_NS16550_IOPORT_ENABLED
471 : : const struct uart_ns16550_device_config *config = dev->config;
472 : :
473 : : if (config->io_map) {
474 : : port = config->port;
475 : : } else {
476 : : #else
477 : : {
478 : : #endif
479 : 1114620 : port = DEVICE_MMIO_GET(dev);
480 : : }
481 : :
482 : 1114620 : return port;
483 : : }
484 : :
485 : 4 : static uint32_t get_uart_burdrate_divisor(const struct device *dev,
486 : : uint32_t baud_rate,
487 : : uint32_t pclk)
488 : : {
489 : : ARG_UNUSED(dev);
490 : : /*
491 : : * calculate baud rate divisor. a variant of
492 : : * (uint32_t)(pclk / (16.0 * baud_rate) + 0.5)
493 : : */
494 : 4 : return ((pclk + (baud_rate << 3)) / baud_rate) >> 4;
495 : : }
496 : :
497 : : #ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE
498 : : static uint32_t get_ite_uart_burdrate_divisor(const struct device *dev,
499 : : uint32_t baud_rate,
500 : : uint32_t pclk)
501 : : {
502 : : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
503 : : uint32_t divisor = 0;
504 : :
505 : : if (baud_rate > UART_BAUDRATE_115200) {
506 : : /* Baud rate divisor for high speed */
507 : : if (baud_rate == UART_BAUDRATE_230400) {
508 : : divisor = IT8XXX2_230400_DIVISOR;
509 : : } else if (baud_rate == UART_BAUDRATE_460800) {
510 : : divisor = IT8XXX2_460800_DIVISOR;
511 : : }
512 : : /*
513 : : * This bit indicates that the supported baud rate of
514 : : * UART1/UART2 can be up to 230.4k and 460.8k.
515 : : * Other bits are reserved and have no setting, so we
516 : : * directly write the ECSPMR register.
517 : : */
518 : : ns16550_outbyte(dev_cfg, ECSPMR(dev), ECSPMR_ECHS);
519 : : } else {
520 : : divisor = get_uart_burdrate_divisor(dev, baud_rate, pclk);
521 : : /* Set ECSPMR register as default */
522 : : ns16550_outbyte(dev_cfg, ECSPMR(dev), 0);
523 : : }
524 : :
525 : : return divisor;
526 : : }
527 : : #endif
528 : :
529 : 4 : static void set_baud_rate(const struct device *dev, uint32_t baud_rate, uint32_t pclk)
530 : : {
531 : 4 : struct uart_ns16550_dev_data * const dev_data = dev->data;
532 : 4 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
533 : : uint32_t divisor; /* baud rate divisor */
534 : : uint8_t lcr_cache;
535 : :
536 [ + - + - ]: 4 : if ((baud_rate != 0U) && (pclk != 0U)) {
537 : : #ifdef CONFIG_UART_NS16550_ITE_HIGH_SPEED_BUADRATE
538 : : divisor = get_ite_uart_burdrate_divisor(dev, baud_rate, pclk);
539 : : #else
540 : 4 : divisor = get_uart_burdrate_divisor(dev, baud_rate, pclk);
541 : : #endif
542 : : /* set the DLAB to access the baud rate divisor registers */
543 : 4 : lcr_cache = ns16550_inbyte(dev_cfg, LCR(dev));
544 : 4 : ns16550_outbyte(dev_cfg, LCR(dev), LCR_DLAB | lcr_cache);
545 : 4 : ns16550_outbyte(dev_cfg, BRDL(dev), (unsigned char)(divisor & 0xff));
546 : 4 : ns16550_outbyte(dev_cfg, BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));
547 : :
548 : : /* restore the DLAB to access the baud rate divisor registers */
549 : 4 : ns16550_outbyte(dev_cfg, LCR(dev), lcr_cache);
550 : :
551 : 4 : dev_data->uart_config.baudrate = baud_rate;
552 : : }
553 : 4 : }
554 : :
555 : 4 : static int uart_ns16550_configure(const struct device *dev,
556 : : const struct uart_config *cfg)
557 : : {
558 : 4 : struct uart_ns16550_dev_data * const dev_data = dev->data;
559 : 4 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
560 : 4 : uint8_t mdc = 0U;
561 : 4 : uint32_t pclk = 0U;
562 : :
563 : : /* temp for return value if error occurs in this locked region */
564 : 4 : int ret = 0;
565 : :
566 : 4 : k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
567 : :
568 : : #if defined(CONFIG_PINCTRL)
569 : : if (dev_cfg->pincfg != NULL) {
570 : : pinctrl_apply_state(dev_cfg->pincfg, PINCTRL_STATE_DEFAULT);
571 : : }
572 : : #endif
573 : :
574 : : #ifdef CONFIG_UART_INTERRUPT_DRIVEN
575 : 3 : dev_data->iir_cache = 0U;
576 : : #endif
577 : :
578 : : #if UART_NS16550_DLF_ENABLED
579 : : ns16550_outbyte(dev_cfg, DLF(dev), dev_data->dlf);
580 : : #endif
581 : :
582 : : #if UART_NS16550_PCP_ENABLED
583 : : uint32_t pcp = dev_cfg->pcp;
584 : :
585 : : if (pcp) {
586 : : pcp |= PCP_EN;
587 : : ns16550_outbyte(dev_cfg, PCP(dev), pcp & ~PCP_UPDATE);
588 : : ns16550_outbyte(dev_cfg, PCP(dev), pcp | PCP_UPDATE);
589 : : }
590 : : #endif
591 : :
592 : : #ifdef CONFIG_UART_NS16550_TI_K3
593 : : uint32_t mdr = ns16550_inbyte(dev_cfg, MDR1(dev));
594 : :
595 : : mdr = ((mdr & ~MDR1_MODE_SELECT_FIELD_MASK) | ((((MDR1_STD_MODE) <<
596 : : MDR1_MODE_SELECT_FIELD_SHIFT)) & MDR1_MODE_SELECT_FIELD_MASK));
597 : : ns16550_outbyte(dev_cfg, MDR1(dev), mdr);
598 : : #endif
599 : : /*
600 : : * set clock frequency from clock_frequency property if valid,
601 : : * otherwise, get clock frequency from clock manager
602 : : */
603 [ + - ]: 4 : if (dev_cfg->sys_clk_freq != 0U) {
604 : 4 : pclk = dev_cfg->sys_clk_freq;
605 : : } else {
606 [ # # ]: 0 : if (!device_is_ready(dev_cfg->clock_dev)) {
607 : 0 : ret = -EINVAL;
608 : 0 : goto out;
609 : : }
610 : :
611 [ # # ]: 0 : if (clock_control_get_rate(dev_cfg->clock_dev,
612 : 0 : dev_cfg->clock_subsys,
613 : : &pclk) != 0) {
614 : 0 : ret = -EINVAL;
615 : 0 : goto out;
616 : : }
617 : : }
618 : :
619 : 4 : set_baud_rate(dev, cfg->baudrate, pclk);
620 : :
621 : : /* Local structure to hold temporary values to pass to ns16550_outbyte() */
622 : : struct uart_config uart_cfg;
623 : :
624 [ - - - + : 4 : switch (cfg->data_bits) {
- ]
625 : 0 : case UART_CFG_DATA_BITS_5:
626 : 0 : uart_cfg.data_bits = LCR_CS5;
627 : 0 : break;
628 : 0 : case UART_CFG_DATA_BITS_6:
629 : 0 : uart_cfg.data_bits = LCR_CS6;
630 : 0 : break;
631 : 0 : case UART_CFG_DATA_BITS_7:
632 : 0 : uart_cfg.data_bits = LCR_CS7;
633 : 0 : break;
634 : 4 : case UART_CFG_DATA_BITS_8:
635 : 4 : uart_cfg.data_bits = LCR_CS8;
636 : 4 : break;
637 : 0 : default:
638 : 0 : ret = -ENOTSUP;
639 : 0 : goto out;
640 : : }
641 : :
642 [ + - - ]: 4 : switch (cfg->stop_bits) {
643 : 4 : case UART_CFG_STOP_BITS_1:
644 : 4 : uart_cfg.stop_bits = LCR_1_STB;
645 : 4 : break;
646 : 0 : case UART_CFG_STOP_BITS_2:
647 : 0 : uart_cfg.stop_bits = LCR_2_STB;
648 : 0 : break;
649 : 0 : default:
650 : 0 : ret = -ENOTSUP;
651 : 0 : goto out;
652 : : }
653 : :
654 [ + - - ]: 4 : switch (cfg->parity) {
655 : 4 : case UART_CFG_PARITY_NONE:
656 : 4 : uart_cfg.parity = LCR_PDIS;
657 : 4 : break;
658 : 0 : case UART_CFG_PARITY_EVEN:
659 : 0 : uart_cfg.parity = LCR_EPS;
660 : 0 : break;
661 : 0 : default:
662 : 0 : ret = -ENOTSUP;
663 : 0 : goto out;
664 : : }
665 : :
666 : 4 : dev_data->uart_config = *cfg;
667 : :
668 : : /* data bits, stop bits, parity, clear DLAB */
669 : 4 : ns16550_outbyte(dev_cfg, LCR(dev),
670 : 4 : uart_cfg.data_bits | uart_cfg.stop_bits | uart_cfg.parity);
671 : :
672 : 4 : mdc = MCR_OUT2 | MCR_RTS | MCR_DTR;
673 : : #if defined(CONFIG_UART_NS16550_VARIANT_NS16750) || \
674 : : defined(CONFIG_UART_NS16550_VARIANT_NS16950)
675 : : if (cfg->flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS) {
676 : : mdc |= MCR_AFCE;
677 : : }
678 : : #endif
679 : :
680 : 4 : ns16550_outbyte(dev_cfg, MDC(dev), mdc);
681 : :
682 : : /*
683 : : * Program FIFO: enabled, mode 0 (set for compatibility with quark),
684 : : * generate the interrupt at 8th byte
685 : : * Clear TX and RX FIFO
686 : : */
687 : 4 : ns16550_outbyte(dev_cfg, FCR(dev),
688 : : FCR_FIFO | FCR_MODE0 | FCR_FIFO_8 | FCR_RCVRCLR | FCR_XMITCLR
689 : : #ifdef CONFIG_UART_NS16550_VARIANT_NS16750
690 : : | FCR_FIFO_64
691 : : #endif
692 : : );
693 : :
694 [ + - ]: 4 : if ((ns16550_inbyte(dev_cfg, IIR(dev)) & IIR_FE) == IIR_FE) {
695 : : #ifdef CONFIG_UART_NS16550_VARIANT_NS16750
696 : : dev_data->fifo_size = 64;
697 : : #elif defined(CONFIG_UART_NS16550_VARIANT_NS16950)
698 : : dev_data->fifo_size = 128;
699 : : #else
700 : 4 : dev_data->fifo_size = 16;
701 : : #endif
702 : : } else {
703 : 0 : dev_data->fifo_size = 1;
704 : : }
705 : :
706 : : /* clear the port */
707 : 4 : ns16550_inbyte(dev_cfg, RDR(dev));
708 : :
709 : : /* disable interrupts */
710 : 4 : ns16550_outbyte(dev_cfg, IER(dev), 0x00);
711 : :
712 : 4 : out:
713 : 4 : k_spin_unlock(&dev_data->lock, key);
714 : 4 : return ret;
715 : : };
716 : :
717 : : #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
718 : 1 : static int uart_ns16550_config_get(const struct device *dev,
719 : : struct uart_config *cfg)
720 : : {
721 : 1 : struct uart_ns16550_dev_data *data = dev->data;
722 : :
723 : 1 : cfg->baudrate = data->uart_config.baudrate;
724 : 1 : cfg->parity = data->uart_config.parity;
725 : 1 : cfg->stop_bits = data->uart_config.stop_bits;
726 : 1 : cfg->data_bits = data->uart_config.data_bits;
727 : 1 : cfg->flow_ctrl = data->uart_config.flow_ctrl;
728 : :
729 : 1 : return 0;
730 : : }
731 : : #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
732 : :
733 : : #if UART_NS16550_RESET_ENABLED
734 : : /**
735 : : * @brief Toggle the reset UART line
736 : : *
737 : : * This routine is called to bring UART IP out of reset state.
738 : : *
739 : : * @param reset_spec Reset controller device configuration struct
740 : : *
741 : : * @return 0 if successful, failed otherwise
742 : : */
743 : : static int uart_reset_config(const struct reset_dt_spec *reset_spec)
744 : : {
745 : : int ret;
746 : :
747 : : if (!device_is_ready(reset_spec->dev)) {
748 : : LOG_ERR("Reset controller device is not ready");
749 : : return -ENODEV;
750 : : }
751 : :
752 : : ret = reset_line_toggle(reset_spec->dev, reset_spec->id);
753 : : if (ret != 0) {
754 : : LOG_ERR("UART toggle reset line failed");
755 : : return ret;
756 : : }
757 : :
758 : : return 0;
759 : : }
760 : : #endif /* UART_NS16550_RESET_ENABLED */
761 : :
762 : : #if (IS_ENABLED(CONFIG_UART_ASYNC_API))
763 : : static inline void async_timer_start(struct k_work_delayable *work, size_t timeout_us)
764 : : {
765 : : if ((timeout_us != SYS_FOREVER_US) && (timeout_us != 0)) {
766 : : k_work_reschedule(work, K_USEC(timeout_us));
767 : : }
768 : : }
769 : :
770 : : #endif
771 : :
772 : : /**
773 : : * @brief Initialize individual UART port
774 : : *
775 : : * This routine is called to reset the chip in a quiescent state.
776 : : *
777 : : * @param dev UART device struct
778 : : *
779 : : * @return 0 if successful, failed otherwise
780 : : */
781 : 2 : static int uart_ns16550_init(const struct device *dev)
782 : : {
783 : 2 : struct uart_ns16550_dev_data *data = dev->data;
784 : 2 : const struct uart_ns16550_device_config *dev_cfg = dev->config;
785 : : int ret;
786 : :
787 : : ARG_UNUSED(dev_cfg);
788 : :
789 : : #if UART_NS16550_RESET_ENABLED
790 : : /* Assert the UART reset line if it is defined. */
791 : : if (dev_cfg->reset_spec.dev != NULL) {
792 : : ret = uart_reset_config(&(dev_cfg->reset_spec));
793 : : if (ret != 0) {
794 : : return ret;
795 : : }
796 : : }
797 : : #endif
798 : :
799 : : #if DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie)
800 : : if (dev_cfg->pcie) {
801 : : struct pcie_bar mbar;
802 : :
803 : : if (dev_cfg->pcie->bdf == PCIE_BDF_NONE) {
804 : : return -EINVAL;
805 : : }
806 : :
807 : : pcie_probe_mbar(dev_cfg->pcie->bdf, 0, &mbar);
808 : : pcie_set_cmd(dev_cfg->pcie->bdf, PCIE_CONF_CMDSTAT_MEM, true);
809 : :
810 : : device_map(DEVICE_MMIO_RAM_PTR(dev), mbar.phys_addr, mbar.size,
811 : : K_MEM_CACHE_NONE);
812 : : #if defined(CONFIG_UART_ASYNC_API)
813 : : if (data->async.tx_dma_params.dma_dev != NULL) {
814 : : pcie_set_cmd(dev_cfg->pcie->bdf, PCIE_CONF_CMDSTAT_MASTER, true);
815 : : data->phys_addr = mbar.phys_addr;
816 : : }
817 : : #endif
818 : : } else
819 : : #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) */
820 : : {
821 : : #if UART_NS16550_IOPORT_ENABLED
822 : : /* Map directly from DTS */
823 : : if (!dev_cfg->io_map) {
824 : : #else
825 : : {
826 : : #endif
827 : : DEVICE_MMIO_MAP(dev, K_MEM_CACHE_NONE);
828 : : }
829 : : }
830 : : #if defined(CONFIG_UART_ASYNC_API)
831 : : if (data->async.tx_dma_params.dma_dev != NULL) {
832 : : data->async.next_rx_buffer = NULL;
833 : : data->async.next_rx_buffer_len = 0;
834 : : data->async.uart_dev = dev;
835 : : k_work_init_delayable(&data->async.rx_dma_params.timeout_work,
836 : : uart_ns16550_async_rx_timeout);
837 : : k_work_init_delayable(&data->async.tx_dma_params.timeout_work,
838 : : uart_ns16550_async_tx_timeout);
839 : : data->async.rx_dma_params.dma_cfg.head_block =
840 : : &data->async.rx_dma_params.active_dma_block;
841 : : data->async.tx_dma_params.dma_cfg.head_block =
842 : : &data->async.tx_dma_params.active_dma_block;
843 : : #if defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA)
844 : : #if UART_NS16550_IOPORT_ENABLED
845 : : if (!dev_cfg->io_map)
846 : : #endif
847 : : {
848 : : uintptr_t base;
849 : :
850 : : base = DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_OFFSET;
851 : : dma_intel_lpss_set_base(data->async.tx_dma_params.dma_dev, base);
852 : : dma_intel_lpss_setup(data->async.tx_dma_params.dma_dev);
853 : : sys_write32((uint32_t)data->phys_addr,
854 : : DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_REMAP_LOW);
855 : : sys_write32((uint32_t)(data->phys_addr >> DMA_INTEL_LPSS_ADDR_RIGHT_SHIFT),
856 : : DEVICE_MMIO_GET(dev) + DMA_INTEL_LPSS_REMAP_HI);
857 : : }
858 : : #endif
859 : : }
860 : : #endif
861 : 2 : ret = uart_ns16550_configure(dev, &data->uart_config);
862 [ - + ]: 2 : if (ret != 0) {
863 : 0 : return ret;
864 : : }
865 : :
866 : : #ifdef CONFIG_UART_INTERRUPT_DRIVEN
867 : 1 : dev_cfg->irq_config_func(dev);
868 : : #endif
869 : :
870 : 2 : return 0;
871 : : }
872 : :
873 : : /**
874 : : * @brief Poll the device for input.
875 : : *
876 : : * @param dev UART device struct
877 : : * @param c Pointer to character
878 : : *
879 : : * @return 0 if a character arrived, -1 if the input buffer if empty.
880 : : */
881 : 44147 : static int uart_ns16550_poll_in(const struct device *dev, unsigned char *c)
882 : : {
883 : 44147 : struct uart_ns16550_dev_data *data = dev->data;
884 : 44147 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
885 : 44147 : int ret = -1;
886 : 44147 : k_spinlock_key_t key = k_spin_lock(&data->lock);
887 : :
888 [ + + ]: 44147 : if ((ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_RXRDY) != 0) {
889 : : /* got a character */
890 : 10 : *c = ns16550_inbyte(dev_cfg, RDR(dev));
891 : 10 : ret = 0;
892 : : }
893 : :
894 : 44147 : k_spin_unlock(&data->lock, key);
895 : :
896 : 44147 : return ret;
897 : : }
898 : :
899 : : /**
900 : : * @brief Output a character in polled mode.
901 : : *
902 : : * Checks if the transmitter is empty. If empty, a character is written to
903 : : * the data register.
904 : : *
905 : : * If the hardware flow control is enabled then the handshake signal CTS has to
906 : : * be asserted in order to send a character.
907 : : *
908 : : * @param dev UART device struct
909 : : * @param c Character to send
910 : : */
911 : 90951 : static void uart_ns16550_poll_out(const struct device *dev,
912 : : unsigned char c)
913 : : {
914 : 90951 : struct uart_ns16550_dev_data *data = dev->data;
915 : 90951 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
916 : 90951 : k_spinlock_key_t key = k_spin_lock(&data->lock);
917 : :
918 [ + + ]: 979356 : while ((ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_THRE) == 0) {
919 : : }
920 : :
921 : 90951 : ns16550_outbyte(dev_cfg, THR(dev), c);
922 : :
923 : 90951 : k_spin_unlock(&data->lock, key);
924 : 90951 : }
925 : :
926 : : /**
927 : : * @brief Check if an error was received
928 : : *
929 : : * @param dev UART device struct
930 : : *
931 : : * @return one of UART_ERROR_OVERRUN, UART_ERROR_PARITY, UART_ERROR_FRAMING,
932 : : * UART_BREAK if an error was detected, 0 otherwise.
933 : : */
934 : 0 : static int uart_ns16550_err_check(const struct device *dev)
935 : : {
936 : 0 : struct uart_ns16550_dev_data *data = dev->data;
937 : 0 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
938 : 0 : k_spinlock_key_t key = k_spin_lock(&data->lock);
939 : 0 : int check = (ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_EOB_MASK);
940 : :
941 : 0 : k_spin_unlock(&data->lock, key);
942 : :
943 : 0 : return check >> 1;
944 : : }
945 : :
946 : : #if CONFIG_UART_INTERRUPT_DRIVEN
947 : :
948 : : /**
949 : : * @brief Fill FIFO with data
950 : : *
951 : : * @param dev UART device struct
952 : : * @param tx_data Data to transmit
953 : : * @param size Number of bytes to send
954 : : *
955 : : * @return Number of bytes sent
956 : : */
957 : 2 : static int uart_ns16550_fifo_fill(const struct device *dev,
958 : : const uint8_t *tx_data,
959 : : int size)
960 : : {
961 : 2 : struct uart_ns16550_dev_data *data = dev->data;
962 : 2 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
963 : : int i;
964 : 2 : k_spinlock_key_t key = k_spin_lock(&data->lock);
965 : :
966 [ + + + + ]: 24 : for (i = 0; (i < size) && (i < data->fifo_size); i++) {
967 : 22 : ns16550_outbyte(dev_cfg, THR(dev), tx_data[i]);
968 : : }
969 : :
970 : 2 : k_spin_unlock(&data->lock, key);
971 : :
972 : 2 : return i;
973 : : }
974 : :
975 : : /**
976 : : * @brief Read data from FIFO
977 : : *
978 : : * @param dev UART device struct
979 : : * @param rxData Data container
980 : : * @param size Container size
981 : : *
982 : : * @return Number of bytes read
983 : : */
984 : 25 : static int uart_ns16550_fifo_read(const struct device *dev, uint8_t *rx_data,
985 : : const int size)
986 : : {
987 : 25 : struct uart_ns16550_dev_data *data = dev->data;
988 : 25 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
989 : : int i;
990 : 25 : k_spinlock_key_t key = k_spin_lock(&data->lock);
991 : :
992 [ + + + + ]: 49 : for (i = 0; (i < size) && (ns16550_inbyte(dev_cfg, LSR(dev)) & LSR_RXRDY) != 0; i++) {
993 : 24 : rx_data[i] = ns16550_inbyte(dev_cfg, RDR(dev));
994 : : }
995 : :
996 : 25 : k_spin_unlock(&data->lock, key);
997 : :
998 : 25 : return i;
999 : : }
1000 : :
1001 : : /**
1002 : : * @brief Enable TX interrupt in IER
1003 : : *
1004 : : * @param dev UART device struct
1005 : : */
1006 : 1 : static void uart_ns16550_irq_tx_enable(const struct device *dev)
1007 : : {
1008 : 1 : struct uart_ns16550_dev_data *data = dev->data;
1009 : 1 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1010 : 1 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1011 : :
1012 : : #if defined(CONFIG_UART_INTERRUPT_DRIVEN) && defined(CONFIG_PM)
1013 : : struct uart_ns16550_dev_data *const dev_data = dev->data;
1014 : :
1015 : : if (!dev_data->tx_stream_on) {
1016 : : dev_data->tx_stream_on = true;
1017 : : uint8_t num_cpu_states;
1018 : : const struct pm_state_info *cpu_states;
1019 : :
1020 : : num_cpu_states = pm_state_cpu_get_all(0U, &cpu_states);
1021 : :
1022 : : /*
1023 : : * Power state to be disabled. Some platforms have multiple
1024 : : * states and need to be given a constraint set according to
1025 : : * different states.
1026 : : */
1027 : : for (uint8_t i = 0U; i < num_cpu_states; i++) {
1028 : : pm_policy_state_lock_get(cpu_states[i].state, PM_ALL_SUBSTATES);
1029 : : }
1030 : : }
1031 : : #endif
1032 : 1 : ns16550_outbyte(dev_cfg, IER(dev), ns16550_inbyte(dev_cfg, IER(dev)) | IER_TBE);
1033 : :
1034 : 1 : k_spin_unlock(&data->lock, key);
1035 : 1 : }
1036 : :
1037 : : /**
1038 : : * @brief Disable TX interrupt in IER
1039 : : *
1040 : : * @param dev UART device struct
1041 : : */
1042 : 3 : static void uart_ns16550_irq_tx_disable(const struct device *dev)
1043 : : {
1044 : 3 : struct uart_ns16550_dev_data *data = dev->data;
1045 : 3 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1046 : 3 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1047 : :
1048 : 6 : ns16550_outbyte(dev_cfg, IER(dev),
1049 : 3 : ns16550_inbyte(dev_cfg, IER(dev)) & (~IER_TBE));
1050 : :
1051 : : #if defined(CONFIG_UART_INTERRUPT_DRIVEN) && defined(CONFIG_PM)
1052 : : struct uart_ns16550_dev_data *const dev_data = dev->data;
1053 : :
1054 : : if (dev_data->tx_stream_on) {
1055 : : dev_data->tx_stream_on = false;
1056 : : uint8_t num_cpu_states;
1057 : : const struct pm_state_info *cpu_states;
1058 : :
1059 : : num_cpu_states = pm_state_cpu_get_all(0U, &cpu_states);
1060 : :
1061 : : /*
1062 : : * Power state to be enabled. Some platforms have multiple
1063 : : * states and need to be given a constraint release according
1064 : : * to different states.
1065 : : */
1066 : : for (uint8_t i = 0U; i < num_cpu_states; i++) {
1067 : : pm_policy_state_lock_put(cpu_states[i].state, PM_ALL_SUBSTATES);
1068 : : }
1069 : : }
1070 : : #endif
1071 : 3 : k_spin_unlock(&data->lock, key);
1072 : 3 : }
1073 : :
1074 : : /**
1075 : : * @brief Check if Tx IRQ has been raised
1076 : : *
1077 : : * @param dev UART device struct
1078 : : *
1079 : : * @return 1 if an IRQ is ready, 0 otherwise
1080 : : */
1081 : 25 : static int uart_ns16550_irq_tx_ready(const struct device *dev)
1082 : : {
1083 : 25 : struct uart_ns16550_dev_data *data = dev->data;
1084 : 25 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1085 : :
1086 : 25 : int ret = ((IIRC(dev) & IIR_ID) == IIR_THRE) ? 1 : 0;
1087 : :
1088 : 25 : k_spin_unlock(&data->lock, key);
1089 : :
1090 : 25 : return ret;
1091 : : }
1092 : :
1093 : : /**
1094 : : * @brief Check if nothing remains to be transmitted
1095 : : *
1096 : : * @param dev UART device struct
1097 : : *
1098 : : * @return 1 if nothing remains to be transmitted, 0 otherwise
1099 : : */
1100 : 0 : static int uart_ns16550_irq_tx_complete(const struct device *dev)
1101 : : {
1102 : 0 : struct uart_ns16550_dev_data *data = dev->data;
1103 : 0 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1104 : 0 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1105 : :
1106 : 0 : int ret = ((ns16550_inbyte(dev_cfg, LSR(dev)) & (LSR_TEMT | LSR_THRE))
1107 : 0 : == (LSR_TEMT | LSR_THRE)) ? 1 : 0;
1108 : :
1109 : 0 : k_spin_unlock(&data->lock, key);
1110 : :
1111 : 0 : return ret;
1112 : : }
1113 : :
1114 : : /**
1115 : : * @brief Enable RX interrupt in IER
1116 : : *
1117 : : * @param dev UART device struct
1118 : : */
1119 : 2 : static void uart_ns16550_irq_rx_enable(const struct device *dev)
1120 : : {
1121 : 2 : struct uart_ns16550_dev_data *data = dev->data;
1122 : 2 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1123 : 2 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1124 : :
1125 : 2 : ns16550_outbyte(dev_cfg, IER(dev), ns16550_inbyte(dev_cfg, IER(dev)) | IER_RXRDY);
1126 : :
1127 : 2 : k_spin_unlock(&data->lock, key);
1128 : 2 : }
1129 : :
1130 : : /**
1131 : : * @brief Disable RX interrupt in IER
1132 : : *
1133 : : * @param dev UART device struct
1134 : : */
1135 : 1 : static void uart_ns16550_irq_rx_disable(const struct device *dev)
1136 : : {
1137 : 1 : struct uart_ns16550_dev_data *data = dev->data;
1138 : 1 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1139 : 1 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1140 : :
1141 : 2 : ns16550_outbyte(dev_cfg, IER(dev),
1142 : 1 : ns16550_inbyte(dev_cfg, IER(dev)) & (~IER_RXRDY));
1143 : :
1144 : 1 : k_spin_unlock(&data->lock, key);
1145 : 1 : }
1146 : :
1147 : : /**
1148 : : * @brief Check if Rx IRQ has been raised
1149 : : *
1150 : : * @param dev UART device struct
1151 : : *
1152 : : * @return 1 if an IRQ is ready, 0 otherwise
1153 : : */
1154 : 26 : static int uart_ns16550_irq_rx_ready(const struct device *dev)
1155 : : {
1156 : 26 : struct uart_ns16550_dev_data *data = dev->data;
1157 : 26 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1158 : :
1159 : 26 : int ret = ((IIRC(dev) & IIR_ID) == IIR_RBRF) ? 1 : 0;
1160 : :
1161 : 26 : k_spin_unlock(&data->lock, key);
1162 : :
1163 : 26 : return ret;
1164 : : }
1165 : :
1166 : : /**
1167 : : * @brief Enable error interrupt in IER
1168 : : *
1169 : : * @param dev UART device struct
1170 : : */
1171 : 0 : static void uart_ns16550_irq_err_enable(const struct device *dev)
1172 : : {
1173 : 0 : struct uart_ns16550_dev_data *data = dev->data;
1174 : 0 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1175 : 0 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1176 : :
1177 : 0 : ns16550_outbyte(dev_cfg, IER(dev),
1178 : 0 : ns16550_inbyte(dev_cfg, IER(dev)) | IER_LSR);
1179 : :
1180 : 0 : k_spin_unlock(&data->lock, key);
1181 : 0 : }
1182 : :
1183 : : /**
1184 : : * @brief Disable error interrupt in IER
1185 : : *
1186 : : * @param dev UART device struct
1187 : : *
1188 : : * @return 1 if an IRQ is ready, 0 otherwise
1189 : : */
1190 : 0 : static void uart_ns16550_irq_err_disable(const struct device *dev)
1191 : : {
1192 : 0 : struct uart_ns16550_dev_data *data = dev->data;
1193 : 0 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1194 : 0 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1195 : :
1196 : 0 : ns16550_outbyte(dev_cfg, IER(dev),
1197 : 0 : ns16550_inbyte(dev_cfg, IER(dev)) & (~IER_LSR));
1198 : :
1199 : 0 : k_spin_unlock(&data->lock, key);
1200 : 0 : }
1201 : :
1202 : : /**
1203 : : * @brief Check if any IRQ is pending
1204 : : *
1205 : : * @param dev UART device struct
1206 : : *
1207 : : * @return 1 if an IRQ is pending, 0 otherwise
1208 : : */
1209 : 2 : static int uart_ns16550_irq_is_pending(const struct device *dev)
1210 : : {
1211 : 2 : struct uart_ns16550_dev_data *data = dev->data;
1212 : 2 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1213 : :
1214 : 2 : int ret = (!(IIRC(dev) & IIR_NIP)) ? 1 : 0;
1215 : :
1216 : 2 : k_spin_unlock(&data->lock, key);
1217 : :
1218 : 2 : return ret;
1219 : : }
1220 : :
1221 : : /**
1222 : : * @brief Update cached contents of IIR
1223 : : *
1224 : : * @param dev UART device struct
1225 : : *
1226 : : * @return Always 1
1227 : : */
1228 : 27 : static int uart_ns16550_irq_update(const struct device *dev)
1229 : : {
1230 : 27 : struct uart_ns16550_dev_data *data = dev->data;
1231 : 27 : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1232 : 27 : k_spinlock_key_t key = k_spin_lock(&data->lock);
1233 : :
1234 : 27 : IIRC(dev) = ns16550_inbyte(dev_cfg, IIR(dev));
1235 : :
1236 : 27 : k_spin_unlock(&data->lock, key);
1237 : :
1238 : 27 : return 1;
1239 : : }
1240 : :
1241 : : /**
1242 : : * @brief Set the callback function pointer for IRQ.
1243 : : *
1244 : : * @param dev UART device struct
1245 : : * @param cb Callback function pointer.
1246 : : */
1247 : 3 : static void uart_ns16550_irq_callback_set(const struct device *dev,
1248 : : uart_irq_callback_user_data_t cb,
1249 : : void *cb_data)
1250 : : {
1251 : 3 : struct uart_ns16550_dev_data * const dev_data = dev->data;
1252 : 3 : k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
1253 : :
1254 : 3 : dev_data->cb = cb;
1255 : 3 : dev_data->cb_data = cb_data;
1256 : :
1257 : 3 : k_spin_unlock(&dev_data->lock, key);
1258 : 3 : }
1259 : :
1260 : : /**
1261 : : * @brief Interrupt service routine.
1262 : : *
1263 : : * This simply calls the callback function, if one exists.
1264 : : *
1265 : : * @param arg Argument to ISR.
1266 : : */
1267 : 26 : static void uart_ns16550_isr(const struct device *dev)
1268 : : {
1269 : 26 : struct uart_ns16550_dev_data * const dev_data = dev->data;
1270 : :
1271 [ + - ]: 26 : if (dev_data->cb) {
1272 : 26 : dev_data->cb(dev, dev_data->cb_data);
1273 : : }
1274 : : #if (IS_ENABLED(CONFIG_UART_ASYNC_API))
1275 : : if (dev_data->async.tx_dma_params.dma_dev != NULL) {
1276 : : const struct uart_ns16550_device_config * const config = dev->config;
1277 : : uint8_t IIR_status = ns16550_inbyte(config, IIR(dev));
1278 : : #if (IS_ENABLED(CONFIG_UART_NS16550_INTEL_LPSS_DMA))
1279 : : uint32_t dma_status = ns16550_inword(config, SRC_TRAN(dev));
1280 : :
1281 : : if (dma_status & BIT(dev_data->async.rx_dma_params.dma_channel)) {
1282 : : async_timer_start(&dev_data->async.rx_dma_params.timeout_work,
1283 : : dev_data->async.rx_dma_params.timeout_us);
1284 : : ns16550_outword(config, CLR_SRC_TRAN(dev),
1285 : : BIT(dev_data->async.rx_dma_params.dma_channel));
1286 : : return;
1287 : : }
1288 : : dma_intel_lpss_isr(dev_data->async.rx_dma_params.dma_dev);
1289 : : #endif
1290 : : if (IIR_status & IIR_RBRF) {
1291 : : async_timer_start(&dev_data->async.rx_dma_params.timeout_work,
1292 : : dev_data->async.rx_dma_params.timeout_us);
1293 : : return;
1294 : : }
1295 : : }
1296 : : #endif
1297 : :
1298 : : #ifdef CONFIG_UART_NS16550_WA_ISR_REENABLE_INTERRUPT
1299 : : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1300 : : uint8_t cached_ier = ns16550_inbyte(dev_cfg, IER(dev));
1301 : :
1302 : : ns16550_outbyte(dev_cfg, IER(dev), 0U);
1303 : : ns16550_outbyte(dev_cfg, IER(dev), cached_ier);
1304 : : #endif
1305 : 26 : }
1306 : :
1307 : : #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
1308 : :
1309 : : #ifdef CONFIG_UART_NS16550_LINE_CTRL
1310 : :
1311 : : /**
1312 : : * @brief Manipulate line control for UART.
1313 : : *
1314 : : * @param dev UART device struct
1315 : : * @param ctrl The line control to be manipulated
1316 : : * @param val Value to set the line control
1317 : : *
1318 : : * @return 0 if successful, failed otherwise
1319 : : */
1320 : : static int uart_ns16550_line_ctrl_set(const struct device *dev,
1321 : : uint32_t ctrl, uint32_t val)
1322 : : {
1323 : : struct uart_ns16550_dev_data *data = dev->data;
1324 : : const struct uart_ns16550_device_config *const dev_cfg = dev->config;
1325 : : uint32_t mdc, chg, pclk = 0U;
1326 : : k_spinlock_key_t key;
1327 : :
1328 : : if (dev_cfg->sys_clk_freq != 0U) {
1329 : : pclk = dev_cfg->sys_clk_freq;
1330 : : } else {
1331 : : if (device_is_ready(dev_cfg->clock_dev)) {
1332 : : clock_control_get_rate(dev_cfg->clock_dev, dev_cfg->clock_subsys, &pclk);
1333 : : }
1334 : : }
1335 : :
1336 : : switch (ctrl) {
1337 : : case UART_LINE_CTRL_BAUD_RATE:
1338 : : set_baud_rate(dev, val, pclk);
1339 : : return 0;
1340 : :
1341 : : case UART_LINE_CTRL_RTS:
1342 : : case UART_LINE_CTRL_DTR:
1343 : : key = k_spin_lock(&data->lock);
1344 : : mdc = ns16550_inbyte(dev_cfg, MDC(dev));
1345 : :
1346 : : if (ctrl == UART_LINE_CTRL_RTS) {
1347 : : chg = MCR_RTS;
1348 : : } else {
1349 : : chg = MCR_DTR;
1350 : : }
1351 : :
1352 : : if (val) {
1353 : : mdc |= chg;
1354 : : } else {
1355 : : mdc &= ~(chg);
1356 : : }
1357 : : ns16550_outbyte(dev_cfg, MDC(dev), mdc);
1358 : : k_spin_unlock(&data->lock, key);
1359 : : return 0;
1360 : : }
1361 : :
1362 : : return -ENOTSUP;
1363 : : }
1364 : :
1365 : : #endif /* CONFIG_UART_NS16550_LINE_CTRL */
1366 : :
1367 : : #ifdef CONFIG_UART_NS16550_DRV_CMD
1368 : :
1369 : : /**
1370 : : * @brief Send extra command to driver
1371 : : *
1372 : : * @param dev UART device struct
1373 : : * @param cmd Command to driver
1374 : : * @param p Parameter to the command
1375 : : *
1376 : : * @return 0 if successful, failed otherwise
1377 : : */
1378 : : static int uart_ns16550_drv_cmd(const struct device *dev, uint32_t cmd,
1379 : : uint32_t p)
1380 : : {
1381 : : #if UART_NS16550_DLF_ENABLED
1382 : : if (cmd == CMD_SET_DLF) {
1383 : : struct uart_ns16550_dev_data * const dev_data = dev->data;
1384 : : const struct uart_ns16550_device_config * const dev_cfg = dev->config;
1385 : : k_spinlock_key_t key = k_spin_lock(&dev_data->lock);
1386 : :
1387 : : dev_data->dlf = p;
1388 : : ns16550_outbyte(dev_cfg, DLF(dev), dev_data->dlf);
1389 : : k_spin_unlock(&dev_data->lock, key);
1390 : : return 0;
1391 : : }
1392 : : #endif
1393 : :
1394 : : return -ENOTSUP;
1395 : : }
1396 : :
1397 : : #endif /* CONFIG_UART_NS16550_DRV_CMD */
1398 : :
1399 : : #if (IS_ENABLED(CONFIG_UART_ASYNC_API))
1400 : : static void async_user_callback(const struct device *dev, struct uart_event *evt)
1401 : : {
1402 : : const struct uart_ns16550_dev_data *data = dev->data;
1403 : :
1404 : : if (data->async.user_callback) {
1405 : : data->async.user_callback(dev, evt, data->async.user_data);
1406 : : }
1407 : : }
1408 : :
1409 : : #if UART_NS16550_DMAS_ENABLED
1410 : : static void async_evt_tx_done(struct device *dev)
1411 : : {
1412 : : struct uart_ns16550_dev_data *data = dev->data;
1413 : : struct uart_ns16550_tx_dma_params *tx_params = &data->async.tx_dma_params;
1414 : :
1415 : : (void)k_work_cancel_delayable(&data->async.tx_dma_params.timeout_work);
1416 : :
1417 : : struct uart_event event = {
1418 : : .type = UART_TX_DONE,
1419 : : .data.tx.buf = tx_params->buf,
1420 : : .data.tx.len = tx_params->buf_len
1421 : : };
1422 : :
1423 : : tx_params->buf = NULL;
1424 : : tx_params->buf_len = 0U;
1425 : :
1426 : : async_user_callback(dev, &event);
1427 : : }
1428 : : #endif
1429 : :
1430 : : static void async_evt_rx_rdy(const struct device *dev)
1431 : : {
1432 : : struct uart_ns16550_dev_data *data = dev->data;
1433 : : struct uart_ns16550_rx_dma_params *dma_params = &data->async.rx_dma_params;
1434 : :
1435 : : struct uart_event event = {
1436 : : .type = UART_RX_RDY,
1437 : : .data.rx.buf = dma_params->buf,
1438 : : .data.rx.len = dma_params->counter - dma_params->offset,
1439 : : .data.rx.offset = dma_params->offset
1440 : : };
1441 : :
1442 : : dma_params->offset = dma_params->counter;
1443 : :
1444 : : if (event.data.rx.len > 0) {
1445 : : async_user_callback(dev, &event);
1446 : : }
1447 : : }
1448 : :
1449 : : static void async_evt_rx_buf_release(const struct device *dev)
1450 : : {
1451 : : struct uart_ns16550_dev_data *data = (struct uart_ns16550_dev_data *)dev->data;
1452 : : struct uart_event evt = {
1453 : : .type = UART_RX_BUF_RELEASED,
1454 : : .data.rx_buf.buf = data->async.rx_dma_params.buf
1455 : : };
1456 : :
1457 : : async_user_callback(dev, &evt);
1458 : : data->async.rx_dma_params.buf = NULL;
1459 : : data->async.rx_dma_params.buf_len = 0U;
1460 : : data->async.rx_dma_params.offset = 0U;
1461 : : data->async.rx_dma_params.counter = 0U;
1462 : : }
1463 : :
1464 : : static void async_evt_rx_buf_request(const struct device *dev)
1465 : : {
1466 : : struct uart_event evt = {
1467 : : .type = UART_RX_BUF_REQUEST
1468 : : };
1469 : : async_user_callback(dev, &evt);
1470 : : }
1471 : :
1472 : : static void uart_ns16550_async_rx_flush(const struct device *dev)
1473 : : {
1474 : : struct uart_ns16550_dev_data *data = dev->data;
1475 : : struct uart_ns16550_rx_dma_params *dma_params = &data->async.rx_dma_params;
1476 : : struct dma_status status;
1477 : :
1478 : : dma_get_status(dma_params->dma_dev,
1479 : : dma_params->dma_channel,
1480 : : &status);
1481 : :
1482 : : const int rx_count = dma_params->buf_len - status.pending_length;
1483 : :
1484 : : if (rx_count > dma_params->counter) {
1485 : : dma_params->counter = rx_count;
1486 : : async_evt_rx_rdy(dev);
1487 : : }
1488 : : }
1489 : :
1490 : : static int uart_ns16550_rx_disable(const struct device *dev)
1491 : : {
1492 : : struct uart_ns16550_dev_data *data = (struct uart_ns16550_dev_data *)dev->data;
1493 : : struct uart_ns16550_rx_dma_params *dma_params = &data->async.rx_dma_params;
1494 : : k_spinlock_key_t key = k_spin_lock(&data->lock);
1495 : : int ret = 0;
1496 : :
1497 : : if (!device_is_ready(dma_params->dma_dev)) {
1498 : : ret = -ENODEV;
1499 : : goto out;
1500 : : }
1501 : :
1502 : : (void)k_work_cancel_delayable(&data->async.rx_dma_params.timeout_work);
1503 : :
1504 : : if (dma_params->buf && (dma_params->buf_len > 0)) {
1505 : : uart_ns16550_async_rx_flush(dev);
1506 : : async_evt_rx_buf_release(dev);
1507 : : if (data->async.next_rx_buffer != NULL) {
1508 : : dma_params->buf = data->async.next_rx_buffer;
1509 : : dma_params->buf_len = data->async.next_rx_buffer_len;
1510 : : data->async.next_rx_buffer = NULL;
1511 : : data->async.next_rx_buffer_len = 0;
1512 : : async_evt_rx_buf_release(dev);
1513 : : }
1514 : : }
1515 : : ret = dma_stop(dma_params->dma_dev,
1516 : : dma_params->dma_channel);
1517 : :
1518 : : struct uart_event event = {
1519 : : .type = UART_RX_DISABLED
1520 : : };
1521 : :
1522 : : async_user_callback(dev, &event);
1523 : :
1524 : : out:
1525 : : k_spin_unlock(&data->lock, key);
1526 : : return ret;
1527 : : }
1528 : :
1529 : : static void prepare_rx_dma_block_config(const struct device *dev)
1530 : : {
1531 : : struct uart_ns16550_dev_data *data = (struct uart_ns16550_dev_data *)dev->data;
1532 : : struct uart_ns16550_rx_dma_params *rx_dma_params = &data->async.rx_dma_params;
1533 : :
1534 : : assert(rx_dma_params->buf != NULL);
1535 : : assert(rx_dma_params->buf_len > 0);
1536 : :
1537 : : struct dma_block_config *head_block_config = &rx_dma_params->active_dma_block;
1538 : :
1539 : : head_block_config->dest_address = (uintptr_t)rx_dma_params->buf;
1540 : : head_block_config->source_address = data->phys_addr;
1541 : : head_block_config->block_size = rx_dma_params->buf_len;
1542 : : }
1543 : :
1544 : : #if UART_NS16550_DMAS_ENABLED
1545 : : static void dma_callback(const struct device *dev, void *user_data, uint32_t channel,
1546 : : int status)
1547 : : {
1548 : : struct device *uart_dev = (struct device *)user_data;
1549 : : struct uart_ns16550_dev_data *data = (struct uart_ns16550_dev_data *)uart_dev->data;
1550 : : struct uart_ns16550_rx_dma_params *rx_params = &data->async.rx_dma_params;
1551 : : struct uart_ns16550_tx_dma_params *tx_params = &data->async.tx_dma_params;
1552 : :
1553 : : if (channel == tx_params->dma_channel) {
1554 : : async_evt_tx_done(uart_dev);
1555 : : } else if (channel == rx_params->dma_channel) {
1556 : :
1557 : : rx_params->counter = rx_params->buf_len;
1558 : :
1559 : : async_evt_rx_rdy(uart_dev);
1560 : : async_evt_rx_buf_release(uart_dev);
1561 : :
1562 : : rx_params->buf = data->async.next_rx_buffer;
1563 : : rx_params->buf_len = data->async.next_rx_buffer_len;
1564 : : data->async.next_rx_buffer = NULL;
1565 : : data->async.next_rx_buffer_len = 0U;
1566 : :
1567 : : if (rx_params->buf != NULL &&
1568 : : rx_params->buf_len > 0) {
1569 : : dma_reload(dev, rx_params->dma_channel, data->phys_addr,
1570 : : (uintptr_t)rx_params->buf, rx_params->buf_len);
1571 : : dma_start(dev, rx_params->dma_channel);
1572 : : async_evt_rx_buf_request(uart_dev);
1573 : : } else {
1574 : : uart_ns16550_rx_disable(uart_dev);
1575 : : }
1576 : : }
1577 : : }
1578 : : #endif
1579 : :
1580 : : static int uart_ns16550_callback_set(const struct device *dev, uart_callback_t callback,
1581 : : void *user_data)
1582 : : {
1583 : : struct uart_ns16550_dev_data *data = dev->data;
1584 : :
1585 : : data->async.user_callback = callback;
1586 : : data->async.user_data = user_data;
1587 : :
1588 : : return 0;
1589 : : }
1590 : :
1591 : : static int uart_ns16550_tx(const struct device *dev, const uint8_t *buf, size_t len,
1592 : : int32_t timeout_us)
1593 : : {
1594 : : struct uart_ns16550_dev_data *data = dev->data;
1595 : : struct uart_ns16550_tx_dma_params *tx_params = &data->async.tx_dma_params;
1596 : : k_spinlock_key_t key = k_spin_lock(&data->lock);
1597 : : int ret = 0;
1598 : :
1599 : : if (!device_is_ready(tx_params->dma_dev)) {
1600 : : ret = -ENODEV;
1601 : : goto out;
1602 : : }
1603 : :
1604 : : tx_params->buf = buf;
1605 : : tx_params->buf_len = len;
1606 : : tx_params->active_dma_block.source_address = (uintptr_t)buf;
1607 : : tx_params->active_dma_block.dest_address = data->phys_addr;
1608 : : tx_params->active_dma_block.block_size = len;
1609 : : tx_params->active_dma_block.next_block = NULL;
1610 : :
1611 : : ret = dma_config(tx_params->dma_dev,
1612 : : tx_params->dma_channel,
1613 : : (struct dma_config *)&tx_params->dma_cfg);
1614 : :
1615 : : if (ret == 0) {
1616 : : ret = dma_start(tx_params->dma_dev,
1617 : : tx_params->dma_channel);
1618 : : if (ret) {
1619 : : ret = -EIO;
1620 : : goto out;
1621 : : }
1622 : : async_timer_start(&data->async.tx_dma_params.timeout_work, timeout_us);
1623 : : }
1624 : :
1625 : : out:
1626 : : k_spin_unlock(&data->lock, key);
1627 : : return ret;
1628 : : }
1629 : :
1630 : : static int uart_ns16550_tx_abort(const struct device *dev)
1631 : : {
1632 : : struct uart_ns16550_dev_data *data = dev->data;
1633 : : struct uart_ns16550_tx_dma_params *tx_params = &data->async.tx_dma_params;
1634 : : struct dma_status status;
1635 : : int ret = 0;
1636 : : size_t bytes_tx;
1637 : :
1638 : : k_spinlock_key_t key = k_spin_lock(&data->lock);
1639 : :
1640 : : if (!device_is_ready(tx_params->dma_dev)) {
1641 : : ret = -ENODEV;
1642 : : goto out;
1643 : : }
1644 : :
1645 : : (void)k_work_cancel_delayable(&data->async.tx_dma_params.timeout_work);
1646 : :
1647 : : ret = dma_stop(tx_params->dma_dev, tx_params->dma_channel);
1648 : : dma_get_status(tx_params->dma_dev,
1649 : : tx_params->dma_channel,
1650 : : &status);
1651 : : bytes_tx = tx_params->buf_len - status.pending_length;
1652 : :
1653 : : if (ret == 0) {
1654 : : struct uart_event tx_aborted_event = {
1655 : : .type = UART_TX_ABORTED,
1656 : : .data.tx.buf = tx_params->buf,
1657 : : .data.tx.len = bytes_tx
1658 : : };
1659 : : async_user_callback(dev, &tx_aborted_event);
1660 : : }
1661 : : out:
1662 : : k_spin_unlock(&data->lock, key);
1663 : : return ret;
1664 : : }
1665 : :
1666 : : static int uart_ns16550_rx_enable(const struct device *dev, uint8_t *buf, const size_t len,
1667 : : const int32_t timeout_us)
1668 : : {
1669 : : struct uart_ns16550_dev_data *data = dev->data;
1670 : : const struct uart_ns16550_device_config *config = dev->config;
1671 : : struct uart_ns16550_rx_dma_params *rx_dma_params = &data->async.rx_dma_params;
1672 : : int ret = 0;
1673 : : k_spinlock_key_t key = k_spin_lock(&data->lock);
1674 : :
1675 : : if (!device_is_ready(rx_dma_params->dma_dev)) {
1676 : : ret = -ENODEV;
1677 : : goto out;
1678 : : }
1679 : :
1680 : : rx_dma_params->timeout_us = timeout_us;
1681 : : rx_dma_params->buf = buf;
1682 : : rx_dma_params->buf_len = len;
1683 : :
1684 : : #if defined(CONFIG_UART_NS16550_INTEL_LPSS_DMA)
1685 : : ns16550_outword(config, MST(dev), UNMASK_LPSS_INT(rx_dma_params->dma_channel));
1686 : : #else
1687 : : ns16550_outbyte(config, IER(dev),
1688 : : (ns16550_inbyte(config, IER(dev)) | IER_RXRDY));
1689 : : ns16550_outbyte(config, FCR(dev), FCR_FIFO);
1690 : : #endif
1691 : : prepare_rx_dma_block_config(dev);
1692 : : dma_config(rx_dma_params->dma_dev,
1693 : : rx_dma_params->dma_channel,
1694 : : (struct dma_config *)&rx_dma_params->dma_cfg);
1695 : : dma_start(rx_dma_params->dma_dev, rx_dma_params->dma_channel);
1696 : : async_evt_rx_buf_request(dev);
1697 : : out:
1698 : : k_spin_unlock(&data->lock, key);
1699 : : return ret;
1700 : : }
1701 : :
1702 : : static int uart_ns16550_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len)
1703 : : {
1704 : : struct uart_ns16550_dev_data *data = dev->data;
1705 : :
1706 : : assert(data->async.next_rx_buffer == NULL);
1707 : : assert(data->async.next_rx_buffer_len == 0);
1708 : : data->async.next_rx_buffer = buf;
1709 : : data->async.next_rx_buffer_len = len;
1710 : :
1711 : : return 0;
1712 : : }
1713 : :
1714 : : static void uart_ns16550_async_rx_timeout(struct k_work *work)
1715 : : {
1716 : : struct k_work_delayable *work_delay = CONTAINER_OF(work, struct k_work_delayable, work);
1717 : : struct uart_ns16550_rx_dma_params *rx_params =
1718 : : CONTAINER_OF(work_delay, struct uart_ns16550_rx_dma_params,
1719 : : timeout_work);
1720 : : struct uart_ns16550_async_data *async_data =
1721 : : CONTAINER_OF(rx_params, struct uart_ns16550_async_data,
1722 : : rx_dma_params);
1723 : : const struct device *dev = async_data->uart_dev;
1724 : :
1725 : : uart_ns16550_async_rx_flush(dev);
1726 : :
1727 : : }
1728 : :
1729 : : static void uart_ns16550_async_tx_timeout(struct k_work *work)
1730 : : {
1731 : : struct k_work_delayable *work_delay = CONTAINER_OF(work, struct k_work_delayable, work);
1732 : : struct uart_ns16550_tx_dma_params *tx_params =
1733 : : CONTAINER_OF(work_delay, struct uart_ns16550_tx_dma_params,
1734 : : timeout_work);
1735 : : struct uart_ns16550_async_data *async_data =
1736 : : CONTAINER_OF(tx_params, struct uart_ns16550_async_data,
1737 : : tx_dma_params);
1738 : : const struct device *dev = async_data->uart_dev;
1739 : :
1740 : : (void)uart_ns16550_tx_abort(dev);
1741 : : }
1742 : :
1743 : : #endif /* CONFIG_UART_ASYNC_API */
1744 : :
1745 : : static const struct uart_driver_api uart_ns16550_driver_api = {
1746 : : .poll_in = uart_ns16550_poll_in,
1747 : : .poll_out = uart_ns16550_poll_out,
1748 : : .err_check = uart_ns16550_err_check,
1749 : : #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
1750 : : .configure = uart_ns16550_configure,
1751 : : .config_get = uart_ns16550_config_get,
1752 : : #endif
1753 : : #ifdef CONFIG_UART_INTERRUPT_DRIVEN
1754 : :
1755 : : .fifo_fill = uart_ns16550_fifo_fill,
1756 : : .fifo_read = uart_ns16550_fifo_read,
1757 : : .irq_tx_enable = uart_ns16550_irq_tx_enable,
1758 : : .irq_tx_disable = uart_ns16550_irq_tx_disable,
1759 : : .irq_tx_ready = uart_ns16550_irq_tx_ready,
1760 : : .irq_tx_complete = uart_ns16550_irq_tx_complete,
1761 : : .irq_rx_enable = uart_ns16550_irq_rx_enable,
1762 : : .irq_rx_disable = uart_ns16550_irq_rx_disable,
1763 : : .irq_rx_ready = uart_ns16550_irq_rx_ready,
1764 : : .irq_err_enable = uart_ns16550_irq_err_enable,
1765 : : .irq_err_disable = uart_ns16550_irq_err_disable,
1766 : : .irq_is_pending = uart_ns16550_irq_is_pending,
1767 : : .irq_update = uart_ns16550_irq_update,
1768 : : .irq_callback_set = uart_ns16550_irq_callback_set,
1769 : :
1770 : : #endif
1771 : :
1772 : : #ifdef CONFIG_UART_ASYNC_API
1773 : : .callback_set = uart_ns16550_callback_set,
1774 : : .tx = uart_ns16550_tx,
1775 : : .tx_abort = uart_ns16550_tx_abort,
1776 : : .rx_enable = uart_ns16550_rx_enable,
1777 : : .rx_disable = uart_ns16550_rx_disable,
1778 : : .rx_buf_rsp = uart_ns16550_rx_buf_rsp,
1779 : : #endif
1780 : :
1781 : : #ifdef CONFIG_UART_NS16550_LINE_CTRL
1782 : : .line_ctrl_set = uart_ns16550_line_ctrl_set,
1783 : : #endif
1784 : :
1785 : : #ifdef CONFIG_UART_NS16550_DRV_CMD
1786 : : .drv_cmd = uart_ns16550_drv_cmd,
1787 : : #endif
1788 : : };
1789 : :
1790 : : #define UART_NS16550_IRQ_FLAGS(n) \
1791 : : COND_CODE_1(DT_INST_IRQ_HAS_CELL(n, sense), \
1792 : : (DT_INST_IRQ(n, sense)), \
1793 : : (0))
1794 : :
1795 : : /* IO-port or MMIO based UART */
1796 : : #define UART_NS16550_IRQ_CONFIG(n) \
1797 : : static void uart_ns16550_irq_config_func##n(const struct device *dev) \
1798 : : { \
1799 : : ARG_UNUSED(dev); \
1800 : : IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
1801 : : uart_ns16550_isr, DEVICE_DT_INST_GET(n), \
1802 : : UART_NS16550_IRQ_FLAGS(n)); \
1803 : : irq_enable(DT_INST_IRQN(n)); \
1804 : : }
1805 : :
1806 : : /* PCI(e) with auto IRQ detection */
1807 : : #define UART_NS16550_IRQ_CONFIG_PCIE(n) \
1808 : : static void uart_ns16550_irq_config_func##n(const struct device *dev) \
1809 : : { \
1810 : : BUILD_ASSERT(DT_INST_IRQN(n) == PCIE_IRQ_DETECT, \
1811 : : "Only runtime IRQ configuration is supported"); \
1812 : : BUILD_ASSERT(IS_ENABLED(CONFIG_DYNAMIC_INTERRUPTS), \
1813 : : "NS16550 PCIe requires dynamic interrupts"); \
1814 : : const struct uart_ns16550_device_config *dev_cfg = dev->config;\
1815 : : unsigned int irq = pcie_alloc_irq(dev_cfg->pcie->bdf); \
1816 : : if (irq == PCIE_CONF_INTR_IRQ_NONE) { \
1817 : : return; \
1818 : : } \
1819 : : pcie_connect_dynamic_irq(dev_cfg->pcie->bdf, irq, \
1820 : : DT_INST_IRQ(n, priority), \
1821 : : (void (*)(const void *))uart_ns16550_isr, \
1822 : : DEVICE_DT_INST_GET(n), \
1823 : : UART_NS16550_IRQ_FLAGS(n)); \
1824 : : pcie_irq_enable(dev_cfg->pcie->bdf, irq); \
1825 : : }
1826 : :
1827 : : #ifdef CONFIG_UART_INTERRUPT_DRIVEN
1828 : : #define DEV_CONFIG_IRQ_FUNC_INIT(n) \
1829 : : .irq_config_func = uart_ns16550_irq_config_func##n,
1830 : : #define UART_NS16550_IRQ_FUNC_DECLARE(n) \
1831 : : static void uart_ns16550_irq_config_func##n(const struct device *dev);
1832 : : #define UART_NS16550_IRQ_FUNC_DEFINE(n) \
1833 : : UART_NS16550_IRQ_CONFIG(n)
1834 : :
1835 : : #define DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) \
1836 : : .irq_config_func = uart_ns16550_irq_config_func##n,
1837 : : #define UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n) \
1838 : : static void uart_ns16550_irq_config_func##n(const struct device *dev);
1839 : : #define UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n) \
1840 : : UART_NS16550_IRQ_CONFIG_PCIE(n)
1841 : : #else
1842 : : /* !CONFIG_UART_INTERRUPT_DRIVEN */
1843 : : #define DEV_CONFIG_IRQ_FUNC_INIT(n)
1844 : : #define UART_NS16550_IRQ_FUNC_DECLARE(n)
1845 : : #define UART_NS16550_IRQ_FUNC_DEFINE(n)
1846 : :
1847 : : #define DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n)
1848 : : #define UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n)
1849 : : #define UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n)
1850 : : #endif /* CONFIG_UART_INTERRUPT_DRIVEN */
1851 : :
1852 : : #ifdef CONFIG_UART_ASYNC_API
1853 : : #define DMA_PARAMS(n) \
1854 : : .async.tx_dma_params = { \
1855 : : .dma_dev = \
1856 : : DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, tx)), \
1857 : : .dma_channel = \
1858 : : DT_INST_DMAS_CELL_BY_NAME(n, tx, channel), \
1859 : : .dma_cfg = { \
1860 : : .source_burst_length = 1, \
1861 : : .dest_burst_length = 1, \
1862 : : .source_data_size = 1, \
1863 : : .dest_data_size = 1, \
1864 : : .complete_callback_en = 0, \
1865 : : .error_callback_dis = 1, \
1866 : : .block_count = 1, \
1867 : : .channel_direction = MEMORY_TO_PERIPHERAL, \
1868 : : .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, tx, channel), \
1869 : : .dma_callback = dma_callback, \
1870 : : .user_data = (void *)DEVICE_DT_INST_GET(n) \
1871 : : }, \
1872 : : }, \
1873 : : .async.rx_dma_params = { \
1874 : : .dma_dev = \
1875 : : DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(n, rx)), \
1876 : : .dma_channel = \
1877 : : DT_INST_DMAS_CELL_BY_NAME(n, rx, channel), \
1878 : : .dma_cfg = { \
1879 : : .source_burst_length = 1, \
1880 : : .dest_burst_length = 1, \
1881 : : .source_data_size = 1, \
1882 : : .dest_data_size = 1, \
1883 : : .complete_callback_en = 0, \
1884 : : .error_callback_dis = 1, \
1885 : : .block_count = 1, \
1886 : : .channel_direction = PERIPHERAL_TO_MEMORY, \
1887 : : .dma_slot = DT_INST_DMAS_CELL_BY_NAME(n, rx, channel), \
1888 : : .dma_callback = dma_callback, \
1889 : : .user_data = (void *)DEVICE_DT_INST_GET(n) \
1890 : : }, \
1891 : : }, \
1892 : : COND_CODE_0(DT_INST_ON_BUS(n, pcie), \
1893 : : (.phys_addr = DT_INST_REG_ADDR(n),), ())
1894 : :
1895 : : #define DMA_PARAMS_NULL(n) \
1896 : : .async.tx_dma_params = { \
1897 : : .dma_dev = NULL \
1898 : : }, \
1899 : : .async.rx_dma_params = { \
1900 : : .dma_dev = NULL \
1901 : : }, \
1902 : :
1903 : : #define DEV_DATA_ASYNC(n) \
1904 : : COND_CODE_0(DT_INST_PROP(n, io_mapped), \
1905 : : (COND_CODE_1(DT_INST_NODE_HAS_PROP(n, dmas), \
1906 : : (DMA_PARAMS(n)), (DMA_PARAMS_NULL(n)))), \
1907 : : (DMA_PARAMS_NULL(n)))
1908 : : #else
1909 : : #define DEV_DATA_ASYNC(n)
1910 : : #endif /* CONFIG_UART_ASYNC_API */
1911 : :
1912 : :
1913 : : #define UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \
1914 : : COND_CODE_1(DT_INST_NODE_HAS_PROP(n, clock_frequency), ( \
1915 : : .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \
1916 : : .clock_dev = NULL, \
1917 : : .clock_subsys = NULL, \
1918 : : ), ( \
1919 : : .sys_clk_freq = 0, \
1920 : : .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
1921 : : .clock_subsys = (clock_control_subsys_t) DT_INST_PHA(\
1922 : : 0, clocks, clkid), \
1923 : : ) \
1924 : : ) \
1925 : : IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pcp), \
1926 : : (.pcp = DT_INST_PROP_OR(n, pcp, 0),)) \
1927 : : .reg_interval = (1 << DT_INST_PROP(n, reg_shift)), \
1928 : : IF_ENABLED(CONFIG_PINCTRL, \
1929 : : (.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),)) \
1930 : : IF_ENABLED(DT_INST_NODE_HAS_PROP(n, resets), \
1931 : : (.reset_spec = RESET_DT_SPEC_INST_GET(n),))
1932 : :
1933 : : #define UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \
1934 : : .uart_config.baudrate = DT_INST_PROP_OR(n, current_speed, 0), \
1935 : : .uart_config.parity = UART_CFG_PARITY_NONE, \
1936 : : .uart_config.stop_bits = UART_CFG_STOP_BITS_1, \
1937 : : .uart_config.data_bits = UART_CFG_DATA_BITS_8, \
1938 : : .uart_config.flow_ctrl = \
1939 : : COND_CODE_1(DT_INST_PROP_OR(n, hw_flow_control, 0), \
1940 : : (UART_CFG_FLOW_CTRL_RTS_CTS), \
1941 : : (UART_CFG_FLOW_CTRL_NONE)), \
1942 : : IF_ENABLED(DT_INST_NODE_HAS_PROP(n, dlf), \
1943 : : (.dlf = DT_INST_PROP_OR(n, dlf, 0),)) \
1944 : : DEV_DATA_ASYNC(n) \
1945 : :
1946 : : #define UART_NS16550_DEVICE_IO_MMIO_INIT(n) \
1947 : : UART_NS16550_IRQ_FUNC_DECLARE(n); \
1948 : : IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(n))); \
1949 : : static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \
1950 : : COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \
1951 : : (.port = DT_INST_REG_ADDR(n),), \
1952 : : (DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),)) \
1953 : : IF_ENABLED(DT_INST_PROP_OR(n, io_mapped, 0), \
1954 : : (.io_map = true,)) \
1955 : : UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \
1956 : : DEV_CONFIG_IRQ_FUNC_INIT(n) \
1957 : : }; \
1958 : : static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \
1959 : : UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \
1960 : : }; \
1961 : : DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \
1962 : : &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \
1963 : : PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \
1964 : : &uart_ns16550_driver_api); \
1965 : : UART_NS16550_IRQ_FUNC_DEFINE(n)
1966 : :
1967 : : #define UART_NS16550_DEVICE_PCIE_INIT(n) \
1968 : : UART_NS16550_PCIE_IRQ_FUNC_DECLARE(n); \
1969 : : DEVICE_PCIE_INST_DECLARE(n); \
1970 : : IF_ENABLED(CONFIG_PINCTRL, (PINCTRL_DT_INST_DEFINE(n))); \
1971 : : static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \
1972 : : UART_NS16550_COMMON_DEV_CFG_INITIALIZER(n) \
1973 : : DEV_CONFIG_PCIE_IRQ_FUNC_INIT(n) \
1974 : : DEVICE_PCIE_INST_INIT(n, pcie) \
1975 : : }; \
1976 : : static struct uart_ns16550_dev_data uart_ns16550_dev_data_##n = { \
1977 : : UART_NS16550_COMMON_DEV_DATA_INITIALIZER(n) \
1978 : : }; \
1979 : : DEVICE_DT_INST_DEFINE(n, &uart_ns16550_init, NULL, \
1980 : : &uart_ns16550_dev_data_##n, &uart_ns16550_dev_cfg_##n, \
1981 : : PRE_KERNEL_1, \
1982 : : CONFIG_SERIAL_INIT_PRIORITY, \
1983 : : &uart_ns16550_driver_api); \
1984 : : UART_NS16550_PCIE_IRQ_FUNC_DEFINE(n)
1985 : :
1986 : : #define UART_NS16550_DEVICE_INIT(n) \
1987 : : COND_CODE_1(DT_INST_ON_BUS(n, pcie), \
1988 : : (UART_NS16550_DEVICE_PCIE_INIT(n)), \
1989 : : (UART_NS16550_DEVICE_IO_MMIO_INIT(n)))
1990 : :
1991 : 1 : DT_INST_FOREACH_STATUS_OKAY(UART_NS16550_DEVICE_INIT)
|