Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 603aeb2c authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "usb: phy-msm-ssusb-qmp: Perform USB only reset in USB+DP mode"

parents 94de93b5 1837de63
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -4423,7 +4423,7 @@ static void dwc3_start_stop_device(struct dwc3_msm *mdwc, bool start)
		dbg_log_string("stop_device_mode completed");
}

int dwc3_msm_release_ss_lane(struct device *dev)
int dwc3_msm_release_ss_lane(struct device *dev, bool usb_dp_concurrent_mode)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = NULL;
@@ -4439,6 +4439,16 @@ int dwc3_msm_release_ss_lane(struct device *dev)
		return -EAGAIN;
	}

	/*
	 * If the MPA connected is multi_func capable set the flag assuming
	 * that USB and DP is operating in concurrent mode and bail out early.
	 */
	if (usb_dp_concurrent_mode) {
		mdwc->ss_phy->flags |= PHY_USB_DP_CONCURRENT_MODE;
		dbg_event(0xFF, "USB_DP_CONCURRENT_MODE", 1);
		return 0;
	}

	dbg_event(0xFF, "ss_lane_release", 0);
	/* flush any pending work */
	flush_work(&mdwc->resume_work);
@@ -5244,6 +5254,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on)
					USB_SPEED_SUPER);
			usb_phy_notify_disconnect(mdwc->ss_phy,
					USB_SPEED_SUPER);
			mdwc->ss_phy->flags &= ~PHY_USB_DP_CONCURRENT_MODE;
		}
		redriver_notify_disconnect(mdwc->ss_redriver_node);

@@ -5365,6 +5376,7 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on)
		usb_phy_notify_disconnect(mdwc->hs_phy, USB_SPEED_HIGH);
		usb_phy_notify_disconnect(mdwc->ss_phy, USB_SPEED_SUPER);
		redriver_notify_disconnect(mdwc->ss_redriver_node);
		mdwc->ss_phy->flags &= ~PHY_USB_DP_CONCURRENT_MODE;
		dwc3_override_vbus_status(mdwc, false);
		dwc3_msm_write_reg_field(mdwc->base, DWC3_GUSB3PIPECTL(0),
				DWC3_GUSB3PIPECTL_SUSPHY, 0);
+37 −8
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -405,9 +405,11 @@ static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)
		}

		/* override hardware control for reset of qmp phy */
		if (!(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE))
			writel_relaxed(SW_DPPHY_RESET_MUX | SW_DPPHY_RESET |
				SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET,
			phy->base + phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
				phy->base +
				phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);

		/* update port select */
		if (val > 0) {
@@ -417,11 +419,13 @@ static void usb_qmp_update_portselect_phymode(struct msm_ssphy_qmp *phy)
				phy->phy_reg[USB3_DP_COM_TYPEC_CTRL]);
		}

		if (!(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE)) {
			msm_ssphy_qmp_setmode(phy, USB3_DP_COMBO_MODE);

			/* bring both USB and DP PHYs PCS block out of reset */
			writel_relaxed(0x00, phy->base +
				phy->phy_reg[USB3_DP_COM_RESET_OVRD_CTRL]);
		}
		break;
	case  USB3_OR_DP:
		if (val > 0) {
@@ -513,6 +517,12 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy)
		goto fail;
	}

	/* perform software reset of PHY common logic */
	if (phy->phy_type == USB3_AND_DP &&
				!(phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE))
		writel_relaxed(0x00,
			phy->base + phy->phy_reg[USB3_DP_COM_SW_RESET]);

	/* perform software reset of PCS/Serdes */
	writel_relaxed(0x00, phy->base + phy->phy_reg[USB3_PHY_SW_RESET]);
	/* start PCS/Serdes to operation mode */
@@ -556,6 +566,25 @@ static int msm_ssphy_qmp_dp_combo_reset(struct usb_phy *uphy)
					phy);
	int ret = 0;

	if (phy->phy.flags & PHY_USB_DP_CONCURRENT_MODE) {
		dev_dbg(uphy->dev, "Resetting USB part of QMP phy\n");

		/* Assert USB3 PHY CSR reset */
		ret = reset_control_assert(phy->phy_reset);
		if (ret) {
			dev_err(uphy->dev, "phy_reset assert failed\n");
			goto exit;
		}

		/* Deassert USB3 PHY CSR reset */
		ret = reset_control_deassert(phy->phy_reset);
		if (ret) {
			dev_err(uphy->dev, "phy_reset deassert failed\n");
			goto exit;
		}
		return 0;
	}

	dev_dbg(uphy->dev, "Global reset of QMP DP combo phy\n");
	/* Assert global PHY reset */
	ret = reset_control_assert(phy->global_phy_reset);
+4 −3
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
 */

#ifndef __LINUX_USB_DWC3_MSM_H
@@ -19,6 +19,7 @@
#define EUD_SPOOF_DISCONNECT		BIT(6)
#define EUD_SPOOF_CONNECT		BIT(7)
#define PHY_SUS_OVERRIDE		BIT(8)
#define PHY_USB_DP_CONCURRENT_MODE	BIT(9)

/*
 * The following are bit fields describing the USB BAM options.
@@ -135,7 +136,7 @@ int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size,
	u8 dst_pipe_idx);
bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget);
int msm_dwc3_reset_dbm_ep(struct usb_ep *ep);
int dwc3_msm_release_ss_lane(struct device *dev);
int dwc3_msm_release_ss_lane(struct device *dev, bool usb_dp_concurrent_mode);
bool usb_get_remote_wakeup_status(struct usb_gadget *gadget);
#else
static inline struct usb_ep *usb_ep_autoconfig_by_name(
@@ -162,7 +163,7 @@ static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget)
{ return false; }
static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep)
{ return -ENODEV; }
static inline int dwc3_msm_release_ss_lane(struct device *dev)
static inline int dwc3_msm_release_ss_lane(struct device *dev, bool usb_dp_concurrent_mode)
{ return -ENODEV; }
static bool __maybe_unused usb_get_remote_wakeup_status(struct usb_gadget *gadget)
{ return false; }