summaryrefslogtreecommitdiff
path: root/common/usbc/dp_alt_mode.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/usbc/dp_alt_mode.c')
-rw-r--r--common/usbc/dp_alt_mode.c292
1 files changed, 0 insertions, 292 deletions
diff --git a/common/usbc/dp_alt_mode.c b/common/usbc/dp_alt_mode.c
deleted file mode 100644
index 9a3493c6e1..0000000000
--- a/common/usbc/dp_alt_mode.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/* 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.
- */
-
-/*
- * DisplayPort alternate mode support
- * Refer to VESA DisplayPort Alt Mode on USB Type-C Standard, version 2.0,
- * section 5.2
- */
-
-#include <stdbool.h>
-#include <stdint.h>
-#include "assert.h"
-#include "usb_common.h"
-#include "usb_dp_alt_mode.h"
-#include "usb_pd.h"
-#include "usb_pd_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
-
-/* The state of the DP negotiation */
-enum dp_states {
- DP_START = 0,
- DP_ENTER_ACKED,
- DP_ENTER_NAKED,
- DP_STATUS_ACKED,
- DP_ACTIVE,
- DP_ENTER_RETRY,
- DP_INACTIVE,
- DP_STATE_COUNT
-};
-static enum dp_states dp_state[CONFIG_USB_PD_PORT_MAX_COUNT];
-
-/*
- * Map of states to expected VDM commands in responses.
- * Default of 0 indicates no command expected.
- */
-static const uint8_t state_vdm_cmd[DP_STATE_COUNT] = {
- [DP_START] = CMD_ENTER_MODE,
- [DP_ENTER_ACKED] = CMD_DP_STATUS,
- [DP_STATUS_ACKED] = CMD_DP_CONFIG,
- [DP_ACTIVE] = CMD_EXIT_MODE,
- [DP_ENTER_NAKED] = CMD_EXIT_MODE,
- [DP_ENTER_RETRY] = CMD_ENTER_MODE,
-};
-
-bool dp_is_active(int port)
-{
- return dp_state[port] == DP_ACTIVE;
-}
-
-void dp_init(int port)
-{
- dp_state[port] = DP_START;
-}
-
-bool dp_entry_is_done(int port)
-{
- return dp_state[port] == DP_ACTIVE ||
- dp_state[port] == DP_INACTIVE;
-}
-
-static void dp_entry_failed(int port)
-{
- CPRINTS("C%d: DP alt mode protocol failed!", port);
- dp_state[port] = DP_INACTIVE;
-}
-
-static bool dp_response_valid(int port, enum tcpci_msg_type type,
- char *cmdt, int vdm_cmd)
-{
- enum dp_states st = dp_state[port];
-
- /*
- * Check for an unexpected response.
- * If DP is inactive, ignore the command.
- */
- if (type != TCPCI_MSG_SOP ||
- (st != DP_INACTIVE && state_vdm_cmd[st] != vdm_cmd)) {
- CPRINTS("C%d: Received unexpected DP VDM %s (cmd %d) from"
- " %s in state %d", port, cmdt, vdm_cmd,
- type == TCPCI_MSG_SOP ? "port partner" : "cable plug",
- st);
- dp_entry_failed(port);
- return false;
- }
- return true;
-}
-
-static void dp_exit_to_usb_mode(int port)
-{
- int opos = pd_alt_mode(port, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT);
-
- pd_dfp_exit_mode(port, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT, opos);
- set_usb_mux_with_current_data_role(port);
-
- CPRINTS("C%d: Exited DP mode", port);
- /*
- * If the EC exits an alt mode autonomously, don't try to enter it again. If
- * the AP commands the EC to exit DP mode, it might command the EC to enter
- * again later, so leave the state machine ready for that possibility.
- */
- dp_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY)
- ? DP_START : DP_INACTIVE;
-}
-
-void dp_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count,
- uint32_t *vdm)
-{
- const struct svdm_amode_data *modep =
- pd_get_amode_data(port, type, USB_SID_DISPLAYPORT);
- const uint8_t vdm_cmd = PD_VDO_CMD(vdm[0]);
-
- if (!dp_response_valid(port, type, "ACK", vdm_cmd))
- return;
-
- /* TODO(b/155890173): Validate VDO count for specific commands */
-
- switch (dp_state[port]) {
- case DP_START:
- case DP_ENTER_RETRY:
- dp_state[port] = DP_ENTER_ACKED;
- /* Inform PE layer that alt mode is now active */
- pd_set_dfp_enter_mode_flag(port, true);
- break;
- case DP_ENTER_ACKED:
- /* DP status response & UFP's DP attention have same payload. */
- dfp_consume_attention(port, vdm);
- dp_state[port] = DP_STATUS_ACKED;
- break;
- case DP_STATUS_ACKED:
- if (modep && modep->opos && modep->fx->post_config)
- modep->fx->post_config(port);
- dp_state[port] = DP_ACTIVE;
- CPRINTS("C%d: Entered DP mode", port);
- break;
- case DP_ACTIVE:
- /*
- * Request to exit mode successful, so put the module in an
- * inactive state.
- */
- dp_exit_to_usb_mode(port);
- break;
- case DP_ENTER_NAKED:
- /*
- * The request to exit the mode was successful,
- * so try to enter the mode again.
- */
- dp_state[port] = DP_ENTER_RETRY;
- break;
- case DP_INACTIVE:
- /*
- * This can occur if the mode is shutdown because
- * the CPU is being turned off, and an exit mode
- * command has been sent.
- */
- break;
- default:
- /* Invalid or unexpected negotiation state */
- CPRINTF("%s called with invalid state %d\n",
- __func__, dp_state[port]);
- dp_entry_failed(port);
- break;
- }
-}
-
-void dp_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd)
-{
- if (!dp_response_valid(port, type, "NAK", vdm_cmd))
- return;
-
- switch (dp_state[port]) {
- case DP_START:
- /*
- * If a request to enter DP mode is NAK'ed, this likely
- * means the partner is already in DP alt mode, so
- * request to exit the mode first before retrying
- * the enter command. This can happen if the EC
- * is restarted (e.g to go into recovery mode) while
- * DP alt mode is active.
- */
- dp_state[port] = DP_ENTER_NAKED;
- break;
- case DP_ENTER_RETRY:
- /*
- * Another NAK on the second attempt to enter DP mode.
- * Give up.
- */
- dp_entry_failed(port);
- break;
- case DP_ACTIVE:
- /* Treat an Exit Mode NAK the same as an Exit Mode ACK. */
- dp_exit_to_usb_mode(port);
- break;
- default:
- CPRINTS("C%d: NAK for cmd %d in state %d", port,
- vdm_cmd, dp_state[port]);
- dp_entry_failed(port);
- break;
- }
-}
-
-int dp_setup_next_vdm(int port, int vdo_count, uint32_t *vdm)
-{
- const struct svdm_amode_data *modep = pd_get_amode_data(port,
- TCPCI_MSG_SOP, USB_SID_DISPLAYPORT);
- int vdo_count_ret;
-
- if (vdo_count < VDO_MAX_SIZE)
- return -1;
-
- switch (dp_state[port]) {
- case DP_START:
- case DP_ENTER_RETRY:
- /* Enter the first supported mode for DisplayPort. */
- vdm[0] = pd_dfp_enter_mode(port, TCPCI_MSG_SOP,
- USB_SID_DISPLAYPORT, 0);
- if (vdm[0] == 0)
- return -1;
- /* CMDT_INIT is 0, so this is a no-op */
- vdm[0] |= VDO_CMDT(CMDT_INIT);
- vdm[0] |= VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP));
- vdo_count_ret = 1;
- if (dp_state[port] == DP_START)
- CPRINTS("C%d: Attempting to enter DP mode", port);
- break;
- case DP_ENTER_ACKED:
- if (!(modep && modep->opos))
- return -1;
-
- vdo_count_ret = modep->fx->status(port, vdm);
- if (vdo_count_ret == 0)
- return -1;
- vdm[0] |= PD_VDO_OPOS(modep->opos);
- vdm[0] |= VDO_CMDT(CMDT_INIT);
- vdm[0] |= VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP));
- break;
- case DP_STATUS_ACKED:
- if (!(modep && modep->opos))
- return -1;
-
- vdo_count_ret = modep->fx->config(port, vdm);
- if (vdo_count_ret == 0)
- return -1;
- vdm[0] |= VDO_CMDT(CMDT_INIT);
- vdm[0] |= VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP));
- break;
- case DP_ENTER_NAKED:
- case DP_ACTIVE:
- /*
- * Called to exit DP alt mode, either when the mode
- * is active and the system is shutting down, or
- * when an initial request to enter the mode is NAK'ed.
- * This can happen if the EC is restarted (e.g to go
- * into recovery mode) while DP alt mode is active.
- * It would be good to invoke modep->fx->exit but
- * this doesn't set up the VDM, it clears state.
- * TODO(b/159856063): Clean up the API to the fx functions.
- */
- if (!(modep && modep->opos))
- return -1;
-
- usb_mux_set_safe_mode_exit(port);
-
- vdm[0] = VDO(USB_SID_DISPLAYPORT,
- 1, /* structured */
- CMD_EXIT_MODE);
-
- vdm[0] |= VDO_OPOS(modep->opos);
- vdm[0] |= VDO_CMDT(CMDT_INIT);
- vdm[0] |= VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP));
- vdo_count_ret = 1;
- break;
- case DP_INACTIVE:
- /*
- * DP mode is inactive.
- */
- return -1;
- default:
- CPRINTF("%s called with invalid state %d\n",
- __func__, dp_state[port]);
- return -1;
- }
- return vdo_count_ret;
-}