summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/npcx/registers.h2
-rw-r--r--chip/npcx/uart.c12
-rw-r--r--chip/npcx/uartn.c25
-rw-r--r--chip/npcx/uartn.h2
4 files changed, 39 insertions, 2 deletions
diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h
index d31800f841..3a63f6ccb7 100644
--- a/chip/npcx/registers.h
+++ b/chip/npcx/registers.h
@@ -326,7 +326,7 @@
#define NPCX_UFTCTL_TEMPTY_LVL_SEL FIELD(0, 5)
#define NPCX_UFTCTL_TEMPTY_LVL_EN 5
#define NPCX_UFTCTL_TEMPTY_EN 6
-#define NPCX_UFTCTL_NXIMPEN 7
+#define NPCX_UFTCTL_NXMIPEN 7
#define NPCX_UFRCTL_RFULL_LVL_SEL FIELD(0, 5)
#define NPCX_UFRCTL_RFULL_LVL_EN 5
diff --git a/chip/npcx/uart.c b/chip/npcx/uart.c
index a83de311ef..1e4d88f789 100644
--- a/chip/npcx/uart.c
+++ b/chip/npcx/uart.c
@@ -123,10 +123,14 @@ void uart_tx_start(void)
void uart_tx_stop(void)
{
+#ifdef NPCX_UART_FIFO_SUPPORT
+ uartn_tx_stop(CONSOLE_UART, 0);
+#else
uint8_t sleep_ena;
sleep_ena = (pad == UART_DEFAULT_PAD) ? 1 : 0;
uartn_tx_stop(CONSOLE_UART, sleep_ena);
+#endif
}
void uart_tx_flush(void)
@@ -196,6 +200,14 @@ void uart_ec_interrupt(void)
return;
}
#endif
+#ifdef NPCX_UART_FIFO_SUPPORT
+ if (!uartn_tx_in_progress(CONSOLE_UART)) {
+ if (uart_buffer_empty()) {
+ uartn_enable_tx_complete_int(CONSOLE_UART, 0);
+ enable_sleep(SLEEP_MASK_UART);
+ }
+ }
+#endif
/* Default pad. */
/* Read input FIFO until empty, then fill output FIFO */
diff --git a/chip/npcx/uartn.c b/chip/npcx/uartn.c
index 692e75419f..2269e11e7c 100644
--- a/chip/npcx/uartn.c
+++ b/chip/npcx/uartn.c
@@ -28,6 +28,13 @@
/* True if the Tx FIFO is not completely full */
#define NPCX_UART_TX_IS_READY(n) \
(!(GET_FIELD(NPCX_UFTSTS(n), NPCX_UFTSTS_TEMPTY_LVL) == 0))
+
+/* Enable UART Tx "not" in transmission interrupt */
+#define NPCX_UART_TX_NXMIP_INT_EN(n) \
+ (SET_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_NXMIPEN))
+/* Disable UART Tx "not" in transmission interrupt */
+#define NPCX_UART_TX_NXMIP_INT_DIS(n) \
+ (CLEAR_BIT(NPCX_UFTCTL(n), NPCX_UFTCTL_NXMIPEN))
/*
* True if Tx is in progress
* (i.e. FIFO is not empty or last byte in TSFT (Transmit Shift register)
@@ -114,6 +121,13 @@ void uartn_tx_start(uint8_t uart_num)
/* Do not allow deep sleep while transmit in progress */
disable_sleep(SLEEP_MASK_UART);
+#ifdef NPCX_UART_FIFO_SUPPORT
+ /*
+ * For FIFO mode, enable the NXMIP interrupt. This generates an
+ * interrupt when Tx (both FIFO and shift register) is empty
+ */
+ NPCX_UART_TX_NXMIP_INT_EN(uart_num);
+#else
/*
* Re-enable the transmit interrupt, then forcibly trigger the
* interrupt. This works around a hardware problem with the
@@ -121,10 +135,19 @@ void uartn_tx_start(uint8_t uart_num)
* threshold is _crossed_, not just met.
*/
NPCX_UART_TX_EMPTY_INT_EN(uart_num);
+#endif
task_trigger_irq(uart_cfg[uart_num].irq);
}
+#ifdef NPCX_UART_FIFO_SUPPORT
+void uartn_enable_tx_complete_int(uint8_t uart_num, uint8_t enable)
+{
+ enable ? NPCX_UART_TX_NXMIP_INT_EN(uart_num) :
+ NPCX_UART_TX_NXMIP_INT_DIS(uart_num);
+}
+#endif
+
void uartn_tx_stop(uint8_t uart_num, uint8_t sleep_ena)
{
/* Disable TX interrupt */
@@ -190,7 +213,7 @@ static void uartn_set_fifo_mode(uint8_t uart_num)
/* Disable all Tx interrupts */
NPCX_UFTCTL(uart_num) &= ~(BIT(NPCX_UFTCTL_TEMPTY_LVL_EN) |
BIT(NPCX_UFTCTL_TEMPTY_EN) |
- BIT(NPCX_UFTCTL_NXIMPEN));
+ BIT(NPCX_UFTCTL_NXMIPEN));
}
#endif
diff --git a/chip/npcx/uartn.h b/chip/npcx/uartn.h
index fc5c2599d0..e5326f72b8 100644
--- a/chip/npcx/uartn.h
+++ b/chip/npcx/uartn.h
@@ -60,4 +60,6 @@ void uartn_clear_rx_fifo(int channel);
void uartn_rx_int_en(uint8_t uart_num);
/* Enable the UART Wake-up */
void uartn_wui_en(uint8_t uart_num);
+/* Enable/disable Tx NXMIP (No Transmit In Progress) interrupt */
+void uartn_enable_tx_complete_int(uint8_t uart_num, uint8_t enable);
#endif /* __CROS_EC_UARTN_H */