From bbadd37a1156dce13006d6e2a967fed6178296f5 Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Tue, 24 Oct 2017 11:35:02 +0800 Subject: [PATCH] npcx/uart: Disallow deep sleep when alternate pad is selected Also, fix uart_rx_available to only call clock_refresh_console_in_use when the default pad is selected. BRANCH=none BUG=b:65526215 TEST=On Lux, EC console works, so does pad-switching EC-EC comm, and idlestats shows that the EC goes to deep sleep. TEST=In uart_alt_pad_write_read, increase usleep time in loop from 100 to 10000 (the shorter 100us time prevents EC from going into deep sleep during the transaction), no transaction error in EC-EC communication when system goes into deep sleep. Change-Id: I3855b07f37def0ac9cfd700318ba64c432d3c42b Signed-off-by: Nicolas Boichat Reviewed-on: https://chromium-review.googlesource.com/735103 Reviewed-by: Vincent Palatin --- chip/npcx/uart.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/chip/npcx/uart.c b/chip/npcx/uart.c index 3fc166b362..b7df104dbe 100644 --- a/chip/npcx/uart.c +++ b/chip/npcx/uart.c @@ -132,8 +132,12 @@ void uart_tx_stop(void) /* Disable TX interrupt */ { NPCX_UICTRL &= ~0x20; - /* Re-allow deep sleep */ - enable_sleep(SLEEP_MASK_UART); + /* + * Re-allow deep sleep when transmiting on the default pad (deep sleep + * is always disabled when alternate pad is selected). + */ + if (pad == UART_DEFAULT_PAD) + enable_sleep(SLEEP_MASK_UART); } void uart_tx_flush(void) @@ -161,7 +165,7 @@ int uart_rx_available(void) { int rx_available = NPCX_UICTRL & 0x02; - if (rx_available) { + if (rx_available && pad == UART_DEFAULT_PAD) { #ifdef CONFIG_LOW_POWER_IDLE /* * Activity seen on UART RX pin while UART was disabled for deep @@ -172,8 +176,7 @@ int uart_rx_available(void) clock_refresh_console_in_use(); #endif #ifdef CONFIG_UART_PAD_SWITCH - if (pad == UART_DEFAULT_PAD) - last_default_pad_rx_time = get_time(); + last_default_pad_rx_time = get_time(); #endif } return rx_available; /* If RX FIFO is empty return '0'. */ @@ -259,6 +262,15 @@ static void uart_set_pad(enum uart_pad newpad) uart_tx_flush(); uart_tx_stop(); + /* + * Allow deep sleep when default pad is selected (sleep is inhibited + * during TX). Disallow deep sleep when alternate pad is selected. + */ + if (newpad == UART_DEFAULT_PAD) + enable_sleep(SLEEP_MASK_UART); + else + disable_sleep(SLEEP_MASK_UART); + pad = newpad; /* Configure new pad. */ @@ -286,8 +298,13 @@ void uart_default_pad_rx_interrupt(enum gpio_signal signal) * transaction and switch back. */ gpio_disable_interrupt(GPIO_UART_MAIN_RX); - uart_set_pad(UART_DEFAULT_PAD); + +#ifdef CONFIG_LOW_POWER_IDLE + clock_refresh_console_in_use(); +#endif last_default_pad_rx_time = get_time(); + + uart_set_pad(UART_DEFAULT_PAD); } int uart_alt_pad_write_read(uint8_t *tx, int tx_len, uint8_t *rx, int rx_len,