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

Commit e889f949 authored by Subhash Jadavani's avatar Subhash Jadavani Committed by Gerrit - the friendly Code Review server
Browse files

scsi: ufs: split broken LCC quirk



Currently when UFSHCD_BROKEN_LCC quirk is defined, LCC is getting
disabled on both host and device side but there could be a need
where we don't want to disable the LCC on both side hence this change
splits the quirk in 2 parts one for host and one for device.

Change-Id: I906a24a428665e3ee67a4c2ec3fc31f47e5c7e3c
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent a7d090b9
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -2567,12 +2567,14 @@ static void msm_ufs_advertise_quirks(struct ufs_hba *hba)
			      | UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
			      | UFSHCD_QUIRK_BROKEN_2_TX_LANES
			      | UFSHCD_QUIRK_BROKEN_SUSPEND
			      | UFSHCD_BROKEN_LCC);
			      | UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST
			      | UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE);
	} else if ((major == 0x1) && (minor == 0x001) && (step == 0x0001)) {
		hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
			      | UFSHCD_QUIRK_BROKEN_INTR_AGGR
			      | UFSHCD_BROKEN_GEAR_CHANGE_INTO_HS
			      | UFSHCD_BROKEN_LCC);
			      | UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST
			      | UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE);

		phy->quirks = MSM_UFS_PHY_QUIRK_CFG_RESTORE;
	}
+47 −35
Original line number Diff line number Diff line
@@ -2855,6 +2855,43 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
	return 0;
}

static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
{
	int tx_lanes, i, err;

	if (!peer)
		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
			       &tx_lanes);
	else
		ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
				    &tx_lanes);
	for (i = 0; i < tx_lanes; i++) {
		if (!peer)
			err = ufshcd_dme_set(hba,
					UIC_ARG_MIB_SEL(TX_LCC_ENABLE, i), 0);
		else
			err = ufshcd_dme_peer_set(hba,
					UIC_ARG_MIB_SEL(TX_LCC_ENABLE, i), 0);
		if (err) {
			dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d",
				__func__, peer, i, err);
			break;
		}
	}

	return err;
}

static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba)
{
	return ufshcd_disable_tx_lcc(hba, false);
}

static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
{
	return ufshcd_disable_tx_lcc(hba, true);
}

/**
 * ufshcd_link_startup - Initialize unipro link startup
 * @hba: per adapter instance
@@ -2888,45 +2925,20 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
			goto out;
	} while (ret && retries--);

	if (ret) {
	if (ret)
		/* failed to get the link up... retire */
		goto out;
	} else if (hba->quirks & UFSHCD_BROKEN_LCC) {
		int hc_tx_lanes;
		int device_tx_lanes;
		int i;
		int err;

		/*
		 * Disabling the TX_LCC_ENABLE in the Host and in the Device.
		 * As disabling operation is done for each lane, the number of
		 * TX Connected Lanes should be read seperately from host and
		 * from Device and then, apply the disable command on every
		 * lane, on both, Host and Device
		 */
		ufshcd_dme_get(hba,
			UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), &hc_tx_lanes);

		ufshcd_dme_peer_get(hba,
				    UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
				    &device_tx_lanes);

		for (i = 0; i < hc_tx_lanes; ++i) {
			err = ufshcd_dme_set(hba,
				UIC_ARG_MIB_SEL(TX_LCC_ENABLE, i), 0);
			if (err)
				dev_err(hba->dev, "%s: Disable TX_LCC_ENABLE (Host) failed, lane = %d, err = %d",
					__func__, i, err);
		}

		for (i = 0; i < device_tx_lanes; ++i) {
			err = ufshcd_dme_peer_set(hba,
				UIC_ARG_MIB_SEL(TX_LCC_ENABLE, i), 0);
			if (err)
				dev_err(hba->dev, "%s: Disable TX_LCC_ENABLE (Device) failed, lane = %d, err = %d",
					__func__, i, err);
	if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST) {
		ret = ufshcd_disable_device_tx_lcc(hba);
		if (ret)
			goto out;
	}

	if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE) {
		ret = ufshcd_disable_host_tx_lcc(hba);
		if (ret)
			goto out;
	}

	/* Include any host controller configuration via UIC commands */
+16 −4
Original line number Diff line number Diff line
@@ -483,11 +483,13 @@ struct ufs_hba {
	#define UFSHCD_QUIRK_BROKEN_2_TX_LANES            (1 << 8)

	/*
	 * If LCC (Line Control Command) are having issue on the host
	 * controller then enable this quirk. Note that connected UFS device
	 * should also have workaround to not expect LCC commands from host.
	 * If UFS host controller is having issue in processing LCC (Line
	 * Control Command) coming from device then enable this quirk.
	 * When this quirk is enabled, host controller driver should disable
	 * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE
	 * attribute of device to 0).
	 */
	#define UFSHCD_BROKEN_LCC			  (1 << 9)
	#define UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST	  (1 << 9)

	/*
	 * The attribute PA_RXHSUNTERMCAP specifies whether or not the
@@ -496,6 +498,16 @@ struct ufs_hba {
	 */
	#define UFSHCD_BROKEN_GEAR_CHANGE_INTO_HS        (1 << 10)

	/*
	 * If UFS device is having issue in processing LCC (Line Control
	 * Command) coming from UFS host controller then enable this quirk.
	 * When this quirk is enabled, host controller driver should disable
	 * the LCC transmission on UFS host controller (by clearing
	 * TX_LCC_ENABLE attribute of host to 0).
	 */
	#define UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE	  (1 << 11)


	wait_queue_head_t tm_wq;
	wait_queue_head_t tm_tag_wq;
	unsigned long tm_condition;