summaryrefslogtreecommitdiff
path: root/common/usbc/usb_pd_dpm.c
diff options
context:
space:
mode:
authorAbe Levkoy <alevkoy@chromium.org>2020-05-14 10:41:45 -0600
committerCommit Bot <commit-bot@chromium.org>2020-06-10 01:25:03 +0000
commitbf24e746f41621ff2fbb72bf8067e9b672e79eb9 (patch)
treeaf1173f6e743e3ac93bb1e3adbc1c772c361bbd1 /common/usbc/usb_pd_dpm.c
parentb5d255029d4662dca049b9754a5c159871a4b92d (diff)
downloadchrome-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.c110
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);
+}