summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Laurie <dlaurie@chromium.org>2013-05-10 09:40:29 -0700
committerChromeBot <chrome-bot@google.com>2013-05-13 19:31:09 -0700
commite5ec5f34fc25e0367bd6b89d4d93fb1d3c90c404 (patch)
treee7512d1f0b38704331f33cc839648f8884c8bae7
parentc882edb530a8b44044e4f96645edcaad035fa01d (diff)
downloadchrome-ec-e5ec5f34fc25e0367bd6b89d4d93fb1d3c90c404.tar.gz
LM4: Support configurable host UART interface
Slippy uses UART2 instead of UART1 and so the EC needs to be able to tolerate having the host use a different interface. There are of course many ways to accomplish that but this approach adds two config variables to specify the host uart and the host uart irq. The UART port setup is split out to allow them to be configured separately rather than needing to be adjacent in a for loop. The interrupt functions were renamed (to ec and host) in order to indicate which interface they are responsible for. BUG=chrome-os-partner:19356 BRANCH=none TEST=boot slippy and see host serial output Change-Id: I1913ff3d650f329224c9654eee7bb7412fae5402 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/50837
-rw-r--r--board/bds/board.h4
-rw-r--r--board/link/board.h4
-rw-r--r--board/slippy/board.h4
-rw-r--r--chip/lm4/uart.c118
4 files changed, 71 insertions, 59 deletions
diff --git a/board/bds/board.h b/board/bds/board.h
index 6f4850d769..770269a9b4 100644
--- a/board/bds/board.h
+++ b/board/bds/board.h
@@ -36,7 +36,9 @@ enum adc_channel
#define I2C_PORTS_USED 1
/* GPIOs for second UART port */
-#define CONFIG_UART1_GPIOS_PB0_1
+#define CONFIG_HOST_UART 1
+#define CONFIG_HOST_UART_IRQ LM4_IRQ_UART1
+#define CONFIG_HOST_UART1_GPIOS_PB0_1
/* GPIO signal list */
enum gpio_signal {
diff --git a/board/link/board.h b/board/link/board.h
index 9552e62b5b..b391fbaab6 100644
--- a/board/link/board.h
+++ b/board/link/board.h
@@ -94,7 +94,9 @@ enum adc_channel
#define USB_CHARGE_PORT_COUNT 2
/* GPIOs for second UART port */
-#define CONFIG_UART1_GPIOS_PC4_5
+#define CONFIG_HOST_UART 1
+#define CONFIG_HOST_UART_IRQ LM4_IRQ_UART1
+#define CONFIG_HOST_UART1_GPIOS_PC4_5
/* GPIO signal definitions. */
enum gpio_signal {
diff --git a/board/slippy/board.h b/board/slippy/board.h
index 93b0b187b9..c96f2ca4bb 100644
--- a/board/slippy/board.h
+++ b/board/slippy/board.h
@@ -58,7 +58,9 @@
#define USB_PORT_COUNT 2
/* GPIOs for second UART port */
-#define CONFIG_UART1_GPIOS_PC4_5
+#define CONFIG_HOST_UART 2
+#define CONFIG_HOST_UART_IRQ LM4_IRQ_UART2
+#define CONFIG_HOST_UART2_GPIOS_PG4_5
/* GPIO signal definitions. */
enum gpio_signal {
diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c
index 3aebbac269..e9ed2f790d 100644
--- a/chip/lm4/uart.c
+++ b/chip/lm4/uart.c
@@ -97,7 +97,7 @@ void uart_enable_interrupt(void)
/**
* Interrupt handler for UART0
*/
-static void uart_0_interrupt(void)
+static void uart_ec_interrupt(void)
{
/* Clear transmit and receive interrupt status */
LM4_UART_ICR(0) = 0x70;
@@ -106,25 +106,25 @@ static void uart_0_interrupt(void)
/* Read input FIFO until empty, then fill output FIFO */
uart_process();
}
-DECLARE_IRQ(LM4_IRQ_UART0, uart_0_interrupt, 1);
+DECLARE_IRQ(LM4_IRQ_UART0, uart_ec_interrupt, 1);
/**
- * Interrupt handler for UART1
+ * Interrupt handler for Host UART
*/
-static void uart_1_interrupt(void)
+static void uart_host_interrupt(void)
{
/* Clear transmit and receive interrupt status */
- LM4_UART_ICR(1) = 0x70;
+ LM4_UART_ICR(CONFIG_HOST_UART) = 0x70;
#ifdef CONFIG_LPC
/*
* If we have space in our FIFO and a character is pending in LPC,
* handle that character.
*/
- if (!(LM4_UART_FR(1) & 0x20) && lpc_comx_has_char()) {
+ if (!(LM4_UART_FR(CONFIG_HOST_UART) & 0x20) && lpc_comx_has_char()) {
/* Copy the next byte then disable transmit interrupt */
- LM4_UART_DR(1) = lpc_comx_get_char();
- LM4_UART_IM(1) &= ~0x20;
+ LM4_UART_DR(CONFIG_HOST_UART) = lpc_comx_get_char();
+ LM4_UART_IM(CONFIG_HOST_UART) &= ~0x20;
}
/*
@@ -133,12 +133,12 @@ static void uart_1_interrupt(void)
* because LPC is much faster than UART, and we don't have flow control
* on the UART receive-side either.
*/
- if (!(LM4_UART_FR(1) & 0x10))
- lpc_comx_put_char(LM4_UART_DR(1));
+ if (!(LM4_UART_FR(CONFIG_HOST_UART) & 0x10))
+ lpc_comx_put_char(LM4_UART_DR(CONFIG_HOST_UART));
#endif
}
/* Must be same prio as LPC interrupt handler so they don't preempt */
-DECLARE_IRQ(LM4_IRQ_UART1, uart_1_interrupt, 2);
+DECLARE_IRQ(CONFIG_HOST_UART_IRQ, uart_host_interrupt, 2);
/**
* Configure GPIOs for the UART module.
@@ -148,64 +148,70 @@ static void configure_gpio(void)
/* UART0 RX and TX are GPIO PA0:1 alternate function 1 */
gpio_set_alternate_function(LM4_GPIO_A, 0x03, 1);
-#if defined(CONFIG_UART1_GPIOS_PC4_5)
+#if defined(CONFIG_HOST_UART1_GPIOS_PC4_5)
/* UART1 RX and TX are GPIO PC4:5 alternate function 2 */
gpio_set_alternate_function(LM4_GPIO_C, 0x30, 2);
-#elif defined(CONFIG_UART1_GPIOS_PB0_1)
- /* UART1 RX and TX are GPIO PB0:1 alternate function 1*/
+#elif defined(CONFIG_HOST_UART1_GPIOS_PB0_1)
+ /* UART1 RX and TX are GPIO PB0:1 alternate function 1 */
gpio_set_alternate_function(LM4_GPIO_B, 0x03, 1);
+#elif defined(CONFIG_HOST_UART2_GPIOS_PG4_5)
+ /* UART2 RX and TX are GPIO PG4:5 alternate function 1 */
+ gpio_set_alternate_function(LM4_GPIO_G, 0x30, 1);
#else
-#error "Must put UART1 GPIOs somewhere"
+#error "Must put Host UART GPIOs somewhere"
#endif
}
+static void uart_config(int port)
+{
+ /* Disable the port */
+ LM4_UART_CTL(port) = 0x0300;
+ /* Use the internal oscillator */
+ LM4_UART_CC(port) = 0x1;
+ /* Set the baud rate divisor */
+ LM4_UART_IBRD(port) = (INTERNAL_CLOCK / 16) / BAUD_RATE;
+ LM4_UART_FBRD(port) =
+ (((INTERNAL_CLOCK / 16) % BAUD_RATE) * 64
+ + BAUD_RATE / 2) / BAUD_RATE;
+ /*
+ * 8-N-1, FIFO enabled. Must be done after setting
+ * the divisor for the new divisor to take effect.
+ */
+ LM4_UART_LCRH(port) = 0x70;
+ /*
+ * Interrupt when RX fifo at minimum (>= 1/8 full), and TX fifo
+ * when <= 1/4 full
+ */
+ LM4_UART_IFLS(port) = 0x01;
+ /*
+ * Unmask receive-FIFO, receive-timeout. We need
+ * receive-timeout because the minimum RX FIFO depth is 1/8 = 2
+ * bytes; without the receive-timeout we'd never be notified
+ * about single received characters.
+ */
+ LM4_UART_IM(port) = 0x50;
+ /* Enable the port */
+ LM4_UART_CTL(port) |= 0x0001;
+}
+
void uart_init(void)
{
volatile uint32_t scratch __attribute__((unused));
- int ch;
- /* Enable UART0 and UART1 and delay a few clocks */
- LM4_SYSTEM_RCGCUART |= 0x03;
+ /* Enable UART0 and Host UART and delay a few clocks */
+ LM4_SYSTEM_RCGCUART |= (1 << CONFIG_HOST_UART) | 1;
scratch = LM4_SYSTEM_RCGCUART;
/* Configure GPIOs */
configure_gpio();
- /* Configure UART0 and UART1 (identically) */
- for (ch = 0; ch < 2; ch++) {
- /* Disable the port */
- LM4_UART_CTL(ch) = 0x0300;
- /* Use the internal oscillator */
- LM4_UART_CC(ch) = 0x1;
- /* Set the baud rate divisor */
- LM4_UART_IBRD(ch) = (INTERNAL_CLOCK / 16) / BAUD_RATE;
- LM4_UART_FBRD(ch) =
- (((INTERNAL_CLOCK / 16) % BAUD_RATE) * 64
- + BAUD_RATE / 2) / BAUD_RATE;
- /*
- * 8-N-1, FIFO enabled. Must be done after setting
- * the divisor for the new divisor to take effect.
- */
- LM4_UART_LCRH(ch) = 0x70;
- /*
- * Interrupt when RX fifo at minimum (>= 1/8 full), and TX fifo
- * when <= 1/4 full
- */
- LM4_UART_IFLS(ch) = 0x01;
- /*
- * Unmask receive-FIFO, receive-timeout. We need
- * receive-timeout because the minimum RX FIFO depth is 1/8 = 2
- * bytes; without the receive-timeout we'd never be notified
- * about single received characters.
- */
- LM4_UART_IM(ch) = 0x50;
- /* Enable the port */
- LM4_UART_CTL(ch) |= 0x0001;
- }
+ /* Configure UARTs (identically) */
+ uart_config(0);
+ uart_config(CONFIG_HOST_UART);
/*
- * Enable interrupts for UART0 only. UART1 will have to wait until the
- * LPC bus is initialized.
+ * Enable interrupts for UART0 only. Host UART will have to wait
+ * until the LPC bus is initialized.
*/
uart_clear_rx_fifo(0);
task_enable_irq(LM4_IRQ_UART0);
@@ -218,18 +224,18 @@ void uart_init(void)
void uart_comx_enable(void)
{
- uart_clear_rx_fifo(1);
- task_enable_irq(LM4_IRQ_UART1);
+ uart_clear_rx_fifo(CONFIG_HOST_UART);
+ task_enable_irq(CONFIG_HOST_UART_IRQ);
}
int uart_comx_putc_ok(void)
{
- if (LM4_UART_FR(1) & 0x20) {
+ if (LM4_UART_FR(CONFIG_HOST_UART) & 0x20) {
/*
* FIFO is full, so enable transmit interrupt to let us know
* when it empties.
*/
- LM4_UART_IM(1) |= 0x20;
+ LM4_UART_IM(CONFIG_HOST_UART) |= 0x20;
return 0;
} else {
return 1;
@@ -238,7 +244,7 @@ int uart_comx_putc_ok(void)
void uart_comx_putc(int c)
{
- LM4_UART_DR(1) = c;
+ LM4_UART_DR(CONFIG_HOST_UART) = c;
}
/*****************************************************************************/