summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamyoon Woo <namyoon@chromium.org>2020-01-23 18:47:51 -0800
committerCommit Bot <commit-bot@chromium.org>2020-02-19 20:40:15 +0000
commit88025bd9551eb73e21221279df415a39444d076c (patch)
tree67a3424f5fffe5bbd70083ac7378dd9bbbbccf70
parentecef6be26f54aba46569b4a578442565cc2ffcba (diff)
downloadchrome-ec-88025bd9551eb73e21221279df415a39444d076c.tar.gz
control EC USB-UART bridge
This CL separates the control on USB-UART bridge of EC device from EC UART control. USB-UART bridge shall be enabled if CCD connection is detected and the CCD capability is enabled. Otherwise, EC USB-UART shall be disabled. By doing so, CCD capability can be observed even when EC-CR50 communication enables EC UART. This patch increases the flash usage by 204 bytes BUG=b:148247228 BRANCH=cr50, cr50_mp TEST=ran firmware_Cr50CCDServoCap on Helios. > ccd State: Locked Password: none Flags: 0x000001 Capabilities: 0000000000000000 ... > ccdstate AP: on AP UART: on EC: on Rdd: connected Servo: connected CCD EXT: enabled State flags: UARTAP UARTEC I2C USBEC > ccdstate AP: on AP UART: on EC: on Rdd: connected Servo: disconnected CCD EXT: enabled State flags: UARTAP+TX UARTEC USBEC CCD ports blocked: (none) > ccd State: Opened Password: none Flags: 0x800001 Capabilities: 5555454115000000 ... > ccdstate AP: on AP UART: on EC: on Rdd: connected Servo: connected CCD EXT: enabled State flags: UARTAP UARTEC I2C USBEC+TX CCD ports blocked: (none) > ccdstate AP: on AP UART: on EC: on Rdd: connected Servo: undetectable CCD EXT: enabled State flags: UARTAP+TX UARTEC+TX I2C SPI USBEC+TX CCD ports blocked: (none) Change-Id: I6bb560a05831105ff68a9e13e4b28b002ed98096 Signed-off-by: Namyoon Woo <namyoon@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2018061 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
-rw-r--r--board/cr50/rdd.c28
-rw-r--r--chip/g/usart.c60
-rw-r--r--chip/g/usart.h9
3 files changed, 89 insertions, 8 deletions
diff --git a/board/cr50/rdd.c b/board/cr50/rdd.c
index 21d1357df8..9cc217129c 100644
--- a/board/cr50/rdd.c
+++ b/board/cr50/rdd.c
@@ -15,6 +15,7 @@
#include "system.h"
#include "uart_bitbang.h"
#include "uartn.h"
+#include "usart.h"
#include "usb_api.h"
#include "usb_console.h"
#include "usb_i2c.h"
@@ -134,6 +135,12 @@ enum ccd_state_flag {
/* SPI port is enabled for AP and/or EC flash */
CCD_ENABLE_SPI = BIT(6),
+
+ /* EC data bridging from UART to USB is enabled. */
+ CCD_ENABLE_USB_FROM_UART_EC = BIT(7),
+
+ /* EC data bridging from USB to UART is enabled. */
+ CCD_ENABLE_USB_TO_UART_EC = BIT(8),
};
int console_is_restricted(void)
@@ -168,6 +175,11 @@ static uint32_t get_state_flags(void)
if (ccd_usb_spi.state->enabled_device)
flags_now |= CCD_ENABLE_SPI;
+ if (uart_ec_bridge_is_enabled())
+ flags_now |= CCD_ENABLE_USB_FROM_UART_EC;
+ if (uart_ec_bridge_tx_is_enabled())
+ flags_now |= CCD_ENABLE_USB_TO_UART_EC;
+
return flags_now;
}
@@ -193,6 +205,10 @@ static void print_state_flags(enum console_channel channel, uint32_t flags)
cprintf(channel, " I2C");
if (flags & CCD_ENABLE_SPI)
cprintf(channel, " SPI");
+ if (flags & CCD_ENABLE_USB_FROM_UART_EC)
+ cprintf(channel, " USBEC");
+ if (flags & CCD_ENABLE_USB_TO_UART_EC)
+ cprintf(channel, "+TX");
}
static void ccd_state_change_hook(void)
@@ -223,6 +239,8 @@ static void ccd_state_change_hook(void)
*/
if (ccd_ext_is_enabled())
flags_want |= (CCD_ENABLE_UART_AP_TX | CCD_ENABLE_UART_EC_TX |
+ CCD_ENABLE_USB_FROM_UART_EC |
+ CCD_ENABLE_USB_TO_UART_EC |
CCD_ENABLE_I2C | CCD_ENABLE_SPI);
else
flags_want = 0;
@@ -241,9 +259,14 @@ static void ccd_state_change_hook(void)
if (!ccd_is_cap_enabled(CCD_CAP_GSC_TX_AP_RX))
flags_want &= ~CCD_ENABLE_UART_AP_TX;
if (!ccd_is_cap_enabled(CCD_CAP_GSC_RX_EC_TX))
- flags_want &= ~CCD_ENABLE_UART_EC;
+ flags_want &= ~CCD_ENABLE_USB_FROM_UART_EC;
+ /*
+ * UART_EC TX needs to be disconnected as well as USB RX, otherwise
+ * Servo is not detectable.
+ */
if (!ccd_is_cap_enabled(CCD_CAP_GSC_TX_EC_RX))
flags_want &= ~(CCD_ENABLE_UART_EC_TX |
+ CCD_ENABLE_USB_TO_UART_EC |
CCD_ENABLE_UART_EC_BITBANG);
if (!ccd_is_cap_enabled(CCD_CAP_I2C))
flags_want &= ~CCD_ENABLE_I2C;
@@ -272,6 +295,9 @@ static void ccd_state_change_hook(void)
if (!(flags_want & CCD_ENABLE_UART_EC))
flags_want &= ~CCD_ENABLE_UART_EC_TX;
+ uart_ec_bridge_enable(flags_want & CCD_ENABLE_USB_FROM_UART_EC,
+ flags_want & CCD_ENABLE_USB_TO_UART_EC);
+
/* If no change, we're done */
if (flags_now == flags_want)
return;
diff --git a/chip/g/usart.c b/chip/g/usart.c
index d7ca39ea14..68ab726814 100644
--- a/chip/g/usart.c
+++ b/chip/g/usart.c
@@ -129,19 +129,57 @@ USB_STREAM_CONFIG(ec_usb,
ec_uart_to_usb)
#endif
+#ifdef BOARD_CR50
+static uint8_t ec_bridge_enabled_;
+static uint8_t ec_bridge_tx_enabled_;
+
+void uart_ec_bridge_enable(int enable, int write)
+{
+ write = enable && write;
+
+ if (write && !ec_bridge_tx_enabled_)
+ task_trigger_irq(GC_IRQNUM_UART2_TXINT);
+
+ ec_bridge_enabled_ = enable;
+ ec_bridge_tx_enabled_ = write;
+}
+
+int uart_ec_bridge_is_enabled(void)
+{
+ return !!ec_bridge_enabled_;
+}
+
+int uart_ec_bridge_tx_is_enabled(void)
+{
+ return !!ec_bridge_tx_enabled_;
+}
+
+#endif /* BOARD_CR50 */
+
void get_data_from_usb(struct usart_config const *config)
{
struct queue const *uart_out = config->consumer.queue;
int c;
#ifdef BOARD_CR50
- /*
- * If EC-CR50 communication is on-going, then let's not forward
- * console input to EC for now.
- */
- if (ec_comm_is_uart_in_packet_mode(config->uart))
- return;
-#endif
+ if (config->uart == UART_EC) {
+ /*
+ * If USB-to-UART bridging is disabled, drop all input data.
+ * Otherwise, data could be pushed into UART TX FIFO, and
+ * transferred to EC eventually once EC-CR50 communication
+ * enables EC UART.
+ */
+ if (!ec_bridge_tx_enabled_)
+ return;
+
+ /*
+ * If EC-CR50 communication is on-going, then let's not forward
+ * console input to EC for now.
+ */
+ if (ec_comm_is_uart_in_packet_mode(UART_EC))
+ return;
+ }
+#endif /* BOARD_CR50 */
/* Copy output from buffer until TX fifo full or output buffer empty */
while (queue_count(uart_out) && QUEUE_REMOVE_UNITS(uart_out, &c, 1))
@@ -170,6 +208,14 @@ void send_data_to_usb(struct usart_config const *config)
tail = uart_in->state->tail & mask;
count = 0;
+#ifdef BOARD_CR50
+ /*
+ * If UART-to-USB bridging is not allowed, do not put any output
+ * data to uart_in queue.
+ */
+ if ((uart == UART_EC) && !ec_bridge_enabled_)
+ return;
+#endif /* BOARD_CR50 */
/*
* TODO(b/119329144): Process packet data separately,
* and filter console data based on ccd capability.
diff --git a/chip/g/usart.h b/chip/g/usart.h
index cd3a9cfe40..2d9f04974f 100644
--- a/chip/g/usart.h
+++ b/chip/g/usart.h
@@ -74,4 +74,13 @@ void get_data_from_usb(struct usart_config const *config);
/* Helper for UART bitbang mode. */
extern struct usart_config const ec_uart;
+/* Change EC UART-USB Bridge status */
+void uart_ec_bridge_enable(int enabled, int write);
+
+/* Return non-zero if EC UART-USB Bridge is enabled, or 0 otherwise */
+int uart_ec_bridge_is_enabled(void);
+
+/* Return non-zero if EC UART-USB Bridge is readwritable, or 0 otherwise */
+int uart_ec_bridge_tx_is_enabled(void);
+
#endif /* __CROS_FORWARD_UART_H */