diff --git a/drivers/serial/Kconfig.npcx b/drivers/serial/Kconfig.npcx index 78f4dd16e12..2c0fd8dc353 100644 --- a/drivers/serial/Kconfig.npcx +++ b/drivers/serial/Kconfig.npcx @@ -25,3 +25,10 @@ config UART_NPCX_USE_MDMA select SERIAL_SUPPORT_ASYNC help Enable support for npcx UART DMA mode. + +config UART_NPCX_FIFO_EX + bool "Extended NPCX UART FIFO driver support" + default y if DT_HAS_NUVOTON_NPCX_UART_NPCKN_ENABLED + help + This option enables the extended UART FIFO driver for NPCKN variant + of processors. diff --git a/drivers/serial/uart_npcx.c b/drivers/serial/uart_npcx.c index 14e32c62ae1..0bc364c096e 100644 --- a/drivers/serial/uart_npcx.c +++ b/drivers/serial/uart_npcx.c @@ -167,7 +167,11 @@ static int uart_npcx_rx_fifo_available(const struct device *dev) struct uart_reg *const inst = config->inst; /* True if at least one byte is in the Rx FIFO */ +#if defined(CONFIG_UART_NPCX_FIFO_EX) + return inst->URXFLV != 0; +#else return IS_BIT_SET(inst->UFRSTS, NPCX_UFRSTS_RFIFO_NEMPTY_STS); +#endif } static void uart_npcx_dis_all_tx_interrupts(const struct device *dev) @@ -176,8 +180,12 @@ static void uart_npcx_dis_all_tx_interrupts(const struct device *dev) struct uart_reg *const inst = config->inst; /* Disable all Tx interrupts */ +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UICTRL &= ~BIT(NPCX_UICTRL_ETI); +#else inst->UFTCTL &= ~(BIT(NPCX_UFTCTL_TEMPTY_LVL_EN) | BIT(NPCX_UFTCTL_TEMPTY_EN) | BIT(NPCX_UFTCTL_NXMIP_EN)); +#endif } static void uart_npcx_clear_rx_fifo(const struct device *dev) @@ -201,7 +209,11 @@ static int uart_npcx_tx_fifo_ready(const struct device *dev) struct uart_reg *const inst = config->inst; /* True if the Tx FIFO is not completely full */ +#if defined(CONFIG_UART_NPCX_FIFO_EX) + return inst->UTXFLV != NPCK_SZ_UART_FIFO; +#else return !(GET_FIELD(inst->UFTSTS, NPCX_UFTSTS_TEMPTY_LVL) == 0); +#endif } static int uart_npcx_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) @@ -246,22 +258,32 @@ static void uart_npcx_irq_tx_enable(const struct device *dev) { const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; + +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UICTRL |= BIT(NPCX_UICTRL_ETI); +#else struct uart_npcx_data *data = dev->data; k_spinlock_key_t key = k_spin_lock(&data->lock); inst->UFTCTL |= BIT(NPCX_UFTCTL_TEMPTY_EN); k_spin_unlock(&data->lock, key); +#endif } static void uart_npcx_irq_tx_disable(const struct device *dev) { const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; + +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UICTRL &= ~(BIT(NPCX_UICTRL_ETI)); +#else struct uart_npcx_data *data = dev->data; k_spinlock_key_t key = k_spin_lock(&data->lock); inst->UFTCTL &= ~(BIT(NPCX_UFTCTL_TEMPTY_EN)); k_spin_unlock(&data->lock, key); +#endif } static bool uart_npcx_irq_tx_is_enabled(const struct device *dev) @@ -269,7 +291,11 @@ static bool uart_npcx_irq_tx_is_enabled(const struct device *dev) const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; +#if defined(CONFIG_UART_NPCX_FIFO_EX) + return IS_BIT_SET(inst->UICTRL, NPCX_UICTRL_ETI); +#else return IS_BIT_SET(inst->UFTCTL, NPCX_UFTCTL_TEMPTY_EN); +#endif } static int uart_npcx_irq_tx_ready(const struct device *dev) @@ -283,7 +309,11 @@ static int uart_npcx_irq_tx_complete(const struct device *dev) struct uart_reg *const inst = config->inst; /* Tx FIFO is empty or last byte is sending */ +#if defined(CONFIG_UART_NPCX_FIFO_EX) + return inst->UTXFLV == 0; +#else return IS_BIT_SET(inst->UFTSTS, NPCX_UFTSTS_NXMIP); +#endif } static void uart_npcx_irq_rx_enable(const struct device *dev) @@ -291,7 +321,11 @@ static void uart_npcx_irq_rx_enable(const struct device *dev) const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UICTRL |= BIT(NPCX_UICTRL_ERI); +#else inst->UFRCTL |= BIT(NPCX_UFRCTL_RNEMPTY_EN); +#endif } static void uart_npcx_irq_rx_disable(const struct device *dev) @@ -299,7 +333,11 @@ static void uart_npcx_irq_rx_disable(const struct device *dev) const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UICTRL &= ~(BIT(NPCX_UICTRL_ERI)); +#else inst->UFRCTL &= ~(BIT(NPCX_UFRCTL_RNEMPTY_EN)); +#endif } static bool uart_npcx_irq_rx_is_enabled(const struct device *dev) @@ -307,7 +345,11 @@ static bool uart_npcx_irq_rx_is_enabled(const struct device *dev) const struct uart_npcx_config *const config = dev->config; struct uart_reg *const inst = config->inst; +#if defined(CONFIG_UART_NPCX_FIFO_EX) + return IS_BIT_SET(inst->UICTRL, NPCX_UICTRL_ERI); +#else return IS_BIT_SET(inst->UFRCTL, NPCX_UFRCTL_RNEMPTY_EN); +#endif } static int uart_npcx_irq_rx_ready(const struct device *dev) @@ -895,6 +937,7 @@ static void uart_npcx_isr(const struct device *dev) } #endif +#if !defined(CONFIG_UART_NPCX_FIFO_EX) #if defined(CONFIG_PM) || defined(CONFIG_UART_ASYNC_API) if (IS_BIT_SET(inst->UFTCTL, NPCX_UFTCTL_NXMIP_EN) && IS_BIT_SET(inst->UFTSTS, NPCX_UFTSTS_NXMIP)) { @@ -915,6 +958,7 @@ static void uart_npcx_isr(const struct device *dev) #endif } #endif +#endif } #endif @@ -1060,8 +1104,12 @@ static int uart_npcx_init(const struct device *dev) /* Initialize UART FIFO if mode is interrupt driven */ #if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) +#if defined(CONFIG_UART_NPCX_FIFO_EX) + inst->UFCTRL |= BIT(NPCK_FIFO_EN); +#else /* Enable the UART FIFO mode */ inst->UMDSL |= BIT(NPCX_UMDSL_FIFO_MD); +#endif /* Disable all UART tx FIFO interrupts */ uart_npcx_dis_all_tx_interrupts(dev); diff --git a/dts/arm/nuvoton/npck/npck3.dtsi b/dts/arm/nuvoton/npck/npck3.dtsi index ffdfd49534b..c1ddbfd7403 100644 --- a/dts/arm/nuvoton/npck/npck3.dtsi +++ b/dts/arm/nuvoton/npck/npck3.dtsi @@ -53,7 +53,7 @@ }; uart1: serial@400c4000 { - compatible = "nuvoton,npcx-uart"; + compatible = "nuvoton,npcx-uart", "nuvoton,npcx-uart-npckn"; reg = <0x400C4000 0x2000>; interrupts = <23 3>; clocks = <&pcc NPCX_CLOCK_BUS_APB2 NPCX_PWDWN_CTL1 4>; diff --git a/dts/bindings/serial/nuvoton,npcx-uart-npckn.yaml b/dts/bindings/serial/nuvoton,npcx-uart-npckn.yaml new file mode 100644 index 00000000000..218bdbf10b6 --- /dev/null +++ b/dts/bindings/serial/nuvoton,npcx-uart-npckn.yaml @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nuvoton npcx serial uart for npckn variant + +compatible: "nuvoton,npcx-uart-npckn" + +include: nuvoton,npcx-uart.yaml