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

Commit c2805f54 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "scsi: ufs-qcom: set device ref. clk bit"

parents 31d344c3 fb4a0e6a
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1198,8 +1198,8 @@

	ufsphy1: ufsphy@fc597000 {
			compatible = "qcom,ufs-phy-qmp-20nm";
			reg = <0xfc597000 0xda8>, <0xfd512074 0x4>;
			reg-names = "phy_mem", "dev_ref_clk_ctrl_mem";
			reg = <0xfc597000 0xda8>;
			reg-names = "phy_mem";
			#phy-cells = <0>;
			vdda-phy-supply = <&pm8994_l28>;
			vdda-pll-supply = <&pm8994_l12>;
@@ -1221,7 +1221,7 @@

	ufs1: ufshc@fc594000 {
			compatible = "qcom,ufshc";
			reg = <0xfc594000 0x2500>;
			reg = <0xfc594000 0x2500>, <0xfd512074 0x4>;
			interrupts = <0 265 0>;
			phys = <&ufsphy1>;
			phy-names = "ufsphy";
+0 −67
Original line number Diff line number Diff line
@@ -142,26 +142,7 @@ int ufs_qcom_phy_base_init(struct platform_device *pdev,
		phy_common->mmio = NULL;
		dev_err(dev, "%s: ioremap for phy_mem resource failed %d\n",
			__func__, err);
		goto out;
	}

	/* "dev_ref_clk_ctrl_mem" is optional resource */
	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
					   "dev_ref_clk_ctrl_mem");
	if (!res) {
		dev_dbg(dev, "%s: dev_ref_clk_ctrl_mem resource not found\n",
			__func__);
		goto out;
	}

	phy_common->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res);
	if (IS_ERR(phy_common->dev_ref_clk_ctrl_mmio)) {
		err = PTR_ERR(phy_common->dev_ref_clk_ctrl_mmio);
		phy_common->dev_ref_clk_ctrl_mmio = NULL;
		dev_err(dev, "%s: ioremap for dev_ref_clk_ctrl_mem resource failed %d\n",
			__func__, err);
	}

out:
	return err;
}
@@ -481,54 +462,6 @@ void ufs_qcom_phy_disable_ref_clk(struct phy *generic_phy)
	}
}

#define UFS_REF_CLK_EN	(1 << 5)

static void ufs_qcom_phy_dev_ref_clk_ctrl(struct phy *generic_phy, bool enable)
{
	struct ufs_qcom_phy *phy = get_ufs_qcom_phy(generic_phy);

	if (phy->dev_ref_clk_ctrl_mmio &&
	    (enable ^ phy->is_dev_ref_clk_enabled)) {
		u32 temp = readl_relaxed(phy->dev_ref_clk_ctrl_mmio);

		if (enable)
			temp |= UFS_REF_CLK_EN;
		else
			temp &= ~UFS_REF_CLK_EN;

		/*
		 * If we are here to disable this clock immediately after
		 * entering into hibern8, we need to make sure that device
		 * ref_clk is active atleast 1us after the hibern8 enter.
		 */
		if (!enable)
			udelay(1);

		writel_relaxed(temp, phy->dev_ref_clk_ctrl_mmio);
		/* ensure that ref_clk is enabled/disabled before we return */
		wmb();
		/*
		 * If we call hibern8 exit after this, we need to make sure that
		 * device ref_clk is stable for atleast 1us before the hibern8
		 * exit command.
		 */
		if (enable)
			udelay(1);

		phy->is_dev_ref_clk_enabled = enable;
	}
}

void ufs_qcom_phy_enable_dev_ref_clk(struct phy *generic_phy)
{
	ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, true);
}

void ufs_qcom_phy_disable_dev_ref_clk(struct phy *generic_phy)
{
	ufs_qcom_phy_dev_ref_clk_ctrl(generic_phy, false);
}

void ufs_qcom_phy_restore_swi_regs(struct phy *generic_phy)
{
	int i;
+73 −9
Original line number Diff line number Diff line
@@ -796,6 +796,44 @@ static int ufs_qcom_update_bus_bw_vote(struct ufs_qcom_host *host)
	return err;
}

#define UFS_REF_CLK_EN	(1 << 5)
static void ufs_qcom_enable_dev_ref_clk(struct ufs_qcom_host *host, bool enable)
{
	if (host->dev_ref_clk_ctrl_mmio &&
	    (enable ^ host->is_dev_ref_clk_enabled)) {
		u32 temp = readl_relaxed(host->dev_ref_clk_ctrl_mmio);

		if (enable)
			temp |= UFS_REF_CLK_EN;
		else
			temp &= ~UFS_REF_CLK_EN;

		/*
		 * If we are here to disable this clock it might be immediately
		 * after entering into hibern8 in which case we need to make
		 * sure that device ref_clk is active at least 1us after the
		 * hibern8 enter.
		 */
		if (!enable)
			udelay(1);

		writel_relaxed(temp, host->dev_ref_clk_ctrl_mmio);

		/* ensure that ref_clk is enabled/disabled before we return */
		wmb();

		/*
		 * If we call hibern8 exit after this, we need to make sure that
		 * device ref_clk is stable for at least 1us before the hibern8
		 * exit command.
		 */
		if (enable)
			udelay(1);

		host->is_dev_ref_clk_enabled = enable;
	}
}

static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
				bool status,
				struct ufs_pa_layer_attr *dev_max_params,
