summaryrefslogtreecommitdiff
path: root/driver/usb_mux/amd_fp5.c
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2020-07-22 20:29:57 -0600
committerCommit Bot <commit-bot@chromium.org>2020-07-24 02:02:08 +0000
commit3a31737877176ac8fb0effb2a9cf8c8a78d61cb1 (patch)
treea6571a63bc0ce92ae06f794a06f33e4995462e4f /driver/usb_mux/amd_fp5.c
parent73745ba8e0ea7725fc40a60356b40f146ff9673b (diff)
downloadchrome-ec-3a31737877176ac8fb0effb2a9cf8c8a78d61cb1.tar.gz
zork: Restore AP mux setting after reboot
BUG=b:158960403 BRANCH=none TEST=USB3 works after AP reboot Signed-off-by: Edward Hill <ecgh@chromium.org> Change-Id: Ia6ec65ad38933106e183747e78827d564be5aefd Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2314033 Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'driver/usb_mux/amd_fp5.c')
-rw-r--r--driver/usb_mux/amd_fp5.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/driver/usb_mux/amd_fp5.c b/driver/usb_mux/amd_fp5.c
index ecba47851f..92c7e682a4 100644
--- a/driver/usb_mux/amd_fp5.c
+++ b/driver/usb_mux/amd_fp5.c
@@ -8,9 +8,14 @@
#include "amd_fp5.h"
#include "chipset.h"
#include "common.h"
+#include "hooks.h"
#include "i2c.h"
+#include "queue.h"
+#include "timer.h"
#include "usb_mux.h"
+static mux_state_t saved_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT];
+
static inline int amd_fp5_mux_read(const struct usb_mux *me, uint8_t *val)
{
uint8_t buf[3] = { 0 };
@@ -41,6 +46,8 @@ static int amd_fp5_set_mux(const struct usb_mux *me, mux_state_t mux_state)
{
uint8_t val = 0;
+ saved_mux_state[me->usb_port] = mux_state;
+
/*
* This MUX is on the FP5 SoC. If that device is not powered then
* we either have to complain that it is not powered or if we were
@@ -114,8 +121,36 @@ static int amd_fp5_get_mux(const struct usb_mux *me, mux_state_t *mux_state)
return EC_SUCCESS;
}
+static struct queue const chipset_reset_queue
+ = QUEUE_NULL(CONFIG_USB_PD_PORT_MAX_COUNT, struct usb_mux *);
+
+static void amd_fp5_chipset_reset_delay(void)
+{
+ struct usb_mux *me;
+ int rv;
+
+ while (queue_remove_unit(&chipset_reset_queue, &me)) {
+ rv = amd_fp5_set_mux(me, saved_mux_state[me->usb_port]);
+ if (rv)
+ ccprints("C%d restore mux rv:%d", me->usb_port, rv);
+ }
+}
+DECLARE_DEFERRED(amd_fp5_chipset_reset_delay);
+
+/*
+ * The AP's internal USB-C mux is reset when AP resets, so wait for
+ * it to be ready and then restore the previous setting.
+ */
+static int amd_fp5_chipset_reset(const struct usb_mux *me)
+{
+ queue_add_unit(&chipset_reset_queue, &me);
+ hook_call_deferred(&amd_fp5_chipset_reset_delay_data, 200 * MSEC);
+ return EC_SUCCESS;
+}
+
const struct usb_mux_driver amd_fp5_usb_mux_driver = {
.init = &amd_fp5_init,
.set = &amd_fp5_set_mux,
.get = &amd_fp5_get_mux,
+ .chipset_reset = &amd_fp5_chipset_reset,
};