diff options
author | Jack Rosenthal <jrosenth@chromium.org> | 2019-04-24 16:04:06 -0600 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-04-26 09:09:06 -0700 |
commit | 5c87411b3a573eb8d9d6f3b63e099e7ab44cbd5b (patch) | |
tree | da1d9a58d68c25020eb06d38f1de9f1f77403b0d /chip/ish/uart.c | |
parent | c3ecd60e5f12c344baa6caa4b51b19f00c7e8adf (diff) | |
download | chrome-ec-5c87411b3a573eb8d9d6f3b63e099e7ab44cbd5b.tar.gz |
ish: cleanup of UART-related functionality
This commit cleans up UART-related ISH code:
* Moving REG{8,16,32} macro usages into header files
* Changing ifdef logic in code to use IS_ENABLED macro
* Reduce repeated code in uart_defs.h
* Change hexadecimal masks in uart_defs.h to use BIT(n) macros
* Change disabling of UART2 to use common logic in uart_stop_hw
BUG=b:130573158
BRANCH=none
TEST=UART on arcada_ish is functioning as normal
Change-Id: Ia05feea2de8c14e44e4d3f9dd7c790bcb81cd1c0
Signed-off-by: Jack Rosenthal <jrosenth@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1582457
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'chip/ish/uart.c')
-rw-r--r-- | chip/ish/uart.c | 152 |
1 files changed, 60 insertions, 92 deletions
diff --git a/chip/ish/uart.c b/chip/ish/uart.c index 5076f5eeaf..e512b53588 100644 --- a/chip/ish/uart.c +++ b/chip/ish/uart.c @@ -46,6 +46,13 @@ static struct uart_ctx uart_ctx[UART_DEVICES] = { .input_freq = UART_ISH_INPUT_FREQ, .addr_interval = UART_ISH_ADDR_INTERVAL, .uart_state = UART_STATE_CG, + }, + { + .id = 2, + .base = UART2_BASE, + .input_freq = UART_ISH_INPUT_FREQ, + .addr_interval = UART_ISH_ADDR_INTERVAL, + .uart_state = UART_STATE_CG, } }; @@ -58,47 +65,35 @@ int uart_init_done(void) void uart_tx_start(void) { -#if !defined(CONFIG_POLLING_UART) - - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ - - if (REG8(IER(id)) & IER_TDRQ) - return; - - /* Do not allow deep sleep while transmit in progress */ - disable_sleep(SLEEP_MASK_UART); - - /* TODO: disable low power mode while transmit */ + if (!IS_ENABLED(CONFIG_POLLING_UART)) { + if (IER(ISH_DEBUG_UART) & IER_TDRQ) + return; - REG8(IER(id)) |= IER_TDRQ; + /* Do not allow deep sleep while transmit in progress */ + disable_sleep(SLEEP_MASK_UART); - task_trigger_irq(ISH_DEBUG_UART_IRQ); + IER(ISH_DEBUG_UART) |= IER_TDRQ; -#endif + task_trigger_irq(ISH_DEBUG_UART_IRQ); + } } void uart_tx_stop(void) { -#if !defined(CONFIG_POLLING_UART) - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ - - /* Re-allow deep sleep */ - enable_sleep(SLEEP_MASK_UART); - - REG8(IER(id)) &= ~IER_TDRQ; + if (!IS_ENABLED(CONFIG_POLLING_UART)) { + /* Re-allow deep sleep */ + enable_sleep(SLEEP_MASK_UART); - /* TODO: re-enable low power mode */ -#endif + IER(ISH_DEBUG_UART) &= ~IER_TDRQ; + } } void uart_tx_flush(void) { -#if !defined(CONFIG_POLLING_UART) - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ - - while (!(REG8(LSR(id)) & LSR_TEMT) ) - ; -#endif + if (!IS_ENABLED(CONFIG_POLLING_UART)) { + while (!(LSR(ISH_DEBUG_UART) & LSR_TEMT)) + continue; + } } int uart_tx_ready(void) @@ -108,32 +103,24 @@ int uart_tx_ready(void) int uart_rx_available(void) { -#if !defined(CONFIG_POLLING_UART) - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ + if (IS_ENABLED(CONFIG_POLLING_UART)) + return 0; - return REG8(LSR(id)) & LSR_DR; -#else - return 0; -#endif + return LSR(ISH_DEBUG_UART) & LSR_DR; } void uart_write_char(char c) { - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ - /* Wait till reciever is ready */ - while ((REG8(LSR(id)) & LSR_TEMT) == 0) - ; + while ((LSR(ISH_DEBUG_UART) & LSR_TEMT) == 0) + continue; - REG8(THR(id)) = c; + THR(ISH_DEBUG_UART) = c; } -#if !defined(CONFIG_POLLING_UART) int uart_read_char(void) { - enum UART_PORT id = ISH_DEBUG_UART; /* UART for ISH */ - - return REG8(RBR(id)); + return RBR(ISH_DEBUG_UART); } void uart_ec_interrupt(void) @@ -142,8 +129,9 @@ void uart_ec_interrupt(void) uart_process_input(); uart_process_output(); } +#ifndef CONFIG_POLLING_UART DECLARE_IRQ(ISH_DEBUG_UART_IRQ, uart_ec_interrupt); -#endif /* !defined(CONFIG_POLLING_UART) */ +#endif static int uart_return_baud_rate_by_id(int baud_rate_id) { @@ -167,42 +155,43 @@ static void uart_hw_init(enum UART_PORT id) /* Calculate baud rate divisor */ divisor = (ctx->input_freq / ctx->baud_rate) >> 4; - REG32(MUL(ctx->id)) = (divisor * ctx->baud_rate); - REG32(DIV(ctx->id)) = (ctx->input_freq / 16); - REG32(PS(ctx->id)) = 16; + MUL(ctx->id) = (divisor * ctx->baud_rate); + DIV(ctx->id) = (ctx->input_freq / 16); + PS(ctx->id) = 16; /* Set the DLAB to access the baud rate divisor registers */ - REG8(LCR(ctx->id)) = LCR_DLAB; - REG8(DLL(ctx->id)) = (divisor & 0xff); - REG8(DLH(ctx->id)) = ((divisor >> 8) & 0xff); + LCR(ctx->id) = LCR_DLAB; + DLL(ctx->id) = (divisor & 0xff); + DLH(ctx->id) = ((divisor >> 8) & 0xff); /* 8 data bits, 1 stop bit, no parity, clear DLAB */ - REG8(LCR(ctx->id)) = LCR_8BIT_CHR; + LCR(ctx->id) = LCR_8BIT_CHR; if (ctx->client_flags & UART_CONFIG_HW_FLOW_CONTROL) mcr = MCR_AUTO_FLOW_EN; - mcr |= MCR_INTR_ENABLE; /* needs to be set regardless of flow control */ + /* needs to be set regardless of flow control */ + mcr |= MCR_INTR_ENABLE; mcr |= (MCR_RTS | MCR_DTR); - REG8(MCR(ctx->id)) = mcr; + MCR(ctx->id) = mcr; fcr = FCR_FIFO_SIZE_64 | FCR_ITL_FIFO_64_BYTES_1; /* configure FIFOs */ - REG8(FCR(ctx->id)) = (fcr | FCR_FIFO_ENABLE - | FCR_RESET_RX | FCR_RESET_TX); + FCR(ctx->id) = (fcr | FCR_FIFO_ENABLE + | FCR_RESET_RX | FCR_RESET_TX); /* enable UART unit */ - REG32(ABR(ctx->id)) = ABR_UUE; + ABR(ctx->id) = ABR_UUE; /* clear the port */ - REG8(RBR(ctx->id)); -#ifdef CONFIG_POLLING_UART - REG8(IER(ctx->id)) = 0x00; -#else - REG8(IER(ctx->id)) = IER_RECV; -#endif + RBR(ctx->id); + + if (IS_ENABLED(CONFIG_POLLING_UART)) + IER(ctx->id) = 0x00; + else + IER(ctx->id) = IER_RECV; } static void uart_stop_hw(enum UART_PORT id) @@ -213,25 +202,24 @@ static void uart_stop_hw(enum UART_PORT id) /* Manually clearing the fifo from possible noise. * Entering D0i3 when fifo is not cleared may result in a hang. */ - fifo_len = (REG32(FOR(id)) & FOR_OCCUPANCY_MASK) >> FOR_OCCUPANCY_OFFS; + fifo_len = (FOR(id) & FOR_OCCUPANCY_MASK) >> FOR_OCCUPANCY_OFFS; for (i = 0; i < fifo_len; i++) - (void)REG8(RBR(id)); + (void)RBR(id); /* No interrupts are enabled */ - REG8(IER(id)) = 0; - REG8(MCR(id)) = 0; + IER(id) = 0; + MCR(id) = 0; /* Clear and disable FIFOs */ - REG8(FCR(id)) = (FCR_RESET_RX | FCR_RESET_TX); + FCR(id) = (FCR_RESET_RX | FCR_RESET_TX); /* Disable uart unit */ - REG32(ABR(id)) = 0; + ABR(id) = 0; } static int uart_client_init(enum UART_PORT id, uint32_t baud_rate_id, int flags) { - if ((uart_ctx[id].base == 0) || (id >= UART_DEVICES)) return UART_ERROR; @@ -254,7 +242,6 @@ static int uart_client_init(enum UART_PORT id, uint32_t baud_rate_id, int flags) static void uart_drv_init(void) { int i; - uint32_t fifo_len; /* Disable UART */ for (i = 0; i < UART_DEVICES; i++) @@ -263,34 +250,15 @@ static void uart_drv_init(void) /* Enable HSU global interrupts (DMA/U0/U1) and set PMEN bit * to allow PMU to clock gate ISH */ - REG32(HSU_BASE + HSU_REG_GIEN) = (GIEN_DMA_EN | GIEN_UART0_EN - | GIEN_UART1_EN | GIEN_PWR_MGMT); - - /* There is a by design HW "bug" where all UARTs are enabled by default - * but they must be disbled to enter clock gating. - * UART0 and UART1 are disabled during their init - but we don't init - * UART2 so as a w/a we disable UART2 even though it isn't being used. - * we also clear UART 2 fifo, which may cause problem entrying TCG is - * not empty (we do the same for UART0 and 1 in "uart_stop_hw" - */ - - fifo_len = (REG32(UART2_BASE + UART_REG_FOR) - & FOR_OCCUPANCY_MASK) >> FOR_OCCUPANCY_OFFS; - - for (i = 0; i < fifo_len; i++) - (void)REG8((UART2_BASE + UART_REG_RBR)); - - REG32(UART2_BASE + UART_REG_ABR) = 0; + HSU_REG_GIEN = (GIEN_DMA_EN | GIEN_UART0_EN + | GIEN_UART1_EN | GIEN_PWR_MGMT); task_enable_irq(ISH_DEBUG_UART_IRQ); } void uart_init(void) { - uart_drv_init(); - uart_client_init(ISH_DEBUG_UART, B115200, 0); - init_done = 1; } |