summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuibin Chang <Ruibin.Chang@ite.com.tw>2018-11-16 17:18:55 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-29 12:11:08 -0800
commitbd19b03b128db664dfb5e6582810bd177b635408 (patch)
tree2c84666be1ae0377f787266e772dc8573c955244
parent4c3621ace087613604f6d5fb094da62434333893 (diff)
downloadchrome-ec-bd19b03b128db664dfb5e6582810bd177b635408.tar.gz
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 <Ruibin.Chang@ite.com.tw> Reviewed-on: https://chromium-review.googlesource.com/1309564 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--chip/it83xx/intc.c48
-rw-r--r--driver/tcpm/it83xx.c11
-rw-r--r--driver/tcpm/it83xx_pd.h2
3 files changed, 60 insertions, 1 deletions
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 */