From 1ae3ffc6080ed23beb7d57b57b825ad2b8aba172 Mon Sep 17 00:00:00 2001 From: Mary Ruthven Date: Tue, 20 Sep 2016 14:46:10 -0700 Subject: [PATCH] cr50: use RXILVL to trigger fewer UART RXINTs This change sets UART_FIFO_RXILVL to 3 for the AP and EC UART. With this change RXINT will only be triggered when 4 characters are received instead of for every character. The change also flushes the RX FIFO whenever console input is received through usb make sure to the user can see their input as they are typing. BUG=none BRANCH=none TEST=run taskinfo after the system finishes booting. Before Change the IRQ count for 181 should be around 20000. After the change it should be around 5000. Use the AP and EC console over USB and verify there is no noticeable change in their usability. Change-Id: I134ea0d2bc254038dad6c341b94f822adb90c000 Signed-off-by: Mary Ruthven Reviewed-on: https://chromium-review.googlesource.com/387175 Reviewed-by: Bill Richardson --- chip/g/uartn.c | 9 +++++++++ chip/g/usart.c | 23 +++++++++++++++++------ chip/g/usart.h | 18 ++++++++++++++---- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/chip/g/uartn.c b/chip/g/uartn.c index c534705eb3..a2d29e8053 100644 --- a/chip/g/uartn.c +++ b/chip/g/uartn.c @@ -147,6 +147,15 @@ void uartn_init(int uart) */ GR_UART_FIFO(uart) = 0x63; + /* + * To reduce the number of UART RX interrupts on the peripheral UARTS, + * set the FIFO RXILVL to only trigger rx interrupts every 4 characters. + * + * Reset the RX FIFO. + */ + if (uart) + GR_UART_FIFO(uart) |= 0x7; + /* enable RX interrupts in block */ /* Note: doesn't do anything unless turned on in NVIC */ GR_UART_ICTRL(uart) = 0x02; diff --git a/chip/g/usart.c b/chip/g/usart.c index 0d22b94bfc..6c39701178 100644 --- a/chip/g/usart.c +++ b/chip/g/usart.c @@ -5,6 +5,7 @@ #include "queue.h" #include "queue_policies.h" +#include "timer.h" #include "uartn.h" #include "usart.h" #include "usb-stream.h" @@ -29,12 +30,15 @@ static struct queue const ec_uart_to_usb = static struct queue const ec_usb_to_uart = QUEUE_DIRECT(QUEUE_SIZE, uint8_t, ec_usb.producer, ec_uart.consumer); -struct usart_config const ap_uart = USART_CONFIG(UART_AP, - ap_uart_to_usb, - ap_usb_to_uart); -struct usart_config const ec_uart = USART_CONFIG(UART_EC, - ec_uart_to_usb, - ec_usb_to_uart); +USART_CONFIG(ec_uart, + UART_EC, + ec_uart_to_usb, + ec_usb_to_uart); +USART_CONFIG(ap_uart, + UART_AP, + ap_uart_to_usb, + ap_usb_to_uart); + USB_STREAM_CONFIG(ap_usb, USB_IFACE_AP, USB_STR_AP_NAME, @@ -64,6 +68,13 @@ void get_data_from_usb(struct usart_config const *config) /* If output buffer is empty, disable transmit interrupt */ if (!queue_count(uart_out)) uartn_tx_stop(config->uart); + + /* + * Make sure rx fifo is cleared after any input to the console to ensure + * user will be able to see their input as they are typing instead of + * only when the RX FIFO reaches the level set by RXILVL. + */ + hook_call_deferred(config->deferred, 1 * MSEC); } void send_data_to_usb(struct usart_config const *config) diff --git a/chip/g/usart.h b/chip/g/usart.h index 79616a48e0..133dc7a3af 100644 --- a/chip/g/usart.h +++ b/chip/g/usart.h @@ -16,6 +16,8 @@ struct usart_config { struct producer const producer; struct consumer const consumer; + + const struct deferred_data *deferred; }; extern struct consumer_ops const uart_consumer_ops; @@ -41,14 +43,17 @@ extern struct producer_ops const uart_producer_ops; GR_UART_ISTATECLR(NAME.uart) = \ GC_UART_ISTATECLR_RX_MASK; \ /* Read input FIFO until empty */ \ - send_data_to_usb(&NAME); \ + hook_call_deferred(NAME.deferred, 0); \ } -#define USART_CONFIG(UART, \ +#define USART_CONFIG(NAME, \ + UART, \ RX_QUEUE, \ TX_QUEUE) \ - ((struct usart_config const) { \ + static void CONCAT2(NAME, _deferred_)(void); \ + DECLARE_DEFERRED(CONCAT2(NAME, _deferred_)); \ + struct usart_config const NAME = { \ .uart = UART, \ .consumer = { \ .queue = &TX_QUEUE, \ @@ -58,7 +63,12 @@ extern struct producer_ops const uart_producer_ops; .queue = &RX_QUEUE, \ .ops = &uart_producer_ops, \ }, \ - }) + .deferred = &CONCAT2(NAME, _deferred__data), \ + }; \ + static void CONCAT2(NAME, _deferred_)(void) \ + { \ + send_data_to_usb(&NAME); \ + } \ /* Read data from UART and add it to the producer queue */