Lines Matching +full:vdda +full:- +full:phy +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/clk-provider.h>
16 #include <linux/phy/phy.h>
24 #include "phy-qcom-qmp-common.h"
26 #include "phy-qcom-qmp.h"
27 #include "phy-qcom-qmp-pcs-ufs-v2.h"
28 #include "phy-qcom-qmp-pcs-ufs-v3.h"
29 #include "phy-qcom-qmp-pcs-ufs-v4.h"
30 #include "phy-qcom-qmp-pcs-ufs-v5.h"
31 #include "phy-qcom-qmp-pcs-ufs-v6.h"
33 #include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
34 #include "phy-qcom-qmp-qserdes-txrx-ufs-v7.h"
43 /* set of registers with offsets different per-PHY */
1081 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
1094 /* struct qmp_phy_cfg - per-PHY initialization config */
1102 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
1138 struct phy *phy; member
1169 { .supply = "vdda-phy", .init_load_uA = 51400 },
1170 { .supply = "vdda-pll", .init_load_uA = 14600 },
1174 { .supply = "vdda-phy", .init_load_uA = 137000 },
1175 { .supply = "vdda-pll", .init_load_uA = 18300 },
1179 { .supply = "vdda-phy", .init_load_uA = 97500 },
1180 { .supply = "vdda-pll", .init_load_uA = 18400 },
1184 { .supply = "vdda-phy", .init_load_uA = 85700 },
1185 { .supply = "vdda-pll", .init_load_uA = 18300 },
1189 { .supply = "vdda-phy", .init_load_uA = 51400 },
1190 { .supply = "vdda-pll", .init_load_uA = 14600 },
1194 { .supply = "vdda-phy", .init_load_uA = 51400 },
1195 { .supply = "vdda-pll", .init_load_uA = 14200 },
1199 { .supply = "vdda-phy", .init_load_uA = 62900 },
1200 { .supply = "vdda-pll", .init_load_uA = 18300 },
1204 { .supply = "vdda-phy", .init_load_uA = 90200 },
1205 { .supply = "vdda-pll", .init_load_uA = 19000 },
1209 { .supply = "vdda-phy", .init_load_uA = 89900 },
1210 { .supply = "vdda-pll", .init_load_uA = 18800 },
1214 { .supply = "vdda-phy", .init_load_uA = 91600 },
1215 { .supply = "vdda-pll", .init_load_uA = 19000 },
1219 { .supply = "vdda-phy", .init_load_uA = 173000 },
1220 { .supply = "vdda-pll", .init_load_uA = 24900 },
1224 { .supply = "vdda-phy", .init_load_uA = 213030 },
1225 { .supply = "vdda-pll", .init_load_uA = 18340 },
1229 { .supply = "vdda-phy", .init_load_uA = 188000 },
1230 { .supply = "vdda-pll", .init_load_uA = 18300 },
1234 { .supply = "vdda-phy", .init_load_uA = 205000 },
1235 { .supply = "vdda-pll", .init_load_uA = 17500 },
1239 { .supply = "vdda-phy", .init_load_uA = 213000 },
1240 { .supply = "vdda-pll", .init_load_uA = 18300 },
1757 void __iomem *serdes = qmp->serdes; in qmp_ufs_serdes_init()
1759 qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num); in qmp_ufs_serdes_init()
1764 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_lanes_init()
1765 void __iomem *tx = qmp->tx; in qmp_ufs_lanes_init()
1766 void __iomem *rx = qmp->rx; in qmp_ufs_lanes_init()
1768 qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1); in qmp_ufs_lanes_init()
1769 qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1); in qmp_ufs_lanes_init()
1771 if (cfg->lanes >= 2) { in qmp_ufs_lanes_init()
1772 qmp_configure_lane(qmp->dev, qmp->tx2, tbls->tx, tbls->tx_num, 2); in qmp_ufs_lanes_init()
1773 qmp_configure_lane(qmp->dev, qmp->rx2, tbls->rx, tbls->rx_num, 2); in qmp_ufs_lanes_init()
1779 void __iomem *pcs = qmp->pcs; in qmp_ufs_pcs_init()
1781 qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num); in qmp_ufs_pcs_init()
1786 u32 max_gear, floor_max_gear = cfg->max_supported_gear; in qmp_ufs_get_gear_overlay()
1787 int idx, ret = -EINVAL; in qmp_ufs_get_gear_overlay()
1789 for (idx = NUM_OVERLAY - 1; idx >= 0; idx--) { in qmp_ufs_get_gear_overlay()
1790 max_gear = cfg->tbls_hs_overlay[idx].max_gear; in qmp_ufs_get_gear_overlay()
1797 if (qmp->submode == max_gear) in qmp_ufs_get_gear_overlay()
1821 qmp_ufs_init_all(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1825 qmp_ufs_init_all(qmp, &cfg->tbls_hs_overlay[i]); in qmp_ufs_init_registers()
1828 if (qmp->mode == PHY_MODE_UFS_HS_B) in qmp_ufs_init_registers()
1829 qmp_ufs_init_all(qmp, &cfg->tbls_hs_b); in qmp_ufs_init_registers()
1832 static int qmp_ufs_power_on(struct phy *phy) in qmp_ufs_power_on() argument
1834 struct qmp_ufs *qmp = phy_get_drvdata(phy); in qmp_ufs_power_on()
1835 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_on()
1836 void __iomem *pcs = qmp->pcs; in qmp_ufs_power_on()
1839 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); in qmp_ufs_power_on()
1841 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); in qmp_ufs_power_on()
1845 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_ufs_power_on()
1849 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); in qmp_ufs_power_on()
1853 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_power_on()
1857 static int qmp_ufs_phy_calibrate(struct phy *phy) in qmp_ufs_phy_calibrate() argument
1859 struct qmp_ufs *qmp = phy_get_drvdata(phy); in qmp_ufs_phy_calibrate()
1860 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_phy_calibrate()
1861 void __iomem *pcs = qmp->pcs; in qmp_ufs_phy_calibrate()
1866 ret = reset_control_assert(qmp->ufs_reset); in qmp_ufs_phy_calibrate()
1872 ret = reset_control_deassert(qmp->ufs_reset); in qmp_ufs_phy_calibrate()
1876 /* Pull PHY out of reset state */ in qmp_ufs_phy_calibrate()
1877 if (!cfg->no_pcs_sw_reset) in qmp_ufs_phy_calibrate()
1878 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_ufs_phy_calibrate()
1881 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); in qmp_ufs_phy_calibrate()
1883 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; in qmp_ufs_phy_calibrate()
1887 dev_err(qmp->dev, "phy initialization timed-out\n"); in qmp_ufs_phy_calibrate()
1894 static int qmp_ufs_power_off(struct phy *phy) in qmp_ufs_power_off() argument
1896 struct qmp_ufs *qmp = phy_get_drvdata(phy); in qmp_ufs_power_off()
1897 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_off()
1899 /* Put PHY into POWER DOWN state: active low */ in qmp_ufs_power_off()
1900 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_ufs_power_off()
1903 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_ufs_power_off()
1905 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_power_off()
1910 static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode) in qmp_ufs_set_mode() argument
1912 struct qmp_ufs *qmp = phy_get_drvdata(phy); in qmp_ufs_set_mode()
1913 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_set_mode()
1915 if (submode > cfg->max_supported_gear || submode == 0) { in qmp_ufs_set_mode()
1916 dev_err(qmp->dev, "Invalid PHY submode %d\n", submode); in qmp_ufs_set_mode()
1917 return -EINVAL; in qmp_ufs_set_mode()
1920 qmp->mode = mode; in qmp_ufs_set_mode()
1921 qmp->submode = submode; in qmp_ufs_set_mode()
1926 static int qmp_ufs_phy_init(struct phy *phy) in qmp_ufs_phy_init() argument
1928 struct qmp_ufs *qmp = phy_get_drvdata(phy); in qmp_ufs_phy_init()
1929 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_phy_init()
1932 if (!cfg->no_pcs_sw_reset) in qmp_ufs_phy_init()
1937 * circular dependency where UFS needs its PHY, but the PHY in qmp_ufs_phy_init()
1940 if (!qmp->ufs_reset) { in qmp_ufs_phy_init()
1941 qmp->ufs_reset = in qmp_ufs_phy_init()
1942 devm_reset_control_get_exclusive(qmp->dev, "ufsphy"); in qmp_ufs_phy_init()
1944 if (IS_ERR(qmp->ufs_reset)) { in qmp_ufs_phy_init()
1945 ret = PTR_ERR(qmp->ufs_reset); in qmp_ufs_phy_init()
1946 dev_err(qmp->dev, "failed to get PHY reset: %d\n", ret); in qmp_ufs_phy_init()
1947 qmp->ufs_reset = NULL; in qmp_ufs_phy_init()
1967 struct device *dev = qmp->dev; in qmp_ufs_clk_init()
1969 qmp->num_clks = devm_clk_bulk_get_all(dev, &qmp->clks); in qmp_ufs_clk_init()
1970 if (qmp->num_clks < 0) in qmp_ufs_clk_init()
1971 return qmp->num_clks; in qmp_ufs_clk_init()
1990 clk_data = devm_kzalloc(qmp->dev, in qmp_ufs_register_clocks()
1994 return -ENOMEM; in qmp_ufs_register_clocks()
1996 clk_data->num = UFS_SYMBOL_CLOCKS; in qmp_ufs_register_clocks()
1998 snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1999 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
2003 clk_data->hws[0] = hw; in qmp_ufs_register_clocks()
2005 snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
2006 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
2010 clk_data->hws[1] = hw; in qmp_ufs_register_clocks()
2012 snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
2013 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
2017 clk_data->hws[2] = hw; in qmp_ufs_register_clocks()
2026 return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np); in qmp_ufs_register_clocks()
2031 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt_legacy()
2032 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt_legacy()
2033 struct device *dev = qmp->dev; in qmp_ufs_parse_dt_legacy()
2035 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); in qmp_ufs_parse_dt_legacy()
2036 if (IS_ERR(qmp->serdes)) in qmp_ufs_parse_dt_legacy()
2037 return PTR_ERR(qmp->serdes); in qmp_ufs_parse_dt_legacy()
2040 * Get memory resources for the PHY: in qmp_ufs_parse_dt_legacy()
2041 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. in qmp_ufs_parse_dt_legacy()
2042 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 in qmp_ufs_parse_dt_legacy()
2043 * For single lane PHYs: pcs_misc (optional) -> 3. in qmp_ufs_parse_dt_legacy()
2045 qmp->tx = devm_of_iomap(dev, np, 0, NULL); in qmp_ufs_parse_dt_legacy()
2046 if (IS_ERR(qmp->tx)) in qmp_ufs_parse_dt_legacy()
2047 return PTR_ERR(qmp->tx); in qmp_ufs_parse_dt_legacy()
2049 qmp->rx = devm_of_iomap(dev, np, 1, NULL); in qmp_ufs_parse_dt_legacy()
2050 if (IS_ERR(qmp->rx)) in qmp_ufs_parse_dt_legacy()
2051 return PTR_ERR(qmp->rx); in qmp_ufs_parse_dt_legacy()
2053 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); in qmp_ufs_parse_dt_legacy()
2054 if (IS_ERR(qmp->pcs)) in qmp_ufs_parse_dt_legacy()
2055 return PTR_ERR(qmp->pcs); in qmp_ufs_parse_dt_legacy()
2057 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt_legacy()
2058 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
2059 if (IS_ERR(qmp->tx2)) in qmp_ufs_parse_dt_legacy()
2060 return PTR_ERR(qmp->tx2); in qmp_ufs_parse_dt_legacy()
2062 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); in qmp_ufs_parse_dt_legacy()
2063 if (IS_ERR(qmp->rx2)) in qmp_ufs_parse_dt_legacy()
2064 return PTR_ERR(qmp->rx2); in qmp_ufs_parse_dt_legacy()
2066 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); in qmp_ufs_parse_dt_legacy()
2068 qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
2071 if (IS_ERR(qmp->pcs_misc)) in qmp_ufs_parse_dt_legacy()
2072 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); in qmp_ufs_parse_dt_legacy()
2079 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt()
2080 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt()
2081 const struct qmp_ufs_offsets *offs = cfg->offsets; in qmp_ufs_parse_dt()
2085 return -EINVAL; in qmp_ufs_parse_dt()
2091 qmp->serdes = base + offs->serdes; in qmp_ufs_parse_dt()
2092 qmp->pcs = base + offs->pcs; in qmp_ufs_parse_dt()
2093 qmp->tx = base + offs->tx; in qmp_ufs_parse_dt()
2094 qmp->rx = base + offs->rx; in qmp_ufs_parse_dt()
2096 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt()
2097 qmp->tx2 = base + offs->tx2; in qmp_ufs_parse_dt()
2098 qmp->rx2 = base + offs->rx2; in qmp_ufs_parse_dt()
2106 struct device *dev = &pdev->dev; in qmp_ufs_probe()
2114 return -ENOMEM; in qmp_ufs_probe()
2116 qmp->dev = dev; in qmp_ufs_probe()
2118 qmp->cfg = of_device_get_match_data(dev); in qmp_ufs_probe()
2119 if (!qmp->cfg) in qmp_ufs_probe()
2120 return -EINVAL; in qmp_ufs_probe()
2126 ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, in qmp_ufs_probe()
2127 qmp->cfg->vreg_list, in qmp_ufs_probe()
2128 &qmp->vregs); in qmp_ufs_probe()
2133 np = of_get_next_available_child(dev->of_node, NULL); in qmp_ufs_probe()
2137 np = of_node_get(dev->of_node); in qmp_ufs_probe()
2147 qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops); in qmp_ufs_probe()
2148 if (IS_ERR(qmp->phy)) { in qmp_ufs_probe()
2149 ret = PTR_ERR(qmp->phy); in qmp_ufs_probe()
2150 dev_err(dev, "failed to create PHY: %d\n", ret); in qmp_ufs_probe()
2154 phy_set_drvdata(qmp->phy, qmp); in qmp_ufs_probe()
2169 .compatible = "qcom,msm8996-qmp-ufs-phy",
2172 .compatible = "qcom,msm8998-qmp-ufs-phy",
2175 .compatible = "qcom,sa8775p-qmp-ufs-phy",
2178 .compatible = "qcom,sc7180-qmp-ufs-phy",
2181 .compatible = "qcom,sc7280-qmp-ufs-phy",
2184 .compatible = "qcom,sc8180x-qmp-ufs-phy",
2187 .compatible = "qcom,sc8280xp-qmp-ufs-phy",
2190 .compatible = "qcom,sdm845-qmp-ufs-phy",
2193 .compatible = "qcom,sm6115-qmp-ufs-phy",
2196 .compatible = "qcom,sm6125-qmp-ufs-phy",
2199 .compatible = "qcom,sm6350-qmp-ufs-phy",
2202 .compatible = "qcom,sm7150-qmp-ufs-phy",
2205 .compatible = "qcom,sm8150-qmp-ufs-phy",
2208 .compatible = "qcom,sm8250-qmp-ufs-phy",
2211 .compatible = "qcom,sm8350-qmp-ufs-phy",
2214 .compatible = "qcom,sm8450-qmp-ufs-phy",
2217 .compatible = "qcom,sm8475-qmp-ufs-phy",
2220 .compatible = "qcom,sm8550-qmp-ufs-phy",
2223 .compatible = "qcom,sm8650-qmp-ufs-phy",
2226 .compatible = "qcom,sm8750-qmp-ufs-phy",
2237 .name = "qcom-qmp-ufs-phy",
2245 MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");