summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2020-12-12 19:12:02 -0800
committerCommit Bot <commit-bot@chromium.org>2020-12-22 17:42:10 +0000
commit283c0e9ebe822201b282beca8818e81fc2217c05 (patch)
treef4e17fbe6b80e54a57fd4b1c0e3536e1b3a656f1
parent4b996f19dfc12c3bbce79601b15e325a782211db (diff)
downloadchrome-ec-283c0e9ebe822201b282beca8818e81fc2217c05.tar.gz
stm32g4: ucpd: Add missing tcpci methods
This CL adds a VCONN enabe/disable support function to remove the pull resistor and 2 addiltional functions which are required to complete the stm32gx tcpci driver. BUG=b:167601672 BRANCH=None TEST=verfied type-c attaches properly on quiche Signed-off-by: Scott Collyer <scollyer@google.com> Change-Id: I5a3732f15a5a0af9d372ae37475e9e8bdd3914b4 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2588850 Tested-by: Scott Collyer <scollyer@chromium.org> Commit-Queue: Scott Collyer <scollyer@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--chip/stm32/registers-stm32g4.h1
-rw-r--r--chip/stm32/ucpd-stm32gx.c76
-rw-r--r--chip/stm32/ucpd-stm32gx.h29
3 files changed, 103 insertions, 3 deletions
diff --git a/chip/stm32/registers-stm32g4.h b/chip/stm32/registers-stm32g4.h
index c774118159..cf4306984b 100644
--- a/chip/stm32/registers-stm32g4.h
+++ b/chip/stm32/registers-stm32g4.h
@@ -896,6 +896,7 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t;
#define STM32_SPI_SR_FTLVL (3 << 11)
/* --- Debug --- */
+#define STM32_DBGMCU_IDCODE REG32(STM32_DBGMCU_BASE + 0x00)
#define STM32_DBGMCU_CR REG32(STM32_DBGMCU_BASE + 0x04)
#define STM32_DBGMCU_APB1FZ REG32(STM32_DBGMCU_BASE + 0x08)
#define STM32_DBGMCU_APB2FZ REG32(STM32_DBGMCU_BASE + 0x0C)
diff --git a/chip/stm32/ucpd-stm32gx.c b/chip/stm32/ucpd-stm32gx.c
index 15d4fda0d7..e9693dfa1e 100644
--- a/chip/stm32/ucpd-stm32gx.c
+++ b/chip/stm32/ucpd-stm32gx.c
@@ -22,6 +22,8 @@
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
+
+#define USB_VID_STM32 0x0483
/*
* UCPD is fed directly from HSI which is @ 16MHz. The ucpd_clk goes to
* a prescaler who's output feeds the 'half-bit' divider which is used
@@ -153,6 +155,7 @@ static int ucpd_txorderset[] = {
static int ucpd_rx_byte_count;
static uint8_t ucpd_rx_buffer[UCPD_BUF_LEN];
static int ucpd_crc_id;
+static bool ucpd_rx_sop_prime_enabled;
#ifdef CONFIG_STM32G4_UCPD_DEBUG
/* Defines and macros used for ucpd pd message logging */
@@ -433,6 +436,9 @@ int stm32gx_ucpd_init(int port)
STM32_UCPD_ICR(port) = STM32_UCPD_ICR_TYPECEVT1CF |
STM32_UCPD_ICR_TYPECEVT2CF;
+ /* SOP'/SOP'' must be enabled via TCPCI call */
+ ucpd_rx_sop_prime_enabled = false;
+
/* Enable UCPD interrupts */
task_enable_irq(STM32_IRQ_UCPD1);
@@ -546,6 +552,34 @@ int stm32gx_ucpd_get_role_control(int port)
return role_control;
}
+int stm32gx_ucpd_vconn_disc_rp(int port, int enable)
+{
+ int cr = STM32_UCPD_CR(port);
+ int pol;
+ int cc_disable_mask;
+
+ /*
+ * This function is called when tcpm_set_vconn() method is called to
+ * enable VCONN. ucpd does not provide vconn, but Rp must be
+ * disconnected from the CCx line prior to enabling vconn.
+ */
+ if (enable) {
+ /* Get CC polarity */
+ pol = !!(cr & STM32_UCPD_CR_PHYCCSEL);
+ /* Disconnect cc line that is not being used for PD messaging */
+ cc_disable_mask = 1 << (STM32_UCPD_CR_CCENABLE_SHIFT + !pol);
+ cr &= ~cc_disable_mask;
+ CPRINTS("ucpd: vconn disable Rp, pol = %d, cr = %x", pol, cr);
+ } else {
+ /* make sure Rp/Rd is connected */
+ cr |= STM32_UCPD_CR_CCENABLE_MASK;
+ }
+ /* Apply cc pull resistor change */
+ STM32_UCPD_CR(port) = cr;
+
+ return EC_SUCCESS;
+}
+
int stm32gx_ucpd_set_cc(int port, int cc_pull, int rp)
{
uint32_t cr = STM32_UCPD_CR(port);
@@ -628,6 +662,26 @@ int stm32gx_ucpd_set_msg_header(int port, int power_role, int data_role)
return EC_SUCCESS;
}
+int stm32gx_ucpd_sop_prime_enable(int port, bool enable)
+{
+ /* Update static varialbe used to filter SOP//SOP'' messages */
+ ucpd_rx_sop_prime_enabled = enable;
+
+ CPRINTS("ucpd: sop_prime_enable = %d", enable);
+ return EC_SUCCESS;
+}
+
+int stm32gx_ucpd_get_chip_info(int port, int live,
+ struct ec_response_pd_chip_info_v1 *chip_info)
+{
+ chip_info->vendor_id = USB_VID_STM32;
+ chip_info->product_id = 0;
+ chip_info->device_id = STM32_DBGMCU_IDCODE & 0xfff;
+ chip_info->fw_version_number = 0xEC;
+
+ return EC_SUCCESS;
+}
+
static int stm32gx_ucpd_start_transmit(int port, enum ucpd_tx_msg msg_type)
{
enum tcpm_transmit_type type;
@@ -1079,12 +1133,28 @@ void stm32gx_ucpd1_irq(void)
if (!(sr & STM32_UCPD_SR_RXERR)) {
int rv;
uint16_t *rx_header = (uint16_t *)ucpd_rx_buffer;
+ enum tcpm_transmit_type type;
+ int good_crc = 0;
+
+ type = STM32_UCPD_RX_ORDSETR(port) &
+ STM32_UCPD_RXORDSETR_MASK;
+
+ good_crc = ucpd_msg_is_good_crc(*rx_header);
#ifdef CONFIG_STM32G4_UCPD_DEBUG
ucpd_log_add_msg(*rx_header, 1);
#endif
- /* Don't pass GoodCRC control messages TCPM */
- if (!ucpd_msg_is_good_crc(*rx_header)) {
+ /*
+ * Don't pass GoodCRC control messages to the TCPM
+ * layer. In addition, need to filter for SOP'/SOP''
+ * packets if those are not enabled. SOP'/SOP''
+ * reception is controlled by a static variable. The
+ * hardware orderset detection pattern can't be changed
+ * without disabling the ucpd peripheral.
+ */
+ if (!good_crc && (ucpd_rx_sop_prime_enabled ||
+ type == TCPC_TX_SOP)) {
+
/* TODO - Add error checking here */
rv = tcpm_enqueue_message(port);
if (rv)
@@ -1092,7 +1162,7 @@ void stm32gx_ucpd1_irq(void)
0);
/* Send GoodCRC message (if required) */
ucpd_send_good_crc(port, *rx_header);
- } else {
+ } else if (good_crc) {
task_set_event(TASK_ID_UCPD,
UCPD_EVT_RX_GOOD_CRC);
ucpd_crc_id = PD_HEADER_ID(*rx_header);
diff --git a/chip/stm32/ucpd-stm32gx.h b/chip/stm32/ucpd-stm32gx.h
index 92cd28b8a0..06408ab8dc 100644
--- a/chip/stm32/ucpd-stm32gx.h
+++ b/chip/stm32/ucpd-stm32gx.h
@@ -158,4 +158,33 @@ int stm32gx_ucpd_transmit(int port,
*/
int stm32gx_ucpd_get_message_raw(int port, uint32_t *payload, int *head);
+/**
+ * STM32Gx method to remove Rp when VCONN is being supplied
+ *
+ * @param usbc_port -> USB-C Port number
+ * @param enable -> connect/disc Rp
+ * @return EC_SUCCESS
+ */
+int stm32gx_ucpd_vconn_disc_rp(int port, int enable);
+
+/**
+ * STM32Gx UCPD implementation of tcpci .sop_prime_enable method
+ *
+ * @param usbc_port -> USB-C Port number
+ * @param enable -> control of SOP'/SOP'' messages
+ * @return EC_SUCCESS
+ */
+int stm32gx_ucpd_sop_prime_enable(int port, bool enable);
+
+int stm32gx_ucpd_get_chip_info(int port, int live,
+ struct ec_response_pd_chip_info_v1 *chip_info);
+
+/**
+ * This function is used to enable/disable a ucpd debug feature that is used to
+ * mark the ucpd message log when there is a usbc detach event.
+ *
+ * @param enable -> on/off control for debug feature
+ */
+void ucpd_cc_detect_notify_enable(int enable);
+
#endif /* __CROS_EC_UCPD_STM32GX_H */