summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Herrmann <eherrmann@chromium.org>2021-03-25 19:16:25 -0700
committerCommit Bot <commit-bot@chromium.org>2021-04-01 18:00:01 +0000
commite724cd221302fd4d03a308133416d954f6a2a909 (patch)
treea3a21c2378b840ff0b75e92c62e75e3427674188
parent9a34228e865a6567350e416f1877e885ed17d27b (diff)
downloadchrome-ec-e724cd221302fd4d03a308133416d954f6a2a909.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> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2799921 Tested-by: Abe Levkoy <alevkoy@chromium.org> Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r--driver/ppc/syv682x.c30
-rw-r--r--driver/ppc/syv682x.h3
2 files changed, 19 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);
- }
}
}
diff --git a/driver/ppc/syv682x.h b/driver/ppc/syv682x.h
index 0afa56190f..3ecbede18c 100644
--- a/driver/ppc/syv682x.h
+++ b/driver/ppc/syv682x.h
@@ -10,6 +10,9 @@
#include "driver/ppc/syv682x_public.h"
+/* Source OC deglitch implemented in HW for SYV682B */
+#define SYV682X_HW_OC_DEGLITCH_MS 10
+
/* SYV682x register addresses */
#define SYV682X_STATUS_REG 0x00
#define SYV682X_CONTROL_1_REG 0x01