Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: add driver for MediaTek SoC built-in GE PHYs

Some of MediaTek's Filogic SoCs come with built-in gigabit Ethernet
PHYs which require calibration data from the SoC's efuse.
Despite the similar design the driver doesn't share any code with the
existing mediatek-ge.c.
Add support for such PHYs by introducing a new driver with basic
support for MediaTek SoCs MT7981 and MT7988 built-in 1GE PHYs.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniel Golle and committed by
David S. Miller
98c485ea a89dc587

+1140 -1
+9
MAINTAINERS
··· 13151 13151 F: drivers/net/pcs/pcs-mtk-lynxi.c 13152 13152 F: include/linux/pcs/pcs-mtk-lynxi.h 13153 13153 13154 + MEDIATEK ETHERNET PHY DRIVERS 13155 + M: Daniel Golle <daniel@makrotopia.org> 13156 + M: Qingfang Deng <dqfext@gmail.com> 13157 + M: SkyLake Huang <SkyLake.Huang@mediatek.com> 13158 + L: netdev@vger.kernel.org 13159 + S: Maintained 13160 + F: drivers/net/phy/mediatek-ge-soc.c 13161 + F: drivers/net/phy/mediatek-ge.c 13162 + 13154 13163 MEDIATEK I2C CONTROLLER DRIVER 13155 13164 M: Qii Wang <qii.wang@mediatek.com> 13156 13165 L: linux-i2c@vger.kernel.org
+12
drivers/net/phy/Kconfig
··· 236 236 help 237 237 Supports the MediaTek Gigabit Ethernet PHYs. 238 238 239 + config MEDIATEK_GE_SOC_PHY 240 + tristate "MediaTek SoC Ethernet PHYs" 241 + depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST 242 + select NVMEM_MTK_EFUSE 243 + help 244 + Supports MediaTek SoC built-in Gigabit Ethernet PHYs. 245 + 246 + Include support for built-in Ethernet PHYs which are present in 247 + the MT7981 and MT7988 SoCs. These PHYs need calibration data 248 + present in the SoCs efuse and will dynamically calibrate VCM 249 + (common-mode voltage) during startup. 250 + 239 251 config MICREL_PHY 240 252 tristate "Micrel PHYs" 241 253 depends on PTP_1588_CLOCK_OPTIONAL
+1
drivers/net/phy/Makefile
··· 69 69 obj-$(CONFIG_MARVELL_88X2222_PHY) += marvell-88x2222.o 70 70 obj-$(CONFIG_MAXLINEAR_GPHY) += mxl-gpy.o 71 71 obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o 72 + obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o 72 73 obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o 73 74 obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o 74 75 obj-$(CONFIG_MICREL_PHY) += micrel.o
+1116
drivers/net/phy/mediatek-ge-soc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + #include <linux/bitfield.h> 3 + #include <linux/module.h> 4 + #include <linux/nvmem-consumer.h> 5 + #include <linux/of_address.h> 6 + #include <linux/of_platform.h> 7 + #include <linux/pinctrl/consumer.h> 8 + #include <linux/phy.h> 9 + 10 + #define MTK_GPHY_ID_MT7981 0x03a29461 11 + #define MTK_GPHY_ID_MT7988 0x03a29481 12 + 13 + #define MTK_EXT_PAGE_ACCESS 0x1f 14 + #define MTK_PHY_PAGE_STANDARD 0x0000 15 + #define MTK_PHY_PAGE_EXTENDED_3 0x0003 16 + 17 + #define MTK_PHY_LPI_REG_14 0x14 18 + #define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0) 19 + 20 + #define MTK_PHY_LPI_REG_1c 0x1c 21 + #define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8) 22 + 23 + #define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30 24 + #define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5 25 + 26 + #define ANALOG_INTERNAL_OPERATION_MAX_US 20 27 + #define TXRESERVE_MIN 0 28 + #define TXRESERVE_MAX 7 29 + 30 + #define MTK_PHY_ANARG_RG 0x10 31 + #define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8) 32 + 33 + /* Registers on MDIO_MMD_VEND1 */ 34 + #define MTK_PHY_TXVLD_DA_RG 0x12 35 + #define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10) 36 + #define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0) 37 + 38 + #define MTK_PHY_TX_I2MPB_TEST_MODE_A2 0x16 39 + #define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10) 40 + #define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0) 41 + 42 + #define MTK_PHY_TX_I2MPB_TEST_MODE_B1 0x17 43 + #define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8) 44 + #define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0) 45 + 46 + #define MTK_PHY_TX_I2MPB_TEST_MODE_B2 0x18 47 + #define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8) 48 + #define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0) 49 + 50 + #define MTK_PHY_TX_I2MPB_TEST_MODE_C1 0x19 51 + #define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8) 52 + #define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0) 53 + 54 + #define MTK_PHY_TX_I2MPB_TEST_MODE_C2 0x20 55 + #define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8) 56 + #define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0) 57 + 58 + #define MTK_PHY_TX_I2MPB_TEST_MODE_D1 0x21 59 + #define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8) 60 + #define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0) 61 + 62 + #define MTK_PHY_TX_I2MPB_TEST_MODE_D2 0x22 63 + #define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8) 64 + #define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0) 65 + 66 + #define MTK_PHY_RXADC_CTRL_RG7 0xc6 67 + #define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8) 68 + 69 + #define MTK_PHY_RXADC_CTRL_RG9 0xc8 70 + #define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12) 71 + #define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8) 72 + #define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4) 73 + #define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0) 74 + 75 + #define MTK_PHY_LDO_OUTPUT_V 0xd7 76 + 77 + #define MTK_PHY_RG_ANA_CAL_RG0 0xdb 78 + #define MTK_PHY_RG_CAL_CKINV BIT(12) 79 + #define MTK_PHY_RG_ANA_CALEN BIT(8) 80 + #define MTK_PHY_RG_ZCALEN_A BIT(0) 81 + 82 + #define MTK_PHY_RG_ANA_CAL_RG1 0xdc 83 + #define MTK_PHY_RG_ZCALEN_B BIT(12) 84 + #define MTK_PHY_RG_ZCALEN_C BIT(8) 85 + #define MTK_PHY_RG_ZCALEN_D BIT(4) 86 + #define MTK_PHY_RG_TXVOS_CALEN BIT(0) 87 + 88 + #define MTK_PHY_RG_ANA_CAL_RG5 0xe0 89 + #define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8) 90 + 91 + #define MTK_PHY_RG_TX_FILTER 0xfe 92 + 93 + #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 0x120 94 + #define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8) 95 + #define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0) 96 + 97 + #define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 0x122 98 + #define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0) 99 + 100 + #define MTK_PHY_RG_TESTMUX_ADC_CTRL 0x144 101 + #define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5) 102 + 103 + #define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B 0x172 104 + #define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8) 105 + #define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0) 106 + 107 + #define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D 0x173 108 + #define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8) 109 + #define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0) 110 + 111 + #define MTK_PHY_RG_AD_CAL_COMP 0x17a 112 + #define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8) 113 + 114 + #define MTK_PHY_RG_AD_CAL_CLK 0x17b 115 + #define MTK_PHY_DA_CAL_CLK BIT(0) 116 + 117 + #define MTK_PHY_RG_AD_CALIN 0x17c 118 + #define MTK_PHY_DA_CALIN_FLAG BIT(0) 119 + 120 + #define MTK_PHY_RG_DASN_DAC_IN0_A 0x17d 121 + #define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0) 122 + 123 + #define MTK_PHY_RG_DASN_DAC_IN0_B 0x17e 124 + #define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0) 125 + 126 + #define MTK_PHY_RG_DASN_DAC_IN0_C 0x17f 127 + #define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0) 128 + 129 + #define MTK_PHY_RG_DASN_DAC_IN0_D 0x180 130 + #define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0) 131 + 132 + #define MTK_PHY_RG_DASN_DAC_IN1_A 0x181 133 + #define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0) 134 + 135 + #define MTK_PHY_RG_DASN_DAC_IN1_B 0x182 136 + #define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0) 137 + 138 + #define MTK_PHY_RG_DASN_DAC_IN1_C 0x183 139 + #define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0) 140 + 141 + #define MTK_PHY_RG_DASN_DAC_IN1_D 0x184 142 + #define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0) 143 + 144 + #define MTK_PHY_RG_DEV1E_REG19b 0x19b 145 + #define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8) 146 + 147 + #define MTK_PHY_RG_LP_IIR2_K1_L 0x22a 148 + #define MTK_PHY_RG_LP_IIR2_K1_U 0x22b 149 + #define MTK_PHY_RG_LP_IIR2_K2_L 0x22c 150 + #define MTK_PHY_RG_LP_IIR2_K2_U 0x22d 151 + #define MTK_PHY_RG_LP_IIR2_K3_L 0x22e 152 + #define MTK_PHY_RG_LP_IIR2_K3_U 0x22f 153 + #define MTK_PHY_RG_LP_IIR2_K4_L 0x230 154 + #define MTK_PHY_RG_LP_IIR2_K4_U 0x231 155 + #define MTK_PHY_RG_LP_IIR2_K5_L 0x232 156 + #define MTK_PHY_RG_LP_IIR2_K5_U 0x233 157 + 158 + #define MTK_PHY_RG_DEV1E_REG234 0x234 159 + #define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0) 160 + #define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4) 161 + #define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12) 162 + 163 + #define MTK_PHY_RG_LPF_CNT_VAL 0x235 164 + 165 + #define MTK_PHY_RG_DEV1E_REG238 0x238 166 + #define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0) 167 + #define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12) 168 + 169 + #define MTK_PHY_RG_DEV1E_REG239 0x239 170 + #define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0) 171 + #define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12) 172 + 173 + #define MTK_PHY_RG_DEV1E_REG27C 0x27c 174 + #define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8) 175 + #define MTK_PHY_RG_DEV1E_REG27D 0x27d 176 + #define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0) 177 + 178 + #define MTK_PHY_RG_DEV1E_REG2C7 0x2c7 179 + #define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0) 180 + #define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8) 181 + 182 + #define MTK_PHY_RG_DEV1E_REG2D1 0x2d1 183 + #define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0) 184 + #define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8) 185 + #define MTK_PHY_LPI_TR_READY BIT(9) 186 + #define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10) 187 + 188 + #define MTK_PHY_RG_DEV1E_REG323 0x323 189 + #define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0) 190 + #define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4) 191 + 192 + #define MTK_PHY_RG_DEV1E_REG324 0x324 193 + #define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0) 194 + #define MTK_PHY_SMI_DET_MAX_EN BIT(8) 195 + 196 + #define MTK_PHY_RG_DEV1E_REG326 0x326 197 + #define MTK_PHY_LPI_MODE_SD_ON BIT(0) 198 + #define MTK_PHY_RESET_RANDUPD_CNT BIT(1) 199 + #define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2) 200 + #define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4) 201 + #define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5) 202 + 203 + #define MTK_PHY_LDO_PUMP_EN_PAIRAB 0x502 204 + #define MTK_PHY_LDO_PUMP_EN_PAIRCD 0x503 205 + 206 + #define MTK_PHY_DA_TX_R50_PAIR_A 0x53d 207 + #define MTK_PHY_DA_TX_R50_PAIR_B 0x53e 208 + #define MTK_PHY_DA_TX_R50_PAIR_C 0x53f 209 + #define MTK_PHY_DA_TX_R50_PAIR_D 0x540 210 + 211 + #define MTK_PHY_RG_BG_RASEL 0x115 212 + #define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0) 213 + 214 + /* These macro privides efuse parsing for internal phy. */ 215 + #define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0)) 216 + #define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0)) 217 + #define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0)) 218 + #define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0)) 219 + #define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0)) 220 + 221 + #define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0)) 222 + #define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0)) 223 + #define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0)) 224 + #define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0)) 225 + #define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0)) 226 + 227 + #define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0)) 228 + #define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0)) 229 + 230 + #define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0)) 231 + #define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0)) 232 + 233 + enum { 234 + NO_PAIR, 235 + PAIR_A, 236 + PAIR_B, 237 + PAIR_C, 238 + PAIR_D, 239 + }; 240 + 241 + enum { 242 + GPHY_PORT0, 243 + GPHY_PORT1, 244 + GPHY_PORT2, 245 + GPHY_PORT3, 246 + }; 247 + 248 + enum calibration_mode { 249 + EFUSE_K, 250 + SW_K 251 + }; 252 + 253 + enum CAL_ITEM { 254 + REXT, 255 + TX_OFFSET, 256 + TX_AMP, 257 + TX_R50, 258 + TX_VCM 259 + }; 260 + 261 + enum CAL_MODE { 262 + EFUSE_M, 263 + SW_M 264 + }; 265 + 266 + static int mtk_socphy_read_page(struct phy_device *phydev) 267 + { 268 + return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); 269 + } 270 + 271 + static int mtk_socphy_write_page(struct phy_device *phydev, int page) 272 + { 273 + return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page); 274 + } 275 + 276 + /* One calibration cycle consists of: 277 + * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high 278 + * until AD_CAL_COMP is ready to output calibration result. 279 + * 2.Wait until DA_CAL_CLK is available. 280 + * 3.Fetch AD_CAL_COMP_OUT. 281 + */ 282 + static int cal_cycle(struct phy_device *phydev, int devad, 283 + u32 regnum, u16 mask, u16 cal_val) 284 + { 285 + int reg_val; 286 + int ret; 287 + 288 + phy_modify_mmd(phydev, devad, regnum, 289 + mask, cal_val); 290 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN, 291 + MTK_PHY_DA_CALIN_FLAG); 292 + 293 + ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, 294 + MTK_PHY_RG_AD_CAL_CLK, reg_val, 295 + reg_val & MTK_PHY_DA_CAL_CLK, 500, 296 + ANALOG_INTERNAL_OPERATION_MAX_US, false); 297 + if (ret) { 298 + phydev_err(phydev, "Calibration cycle timeout\n"); 299 + return ret; 300 + } 301 + 302 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN, 303 + MTK_PHY_DA_CALIN_FLAG); 304 + ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >> 305 + MTK_PHY_AD_CAL_COMP_OUT_SHIFT; 306 + phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret); 307 + 308 + return ret; 309 + } 310 + 311 + static int rext_fill_result(struct phy_device *phydev, u16 *buf) 312 + { 313 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5, 314 + MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8); 315 + phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL, 316 + MTK_PHY_RG_BG_RASEL_MASK, buf[1]); 317 + 318 + return 0; 319 + } 320 + 321 + static int rext_cal_efuse(struct phy_device *phydev, u32 *buf) 322 + { 323 + u16 rext_cal_val[2]; 324 + 325 + rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]); 326 + rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]); 327 + rext_fill_result(phydev, rext_cal_val); 328 + 329 + return 0; 330 + } 331 + 332 + static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf) 333 + { 334 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B, 335 + MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8); 336 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B, 337 + MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]); 338 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D, 339 + MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8); 340 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D, 341 + MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]); 342 + 343 + return 0; 344 + } 345 + 346 + static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf) 347 + { 348 + u16 tx_offset_cal_val[4]; 349 + 350 + tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]); 351 + tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]); 352 + tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]); 353 + tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]); 354 + 355 + tx_offset_fill_result(phydev, tx_offset_cal_val); 356 + 357 + return 0; 358 + } 359 + 360 + static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf) 361 + { 362 + int i; 363 + int bias[16] = {}; 364 + const int vals_9461[16] = { 7, 1, 4, 7, 365 + 7, 1, 4, 7, 366 + 7, 1, 4, 7, 367 + 7, 1, 4, 7 }; 368 + const int vals_9481[16] = { 10, 6, 6, 10, 369 + 10, 6, 6, 10, 370 + 10, 6, 6, 10, 371 + 10, 6, 6, 10 }; 372 + switch (phydev->drv->phy_id) { 373 + case MTK_GPHY_ID_MT7981: 374 + /* We add some calibration to efuse values 375 + * due to board level influence. 376 + * GBE: +7, TBT: +1, HBT: +4, TST: +7 377 + */ 378 + memcpy(bias, (const void *)vals_9461, sizeof(bias)); 379 + break; 380 + case MTK_GPHY_ID_MT7988: 381 + memcpy(bias, (const void *)vals_9481, sizeof(bias)); 382 + break; 383 + } 384 + 385 + /* Prevent overflow */ 386 + for (i = 0; i < 12; i++) { 387 + if (buf[i >> 2] + bias[i] > 63) { 388 + buf[i >> 2] = 63; 389 + bias[i] = 0; 390 + } 391 + } 392 + 393 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 394 + MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10); 395 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 396 + MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]); 397 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 398 + MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10); 399 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 400 + MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]); 401 + 402 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 403 + MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8); 404 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 405 + MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]); 406 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 407 + MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8); 408 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 409 + MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]); 410 + 411 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 412 + MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8); 413 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 414 + MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]); 415 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 416 + MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8); 417 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 418 + MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]); 419 + 420 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 421 + MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8); 422 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 423 + MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]); 424 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 425 + MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8); 426 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 427 + MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]); 428 + 429 + return 0; 430 + } 431 + 432 + static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf) 433 + { 434 + u16 tx_amp_cal_val[4]; 435 + 436 + tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]); 437 + tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]); 438 + tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]); 439 + tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]); 440 + tx_amp_fill_result(phydev, tx_amp_cal_val); 441 + 442 + return 0; 443 + } 444 + 445 + static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val, 446 + u8 txg_calen_x) 447 + { 448 + int bias = 0; 449 + u16 reg, val; 450 + 451 + if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) 452 + bias = -2; 453 + 454 + val = clamp_val(bias + tx_r50_cal_val, 0, 63); 455 + 456 + switch (txg_calen_x) { 457 + case PAIR_A: 458 + reg = MTK_PHY_DA_TX_R50_PAIR_A; 459 + break; 460 + case PAIR_B: 461 + reg = MTK_PHY_DA_TX_R50_PAIR_B; 462 + break; 463 + case PAIR_C: 464 + reg = MTK_PHY_DA_TX_R50_PAIR_C; 465 + break; 466 + case PAIR_D: 467 + reg = MTK_PHY_DA_TX_R50_PAIR_D; 468 + break; 469 + default: 470 + return -EINVAL; 471 + } 472 + 473 + phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8); 474 + 475 + return 0; 476 + } 477 + 478 + static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf, 479 + u8 txg_calen_x) 480 + { 481 + u16 tx_r50_cal_val; 482 + 483 + switch (txg_calen_x) { 484 + case PAIR_A: 485 + tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]); 486 + break; 487 + case PAIR_B: 488 + tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]); 489 + break; 490 + case PAIR_C: 491 + tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]); 492 + break; 493 + case PAIR_D: 494 + tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]); 495 + break; 496 + default: 497 + return -EINVAL; 498 + } 499 + tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x); 500 + 501 + return 0; 502 + } 503 + 504 + static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x) 505 + { 506 + u8 lower_idx, upper_idx, txreserve_val; 507 + u8 lower_ret, upper_ret; 508 + int ret; 509 + 510 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0, 511 + MTK_PHY_RG_ANA_CALEN); 512 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0, 513 + MTK_PHY_RG_CAL_CKINV); 514 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1, 515 + MTK_PHY_RG_TXVOS_CALEN); 516 + 517 + switch (rg_txreserve_x) { 518 + case PAIR_A: 519 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 520 + MTK_PHY_RG_DASN_DAC_IN0_A, 521 + MTK_PHY_DASN_DAC_IN0_A_MASK); 522 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 523 + MTK_PHY_RG_DASN_DAC_IN1_A, 524 + MTK_PHY_DASN_DAC_IN1_A_MASK); 525 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, 526 + MTK_PHY_RG_ANA_CAL_RG0, 527 + MTK_PHY_RG_ZCALEN_A); 528 + break; 529 + case PAIR_B: 530 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 531 + MTK_PHY_RG_DASN_DAC_IN0_B, 532 + MTK_PHY_DASN_DAC_IN0_B_MASK); 533 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 534 + MTK_PHY_RG_DASN_DAC_IN1_B, 535 + MTK_PHY_DASN_DAC_IN1_B_MASK); 536 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, 537 + MTK_PHY_RG_ANA_CAL_RG1, 538 + MTK_PHY_RG_ZCALEN_B); 539 + break; 540 + case PAIR_C: 541 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 542 + MTK_PHY_RG_DASN_DAC_IN0_C, 543 + MTK_PHY_DASN_DAC_IN0_C_MASK); 544 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 545 + MTK_PHY_RG_DASN_DAC_IN1_C, 546 + MTK_PHY_DASN_DAC_IN1_C_MASK); 547 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, 548 + MTK_PHY_RG_ANA_CAL_RG1, 549 + MTK_PHY_RG_ZCALEN_C); 550 + break; 551 + case PAIR_D: 552 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 553 + MTK_PHY_RG_DASN_DAC_IN0_D, 554 + MTK_PHY_DASN_DAC_IN0_D_MASK); 555 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 556 + MTK_PHY_RG_DASN_DAC_IN1_D, 557 + MTK_PHY_DASN_DAC_IN1_D_MASK); 558 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, 559 + MTK_PHY_RG_ANA_CAL_RG1, 560 + MTK_PHY_RG_ZCALEN_D); 561 + break; 562 + default: 563 + ret = -EINVAL; 564 + goto restore; 565 + } 566 + 567 + lower_idx = TXRESERVE_MIN; 568 + upper_idx = TXRESERVE_MAX; 569 + 570 + phydev_dbg(phydev, "Start TX-VCM SW cal.\n"); 571 + while ((upper_idx - lower_idx) > 1) { 572 + txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2); 573 + ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9, 574 + MTK_PHY_DA_RX_PSBN_TBT_MASK | 575 + MTK_PHY_DA_RX_PSBN_HBT_MASK | 576 + MTK_PHY_DA_RX_PSBN_GBE_MASK | 577 + MTK_PHY_DA_RX_PSBN_LP_MASK, 578 + txreserve_val << 12 | txreserve_val << 8 | 579 + txreserve_val << 4 | txreserve_val); 580 + if (ret == 1) { 581 + upper_idx = txreserve_val; 582 + upper_ret = ret; 583 + } else if (ret == 0) { 584 + lower_idx = txreserve_val; 585 + lower_ret = ret; 586 + } else { 587 + goto restore; 588 + } 589 + } 590 + 591 + if (lower_idx == TXRESERVE_MIN) { 592 + lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, 593 + MTK_PHY_RXADC_CTRL_RG9, 594 + MTK_PHY_DA_RX_PSBN_TBT_MASK | 595 + MTK_PHY_DA_RX_PSBN_HBT_MASK | 596 + MTK_PHY_DA_RX_PSBN_GBE_MASK | 597 + MTK_PHY_DA_RX_PSBN_LP_MASK, 598 + lower_idx << 12 | lower_idx << 8 | 599 + lower_idx << 4 | lower_idx); 600 + ret = lower_ret; 601 + } else if (upper_idx == TXRESERVE_MAX) { 602 + upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, 603 + MTK_PHY_RXADC_CTRL_RG9, 604 + MTK_PHY_DA_RX_PSBN_TBT_MASK | 605 + MTK_PHY_DA_RX_PSBN_HBT_MASK | 606 + MTK_PHY_DA_RX_PSBN_GBE_MASK | 607 + MTK_PHY_DA_RX_PSBN_LP_MASK, 608 + upper_idx << 12 | upper_idx << 8 | 609 + upper_idx << 4 | upper_idx); 610 + ret = upper_ret; 611 + } 612 + if (ret < 0) 613 + goto restore; 614 + 615 + /* We calibrate TX-VCM in different logic. Check upper index and then 616 + * lower index. If this calibration is valid, apply lower index's result. 617 + */ 618 + ret = upper_ret - lower_ret; 619 + if (ret == 1) { 620 + ret = 0; 621 + /* Make sure we use upper_idx in our calibration system */ 622 + cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9, 623 + MTK_PHY_DA_RX_PSBN_TBT_MASK | 624 + MTK_PHY_DA_RX_PSBN_HBT_MASK | 625 + MTK_PHY_DA_RX_PSBN_GBE_MASK | 626 + MTK_PHY_DA_RX_PSBN_LP_MASK, 627 + upper_idx << 12 | upper_idx << 8 | 628 + upper_idx << 4 | upper_idx); 629 + phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx); 630 + } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && 631 + lower_ret == 1) { 632 + ret = 0; 633 + cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9, 634 + MTK_PHY_DA_RX_PSBN_TBT_MASK | 635 + MTK_PHY_DA_RX_PSBN_HBT_MASK | 636 + MTK_PHY_DA_RX_PSBN_GBE_MASK | 637 + MTK_PHY_DA_RX_PSBN_LP_MASK, 638 + lower_idx << 12 | lower_idx << 8 | 639 + lower_idx << 4 | lower_idx); 640 + phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n", 641 + lower_idx); 642 + } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && 643 + lower_ret == 0) { 644 + ret = 0; 645 + phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n", 646 + upper_idx); 647 + } else { 648 + ret = -EINVAL; 649 + } 650 + 651 + restore: 652 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0, 653 + MTK_PHY_RG_ANA_CALEN); 654 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1, 655 + MTK_PHY_RG_TXVOS_CALEN); 656 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0, 657 + MTK_PHY_RG_ZCALEN_A); 658 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1, 659 + MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | 660 + MTK_PHY_RG_ZCALEN_D); 661 + 662 + return ret; 663 + } 664 + 665 + static void mt798x_phy_common_finetune(struct phy_device *phydev) 666 + { 667 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 668 + /* EnabRandUpdTrig = 1 */ 669 + __phy_write(phydev, 0x11, 0x2f00); 670 + __phy_write(phydev, 0x12, 0xe); 671 + __phy_write(phydev, 0x10, 0x8fb0); 672 + 673 + /* NormMseLoThresh = 85 */ 674 + __phy_write(phydev, 0x11, 0x55a0); 675 + __phy_write(phydev, 0x12, 0x0); 676 + __phy_write(phydev, 0x10, 0x83aa); 677 + 678 + /* TrFreeze = 0 */ 679 + __phy_write(phydev, 0x11, 0x0); 680 + __phy_write(phydev, 0x12, 0x0); 681 + __phy_write(phydev, 0x10, 0x9686); 682 + 683 + /* SSTrKp1000Slv = 5 */ 684 + __phy_write(phydev, 0x11, 0xbaef); 685 + __phy_write(phydev, 0x12, 0x2e); 686 + __phy_write(phydev, 0x10, 0x968c); 687 + 688 + /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, 689 + * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 690 + */ 691 + __phy_write(phydev, 0x11, 0xd10a); 692 + __phy_write(phydev, 0x12, 0x34); 693 + __phy_write(phydev, 0x10, 0x8f82); 694 + 695 + /* VcoSlicerThreshBitsHigh */ 696 + __phy_write(phydev, 0x11, 0x5555); 697 + __phy_write(phydev, 0x12, 0x55); 698 + __phy_write(phydev, 0x10, 0x8ec0); 699 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 700 + 701 + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ 702 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, 703 + MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, 704 + BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); 705 + 706 + /* rg_tr_lpf_cnt_val = 512 */ 707 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200); 708 + 709 + /* IIR2 related */ 710 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82); 711 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0); 712 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103); 713 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0); 714 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82); 715 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0); 716 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177); 717 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3); 718 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82); 719 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe); 720 + 721 + /* FFE peaking */ 722 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C, 723 + MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8); 724 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D, 725 + MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e); 726 + 727 + /* Disable LDO pump */ 728 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0); 729 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0); 730 + /* Adjust LDO output voltage */ 731 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); 732 + } 733 + 734 + static void mt7981_phy_finetune(struct phy_device *phydev) 735 + { 736 + u16 val[8] = { 0x01ce, 0x01c1, 737 + 0x020f, 0x0202, 738 + 0x03d0, 0x03c0, 739 + 0x0013, 0x0005 }; 740 + int i, k; 741 + 742 + /* 100M eye finetune: 743 + * Keep middle level of TX MLT3 shapper as default. 744 + * Only change TX MLT3 overshoot level here. 745 + */ 746 + for (k = 0, i = 1; i < 12; i++) { 747 + if (i % 3 == 0) 748 + continue; 749 + phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); 750 + } 751 + 752 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 753 + /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ 754 + __phy_write(phydev, 0x11, 0xc71); 755 + __phy_write(phydev, 0x12, 0xc); 756 + __phy_write(phydev, 0x10, 0x8fae); 757 + 758 + /* ResetSyncOffset = 6 */ 759 + __phy_write(phydev, 0x11, 0x600); 760 + __phy_write(phydev, 0x12, 0x0); 761 + __phy_write(phydev, 0x10, 0x8fc0); 762 + 763 + /* VgaDecRate = 1 */ 764 + __phy_write(phydev, 0x11, 0x4c2a); 765 + __phy_write(phydev, 0x12, 0x3e); 766 + __phy_write(phydev, 0x10, 0x8fa4); 767 + 768 + /* FfeUpdGainForce = 4 */ 769 + __phy_write(phydev, 0x11, 0x240); 770 + __phy_write(phydev, 0x12, 0x0); 771 + __phy_write(phydev, 0x10, 0x9680); 772 + 773 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 774 + } 775 + 776 + static void mt7988_phy_finetune(struct phy_device *phydev) 777 + { 778 + u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, 779 + 0x020d, 0x0206, 0x0384, 0x03d0, 780 + 0x03c6, 0x030a, 0x0011, 0x0005 }; 781 + int i; 782 + 783 + /* Set default MLT3 shaper first */ 784 + for (i = 0; i < 12; i++) 785 + phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]); 786 + 787 + /* TCT finetune */ 788 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); 789 + 790 + /* Disable TX power saving */ 791 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, 792 + MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); 793 + 794 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 795 + 796 + /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ 797 + __phy_write(phydev, 0x11, 0x671); 798 + __phy_write(phydev, 0x12, 0xc); 799 + __phy_write(phydev, 0x10, 0x8fae); 800 + 801 + /* ResetSyncOffset = 5 */ 802 + __phy_write(phydev, 0x11, 0x500); 803 + __phy_write(phydev, 0x12, 0x0); 804 + __phy_write(phydev, 0x10, 0x8fc0); 805 + 806 + /* VgaDecRate is 1 at default on mt7988 */ 807 + 808 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 809 + 810 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); 811 + /* TxClkOffset = 2 */ 812 + __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, 813 + FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); 814 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 815 + } 816 + 817 + static void mt798x_phy_eee(struct phy_device *phydev) 818 + { 819 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, 820 + MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120, 821 + MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK | 822 + MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 823 + FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) | 824 + FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14)); 825 + 826 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, 827 + MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122, 828 + MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 829 + FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 830 + 0xff)); 831 + 832 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 833 + MTK_PHY_RG_TESTMUX_ADC_CTRL, 834 + MTK_PHY_RG_TXEN_DIG_MASK); 835 + 836 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, 837 + MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY); 838 + 839 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 840 + MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN); 841 + 842 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238, 843 + MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK | 844 + MTK_PHY_LPI_SLV_SEND_TX_EN, 845 + FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); 846 + 847 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, 848 + MTK_PHY_LPI_SEND_LOC_TIMER_MASK | 849 + MTK_PHY_LPI_TXPCS_LOC_RCV, 850 + FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); 851 + 852 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, 853 + MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, 854 + FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | 855 + FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13)); 856 + 857 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1, 858 + MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK, 859 + FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK, 860 + 0x33) | 861 + MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY | 862 + MTK_PHY_LPI_VCO_EEE_STG0_EN); 863 + 864 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323, 865 + MTK_PHY_EEE_WAKE_MAS_INT_DC | 866 + MTK_PHY_EEE_WAKE_SLV_INT_DC); 867 + 868 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324, 869 + MTK_PHY_SMI_DETCNT_MAX_MASK, 870 + FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) | 871 + MTK_PHY_SMI_DET_MAX_EN); 872 + 873 + phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326, 874 + MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT | 875 + MTK_PHY_TREC_UPDATE_ENAB_CLR | 876 + MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF | 877 + MTK_PHY_TR_READY_SKIP_AFE_WAKEUP); 878 + 879 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); 880 + /* Regsigdet_sel_1000 = 0 */ 881 + __phy_write(phydev, 0x11, 0xb); 882 + __phy_write(phydev, 0x12, 0x0); 883 + __phy_write(phydev, 0x10, 0x9690); 884 + 885 + /* REG_EEE_st2TrKf1000 = 3 */ 886 + __phy_write(phydev, 0x11, 0x114f); 887 + __phy_write(phydev, 0x12, 0x2); 888 + __phy_write(phydev, 0x10, 0x969a); 889 + 890 + /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */ 891 + __phy_write(phydev, 0x11, 0x3028); 892 + __phy_write(phydev, 0x12, 0x0); 893 + __phy_write(phydev, 0x10, 0x969e); 894 + 895 + /* RegEEE_slv_wake_int_timer_tar = 8 */ 896 + __phy_write(phydev, 0x11, 0x5010); 897 + __phy_write(phydev, 0x12, 0x0); 898 + __phy_write(phydev, 0x10, 0x96a0); 899 + 900 + /* RegEEE_trfreeze_timer2 = 586 */ 901 + __phy_write(phydev, 0x11, 0x24a); 902 + __phy_write(phydev, 0x12, 0x0); 903 + __phy_write(phydev, 0x10, 0x96a8); 904 + 905 + /* RegEEE100Stg1_tar = 16 */ 906 + __phy_write(phydev, 0x11, 0x3210); 907 + __phy_write(phydev, 0x12, 0x0); 908 + __phy_write(phydev, 0x10, 0x96b8); 909 + 910 + /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ 911 + __phy_write(phydev, 0x11, 0x1463); 912 + __phy_write(phydev, 0x12, 0x0); 913 + __phy_write(phydev, 0x10, 0x96ca); 914 + 915 + /* DfeTailEnableVgaThresh1000 = 27 */ 916 + __phy_write(phydev, 0x11, 0x36); 917 + __phy_write(phydev, 0x12, 0x0); 918 + __phy_write(phydev, 0x10, 0x8f80); 919 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 920 + 921 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3); 922 + __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 923 + FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c)); 924 + 925 + __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK, 926 + FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc)); 927 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); 928 + 929 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, 930 + MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122, 931 + MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 932 + FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff)); 933 + } 934 + 935 + static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item, 936 + u8 start_pair, u8 end_pair) 937 + { 938 + u8 pair_n; 939 + int ret; 940 + 941 + for (pair_n = start_pair; pair_n <= end_pair; pair_n++) { 942 + /* TX_OFFSET & TX_AMP have no SW calibration. */ 943 + switch (cal_item) { 944 + case TX_VCM: 945 + ret = tx_vcm_cal_sw(phydev, pair_n); 946 + break; 947 + default: 948 + return -EINVAL; 949 + } 950 + if (ret) 951 + return ret; 952 + } 953 + return 0; 954 + } 955 + 956 + static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item, 957 + u8 start_pair, u8 end_pair, u32 *buf) 958 + { 959 + u8 pair_n; 960 + int ret; 961 + 962 + for (pair_n = start_pair; pair_n <= end_pair; pair_n++) { 963 + /* TX_VCM has no efuse calibration. */ 964 + switch (cal_item) { 965 + case REXT: 966 + ret = rext_cal_efuse(phydev, buf); 967 + break; 968 + case TX_OFFSET: 969 + ret = tx_offset_cal_efuse(phydev, buf); 970 + break; 971 + case TX_AMP: 972 + ret = tx_amp_cal_efuse(phydev, buf); 973 + break; 974 + case TX_R50: 975 + ret = tx_r50_cal_efuse(phydev, buf, pair_n); 976 + break; 977 + default: 978 + return -EINVAL; 979 + } 980 + if (ret) 981 + return ret; 982 + } 983 + 984 + return 0; 985 + } 986 + 987 + static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item, 988 + enum CAL_MODE cal_mode, u8 start_pair, 989 + u8 end_pair, u32 *buf) 990 + { 991 + int ret; 992 + 993 + switch (cal_mode) { 994 + case EFUSE_M: 995 + ret = cal_efuse(phydev, cal_item, start_pair, 996 + end_pair, buf); 997 + break; 998 + case SW_M: 999 + ret = cal_sw(phydev, cal_item, start_pair, end_pair); 1000 + break; 1001 + default: 1002 + return -EINVAL; 1003 + } 1004 + 1005 + if (ret) { 1006 + phydev_err(phydev, "cal %d failed\n", cal_item); 1007 + return -EIO; 1008 + } 1009 + 1010 + return 0; 1011 + } 1012 + 1013 + static int mt798x_phy_calibration(struct phy_device *phydev) 1014 + { 1015 + int ret = 0; 1016 + u32 *buf; 1017 + size_t len; 1018 + struct nvmem_cell *cell; 1019 + 1020 + cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data"); 1021 + if (IS_ERR(cell)) { 1022 + if (PTR_ERR(cell) == -EPROBE_DEFER) 1023 + return PTR_ERR(cell); 1024 + return 0; 1025 + } 1026 + 1027 + buf = (u32 *)nvmem_cell_read(cell, &len); 1028 + if (IS_ERR(buf)) 1029 + return PTR_ERR(buf); 1030 + nvmem_cell_put(cell); 1031 + 1032 + if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) { 1033 + phydev_err(phydev, "invalid efuse data\n"); 1034 + ret = -EINVAL; 1035 + goto out; 1036 + } 1037 + 1038 + ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf); 1039 + if (ret) 1040 + goto out; 1041 + ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf); 1042 + if (ret) 1043 + goto out; 1044 + ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf); 1045 + if (ret) 1046 + goto out; 1047 + ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf); 1048 + if (ret) 1049 + goto out; 1050 + ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf); 1051 + if (ret) 1052 + goto out; 1053 + 1054 + out: 1055 + kfree(buf); 1056 + return ret; 1057 + } 1058 + 1059 + static int mt798x_phy_config_init(struct phy_device *phydev) 1060 + { 1061 + switch (phydev->drv->phy_id) { 1062 + case MTK_GPHY_ID_MT7981: 1063 + mt7981_phy_finetune(phydev); 1064 + break; 1065 + case MTK_GPHY_ID_MT7988: 1066 + mt7988_phy_finetune(phydev); 1067 + break; 1068 + } 1069 + 1070 + mt798x_phy_common_finetune(phydev); 1071 + mt798x_phy_eee(phydev); 1072 + 1073 + return mt798x_phy_calibration(phydev); 1074 + } 1075 + 1076 + static struct phy_driver mtk_socphy_driver[] = { 1077 + { 1078 + PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), 1079 + .name = "MediaTek MT7981 PHY", 1080 + .config_init = mt798x_phy_config_init, 1081 + .config_intr = genphy_no_config_intr, 1082 + .handle_interrupt = genphy_handle_interrupt_no_ack, 1083 + .probe = mt798x_phy_calibration, 1084 + .suspend = genphy_suspend, 1085 + .resume = genphy_resume, 1086 + .read_page = mtk_socphy_read_page, 1087 + .write_page = mtk_socphy_write_page, 1088 + }, 1089 + { 1090 + PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988), 1091 + .name = "MediaTek MT7988 PHY", 1092 + .config_init = mt798x_phy_config_init, 1093 + .config_intr = genphy_no_config_intr, 1094 + .handle_interrupt = genphy_handle_interrupt_no_ack, 1095 + .probe = mt798x_phy_calibration, 1096 + .suspend = genphy_suspend, 1097 + .resume = genphy_resume, 1098 + .read_page = mtk_socphy_read_page, 1099 + .write_page = mtk_socphy_write_page, 1100 + }, 1101 + }; 1102 + 1103 + module_phy_driver(mtk_socphy_driver); 1104 + 1105 + static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = { 1106 + { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) }, 1107 + { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) }, 1108 + { } 1109 + }; 1110 + 1111 + MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver"); 1112 + MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>"); 1113 + MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>"); 1114 + MODULE_LICENSE("GPL"); 1115 + 1116 + MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);
+2 -1
drivers/net/phy/mediatek-ge.c
··· 102 102 module_phy_driver(mtk_gephy_driver); 103 103 104 104 static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = { 105 - { PHY_ID_MATCH_VENDOR(0x03a29400) }, 105 + { PHY_ID_MATCH_EXACT(0x03a29441) }, 106 + { PHY_ID_MATCH_EXACT(0x03a29412) }, 106 107 { } 107 108 }; 108 109