summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-02-06 13:41:43 -0800
committerRandall Spangler <rspangler@chromium.org>2012-02-06 14:53:49 -0800
commit300e7edb87b9f19bcf0a91a9c0273106e646d897 (patch)
tree5c5a4b7afcf6f3d7db6144f592204281cc239158 /chip
parent6409913523b047ca7b1dd39bb51edf11f3eefdaa (diff)
downloadchrome-ec-300e7edb87b9f19bcf0a91a9c0273106e646d897.tar.gz
Add UART1 receive support (UART to x86 console)
Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:7488 TEST=type things into the x86 console UART; should appear on the u-boot prompt Change-Id: I75fd225842c03d11d79280fb7453ad37695279e3
Diffstat (limited to 'chip')
-rw-r--r--chip/lm4/lpc.c31
-rw-r--r--chip/lm4/uart.c9
2 files changed, 22 insertions, 18 deletions
diff --git a/chip/lm4/lpc.c b/chip/lm4/lpc.c
index e7841576ec..674d35aebd 100644
--- a/chip/lm4/lpc.c
+++ b/chip/lm4/lpc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
@@ -137,8 +137,12 @@ int lpc_init(void)
/* TODO: could configure IRQSELs and set IRQEN2/CX, and then the host
* can enable IRQs on its own. */
LM4_LPC_CTL(LPC_CH_COMX) = 0x0004 | (LPC_POOL_OFFS_COMX << (5 - 1));
- /* Use our LPC interrupt handler to notify COMxIM on write-from-host */
- LM4_LPC_LPCDMACX = 0x00110000;
+ /* Enable COMx emulation for reads and writes. */
+ LM4_LPC_LPCDMACX = 0x00310000;
+ /* Unmask interrupt for host data writes. We don't need interrupts for
+ * reads, because there's no flow control in that direction; LPC is
+ * much faster than the UART, and the UART doesn't have anywhere
+ * sensible to buffer input anyway. */
LM4_LPC_LPCIM |= LM4_LPC_INT_MASK(LPC_CH_COMX, 2);
/* Enable LPC channels */
@@ -188,6 +192,7 @@ int lpc_keyboard_has_char(void) {
return (LM4_LPC_ST(LPC_CH_KEYBOARD) & (1 << 0 /* TOH */)) ? 1 : 0;
}
+
void lpc_keyboard_put_char(uint8_t chr, int send_irq) {
LPC_POOL_KEYBOARD[1] = chr;
if (send_irq) {
@@ -204,15 +209,17 @@ int lpc_comx_has_char(void)
int lpc_comx_get_char(void)
{
- /* TODO: (crosbug.com/p/7488) this clears the receive-ready interrupt
- * too, which will be ok once we're handing output to COMx as well.
- * But we're not yet. */
- LM4_LPC_LPCDMACX = LM4_LPC_LPCDMACX;
- /* Copy the next byte */
return LPC_POOL_COMX[0];
}
+void lpc_comx_put_char(int c)
+{
+ LPC_POOL_COMX[1] = c;
+ /* TODO: manually trigger IRQ, like we do for keyboard? */
+}
+
+
/* LPC interrupt handler */
static void lpc_interrupt(void)
@@ -268,20 +275,12 @@ static void lpc_interrupt(void)
/* Handle COMx */
if (mis & LM4_LPC_INT_MASK(LPC_CH_COMX, 2)) {
- uint32_t cis = LM4_LPC_LPCDMACX;
- /* Clear the interrupt reasons we're handling */
- LM4_LPC_LPCDMACX = cis;
-
/* Handle host writes */
if (lpc_comx_has_char()) {
/* Copy a character to the UART if there's space */
if (uart_comx_putc_ok())
uart_comx_putc(lpc_comx_get_char());
}
-
- /* TODO: (crosbug.com/p/7488) handle UART input to host - if
- * host read the to-host data, see if there's another byte
- * still waiting on UART1. */
}
}
diff --git a/chip/lm4/uart.c b/chip/lm4/uart.c
index 7fa01dec7a..1f4205d4fd 100644
--- a/chip/lm4/uart.c
+++ b/chip/lm4/uart.c
@@ -104,6 +104,13 @@ static void uart_1_interrupt(void)
LM4_UART_DR(1) = lpc_comx_get_char();
LM4_UART_IM(1) &= ~0x20;
}
+
+ /* Handle received character. There is no flow control on input;
+ * received characters are blindly forwarded to LPC. This is ok
+ * 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));
}
/* Must be same prio as LPC interrupt handler so they don't preempt */
DECLARE_IRQ(LM4_IRQ_UART1, uart_1_interrupt, 2);
@@ -183,11 +190,9 @@ int uart_init(void)
return EC_SUCCESS;
}
-
/*****************************************************************************/
/* COMx functions */
-
int uart_comx_putc_ok(void)
{
if (LM4_UART_FR(1) & 0x20) {