summaryrefslogtreecommitdiff
path: root/chip/npcx/uart.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/npcx/uart.c')
-rw-r--r--chip/npcx/uart.c387
1 files changed, 0 insertions, 387 deletions
diff --git a/chip/npcx/uart.c b/chip/npcx/uart.c
deleted file mode 100644
index efe991ec0b..0000000000
--- a/chip/npcx/uart.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/* Copyright 2014 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 Chrome EC */
-
-#include "clock.h"
-#include "common.h"
-#include "console.h"
-#include "gpio.h"
-#include "hwtimer.h"
-#include "hwtimer_chip.h"
-#include "lpc.h"
-#include "registers.h"
-#include "clock_chip.h"
-#include "system.h"
-#include "task.h"
-#include "timer.h"
-#include "uart.h"
-#include "uartn.h"
-#include "util.h"
-
-#define CONSOLE_UART CONFIG_CONSOLE_UART
-
-#if CONSOLE_UART
-#define CONSOLE_UART_IRQ NPCX_IRQ_UART2
-#else
-#define CONSOLE_UART_IRQ NPCX_IRQ_UART
-#endif
-
-static int init_done;
-
-#ifdef CONFIG_UART_PAD_SWITCH
-
-/* Current pad: 0 for default pad, 1 for alternate. */
-static volatile enum uart_pad pad;
-
-/*
- * When switched to alternate pad, read/write data according to the parameters
- * below.
- */
-static uint8_t *altpad_rx_buf;
-static volatile int altpad_rx_pos;
-static int altpad_rx_len;
-static uint8_t *altpad_tx_buf;
-static volatile int altpad_tx_pos;
-static int altpad_tx_len;
-
-/*
- * Time we last received a byte on default UART, we do not allow use of
- * alternate pad for block_alt_timeout_us after that, to make sure input
- * characters are not lost (either interactively, or though servod/FAFT).
- */
-static timestamp_t last_default_pad_rx_time;
-
-static const uint32_t block_alt_timeout_us = 500*MSEC;
-
-#else
-
-/* Default pad is always selected. */
-static const enum uart_pad pad = UART_DEFAULT_PAD;
-
-#endif /* CONFIG_UART_PAD_SWITCH */
-
-#if defined(CHIP_FAMILY_NPCX5)
-/* This routine switches the functionality from UART rx to GPIO */
-void npcx_uart2gpio(void)
-{
- /* Switch both pads back to GPIO mode. */
- CLEAR_BIT(NPCX_DEVALT(0x0C), NPCX_DEVALTC_UART_SL2);
- CLEAR_BIT(NPCX_DEVALT(0x0A), NPCX_DEVALTA_UART_SL1);
-}
-#endif /* CHIP_FAMILY_NPCX5 */
-
-/*
- * This routine switches the functionality from GPIO to UART rx, depending
- * on the global variable "pad". It also deactivates the previous pad.
- *
- * Note that, when switching pad, we first configure the new pad, then switch
- * off the old one, to avoid having no pad selected at a given time, see
- * b/65526215#c26.
- */
-void npcx_gpio2uart(void)
-{
-#ifdef CONFIG_UART_PAD_SWITCH
- if (pad == UART_ALTERNATE_PAD) {
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
- SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SIN__SL);
- SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SOUT_SL);
- CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SIN_SL);
- CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SOUT_SL);
-#else
- SET_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SL);
- CLEAR_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SL);
-#endif
- return;
- }
-#endif
-
-#if NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX9
- SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SIN_SL);
- SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SOUT_SL);
- CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SIN_SL);
- CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SOUT_SL);
-#else
- SET_BIT(NPCX_UART_DEVALT, NPCX_UART_DEVALT_SL);
- CLEAR_BIT(NPCX_UART_ALT_DEVALT, NPCX_UART_ALT_DEVALT_SL);
-#endif
-
-#if !NPCX_UART_MODULE2 && (NPCX_FAMILY_VERSION >= NPCX_FAMILY_NPCX7)
- /*
- * UART module 1 belongs to KSO since wake-up functionality in npcx7
- * and later chips.
- */
- CLEAR_BIT(NPCX_DEVALT(0x09), NPCX_DEVALT9_NO_KSO09_SL);
-#endif
-}
-
-int uart_init_done(void)
-{
- return init_done;
-}
-
-void uart_tx_start(void)
-{
-#if defined(CHIP_FAMILY_NPCX5)
- if (uart_is_enable_wakeup() && pad == UART_DEFAULT_PAD) {
- /* disable MIWU */
- uart_enable_wakeup(0);
- /* Set pin-mask for UART */
- npcx_gpio2uart();
- /* enable uart again from MIWU mode */
- task_enable_irq(NPCX_IRQ_UART);
- }
-#endif
-
- uartn_tx_start(CONSOLE_UART);
-}
-
-void uart_tx_stop(void)
-{
-#ifdef NPCX_UART_FIFO_SUPPORT
- uartn_tx_stop(CONSOLE_UART, 0);
-#else
- uint8_t sleep_ena;
-
- sleep_ena = (pad == UART_DEFAULT_PAD) ? 1 : 0;
- uartn_tx_stop(CONSOLE_UART, sleep_ena);
-#endif
-}
-
-void uart_tx_flush(void)
-{
- uartn_tx_flush(CONSOLE_UART);
-}
-
-int uart_tx_ready(void)
-{
- return uartn_tx_ready(CONSOLE_UART);
-}
-
-int uart_tx_in_progress(void)
-{
- return uartn_tx_in_progress(CONSOLE_UART);
-}
-
-int uart_rx_available(void)
-{
- int rx_available = uartn_rx_available(CONSOLE_UART);
-
- if (rx_available && pad == UART_DEFAULT_PAD) {
-#ifdef CONFIG_LOW_POWER_IDLE
- /*
- * Activity seen on UART RX pin while UART was disabled for deep
- * sleep. The console won't see that character because the UART
- * is disabled, so we need to inform the clock module of UART
- * activity ourselves.
- */
- clock_refresh_console_in_use();
-#endif
-#ifdef CONFIG_UART_PAD_SWITCH
- last_default_pad_rx_time = get_time();
-#endif
- }
- return rx_available; /* If RX FIFO is empty return '0'. */
-}
-
-void uart_write_char(char c)
-{
- uartn_write_char(CONSOLE_UART, c);
-}
-
-int uart_read_char(void)
-{
- return uartn_read_char(CONSOLE_UART);
-}
-
-/* Interrupt handler for Console UART */
-void uart_ec_interrupt(void)
-{
-#ifdef CONFIG_UART_PAD_SWITCH
- if (pad == UART_ALTERNATE_PAD) {
- if (uartn_rx_available(NPCX_UART_PORT0)) {
- uint8_t c = uartn_read_char(NPCX_UART_PORT0);
-
- if (altpad_rx_pos < altpad_rx_len)
- altpad_rx_buf[altpad_rx_pos++] = c;
- }
- if (uartn_tx_ready(NPCX_UART_PORT0)) {
- if (altpad_tx_pos < altpad_tx_len)
- uartn_write_char(NPCX_UART_PORT0,
- altpad_tx_buf[altpad_tx_pos++]);
- else
- uart_tx_stop();
- }
- return;
- }
-#endif
-#ifdef NPCX_UART_FIFO_SUPPORT
- if (!uartn_tx_in_progress(CONSOLE_UART)) {
- if (uart_buffer_empty()) {
- uartn_enable_tx_complete_int(CONSOLE_UART, 0);
- enable_sleep(SLEEP_MASK_UART);
- }
- }
-#endif
-
- /* Default pad. */
- /* Read input FIFO until empty, then fill output FIFO */
- uart_process_input();
- uart_process_output();
-}
-#ifdef NPCX_UART_FIFO_SUPPORT
-DECLARE_IRQ(CONSOLE_UART_IRQ, uart_ec_interrupt, 4);
-#else
-DECLARE_IRQ(CONSOLE_UART_IRQ, uart_ec_interrupt, 1);
-#endif
-
-#ifdef CONFIG_UART_PAD_SWITCH
-/*
- * Switch back to default UART pad, without flushing RX/TX buffers: If we are
- * about to panic, we just want to switch immmediately, and we don't care if we
- * output a bit of garbage.
- */
-void uart_reset_default_pad_panic(void)
-{
- pad = UART_DEFAULT_PAD;
-
- /* Configure new pad. */
- npcx_gpio2uart();
-
- /* Wait for ~2 bytes, to help the receiver resync. */
- udelay(200);
-}
-
-static void uart_set_pad(enum uart_pad newpad)
-{
-#ifdef NPCX_UART_FIFO_SUPPORT
- NPCX_UFTCTL(NPCX_UART_PORT0) &= ~0xE0;
- NPCX_UFRCTL(NPCX_UART_PORT0) &= ~0xE0;
-#else
- NPCX_UICTRL(NPCX_UART_PORT0) = 0x00;
-#endif
- task_disable_irq(NPCX_IRQ_UART);
-
- /* Flush the last byte */
- uartn_tx_flush(NPCX_UART_PORT0);
- uart_tx_stop();
-
- /*
- * Allow deep sleep when default pad is selected (sleep is inhibited
- * during TX). Disallow deep sleep when alternate pad is selected.
- */
- if (newpad == UART_DEFAULT_PAD)
- enable_sleep(SLEEP_MASK_UART);
- else
- disable_sleep(SLEEP_MASK_UART);
-
- pad = newpad;
-
- /* Configure new pad. */
- npcx_gpio2uart();
-
- /* Re-enable receive interrupt. */
- uartn_rx_int_en(NPCX_UART_PORT0);
-
- /*
- * If pad is switched while a byte is being received, the last byte may
- * be corrupted, let's wait for ~1 byte (9/115200 = 78 us + margin),
- * then flush the FIFO. See b/65526215.
- */
- udelay(100);
- uartn_clear_rx_fifo(NPCX_UART_PORT0);
-
- task_enable_irq(NPCX_IRQ_UART);
-}
-
-/* TODO(b:67026316): Remove this and replace with software flow control. */
-void uart_default_pad_rx_interrupt(enum gpio_signal signal)
-{
- /*
- * We received an interrupt on the primary pad, give up on the
- * transaction and switch back.
- */
- gpio_disable_interrupt(GPIO_UART_MAIN_RX);
-
-#ifdef CONFIG_LOW_POWER_IDLE
- clock_refresh_console_in_use();
-#endif
- last_default_pad_rx_time = get_time();
-
- uart_set_pad(UART_DEFAULT_PAD);
-}
-
-int uart_alt_pad_write_read(uint8_t *tx, int tx_len, uint8_t *rx, int rx_len,
- int timeout_us)
-{
- uint32_t start = __hw_clock_source_read();
- int ret = 0;
-
- if ((get_time().val - last_default_pad_rx_time.val)
- < block_alt_timeout_us)
- return -EC_ERROR_BUSY;
-
- cflush();
-
- altpad_rx_buf = rx;
- altpad_rx_pos = 0;
- altpad_rx_len = rx_len;
- altpad_tx_buf = tx;
- altpad_tx_pos = 0;
- altpad_tx_len = tx_len;
-
- /*
- * Turn on additional pull-up during transaction: that prevents the line
- * from going low in case the base gets disconnected during the
- * transaction. See b/68954760.
- */
- gpio_set_flags(GPIO_EC_COMM_PU, GPIO_OUTPUT | GPIO_HIGH);
-
- uart_set_pad(UART_ALTERNATE_PAD);
- gpio_clear_pending_interrupt(GPIO_UART_MAIN_RX);
- gpio_enable_interrupt(GPIO_UART_MAIN_RX);
- uartn_tx_start(NPCX_UART_PORT0);
-
- do {
- usleep(100);
-
- /* Pad switched during transaction. */
- if (pad != UART_ALTERNATE_PAD) {
- ret = -EC_ERROR_BUSY;
- goto out;
- }
-
- if (altpad_rx_pos == altpad_rx_len &&
- altpad_tx_pos == altpad_tx_len)
- break;
- } while ((__hw_clock_source_read() - start) < timeout_us);
-
- gpio_disable_interrupt(GPIO_UART_MAIN_RX);
- uart_set_pad(UART_DEFAULT_PAD);
-
- if (altpad_tx_pos == altpad_tx_len)
- ret = altpad_rx_pos;
- else
- ret = -EC_ERROR_TIMEOUT;
-
-out:
- gpio_set_flags(GPIO_EC_COMM_PU, GPIO_INPUT);
-
- altpad_rx_len = 0;
- altpad_rx_pos = 0;
- altpad_rx_buf = NULL;
- altpad_tx_len = 0;
- altpad_tx_pos = 0;
- altpad_tx_buf = NULL;
-
- return ret;
-}
-#endif
-void uart_init(void)
-{
-
- uartn_init(CONSOLE_UART);
- init_done = 1;
-}