mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-04 22:11:41 +00:00
cr50: Only enable UART RX when EC/AP is on
Previously, some code paths such as CCD permissions change could result in enabling EC or AP UART RX when the EC or AP is off. This could result in interrupt storms. BUG=none BRANCH=cr50 TEST=manual // Initial conditions Assert CCD_MODE_L Deassert DETECT_SERVO // Both RX and TX disabled when processor turns off // and re-enabled when it turns back on Deassert DETECT_EC ccd -> EC UART disabled Assert DETECT_EC ccd --> EC UART RX+TX Deassert DETECT_AP ccd -> AP UART disabled Assert DETECT_AP ccd --> AP UART RX+TX // TX disabled when CCD disabled Deassert CCD_MODE_L ccd --> EC UART RX, AP UART RX Assert DETECT_SERVO ccd --> EC UART RX, AP UART RX // Don't enable TX when detecting EC, if servo is connected Deassert DETECT_EC ccd -> EC UART disabled Assert DETECT_EC ccd --> EC UART RX // Don't enable TX when detecting CCD, if servo is connected Assert CCD_MODE_L ccd --> EC UART RX, AP UART RX // When servo disconnects, enable TX if CCD is connected Deassert DETECT_SERVO ccd --> EC UART RX+TX, AP UART RX+TX Change-Id: Icb144c23e949afb0384c242965aa729b078b03eb Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/642349 Reviewed-by: Mary Ruthven <mruthven@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
b52f9b8ea6
commit
8202ddaa95
@@ -976,10 +976,25 @@ static int servo_state_unknowable(void)
|
||||
|
||||
void enable_ccd_uart(int uart)
|
||||
{
|
||||
if (uart == UART_EC) {
|
||||
/*
|
||||
* Only enable the UART if we have receive permission, and if the
|
||||
* processor we're talking to is on. When the processor is off, its
|
||||
* transmit line (our receive line) may float, leading to interrupt
|
||||
* storms.
|
||||
*/
|
||||
if (uart == UART_AP) {
|
||||
if (!ccd_is_cap_enabled(CCD_CAP_AP_TX_CR50_RX))
|
||||
return;
|
||||
|
||||
if (!ap_is_on())
|
||||
return;
|
||||
} else {
|
||||
if (!ccd_is_cap_enabled(CCD_CAP_EC_TX_CR50_RX))
|
||||
return;
|
||||
|
||||
if (!ec_is_on())
|
||||
return;
|
||||
|
||||
/*
|
||||
* For the EC UART, we can't connect the TX pin to the UART
|
||||
* block when it's in bit bang mode.
|
||||
@@ -988,13 +1003,10 @@ void enable_ccd_uart(int uart)
|
||||
return;
|
||||
}
|
||||
|
||||
if (uart == UART_AP && !ccd_is_cap_enabled(CCD_CAP_AP_TX_CR50_RX))
|
||||
return;
|
||||
|
||||
/* Enable RX and TX on the UART peripheral */
|
||||
uartn_enable(uart);
|
||||
|
||||
/* Connect the TX pin to the UART TX Signal */
|
||||
/* Connect the TX pin to the UART TX signal */
|
||||
if (!uart_tx_is_connected(uart))
|
||||
uartn_tx_connect(uart);
|
||||
}
|
||||
|
||||
@@ -19,16 +19,6 @@
|
||||
|
||||
#define CPRINTS(format, args...) cprints(CC_USB, format, ## args)
|
||||
|
||||
struct uart_config {
|
||||
const char *name;
|
||||
int tx_signal;
|
||||
};
|
||||
|
||||
static struct uart_config uarts[] = {
|
||||
[UART_AP] = {"AP", GC_PINMUX_UART1_TX_SEL},
|
||||
[UART_EC] = {"EC", GC_PINMUX_UART2_TX_SEL},
|
||||
};
|
||||
|
||||
int rdd_is_connected(void)
|
||||
{
|
||||
return ccd_get_mode() == CCD_MODE_ENABLED;
|
||||
@@ -68,25 +58,31 @@ int servo_is_connected(void)
|
||||
|
||||
void uartn_tx_connect(int uart)
|
||||
{
|
||||
if (uart == UART_AP && !ccd_is_cap_enabled(CCD_CAP_AP_RX_CR50_TX))
|
||||
/*
|
||||
* Don't drive TX unless the debug cable is connected (we have
|
||||
* something to transmit) and servo is disconnected (we won't be
|
||||
* drive-fighting with servo).
|
||||
*/
|
||||
if (servo_is_connected() || !rdd_is_connected())
|
||||
return;
|
||||
|
||||
if (uart == UART_EC && !ccd_is_cap_enabled(CCD_CAP_EC_RX_CR50_TX))
|
||||
return;
|
||||
if (uart == UART_AP) {
|
||||
if (!ccd_is_cap_enabled(CCD_CAP_AP_RX_CR50_TX))
|
||||
return;
|
||||
|
||||
if (!rdd_is_connected())
|
||||
return;
|
||||
if (!ap_is_on())
|
||||
return;
|
||||
|
||||
if (servo_is_connected()) {
|
||||
CPRINTS("Servo is attached cannot enable %s UART",
|
||||
uarts[uart].name);
|
||||
return;
|
||||
uart_select_tx(UART_AP, GC_PINMUX_UART1_TX_SEL);
|
||||
} else {
|
||||
if (!ccd_is_cap_enabled(CCD_CAP_EC_RX_CR50_TX))
|
||||
return;
|
||||
|
||||
if (!ec_is_on())
|
||||
return;
|
||||
|
||||
uart_select_tx(UART_EC, GC_PINMUX_UART2_TX_SEL);
|
||||
}
|
||||
|
||||
if (uart == UART_AP ? ap_is_on() : ec_is_on())
|
||||
uart_select_tx(uart, uarts[uart].tx_signal);
|
||||
else if (!uart_tx_is_connected(uart))
|
||||
CPRINTS("%s is powered off", uarts[uart].name);
|
||||
}
|
||||
|
||||
void uartn_tx_disconnect(int uart)
|
||||
|
||||
Reference in New Issue
Block a user