Loading Documentation/devicetree/bindings/ufs/ufs-qcom.txt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,10 @@ Optional properties: - vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply - 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 - 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) (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: Example: Loading @@ -38,6 +42,7 @@ Example: reg = <0xfc597000 0x800>; reg = <0xfc597000 0x800>; reg-names = "phy_mem"; reg-names = "phy_mem"; #phy-cells = <0>; #phy-cells = <0>; lanes-per-direction = <1>; vdda-phy-supply = <&pma8084_l4>; vdda-phy-supply = <&pma8084_l4>; vdda-pll-supply = <&pma8084_l12>; vdda-pll-supply = <&pma8084_l12>; vdda-phy-max-microamp = <50000>; vdda-phy-max-microamp = <50000>; Loading drivers/phy/phy-qcom-ufs-i.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,10 @@ struct ufs_qcom_phy { struct ufs_qcom_phy_vreg vdda_pll; struct ufs_qcom_phy_vreg vdda_pll; struct ufs_qcom_phy_vreg vdda_phy; struct ufs_qcom_phy_vreg vdda_phy; struct ufs_qcom_phy_vreg vddp_ref_clk; 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; unsigned int quirks; /* /* Loading drivers/phy/phy-qcom-ufs-qmp-v3.c +17 −20 Original line number Original line Diff line number Diff line Loading @@ -20,27 +20,24 @@ static int ufs_qcom_phy_qmp_v3_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, int ufs_qcom_phy_qmp_v3_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, bool is_rate_B) bool is_rate_B) { { int err; /* int tbl_size_A, tbl_size_B; * Writing PHY calibration in this order: struct ufs_qcom_phy_calibration *tbl_A, *tbl_B; * 1. Write Rate-A calibration first (1-lane mode). * 2. Write 2nd lane configuration if needed. tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); * 3. Write Rate-B calibration overrides tbl_B = phy_cal_table_rate_B; */ ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_A, tbl_A = phy_cal_table_rate_A; ARRAY_SIZE(phy_cal_table_rate_A)); tbl_size_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, err = ufs_qcom_phy_calibrate(ufs_qcom_phy, ARRAY_SIZE(phy_cal_table_2nd_lane)); tbl_A, tbl_size_A, if (is_rate_B) tbl_B, tbl_size_B, ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_B, is_rate_B); ARRAY_SIZE(phy_cal_table_rate_B)); /* flush buffered writes */ if (err) mb(); dev_err(ufs_qcom_phy->dev, "%s: ufs_qcom_phy_calibrate() failed %d\n", __func__, err); return err; return 0; } } static int ufs_qcom_phy_qmp_v3_init(struct phy *generic_phy) static int ufs_qcom_phy_qmp_v3_init(struct phy *generic_phy) Loading drivers/phy/phy-qcom-ufs-qmp-v3.h +10 −7 Original line number Original line Diff line number Diff line Loading @@ -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_SO_SATURATION_AND_ENABLE, 0x4B), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX0_UCDR_PI_CONTROLS, 0xF1), 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(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_TX1_LANE_MODE_1, 0x06), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_LVL, 0x24), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_LVL, 0x24), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_CNTRL, 0x0F), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_CNTRL, 0x0F), Loading @@ -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_PI_CONTROLS, 0xF1), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_UCDR_FASTLOCK_COUNT_LOW, 0x80), 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_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[] = { static struct ufs_qcom_phy_calibration phy_cal_table_rate_B[] = { Loading drivers/phy/phy-qcom-ufs.c +7 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,8 @@ #define VDDP_REF_CLK_MIN_UV 1200000 #define VDDP_REF_CLK_MIN_UV 1200000 #define VDDP_REF_CLK_MAX_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 *, static int __ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, const char *, bool); const char *, bool); static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, Loading Loading @@ -113,6 +115,11 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, goto out; 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 * UFS PHY power management is managed by its parent (UFS host * controller) hence set the no the no runtime PM callbacks flag * controller) hence set the no the no runtime PM callbacks flag Loading Loading
Documentation/devicetree/bindings/ufs/ufs-qcom.txt +5 −0 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,10 @@ Optional properties: - vdda-pll-max-microamp : specifies max. load that can be drawn from pll supply - 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 - 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) (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: Example: Loading @@ -38,6 +42,7 @@ Example: reg = <0xfc597000 0x800>; reg = <0xfc597000 0x800>; reg-names = "phy_mem"; reg-names = "phy_mem"; #phy-cells = <0>; #phy-cells = <0>; lanes-per-direction = <1>; vdda-phy-supply = <&pma8084_l4>; vdda-phy-supply = <&pma8084_l4>; vdda-pll-supply = <&pma8084_l12>; vdda-pll-supply = <&pma8084_l12>; vdda-phy-max-microamp = <50000>; vdda-phy-max-microamp = <50000>; Loading
drivers/phy/phy-qcom-ufs-i.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -97,6 +97,10 @@ struct ufs_qcom_phy { struct ufs_qcom_phy_vreg vdda_pll; struct ufs_qcom_phy_vreg vdda_pll; struct ufs_qcom_phy_vreg vdda_phy; struct ufs_qcom_phy_vreg vdda_phy; struct ufs_qcom_phy_vreg vddp_ref_clk; 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; unsigned int quirks; /* /* Loading
drivers/phy/phy-qcom-ufs-qmp-v3.c +17 −20 Original line number Original line Diff line number Diff line Loading @@ -20,27 +20,24 @@ static int ufs_qcom_phy_qmp_v3_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, int ufs_qcom_phy_qmp_v3_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy, bool is_rate_B) bool is_rate_B) { { int err; /* int tbl_size_A, tbl_size_B; * Writing PHY calibration in this order: struct ufs_qcom_phy_calibration *tbl_A, *tbl_B; * 1. Write Rate-A calibration first (1-lane mode). * 2. Write 2nd lane configuration if needed. tbl_size_B = ARRAY_SIZE(phy_cal_table_rate_B); * 3. Write Rate-B calibration overrides tbl_B = phy_cal_table_rate_B; */ ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_A, tbl_A = phy_cal_table_rate_A; ARRAY_SIZE(phy_cal_table_rate_A)); tbl_size_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, err = ufs_qcom_phy_calibrate(ufs_qcom_phy, ARRAY_SIZE(phy_cal_table_2nd_lane)); tbl_A, tbl_size_A, if (is_rate_B) tbl_B, tbl_size_B, ufs_qcom_phy_write_tbl(ufs_qcom_phy, phy_cal_table_rate_B, is_rate_B); ARRAY_SIZE(phy_cal_table_rate_B)); /* flush buffered writes */ if (err) mb(); dev_err(ufs_qcom_phy->dev, "%s: ufs_qcom_phy_calibrate() failed %d\n", __func__, err); return err; return 0; } } static int ufs_qcom_phy_qmp_v3_init(struct phy *generic_phy) static int ufs_qcom_phy_qmp_v3_init(struct phy *generic_phy) Loading
drivers/phy/phy-qcom-ufs-qmp-v3.h +10 −7 Original line number Original line Diff line number Diff line Loading @@ -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_SO_SATURATION_AND_ENABLE, 0x4B), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX0_UCDR_PI_CONTROLS, 0xF1), 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(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_TX1_LANE_MODE_1, 0x06), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_LVL, 0x24), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_LVL, 0x24), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_CNTRL, 0x0F), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_SIGDET_CNTRL, 0x0F), Loading @@ -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_PI_CONTROLS, 0xF1), UFS_QCOM_PHY_CAL_ENTRY(QSERDES_RX1_UCDR_FASTLOCK_COUNT_LOW, 0x80), 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_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[] = { static struct ufs_qcom_phy_calibration phy_cal_table_rate_B[] = { Loading
drivers/phy/phy-qcom-ufs.c +7 −0 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,8 @@ #define VDDP_REF_CLK_MIN_UV 1200000 #define VDDP_REF_CLK_MIN_UV 1200000 #define VDDP_REF_CLK_MAX_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 *, static int __ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, const char *, bool); const char *, bool); static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, static int ufs_qcom_phy_init_vreg(struct phy *, struct ufs_qcom_phy_vreg *, Loading Loading @@ -113,6 +115,11 @@ struct phy *ufs_qcom_phy_generic_probe(struct platform_device *pdev, goto out; 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 * UFS PHY power management is managed by its parent (UFS host * controller) hence set the no the no runtime PM callbacks flag * controller) hence set the no the no runtime PM callbacks flag Loading