Lines Matching +full:mt8173 +full:- +full:u3phy
1 // SPDX-License-Identifier: GPL-2.0
8 #include <dt-bindings/phy/phy.h>
14 #include <linux/nvmem-consumer.h>
21 #include "phy-mtk-io.h"
23 /* version V1 sub-banks offset base address */
34 /* version V2/V3 sub-banks offset base address */
215 /* CDR Charge Pump P-path current adjustment */
234 /* TX driver tail current control for 0dB de-empahsis mdoe for Gen1 speed */
243 /* I-path capacitance adjustment for Gen1 */
274 /* avoid RX sensitivity level degradation only for mt8173 */
342 struct u2phy_banks *u2_banks = &instance->u2_banks; in hs_slew_rate_calibrate()
343 void __iomem *fmreg = u2_banks->fmreg; in hs_slew_rate_calibrate()
344 void __iomem *com = u2_banks->com; in hs_slew_rate_calibrate()
350 if (tphy->pdata->version == MTK_PHY_V3) in hs_slew_rate_calibrate()
354 if (instance->eye_src) in hs_slew_rate_calibrate()
368 if (tphy->pdata->version == MTK_PHY_V1) in hs_slew_rate_calibrate()
369 tmp |= FIELD_PREP(P2F_RG_MONCLK_SEL, instance->index >> 1); in hs_slew_rate_calibrate()
390 tmp = tphy->src_ref_clk * tphy->src_coef; in hs_slew_rate_calibrate()
397 dev_dbg(tphy->dev, "phy:%d, fm_out:%d, calib:%d (clk:%d, coef:%d)\n", in hs_slew_rate_calibrate()
398 instance->index, fm_out, calibration_val, in hs_slew_rate_calibrate()
399 tphy->src_ref_clk, tphy->src_coef); in hs_slew_rate_calibrate()
412 struct u3phy_banks *u3_banks = &instance->u3_banks; in u3_phy_instance_init()
413 void __iomem *phya = u3_banks->phya; in u3_phy_instance_init()
414 void __iomem *phyd = u3_banks->phyd; in u3_phy_instance_init()
417 mtk_phy_set_bits(u3_banks->spllc + U3P_SPLLC_XTALCTL3, in u3_phy_instance_init()
427 mtk_phy_update_bits(u3_banks->phyd + U3P_U3_PHYD_CDR1, in u3_phy_instance_init()
438 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index); in u3_phy_instance_init()
444 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_pll_26m_set()
445 void __iomem *com = u2_banks->com; in u2_phy_pll_26m_set()
447 if (!tphy->pdata->sw_pll_48m_to_26m) in u2_phy_pll_26m_set()
463 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_instance_init()
464 void __iomem *com = u2_banks->com; in u2_phy_instance_init()
465 u32 index = instance->index; in u2_phy_instance_init()
482 if (tphy->pdata->avoid_rx_sen_degradation) { in u2_phy_instance_init()
503 dev_dbg(tphy->dev, "%s(%d)\n", __func__, index); in u2_phy_instance_init()
509 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_instance_power_on()
510 void __iomem *com = u2_banks->com; in u2_phy_instance_power_on()
511 u32 index = instance->index; in u2_phy_instance_power_on()
520 if (tphy->pdata->avoid_rx_sen_degradation && index) { in u2_phy_instance_power_on()
525 dev_dbg(tphy->dev, "%s(%d)\n", __func__, index); in u2_phy_instance_power_on()
531 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_instance_power_off()
532 void __iomem *com = u2_banks->com; in u2_phy_instance_power_off()
533 u32 index = instance->index; in u2_phy_instance_power_off()
542 if (tphy->pdata->avoid_rx_sen_degradation && index) { in u2_phy_instance_power_off()
548 dev_dbg(tphy->dev, "%s(%d)\n", __func__, index); in u2_phy_instance_power_off()
554 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_instance_exit()
555 void __iomem *com = u2_banks->com; in u2_phy_instance_exit()
556 u32 index = instance->index; in u2_phy_instance_exit()
558 if (tphy->pdata->avoid_rx_sen_degradation && index) { in u2_phy_instance_exit()
569 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_instance_set_mode()
572 tmp = readl(u2_banks->com + U3P_U2PHYDTM1); in u2_phy_instance_set_mode()
587 writel(tmp, u2_banks->com + U3P_U2PHYDTM1); in u2_phy_instance_set_mode()
593 struct u3phy_banks *u3_banks = &instance->u3_banks; in pcie_phy_instance_init()
594 void __iomem *phya = u3_banks->phya; in pcie_phy_instance_init()
596 if (tphy->pdata->version != MTK_PHY_V1) in pcie_phy_instance_init()
609 /* SSC delta -5000ppm */ in pcie_phy_instance_init()
628 /* Tx Detect Rx Timing: 10us -> 5us */ in pcie_phy_instance_init()
629 mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_RXDET1, in pcie_phy_instance_init()
632 mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_RXDET2, in pcie_phy_instance_init()
637 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index); in pcie_phy_instance_init()
643 struct u3phy_banks *bank = &instance->u3_banks; in pcie_phy_instance_power_on()
645 mtk_phy_clear_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLD, in pcie_phy_instance_power_on()
648 mtk_phy_clear_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLE, in pcie_phy_instance_power_on()
656 struct u3phy_banks *bank = &instance->u3_banks; in pcie_phy_instance_power_off()
658 mtk_phy_set_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLD, in pcie_phy_instance_power_off()
661 mtk_phy_set_bits(bank->chip + U3P_U3_CHIP_GPIO_CTLE, in pcie_phy_instance_power_off()
668 struct u3phy_banks *u3_banks = &instance->u3_banks; in sata_phy_instance_init()
669 void __iomem *phyd = u3_banks->phyd; in sata_phy_instance_init()
707 dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index); in sata_phy_instance_init()
713 struct u2phy_banks *u2_banks = &instance->u2_banks; in phy_v1_banks_init()
714 struct u3phy_banks *u3_banks = &instance->u3_banks; in phy_v1_banks_init()
716 switch (instance->type) { in phy_v1_banks_init()
718 u2_banks->misc = NULL; in phy_v1_banks_init()
719 u2_banks->fmreg = tphy->sif_base + SSUSB_SIFSLV_V1_U2FREQ; in phy_v1_banks_init()
720 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM; in phy_v1_banks_init()
724 u3_banks->spllc = tphy->sif_base + SSUSB_SIFSLV_V1_SPLLC; in phy_v1_banks_init()
725 u3_banks->chip = tphy->sif_base + SSUSB_SIFSLV_V1_CHIP; in phy_v1_banks_init()
726 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; in phy_v1_banks_init()
727 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA; in phy_v1_banks_init()
730 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD; in phy_v1_banks_init()
733 dev_err(tphy->dev, "incompatible PHY type\n"); in phy_v1_banks_init()
741 struct u2phy_banks *u2_banks = &instance->u2_banks; in phy_v2_banks_init()
742 struct u3phy_banks *u3_banks = &instance->u3_banks; in phy_v2_banks_init()
744 switch (instance->type) { in phy_v2_banks_init()
746 u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC; in phy_v2_banks_init()
747 u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ; in phy_v2_banks_init()
748 u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM; in phy_v2_banks_init()
752 u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC; in phy_v2_banks_init()
753 u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP; in phy_v2_banks_init()
754 u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD; in phy_v2_banks_init()
755 u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA; in phy_v2_banks_init()
758 dev_err(tphy->dev, "incompatible PHY type\n"); in phy_v2_banks_init()
766 struct device *dev = &instance->phy->dev; in phy_parse_property()
768 if (instance->type != PHY_TYPE_USB2) in phy_parse_property()
771 instance->bc12_en = device_property_read_bool(dev, "mediatek,bc12"); in phy_parse_property()
772 device_property_read_u32(dev, "mediatek,eye-src", in phy_parse_property()
773 &instance->eye_src); in phy_parse_property()
774 device_property_read_u32(dev, "mediatek,eye-vrt", in phy_parse_property()
775 &instance->eye_vrt); in phy_parse_property()
776 device_property_read_u32(dev, "mediatek,eye-term", in phy_parse_property()
777 &instance->eye_term); in phy_parse_property()
779 &instance->intr); in phy_parse_property()
781 &instance->discth); in phy_parse_property()
782 device_property_read_u32(dev, "mediatek,pre-emphasis", in phy_parse_property()
783 &instance->pre_emphasis); in phy_parse_property()
785 instance->bc12_en, instance->eye_src, in phy_parse_property()
786 instance->eye_vrt, instance->eye_term, in phy_parse_property()
787 instance->intr, instance->discth); in phy_parse_property()
788 dev_dbg(dev, "pre-emp:%d\n", instance->pre_emphasis); in phy_parse_property()
794 struct u2phy_banks *u2_banks = &instance->u2_banks; in u2_phy_props_set()
795 void __iomem *com = u2_banks->com; in u2_phy_props_set()
797 if (instance->bc12_en) /* BC1.2 path Enable */ in u2_phy_props_set()
800 if (tphy->pdata->version < MTK_PHY_V3 && instance->eye_src) in u2_phy_props_set()
802 instance->eye_src); in u2_phy_props_set()
804 if (instance->eye_vrt) in u2_phy_props_set()
806 instance->eye_vrt); in u2_phy_props_set()
808 if (instance->eye_term) in u2_phy_props_set()
810 instance->eye_term); in u2_phy_props_set()
812 if (instance->intr) { in u2_phy_props_set()
813 if (u2_banks->misc) in u2_phy_props_set()
814 mtk_phy_set_bits(u2_banks->misc + U3P_MISC_REG1, in u2_phy_props_set()
818 instance->intr); in u2_phy_props_set()
821 if (instance->discth) in u2_phy_props_set()
823 instance->discth); in u2_phy_props_set()
825 if (instance->pre_emphasis) in u2_phy_props_set()
827 instance->pre_emphasis); in u2_phy_props_set()
838 if (!of_property_read_bool(dn, "mediatek,syscon-type")) in phy_type_syscon_get()
841 ret = of_parse_phandle_with_fixed_args(dn, "mediatek,syscon-type", in phy_type_syscon_get()
846 instance->type_sw_reg = args.args[0]; in phy_type_syscon_get()
847 instance->type_sw_index = args.args[1] & 0x3; /* <=3 */ in phy_type_syscon_get()
848 instance->type_sw = syscon_node_to_regmap(args.np); in phy_type_syscon_get()
850 dev_info(&instance->phy->dev, "type_sw - reg %#x, index %d\n", in phy_type_syscon_get()
851 instance->type_sw_reg, instance->type_sw_index); in phy_type_syscon_get()
853 return PTR_ERR_OR_ZERO(instance->type_sw); in phy_type_syscon_get()
861 if (!instance->type_sw) in phy_type_set()
864 switch (instance->type) { in phy_type_set()
882 offset = instance->type_sw_index * BITS_PER_BYTE; in phy_type_set()
883 regmap_update_bits(instance->type_sw, instance->type_sw_reg, in phy_type_set()
891 struct device *dev = &instance->phy->dev; in phy_efuse_get()
895 if (!tphy->pdata->sw_efuse_supported) { in phy_efuse_get()
896 instance->efuse_sw_en = 0; in phy_efuse_get()
901 instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells"); in phy_efuse_get()
902 if (!instance->efuse_sw_en) in phy_efuse_get()
905 switch (instance->type) { in phy_efuse_get()
907 ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); in phy_efuse_get()
914 if (!instance->efuse_intr) { in phy_efuse_get()
916 instance->efuse_sw_en = 0; in phy_efuse_get()
920 dev_dbg(dev, "u2 efuse - intr %x\n", instance->efuse_intr); in phy_efuse_get()
925 ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); in phy_efuse_get()
931 ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp); in phy_efuse_get()
937 ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp); in phy_efuse_get()
944 if (!instance->efuse_intr && in phy_efuse_get()
945 !instance->efuse_rx_imp && in phy_efuse_get()
946 !instance->efuse_tx_imp) { in phy_efuse_get()
948 instance->efuse_sw_en = 0; in phy_efuse_get()
952 dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n", in phy_efuse_get()
953 instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp); in phy_efuse_get()
956 dev_err(dev, "no sw efuse for type %d\n", instance->type); in phy_efuse_get()
957 ret = -EINVAL; in phy_efuse_get()
965 struct device *dev = &instance->phy->dev; in phy_efuse_set()
966 struct u2phy_banks *u2_banks = &instance->u2_banks; in phy_efuse_set()
967 struct u3phy_banks *u3_banks = &instance->u3_banks; in phy_efuse_set()
969 if (!instance->efuse_sw_en) in phy_efuse_set()
972 switch (instance->type) { in phy_efuse_set()
974 mtk_phy_set_bits(u2_banks->misc + U3P_MISC_REG1, MR1_EFUSE_AUTO_LOAD_DIS); in phy_efuse_set()
976 mtk_phy_update_field(u2_banks->com + U3P_USBPHYACR1, PA1_RG_INTR_CAL, in phy_efuse_set()
977 instance->efuse_intr); in phy_efuse_set()
981 mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_RSV, P3D_RG_EFUSE_AUTO_LOAD_DIS); in phy_efuse_set()
983 mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_TX_IMPEL, in phy_efuse_set()
984 instance->efuse_tx_imp); in phy_efuse_set()
985 mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0, P3D_RG_FORCE_TX_IMPEL); in phy_efuse_set()
987 mtk_phy_update_field(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_RX_IMPEL, in phy_efuse_set()
988 instance->efuse_rx_imp); in phy_efuse_set()
989 mtk_phy_set_bits(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1, P3D_RG_FORCE_RX_IMPEL); in phy_efuse_set()
991 mtk_phy_update_field(u3_banks->phya + U3P_U3_PHYA_REG0, P3A_RG_IEXT_INTR, in phy_efuse_set()
992 instance->efuse_intr); in phy_efuse_set()
995 dev_warn(dev, "no sw efuse for type %d\n", instance->type); in phy_efuse_set()
1003 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); in mtk_phy_init()
1006 ret = clk_bulk_prepare_enable(TPHY_CLKS_CNT, instance->clks); in mtk_phy_init()
1012 switch (instance->type) { in mtk_phy_init()
1030 dev_err(tphy->dev, "incompatible PHY type\n"); in mtk_phy_init()
1031 clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks); in mtk_phy_init()
1032 return -EINVAL; in mtk_phy_init()
1041 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); in mtk_phy_power_on()
1043 if (instance->type == PHY_TYPE_USB2) { in mtk_phy_power_on()
1046 } else if (instance->type == PHY_TYPE_PCIE) { in mtk_phy_power_on()
1056 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); in mtk_phy_power_off()
1058 if (instance->type == PHY_TYPE_USB2) in mtk_phy_power_off()
1060 else if (instance->type == PHY_TYPE_PCIE) in mtk_phy_power_off()
1069 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); in mtk_phy_exit()
1071 if (instance->type == PHY_TYPE_USB2) in mtk_phy_exit()
1074 clk_bulk_disable_unprepare(TPHY_CLKS_CNT, instance->clks); in mtk_phy_exit()
1081 struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); in mtk_phy_set_mode()
1083 if (instance->type == PHY_TYPE_USB2) in mtk_phy_set_mode()
1094 struct device_node *phy_np = args->np; in mtk_phy_xlate()
1098 if (args->args_count != 1) { in mtk_phy_xlate()
1100 return ERR_PTR(-EINVAL); in mtk_phy_xlate()
1103 for (index = 0; index < tphy->nphys; index++) in mtk_phy_xlate()
1104 if (phy_np == tphy->phys[index]->phy->dev.of_node) { in mtk_phy_xlate()
1105 instance = tphy->phys[index]; in mtk_phy_xlate()
1111 return ERR_PTR(-EINVAL); in mtk_phy_xlate()
1114 instance->type = args->args[0]; in mtk_phy_xlate()
1115 if (!(instance->type == PHY_TYPE_USB2 || in mtk_phy_xlate()
1116 instance->type == PHY_TYPE_USB3 || in mtk_phy_xlate()
1117 instance->type == PHY_TYPE_PCIE || in mtk_phy_xlate()
1118 instance->type == PHY_TYPE_SATA || in mtk_phy_xlate()
1119 instance->type == PHY_TYPE_SGMII)) { in mtk_phy_xlate()
1120 dev_err(dev, "unsupported device type: %d\n", instance->type); in mtk_phy_xlate()
1121 return ERR_PTR(-EINVAL); in mtk_phy_xlate()
1124 switch (tphy->pdata->version) { in mtk_phy_xlate()
1134 return ERR_PTR(-EINVAL); in mtk_phy_xlate()
1144 return instance->phy; in mtk_phy_xlate()
1184 { .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
1185 { .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
1186 { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
1187 { .compatible = "mediatek,mt8195-tphy", .data = &mt8195_pdata },
1188 { .compatible = "mediatek,generic-tphy-v1", .data = &tphy_v1_pdata },
1189 { .compatible = "mediatek,generic-tphy-v2", .data = &tphy_v2_pdata },
1190 { .compatible = "mediatek,generic-tphy-v3", .data = &tphy_v3_pdata },
1197 struct device *dev = &pdev->dev; in mtk_tphy_probe()
1198 struct device_node *np = dev->of_node; in mtk_tphy_probe()
1208 return -ENOMEM; in mtk_tphy_probe()
1210 tphy->pdata = of_device_get_match_data(dev); in mtk_tphy_probe()
1211 if (!tphy->pdata) in mtk_tphy_probe()
1212 return -EINVAL; in mtk_tphy_probe()
1214 tphy->nphys = of_get_child_count(np); in mtk_tphy_probe()
1215 tphy->phys = devm_kcalloc(dev, tphy->nphys, in mtk_tphy_probe()
1216 sizeof(*tphy->phys), GFP_KERNEL); in mtk_tphy_probe()
1217 if (!tphy->phys) in mtk_tphy_probe()
1218 return -ENOMEM; in mtk_tphy_probe()
1220 tphy->dev = dev; in mtk_tphy_probe()
1225 if (sif_res && tphy->pdata->version == MTK_PHY_V1) { in mtk_tphy_probe()
1227 tphy->sif_base = devm_ioremap_resource(dev, sif_res); in mtk_tphy_probe()
1228 if (IS_ERR(tphy->sif_base)) { in mtk_tphy_probe()
1230 return PTR_ERR(tphy->sif_base); in mtk_tphy_probe()
1234 if (tphy->pdata->version < MTK_PHY_V3) { in mtk_tphy_probe()
1235 tphy->src_ref_clk = U3P_REF_CLK; in mtk_tphy_probe()
1236 tphy->src_coef = U3P_SLEW_RATE_COEF; in mtk_tphy_probe()
1238 device_property_read_u32(dev, "mediatek,src-ref-clk-mhz", in mtk_tphy_probe()
1239 &tphy->src_ref_clk); in mtk_tphy_probe()
1240 device_property_read_u32(dev, "mediatek,src-coef", in mtk_tphy_probe()
1241 &tphy->src_coef); in mtk_tphy_probe()
1253 retval = -ENOMEM; in mtk_tphy_probe()
1257 tphy->phys[port] = instance; in mtk_tphy_probe()
1266 subdev = &phy->dev; in mtk_tphy_probe()
1269 dev_err(subdev, "failed to get address resource(id-%d)\n", in mtk_tphy_probe()
1274 instance->port_base = devm_ioremap_resource(subdev, &res); in mtk_tphy_probe()
1275 if (IS_ERR(instance->port_base)) { in mtk_tphy_probe()
1276 retval = PTR_ERR(instance->port_base); in mtk_tphy_probe()
1280 instance->phy = phy; in mtk_tphy_probe()
1281 instance->index = port; in mtk_tphy_probe()
1285 clks = instance->clks; in mtk_tphy_probe()
1308 .name = "mtk-tphy",
1316 MODULE_DESCRIPTION("MediaTek T-PHY driver");