summaryrefslogtreecommitdiff
path: root/chip/mec1322/uart.c
diff options
context:
space:
mode:
authorVic (Chun-Ju) Yang <victoryang@chromium.org>2013-11-05 18:50:10 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-11-21 04:30:55 +0000
commit14c7191b53607e46187cea6e95ebf869f3b85e2a (patch)
tree7eccaa37279665a6c67b46c9b43cd814bb34837c /chip/mec1322/uart.c
parent5524ba7bf71b8ee520f3c8410b65b5bba07544c4 (diff)
downloadchrome-ec-14c7191b53607e46187cea6e95ebf869f3b85e2a.tar.gz
mec1322: initial commit
This is the initial commit of mec1322 support. This includes: - Basic GPIO driver. Interrupt not supported yet. - Microsecond timer - UART driver The script to pack the firmware binary will be checked in in following-up CL. BUG=chrome-os-partner:24107 TEST=Build and boot on eval board BRANCH=None Change-Id: I9013c908049d1f740f84bb56abca51b779f39eef Signed-off-by: Vic (Chun-Ju) Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/175716 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'chip/mec1322/uart.c')
-rw-r--r--chip/mec1322/uart.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/chip/mec1322/uart.c b/chip/mec1322/uart.c
new file mode 100644
index 0000000000..351541de9d
--- /dev/null
+++ b/chip/mec1322/uart.c
@@ -0,0 +1,154 @@
+/* Copyright (c) 2013 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.
+ */
+
+/* UART module for MEC1322 */
+
+#include "clock.h"
+#include "common.h"
+#include "console.h"
+#include "gpio.h"
+#include "lpc.h"
+#include "registers.h"
+#include "system.h"
+#include "task.h"
+#include "uart.h"
+#include "util.h"
+
+static int init_done;
+
+int uart_init_done(void)
+{
+ return init_done;
+}
+
+void uart_tx_start(void)
+{
+ /* If interrupt is already enabled, nothing to do */
+ if (MEC1322_UART_IER & (1 << 1))
+ return;
+
+ /*
+ * Re-enable the transmit interrupt, then forcibly trigger the
+ * interrupt. This works around a hardware problem with the
+ * UART where the FIFO only triggers the interrupt when its
+ * threshold is _crossed_, not just met.
+ */
+ MEC1322_UART_IER |= (1 << 1);
+ task_trigger_irq(MEC1322_IRQ_UART);
+}
+
+void uart_tx_stop(void)
+{
+ MEC1322_UART_IER &= ~(1 << 1);
+}
+
+void uart_tx_flush(void)
+{
+ /* Wait for transmit FIFO empty */
+ while (!(MEC1322_UART_LSR & (1 << 5)))
+ ;
+}
+
+int uart_tx_ready(void)
+{
+ /*
+ * TODO(crosbug.com/p/24107): This is FIFO empty bit instead of
+ * FIFO full bit?
+ */
+ return MEC1322_UART_LSR & (1 << 5);
+}
+
+int uart_rx_available(void)
+{
+ return MEC1322_UART_LSR & (1 << 0);
+}
+
+void uart_write_char(char c)
+{
+ /* Wait for space in transmit FIFO. */
+ while (!uart_tx_ready())
+ ;
+
+ MEC1322_UART_TB = c;
+}
+
+int uart_read_char(void)
+{
+ return MEC1322_UART_RB;
+}
+
+static void uart_clear_rx_fifo(int channel)
+{
+ MEC1322_UART_FCR = (1 << 0) | (1 << 1);
+}
+
+void uart_disable_interrupt(void)
+{
+ task_disable_irq(MEC1322_IRQ_UART);
+}
+
+void uart_enable_interrupt(void)
+{
+ task_enable_irq(MEC1322_IRQ_UART);
+}
+
+/**
+ * Interrupt handler for UART
+ */
+static void uart_ec_interrupt(void)
+{
+ /* Read input FIFO until empty, then fill output FIFO */
+ uart_process_input();
+ uart_process_output();
+}
+DECLARE_IRQ(MEC1322_IRQ_UART, uart_ec_interrupt, 1);
+
+void uart_init(void)
+{
+ /* Set UART to reset on VCC1_RESET instaed of nSIO_RESET */
+ MEC1322_UART_CFG &= ~(1 << 1);
+
+ /* Baud rate = 115200. 1.8432MHz clock. Divisor = 1 */
+
+ /* Set CLK_SRC = 0 */
+ MEC1322_UART_CFG &= ~(1 << 0);
+
+ /* Set DLAB = 1 */
+ MEC1322_UART_LCR |= (1 << 7);
+
+ /* PBRG0/PBRG1 */
+ MEC1322_UART_PBRG0 = 1;
+ MEC1322_UART_PBRG1 = 0;
+
+ /* Set DLAB = 0 */
+ MEC1322_UART_LCR &= ~(1 << 7);
+
+ /* Set word length to 8-bit */
+ MEC1322_UART_LCR |= (1 << 0) | (1 << 1);
+
+ /* Enable FIFO */
+ MEC1322_UART_FCR = (1 << 0);
+
+ /* Activate UART */
+ MEC1322_UART_ACT |= (1 << 0);
+
+ /*
+ clock_enable_peripheral(CGC_OFFSET_UART, mask,
+ CGC_MODE_RUN | CGC_MODE_SLEEP);*/
+
+ gpio_config_module(MODULE_UART, 1);
+
+ /*
+ * Enable interrupts for UART0.
+ */
+ uart_clear_rx_fifo(0);
+ MEC1322_UART_IER |= (1 << 0);
+ MEC1322_UART_MCR |= (1 << 3);
+ MEC1322_INT_ENABLE(15) |= (1 << 0);
+ MEC1322_INT_BLK_EN |= (1 << 15);
+ task_enable_irq(MEC1322_IRQ_UART);
+
+ init_done = 1;
+}