summaryrefslogtreecommitdiff
path: root/baseboard/cherry/usb_pd_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'baseboard/cherry/usb_pd_policy.c')
-rw-r--r--baseboard/cherry/usb_pd_policy.c260
1 files changed, 0 insertions, 260 deletions
diff --git a/baseboard/cherry/usb_pd_policy.c b/baseboard/cherry/usb_pd_policy.c
deleted file mode 100644
index 0c7f4dcee5..0000000000
--- a/baseboard/cherry/usb_pd_policy.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* Copyright 2021 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.
- */
-#include "adc.h"
-#include "atomic.h"
-#include "charge_manager.h"
-#include "chipset.h"
-#include "driver/tcpm/rt1718s.h"
-#include "driver/tcpm/tcpci.h"
-#include "timer.h"
-#include "usb_dp_alt_mode.h"
-#include "usb_mux.h"
-#include "usb_pd.h"
-#include "usbc_ppc.h"
-
-#if CONFIG_USB_PD_3A_PORTS != 1
-#error Cherry reference must have at least one 3.0 A port
-#endif
-
-#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
-
-/* The port that the aux channel is on. */
-static enum {
- AUX_PORT_NONE = -1,
- AUX_PORT_C0 = 0,
- AUX_PORT_C1HDMI = 1,
-} aux_port = AUX_PORT_NONE;
-
-int svdm_get_hpd_gpio(int port)
-{
- /* HPD is low active, inverse the result */
- return !gpio_get_level(GPIO_EC_AP_DP_HPD_ODL);
-}
-
-void svdm_set_hpd_gpio(int port, int en)
-{
- /*
- * HPD is low active, inverse the en
- * TODO: C0&C1 shares the same HPD, implement FCFS policy.
- */
- gpio_set_level(GPIO_EC_AP_DP_HPD_ODL, !en);
-}
-
-static void aux_switch_port(int port)
-{
- if (port != AUX_PORT_NONE)
- gpio_set_level_verbose(CC_USBPD, GPIO_DP_PATH_SEL, !port);
- aux_port = port;
-}
-
-static void aux_display_disconnected(int port)
-{
- /* Gets the other port. C0 -> C1, C1 -> C0. */
- int other_port = !port;
-
- /* If the current port is not the aux port, nothing needs to be done. */
- if (aux_port != port)
- return;
-
- /* If the other port is connected to a external display, switch aux. */
- if (dp_status[other_port] & DP_FLAGS_DP_ON)
- aux_switch_port(other_port);
- else
- aux_switch_port(AUX_PORT_NONE);
-}
-
-__override int svdm_dp_attention(int port, uint32_t *payload)
-{
- int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
- int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
-#ifdef CONFIG_USB_PD_DP_HPD_GPIO
- int cur_lvl = svdm_get_hpd_gpio(port);
-#endif /* CONFIG_USB_PD_DP_HPD_GPIO */
- mux_state_t mux_state;
-
- dp_status[port] = payload[1];
-
- if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
- (irq || lvl))
- /*
- * Wake up the AP. IRQ or level high indicates a DP sink is now
- * present.
- */
- if (IS_ENABLED(CONFIG_MKBP_EVENT))
- pd_notify_dp_alt_mode_entry(port);
-
- /* Its initial DP status message prior to config */
- if (!(dp_flags[port] & DP_FLAGS_DP_ON)) {
- if (lvl)
- dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING;
- return 1;
- }
-
-#ifdef CONFIG_USB_PD_DP_HPD_GPIO
- if (irq && !lvl) {
- /*
- * IRQ can only be generated when the level is high, because
- * the IRQ is signaled by a short low pulse from the high level.
- */
- CPRINTF("ERR:HPD:IRQ&LOW\n");
- return 0; /* nak */
- }
-
- if (irq && cur_lvl) {
- uint64_t now = get_time().val;
- /* wait for the minimum spacing between IRQ_HPD if needed */
- if (now < svdm_hpd_deadline[port])
- usleep(svdm_hpd_deadline[port] - now);
-
- /* generate IRQ_HPD pulse */
- svdm_set_hpd_gpio(port, 0);
- /*
- * b/171172053#comment14: since the HPD_DSTREAM_DEBOUNCE_IRQ is
- * very short (500us), we can use udelay instead of usleep for
- * more stable pulse period.
- */
- udelay(HPD_DSTREAM_DEBOUNCE_IRQ);
- svdm_set_hpd_gpio(port, 1);
- } else {
- svdm_set_hpd_gpio(port, lvl);
- }
-
- /*
- * Cherry can only output to 1 display port at a time.
- * This implements FCFS policy by changing the aux channel. If a
- * display is connected to the either port (says A), and the port A
- * will be served until the display is disconnected from port A.
- * It won't output to the other display which connects to port B.
- */
- if (lvl && aux_port == AUX_PORT_NONE)
- /*
- * A display is connected, and no display was plugged on either
- * port.
- */
- aux_switch_port(port);
- else if (!lvl)
- aux_display_disconnected(port);
-
-
- /* set the minimum time delay (2ms) for the next HPD IRQ */
- svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
-#endif /* CONFIG_USB_PD_DP_HPD_GPIO */
-
- mux_state = (lvl ? USB_PD_MUX_HPD_LVL : USB_PD_MUX_HPD_LVL_DEASSERTED) |
- (irq ? USB_PD_MUX_HPD_IRQ : USB_PD_MUX_HPD_IRQ_DEASSERTED);
- usb_mux_hpd_update(port, mux_state);
-
-#ifdef USB_PD_PORT_TCPC_MST
- if (port == USB_PD_PORT_TCPC_MST)
- baseboard_mst_enable_control(port, lvl);
-#endif
-
- /* ack */
- return 1;
-}
-
-__override void svdm_exit_dp_mode(int port)
-{
-#ifdef CONFIG_USB_PD_DP_HPD_GPIO
- svdm_set_hpd_gpio(port, 0);
-#endif /* CONFIG_USB_PD_DP_HPD_GPIO */
- usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL_DEASSERTED |
- USB_PD_MUX_HPD_IRQ_DEASSERTED);
-
- aux_display_disconnected(port);
-
-#ifdef USB_PD_PORT_TCPC_MST
- if (port == USB_PD_PORT_TCPC_MST)
- baseboard_mst_enable_control(port, 0);
-#endif
-}
-
-int pd_snk_is_vbus_provided(int port)
-{
- static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT];
- int vbus;
-
- /*
- * Use ppc_is_vbus_present for all ports on Cherry, and
- * port 1 on other devices.
- */
- if (IS_ENABLED(BOARD_CHERRY) || port == 1)
- return ppc_is_vbus_present(port);
-
- /* b/181203590: use ADC for port 0 (syv682x) */
- vbus = (adc_read_channel(ADC_VBUS) >= PD_V_SINK_DISCONNECT_MAX);
-
-#ifdef CONFIG_USB_CHARGER
- /*
- * There's no PPC to inform VBUS change for usb_charger, so inform
- * the usb_charger now.
- */
- if (!!(vbus_prev[port] != vbus))
- usb_charger_vbus_change(port, vbus);
-
- if (vbus)
- atomic_or(&vbus_prev[port], 1);
- else
- atomic_clear(&vbus_prev[port]);
-#endif
- return vbus;
-}
-
-void pd_power_supply_reset(int port)
-{
- int prev_en;
-
- prev_en = ppc_is_sourcing_vbus(port);
-
- /* Disable VBUS. */
- ppc_vbus_source_enable(port, 0);
-
- /* Enable discharge if we were previously sourcing 5V */
- if (prev_en)
- pd_set_vbus_discharge(port, 1);
-
- if (port == 1)
- rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_5V_OUT, 0);
-
- /* Notify host of power info change. */
- pd_send_host_event(PD_EVENT_POWER_CHANGE);
-}
-
-int pd_check_vconn_swap(int port)
-{
- /* Allow Vconn swap if AP is on. */
- return chipset_in_state(CHIPSET_STATE_SUSPEND | CHIPSET_STATE_ON);
-}
-
-int pd_set_power_supply_ready(int port)
-{
- int rv;
-
- /* Disable charging. */
- rv = ppc_vbus_sink_enable(port, 0);
- if (rv)
- return rv;
-
- pd_set_vbus_discharge(port, 0);
-
- /* Provide Vbus. */
- rv = ppc_vbus_source_enable(port, 1);
- if (rv)
- return rv;
-
- if (port == 1)
- rt1718s_gpio_set_level(port, GPIO_EN_USB_C1_5V_OUT, 1);
-
- /* Notify host of power info change. */
- pd_send_host_event(PD_EVENT_POWER_CHANGE);
-
- return EC_SUCCESS;
-}
-
-int board_vbus_source_enabled(int port)
-{
- return ppc_is_sourcing_vbus(port);
-}