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

Commit 9d4ff08f authored by Asutosh Das's avatar Asutosh Das
Browse files

scsi: ufs: Fix phy init sequence



Phy init is assumed to be done during powerup sequence.
The phy init is now being invoked during clock init as
well. At this point in initialization the phy mode and
submode is not yet set. So the phy initialization puts
the phy in a weird state. It also increments the counters
that prevent re-init and re-power-on of the phy.
Thus, when the phy init is invoked during powerup sequence,
it just returns thus leading to failures during controller
enable.

This patch fixes this by removing the phy init during
clock init.

The ufs device reset traditionally uses pinctrl.
This patch moves it to gpio based reset.

Change-Id: Id9205185b042e4f11fc4132419a179ba81af7226
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
Signed-off-by: default avatarBao D Nguyen <nguyenb@codeaurora.org>
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
parent ae89f176
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -1562,10 +1562,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
		return 0;

	if (on && (status == POST_CHANGE)) {
		if (!host->is_phy_pwr_on) {
			phy_power_on(host->generic_phy);
			host->is_phy_pwr_on = true;
		}
		/* enable the device ref clock for HS mode*/
		if (ufshcd_is_hs_mode(&hba->pwr_info))
			ufs_qcom_dev_ref_clk_ctrl(host, true);
@@ -1580,10 +1576,6 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on,
			/* disable device ref_clk */
			ufs_qcom_dev_ref_clk_ctrl(host, false);
			/* powering off PHY during aggressive clk gating */
			if (host->is_phy_pwr_on) {
				phy_power_off(host->generic_phy);
				host->is_phy_pwr_on = false;
			}
		}


+0 −1
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
		return -ENOMEM;

	vreg->name = kstrdup(name, GFP_KERNEL);

	snprintf(prop_name, MAX_PROP_SIZE, "%s-max-microamp", name);
	if (of_property_read_u32(np, prop_name, &vreg->max_uA)) {
		dev_info(dev, "%s: unable to find %s\n", __func__, prop_name);
+2 −67
Original line number Diff line number Diff line
@@ -463,63 +463,6 @@ void ufshcd_scsi_block_requests(struct ufs_hba *hba)
}
EXPORT_SYMBOL(ufshcd_scsi_block_requests);

static int ufshcd_device_reset_ctrl(struct ufs_hba *hba, bool ctrl)
{
	int ret = 0;

	if (!hba->pctrl)
		return 0;

	/* Assert reset if ctrl == true */
	if (ctrl)
		ret = pinctrl_select_state(hba->pctrl,
			pinctrl_lookup_state(hba->pctrl, "dev-reset-assert"));
	else
		ret = pinctrl_select_state(hba->pctrl,
			pinctrl_lookup_state(hba->pctrl, "dev-reset-deassert"));

	if (ret < 0)
		dev_err(hba->dev, "%s: %s failed with err %d\n",
			__func__, ctrl ? "Assert" : "Deassert", ret);

	return ret;
}

static inline int ufshcd_assert_device_reset(struct ufs_hba *hba)
{
	return ufshcd_device_reset_ctrl(hba, true);
}

static inline int ufshcd_deassert_device_reset(struct ufs_hba *hba)
{
	return ufshcd_device_reset_ctrl(hba, false);
}

static int ufshcd_reset_device(struct ufs_hba *hba)
{
	int ret;

	/* reset the connected UFS device */
	ret = ufshcd_assert_device_reset(hba);
	if (ret)
		goto out;
	/*
	 * The reset signal is active low.
	 * The UFS device shall detect more than or equal to 1us of positive
	 * or negative RST_n pulse width.
	 * To be on safe side, keep the reset low for atleast 10us.
	 */
	usleep_range(10, 15);

	ret = ufshcd_deassert_device_reset(hba);
	if (ret)
		goto out;
	/* same as assert, wait for atleast 10us after deassert */
	usleep_range(10, 15);
out:
	return ret;
}

static void ufshcd_add_cmd_upiu_trace(struct ufs_hba *hba, unsigned int tag,
		const char *str)
{
@@ -7466,12 +7409,7 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)

static int ufshcd_detect_device(struct ufs_hba *hba)
{
	int err = 0;

	err = ufshcd_reset_device(hba);
	if (err)
		dev_warn(hba->dev, "%s: device reset failed. err %d\n",
			 __func__, err);
	ufshcd_vops_device_reset(hba);

	return ufshcd_host_reset_and_restore(hba);
}
@@ -9987,10 +9925,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
	}

	/* reset connected UFS device */
	err = ufshcd_reset_device(hba);
	if (err)
		dev_warn(hba->dev, "%s: device reset failed. err %d\n",
			 __func__, err);
	ufshcd_vops_device_reset(hba);

	/* Init crypto */
	err = ufshcd_hba_init_crypto(hba);
+0 −1
Original line number Diff line number Diff line
@@ -919,7 +919,6 @@ struct ufs_hba {
	/* Allow standalone Hibern8 enter on idle */
#define UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE (1 << 5)
	struct rw_semaphore lock;
	struct pinctrl *pctrl;
	/* Bitmask for enabling debug prints */
	u32 ufshcd_dbg_print;
	/* If set, don't gate device ref_clk during clock gating */