Lines Matching +full:fully +full:- +full:featured

1 // SPDX-License-Identifier: GPL-2.0
5 * Antoine Tenart <antoine.tenart@free-electrons.com>
8 #include <linux/arm-smccc.h>
20 /* Relative to priv->base */
108 /* Relative to priv->regmap */
130 * [ 1- 0]: COMPHY polarity invertion
131 * [ 2- 7]: COMPHY speed
132 * [ 5-11]: COMPHY port index
133 * [12-16]: COMPHY mode
135 * [18-20]: PCIe width (x1, x2, x4)
172 #define COMPHY_FW_MODE_2500BASEX 0x3 /* 2500BASE-X */
204 .mux = -1, \
249 ETH_CONF(4, 1, PHY_INTERFACE_MODE_10GBASER, -1, COMPHY_FW_MODE_XFI),
289 return -EOPNOTSUPP;
291 return -EINVAL;
309 if (conf->lane == lane &&
310 conf->port == port &&
311 conf->mode == mode &&
312 (conf->submode == submode || ignore_submode))
317 return -EINVAL;
320 return conf->fw_mode;
322 return conf->mux;
339 struct mvebu_comphy_priv *priv = lane->priv;
342 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
345 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
348 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
357 switch (lane->submode) {
378 dev_err(priv->dev,
380 lane->submode,
381 lane->id);
382 return -ENOTSUPP;
385 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
387 if (lane->submode == PHY_INTERFACE_MODE_RXAUI) {
388 regmap_read(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, &val);
390 switch (lane->id) {
400 dev_err(priv->dev,
402 lane->id);
403 return -EINVAL;
406 regmap_write(priv->regmap, MVEBU_COMPHY_SD1_CTRL1, val);
410 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
414 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
416 /* de-assert reset */
417 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
420 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
426 regmap_read(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), &val);
428 regmap_write(priv->regmap, MVEBU_COMPHY_CONF6(lane->id), val);
431 val = readl(priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
433 if (lane->submode == PHY_INTERFACE_MODE_10GBASER)
435 writel(val, priv->base + MVEBU_COMPHY_MISC_CTRL0(lane->id));
438 val = readl(priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
443 writel(val, priv->base + MVEBU_COMPHY_PWRPLL_CTRL(lane->id));
445 val = readl(priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
448 writel(val, priv->base + MVEBU_COMPHY_LOOPBACK(lane->id));
455 struct mvebu_comphy_priv *priv = lane->priv;
459 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
463 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG0(lane->id));
466 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
473 return -ETIMEDOUT;
476 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
478 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
481 readl_poll_timeout(priv->base + MVEBU_COMPHY_SERDES_STATUS0(lane->id),
485 return -ETIMEDOUT;
487 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
489 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
497 struct mvebu_comphy_priv *priv = lane->priv;
505 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
508 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
510 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
512 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
514 regmap_read(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), &val);
517 regmap_write(priv->regmap, MVEBU_COMPHY_CONF1(lane->id), val);
519 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
522 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
530 struct mvebu_comphy_priv *priv = lane->priv;
538 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
541 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
543 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
545 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
547 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
549 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
551 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
553 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
555 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
558 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
560 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
566 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
568 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
570 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
572 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
575 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
583 struct mvebu_comphy_priv *priv = lane->priv;
591 val = readl(priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
594 writel(val, priv->base + MVEBU_COMPHY_RX_CTRL1(lane->id));
596 val = readl(priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
598 writel(val, priv->base + MVEBU_COMPHY_DTL_CTRL(lane->id));
601 val = readl(priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
603 writel(val, priv->base + MVEBU_COMPHY_SPEED_DIV(lane->id));
605 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
607 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG2(lane->id));
610 val = readl(priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
612 writel(val, priv->base + MVEBU_COMPHY_DFE_RES(lane->id));
614 val = readl(priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
619 writel(val, priv->base + MVEBU_COMPHY_GEN1_S0(lane->id));
621 val = readl(priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
624 writel(val, priv->base + MVEBU_COMPHY_GEN1_S2(lane->id));
626 val = readl(priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
629 writel(val, priv->base + MVEBU_COMPHY_TX_SLEW_RATE(lane->id));
632 val = readl(priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
636 writel(val, priv->base + MVEBU_COMPHY_IMP_CAL(lane->id));
638 val = readl(priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
640 writel(val, priv->base + MVEBU_COMPHY_GEN1_S5(lane->id));
642 val = readl(priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
652 writel(val, priv->base + MVEBU_COMPHY_GEN1_S1(lane->id));
654 val = readl(priv->base + MVEBU_COMPHY_COEF(lane->id));
656 writel(val, priv->base + MVEBU_COMPHY_COEF(lane->id));
658 val = readl(priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
661 writel(val, priv->base + MVEBU_COMPHY_GEN1_S4(lane->id));
663 val = readl(priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
665 writel(val, priv->base + MVEBU_COMPHY_GEN1_S3(lane->id));
668 val = readl(priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
671 writel(val, priv->base + MVEBU_COMPHY_TRAINING5(lane->id));
674 val = readl(priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
676 writel(val, priv->base + MVEBU_COMPHY_TRAINING0(lane->id));
678 val = readl(priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
681 writel(val, priv->base + MVEBU_COMPHY_TX_PRESET(lane->id));
683 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
685 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT3(lane->id));
687 val = readl(priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
690 writel(val, priv->base + MVEBU_COMPHY_TX_TRAIN_PRESET(lane->id));
692 val = readl(priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
695 writel(val, priv->base + MVEBU_COMPHY_FRAME_DETECT0(lane->id));
697 val = readl(priv->base + MVEBU_COMPHY_DME(lane->id));
699 writel(val, priv->base + MVEBU_COMPHY_DME(lane->id));
701 val = readl(priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
703 writel(val, priv->base + MVEBU_COMPHY_VDD_CAL0(lane->id));
705 val = readl(priv->base + MVEBU_SP_CALIB(lane->id));
709 writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
711 writel(val, priv->base + MVEBU_SP_CALIB(lane->id));
714 val = readl(priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
717 writel(val, priv->base + MVEBU_COMPHY_EXT_SELV(lane->id));
725 struct mvebu_comphy_priv *priv = lane->priv;
729 mux = mvebu_comphy_get_mux(lane->id, lane->port,
730 lane->mode, lane->submode);
732 return -ENOTSUPP;
734 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
735 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
736 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
738 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
739 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
740 val |= mux << MVEBU_COMPHY_SELECTOR_PHY(lane->id);
741 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
743 switch (lane->submode) {
755 return -ENOTSUPP;
759 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
761 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
769 struct mvebu_comphy_priv *priv = lane->priv;
774 fw_mode = mvebu_comphy_get_fw_mode(lane->id, lane->port,
775 lane->mode, lane->submode);
780 switch (lane->mode) {
782 switch (lane->submode) {
784 dev_dbg(priv->dev, "set lane %d to RXAUI mode\n",
785 lane->id);
789 dev_dbg(priv->dev, "set lane %d to 1000BASE-X mode\n",
790 lane->id);
794 dev_dbg(priv->dev, "set lane %d to 2500BASE-X mode\n",
795 lane->id);
799 dev_dbg(priv->dev, "set lane %d to 5GBASE-R mode\n",
800 lane->id);
804 dev_dbg(priv->dev, "set lane %d to 10GBASE-R mode\n",
805 lane->id);
809 dev_err(priv->dev, "unsupported Ethernet mode (%d)\n",
810 lane->submode);
811 return -ENOTSUPP;
813 fw_param = COMPHY_FW_PARAM_ETH(fw_mode, lane->port, fw_speed);
817 dev_dbg(priv->dev, "set lane %d to USB3 mode\n", lane->id);
818 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
821 dev_dbg(priv->dev, "set lane %d to SATA mode\n", lane->id);
822 fw_param = COMPHY_FW_PARAM(fw_mode, lane->port);
825 dev_dbg(priv->dev, "set lane %d to PCIe mode (x%d)\n", lane->id,
826 lane->submode);
827 fw_param = COMPHY_FW_PARAM_PCIE(fw_mode, lane->port,
828 lane->submode);
831 dev_err(priv->dev, "unsupported PHY mode (%d)\n", lane->mode);
832 return -ENOTSUPP;
835 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_ON, priv->cp_phys, lane->id,
840 if (ret == -EOPNOTSUPP)
841 dev_err(priv->dev,
844 dev_warn(priv->dev,
846 lane->id, lane->mode, ret);
861 if (mvebu_comphy_get_fw_mode(lane->id, lane->port, mode, submode) < 0)
862 return -EINVAL;
864 lane->mode = mode;
865 lane->submode = submode;
868 if (mode == PHY_MODE_PCIE && !lane->submode)
869 lane->submode = 1;
877 struct mvebu_comphy_priv *priv = lane->priv;
880 val = readl(priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
884 writel(val, priv->base + MVEBU_COMPHY_SERDES_CFG1(lane->id));
886 regmap_read(priv->regmap, MVEBU_COMPHY_SELECTOR, &val);
887 val &= ~(0xf << MVEBU_COMPHY_SELECTOR_PHY(lane->id));
888 regmap_write(priv->regmap, MVEBU_COMPHY_SELECTOR, val);
890 regmap_read(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, &val);
891 val &= ~(0xf << MVEBU_COMPHY_PIPE_SELECTOR_PIPE(lane->id));
892 regmap_write(priv->regmap, MVEBU_COMPHY_PIPE_SELECTOR, val);
900 struct mvebu_comphy_priv *priv = lane->priv;
903 ret = mvebu_comphy_smc(COMPHY_SIP_POWER_OFF, priv->cp_phys,
904 lane->id, 0);
925 if (WARN_ON(args->args[0] >= MVEBU_COMPHY_PORTS))
926 return ERR_PTR(-EINVAL);
933 lane->port = args->args[0];
942 priv->mg_domain_clk = devm_clk_get(priv->dev, "mg_clk");
943 if (IS_ERR(priv->mg_domain_clk))
944 return PTR_ERR(priv->mg_domain_clk);
946 ret = clk_prepare_enable(priv->mg_domain_clk);
950 priv->mg_core_clk = devm_clk_get(priv->dev, "mg_core_clk");
951 if (IS_ERR(priv->mg_core_clk)) {
952 ret = PTR_ERR(priv->mg_core_clk);
956 ret = clk_prepare_enable(priv->mg_core_clk);
960 priv->axi_clk = devm_clk_get(priv->dev, "axi_clk");
961 if (IS_ERR(priv->axi_clk)) {
962 ret = PTR_ERR(priv->axi_clk);
966 ret = clk_prepare_enable(priv->axi_clk);
973 clk_disable_unprepare(priv->mg_core_clk);
976 clk_disable_unprepare(priv->mg_domain_clk);
978 priv->mg_domain_clk = NULL;
979 priv->mg_core_clk = NULL;
980 priv->axi_clk = NULL;
987 if (priv->axi_clk)
988 clk_disable_unprepare(priv->axi_clk);
990 if (priv->mg_core_clk)
991 clk_disable_unprepare(priv->mg_core_clk);
993 if (priv->mg_domain_clk)
994 clk_disable_unprepare(priv->mg_domain_clk);
1005 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1007 return -ENOMEM;
1009 priv->dev = &pdev->dev;
1010 priv->regmap =
1011 syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
1012 "marvell,system-controller");
1013 if (IS_ERR(priv->regmap))
1014 return PTR_ERR(priv->regmap);
1015 priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1016 if (IS_ERR(priv->base))
1017 return PTR_ERR(priv->base);
1025 if (ret == -EPROBE_DEFER)
1027 dev_warn(&pdev->dev, "cannot initialize clocks\n");
1034 priv->cp_phys = res->start;
1036 for_each_available_child_of_node(pdev->dev.of_node, child) {
1043 dev_err(&pdev->dev, "missing 'reg' property (%d)\n",
1049 dev_err(&pdev->dev, "invalid 'reg' property\n");
1053 lane = devm_kzalloc(&pdev->dev, sizeof(*lane), GFP_KERNEL);
1056 ret = -ENOMEM;
1060 phy = devm_phy_create(&pdev->dev, child, &mvebu_comphy_ops);
1067 lane->priv = priv;
1068 lane->mode = PHY_MODE_INVALID;
1069 lane->submode = PHY_INTERFACE_MODE_NA;
1070 lane->id = val;
1071 lane->port = -1;
1078 * reasons we cannot de-configure the COMPHY without being sure
1079 * that the firmware is up-to-date and fully-featured.
1083 dev_set_drvdata(&pdev->dev, priv);
1084 provider = devm_of_phy_provider_register(&pdev->dev,
1096 { .compatible = "marvell,comphy-cp110" },
1104 .name = "mvebu-comphy",
1110 MODULE_AUTHOR("Antoine Tenart <antoine.tenart@free-electrons.com>");