| .. | .. |
|---|
| 43 | 43 | #define PA0_RG_USB20_INTR_EN BIT(5) |
|---|
| 44 | 44 | |
|---|
| 45 | 45 | #define U3P_USBPHYACR1 0x004 |
|---|
| 46 | +#define PA1_RG_INTR_CAL GENMASK(23, 19) |
|---|
| 47 | +#define PA1_RG_INTR_CAL_VAL(x) ((0x1f & (x)) << 19) |
|---|
| 46 | 48 | #define PA1_RG_VRT_SEL GENMASK(14, 12) |
|---|
| 47 | 49 | #define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12) |
|---|
| 48 | 50 | #define PA1_RG_TERM_SEL GENMASK(10, 8) |
|---|
| .. | .. |
|---|
| 60 | 62 | #define U3P_USBPHYACR6 0x018 |
|---|
| 61 | 63 | #define PA6_RG_U2_BC11_SW_EN BIT(23) |
|---|
| 62 | 64 | #define PA6_RG_U2_OTG_VBUSCMP_EN BIT(20) |
|---|
| 65 | +#define PA6_RG_U2_DISCTH GENMASK(7, 4) |
|---|
| 66 | +#define PA6_RG_U2_DISCTH_VAL(x) ((0xf & (x)) << 4) |
|---|
| 63 | 67 | #define PA6_RG_U2_SQTH GENMASK(3, 0) |
|---|
| 64 | 68 | #define PA6_RG_U2_SQTH_VAL(x) (0xf & (x)) |
|---|
| 65 | 69 | |
|---|
| .. | .. |
|---|
| 294 | 298 | struct u2phy_banks u2_banks; |
|---|
| 295 | 299 | struct u3phy_banks u3_banks; |
|---|
| 296 | 300 | }; |
|---|
| 297 | | - struct clk *ref_clk; /* reference clock of anolog phy */ |
|---|
| 301 | + struct clk *ref_clk; /* reference clock of (digital) phy */ |
|---|
| 302 | + struct clk *da_ref_clk; /* reference clock of analog phy */ |
|---|
| 298 | 303 | u32 index; |
|---|
| 299 | 304 | u8 type; |
|---|
| 300 | 305 | int eye_src; |
|---|
| 301 | 306 | int eye_vrt; |
|---|
| 302 | 307 | int eye_term; |
|---|
| 308 | + int intr; |
|---|
| 309 | + int discth; |
|---|
| 303 | 310 | bool bc12_en; |
|---|
| 304 | 311 | }; |
|---|
| 305 | 312 | |
|---|
| 306 | 313 | struct mtk_tphy { |
|---|
| 307 | 314 | struct device *dev; |
|---|
| 308 | 315 | void __iomem *sif_base; /* only shared sif */ |
|---|
| 309 | | - /* deprecated, use @ref_clk instead in phy instance */ |
|---|
| 310 | | - struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */ |
|---|
| 311 | 316 | const struct mtk_phy_pdata *pdata; |
|---|
| 312 | 317 | struct mtk_phy_instance **phys; |
|---|
| 313 | 318 | int nphys; |
|---|
| .. | .. |
|---|
| 850 | 855 | &instance->eye_vrt); |
|---|
| 851 | 856 | device_property_read_u32(dev, "mediatek,eye-term", |
|---|
| 852 | 857 | &instance->eye_term); |
|---|
| 853 | | - dev_dbg(dev, "bc12:%d, src:%d, vrt:%d, term:%d\n", |
|---|
| 858 | + device_property_read_u32(dev, "mediatek,intr", |
|---|
| 859 | + &instance->intr); |
|---|
| 860 | + device_property_read_u32(dev, "mediatek,discth", |
|---|
| 861 | + &instance->discth); |
|---|
| 862 | + dev_dbg(dev, "bc12:%d, src:%d, vrt:%d, term:%d, intr:%d, disc:%d\n", |
|---|
| 854 | 863 | instance->bc12_en, instance->eye_src, |
|---|
| 855 | | - instance->eye_vrt, instance->eye_term); |
|---|
| 864 | + instance->eye_vrt, instance->eye_term, |
|---|
| 865 | + instance->intr, instance->discth); |
|---|
| 856 | 866 | } |
|---|
| 857 | 867 | |
|---|
| 858 | 868 | static void u2_phy_props_set(struct mtk_tphy *tphy, |
|---|
| .. | .. |
|---|
| 888 | 898 | tmp |= PA1_RG_TERM_SEL_VAL(instance->eye_term); |
|---|
| 889 | 899 | writel(tmp, com + U3P_USBPHYACR1); |
|---|
| 890 | 900 | } |
|---|
| 901 | + |
|---|
| 902 | + if (instance->intr) { |
|---|
| 903 | + tmp = readl(com + U3P_USBPHYACR1); |
|---|
| 904 | + tmp &= ~PA1_RG_INTR_CAL; |
|---|
| 905 | + tmp |= PA1_RG_INTR_CAL_VAL(instance->intr); |
|---|
| 906 | + writel(tmp, com + U3P_USBPHYACR1); |
|---|
| 907 | + } |
|---|
| 908 | + |
|---|
| 909 | + if (instance->discth) { |
|---|
| 910 | + tmp = readl(com + U3P_USBPHYACR6); |
|---|
| 911 | + tmp &= ~PA6_RG_U2_DISCTH; |
|---|
| 912 | + tmp |= PA6_RG_U2_DISCTH_VAL(instance->discth); |
|---|
| 913 | + writel(tmp, com + U3P_USBPHYACR6); |
|---|
| 914 | + } |
|---|
| 891 | 915 | } |
|---|
| 892 | 916 | |
|---|
| 893 | 917 | static int mtk_phy_init(struct phy *phy) |
|---|
| .. | .. |
|---|
| 896 | 920 | struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); |
|---|
| 897 | 921 | int ret; |
|---|
| 898 | 922 | |
|---|
| 899 | | - ret = clk_prepare_enable(tphy->u3phya_ref); |
|---|
| 900 | | - if (ret) { |
|---|
| 901 | | - dev_err(tphy->dev, "failed to enable u3phya_ref\n"); |
|---|
| 902 | | - return ret; |
|---|
| 903 | | - } |
|---|
| 904 | | - |
|---|
| 905 | 923 | ret = clk_prepare_enable(instance->ref_clk); |
|---|
| 906 | 924 | if (ret) { |
|---|
| 907 | 925 | dev_err(tphy->dev, "failed to enable ref_clk\n"); |
|---|
| 926 | + return ret; |
|---|
| 927 | + } |
|---|
| 928 | + |
|---|
| 929 | + ret = clk_prepare_enable(instance->da_ref_clk); |
|---|
| 930 | + if (ret) { |
|---|
| 931 | + dev_err(tphy->dev, "failed to enable da_ref\n"); |
|---|
| 932 | + clk_disable_unprepare(instance->ref_clk); |
|---|
| 908 | 933 | return ret; |
|---|
| 909 | 934 | } |
|---|
| 910 | 935 | |
|---|
| .. | .. |
|---|
| 924 | 949 | break; |
|---|
| 925 | 950 | default: |
|---|
| 926 | 951 | dev_err(tphy->dev, "incompatible PHY type\n"); |
|---|
| 952 | + clk_disable_unprepare(instance->ref_clk); |
|---|
| 953 | + clk_disable_unprepare(instance->da_ref_clk); |
|---|
| 927 | 954 | return -EINVAL; |
|---|
| 928 | 955 | } |
|---|
| 929 | 956 | |
|---|
| .. | .. |
|---|
| 967 | 994 | u2_phy_instance_exit(tphy, instance); |
|---|
| 968 | 995 | |
|---|
| 969 | 996 | clk_disable_unprepare(instance->ref_clk); |
|---|
| 970 | | - clk_disable_unprepare(tphy->u3phya_ref); |
|---|
| 997 | + clk_disable_unprepare(instance->da_ref_clk); |
|---|
| 971 | 998 | return 0; |
|---|
| 972 | 999 | } |
|---|
| 973 | 1000 | |
|---|
| 974 | | -static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode) |
|---|
| 1001 | +static int mtk_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) |
|---|
| 975 | 1002 | { |
|---|
| 976 | 1003 | struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
|---|
| 977 | 1004 | struct mtk_tphy *tphy = dev_get_drvdata(phy->dev.parent); |
|---|
| .. | .. |
|---|
| 1102 | 1129 | } |
|---|
| 1103 | 1130 | } |
|---|
| 1104 | 1131 | |
|---|
| 1105 | | - /* it's deprecated, make it optional for backward compatibility */ |
|---|
| 1106 | | - tphy->u3phya_ref = devm_clk_get(dev, "u3phya_ref"); |
|---|
| 1107 | | - if (IS_ERR(tphy->u3phya_ref)) { |
|---|
| 1108 | | - if (PTR_ERR(tphy->u3phya_ref) == -EPROBE_DEFER) |
|---|
| 1109 | | - return -EPROBE_DEFER; |
|---|
| 1110 | | - |
|---|
| 1111 | | - tphy->u3phya_ref = NULL; |
|---|
| 1112 | | - } |
|---|
| 1113 | | - |
|---|
| 1114 | 1132 | tphy->src_ref_clk = U3P_REF_CLK; |
|---|
| 1115 | 1133 | tphy->src_coef = U3P_SLEW_RATE_COEF; |
|---|
| 1116 | 1134 | /* update parameters of slew rate calibrate if exist */ |
|---|
| .. | .. |
|---|
| 1157 | 1175 | phy_set_drvdata(phy, instance); |
|---|
| 1158 | 1176 | port++; |
|---|
| 1159 | 1177 | |
|---|
| 1160 | | - /* if deprecated clock is provided, ignore instance's one */ |
|---|
| 1161 | | - if (tphy->u3phya_ref) |
|---|
| 1162 | | - continue; |
|---|
| 1163 | | - |
|---|
| 1164 | | - instance->ref_clk = devm_clk_get(&phy->dev, "ref"); |
|---|
| 1178 | + instance->ref_clk = devm_clk_get_optional(&phy->dev, "ref"); |
|---|
| 1165 | 1179 | if (IS_ERR(instance->ref_clk)) { |
|---|
| 1166 | 1180 | dev_err(dev, "failed to get ref_clk(id-%d)\n", port); |
|---|
| 1167 | 1181 | retval = PTR_ERR(instance->ref_clk); |
|---|
| 1168 | 1182 | goto put_child; |
|---|
| 1169 | 1183 | } |
|---|
| 1184 | + |
|---|
| 1185 | + instance->da_ref_clk = |
|---|
| 1186 | + devm_clk_get_optional(&phy->dev, "da_ref"); |
|---|
| 1187 | + if (IS_ERR(instance->da_ref_clk)) { |
|---|
| 1188 | + dev_err(dev, "failed to get da_ref_clk(id-%d)\n", port); |
|---|
| 1189 | + retval = PTR_ERR(instance->da_ref_clk); |
|---|
| 1190 | + goto put_child; |
|---|
| 1191 | + } |
|---|
| 1170 | 1192 | } |
|---|
| 1171 | 1193 | |
|---|
| 1172 | 1194 | provider = devm_of_phy_provider_register(dev, mtk_phy_xlate); |
|---|