Lines Matching +full:tx +full:- +full:pcs
1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/clk-provider.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"
42 /* set of registers with offsets different per-PHY */
44 /* PCS registers */
954 u16 pcs; member
955 u16 tx; member
962 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
965 const struct qmp_phy_init_tbl *tx; member
969 const struct qmp_phy_init_tbl *pcs; member
975 /* struct qmp_phy_cfg - per-PHY initialization config */
983 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
997 /* true, if PCS block has no separate SW_RESET register */
1007 void __iomem *pcs; member
1009 void __iomem *tx; member
1050 "vdda-phy", "vdda-pll",
1055 .pcs = 0xc00,
1056 .tx = 0x400,
1064 .pcs = 0x0400,
1065 .tx = 0x1000,
1080 .tx = msm8996_ufsphy_tx,
1103 .tx = sm8350_ufsphy_tx,
1107 .pcs = sm8350_ufsphy_pcs,
1115 .tx = sm8350_ufsphy_g4_tx,
1119 .pcs = sm8350_ufsphy_g4_pcs,
1137 .tx = sc7280_ufsphy_tx,
1141 .pcs = sc7280_ufsphy_pcs,
1149 .tx = sm8250_ufsphy_hs_g4_tx,
1153 .pcs = sm8150_ufsphy_hs_g4_pcs,
1171 .tx = sm8350_ufsphy_tx,
1175 .pcs = sm8350_ufsphy_pcs,
1183 .tx = sm8350_ufsphy_g4_tx,
1187 .pcs = sm8350_ufsphy_g4_pcs,
1205 .tx = sdm845_ufsphy_tx,
1209 .pcs = sdm845_ufsphy_pcs,
1232 .tx = sm6115_ufsphy_tx,
1236 .pcs = sm6115_ufsphy_pcs,
1259 .tx = sdm845_ufsphy_tx,
1263 .pcs = sm7150_ufsphy_pcs,
1286 .tx = sm8150_ufsphy_tx,
1290 .pcs = sm8150_ufsphy_pcs,
1298 .tx = sm8150_ufsphy_hs_g4_tx,
1302 .pcs = sm8150_ufsphy_hs_g4_pcs,
1320 .tx = sm8150_ufsphy_tx,
1324 .pcs = sm8150_ufsphy_pcs,
1332 .tx = sm8250_ufsphy_hs_g4_tx,
1336 .pcs = sm8150_ufsphy_hs_g4_pcs,
1354 .tx = sm8350_ufsphy_tx,
1358 .pcs = sm8350_ufsphy_pcs,
1366 .tx = sm8350_ufsphy_g4_tx,
1370 .pcs = sm8350_ufsphy_g4_pcs,
1388 .tx = sm8350_ufsphy_tx,
1392 .pcs = sm8350_ufsphy_pcs,
1400 .tx = sm8350_ufsphy_g4_tx,
1404 .pcs = sm8350_ufsphy_g4_pcs,
1422 .tx = sm8550_ufsphy_tx,
1426 .pcs = sm8550_ufsphy_pcs,
1436 .tx = sm8550_ufsphy_g4_tx,
1440 .pcs = sm8475_ufsphy_g4_pcs,
1458 .tx = sm8550_ufsphy_tx,
1462 .pcs = sm8550_ufsphy_pcs,
1472 .tx = sm8550_ufsphy_g4_tx,
1476 .pcs = sm8550_ufsphy_g4_pcs,
1485 .pcs = sm8550_ufsphy_g5_pcs,
1503 .tx = sm8650_ufsphy_tx,
1507 .pcs = sm8650_ufsphy_pcs,
1511 .pcs = sm8650_ufsphy_g4_pcs,
1516 .pcs = sm8650_ufsphy_g5_pcs,
1528 void __iomem *serdes = qmp->serdes; in qmp_ufs_serdes_init()
1530 qmp_configure(qmp->dev, serdes, tbls->serdes, tbls->serdes_num); in qmp_ufs_serdes_init()
1535 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_lanes_init()
1536 void __iomem *tx = qmp->tx; in qmp_ufs_lanes_init() local
1537 void __iomem *rx = qmp->rx; in qmp_ufs_lanes_init()
1539 qmp_configure_lane(qmp->dev, tx, tbls->tx, tbls->tx_num, 1); in qmp_ufs_lanes_init()
1540 qmp_configure_lane(qmp->dev, rx, tbls->rx, tbls->rx_num, 1); in qmp_ufs_lanes_init()
1542 if (cfg->lanes >= 2) { in qmp_ufs_lanes_init()
1543 qmp_configure_lane(qmp->dev, qmp->tx2, tbls->tx, tbls->tx_num, 2); in qmp_ufs_lanes_init()
1544 qmp_configure_lane(qmp->dev, qmp->rx2, tbls->rx, tbls->rx_num, 2); in qmp_ufs_lanes_init()
1550 void __iomem *pcs = qmp->pcs; in qmp_ufs_pcs_init() local
1552 qmp_configure(qmp->dev, pcs, tbls->pcs, tbls->pcs_num); in qmp_ufs_pcs_init()
1557 u32 max_gear, floor_max_gear = cfg->max_supported_gear; in qmp_ufs_get_gear_overlay()
1558 int idx, ret = -EINVAL; in qmp_ufs_get_gear_overlay()
1560 for (idx = NUM_OVERLAY - 1; idx >= 0; idx--) { in qmp_ufs_get_gear_overlay()
1561 max_gear = cfg->tbls_hs_overlay[idx].max_gear; in qmp_ufs_get_gear_overlay()
1568 if (qmp->submode == max_gear) in qmp_ufs_get_gear_overlay()
1585 qmp_ufs_serdes_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1586 qmp_ufs_lanes_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1587 qmp_ufs_pcs_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1591 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_overlay[i]); in qmp_ufs_init_registers()
1592 qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_overlay[i]); in qmp_ufs_init_registers()
1593 qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_overlay[i]); in qmp_ufs_init_registers()
1596 if (qmp->mode == PHY_MODE_UFS_HS_B) in qmp_ufs_init_registers()
1597 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b); in qmp_ufs_init_registers()
1602 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_com_init()
1603 void __iomem *pcs = qmp->pcs; in qmp_ufs_com_init() local
1606 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_init()
1608 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); in qmp_ufs_com_init()
1612 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_ufs_com_init()
1616 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); in qmp_ufs_com_init()
1621 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_init()
1628 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_com_exit()
1630 reset_control_assert(qmp->ufs_reset); in qmp_ufs_com_exit()
1632 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_ufs_com_exit()
1634 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_exit()
1642 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_init()
1644 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); in qmp_ufs_init()
1646 if (cfg->no_pcs_sw_reset) { in qmp_ufs_init()
1652 if (!qmp->ufs_reset) { in qmp_ufs_init()
1653 qmp->ufs_reset = in qmp_ufs_init()
1654 devm_reset_control_get_exclusive(qmp->dev, in qmp_ufs_init()
1657 if (IS_ERR(qmp->ufs_reset)) { in qmp_ufs_init()
1658 ret = PTR_ERR(qmp->ufs_reset); in qmp_ufs_init()
1659 dev_err(qmp->dev, in qmp_ufs_init()
1663 qmp->ufs_reset = NULL; in qmp_ufs_init()
1668 ret = reset_control_assert(qmp->ufs_reset); in qmp_ufs_init()
1683 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_on()
1684 void __iomem *pcs = qmp->pcs; in qmp_ufs_power_on() local
1691 ret = reset_control_deassert(qmp->ufs_reset); in qmp_ufs_power_on()
1696 if (!cfg->no_pcs_sw_reset) in qmp_ufs_power_on()
1697 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_ufs_power_on()
1700 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); in qmp_ufs_power_on()
1702 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; in qmp_ufs_power_on()
1706 dev_err(qmp->dev, "phy initialization timed-out\n"); in qmp_ufs_power_on()
1716 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_off()
1719 if (!cfg->no_pcs_sw_reset) in qmp_ufs_power_off()
1720 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_ufs_power_off()
1723 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); in qmp_ufs_power_off()
1726 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_ufs_power_off()
1769 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_set_mode()
1771 if (submode > cfg->max_supported_gear || submode == 0) { in qmp_ufs_set_mode()
1772 dev_err(qmp->dev, "Invalid PHY submode %d\n", submode); in qmp_ufs_set_mode()
1773 return -EINVAL; in qmp_ufs_set_mode()
1776 qmp->mode = mode; in qmp_ufs_set_mode()
1777 qmp->submode = submode; in qmp_ufs_set_mode()
1791 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_vreg_init()
1792 struct device *dev = qmp->dev; in qmp_ufs_vreg_init()
1793 int num = cfg->num_vregs; in qmp_ufs_vreg_init()
1796 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); in qmp_ufs_vreg_init()
1797 if (!qmp->vregs) in qmp_ufs_vreg_init()
1798 return -ENOMEM; in qmp_ufs_vreg_init()
1801 qmp->vregs[i].supply = cfg->vreg_list[i]; in qmp_ufs_vreg_init()
1803 return devm_regulator_bulk_get(dev, num, qmp->vregs); in qmp_ufs_vreg_init()
1808 struct device *dev = qmp->dev; in qmp_ufs_clk_init()
1810 qmp->num_clks = devm_clk_bulk_get_all(dev, &qmp->clks); in qmp_ufs_clk_init()
1811 if (qmp->num_clks < 0) in qmp_ufs_clk_init()
1812 return qmp->num_clks; in qmp_ufs_clk_init()
1831 clk_data = devm_kzalloc(qmp->dev, in qmp_ufs_register_clocks()
1835 return -ENOMEM; in qmp_ufs_register_clocks()
1837 clk_data->num = UFS_SYMBOL_CLOCKS; in qmp_ufs_register_clocks()
1839 snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1840 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1844 clk_data->hws[0] = hw; in qmp_ufs_register_clocks()
1846 snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1847 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1851 clk_data->hws[1] = hw; in qmp_ufs_register_clocks()
1853 snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1854 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1858 clk_data->hws[2] = hw; in qmp_ufs_register_clocks()
1867 return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np); in qmp_ufs_register_clocks()
1872 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt_legacy()
1873 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt_legacy()
1874 struct device *dev = qmp->dev; in qmp_ufs_parse_dt_legacy()
1876 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); in qmp_ufs_parse_dt_legacy()
1877 if (IS_ERR(qmp->serdes)) in qmp_ufs_parse_dt_legacy()
1878 return PTR_ERR(qmp->serdes); in qmp_ufs_parse_dt_legacy()
1882 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. in qmp_ufs_parse_dt_legacy()
1883 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 in qmp_ufs_parse_dt_legacy()
1884 * For single lane PHYs: pcs_misc (optional) -> 3. in qmp_ufs_parse_dt_legacy()
1886 qmp->tx = devm_of_iomap(dev, np, 0, NULL); in qmp_ufs_parse_dt_legacy()
1887 if (IS_ERR(qmp->tx)) in qmp_ufs_parse_dt_legacy()
1888 return PTR_ERR(qmp->tx); in qmp_ufs_parse_dt_legacy()
1890 qmp->rx = devm_of_iomap(dev, np, 1, NULL); in qmp_ufs_parse_dt_legacy()
1891 if (IS_ERR(qmp->rx)) in qmp_ufs_parse_dt_legacy()
1892 return PTR_ERR(qmp->rx); in qmp_ufs_parse_dt_legacy()
1894 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); in qmp_ufs_parse_dt_legacy()
1895 if (IS_ERR(qmp->pcs)) in qmp_ufs_parse_dt_legacy()
1896 return PTR_ERR(qmp->pcs); in qmp_ufs_parse_dt_legacy()
1898 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt_legacy()
1899 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
1900 if (IS_ERR(qmp->tx2)) in qmp_ufs_parse_dt_legacy()
1901 return PTR_ERR(qmp->tx2); in qmp_ufs_parse_dt_legacy()
1903 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); in qmp_ufs_parse_dt_legacy()
1904 if (IS_ERR(qmp->rx2)) in qmp_ufs_parse_dt_legacy()
1905 return PTR_ERR(qmp->rx2); in qmp_ufs_parse_dt_legacy()
1907 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); in qmp_ufs_parse_dt_legacy()
1909 qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
1912 if (IS_ERR(qmp->pcs_misc)) in qmp_ufs_parse_dt_legacy()
1913 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); in qmp_ufs_parse_dt_legacy()
1920 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt()
1921 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt()
1922 const struct qmp_ufs_offsets *offs = cfg->offsets; in qmp_ufs_parse_dt()
1926 return -EINVAL; in qmp_ufs_parse_dt()
1932 qmp->serdes = base + offs->serdes; in qmp_ufs_parse_dt()
1933 qmp->pcs = base + offs->pcs; in qmp_ufs_parse_dt()
1934 qmp->tx = base + offs->tx; in qmp_ufs_parse_dt()
1935 qmp->rx = base + offs->rx; in qmp_ufs_parse_dt()
1937 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt()
1938 qmp->tx2 = base + offs->tx2; in qmp_ufs_parse_dt()
1939 qmp->rx2 = base + offs->rx2; in qmp_ufs_parse_dt()
1947 struct device *dev = &pdev->dev; in qmp_ufs_probe()
1955 return -ENOMEM; in qmp_ufs_probe()
1957 qmp->dev = dev; in qmp_ufs_probe()
1959 qmp->cfg = of_device_get_match_data(dev); in qmp_ufs_probe()
1960 if (!qmp->cfg) in qmp_ufs_probe()
1961 return -EINVAL; in qmp_ufs_probe()
1972 np = of_get_next_available_child(dev->of_node, NULL); in qmp_ufs_probe()
1976 np = of_node_get(dev->of_node); in qmp_ufs_probe()
1986 qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops); in qmp_ufs_probe()
1987 if (IS_ERR(qmp->phy)) { in qmp_ufs_probe()
1988 ret = PTR_ERR(qmp->phy); in qmp_ufs_probe()
1993 phy_set_drvdata(qmp->phy, qmp); in qmp_ufs_probe()
2008 .compatible = "qcom,msm8996-qmp-ufs-phy",
2011 .compatible = "qcom,msm8998-qmp-ufs-phy",
2014 .compatible = "qcom,sa8775p-qmp-ufs-phy",
2017 .compatible = "qcom,sc7180-qmp-ufs-phy",
2020 .compatible = "qcom,sc7280-qmp-ufs-phy",
2023 .compatible = "qcom,sc8180x-qmp-ufs-phy",
2026 .compatible = "qcom,sc8280xp-qmp-ufs-phy",
2029 .compatible = "qcom,sdm845-qmp-ufs-phy",
2032 .compatible = "qcom,sm6115-qmp-ufs-phy",
2035 .compatible = "qcom,sm6125-qmp-ufs-phy",
2038 .compatible = "qcom,sm6350-qmp-ufs-phy",
2041 .compatible = "qcom,sm7150-qmp-ufs-phy",
2044 .compatible = "qcom,sm8150-qmp-ufs-phy",
2047 .compatible = "qcom,sm8250-qmp-ufs-phy",
2050 .compatible = "qcom,sm8350-qmp-ufs-phy",
2053 .compatible = "qcom,sm8450-qmp-ufs-phy",
2056 .compatible = "qcom,sm8475-qmp-ufs-phy",
2059 .compatible = "qcom,sm8550-qmp-ufs-phy",
2062 .compatible = "qcom,sm8650-qmp-ufs-phy",
2072 .name = "qcom-qmp-ufs-phy",