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

Commit 17c53d66 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/dp: retry usb lane release if busy



Retry to release USB super speed lanes in case the USB
PHY is busy. This is needed to avoid USB programming
the PHY while DP setting up a new connection.

CRs-Fixed: 2219588
Change-Id: Ib53236319809b35bb4a7bf0bb37e0f114ce68337
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent d57a1dd3
Loading
Loading
Loading
Loading
+39 −11
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/delay.h>


#include "dp_usbpd.h"
#include "dp_usbpd.h"


@@ -314,11 +315,44 @@ static int dp_usbpd_validate_callback(u8 cmd,
	return ret;
	return ret;
}
}



static int dp_usbpd_get_ss_lanes(struct dp_usbpd_private *pd)
{
	int rc = 0;
	int timeout = 250;

	/*
	 * By default, USB reserves two lanes for Super Speed.
	 * Which means DP has remaining two lanes to operate on.
	 * If multi-function is not supported, request USB to
	 * release the Super Speed lanes so that DP can use
	 * all four lanes in case DPCD indicates support for
	 * four lanes.
	 */
	if (!pd->dp_usbpd.multi_func) {
		while (timeout) {
			rc = pd->svid_handler.request_usb_ss_lane(
					pd->pd, &pd->svid_handler);
			if (rc != -EBUSY)
				break;

			pr_warn("USB busy, retry\n");

			/* wait for hw recommended delay for usb */
			msleep(20);
			timeout--;
		}
	}

	return rc;
}

static void dp_usbpd_response_cb(struct usbpd_svid_handler *hdlr, u8 cmd,
static void dp_usbpd_response_cb(struct usbpd_svid_handler *hdlr, u8 cmd,
				enum usbpd_svdm_cmd_type cmd_type,
				enum usbpd_svdm_cmd_type cmd_type,
				const u32 *vdos, int num_vdos)
				const u32 *vdos, int num_vdos)
{
{
	struct dp_usbpd_private *pd;
	struct dp_usbpd_private *pd;
	int rc = 0;


	pd = container_of(hdlr, struct dp_usbpd_private, svid_handler);
	pd = container_of(hdlr, struct dp_usbpd_private, svid_handler);


@@ -380,17 +414,11 @@ static void dp_usbpd_response_cb(struct usbpd_svid_handler *hdlr, u8 cmd,


		pd->dp_usbpd.orientation = usbpd_get_plug_orientation(pd->pd);
		pd->dp_usbpd.orientation = usbpd_get_plug_orientation(pd->pd);


		/*
		rc = dp_usbpd_get_ss_lanes(pd);
		 * By default, USB reserves two lanes for Super Speed.
		if (rc) {
		 * Which means DP has remaining two lanes to operate on.
			pr_err("failed to get SuperSpeed lanes\n");
		 * If multi-function is not supported, request USB to
			break;
		 * release the Super Speed lanes so that DP can use
		}
		 * all four lanes in case DPCD indicates support for
		 * four lanes.
		 */
		if (!pd->dp_usbpd.multi_func)
			pd->svid_handler.request_usb_ss_lane(pd->pd,
				&pd->svid_handler);


		if (pd->dp_cb && pd->dp_cb->configure)
		if (pd->dp_cb && pd->dp_cb->configure)
			pd->dp_cb->configure(pd->dev);
			pd->dp_cb->configure(pd->dev);