diff options
author | Eric Herrmann <eherrmann@chromium.org> | 2021-03-25 19:16:25 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-31 22:47:20 +0000 |
commit | d3c52ae401f9190377cc4f1feb24300491fdc922 (patch) | |
tree | df44d1a26ef1d1d17824f69289b27cb2ca502aa3 /driver/ppc/syv682x.c | |
parent | 562676b526dfa9c35bfbe2b4dd36c35da13d566a (diff) | |
download | chrome-ec-d3c52ae401f9190377cc4f1feb24300491fdc922.tar.gz |
SYV682x: Fix Source OCP for SYV682B revision
Force the EC to wait at least 15ms before checking to see if the alerts
are cleared.
This will fix source OCP for the SYV682B, which added a 10ms HW deglitch
to the source OC alert.
BUG=b:183761055
TEST=Check that OCP is triggered instead of TSD when the port is
overloaded on SYV682B
TEST=Check that the SYV682A OCP still works with 100ms deglitch
TEST=make buildall
BRANCH=None
Signed-off-by: Eric Herrmann <eherrmann@chromium.org>
Change-Id: I40207fecc034a8e8238f0deaa7beeaf8dab2a2d6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2787706
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Diffstat (limited to 'driver/ppc/syv682x.c')
-rw-r--r-- | driver/ppc/syv682x.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/driver/ppc/syv682x.c b/driver/ppc/syv682x.c index fe1b85b607..e66411fd0a 100644 --- a/driver/ppc/syv682x.c +++ b/driver/ppc/syv682x.c @@ -39,15 +39,22 @@ static timestamp_t vconn_oc_timer[CONFIG_USB_PD_PORT_MAX_COUNT]; #define SYV682X_VBUS_DET_THRESH_MV 4000 /* Longest time that can be programmed in DSG_TIME field */ -#define SYV682X_MAX_VBUS_DISCHARGE_TIME_MS 400 -/* Delay between checks when polling the interrupt registers */ -#define INTERRUPT_DELAY_MS 10 +#define SYV682X_MAX_VBUS_DISCHARGE_TIME_MS 400 +/* + * Delay between checks when polling the interrupt registers. Must be longer + * than the HW deglitch on OC (10ms) + */ +#define INTERRUPT_DELAY_MS 15 /* Deglitch in ms of sourcing overcurrent detection */ #define SOURCE_OC_DEGLITCH_MS 100 #define VCONN_OC_DEGLITCH_MS 100 /* Max. number of OC events allowed before disabling port */ #define OCP_COUNT_LIMIT 3 +#if INTERRUPT_DELAY_MS <= SYV682X_HW_OC_DEGLITCH_MS +#error "INTERRUPT_DELAY_MS should be greater than SYV682X_HW_OC_DEGLITCH_MS" +#endif + #if SOURCE_OC_DEGLITCH_MS < INTERRUPT_DELAY_MS #error "SOURCE_OC_DEGLITCH_MS should be at least INTERRUPT_DELAY_MS" #endif @@ -563,20 +570,15 @@ static void syv682x_handle_interrupt(int port) /* * Since ALERT_L is level-triggered, check the alert status and repeat - * until all interrupts are cleared. This will not spam indefinitely on - * OCP, but may on OVP, RVS, or TSD + * until all interrupts are cleared. The SYV682B and later have a 10ms + * deglitch on OC, so make sure not to check the status register again + * for at least 10ms to give it time to re-trigger. This will not spam + * indefinitely on OCP, but may on OVP, RVS, or TSD. */ - if (IS_ENABLED(CONFIG_USBC_PPC_DEDICATED_INT) && - ppc_get_alert_status(port)) { + if (status & SYV682X_STATUS_INT_MASK || + control4 & SYV682X_CONTROL_4_INT_MASK) { syv682x_interrupt_delayed(port, INTERRUPT_DELAY_MS); - } else { - read_reg(port, SYV682X_CONTROL_4_REG, &control4); - read_reg(port, SYV682X_STATUS_REG, &status); - if (status & SYV682X_STATUS_INT_MASK || - control4 & SYV682X_CONTROL_4_INT_MASK) { - syv682x_interrupt_delayed(port, INTERRUPT_DELAY_MS); - } } } |