diff options
author | Todd Broch <tbroch@chromium.org> | 2014-11-19 18:17:52 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-12-02 01:57:26 +0000 |
commit | 975cb11ca193a8783ad53950dad5a01013d3d770 (patch) | |
tree | f3b6beac1f5c2f2f9500518001bd0e7f56328915 | |
parent | 01047f65240a1ba333372f53c28f8281cbb7cf1f (diff) | |
download | chrome-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.c | 70 | ||||
-rw-r--r-- | board/hoho/usb_pd_policy.c | 64 |
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 */ } |