diff options
author | Vijay Hiremath <vijay.p.hiremath@intel.com> | 2022-06-21 09:34:42 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-07-07 17:12:03 +0000 |
commit | c906c30b89afbb65a188faadec1f0ddc03bd7a60 (patch) | |
tree | 7003e4c294f8d8b30547612e4b73ce17a8101981 /driver | |
parent | 92f620fa41c4fd08c420518a5bef201188b36f65 (diff) | |
download | chrome-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>
Diffstat (limited to 'driver')
-rw-r--r-- | driver/tcpm/ccgxxf.c | 48 |
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 |