Lines Matching full:qmp

26 #include "phy-qcom-qmp-common.h"
28 #include "phy-qcom-qmp.h"
29 #include "phy-qcom-qmp-pcs-misc-v3.h"
459 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_init() local
460 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_init()
461 void __iomem *pcs = qmp->pcs; in qmp_usbc_init()
465 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); in qmp_usbc_init()
467 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret); in qmp_usbc_init()
471 ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets); in qmp_usbc_init()
473 dev_err(qmp->dev, "reset assert failed\n"); in qmp_usbc_init()
477 ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets); in qmp_usbc_init()
479 dev_err(qmp->dev, "reset deassert failed\n"); in qmp_usbc_init()
483 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_usbc_init()
493 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) in qmp_usbc_init()
495 writel(val, qmp->pcs_misc); in qmp_usbc_init()
500 reset_control_bulk_assert(qmp->num_resets, qmp->resets); in qmp_usbc_init()
502 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_usbc_init()
509 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_exit() local
510 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_exit()
512 reset_control_bulk_assert(qmp->num_resets, qmp->resets); in qmp_usbc_exit()
514 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_usbc_exit()
516 regulator_bulk_disable(cfg->num_vregs, qmp->vregs); in qmp_usbc_exit()
523 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_power_on() local
524 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_power_on()
529 qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl, in qmp_usbc_power_on()
532 ret = clk_prepare_enable(qmp->pipe_clk); in qmp_usbc_power_on()
534 dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret); in qmp_usbc_power_on()
539 qmp_configure_lane(qmp->dev, qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1); in qmp_usbc_power_on()
540 qmp_configure_lane(qmp->dev, qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1); in qmp_usbc_power_on()
542 qmp_configure_lane(qmp->dev, qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2); in qmp_usbc_power_on()
543 qmp_configure_lane(qmp->dev, qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); in qmp_usbc_power_on()
545 qmp_configure(qmp->dev, qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); in qmp_usbc_power_on()
548 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_usbc_power_on()
551 qphy_setbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START); in qmp_usbc_power_on()
553 status = qmp->pcs + cfg->regs[QPHY_PCS_STATUS]; in qmp_usbc_power_on()
557 dev_err(qmp->dev, "phy initialization timed-out\n"); in qmp_usbc_power_on()
564 clk_disable_unprepare(qmp->pipe_clk); in qmp_usbc_power_on()
571 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_power_off() local
572 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_power_off()
574 clk_disable_unprepare(qmp->pipe_clk); in qmp_usbc_power_off()
577 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET); in qmp_usbc_power_off()
580 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], in qmp_usbc_power_off()
584 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], in qmp_usbc_power_off()
592 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_enable() local
595 mutex_lock(&qmp->phy_mutex); in qmp_usbc_enable()
607 qmp->usb_init_count++; in qmp_usbc_enable()
609 mutex_unlock(&qmp->phy_mutex); in qmp_usbc_enable()
616 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_disable() local
619 qmp->usb_init_count--; in qmp_usbc_disable()
628 struct qmp_usbc *qmp = phy_get_drvdata(phy); in qmp_usbc_set_mode() local
630 qmp->mode = mode; in qmp_usbc_set_mode()
642 static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp) in qmp_usbc_enable_autonomous_mode() argument
644 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_enable_autonomous_mode()
645 void __iomem *pcs = qmp->pcs; in qmp_usbc_enable_autonomous_mode()
648 if (qmp->mode == PHY_MODE_USB_HOST_SS || in qmp_usbc_enable_autonomous_mode()
649 qmp->mode == PHY_MODE_USB_DEVICE_SS) in qmp_usbc_enable_autonomous_mode()
666 if (qmp->tcsr_map && qmp->vls_clamp_reg) in qmp_usbc_enable_autonomous_mode()
667 regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 1); in qmp_usbc_enable_autonomous_mode()
670 static void qmp_usbc_disable_autonomous_mode(struct qmp_usbc *qmp) in qmp_usbc_disable_autonomous_mode() argument
672 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_disable_autonomous_mode()
673 void __iomem *pcs = qmp->pcs; in qmp_usbc_disable_autonomous_mode()
676 if (qmp->tcsr_map && qmp->vls_clamp_reg) in qmp_usbc_disable_autonomous_mode()
677 regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 0); in qmp_usbc_disable_autonomous_mode()
689 struct qmp_usbc *qmp = dev_get_drvdata(dev); in qmp_usbc_runtime_suspend() local
691 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); in qmp_usbc_runtime_suspend()
693 if (!qmp->phy->init_count) { in qmp_usbc_runtime_suspend()
698 qmp_usbc_enable_autonomous_mode(qmp); in qmp_usbc_runtime_suspend()
700 clk_disable_unprepare(qmp->pipe_clk); in qmp_usbc_runtime_suspend()
701 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_usbc_runtime_suspend()
708 struct qmp_usbc *qmp = dev_get_drvdata(dev); in qmp_usbc_runtime_resume() local
711 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); in qmp_usbc_runtime_resume()
713 if (!qmp->phy->init_count) { in qmp_usbc_runtime_resume()
718 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks); in qmp_usbc_runtime_resume()
722 ret = clk_prepare_enable(qmp->pipe_clk); in qmp_usbc_runtime_resume()
725 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks); in qmp_usbc_runtime_resume()
729 qmp_usbc_disable_autonomous_mode(qmp); in qmp_usbc_runtime_resume()
739 static int qmp_usbc_vreg_init(struct qmp_usbc *qmp) in qmp_usbc_vreg_init() argument
741 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_vreg_init()
742 struct device *dev = qmp->dev; in qmp_usbc_vreg_init()
746 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); in qmp_usbc_vreg_init()
747 if (!qmp->vregs) in qmp_usbc_vreg_init()
751 qmp->vregs[i].supply = cfg->vreg_list[i]; in qmp_usbc_vreg_init()
753 return devm_regulator_bulk_get(dev, num, qmp->vregs); in qmp_usbc_vreg_init()
756 static int qmp_usbc_reset_init(struct qmp_usbc *qmp, in qmp_usbc_reset_init() argument
760 struct device *dev = qmp->dev; in qmp_usbc_reset_init()
764 qmp->resets = devm_kcalloc(dev, num_resets, in qmp_usbc_reset_init()
765 sizeof(*qmp->resets), GFP_KERNEL); in qmp_usbc_reset_init()
766 if (!qmp->resets) in qmp_usbc_reset_init()
770 qmp->resets[i].id = reset_list[i]; in qmp_usbc_reset_init()
772 qmp->num_resets = num_resets; in qmp_usbc_reset_init()
774 ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets); in qmp_usbc_reset_init()
781 static int qmp_usbc_clk_init(struct qmp_usbc *qmp) in qmp_usbc_clk_init() argument
783 struct device *dev = qmp->dev; in qmp_usbc_clk_init()
787 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL); in qmp_usbc_clk_init()
788 if (!qmp->clks) in qmp_usbc_clk_init()
792 qmp->clks[i].id = qmp_usbc_phy_clk_l[i]; in qmp_usbc_clk_init()
794 qmp->num_clks = num; in qmp_usbc_clk_init()
796 return devm_clk_bulk_get_optional(dev, num, qmp->clks); in qmp_usbc_clk_init()
822 static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) in phy_pipe_clk_register() argument
824 struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; in phy_pipe_clk_register()
830 dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); in phy_pipe_clk_register()
836 /* controllers using QMP phys use 125MHz pipe clock interface */ in phy_pipe_clk_register()
840 ret = devm_clk_hw_register(qmp->dev, &fixed->hw); in phy_pipe_clk_register()
852 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np); in phy_pipe_clk_register()
859 struct qmp_usbc *qmp = typec_switch_get_drvdata(sw); in qmp_usbc_typec_switch_set() local
861 if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE) in qmp_usbc_typec_switch_set()
864 mutex_lock(&qmp->phy_mutex); in qmp_usbc_typec_switch_set()
865 qmp->orientation = orientation; in qmp_usbc_typec_switch_set()
867 if (qmp->usb_init_count) { in qmp_usbc_typec_switch_set()
868 qmp_usbc_power_off(qmp->phy); in qmp_usbc_typec_switch_set()
869 qmp_usbc_exit(qmp->phy); in qmp_usbc_typec_switch_set()
871 qmp_usbc_init(qmp->phy); in qmp_usbc_typec_switch_set()
872 qmp_usbc_power_on(qmp->phy); in qmp_usbc_typec_switch_set()
875 mutex_unlock(&qmp->phy_mutex); in qmp_usbc_typec_switch_set()
882 struct qmp_usbc *qmp = data; in qmp_usbc_typec_unregister() local
884 typec_switch_unregister(qmp->sw); in qmp_usbc_typec_unregister()
887 static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp) in qmp_usbc_typec_switch_register() argument
890 struct device *dev = qmp->dev; in qmp_usbc_typec_switch_register()
892 sw_desc.drvdata = qmp; in qmp_usbc_typec_switch_register()
895 qmp->sw = typec_switch_register(dev, &sw_desc); in qmp_usbc_typec_switch_register()
896 if (IS_ERR(qmp->sw)) { in qmp_usbc_typec_switch_register()
897 dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw); in qmp_usbc_typec_switch_register()
898 return PTR_ERR(qmp->sw); in qmp_usbc_typec_switch_register()
901 return devm_add_action_or_reset(dev, qmp_usbc_typec_unregister, qmp); in qmp_usbc_typec_switch_register()
904 static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp) in qmp_usbc_typec_switch_register() argument
910 static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np) in qmp_usbc_parse_dt_legacy() argument
912 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_usbc_parse_dt_legacy()
913 struct device *dev = qmp->dev; in qmp_usbc_parse_dt_legacy()
916 qmp->serdes = devm_platform_ioremap_resource(pdev, 0); in qmp_usbc_parse_dt_legacy()
917 if (IS_ERR(qmp->serdes)) in qmp_usbc_parse_dt_legacy()
918 return PTR_ERR(qmp->serdes); in qmp_usbc_parse_dt_legacy()
926 qmp->tx = devm_of_iomap(dev, np, 0, NULL); in qmp_usbc_parse_dt_legacy()
927 if (IS_ERR(qmp->tx)) in qmp_usbc_parse_dt_legacy()
928 return PTR_ERR(qmp->tx); in qmp_usbc_parse_dt_legacy()
930 qmp->rx = devm_of_iomap(dev, np, 1, NULL); in qmp_usbc_parse_dt_legacy()
931 if (IS_ERR(qmp->rx)) in qmp_usbc_parse_dt_legacy()
932 return PTR_ERR(qmp->rx); in qmp_usbc_parse_dt_legacy()
934 qmp->pcs = devm_of_iomap(dev, np, 2, NULL); in qmp_usbc_parse_dt_legacy()
935 if (IS_ERR(qmp->pcs)) in qmp_usbc_parse_dt_legacy()
936 return PTR_ERR(qmp->pcs); in qmp_usbc_parse_dt_legacy()
938 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL); in qmp_usbc_parse_dt_legacy()
939 if (IS_ERR(qmp->tx2)) in qmp_usbc_parse_dt_legacy()
940 return PTR_ERR(qmp->tx2); in qmp_usbc_parse_dt_legacy()
942 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL); in qmp_usbc_parse_dt_legacy()
943 if (IS_ERR(qmp->rx2)) in qmp_usbc_parse_dt_legacy()
944 return PTR_ERR(qmp->rx2); in qmp_usbc_parse_dt_legacy()
946 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL); in qmp_usbc_parse_dt_legacy()
947 if (IS_ERR(qmp->pcs_misc)) { in qmp_usbc_parse_dt_legacy()
949 qmp->pcs_misc = NULL; in qmp_usbc_parse_dt_legacy()
952 qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL); in qmp_usbc_parse_dt_legacy()
953 if (IS_ERR(qmp->pipe_clk)) { in qmp_usbc_parse_dt_legacy()
954 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), in qmp_usbc_parse_dt_legacy()
958 ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks); in qmp_usbc_parse_dt_legacy()
962 qmp->num_clks = ret; in qmp_usbc_parse_dt_legacy()
964 ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l, in qmp_usbc_parse_dt_legacy()
972 static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) in qmp_usbc_parse_dt() argument
974 struct platform_device *pdev = to_platform_device(qmp->dev); in qmp_usbc_parse_dt()
975 const struct qmp_phy_cfg *cfg = qmp->cfg; in qmp_usbc_parse_dt()
977 struct device *dev = qmp->dev; in qmp_usbc_parse_dt()
988 qmp->serdes = base + offs->serdes; in qmp_usbc_parse_dt()
989 qmp->pcs = base + offs->pcs; in qmp_usbc_parse_dt()
991 qmp->pcs_misc = base + offs->pcs_misc; in qmp_usbc_parse_dt()
992 qmp->tx = base + offs->tx; in qmp_usbc_parse_dt()
993 qmp->rx = base + offs->rx; in qmp_usbc_parse_dt()
995 qmp->tx2 = base + offs->tx2; in qmp_usbc_parse_dt()
996 qmp->rx2 = base + offs->rx2; in qmp_usbc_parse_dt()
998 ret = qmp_usbc_clk_init(qmp); in qmp_usbc_parse_dt()
1002 qmp->pipe_clk = devm_clk_get(dev, "pipe"); in qmp_usbc_parse_dt()
1003 if (IS_ERR(qmp->pipe_clk)) { in qmp_usbc_parse_dt()
1004 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk), in qmp_usbc_parse_dt()
1008 ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l, in qmp_usbc_parse_dt()
1016 static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) in qmp_usbc_parse_vls_clamp() argument
1019 struct device *dev = qmp->dev; in qmp_usbc_parse_vls_clamp()
1030 qmp->tcsr_map = syscon_node_to_regmap(tcsr_args.np); in qmp_usbc_parse_vls_clamp()
1032 if (IS_ERR(qmp->tcsr_map)) in qmp_usbc_parse_vls_clamp()
1033 return PTR_ERR(qmp->tcsr_map); in qmp_usbc_parse_vls_clamp()
1035 qmp->vls_clamp_reg = tcsr_args.args[0]; in qmp_usbc_parse_vls_clamp()
1045 struct qmp_usbc *qmp; in qmp_usbc_probe() local
1048 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL); in qmp_usbc_probe()
1049 if (!qmp) in qmp_usbc_probe()
1052 qmp->dev = dev; in qmp_usbc_probe()
1053 dev_set_drvdata(dev, qmp); in qmp_usbc_probe()
1055 qmp->orientation = TYPEC_ORIENTATION_NORMAL; in qmp_usbc_probe()
1057 qmp->cfg = of_device_get_match_data(dev); in qmp_usbc_probe()
1058 if (!qmp->cfg) in qmp_usbc_probe()
1061 mutex_init(&qmp->phy_mutex); in qmp_usbc_probe()
1063 ret = qmp_usbc_vreg_init(qmp); in qmp_usbc_probe()
1067 ret = qmp_usbc_typec_switch_register(qmp); in qmp_usbc_probe()
1071 ret = qmp_usbc_parse_vls_clamp(qmp); in qmp_usbc_probe()
1078 ret = qmp_usbc_parse_dt_legacy(qmp, np); in qmp_usbc_probe()
1081 ret = qmp_usbc_parse_dt(qmp); in qmp_usbc_probe()
1096 ret = phy_pipe_clk_register(qmp, np); in qmp_usbc_probe()
1100 qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops); in qmp_usbc_probe()
1101 if (IS_ERR(qmp->phy)) { in qmp_usbc_probe()
1102 ret = PTR_ERR(qmp->phy); in qmp_usbc_probe()
1107 phy_set_drvdata(qmp->phy, qmp); in qmp_usbc_probe()
1122 .compatible = "qcom,msm8998-qmp-usb3-phy",
1125 .compatible = "qcom,qcm2290-qmp-usb3-phy",
1128 .compatible = "qcom,sdm660-qmp-usb3-phy",
1131 .compatible = "qcom,sm6115-qmp-usb3-phy",
1141 .name = "qcom-qmp-usbc-phy",
1150 MODULE_DESCRIPTION("Qualcomm QMP USB-C PHY driver");