@@ -839,6 +877,10 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
			goto out;
		}

		/* enable the device ref clock before changing to HS mode */
		if (!ufshcd_is_hs_mode(&hba->pwr_info) &&
			ufshcd_is_hs_mode(dev_req_params))
			ufs_qcom_enable_dev_ref_clk(host, true);
		break;
	case POST_CHANGE:
		if (!ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
@@ -866,6 +908,11 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
		memcpy(&host->dev_req_params,
				dev_req_params, sizeof(*dev_req_params));
		ufs_qcom_update_bus_bw_vote(host);

		/* disable the device ref clock if entered PWM mode */
		if (ufshcd_is_hs_mode(&hba->pwr_info) &&
			!ufshcd_is_hs_mode(dev_req_params))
			ufs_qcom_enable_dev_ref_clk(host, false);
		break;
	default:
		ret = -EINVAL;
@@ -886,18 +933,15 @@ out:
 */
static void ufs_qcom_advertise_quirks(struct ufs_hba *hba)
{
	u8 major;
	u16 minor, step;

	ufs_qcom_get_controller_revision(hba, &major, &minor, &step);
	struct ufs_qcom_host *host = hba->priv;

	if (major == 0x1) {
	if (host->hw_ver.major == 0x1) {
		hba->quirks |= (UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS
			      | UFSHCD_QUIRK_BROKEN_PA_RXHSUNTERMCAP
			      | UFSHCD_QUIRK_BROKEN_LCC
			      | UFSHCD_QUIRK_DME_PEER_ACCESS_AUTO_MODE);

		if ((minor == 0x001) && (step == 0x0001))
		if (host->hw_ver.minor == 0x001 && host->hw_ver.step == 0x0001)
			hba->quirks |= UFSHCD_QUIRK_BROKEN_INTR_AGGR;
	}
}
@@ -1002,8 +1046,9 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
			ufs_qcom_phy_disable_iface_clk(host->generic_phy);
			goto out;
		}
		/* enable the device ref clock */
		ufs_qcom_phy_enable_dev_ref_clk(host->generic_phy);
		/* enable the device ref clock for HS mode*/
		if (ufshcd_is_hs_mode(&hba->pwr_info))
			ufs_qcom_enable_dev_ref_clk(host, true);
		vote = host->bus_vote.saved_vote;
		if (vote == host->bus_vote.min_bw_vote)
			ufs_qcom_update_bus_bw_vote(host);
@@ -1014,7 +1059,7 @@ static int ufs_qcom_setup_clocks(struct ufs_hba *hba, bool on)
			/* turn off UFS local PHY ref_clk */
			ufs_qcom_phy_disable_ref_clk(host->generic_phy);
			/* disable device ref_clk */
			ufs_qcom_phy_disable_dev_ref_clk(host->generic_phy);
			ufs_qcom_enable_dev_ref_clk(host, false);
		}
		vote = host->bus_vote.min_bw_vote;
	}
@@ -1122,7 +1167,9 @@ static int ufs_qcom_init(struct ufs_hba *hba)
{
	int err;
	struct device *dev = hba->dev;
	struct platform_device *pdev = to_platform_device(dev);
	struct ufs_qcom_host *host;
	struct resource *res;

	if (strlen(android_boot_dev) && strcmp(android_boot_dev, dev_name(dev)))
		return -ENODEV;
@@ -1185,6 +1232,8 @@ static int ufs_qcom_init(struct ufs_hba *hba)
	if (err)
		goto out_disable_phy;

	ufs_qcom_get_controller_revision(hba, &host->hw_ver.major,
		&host->hw_ver.minor, &host->hw_ver.step);
	ufs_qcom_advertise_quirks(hba);

	hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_CLK_SCALING;
@@ -1192,6 +1241,21 @@ static int ufs_qcom_init(struct ufs_hba *hba)
	hba->caps |= UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
	ufs_qcom_setup_clocks(hba, true);

	/* "dev_ref_clk_ctrl_mem" is optional resource */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_dbg(dev, "%s: dev_ref_clk_ctrl_mem resource not found\n",
			__func__);
	} else {
		host->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res);
		if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) {
			dev_warn(dev,
				"%s: could not map dev_ref_clk_ctrl_mmio, err %ld\n",
				__func__, PTR_ERR(host->dev_ref_clk_ctrl_mmio));
			host->dev_ref_clk_ctrl_mmio = NULL;
		}
	}

	if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
		ufs_qcom_hosts[hba->dev->id] = host;

+0 −1
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@
#include <linux/nls.h>

#include <linux/scsi/ufs/ufshcd.h>
#include <linux/scsi/ufs/unipro.h>
#include "ufshci.h"
#include "ufs_quirks.h"
#include "debugfs.h"
+0 −2
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ struct ufs_qcom_phy {
	struct list_head list;
	struct device *dev;
	void __iomem *mmio;
	void __iomem *dev_ref_clk_ctrl_mmio;
	struct clk *tx_iface_clk;
	struct clk *rx_iface_clk;
	bool is_iface_clk_enabled;
@@ -69,7 +68,6 @@ struct ufs_qcom_phy {
	struct clk *ref_clk_parent;
	struct clk *ref_clk;
	bool is_ref_clk_enabled;
	bool is_dev_ref_clk_enabled;
	struct ufs_qcom_phy_vreg vdda_pll;
	struct ufs_qcom_phy_vreg vdda_phy;
	struct ufs_qcom_phy_vreg vddp_ref_clk;
Loading