summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Broch <tbroch@chromium.org>2014-11-19 18:17:52 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-02 01:57:26 +0000
commit975cb11ca193a8783ad53950dad5a01013d3d770 (patch)
treef3b6beac1f5c2f2f9500518001bd0e7f56328915
parent01047f65240a1ba333372f53c28f8281cbb7cf1f (diff)
downloadchrome-ec-975cb11ca193a8783ad53950dad5a01013d3d770.tar.gz
dingdong/hoho: Add GFU alternate mode.
Per USB PD specification even custom VDMs should fall under the alternate mode discovery policy. CL lays ground work for GFU (Google Flash Update) alternate mode. Signed-off-by: Todd Broch <tbroch@chromium.org> BRANCH=samus BUG=chrome-os-partner:31192,chrome-os-partner:31193 TEST=manual, See samus_pd console correctly discover another SVID & subsequent mode. (0) == Discover identity w/ two SVIDs 0xff01 & 0x11d1 (1) == Discover mode for 0xff01 (2) == Discover mode for 0x18d1 console output -------------- SVDM/5 [1] ff008041 2c0018d1 00000000 50110001 1100000b [4070.286120 DONE] (0) SVDM/2 [2] ff008042 ff0118d1 00000000 [4070.289353 DONE] (1) SVDM/2 [3] ff018043 00001085 [4070.292575 DONE] (2) SVDM/2 [3] 18d18043 00000001 [4070.295798 DONE] SVDM/1 [4] ff018144 [4070.298844 DONE] SVDM/2 [16] ff018150 00000002 [4070.302261 DONE] SVDM/1 [17] ff018151 > pe 0 dump IDENT: [ID Header] 2c0018d1 :: AMA, VID:18d1 [Cert Stat] 00000000 [2] 50110001 [3] 1100000b SVID[0]: ff01 MODES: [1] 00001085 SVID[1]: 18d1 MODES: [1] 00000001 MODE[1]: svid:ff01 caps:00001085 Change-Id: Ifab79a6fc6770a6f4bd7690ca8e6723503264137 Reviewed-on: https://chromium-review.googlesource.com/231833 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Todd Broch <tbroch@chromium.org> Commit-Queue: Todd Broch <tbroch@chromium.org> Tested-by: Todd Broch <tbroch@chromium.org>
-rw-r--r--board/dingdong/usb_pd_policy.c70
-rw-r--r--board/hoho/usb_pd_policy.c64
2 files changed, 87 insertions, 47 deletions
diff --git a/board/dingdong/usb_pd_policy.c b/board/dingdong/usb_pd_policy.c
index 2743eb12fd..b38254a83b 100644
--- a/board/dingdong/usb_pd_policy.c
+++ b/board/dingdong/usb_pd_policy.c
@@ -43,6 +43,8 @@ static unsigned select_mv = 5000;
/* Whether alternate mode has been entered or not */
static int alt_mode;
+/* When set true, we are in GFU mode */
+static int gfu_mode;
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
uint32_t *curr_limit, uint32_t *supply_voltage)
@@ -170,40 +172,45 @@ static int svdm_response_identity(int port, uint32_t *payload)
static int svdm_response_svids(int port, uint32_t *payload)
{
- payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, 0);
- return 2;
+ payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, USB_VID_GOOGLE);
+ payload[2] = 0;
+ return 3;
}
-/*
- * Will only ever be a single mode for this UFP_D device as it has no real USB
- * support making it only PIN_E configureable
- */
-#define MODE_CNT 1
-#define OPOS 1
+#define OPOS_DP 1
+#define OPOS_GFU 1
-const uint32_t vdo_dp_mode[MODE_CNT] = {
- VDO_MODE_DP(0, /* UFP pin cfg supported : none */
+const uint32_t vdo_dp_modes[1] = {
+ VDO_MODE_DP(0, /* UFP pin cfg supported : none */
MODE_DP_PIN_E, /* DFP pin cfg supported */
- 1, /* no usb2.0 signalling in AMode */
- CABLE_PLUG, /* its a plug */
+ 1, /* no usb2.0 signalling in AMode */
+ CABLE_PLUG, /* its a plug */
MODE_DP_V13, /* DPv1.3 Support, no Gen2 */
MODE_DP_SNK) /* Its a sink only */
};
+const uint32_t vdo_goog_modes[1] = {
+ VDO_MODE_GOOGLE(MODE_GOOGLE_FU)
+};
+
static int svdm_response_modes(int port, uint32_t *payload)
{
- if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT)
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
+ memcpy(payload + 1, vdo_dp_modes, sizeof(vdo_dp_modes));
+ return ARRAY_SIZE(vdo_dp_modes) + 1;
+ } else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) {
+ memcpy(payload + 1, vdo_goog_modes, sizeof(vdo_goog_modes));
+ return ARRAY_SIZE(vdo_goog_modes) + 1;
+ } else {
return 0; /* nak */
-
- memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
- return MODE_CNT + 1;
+ }
}
static int dp_status(int port, uint32_t *payload)
{
int opos = PD_VDO_OPOS(payload[0]);
int hpd = gpio_get_level(GPIO_DP_HPD);
- if (opos != OPOS)
+ if (opos != OPOS_DP)
return 0; /* nak */
payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
@@ -227,14 +234,21 @@ static int dp_config(int port, uint32_t *payload)
static int svdm_enter_mode(int port, uint32_t *payload)
{
- /* SID & mode request is valid */
- if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != OPOS))
- return 0; /* will generate NAK */
+ int rv = 0; /* will generate a NAK */
- /* TODO(tbroch) Enumerate USB BB here with updated mode choice */
- alt_mode = OPOS;
- return 1;
+ /* SID & mode request is valid */
+ if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_DP)) {
+ alt_mode = OPOS_DP;
+ rv = 1;
+ } else if ((PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_GFU)) {
+ alt_mode = OPOS_GFU;
+ gfu_mode = 1;
+ rv = 1;
+ }
+ /* TODO(p/33968): Enumerate USB BB here with updated mode choice */
+ return rv;
}
int pd_alt_mode(int port)
@@ -244,8 +258,14 @@ int pd_alt_mode(int port)
static int svdm_exit_mode(int port, uint32_t *payload)
{
- gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
alt_mode = 0;
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT)
+ gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
+ else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE)
+ gfu_mode = 0;
+ else
+ CPRINTF("Unknown exit mode req:0x%08x\n", payload[0]);
+
return 1; /* Must return ACK */
}
diff --git a/board/hoho/usb_pd_policy.c b/board/hoho/usb_pd_policy.c
index a2d35f6e58..e15dc3d580 100644
--- a/board/hoho/usb_pd_policy.c
+++ b/board/hoho/usb_pd_policy.c
@@ -43,6 +43,8 @@ static unsigned select_mv = 5000;
/* Whether alternate mode has been entered or not */
static int alt_mode;
+/* When set true, we are in GFU mode */
+static int gfu_mode;
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo,
uint32_t *curr_limit, uint32_t *supply_voltage)
@@ -170,18 +172,15 @@ static int svdm_response_identity(int port, uint32_t *payload)
static int svdm_response_svids(int port, uint32_t *payload)
{
- payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, 0);
- return 2;
+ payload[1] = VDO_SVID(USB_SID_DISPLAYPORT, USB_VID_GOOGLE);
+ payload[2] = 0;
+ return 3;
}
-/*
- * Will only ever be a single mode for this UFP_D device as it has no real USB
- * support making it only PIN_C configureable
- */
-#define MODE_CNT 1
-#define OPOS 1
+#define OPOS_DP 1
+#define OPOS_GFU 1
-const uint32_t vdo_dp_mode[MODE_CNT] = {
+const uint32_t vdo_dp_modes[1] = {
VDO_MODE_DP(0, /* UFP pin cfg supported : none */
MODE_DP_PIN_C, /* DFP pin cfg supported */
1, /* no usb2.0 signalling in AMode */
@@ -190,20 +189,28 @@ const uint32_t vdo_dp_mode[MODE_CNT] = {
MODE_DP_SNK) /* Its a sink only */
};
+const uint32_t vdo_goog_modes[1] = {
+ VDO_MODE_GOOGLE(MODE_GOOGLE_FU)
+};
+
static int svdm_response_modes(int port, uint32_t *payload)
{
- if (PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT)
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
+ memcpy(payload + 1, vdo_dp_modes, sizeof(vdo_dp_modes));
+ return ARRAY_SIZE(vdo_dp_modes) + 1;
+ } else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) {
+ memcpy(payload + 1, vdo_goog_modes, sizeof(vdo_goog_modes));
+ return ARRAY_SIZE(vdo_goog_modes) + 1;
+ } else {
return 0; /* nak */
-
- memcpy(payload + 1, vdo_dp_mode, sizeof(vdo_dp_mode));
- return MODE_CNT + 1;
+ }
}
static int dp_status(int port, uint32_t *payload)
{
int opos = PD_VDO_OPOS(payload[0]);
int hpd = gpio_get_level(GPIO_DP_HPD);
- if (opos != OPOS)
+ if (opos != OPOS_DP)
return 0; /* nak */
payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
@@ -226,14 +233,21 @@ static int dp_config(int port, uint32_t *payload)
static int svdm_enter_mode(int port, uint32_t *payload)
{
- /* SID & mode request is valid */
- if ((PD_VDO_VID(payload[0]) != USB_SID_DISPLAYPORT) ||
- (PD_VDO_OPOS(payload[0]) != OPOS))
- return 0; /* will generate a NAK */
+ int rv = 0; /* will generate a NAK */
- /* TODO(tbroch) Enumerate USB BB here with updated mode choice */
- alt_mode = OPOS;
- return 1;
+ /* SID & mode request is valid */
+ if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_DP)) {
+ alt_mode = OPOS_DP;
+ rv = 1;
+ } else if ((PD_VDO_VID(payload[0]) == USB_VID_GOOGLE) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_GFU)) {
+ alt_mode = OPOS_GFU;
+ gfu_mode = 1;
+ rv = 1;
+ }
+ /* TODO(p/33968): Enumerate USB BB here with updated mode choice */
+ return rv;
}
int pd_alt_mode(int port)
@@ -243,8 +257,14 @@ int pd_alt_mode(int port)
static int svdm_exit_mode(int port, uint32_t *payload)
{
- gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
alt_mode = 0;
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT)
+ gpio_set_level(GPIO_PD_SBU_ENABLE, 0);
+ else if (PD_VDO_VID(payload[0]) == USB_VID_GOOGLE)
+ gfu_mode = 0;
+ else
+ CPRINTF("Unknown exit mode req:0x%08x\n", payload[0]);
+
return 1; /* Must return ACK */
}