summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2022-06-21 09:34:42 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-07-07 17:12:03 +0000
commitc906c30b89afbb65a188faadec1f0ddc03bd7a60 (patch)
tree7003e4c294f8d8b30547612e4b73ce17a8101981
parent92f620fa41c4fd08c420518a5bef201188b36f65 (diff)
downloadchrome-ec-c906c30b89afbb65a188faadec1f0ddc03bd7a60.tar.gz
ccgxxf: Return cached CC state on I2C failure
Once the PD negotiation completes, CCGXXF chip stops responding over I2C for about 10 seconds. As DRP is enabled, TCPM algorithm constantly looks for any CC status changes even after negotiation completes. Hence, cache the CC state and return the cached values in case of I2C failures. This workaround will be removed once the fix is added in the physical layer firmware of CCGXXF. BUG=b:236994474 BRANCH=none TEST=Able to negotiate USB/DP/TBT/USB4 on MTLRVP Change-Id: Ia51b6accca3e9fa0d49b9b27915c4f95c62e35be Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3715434 Reviewed-by: Diana Z <dzigterman@chromium.org> Reviewed-by: RAJESH KUMAR <rajesh3.kumar@intel.com>
-rw-r--r--driver/tcpm/ccgxxf.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/driver/tcpm/ccgxxf.c b/driver/tcpm/ccgxxf.c
index 216b812e5e..2c8431f474 100644
--- a/driver/tcpm/ccgxxf.c
+++ b/driver/tcpm/ccgxxf.c
@@ -9,6 +9,50 @@
#include "console.h"
#include "tcpm/tcpci.h"
+/*
+ * TODO (b/236994474): Once the PD negotiation completes, CCGXXF chip stops
+ * responding over I2C for about 10 seconds. As DRP is enabled, TCPM algorithm
+ * constantly looks for any CC status changes even after negotiation completes.
+ * Hence, cache the CC state and return the cached values in case of I2C
+ * failures. This workaround will be removed once the fix is added in the
+ * physical layer firmware of CCGXXF.
+ */
+
+struct ccgxxf_cc {
+ bool good_cc;
+ enum tcpc_cc_voltage_status cc1;
+ enum tcpc_cc_voltage_status cc2;
+};
+
+static struct ccgxxf_cc ccgxxf_cc_cache[CONFIG_USB_PD_PORT_MAX_COUNT];
+
+static int ccgxxf_tcpci_tcpm_get_cc(int port, enum tcpc_cc_voltage_status *cc1,
+ enum tcpc_cc_voltage_status *cc2)
+{
+ int rv = tcpci_tcpm_get_cc(port, cc1, cc2);
+
+ if (rv) {
+ if (!ccgxxf_cc_cache[port].good_cc)
+ return rv;
+
+ *cc1 = ccgxxf_cc_cache[port].cc1;
+ *cc2 = ccgxxf_cc_cache[port].cc2;
+ } else {
+ ccgxxf_cc_cache[port].good_cc = true;
+ ccgxxf_cc_cache[port].cc1 = *cc1;
+ ccgxxf_cc_cache[port].cc2 = *cc2;
+ }
+
+ return EC_SUCCESS;
+}
+
+static int ccgxxf_tcpci_tcpm_init(int port)
+{
+ ccgxxf_cc_cache[port].good_cc = false;
+
+ return tcpci_tcpm_init(port);
+}
+
#ifdef CONFIG_USB_PD_TCPM_SBU
static int ccgxxf_tcpc_set_sbu(int port, bool enable)
{
@@ -38,9 +82,9 @@ int ccgxxf_reset(int port)
}
const struct tcpm_drv ccgxxf_tcpm_drv = {
- .init = &tcpci_tcpm_init,
+ .init = &ccgxxf_tcpci_tcpm_init,
.release = &tcpci_tcpm_release,
- .get_cc = &tcpci_tcpm_get_cc,
+ .get_cc = &ccgxxf_tcpci_tcpm_get_cc,
#ifdef CONFIG_USB_PD_VBUS_DETECT_TCPC
.check_vbus_level = &tcpci_tcpm_check_vbus_level,
#endif