diff options
author | Abe Levkoy <alevkoy@chromium.org> | 2020-05-14 10:41:45 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-06-10 01:25:03 +0000 |
commit | bf24e746f41621ff2fbb72bf8067e9b672e79eb9 (patch) | |
tree | af1173f6e743e3ac93bb1e3adbc1c772c361bbd1 /common/usbc/usb_pd_dpm.c | |
parent | b5d255029d4662dca049b9754a5c159871a4b92d (diff) | |
download | chrome-ec-bf24e746f41621ff2fbb72bf8067e9b672e79eb9.tar.gz |
TCPMv2: Separate DPM and DP from PE
Create separate modules representing DisplayPort (which decides whether
and how we can set up the DP alt mode) and the Device Policy Manager
(which decides whether we should). The end goal is to have essentially
all code with DP-specific decisions or information in the DP module and
all code with DPM-specific decisions or information in the DPM module.
This will allow the PE to map as directly as practical to its behaviors
defined in the PD spec.
Essentially detach PE_DO_PORT_DISCOVERY from the rest of the PE state
machine in preparation for deleting it.
This change paves the way for
1) Allowing the AP to drive mode entry and
2) Allowing new alt modes to be supported via largely self-contained
modules.
BUG=b:155890173
TEST=Attach DP dongle; observe discovery and DP setup via Twinkie
BRANCH=none
Change-Id: Ie63a2e62d1ac6178722477dc53244898a04ef92f
Signed-off-by: Abe Levkoy <alevkoy@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2203842
Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'common/usbc/usb_pd_dpm.c')
-rw-r--r-- | common/usbc/usb_pd_dpm.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c new file mode 100644 index 0000000000..44ec46e588 --- /dev/null +++ b/common/usbc/usb_pd_dpm.c @@ -0,0 +1,110 @@ +/* Copyright 2020 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* + * Device Policy Manager implementation + * Refer to USB PD 3.0 spec, version 2.0, sections 8.2 and 8.3 + */ + +#include "compile_time_macros.h" +#include "console.h" +#include "usb_dp_alt_mode.h" +#include "usb_pd.h" +#include "usb_pd_dpm.h" +#include "usb_pe_sm.h" +#include "tcpm.h" + +#ifdef CONFIG_COMMON_RUNTIME +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#else +#define CPRINTF(format, args...) +#define CPRINTS(format, args...) +#endif + +static struct { + bool mode_entry_done; +} dpm[CONFIG_USB_PD_PORT_MAX_COUNT]; + +void dpm_init(int port) +{ + dpm[port].mode_entry_done = false; +} + +void dpm_set_mode_entry_done(int port) +{ + dpm[port].mode_entry_done = true; +} + +void dpm_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count, + uint32_t *vdm) +{ + const uint16_t svid = PD_VDO_VID(vdm[0]); + + assert(vdo_count >= 1); + + switch (svid) { + case USB_SID_DISPLAYPORT: + dp_vdm_acked(port, type, vdo_count, vdm); + break; + default: + CPRINTS("C%d: Received unexpected VDM ACK for SVID %d", port, + svid); + } +} + +void dpm_vdm_naked(int port, enum tcpm_transmit_type type, uint16_t svid, + uint8_t vdm_cmd) +{ + switch (svid) { + case USB_SID_DISPLAYPORT: + dp_vdm_naked(port, type, vdm_cmd); + break; + default: + CPRINTS("C%d: Received unexpected VDM NAK for SVID %d", port, + svid); + } +} + +void dpm_attempt_mode_entry(int port) +{ + uint32_t vdo_count; + uint32_t vdm[VDO_MAX_SIZE]; + + if (dpm[port].mode_entry_done) + return; + + if (pd_get_data_role(port) != PD_ROLE_DFP) + return; + + /* + * Check if we even discovered a DisplayPort mode; if not, just + * mark discovery done and get out of here. + */ + if (!pd_is_mode_discovered_for_svid(port, TCPC_TX_SOP, + USB_SID_DISPLAYPORT)) { + CPRINTF("C%d: No DP mode discovered\n", port); + dpm_set_mode_entry_done(port); + return; + } + + vdo_count = dp_setup_next_vdm(port, ARRAY_SIZE(vdm), vdm); + if (vdo_count < 0) { + dpm_set_mode_entry_done(port); + CPRINTF("C%d: Couldn't set up DP VDM\n", port); + return; + } + + /* + * TODO(b/155890173): Provide a host command to request that the PE send + * an arbitrary VDM via this mechanism. + */ + if (!pd_setup_vdm_request(port, vdm, vdo_count)) { + dpm_set_mode_entry_done(port); + return; + } + + pe_dpm_request(port, DPM_REQUEST_VDM); +} |