From bd19b03b128db664dfb5e6582810bd177b635408 Mon Sep 17 00:00:00 2001 From: Ruibin Chang Date: Fri, 16 Nov 2018 17:18:55 +0800 Subject: it83xx/intc:message id of pd packet repeat According USB-PD spec ch.6.7.1, if transmitter sends the repetitive message id packet, receiver does not respond subsequent message(except softreset). BRANCH=None BUG=None TEST=GRL USB-PD test Change-Id: Ideea31cdf2e2d24dc70ac66f5cb830b4cb4b7d46 Signed-off-by: Ruibin Chang Reviewed-on: https://chromium-review.googlesource.com/1309564 Commit-Ready: ChromeOS CL Exonerator Bot Reviewed-by: Jett Rink --- chip/it83xx/intc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- driver/tcpm/it83xx.c | 11 +++++++++++ driver/tcpm/it83xx_pd.h | 2 ++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c index ae52a5d5a2..36a6029f9c 100644 --- a/chip/it83xx/intc.c +++ b/chip/it83xx/intc.c @@ -11,8 +11,51 @@ #include "task.h" #include "tcpm.h" #include "usb_pd.h" +#include "console.h" + +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) #ifdef CONFIG_USB_PD_TCPM_ITE83XX +/* Store each port last message id of received packet */ +static uint8_t message_id_last[USBPD_PORT_COUNT]; + +/* Invalidate last received message id variable */ +void invalidate_last_message_id(int port) +{ + /* + * Message id starts from 0 to 7. If static global variable + * message_id_last is initialed 0, it will occur repetitive message id + * with first received packet, so we initial an invalid value 0xff. + */ + message_id_last[port] = 0xff; +} + +static int consume_repeat_message(int port) +{ + uint16_t msg_header = IT83XX_USBPD_RMH(port); + int msg_id = PD_HEADER_ID(msg_header); + /* pre-set not repeat */ + int ret = 0; + + /* + * Check does message id repeat? if yes don't respond subsequent + * messages, except softreset control request. + */ + if (PD_HEADER_TYPE(msg_header) == PD_CTRL_SOFT_RESET && + PD_HEADER_CNT(msg_header) == 0) + invalidate_last_message_id(port); + else if (message_id_last[port] != msg_id) + message_id_last[port] = msg_id; + else if (message_id_last[port] == msg_id) { + /* If clear this bit, USBPD receives next packet */ + IT83XX_USBPD_MRSR(port) = USBPD_REG_MASK_RX_MSG_VALID; + CPRINTS("receive repetitive msg id: p[%d] id=%d", port, msg_id); + ret = 1; + } + + return ret; +} + static void chip_pd_irq(enum usbpd_port port) { task_clear_pending_irq(usbpd_ctrl_regs[port].irq); @@ -21,11 +64,14 @@ static void chip_pd_irq(enum usbpd_port port) if (USBPD_IS_HARD_RESET_DETECT(port)) { /* clear interrupt */ IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_HARD_RESET_DETECT; + /* Invalidate last received message id variable */ + invalidate_last_message_id(port); task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_TCPC_RESET, 0); } else { if (USBPD_IS_RX_DONE(port)) { - tcpm_enqueue_message(port); + if (!consume_repeat_message(port)) + tcpm_enqueue_message(port); /* clear RX done interrupt */ IT83XX_USBPD_ISR(port) = USBPD_REG_MASK_MSG_RX_DONE; } diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c index f4783c1725..447ba7fd1d 100644 --- a/driver/tcpm/it83xx.c +++ b/driver/tcpm/it83xx.c @@ -210,6 +210,10 @@ static enum tcpc_transmit_complete it83xx_tx_data( if (r > PD_RETRY_COUNT) return TCPC_TX_COMPLETE_DISCARDED; + /* Transmit softreset, invalidate last received message id variable */ + if (PD_HEADER_TYPE(header) == PD_CTRL_SOFT_RESET && length == 0) + invalidate_last_message_id(port); + return TCPC_TX_COMPLETE_SUCCESS; } @@ -228,6 +232,9 @@ static enum tcpc_transmit_complete it83xx_send_hw_reset(enum usbpd_port port, if (IT83XX_USBPD_MTSR0(port) & USBPD_REG_MASK_SEND_HW_RESET) return TCPC_TX_COMPLETE_FAILED; + /* Transmit hardreset, invalidate last received message id variable */ + invalidate_last_message_id(port); + return TCPC_TX_COMPLETE_SUCCESS; } @@ -328,6 +335,8 @@ static void it83xx_set_data_role(enum usbpd_port port, int pd_role) static void it83xx_init(enum usbpd_port port, int role) { + /* Invalidate last received message id variable */ + invalidate_last_message_id(port); /* bit7: Reload CC parameter setting. */ IT83XX_USBPD_CCPSR0(port) |= (1 << 7); /* reset and disable HW auto generate message header */ @@ -570,6 +579,8 @@ static int it83xx_tcpm_get_chip_info(int port, int renew, static void it83xx_tcpm_sw_reset(void) { int port = TASK_ID_TO_PD_PORT(task_get_current()); + /* Invalidate last received message id variable */ + invalidate_last_message_id(port); /* exit BIST test data mode */ USBPD_SW_RESET(port); } diff --git a/driver/tcpm/it83xx_pd.h b/driver/tcpm/it83xx_pd.h index 8eb5cab00b..c0714dd9b1 100644 --- a/driver/tcpm/it83xx_pd.h +++ b/driver/tcpm/it83xx_pd.h @@ -106,5 +106,7 @@ extern const struct usbpd_ctrl_t usbpd_ctrl_regs[]; extern const struct tcpm_drv it83xx_tcpm_drv; /* Disable integrated pd module */ void it83xx_disable_pd_module(int port); +/* Invalidate last received message id variable */ +extern void invalidate_last_message_id(int port); #endif /* __CROS_EC_DRIVER_TCPM_IT83XX_H */ -- cgit v1.2.1