virtual mux: Wait for mux config ACK from the kernel

This CL:
1. Add a new config CONFIG_USB_MUX_AP_ACK_REQUEST to enable request
   for ACK from AP
1. Adds a new feature flag to inform the AP that an ACK is needed
   for boards supporting Burnside bridge retimer.
2. Adds a new host command for the EC to wait for mux config ACK
   for entering and exiting the safe mode.
3. Adds 12.5msec delay after configuring retimer and SoC as
   recommended.

BUG=b:166300460,b:161327513
BRANCH=none
TEST=Verify Type-C dock is functional with multiple hotplugs
     and flipped orientation.
     Verify USB3.0 is detected and not downgraded.
     Verify no regression with TBT3 and USB4 dock.

Cq-Depend: chromium:2530517
Change-Id: I5b8224648f0fc36b30e24ca3e7254d708c676149
Signed-off-by: Divya Sasidharan <divya.s.sasidharan@intel.com>
Signed-off-by: Ayushee Shah <ayushee.shah@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2366127
Commit-Queue: YH Lin <yueherngl@chromium.org>
Commit-Queue: Abe Levkoy <alevkoy@chromium.org>
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
This commit is contained in:
Divya Sasidharan 2020-10-28 16:11:55 -07:00 committed by Commit Bot
parent 49a18c25f8
commit 5316af00b3
6 changed files with 82 additions and 3 deletions

View File

@ -143,6 +143,9 @@ uint32_t get_feature_flags1(void)
#endif
#ifdef CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY
| EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY
#endif
#ifdef CONFIG_USB_MUX_AP_ACK_REQUEST
| EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK)
#endif
;
return board_override_feature_flags1(result);

View File

@ -9,6 +9,7 @@
#include "console.h"
#include "hooks.h"
#include "host_command.h"
#include "task.h"
#include "usb_mux.h"
#include "usbc_ppc.h"
#include "util.h"
@ -388,3 +389,18 @@ static enum ec_status hc_usb_pd_mux_info(struct host_cmd_handler_args *args)
DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_INFO,
hc_usb_pd_mux_info,
EC_VER_MASK(0));
static enum ec_status hc_usb_pd_mux_ack(struct host_cmd_handler_args *args)
{
__maybe_unused const struct ec_params_usb_pd_mux_ack *p = args->params;
if (!IS_ENABLED(CONFIG_USB_MUX_AP_ACK_REQUEST))
return EC_RES_INVALID_COMMAND;
task_set_event(PD_PORT_TO_TASK_ID(p->port), PD_EVENT_AP_MUX_DONE);
return EC_RES_SUCCESS;
}
DECLARE_HOST_COMMAND(EC_CMD_USB_PD_MUX_ACK,
hc_usb_pd_mux_ack,
EC_VER_MASK(0));

View File

@ -8,6 +8,8 @@
#include "common.h"
#include "console.h"
#include "host_command.h"
#include "task.h"
#include "timer.h"
#include "usb_mux.h"
#include "util.h"
@ -26,10 +28,39 @@ static mux_state_t virtual_mux_state[CONFIG_USB_PD_PORT_MAX_COUNT];
static inline void virtual_mux_update_state(int port, mux_state_t mux_state)
{
mux_state_t previous_mux_state = virtual_mux_state[port];
virtual_mux_state[port] = mux_state;
#ifdef CONFIG_HOSTCMD_EVENTS
if (!IS_ENABLED(CONFIG_HOSTCMD_EVENTS))
return;
host_set_single_event(EC_HOST_EVENT_USB_MUX);
#endif
if (!IS_ENABLED(CONFIG_USB_MUX_AP_ACK_REQUEST))
return;
/* This should only be called from the PD task */
assert(port == TASK_ID_TO_PD_PORT(task_get_current()));
/*
* EC waits for the ACK from kernel indicating that TCSS Mux
* configuration is completed. This mechanism is implemented for
* entering and exiting the safe mode. This is needed to remove
* timing senstivity between BB retimer and TCSS Mux to allow better
* synchronization between them and thereby remain in the same state
* for achieving proper safe state terminations.
*
* Note: While the EC waits for the ACK, the value of usb_mux_get
* won't match the most recently set value with usb_mux_set.
*/
if ((!(previous_mux_state & USB_PD_MUX_SAFE_MODE) &&
(mux_state & USB_PD_MUX_SAFE_MODE)) ||
((previous_mux_state & USB_PD_MUX_SAFE_MODE) &&
!(mux_state & USB_PD_MUX_SAFE_MODE))) {
task_wait_event_mask(PD_EVENT_AP_MUX_DONE, 100*MSEC);
usleep(12.5 * MSEC);
}
}
static int virtual_init(const struct usb_mux *me)

View File

@ -4696,6 +4696,13 @@
/* Enable IT5205H SBU protection switch */
#undef CONFIG_USB_MUX_IT5205H_SBU_OVP
/*
* Enable to inform the AP that an ACK is needed on configuring the TCSS mux.
* The config is enabled automatically when the board has CONFIG_USB_MUX_VIRTUAL
* and CONFIG_USBC_RETIMER_INTEL_BB enabled.
*/
#undef CONFIG_USB_MUX_AP_ACK_REQUEST
/*****************************************************************************/
/* USB GPIO config */
#undef CONFIG_USB_GPIO
@ -5635,6 +5642,14 @@
#endif
#endif /* CONFIG_CHIP_INIT_ROM_REGION */
/*
* By default, enable a request for an ACK from AP, on setting the mux, if the
* board supports Burnside Bridge retimer.
*/
#if defined(CONFIG_USBC_RETIMER_INTEL_BB) && defined(CONFIG_USB_MUX_VIRTUAL)
#define CONFIG_USB_MUX_AP_ACK_REQUEST
#endif /* CONFIG_USBC_RETIMER_INTEL_BB */
/*****************************************************************************/
/*

View File

@ -1418,6 +1418,11 @@ enum ec_feature_code {
* modes or USB4.
*/
EC_FEATURE_TYPEC_REQUIRE_AP_MODE_ENTRY = 42,
/*
* The EC will wait for an acknowledge from the AP after setting the
* mux.
*/
EC_FEATURE_TYPEC_MUX_REQUIRE_AP_ACK = 43,
};
#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
@ -7116,6 +7121,13 @@ struct ec_params_charger_control {
uint8_t allow_charging;
} __ec_align_size1;
/* Get ACK from the USB-C SS muxes */
#define EC_CMD_USB_PD_MUX_ACK 0x0603
struct ec_params_usb_pd_mux_ack {
uint8_t port; /* USB-C port number */
} __ec_align1;
/*****************************************************************************/
/*
* Reserve a range of host commands for board-specific, experimental, or

View File

@ -64,8 +64,10 @@ enum pd_rx_errors {
#define PD_EVENT_SYSJUMP TASK_EVENT_CUSTOM_BIT(10)
/* Receive a Hard Reset. */
#define PD_EVENT_RX_HARD_RESET TASK_EVENT_CUSTOM_BIT(11)
/* MUX configured notification event */
#define PD_EVENT_AP_MUX_DONE TASK_EVENT_CUSTOM_BIT(12)
/* First free event on PD task */
#define PD_EVENT_FIRST_FREE_BIT 12
#define PD_EVENT_FIRST_FREE_BIT 13
/* Ensure TCPC is out of low power mode before handling these events. */
#define PD_EXIT_LOW_POWER_EVENT_MASK \