Strago: add HPD handling to policy layer

Ported the HPD handling to policy from Glados
 Change-Id: I293224fa5189c8827f1837877ffb791fddc7fb77
 Reviewed-on: https://chromium-review.googlesource.com/285743

BUG=none
TEST=make buildall -j
BRANCH=none

Change-Id: I982c6bd162b5ba239d4c9d066995c3d2fcaa97fd
Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/287812
Reviewed-by: Alec Berg <alecaberg@chromium.org>
This commit is contained in:
Vijay Hiremath
2015-07-22 11:07:11 -07:00
committed by ChromeOS Commit Bot
parent aff095dd9b
commit 3e9bd8027c
3 changed files with 71 additions and 12 deletions

View File

@@ -43,6 +43,7 @@
#define CONFIG_USB_SWITCH_PI3USB9281
#define CONFIG_USB_SWITCH_PI3USB9281_CHIP_COUNT 1
#define CONFIG_USBC_SS_MUX
#define CONFIG_USBC_VCONN
#define CONFIG_SPI_PORT 1
#define CONFIG_SPI_CS_GPIO GPIO_PVT_CS0
@@ -90,12 +91,15 @@
#define CONFIG_BUTTON_COUNT 2
#undef DEFERRABLE_MAX_COUNT
#define DEFERRABLE_MAX_COUNT 11
#define DEFERRABLE_MAX_COUNT 12
#define CONFIG_ADC
/* Modules we want to exclude */
#undef CONFIG_CMD_HASH
#undef CONFIG_CMD_HOSTCMD
#undef CONFIG_CMD_PD
#undef CONFIG_CMD_SHMEM
#undef CONFIG_CMD_TIMERINFO
#undef CONFIG_CONSOLE_CMDHELP
#undef CONFIG_CONSOLE_HISTORY

View File

@@ -56,7 +56,7 @@ GPIO(USB2_ENABLE, PIN(36), GPIO_OUT_LOW) /* Enable power
GPIO(ENTERING_RW, PIN(41), GPIO_OUT_LOW) /* Indicate when EC is entering RW code */
GPIO(PCH_SMI_L, PIN(44), GPIO_ODR_HIGH) /* SMI output */
GPIO(USB_OC1_L, PIN(45), GPIO_INT_FALLING) /* DB2 BC1.2 over current signal to EC */
GPIO(DP_USB_C_HPD_Q, PIN(46), GPIO_OUT_HIGH) /* DP hot plug detect from EC to SOC */
GPIO(USB_C0_DP_HPD, PIN(46), GPIO_OUT_LOW) /* DP hot plug detect from EC to SOC */
GPIO(USB_C0_5V_EN, PIN(50), GPIO_OUT_LOW) /* USB C0 5V enable */
GPIO(PCH_SUS_STAT_L, PIN(51), GPIO_INT_FALLING) /* Signal to inform EC that SOC is entering low power state */

View File

@@ -145,18 +145,30 @@ void pd_execute_data_swap(int port, int data_role)
/* TODO: need to open/close D+/D- switch based on role */
}
void pd_check_pr_role(int port, int pr_role, int partner_pr_swap)
void pd_check_pr_role(int port, int pr_role, int flags)
{
/* If sink, and dual role toggling is on, then switch to source */
if (partner_pr_swap && pr_role == PD_ROLE_SINK &&
pd_get_dual_role() == PD_DRP_TOGGLE_ON)
pd_request_power_swap(port);
/*
* If partner is dual-role power and dualrole toggling is on, consider
* if a power swap is necessary.
*/
if ((flags & PD_FLAGS_PARTNER_DR_POWER) &&
pd_get_dual_role() == PD_DRP_TOGGLE_ON) {
/*
* If we are a sink and partner is not externally powered, then
* swap to become a source. If we are source and partner is
* externally powered, swap to become a sink.
*/
int partner_extpower = flags & PD_FLAGS_PARTNER_EXTPOWER;
if ((!partner_extpower && pr_role == PD_ROLE_SINK) ||
(partner_extpower && pr_role == PD_ROLE_SOURCE))
pd_request_power_swap(port);
}
}
void pd_check_dr_role(int port, int dr_role, int partner_dr_swap)
void pd_check_dr_role(int port, int dr_role, int flags)
{
/* If UFP, try to switch to DFP */
if (partner_dr_swap && dr_role == PD_ROLE_UFP)
if ((flags & PD_FLAGS_PARTNER_DR_DATA) && dr_role == PD_ROLE_UFP)
pd_request_data_swap(port);
}
@@ -220,11 +232,14 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload,
#ifdef CONFIG_USB_PD_ALT_MODE_DFP
static int dp_flags;
/* DP Status VDM as returned by UFP */
static uint32_t dp_status;
static void svdm_safe_dp_mode(int port)
{
/* make DP interface safe until configure */
dp_flags = 0;
dp_status = 0;
usb_mux_set(port, TYPEC_MUX_NONE,
USB_SWITCH_CONNECT, pd_get_polarity(port));
}
@@ -259,12 +274,18 @@ static int svdm_dp_status(int port, uint32_t *payload)
static int svdm_dp_config(int port, uint32_t *payload)
{
int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status);
int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status);
usb_mux_set(port, TYPEC_MUX_DP,
if (!pin_mode)
return 0;
usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP,
USB_SWITCH_CONNECT, pd_get_polarity(port));
payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
CMD_DP_CONFIG | VDO_OPOS(opos));
payload[1] = VDO_DP_CFG(MODE_DP_PIN_E, /* pin mode */
payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
1, /* DPv1.3 signaling */
2); /* UFP connected */
return 2;
@@ -275,10 +296,44 @@ static void svdm_dp_post_config(int port)
dp_flags |= DP_FLAGS_DP_ON;
if (!(dp_flags & DP_FLAGS_HPD_HI_PENDING))
return;
gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
}
static void hpd0_irq_deferred(void)
{
gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
}
DECLARE_DEFERRED(hpd0_irq_deferred);
static int svdm_dp_attention(int port, uint32_t *payload)
{
int cur_lvl;
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
enum gpio_signal hpd = GPIO_USB_C0_DP_HPD;
cur_lvl = gpio_get_level(hpd);
dp_status = payload[1];
/* Its initial DP status message prior to config */
if (!(dp_flags & DP_FLAGS_DP_ON)) {
if (lvl)
dp_flags |= DP_FLAGS_HPD_HI_PENDING;
return 1;
}
if (irq & cur_lvl) {
gpio_set_level(hpd, 0);
hook_call_deferred(hpd0_irq_deferred,
HPD_DSTREAM_DEBOUNCE_IRQ);
} else if (irq & !cur_lvl) {
CPRINTF("ERR:HPD:IRQ&LOW\n");
return 0; /* nak */
} else {
gpio_set_level(hpd, lvl);
}
/* ack */
return 1;
}
@@ -286,7 +341,7 @@ static int svdm_dp_attention(int port, uint32_t *payload)
static void svdm_exit_dp_mode(int port)
{
svdm_safe_dp_mode(port);
/* gpio_set_level(PORT_TO_HPD(port), 0); */
gpio_set_level(GPIO_USB_C0_DP_HPD, 0);
}
static int svdm_enter_gfu_mode(int port, uint32_t mode_caps)