Files
OpenCellular/chip/g/uart.c
Mary Ruthven 7d2b50f641 g: disable uart 1 and 2 during init
When the uart rx signal is not externally pulled high by the EC or AP,
the low rx signal triggers thousands of uart interrupts. At
initialization Cr50 does not know the state of those devices. If the
uart is initialized when the device is off these interrupts may prevent
Cr50 from booting on certain boards. This change does not enable the
uart until the device state is know. When the device state monitoring
detects that the AP or EC is powered on it will enable uart 1
or 2 and when it detects that it is powered off then the uart will be
disabled.

BUG=none
BRANCH=none
TEST=UART_CTRL registers are set to 0 for uart 1 and 2, and are changed
to 3 when the device state is on.

Change-Id: I43e847c6abb8507a86de92a5c226a79f3add7f97
Signed-off-by: Mary Ruthven <mruthven@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/360026
Reviewed-by: Scott Collyer <scollyer@chromium.org>
2016-07-13 19:09:19 -07:00

115 lines
2.0 KiB
C

/* Copyright (c) 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.
*/
#include "clock.h"
#include "common.h"
#include "gpio.h"
#include "registers.h"
#include "system.h"
#include "task.h"
#include "uart.h"
#include "uartn.h"
#include "util.h"
static int done_uart_init_yet;
#define USE_UART_INTERRUPTS (!(defined(CONFIG_CUSTOMIZED_RO) && \
defined(SECTION_IS_RO)))
#ifndef UARTN
#define UARTN 0
#endif
int uart_init_done(void)
{
return done_uart_init_yet;
}
void uart_tx_start(void)
{
uartn_tx_start(UARTN);
}
void uart_tx_stop(void)
{
uartn_tx_stop(UARTN);
}
int uart_tx_in_progress(void)
{
return uartn_tx_in_progress(UARTN);
}
void uart_tx_flush(void)
{
uartn_tx_flush(UARTN);
}
int uart_tx_ready(void)
{
/* True if the TX buffer is not completely full */
return uartn_tx_ready(UARTN);
}
int uart_rx_available(void)
{
/* True if the RX buffer is not completely empty. */
return uartn_rx_available(UARTN);
}
void uart_write_char(char c)
{
uartn_write_char(UARTN, c);
}
int uart_read_char(void)
{
return uartn_read_char(UARTN);
}
#if USE_UART_INTERRUPTS
/**
* Interrupt handlers for UART0
*/
void uart_ec_tx_interrupt(void)
{
/* Clear transmit interrupt status */
GR_UART_ISTATECLR(UARTN) = GC_UART_ISTATECLR_TX_MASK;
/* Fill output FIFO */
uart_process_output();
}
DECLARE_IRQ(GC_IRQNUM_UART0_TXINT, uart_ec_tx_interrupt, 1);
void uart_ec_rx_interrupt(void)
{
/* Clear receive interrupt status */
GR_UART_ISTATECLR(UARTN) = GC_UART_ISTATECLR_RX_MASK;
/* Read input FIFO until empty */
uart_process_input();
}
DECLARE_IRQ(GC_IRQNUM_UART0_RXINT, uart_ec_rx_interrupt, 1);
#endif /* USE_UART_INTERRUPTS */
void uart_init(void)
{
clock_enable_module(MODULE_UART, 1);
/* Initialize the Cr50 UART */
uartn_init(UARTN);
uartn_enable(UARTN);
#ifdef UART_AP
uartn_init(UART_AP);
#endif
#ifdef UART_EC
uartn_init(UART_EC);
#endif
done_uart_init_yet = 1;
}