diff options
Diffstat (limited to 'chip/ish/uart.c')
-rw-r--r-- | chip/ish/uart.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/chip/ish/uart.c b/chip/ish/uart.c index 63709e86c7..93df2c6504 100644 --- a/chip/ish/uart.c +++ b/chip/ish/uart.c @@ -5,6 +5,7 @@ /* UART module for ISH */ #include "common.h" +#include "math_util.h" #include "console.h" #include "uart_defs.h" #include "atomic.h" @@ -149,18 +150,25 @@ static void uart_hw_init(enum UART_PORT id) uint8_t mcr = 0; uint8_t fcr = 0; struct uart_ctx *ctx = &uart_ctx[id]; + uint8_t fraction; /* Calculate baud rate divisor */ divisor = (ctx->input_freq / ctx->baud_rate) >> 4; - - MUL(ctx->id) = (divisor * ctx->baud_rate); - DIV(ctx->id) = (ctx->input_freq / 16); - PS(ctx->id) = 16; + if (IS_ENABLED(CONFIG_ISH_DW_UART)) { + /* calculate the fractional part */ + fraction = ceil_for(ctx->input_freq, ctx->baud_rate) - (divisor << 4); + } else { + 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 */ LCR(ctx->id) = LCR_DLAB; DLL(ctx->id) = (divisor & 0xff); DLH(ctx->id) = ((divisor >> 8) & 0xff); + if (IS_ENABLED(CONFIG_ISH_DW_UART)) + DLF(ctx->id) = fraction; /* 8 data bits, 1 stop bit, no parity, clear DLAB */ LCR(ctx->id) = LCR_8BIT_CHR; @@ -169,19 +177,24 @@ static void uart_hw_init(enum UART_PORT id) mcr = MCR_AUTO_FLOW_EN; /* needs to be set regardless of flow control */ - mcr |= MCR_INTR_ENABLE; + if (!IS_ENABLED(CONFIG_ISH_DW_UART)) + mcr |= MCR_INTR_ENABLE; mcr |= (MCR_RTS | MCR_DTR); MCR(ctx->id) = mcr; - fcr = FCR_FIFO_SIZE_64 | FCR_ITL_FIFO_64_BYTES_1; + if (IS_ENABLED(CONFIG_ISH_DW_UART)) + fcr = FCR_TET_EMPTY | FCR_RT_1CHAR; + else + fcr = FCR_FIFO_SIZE_64 | FCR_ITL_FIFO_64_BYTES_1; /* configure FIFOs */ FCR(ctx->id) = (fcr | FCR_FIFO_ENABLE | FCR_RESET_RX | FCR_RESET_TX); - /* enable UART unit */ - ABR(ctx->id) = ABR_UUE; + if (!IS_ENABLED(CONFIG_ISH_DW_UART)) + /* enable UART unit */ + ABR(ctx->id) = ABR_UUE; /* clear the port */ RBR(ctx->id); @@ -197,13 +210,15 @@ static void uart_stop_hw(enum UART_PORT id) int i; uint32_t fifo_len; - /* Manually clearing the fifo from possible noise. - * Entering D0i3 when fifo is not cleared may result in a hang. - */ - fifo_len = (FOR(id) & FOR_OCCUPANCY_MASK) >> FOR_OCCUPANCY_OFFS; + if (!IS_ENABLED(CONFIG_ISH_DW_UART)) { + /* Manually clearing the fifo from possible noise. + * Entering D0i3 when fifo is not cleared may result in a hang. + */ + fifo_len = (FOR(id) & FOR_OCCUPANCY_MASK) >> FOR_OCCUPANCY_OFFS; - for (i = 0; i < fifo_len; i++) - (void)RBR(id); + for (i = 0; i < fifo_len; i++) + (void)RBR(id); + } /* No interrupts are enabled */ IER(id) = 0; @@ -212,8 +227,9 @@ static void uart_stop_hw(enum UART_PORT id) /* Clear and disable FIFOs */ FCR(id) = (FCR_RESET_RX | FCR_RESET_TX); - /* Disable uart unit */ - ABR(id) = 0; + if (!IS_ENABLED(CONFIG_ISH_DW_UART)) + /* Disable uart unit */ + ABR(id) = 0; } static int uart_client_init(enum UART_PORT id, uint32_t baud_rate_id, int flags) @@ -245,11 +261,12 @@ static void uart_drv_init(void) for (i = 0; i < UART_DEVICES; i++) uart_stop_hw(i); - /* Enable HSU global interrupts (DMA/U0/U1) and set PMEN bit - * to allow PMU to clock gate ISH - */ - HSU_REG_GIEN = (GIEN_DMA_EN | GIEN_UART0_EN - | GIEN_UART1_EN | GIEN_PWR_MGMT); + if (!IS_ENABLED(CONFIG_ISH_DW_UART)) + /* Enable HSU global interrupts (DMA/U0/U1) and set PMEN bit + * to allow PMU to clock gate ISH + */ + HSU_REG_GIEN = (GIEN_DMA_EN | GIEN_UART0_EN + | GIEN_UART1_EN | GIEN_PWR_MGMT); task_enable_irq(ISH_DEBUG_UART_IRQ); } |