diff options
author | Scott Collyer <scollyer@google.com> | 2020-12-12 19:12:02 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-12-22 17:42:10 +0000 |
commit | 283c0e9ebe822201b282beca8818e81fc2217c05 (patch) | |
tree | f4e17fbe6b80e54a57fd4b1c0e3536e1b3a656f1 | |
parent | 4b996f19dfc12c3bbce79601b15e325a782211db (diff) | |
download | chrome-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.h | 1 | ||||
-rw-r--r-- | chip/stm32/ucpd-stm32gx.c | 76 | ||||
-rw-r--r-- | chip/stm32/ucpd-stm32gx.h | 29 |
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 */ |