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

Commit 8bfeb635 authored by Subhash Jadavani's avatar Subhash Jadavani
Browse files

phy: qcom-ufs-qmp-v3: separate out 2 lanes configuration



SDM845 have 2 UFS PHY instances, one instance supports 2-lane while other
instance supports only 1-lane. This change separates out the 2nd lane
configuration from 1-lane configuration so that we can apply the 2nd
lane configuration only if needed. Added DT attribute "lanes-per-direction"
to differentiate between 1-lane and 2-lane PHY.

Change-Id: Idcf8aaa8ed7a9662c0f4186e5a28d2405f8fd5fc
Signed-off-by: default avatarSubhash Jadavani <subhashj@codeaurora.org>
parent e5bb92bd
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -30,6 +30,10 @@ Optional properties:
- vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply
- qcom,disable-lpm : disable various LPM mechanisms in UFS for platform compatibility
  (limit link to PWM Gear-1, 1-lane slow mode; disable hibernate, and avoid suspend/resume)
- lanes-per-direction:	number of lanes available per direction - either 1 or 2.
			Note that it is assumed that same number of lanes is
			used both directions at once.
			If not specified, default is 2 lanes per direction.

Example:

@@ -38,6 +42,7 @@ Example:
		reg = <0xfc597000 0x800>;
		reg-names = "phy_mem";
		#phy-cells = <0>;
		lanes-per-direction = <1>;
		vdda-phy-supply = <&pma8084_l4>;
		vdda-pll-supply = <&pma8084_l12>;
		vdda-phy-max-microamp = <50000>;
+4 −0
Original line number Diff line number Diff line
@@ -97,6 +97,10 @@ struct ufs_qcom_phy {
	struct ufs_qcom_phy_vreg vdda_pll;
	struct ufs_qcom_phy_vreg vdda_phy;
	struct ufs_qcom_phy_vreg vddp_ref_clk;

	/* Number of lanes available (1 or 2) for Rx/Tx */
	u32 lanes_per_direction;

	unsigned int quirks;

	/*
+17 −20
Original line number Diff line number Diff line
@@ -20,27 +20,24 @@ static
int ufs_qcom_phy_qmp_v3_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
					bool is_rate_B)
{
	int err;
	int tbl_size_A, tbl_size_B;
	struct ufs_qcom_phy_calibration *tbl_A, *tbl_B;

	tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B);
	tbl_B = phy_cal_table_rate_B;

	tbl_A = phy_cal_table_rate_A;
	tbl_size_A = ARRAY_SIZE(phy_cal_table_rate_A);

	err = ufs_qcom_phy_calibrate(ufs_qcom_phy,
				     tbl_A, tbl_size_A,
				     tbl_B, tbl_size_B,
				     is_rate_B);

	if (err)
		dev_err(ufs_qcom_phy->dev,
			"%s: ufs_qcom_phy_calibrate() failed %d\n",
			__func__, err);
	/*
	 * Writing PHY calibration in this order:
	 * 1. Write Rate-A calibration first (1-lane mode).
	 * 2. Write 2nd lane configuration if needed.
	 * 3. Write Rate-B calibration overrides
	 */
	ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_A,
			       ARRAY_SIZE(phy_cal_table_rate_A));
	if (ufs_qcom_phy->lanes_per_direction == 2)
		ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_2nd_lane,
				       ARRAY_SIZE(phy_cal_table_2nd_lane));
	if (is_rate_B)
		ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_B,
				       ARRAY_SIZE(phy_cal_table_rate_B));
	/* flush buffered writes */
	mb();

	return err;
	return 0;
}

static int ufs_qcom_phy_qmp_v3_init(struct phy *generic_phy)
+10 −7
Original line number Diff line number Diff line
@@ -262,6 +262,16 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A[] = {
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x4B),
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX0_UCDR_PI_CONTROLS, 0xF1),
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX0_UCDR_FASTLOCK_COUNT_LOW, 0x80),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SIGDET_CTRL2, 0x6C),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_LARGE_AMP_DRV_LVL, 0x0A),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_SMALL_AMP_DRV_LVL, 0x02),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SYM_RESYNC_CTRL, 0x03),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_MID_TERM_CTRL1, 0x43),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SIGDET_CTRL1, 0x0F),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_HIBERN8_TIME, 0x9A), /* 8 us */
};

static struct ufs_qcom_phy_calibration phy_cal_table_2nd_lane[] = {
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_TX1_LANE_MODE_1, 0x06),
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_LVL, 0x24),
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_CNTRL, 0x0F),
@@ -279,13 +289,6 @@ static struct ufs_qcom_phy_calibration phy_cal_table_rate_A[] = {
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_UCDR_PI_CONTROLS, 0xF1),
	UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_UCDR_FASTLOCK_COUNT_LOW, 0x80),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_MULTI_LANE_CTRL1, 0x02),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SIGDET_CTRL2, 0x6C),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_LARGE_AMP_DRV_LVL, 0x0A),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_SMALL_AMP_DRV_LVL, 0x02),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SYM_RESYNC_CTRL, 0x03),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_TX_MID_TERM_CTRL1, 0x43),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_SIGDET_CTRL1, 0x0F),
	UFS_QCOM_PHY_CAL_ENTRY(UFS_PHY_RX_MIN_HIBERN8_TIME, 0x9A), /* 8 us */
};

static struct ufs_qcom_phy_calibration phy_cal_table_rate_B[] = {
+7 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#define VDDP_REF_CLK_MIN_UV        1200000
#define VDDP_REF_CLK_MAX_UV        1200000

#define UFS_PHY_DEFAULT_LANES_PER_DIRECTION	1

static int __ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
				    const char *, bool);
static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *,
@@ -113,6 +115,11 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev,
		goto out;
	}

	if (of_property_read_u32(dev->of_node, "lanes-per-direction",
				 &common_cfg->lanes_per_direction))
		common_cfg->lanes_per_direction =
			UFS_PHY_DEFAULT_LANES_PER_DIRECTION;

	/*
	 * UFS PHY power management is managed by its parent (UFS host
	 * controller) hence set the no the no runtime PM callbacks flag