Lines Matching +full:regulator +full:- +full:v6
1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/clk-provider.h>
18 #include <linux/regulator/consumer.h>
23 #include "phy-qcom-qmp.h"
24 #include "phy-qcom-qmp-pcs-ufs-v2.h"
25 #include "phy-qcom-qmp-pcs-ufs-v3.h"
26 #include "phy-qcom-qmp-pcs-ufs-v4.h"
27 #include "phy-qcom-qmp-pcs-ufs-v5.h"
28 #include "phy-qcom-qmp-pcs-ufs-v6.h"
30 #include "phy-qcom-qmp-qserdes-txrx-ufs-v6.h"
68 /* set of registers with offsets different per-PHY */
711 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
722 /* struct qmp_phy_cfg - per-PHY initialization config */
728 /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
811 "vdda-phy", "vdda-pll",
1179 if (!(t->lane_mask & lane_mask)) in qmp_ufs_configure_lane()
1182 writel(t->val, base + t->offset); in qmp_ufs_configure_lane()
1195 void __iomem *serdes = qmp->serdes; in qmp_ufs_serdes_init()
1197 qmp_ufs_configure(serdes, tbls->serdes, tbls->serdes_num); in qmp_ufs_serdes_init()
1202 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_lanes_init()
1203 void __iomem *tx = qmp->tx; in qmp_ufs_lanes_init()
1204 void __iomem *rx = qmp->rx; in qmp_ufs_lanes_init()
1206 qmp_ufs_configure_lane(tx, tbls->tx, tbls->tx_num, 1); in qmp_ufs_lanes_init()
1207 qmp_ufs_configure_lane(rx, tbls->rx, tbls->rx_num, 1); in qmp_ufs_lanes_init()
1209 if (cfg->lanes >= 2) { in qmp_ufs_lanes_init()
1210 qmp_ufs_configure_lane(qmp->tx2, tbls->tx, tbls->tx_num, 2); in qmp_ufs_lanes_init()
1211 qmp_ufs_configure_lane(qmp->rx2, tbls->rx, tbls->rx_num, 2); in qmp_ufs_lanes_init()
1217 void __iomem *pcs = qmp->pcs; in qmp_ufs_pcs_init()
1219 qmp_ufs_configure(pcs, tbls->pcs, tbls->pcs_num); in qmp_ufs_pcs_init()
1224 qmp_ufs_serdes_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1225 if (qmp->mode == PHY_MODE_UFS_HS_B) in qmp_ufs_init_registers()
1226 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b); in qmp_ufs_init_registers()
1227 qmp_ufs_lanes_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1228 if (qmp->submode == UFS_HS_G4) in qmp_ufs_init_registers()
1229 qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4); in qmp_ufs_init_registers()
1230 qmp_ufs_pcs_init(qmp, &cfg->tbls); in qmp_ufs_init_registers()
1231 if (qmp->submode == UFS_HS_G4) in qmp_ufs_init_registers()
1232 qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4); in qmp_ufs_init_registers()
1237 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_com_init()
1238 void __iomem *pcs = qmp->pcs; in qmp_ufs_com_init()
1241 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_init()
1243 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); in qmp_ufs_com_init()
1247 ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks); in qmp_ufs_com_init()
1251 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); in qmp_ufs_com_init()
1256 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_init()
1263 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_com_exit()
1265 reset_control_assert(qmp->ufs_reset); in qmp_ufs_com_exit()
1267 clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks); in qmp_ufs_com_exit()
1269 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_ufs_com_exit()
1277 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_init()
1279 dev_vdbg(qmp->dev, "Initializing QMP phy\n"); in qmp_ufs_init()
1281 if (cfg->no_pcs_sw_reset) { in qmp_ufs_init()
1287 if (!qmp->ufs_reset) { in qmp_ufs_init()
1288 qmp->ufs_reset = in qmp_ufs_init()
1289 devm_reset_control_get_exclusive(qmp->dev, in qmp_ufs_init()
1292 if (IS_ERR(qmp->ufs_reset)) { in qmp_ufs_init()
1293 ret = PTR_ERR(qmp->ufs_reset); in qmp_ufs_init()
1294 dev_err(qmp->dev, in qmp_ufs_init()
1298 qmp->ufs_reset = NULL; in qmp_ufs_init()
1303 ret = reset_control_assert(qmp->ufs_reset); in qmp_ufs_init()
1318 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_on()
1319 void __iomem *pcs = qmp->pcs; in qmp_ufs_power_on()
1326 ret = reset_control_deassert(qmp->ufs_reset); in qmp_ufs_power_on()
1331 if (!cfg->no_pcs_sw_reset) in qmp_ufs_power_on()
1332 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_ufs_power_on()
1335 qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); in qmp_ufs_power_on()
1337 status = pcs + cfg->regs[QPHY_PCS_READY_STATUS]; in qmp_ufs_power_on()
1341 dev_err(qmp->dev, "phy initialization timed-out\n"); in qmp_ufs_power_on()
1351 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_power_off()
1354 if (!cfg->no_pcs_sw_reset) in qmp_ufs_power_off()
1355 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_ufs_power_off()
1358 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START); in qmp_ufs_power_off()
1361 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_ufs_power_off()
1405 qmp->mode = mode; in qmp_ufs_set_mode()
1406 qmp->submode = submode; in qmp_ufs_set_mode()
1420 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_vreg_init()
1421 struct device *dev = qmp->dev; in qmp_ufs_vreg_init()
1422 int num = cfg->num_vregs; in qmp_ufs_vreg_init()
1425 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); in qmp_ufs_vreg_init()
1426 if (!qmp->vregs) in qmp_ufs_vreg_init()
1427 return -ENOMEM; in qmp_ufs_vreg_init()
1430 qmp->vregs[i].supply = cfg->vreg_list[i]; in qmp_ufs_vreg_init()
1432 return devm_regulator_bulk_get(dev, num, qmp->vregs); in qmp_ufs_vreg_init()
1437 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_clk_init()
1438 struct device *dev = qmp->dev; in qmp_ufs_clk_init()
1439 int num = cfg->num_clks; in qmp_ufs_clk_init()
1442 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); in qmp_ufs_clk_init()
1443 if (!qmp->clks) in qmp_ufs_clk_init()
1444 return -ENOMEM; in qmp_ufs_clk_init()
1447 qmp->clks[i].id = cfg->clk_list[i]; in qmp_ufs_clk_init()
1449 return devm_clk_bulk_get(dev, num, qmp->clks); in qmp_ufs_clk_init()
1466 clk_data = devm_kzalloc(qmp->dev, in qmp_ufs_register_clocks()
1470 return -ENOMEM; in qmp_ufs_register_clocks()
1472 clk_data->num = UFS_SYMBOL_CLOCKS; in qmp_ufs_register_clocks()
1474 snprintf(name, sizeof(name), "%s::rx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1475 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1479 clk_data->hws[0] = hw; in qmp_ufs_register_clocks()
1481 snprintf(name, sizeof(name), "%s::rx_symbol_1", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1482 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1486 clk_data->hws[1] = hw; in qmp_ufs_register_clocks()
1488 snprintf(name, sizeof(name), "%s::tx_symbol_0", dev_name(qmp->dev)); in qmp_ufs_register_clocks()
1489 hw = devm_clk_hw_register_fixed_rate(qmp->dev, name, NULL, 0, 0); in qmp_ufs_register_clocks()
1493 clk_data->hws[2] = hw; in qmp_ufs_register_clocks()
1502 return devm_add_action_or_reset(qmp->dev, qmp_ufs_clk_release_provider, np); in qmp_ufs_register_clocks()
1507 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt_legacy()
1508 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt_legacy()
1509 struct device *dev = qmp->dev; in qmp_ufs_parse_dt_legacy()
1511 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); in qmp_ufs_parse_dt_legacy()
1512 if (IS_ERR(qmp->serdes)) in qmp_ufs_parse_dt_legacy()
1513 return PTR_ERR(qmp->serdes); in qmp_ufs_parse_dt_legacy()
1517 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2. in qmp_ufs_parse_dt_legacy()
1518 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5 in qmp_ufs_parse_dt_legacy()
1519 * For single lane PHYs: pcs_misc (optional) -> 3. in qmp_ufs_parse_dt_legacy()
1521 qmp->tx = devm_of_iomap(dev, np, 0, NULL); in qmp_ufs_parse_dt_legacy()
1522 if (IS_ERR(qmp->tx)) in qmp_ufs_parse_dt_legacy()
1523 return PTR_ERR(qmp->tx); in qmp_ufs_parse_dt_legacy()
1525 qmp->rx = devm_of_iomap(dev, np, 1, NULL); in qmp_ufs_parse_dt_legacy()
1526 if (IS_ERR(qmp->rx)) in qmp_ufs_parse_dt_legacy()
1527 return PTR_ERR(qmp->rx); in qmp_ufs_parse_dt_legacy()
1529 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); in qmp_ufs_parse_dt_legacy()
1530 if (IS_ERR(qmp->pcs)) in qmp_ufs_parse_dt_legacy()
1531 return PTR_ERR(qmp->pcs); in qmp_ufs_parse_dt_legacy()
1533 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt_legacy()
1534 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
1535 if (IS_ERR(qmp->tx2)) in qmp_ufs_parse_dt_legacy()
1536 return PTR_ERR(qmp->tx2); in qmp_ufs_parse_dt_legacy()
1538 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); in qmp_ufs_parse_dt_legacy()
1539 if (IS_ERR(qmp->rx2)) in qmp_ufs_parse_dt_legacy()
1540 return PTR_ERR(qmp->rx2); in qmp_ufs_parse_dt_legacy()
1542 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); in qmp_ufs_parse_dt_legacy()
1544 qmp->pcs_misc = devm_of_iomap(dev, np, 3, NULL); in qmp_ufs_parse_dt_legacy()
1547 if (IS_ERR(qmp->pcs_misc)) in qmp_ufs_parse_dt_legacy()
1548 dev_vdbg(dev, "PHY pcs_misc-reg not used\n"); in qmp_ufs_parse_dt_legacy()
1555 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_ufs_parse_dt()
1556 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_ufs_parse_dt()
1557 const struct qmp_ufs_offsets *offs = cfg->offsets; in qmp_ufs_parse_dt()
1561 return -EINVAL; in qmp_ufs_parse_dt()
1567 qmp->serdes = base + offs->serdes; in qmp_ufs_parse_dt()
1568 qmp->pcs = base + offs->pcs; in qmp_ufs_parse_dt()
1569 qmp->tx = base + offs->tx; in qmp_ufs_parse_dt()
1570 qmp->rx = base + offs->rx; in qmp_ufs_parse_dt()
1572 if (cfg->lanes >= 2) { in qmp_ufs_parse_dt()
1573 qmp->tx2 = base + offs->tx2; in qmp_ufs_parse_dt()
1574 qmp->rx2 = base + offs->rx2; in qmp_ufs_parse_dt()
1582 struct device *dev = &pdev->dev; in qmp_ufs_probe()
1590 return -ENOMEM; in qmp_ufs_probe()
1592 qmp->dev = dev; in qmp_ufs_probe()
1594 qmp->cfg = of_device_get_match_data(dev); in qmp_ufs_probe()
1595 if (!qmp->cfg) in qmp_ufs_probe()
1596 return -EINVAL; in qmp_ufs_probe()
1607 np = of_get_next_available_child(dev->of_node, NULL); in qmp_ufs_probe()
1611 np = of_node_get(dev->of_node); in qmp_ufs_probe()
1621 qmp->phy = devm_phy_create(dev, np, &qcom_qmp_ufs_phy_ops); in qmp_ufs_probe()
1622 if (IS_ERR(qmp->phy)) { in qmp_ufs_probe()
1623 ret = PTR_ERR(qmp->phy); in qmp_ufs_probe()
1628 phy_set_drvdata(qmp->phy, qmp); in qmp_ufs_probe()
1643 .compatible = "qcom,msm8996-qmp-ufs-phy",
1646 .compatible = "qcom,msm8998-qmp-ufs-phy",
1649 .compatible = "qcom,sa8775p-qmp-ufs-phy",
1652 .compatible = "qcom,sc8180x-qmp-ufs-phy",
1655 .compatible = "qcom,sc8280xp-qmp-ufs-phy",
1658 .compatible = "qcom,sdm845-qmp-ufs-phy",
1661 .compatible = "qcom,sm6115-qmp-ufs-phy",
1664 .compatible = "qcom,sm6125-qmp-ufs-phy",
1667 .compatible = "qcom,sm6350-qmp-ufs-phy",
1670 .compatible = "qcom,sm7150-qmp-ufs-phy",
1673 .compatible = "qcom,sm8150-qmp-ufs-phy",
1676 .compatible = "qcom,sm8250-qmp-ufs-phy",
1679 .compatible = "qcom,sm8350-qmp-ufs-phy",
1682 .compatible = "qcom,sm8450-qmp-ufs-phy",
1685 .compatible = "qcom,sm8550-qmp-ufs-phy",
1695 .name = "qcom-qmp-ufs-phy",