brintos

brintos / linux-shallow public Read only

0
0
Text · 45.9 KiB · f4f9412 Raw
1556 lines · c
1// SPDX-License-Identifier: GPL-2.0+2#include <linux/bitfield.h>3#include <linux/bitmap.h>4#include <linux/mfd/syscon.h>5#include <linux/module.h>6#include <linux/nvmem-consumer.h>7#include <linux/pinctrl/consumer.h>8#include <linux/phy.h>9#include <linux/regmap.h>10 11#define MTK_GPHY_ID_MT7981			0x03a2946112#define MTK_GPHY_ID_MT7988			0x03a2948113 14#define MTK_EXT_PAGE_ACCESS			0x1f15#define MTK_PHY_PAGE_STANDARD			0x000016#define MTK_PHY_PAGE_EXTENDED_3			0x000317 18#define MTK_PHY_LPI_REG_14			0x1419#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK	GENMASK(8, 0)20 21#define MTK_PHY_LPI_REG_1c			0x1c22#define MTK_PHY_SMI_DET_ON_THRESH_MASK		GENMASK(13, 8)23 24#define MTK_PHY_PAGE_EXTENDED_2A30		0x2a3025#define MTK_PHY_PAGE_EXTENDED_52B5		0x52b526 27#define ANALOG_INTERNAL_OPERATION_MAX_US	2028#define TXRESERVE_MIN				029#define TXRESERVE_MAX				730 31#define MTK_PHY_ANARG_RG			0x1032#define   MTK_PHY_TCLKOFFSET_MASK		GENMASK(12, 8)33 34/* Registers on MDIO_MMD_VEND1 */35#define MTK_PHY_TXVLD_DA_RG			0x1236#define   MTK_PHY_DA_TX_I2MPB_A_GBE_MASK	GENMASK(15, 10)37#define   MTK_PHY_DA_TX_I2MPB_A_TBT_MASK	GENMASK(5, 0)38 39#define MTK_PHY_TX_I2MPB_TEST_MODE_A2		0x1640#define   MTK_PHY_DA_TX_I2MPB_A_HBT_MASK	GENMASK(15, 10)41#define   MTK_PHY_DA_TX_I2MPB_A_TST_MASK	GENMASK(5, 0)42 43#define MTK_PHY_TX_I2MPB_TEST_MODE_B1		0x1744#define   MTK_PHY_DA_TX_I2MPB_B_GBE_MASK	GENMASK(13, 8)45#define   MTK_PHY_DA_TX_I2MPB_B_TBT_MASK	GENMASK(5, 0)46 47#define MTK_PHY_TX_I2MPB_TEST_MODE_B2		0x1848#define   MTK_PHY_DA_TX_I2MPB_B_HBT_MASK	GENMASK(13, 8)49#define   MTK_PHY_DA_TX_I2MPB_B_TST_MASK	GENMASK(5, 0)50 51#define MTK_PHY_TX_I2MPB_TEST_MODE_C1		0x1952#define   MTK_PHY_DA_TX_I2MPB_C_GBE_MASK	GENMASK(13, 8)53#define   MTK_PHY_DA_TX_I2MPB_C_TBT_MASK	GENMASK(5, 0)54 55#define MTK_PHY_TX_I2MPB_TEST_MODE_C2		0x2056#define   MTK_PHY_DA_TX_I2MPB_C_HBT_MASK	GENMASK(13, 8)57#define   MTK_PHY_DA_TX_I2MPB_C_TST_MASK	GENMASK(5, 0)58 59#define MTK_PHY_TX_I2MPB_TEST_MODE_D1		0x2160#define   MTK_PHY_DA_TX_I2MPB_D_GBE_MASK	GENMASK(13, 8)61#define   MTK_PHY_DA_TX_I2MPB_D_TBT_MASK	GENMASK(5, 0)62 63#define MTK_PHY_TX_I2MPB_TEST_MODE_D2		0x2264#define   MTK_PHY_DA_TX_I2MPB_D_HBT_MASK	GENMASK(13, 8)65#define   MTK_PHY_DA_TX_I2MPB_D_TST_MASK	GENMASK(5, 0)66 67#define MTK_PHY_RXADC_CTRL_RG7			0xc668#define   MTK_PHY_DA_AD_BUF_BIAS_LP_MASK	GENMASK(9, 8)69 70#define MTK_PHY_RXADC_CTRL_RG9			0xc871#define   MTK_PHY_DA_RX_PSBN_TBT_MASK		GENMASK(14, 12)72#define   MTK_PHY_DA_RX_PSBN_HBT_MASK		GENMASK(10, 8)73#define   MTK_PHY_DA_RX_PSBN_GBE_MASK		GENMASK(6, 4)74#define   MTK_PHY_DA_RX_PSBN_LP_MASK		GENMASK(2, 0)75 76#define MTK_PHY_LDO_OUTPUT_V			0xd777 78#define MTK_PHY_RG_ANA_CAL_RG0			0xdb79#define   MTK_PHY_RG_CAL_CKINV			BIT(12)80#define   MTK_PHY_RG_ANA_CALEN			BIT(8)81#define   MTK_PHY_RG_ZCALEN_A			BIT(0)82 83#define MTK_PHY_RG_ANA_CAL_RG1			0xdc84#define   MTK_PHY_RG_ZCALEN_B			BIT(12)85#define   MTK_PHY_RG_ZCALEN_C			BIT(8)86#define   MTK_PHY_RG_ZCALEN_D			BIT(4)87#define   MTK_PHY_RG_TXVOS_CALEN		BIT(0)88 89#define MTK_PHY_RG_ANA_CAL_RG5			0xe090#define   MTK_PHY_RG_REXT_TRIM_MASK		GENMASK(13, 8)91 92#define MTK_PHY_RG_TX_FILTER			0xfe93 94#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120	0x12095#define   MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK	GENMASK(12, 8)96#define   MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK	GENMASK(4, 0)97 98#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122	0x12299#define   MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK	GENMASK(7, 0)100 101#define MTK_PHY_RG_TESTMUX_ADC_CTRL		0x144102#define   MTK_PHY_RG_TXEN_DIG_MASK		GENMASK(5, 5)103 104#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B		0x172105#define   MTK_PHY_CR_TX_AMP_OFFSET_A_MASK	GENMASK(13, 8)106#define   MTK_PHY_CR_TX_AMP_OFFSET_B_MASK	GENMASK(6, 0)107 108#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D		0x173109#define   MTK_PHY_CR_TX_AMP_OFFSET_C_MASK	GENMASK(13, 8)110#define   MTK_PHY_CR_TX_AMP_OFFSET_D_MASK	GENMASK(6, 0)111 112#define MTK_PHY_RG_AD_CAL_COMP			0x17a113#define   MTK_PHY_AD_CAL_COMP_OUT_SHIFT		(8)114 115#define MTK_PHY_RG_AD_CAL_CLK			0x17b116#define   MTK_PHY_DA_CAL_CLK			BIT(0)117 118#define MTK_PHY_RG_AD_CALIN			0x17c119#define   MTK_PHY_DA_CALIN_FLAG			BIT(0)120 121#define MTK_PHY_RG_DASN_DAC_IN0_A		0x17d122#define   MTK_PHY_DASN_DAC_IN0_A_MASK		GENMASK(9, 0)123 124#define MTK_PHY_RG_DASN_DAC_IN0_B		0x17e125#define   MTK_PHY_DASN_DAC_IN0_B_MASK		GENMASK(9, 0)126 127#define MTK_PHY_RG_DASN_DAC_IN0_C		0x17f128#define   MTK_PHY_DASN_DAC_IN0_C_MASK		GENMASK(9, 0)129 130#define MTK_PHY_RG_DASN_DAC_IN0_D		0x180131#define   MTK_PHY_DASN_DAC_IN0_D_MASK		GENMASK(9, 0)132 133#define MTK_PHY_RG_DASN_DAC_IN1_A		0x181134#define   MTK_PHY_DASN_DAC_IN1_A_MASK		GENMASK(9, 0)135 136#define MTK_PHY_RG_DASN_DAC_IN1_B		0x182137#define   MTK_PHY_DASN_DAC_IN1_B_MASK		GENMASK(9, 0)138 139#define MTK_PHY_RG_DASN_DAC_IN1_C		0x183140#define   MTK_PHY_DASN_DAC_IN1_C_MASK		GENMASK(9, 0)141 142#define MTK_PHY_RG_DASN_DAC_IN1_D		0x184143#define   MTK_PHY_DASN_DAC_IN1_D_MASK		GENMASK(9, 0)144 145#define MTK_PHY_RG_DEV1E_REG19b			0x19b146#define   MTK_PHY_BYPASS_DSP_LPI_READY		BIT(8)147 148#define MTK_PHY_RG_LP_IIR2_K1_L			0x22a149#define MTK_PHY_RG_LP_IIR2_K1_U			0x22b150#define MTK_PHY_RG_LP_IIR2_K2_L			0x22c151#define MTK_PHY_RG_LP_IIR2_K2_U			0x22d152#define MTK_PHY_RG_LP_IIR2_K3_L			0x22e153#define MTK_PHY_RG_LP_IIR2_K3_U			0x22f154#define MTK_PHY_RG_LP_IIR2_K4_L			0x230155#define MTK_PHY_RG_LP_IIR2_K4_U			0x231156#define MTK_PHY_RG_LP_IIR2_K5_L			0x232157#define MTK_PHY_RG_LP_IIR2_K5_U			0x233158 159#define MTK_PHY_RG_DEV1E_REG234			0x234160#define   MTK_PHY_TR_OPEN_LOOP_EN_MASK		GENMASK(0, 0)161#define   MTK_PHY_LPF_X_AVERAGE_MASK		GENMASK(7, 4)162#define   MTK_PHY_TR_LP_IIR_EEE_EN		BIT(12)163 164#define MTK_PHY_RG_LPF_CNT_VAL			0x235165 166#define MTK_PHY_RG_DEV1E_REG238			0x238167#define   MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK	GENMASK(8, 0)168#define   MTK_PHY_LPI_SLV_SEND_TX_EN		BIT(12)169 170#define MTK_PHY_RG_DEV1E_REG239			0x239171#define   MTK_PHY_LPI_SEND_LOC_TIMER_MASK	GENMASK(8, 0)172#define   MTK_PHY_LPI_TXPCS_LOC_RCV		BIT(12)173 174#define MTK_PHY_RG_DEV1E_REG27C			0x27c175#define   MTK_PHY_VGASTATE_FFE_THR_ST1_MASK	GENMASK(12, 8)176#define MTK_PHY_RG_DEV1E_REG27D			0x27d177#define   MTK_PHY_VGASTATE_FFE_THR_ST2_MASK	GENMASK(4, 0)178 179#define MTK_PHY_RG_DEV1E_REG2C7			0x2c7180#define   MTK_PHY_MAX_GAIN_MASK			GENMASK(4, 0)181#define   MTK_PHY_MIN_GAIN_MASK			GENMASK(12, 8)182 183#define MTK_PHY_RG_DEV1E_REG2D1			0x2d1184#define   MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK	GENMASK(7, 0)185#define   MTK_PHY_LPI_SKIP_SD_SLV_TR		BIT(8)186#define   MTK_PHY_LPI_TR_READY			BIT(9)187#define   MTK_PHY_LPI_VCO_EEE_STG0_EN		BIT(10)188 189#define MTK_PHY_RG_DEV1E_REG323			0x323190#define   MTK_PHY_EEE_WAKE_MAS_INT_DC		BIT(0)191#define   MTK_PHY_EEE_WAKE_SLV_INT_DC		BIT(4)192 193#define MTK_PHY_RG_DEV1E_REG324			0x324194#define   MTK_PHY_SMI_DETCNT_MAX_MASK		GENMASK(5, 0)195#define   MTK_PHY_SMI_DET_MAX_EN		BIT(8)196 197#define MTK_PHY_RG_DEV1E_REG326			0x326198#define   MTK_PHY_LPI_MODE_SD_ON		BIT(0)199#define   MTK_PHY_RESET_RANDUPD_CNT		BIT(1)200#define   MTK_PHY_TREC_UPDATE_ENAB_CLR		BIT(2)201#define   MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF	BIT(4)202#define   MTK_PHY_TR_READY_SKIP_AFE_WAKEUP	BIT(5)203 204#define MTK_PHY_LDO_PUMP_EN_PAIRAB		0x502205#define MTK_PHY_LDO_PUMP_EN_PAIRCD		0x503206 207#define MTK_PHY_DA_TX_R50_PAIR_A		0x53d208#define MTK_PHY_DA_TX_R50_PAIR_B		0x53e209#define MTK_PHY_DA_TX_R50_PAIR_C		0x53f210#define MTK_PHY_DA_TX_R50_PAIR_D		0x540211 212/* Registers on MDIO_MMD_VEND2 */213#define MTK_PHY_LED0_ON_CTRL			0x24214#define MTK_PHY_LED1_ON_CTRL			0x26215#define   MTK_PHY_LED_ON_MASK			GENMASK(6, 0)216#define   MTK_PHY_LED_ON_LINK1000		BIT(0)217#define   MTK_PHY_LED_ON_LINK100		BIT(1)218#define   MTK_PHY_LED_ON_LINK10			BIT(2)219#define   MTK_PHY_LED_ON_LINK			(MTK_PHY_LED_ON_LINK10 |\220						 MTK_PHY_LED_ON_LINK100 |\221						 MTK_PHY_LED_ON_LINK1000)222#define   MTK_PHY_LED_ON_LINKDOWN		BIT(3)223#define   MTK_PHY_LED_ON_FDX			BIT(4) /* Full duplex */224#define   MTK_PHY_LED_ON_HDX			BIT(5) /* Half duplex */225#define   MTK_PHY_LED_ON_FORCE_ON		BIT(6)226#define   MTK_PHY_LED_ON_POLARITY		BIT(14)227#define   MTK_PHY_LED_ON_ENABLE			BIT(15)228 229#define MTK_PHY_LED0_BLINK_CTRL			0x25230#define MTK_PHY_LED1_BLINK_CTRL			0x27231#define   MTK_PHY_LED_BLINK_1000TX		BIT(0)232#define   MTK_PHY_LED_BLINK_1000RX		BIT(1)233#define   MTK_PHY_LED_BLINK_100TX		BIT(2)234#define   MTK_PHY_LED_BLINK_100RX		BIT(3)235#define   MTK_PHY_LED_BLINK_10TX		BIT(4)236#define   MTK_PHY_LED_BLINK_10RX		BIT(5)237#define   MTK_PHY_LED_BLINK_RX			(MTK_PHY_LED_BLINK_10RX |\238						 MTK_PHY_LED_BLINK_100RX |\239						 MTK_PHY_LED_BLINK_1000RX)240#define   MTK_PHY_LED_BLINK_TX			(MTK_PHY_LED_BLINK_10TX |\241						 MTK_PHY_LED_BLINK_100TX |\242						 MTK_PHY_LED_BLINK_1000TX)243#define   MTK_PHY_LED_BLINK_COLLISION		BIT(6)244#define   MTK_PHY_LED_BLINK_RX_CRC_ERR		BIT(7)245#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR		BIT(8)246#define   MTK_PHY_LED_BLINK_FORCE_BLINK		BIT(9)247 248#define MTK_PHY_LED1_DEFAULT_POLARITIES		BIT(1)249 250#define MTK_PHY_RG_BG_RASEL			0x115251#define   MTK_PHY_RG_BG_RASEL_MASK		GENMASK(2, 0)252 253/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */254#define RG_GPIO_MISC_TPBANK0			0x6f0255#define   RG_GPIO_MISC_TPBANK0_BOOTMODE		GENMASK(11, 8)256 257/* These macro privides efuse parsing for internal phy. */258#define EFS_DA_TX_I2MPB_A(x)			(((x) >> 0) & GENMASK(5, 0))259#define EFS_DA_TX_I2MPB_B(x)			(((x) >> 6) & GENMASK(5, 0))260#define EFS_DA_TX_I2MPB_C(x)			(((x) >> 12) & GENMASK(5, 0))261#define EFS_DA_TX_I2MPB_D(x)			(((x) >> 18) & GENMASK(5, 0))262#define EFS_DA_TX_AMP_OFFSET_A(x)		(((x) >> 24) & GENMASK(5, 0))263 264#define EFS_DA_TX_AMP_OFFSET_B(x)		(((x) >> 0) & GENMASK(5, 0))265#define EFS_DA_TX_AMP_OFFSET_C(x)		(((x) >> 6) & GENMASK(5, 0))266#define EFS_DA_TX_AMP_OFFSET_D(x)		(((x) >> 12) & GENMASK(5, 0))267#define EFS_DA_TX_R50_A(x)			(((x) >> 18) & GENMASK(5, 0))268#define EFS_DA_TX_R50_B(x)			(((x) >> 24) & GENMASK(5, 0))269 270#define EFS_DA_TX_R50_C(x)			(((x) >> 0) & GENMASK(5, 0))271#define EFS_DA_TX_R50_D(x)			(((x) >> 6) & GENMASK(5, 0))272 273#define EFS_RG_BG_RASEL(x)			(((x) >> 4) & GENMASK(2, 0))274#define EFS_RG_REXT_TRIM(x)			(((x) >> 7) & GENMASK(5, 0))275 276enum {277	NO_PAIR,278	PAIR_A,279	PAIR_B,280	PAIR_C,281	PAIR_D,282};283 284enum calibration_mode {285	EFUSE_K,286	SW_K287};288 289enum CAL_ITEM {290	REXT,291	TX_OFFSET,292	TX_AMP,293	TX_R50,294	TX_VCM295};296 297enum CAL_MODE {298	EFUSE_M,299	SW_M300};301 302#define MTK_PHY_LED_STATE_FORCE_ON	0303#define MTK_PHY_LED_STATE_FORCE_BLINK	1304#define MTK_PHY_LED_STATE_NETDEV	2305 306struct mtk_socphy_priv {307	unsigned long		led_state;308};309 310struct mtk_socphy_shared {311	u32			boottrap;312	struct mtk_socphy_priv	priv[4];313};314 315static int mtk_socphy_read_page(struct phy_device *phydev)316{317	return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);318}319 320static int mtk_socphy_write_page(struct phy_device *phydev, int page)321{322	return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);323}324 325/* One calibration cycle consists of:326 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high327 *   until AD_CAL_COMP is ready to output calibration result.328 * 2.Wait until DA_CAL_CLK is available.329 * 3.Fetch AD_CAL_COMP_OUT.330 */331static int cal_cycle(struct phy_device *phydev, int devad,332		     u32 regnum, u16 mask, u16 cal_val)333{334	int reg_val;335	int ret;336 337	phy_modify_mmd(phydev, devad, regnum,338		       mask, cal_val);339	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,340			 MTK_PHY_DA_CALIN_FLAG);341 342	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,343					MTK_PHY_RG_AD_CAL_CLK, reg_val,344					reg_val & MTK_PHY_DA_CAL_CLK, 500,345					ANALOG_INTERNAL_OPERATION_MAX_US, false);346	if (ret) {347		phydev_err(phydev, "Calibration cycle timeout\n");348		return ret;349	}350 351	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,352			   MTK_PHY_DA_CALIN_FLAG);353	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>354			   MTK_PHY_AD_CAL_COMP_OUT_SHIFT;355	phydev_dbg(phydev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);356 357	return ret;358}359 360static int rext_fill_result(struct phy_device *phydev, u16 *buf)361{362	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,363		       MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);364	phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,365		       MTK_PHY_RG_BG_RASEL_MASK, buf[1]);366 367	return 0;368}369 370static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)371{372	u16 rext_cal_val[2];373 374	rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);375	rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);376	rext_fill_result(phydev, rext_cal_val);377 378	return 0;379}380 381static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)382{383	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,384		       MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);385	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,386		       MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);387	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,388		       MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);389	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,390		       MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);391 392	return 0;393}394 395static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)396{397	u16 tx_offset_cal_val[4];398 399	tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);400	tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);401	tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);402	tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);403 404	tx_offset_fill_result(phydev, tx_offset_cal_val);405 406	return 0;407}408 409static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)410{411	int i;412	int bias[16] = {};413	const int vals_9461[16] = { 7, 1, 4, 7,414				    7, 1, 4, 7,415				    7, 1, 4, 7,416				    7, 1, 4, 7 };417	const int vals_9481[16] = { 10, 6, 6, 10,418				    10, 6, 6, 10,419				    10, 6, 6, 10,420				    10, 6, 6, 10 };421	switch (phydev->drv->phy_id) {422	case MTK_GPHY_ID_MT7981:423		/* We add some calibration to efuse values424		 * due to board level influence.425		 * GBE: +7, TBT: +1, HBT: +4, TST: +7426		 */427		memcpy(bias, (const void *)vals_9461, sizeof(bias));428		break;429	case MTK_GPHY_ID_MT7988:430		memcpy(bias, (const void *)vals_9481, sizeof(bias));431		break;432	}433 434	/* Prevent overflow */435	for (i = 0; i < 12; i++) {436		if (buf[i >> 2] + bias[i] > 63) {437			buf[i >> 2] = 63;438			bias[i] = 0;439		}440	}441 442	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,443		       MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);444	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,445		       MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);446	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,447		       MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);448	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,449		       MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);450 451	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,452		       MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);453	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,454		       MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);455	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,456		       MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);457	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,458		       MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);459 460	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,461		       MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);462	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,463		       MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);464	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,465		       MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);466	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,467		       MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);468 469	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,470		       MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);471	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,472		       MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);473	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,474		       MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);475	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,476		       MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);477 478	return 0;479}480 481static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)482{483	u16 tx_amp_cal_val[4];484 485	tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);486	tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);487	tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);488	tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);489	tx_amp_fill_result(phydev, tx_amp_cal_val);490 491	return 0;492}493 494static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,495			      u8 txg_calen_x)496{497	int bias = 0;498	u16 reg, val;499 500	if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)501		bias = -1;502 503	val = clamp_val(bias + tx_r50_cal_val, 0, 63);504 505	switch (txg_calen_x) {506	case PAIR_A:507		reg = MTK_PHY_DA_TX_R50_PAIR_A;508		break;509	case PAIR_B:510		reg = MTK_PHY_DA_TX_R50_PAIR_B;511		break;512	case PAIR_C:513		reg = MTK_PHY_DA_TX_R50_PAIR_C;514		break;515	case PAIR_D:516		reg = MTK_PHY_DA_TX_R50_PAIR_D;517		break;518	default:519		return -EINVAL;520	}521 522	phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);523 524	return 0;525}526 527static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,528			    u8 txg_calen_x)529{530	u16 tx_r50_cal_val;531 532	switch (txg_calen_x) {533	case PAIR_A:534		tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);535		break;536	case PAIR_B:537		tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);538		break;539	case PAIR_C:540		tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);541		break;542	case PAIR_D:543		tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);544		break;545	default:546		return -EINVAL;547	}548	tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);549 550	return 0;551}552 553static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)554{555	u8 lower_idx, upper_idx, txreserve_val;556	u8 lower_ret, upper_ret;557	int ret;558 559	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,560			 MTK_PHY_RG_ANA_CALEN);561	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,562			   MTK_PHY_RG_CAL_CKINV);563	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,564			 MTK_PHY_RG_TXVOS_CALEN);565 566	switch (rg_txreserve_x) {567	case PAIR_A:568		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,569				   MTK_PHY_RG_DASN_DAC_IN0_A,570				   MTK_PHY_DASN_DAC_IN0_A_MASK);571		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,572				   MTK_PHY_RG_DASN_DAC_IN1_A,573				   MTK_PHY_DASN_DAC_IN1_A_MASK);574		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,575				 MTK_PHY_RG_ANA_CAL_RG0,576				 MTK_PHY_RG_ZCALEN_A);577		break;578	case PAIR_B:579		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,580				   MTK_PHY_RG_DASN_DAC_IN0_B,581				   MTK_PHY_DASN_DAC_IN0_B_MASK);582		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,583				   MTK_PHY_RG_DASN_DAC_IN1_B,584				   MTK_PHY_DASN_DAC_IN1_B_MASK);585		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,586				 MTK_PHY_RG_ANA_CAL_RG1,587				 MTK_PHY_RG_ZCALEN_B);588		break;589	case PAIR_C:590		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,591				   MTK_PHY_RG_DASN_DAC_IN0_C,592				   MTK_PHY_DASN_DAC_IN0_C_MASK);593		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,594				   MTK_PHY_RG_DASN_DAC_IN1_C,595				   MTK_PHY_DASN_DAC_IN1_C_MASK);596		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,597				 MTK_PHY_RG_ANA_CAL_RG1,598				 MTK_PHY_RG_ZCALEN_C);599		break;600	case PAIR_D:601		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,602				   MTK_PHY_RG_DASN_DAC_IN0_D,603				   MTK_PHY_DASN_DAC_IN0_D_MASK);604		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,605				   MTK_PHY_RG_DASN_DAC_IN1_D,606				   MTK_PHY_DASN_DAC_IN1_D_MASK);607		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,608				 MTK_PHY_RG_ANA_CAL_RG1,609				 MTK_PHY_RG_ZCALEN_D);610		break;611	default:612		ret = -EINVAL;613		goto restore;614	}615 616	lower_idx = TXRESERVE_MIN;617	upper_idx = TXRESERVE_MAX;618 619	phydev_dbg(phydev, "Start TX-VCM SW cal.\n");620	while ((upper_idx - lower_idx) > 1) {621		txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);622		ret = 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				txreserve_val << 12 | txreserve_val << 8 |628				txreserve_val << 4 | txreserve_val);629		if (ret == 1) {630			upper_idx = txreserve_val;631			upper_ret = ret;632		} else if (ret == 0) {633			lower_idx = txreserve_val;634			lower_ret = ret;635		} else {636			goto restore;637		}638	}639 640	if (lower_idx == TXRESERVE_MIN) {641		lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,642				      MTK_PHY_RXADC_CTRL_RG9,643				      MTK_PHY_DA_RX_PSBN_TBT_MASK |644				      MTK_PHY_DA_RX_PSBN_HBT_MASK |645				      MTK_PHY_DA_RX_PSBN_GBE_MASK |646				      MTK_PHY_DA_RX_PSBN_LP_MASK,647				      lower_idx << 12 | lower_idx << 8 |648				      lower_idx << 4 | lower_idx);649		ret = lower_ret;650	} else if (upper_idx == TXRESERVE_MAX) {651		upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,652				      MTK_PHY_RXADC_CTRL_RG9,653				      MTK_PHY_DA_RX_PSBN_TBT_MASK |654				      MTK_PHY_DA_RX_PSBN_HBT_MASK |655				      MTK_PHY_DA_RX_PSBN_GBE_MASK |656				      MTK_PHY_DA_RX_PSBN_LP_MASK,657				      upper_idx << 12 | upper_idx << 8 |658				      upper_idx << 4 | upper_idx);659		ret = upper_ret;660	}661	if (ret < 0)662		goto restore;663 664	/* We calibrate TX-VCM in different logic. Check upper index and then665	 * lower index. If this calibration is valid, apply lower index's result.666	 */667	ret = upper_ret - lower_ret;668	if (ret == 1) {669		ret = 0;670		/* Make sure we use upper_idx in our calibration system */671		cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,672			  MTK_PHY_DA_RX_PSBN_TBT_MASK |673			  MTK_PHY_DA_RX_PSBN_HBT_MASK |674			  MTK_PHY_DA_RX_PSBN_GBE_MASK |675			  MTK_PHY_DA_RX_PSBN_LP_MASK,676			  upper_idx << 12 | upper_idx << 8 |677			  upper_idx << 4 | upper_idx);678		phydev_dbg(phydev, "TX-VCM SW cal result: 0x%x\n", upper_idx);679	} else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&680		   lower_ret == 1) {681		ret = 0;682		cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,683			  MTK_PHY_DA_RX_PSBN_TBT_MASK |684			  MTK_PHY_DA_RX_PSBN_HBT_MASK |685			  MTK_PHY_DA_RX_PSBN_GBE_MASK |686			  MTK_PHY_DA_RX_PSBN_LP_MASK,687			  lower_idx << 12 | lower_idx << 8 |688			  lower_idx << 4 | lower_idx);689		phydev_warn(phydev, "TX-VCM SW cal result at low margin 0x%x\n",690			    lower_idx);691	} else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&692		   lower_ret == 0) {693		ret = 0;694		phydev_warn(phydev, "TX-VCM SW cal result at high margin 0x%x\n",695			    upper_idx);696	} else {697		ret = -EINVAL;698	}699 700restore:701	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,702			   MTK_PHY_RG_ANA_CALEN);703	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,704			   MTK_PHY_RG_TXVOS_CALEN);705	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,706			   MTK_PHY_RG_ZCALEN_A);707	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,708			   MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |709			   MTK_PHY_RG_ZCALEN_D);710 711	return ret;712}713 714static void mt798x_phy_common_finetune(struct phy_device *phydev)715{716	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);717	/* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */718	__phy_write(phydev, 0x11, 0xc71);719	__phy_write(phydev, 0x12, 0xc);720	__phy_write(phydev, 0x10, 0x8fae);721 722	/* EnabRandUpdTrig = 1 */723	__phy_write(phydev, 0x11, 0x2f00);724	__phy_write(phydev, 0x12, 0xe);725	__phy_write(phydev, 0x10, 0x8fb0);726 727	/* NormMseLoThresh = 85 */728	__phy_write(phydev, 0x11, 0x55a0);729	__phy_write(phydev, 0x12, 0x0);730	__phy_write(phydev, 0x10, 0x83aa);731 732	/* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */733	__phy_write(phydev, 0x11, 0x240);734	__phy_write(phydev, 0x12, 0x0);735	__phy_write(phydev, 0x10, 0x9680);736 737	/* TrFreeze = 0 (mt7988 default) */738	__phy_write(phydev, 0x11, 0x0);739	__phy_write(phydev, 0x12, 0x0);740	__phy_write(phydev, 0x10, 0x9686);741 742	/* SSTrKp100 = 5 */743	/* SSTrKf100 = 6 */744	/* SSTrKp1000Mas = 5 */745	/* SSTrKf1000Mas = 6 */746	/* SSTrKp1000Slv = 5 */747	/* SSTrKf1000Slv = 6 */748	__phy_write(phydev, 0x11, 0xbaef);749	__phy_write(phydev, 0x12, 0x2e);750	__phy_write(phydev, 0x10, 0x968c);751	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);752}753 754static void mt7981_phy_finetune(struct phy_device *phydev)755{756	u16 val[8] = { 0x01ce, 0x01c1,757		       0x020f, 0x0202,758		       0x03d0, 0x03c0,759		       0x0013, 0x0005 };760	int i, k;761 762	/* 100M eye finetune:763	 * Keep middle level of TX MLT3 shapper as default.764	 * Only change TX MLT3 overshoot level here.765	 */766	for (k = 0, i = 1; i < 12; i++) {767		if (i % 3 == 0)768			continue;769		phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);770	}771 772	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);773	/* ResetSyncOffset = 6 */774	__phy_write(phydev, 0x11, 0x600);775	__phy_write(phydev, 0x12, 0x0);776	__phy_write(phydev, 0x10, 0x8fc0);777 778	/* VgaDecRate = 1 */779	__phy_write(phydev, 0x11, 0x4c2a);780	__phy_write(phydev, 0x12, 0x3e);781	__phy_write(phydev, 0x10, 0x8fa4);782 783	/* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,784	 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2785	 */786	__phy_write(phydev, 0x11, 0xd10a);787	__phy_write(phydev, 0x12, 0x34);788	__phy_write(phydev, 0x10, 0x8f82);789 790	/* VcoSlicerThreshBitsHigh */791	__phy_write(phydev, 0x11, 0x5555);792	__phy_write(phydev, 0x12, 0x55);793	__phy_write(phydev, 0x10, 0x8ec0);794	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);795 796	/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */797	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,798		       MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,799		       BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));800 801	/* rg_tr_lpf_cnt_val = 512 */802	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);803 804	/* IIR2 related */805	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);806	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);807	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);808	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);809	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);810	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);811	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);812	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);813	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);814	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);815 816	/* FFE peaking */817	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,818		       MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);819	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,820		       MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);821 822	/* Disable LDO pump */823	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);824	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);825	/* Adjust LDO output voltage */826	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);827}828 829static void mt7988_phy_finetune(struct phy_device *phydev)830{831	u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,832			0x020d, 0x0206, 0x0384, 0x03d0,833			0x03c6, 0x030a, 0x0011, 0x0005 };834	int i;835 836	/* Set default MLT3 shaper first */837	for (i = 0; i < 12; i++)838		phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);839 840	/* TCT finetune */841	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);842 843	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);844	/* ResetSyncOffset = 5 */845	__phy_write(phydev, 0x11, 0x500);846	__phy_write(phydev, 0x12, 0x0);847	__phy_write(phydev, 0x10, 0x8fc0);848 849	/* VgaDecRate is 1 at default on mt7988 */850 851	/* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,852	 * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7853	 */854	__phy_write(phydev, 0x11, 0xb90a);855	__phy_write(phydev, 0x12, 0x6f);856	__phy_write(phydev, 0x10, 0x8f82);857 858	/* RemAckCntLimitCtrl = 1 */859	__phy_write(phydev, 0x11, 0xfbba);860	__phy_write(phydev, 0x12, 0xc3);861	__phy_write(phydev, 0x10, 0x87f8);862 863	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);864 865	/* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */866	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,867		       MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,868		       BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));869 870	/* rg_tr_lpf_cnt_val = 1023 */871	phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);872}873 874static void mt798x_phy_eee(struct phy_device *phydev)875{876	phy_modify_mmd(phydev, MDIO_MMD_VEND1,877		       MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,878		       MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |879		       MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,880		       FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |881		       FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));882 883	phy_modify_mmd(phydev, MDIO_MMD_VEND1,884		       MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,885		       MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,886		       FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,887				  0xff));888 889	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,890			   MTK_PHY_RG_TESTMUX_ADC_CTRL,891			   MTK_PHY_RG_TXEN_DIG_MASK);892 893	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,894			 MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);895 896	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,897			   MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);898 899	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,900		       MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |901		       MTK_PHY_LPI_SLV_SEND_TX_EN,902		       FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));903 904	/* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */905	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,906			   MTK_PHY_LPI_TXPCS_LOC_RCV);907 908	/* This also fixes some IoT issues, such as CH340 */909	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,910		       MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,911		       FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |912		       FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));913 914	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,915		       MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,916		       FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,917				  0x33) |918		       MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |919		       MTK_PHY_LPI_VCO_EEE_STG0_EN);920 921	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,922			 MTK_PHY_EEE_WAKE_MAS_INT_DC |923			 MTK_PHY_EEE_WAKE_SLV_INT_DC);924 925	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,926		       MTK_PHY_SMI_DETCNT_MAX_MASK,927		       FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |928		       MTK_PHY_SMI_DET_MAX_EN);929 930	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,931			 MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |932			 MTK_PHY_TREC_UPDATE_ENAB_CLR |933			 MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |934			 MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);935 936	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);937	/* Regsigdet_sel_1000 = 0 */938	__phy_write(phydev, 0x11, 0xb);939	__phy_write(phydev, 0x12, 0x0);940	__phy_write(phydev, 0x10, 0x9690);941 942	/* REG_EEE_st2TrKf1000 = 2 */943	__phy_write(phydev, 0x11, 0x114f);944	__phy_write(phydev, 0x12, 0x2);945	__phy_write(phydev, 0x10, 0x969a);946 947	/* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */948	__phy_write(phydev, 0x11, 0x3028);949	__phy_write(phydev, 0x12, 0x0);950	__phy_write(phydev, 0x10, 0x969e);951 952	/* RegEEE_slv_wake_int_timer_tar = 8 */953	__phy_write(phydev, 0x11, 0x5010);954	__phy_write(phydev, 0x12, 0x0);955	__phy_write(phydev, 0x10, 0x96a0);956 957	/* RegEEE_trfreeze_timer2 = 586 */958	__phy_write(phydev, 0x11, 0x24a);959	__phy_write(phydev, 0x12, 0x0);960	__phy_write(phydev, 0x10, 0x96a8);961 962	/* RegEEE100Stg1_tar = 16 */963	__phy_write(phydev, 0x11, 0x3210);964	__phy_write(phydev, 0x12, 0x0);965	__phy_write(phydev, 0x10, 0x96b8);966 967	/* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */968	__phy_write(phydev, 0x11, 0x1463);969	__phy_write(phydev, 0x12, 0x0);970	__phy_write(phydev, 0x10, 0x96ca);971 972	/* DfeTailEnableVgaThresh1000 = 27 */973	__phy_write(phydev, 0x11, 0x36);974	__phy_write(phydev, 0x12, 0x0);975	__phy_write(phydev, 0x10, 0x8f80);976	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);977 978	phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);979	__phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,980		     FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));981 982	__phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,983		     FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));984	phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);985 986	phy_modify_mmd(phydev, MDIO_MMD_VEND1,987		       MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,988		       MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,989		       FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));990}991 992static int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,993		  u8 start_pair, u8 end_pair)994{995	u8 pair_n;996	int ret;997 998	for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {999		/* TX_OFFSET & TX_AMP have no SW calibration. */1000		switch (cal_item) {1001		case TX_VCM:1002			ret = tx_vcm_cal_sw(phydev, pair_n);1003			break;1004		default:1005			return -EINVAL;1006		}1007		if (ret)1008			return ret;1009	}1010	return 0;1011}1012 1013static int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,1014		     u8 start_pair, u8 end_pair, u32 *buf)1015{1016	u8 pair_n;1017	int ret;1018 1019	for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {1020		/* TX_VCM has no efuse calibration. */1021		switch (cal_item) {1022		case REXT:1023			ret = rext_cal_efuse(phydev, buf);1024			break;1025		case TX_OFFSET:1026			ret = tx_offset_cal_efuse(phydev, buf);1027			break;1028		case TX_AMP:1029			ret = tx_amp_cal_efuse(phydev, buf);1030			break;1031		case TX_R50:1032			ret = tx_r50_cal_efuse(phydev, buf, pair_n);1033			break;1034		default:1035			return -EINVAL;1036		}1037		if (ret)1038			return ret;1039	}1040 1041	return 0;1042}1043 1044static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,1045		     enum CAL_MODE cal_mode, u8 start_pair,1046		     u8 end_pair, u32 *buf)1047{1048	int ret;1049 1050	switch (cal_mode) {1051	case EFUSE_M:1052		ret = cal_efuse(phydev, cal_item, start_pair,1053				end_pair, buf);1054		break;1055	case SW_M:1056		ret = cal_sw(phydev, cal_item, start_pair, end_pair);1057		break;1058	default:1059		return -EINVAL;1060	}1061 1062	if (ret) {1063		phydev_err(phydev, "cal %d failed\n", cal_item);1064		return -EIO;1065	}1066 1067	return 0;1068}1069 1070static int mt798x_phy_calibration(struct phy_device *phydev)1071{1072	int ret = 0;1073	u32 *buf;1074	size_t len;1075	struct nvmem_cell *cell;1076 1077	cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");1078	if (IS_ERR(cell)) {1079		if (PTR_ERR(cell) == -EPROBE_DEFER)1080			return PTR_ERR(cell);1081		return 0;1082	}1083 1084	buf = (u32 *)nvmem_cell_read(cell, &len);1085	if (IS_ERR(buf))1086		return PTR_ERR(buf);1087	nvmem_cell_put(cell);1088 1089	if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {1090		phydev_err(phydev, "invalid efuse data\n");1091		ret = -EINVAL;1092		goto out;1093	}1094 1095	ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);1096	if (ret)1097		goto out;1098	ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);1099	if (ret)1100		goto out;1101	ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);1102	if (ret)1103		goto out;1104	ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);1105	if (ret)1106		goto out;1107	ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);1108	if (ret)1109		goto out;1110 1111out:1112	kfree(buf);1113	return ret;1114}1115 1116static int mt798x_phy_config_init(struct phy_device *phydev)1117{1118	switch (phydev->drv->phy_id) {1119	case MTK_GPHY_ID_MT7981:1120		mt7981_phy_finetune(phydev);1121		break;1122	case MTK_GPHY_ID_MT7988:1123		mt7988_phy_finetune(phydev);1124		break;1125	}1126 1127	mt798x_phy_common_finetune(phydev);1128	mt798x_phy_eee(phydev);1129 1130	return mt798x_phy_calibration(phydev);1131}1132 1133static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,1134				    bool on)1135{1136	unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);1137	struct mtk_socphy_priv *priv = phydev->priv;1138	bool changed;1139 1140	if (on)1141		changed = !test_and_set_bit(bit_on, &priv->led_state);1142	else1143		changed = !!test_and_clear_bit(bit_on, &priv->led_state);1144 1145	changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +1146					(index ? 16 : 0), &priv->led_state);1147	if (changed)1148		return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?1149				      MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,1150				      MTK_PHY_LED_ON_MASK,1151				      on ? MTK_PHY_LED_ON_FORCE_ON : 0);1152	else1153		return 0;1154}1155 1156static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,1157				       bool blinking)1158{1159	unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);1160	struct mtk_socphy_priv *priv = phydev->priv;1161	bool changed;1162 1163	if (blinking)1164		changed = !test_and_set_bit(bit_blink, &priv->led_state);1165	else1166		changed = !!test_and_clear_bit(bit_blink, &priv->led_state);1167 1168	changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +1169			      (index ? 16 : 0), &priv->led_state);1170	if (changed)1171		return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?1172				     MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,1173				     blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);1174	else1175		return 0;1176}1177 1178static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,1179				    unsigned long *delay_on,1180				    unsigned long *delay_off)1181{1182	bool blinking = false;1183	int err = 0;1184 1185	if (index > 1)1186		return -EINVAL;1187 1188	if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {1189		blinking = true;1190		*delay_on = 50;1191		*delay_off = 50;1192	}1193 1194	err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);1195	if (err)1196		return err;1197 1198	return mt798x_phy_hw_led_on_set(phydev, index, false);1199}1200 1201static int mt798x_phy_led_brightness_set(struct phy_device *phydev,1202					 u8 index, enum led_brightness value)1203{1204	int err;1205 1206	err = mt798x_phy_hw_led_blink_set(phydev, index, false);1207	if (err)1208		return err;1209 1210	return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));1211}1212 1213static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |1214						 BIT(TRIGGER_NETDEV_HALF_DUPLEX) |1215						 BIT(TRIGGER_NETDEV_LINK)        |1216						 BIT(TRIGGER_NETDEV_LINK_10)     |1217						 BIT(TRIGGER_NETDEV_LINK_100)    |1218						 BIT(TRIGGER_NETDEV_LINK_1000)   |1219						 BIT(TRIGGER_NETDEV_RX)          |1220						 BIT(TRIGGER_NETDEV_TX));1221 1222static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,1223					  unsigned long rules)1224{1225	if (index > 1)1226		return -EINVAL;1227 1228	/* All combinations of the supported triggers are allowed */1229	if (rules & ~supported_triggers)1230		return -EOPNOTSUPP;1231 1232	return 0;1233};1234 1235static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,1236					 unsigned long *rules)1237{1238	unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);1239	unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);1240	unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);1241	struct mtk_socphy_priv *priv = phydev->priv;1242	int on, blink;1243 1244	if (index > 1)1245		return -EINVAL;1246 1247	on = phy_read_mmd(phydev, MDIO_MMD_VEND2,1248			  index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);1249 1250	if (on < 0)1251		return -EIO;1252 1253	blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,1254			     index ? MTK_PHY_LED1_BLINK_CTRL :1255				     MTK_PHY_LED0_BLINK_CTRL);1256	if (blink < 0)1257		return -EIO;1258 1259	if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |1260		   MTK_PHY_LED_ON_LINKDOWN)) ||1261	    (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))1262		set_bit(bit_netdev, &priv->led_state);1263	else1264		clear_bit(bit_netdev, &priv->led_state);1265 1266	if (on & MTK_PHY_LED_ON_FORCE_ON)1267		set_bit(bit_on, &priv->led_state);1268	else1269		clear_bit(bit_on, &priv->led_state);1270 1271	if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)1272		set_bit(bit_blink, &priv->led_state);1273	else1274		clear_bit(bit_blink, &priv->led_state);1275 1276	if (!rules)1277		return 0;1278 1279	if (on & MTK_PHY_LED_ON_LINK)1280		*rules |= BIT(TRIGGER_NETDEV_LINK);1281 1282	if (on & MTK_PHY_LED_ON_LINK10)1283		*rules |= BIT(TRIGGER_NETDEV_LINK_10);1284 1285	if (on & MTK_PHY_LED_ON_LINK100)1286		*rules |= BIT(TRIGGER_NETDEV_LINK_100);1287 1288	if (on & MTK_PHY_LED_ON_LINK1000)1289		*rules |= BIT(TRIGGER_NETDEV_LINK_1000);1290 1291	if (on & MTK_PHY_LED_ON_FDX)1292		*rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);1293 1294	if (on & MTK_PHY_LED_ON_HDX)1295		*rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);1296 1297	if (blink & MTK_PHY_LED_BLINK_RX)1298		*rules |= BIT(TRIGGER_NETDEV_RX);1299 1300	if (blink & MTK_PHY_LED_BLINK_TX)1301		*rules |= BIT(TRIGGER_NETDEV_TX);1302 1303	return 0;1304};1305 1306static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,1307					 unsigned long rules)1308{1309	unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);1310	struct mtk_socphy_priv *priv = phydev->priv;1311	u16 on = 0, blink = 0;1312	int ret;1313 1314	if (index > 1)1315		return -EINVAL;1316 1317	if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))1318		on |= MTK_PHY_LED_ON_FDX;1319 1320	if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))1321		on |= MTK_PHY_LED_ON_HDX;1322 1323	if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))1324		on |= MTK_PHY_LED_ON_LINK10;1325 1326	if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))1327		on |= MTK_PHY_LED_ON_LINK100;1328 1329	if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))1330		on |= MTK_PHY_LED_ON_LINK1000;1331 1332	if (rules & BIT(TRIGGER_NETDEV_RX)) {1333		blink |= (on & MTK_PHY_LED_ON_LINK) ?1334			  (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |1335			   ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |1336			   ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :1337			  MTK_PHY_LED_BLINK_RX;1338	}1339 1340	if (rules & BIT(TRIGGER_NETDEV_TX)) {1341		blink |= (on & MTK_PHY_LED_ON_LINK) ?1342			  (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |1343			   ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |1344			   ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :1345			  MTK_PHY_LED_BLINK_TX;1346	}1347 1348	if (blink || on)1349		set_bit(bit_netdev, &priv->led_state);1350	else1351		clear_bit(bit_netdev, &priv->led_state);1352 1353	ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?1354				MTK_PHY_LED1_ON_CTRL :1355				MTK_PHY_LED0_ON_CTRL,1356			     MTK_PHY_LED_ON_FDX     |1357			     MTK_PHY_LED_ON_HDX     |1358			     MTK_PHY_LED_ON_LINK,1359			     on);1360 1361	if (ret)1362		return ret;1363 1364	return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?1365				MTK_PHY_LED1_BLINK_CTRL :1366				MTK_PHY_LED0_BLINK_CTRL, blink);1367};1368 1369static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)1370{1371	struct mtk_socphy_shared *priv = phydev->shared->priv;1372	u32 polarities;1373 1374	if (led_num == 0)1375		polarities = ~(priv->boottrap);1376	else1377		polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;1378 1379	if (polarities & BIT(phydev->mdio.addr))1380		return true;1381 1382	return false;1383}1384 1385static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)1386{1387	struct pinctrl *pinctrl;1388	int index;1389 1390	/* Setup LED polarity according to bootstrap use of LED pins */1391	for (index = 0; index < 2; ++index)1392		phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?1393				MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,1394			       MTK_PHY_LED_ON_POLARITY,1395			       mt7988_phy_led_get_polarity(phydev, index) ?1396				MTK_PHY_LED_ON_POLARITY : 0);1397 1398	/* Only now setup pinctrl to avoid bogus blinking */1399	pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");1400	if (IS_ERR(pinctrl))1401		dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");1402 1403	return 0;1404}1405 1406static int mt7988_phy_probe_shared(struct phy_device *phydev)1407{1408	struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);1409	struct mtk_socphy_shared *shared = phydev->shared->priv;1410	struct regmap *regmap;1411	u32 reg;1412	int ret;1413 1414	/* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,1415	 * LED_C and LED_D respectively. At the same time those pins are used to1416	 * bootstrap configuration of the reference clock source (LED_A),1417	 * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).1418	 * In practise this is done using a LED and a resistor pulling the pin1419	 * either to GND or to VIO.1420	 * The detected value at boot time is accessible at run-time using the1421	 * TPBANK0 register located in the gpio base of the pinctrl, in order1422	 * to read it here it needs to be referenced by a phandle called1423	 * 'mediatek,pio' in the MDIO bus hosting the PHY.1424	 * The 4 bits in TPBANK0 are kept as package shared data and are used to1425	 * set LED polarity for each of the LED0.1426	 */1427	regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");1428	if (IS_ERR(regmap))1429		return PTR_ERR(regmap);1430 1431	ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);1432	if (ret)1433		return ret;1434 1435	shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);1436 1437	return 0;1438}1439 1440static void mt798x_phy_leds_state_init(struct phy_device *phydev)1441{1442	int i;1443 1444	for (i = 0; i < 2; ++i)1445		mt798x_phy_led_hw_control_get(phydev, i, NULL);1446}1447 1448static int mt7988_phy_probe(struct phy_device *phydev)1449{1450	struct mtk_socphy_shared *shared;1451	struct mtk_socphy_priv *priv;1452	int err;1453 1454	if (phydev->mdio.addr > 3)1455		return -EINVAL;1456 1457	err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,1458				    sizeof(struct mtk_socphy_shared));1459	if (err)1460		return err;1461 1462	if (phy_package_probe_once(phydev)) {1463		err = mt7988_phy_probe_shared(phydev);1464		if (err)1465			return err;1466	}1467 1468	shared = phydev->shared->priv;1469	priv = &shared->priv[phydev->mdio.addr];1470 1471	phydev->priv = priv;1472 1473	mt798x_phy_leds_state_init(phydev);1474 1475	err = mt7988_phy_fix_leds_polarities(phydev);1476	if (err)1477		return err;1478 1479	/* Disable TX power saving at probing to:1480	 * 1. Meet common mode compliance test criteria1481	 * 2. Make sure that TX-VCM calibration works fine1482	 */1483	phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,1484		       MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);1485 1486	return mt798x_phy_calibration(phydev);1487}1488 1489static int mt7981_phy_probe(struct phy_device *phydev)1490{1491	struct mtk_socphy_priv *priv;1492 1493	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),1494			    GFP_KERNEL);1495	if (!priv)1496		return -ENOMEM;1497 1498	phydev->priv = priv;1499 1500	mt798x_phy_leds_state_init(phydev);1501 1502	return mt798x_phy_calibration(phydev);1503}1504 1505static struct phy_driver mtk_socphy_driver[] = {1506	{1507		PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),1508		.name		= "MediaTek MT7981 PHY",1509		.config_init	= mt798x_phy_config_init,1510		.config_intr	= genphy_no_config_intr,1511		.handle_interrupt = genphy_handle_interrupt_no_ack,1512		.probe		= mt7981_phy_probe,1513		.suspend	= genphy_suspend,1514		.resume		= genphy_resume,1515		.read_page	= mtk_socphy_read_page,1516		.write_page	= mtk_socphy_write_page,1517		.led_blink_set	= mt798x_phy_led_blink_set,1518		.led_brightness_set = mt798x_phy_led_brightness_set,1519		.led_hw_is_supported = mt798x_phy_led_hw_is_supported,1520		.led_hw_control_set = mt798x_phy_led_hw_control_set,1521		.led_hw_control_get = mt798x_phy_led_hw_control_get,1522	},1523	{1524		PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),1525		.name		= "MediaTek MT7988 PHY",1526		.config_init	= mt798x_phy_config_init,1527		.config_intr	= genphy_no_config_intr,1528		.handle_interrupt = genphy_handle_interrupt_no_ack,1529		.probe		= mt7988_phy_probe,1530		.suspend	= genphy_suspend,1531		.resume		= genphy_resume,1532		.read_page	= mtk_socphy_read_page,1533		.write_page	= mtk_socphy_write_page,1534		.led_blink_set	= mt798x_phy_led_blink_set,1535		.led_brightness_set = mt798x_phy_led_brightness_set,1536		.led_hw_is_supported = mt798x_phy_led_hw_is_supported,1537		.led_hw_control_set = mt798x_phy_led_hw_control_set,1538		.led_hw_control_get = mt798x_phy_led_hw_control_get,1539	},1540};1541 1542module_phy_driver(mtk_socphy_driver);1543 1544static struct mdio_device_id __maybe_unused mtk_socphy_tbl[] = {1545	{ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981) },1546	{ PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988) },1547	{ }1548};1549 1550MODULE_DESCRIPTION("MediaTek SoC Gigabit Ethernet PHY driver");1551MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");1552MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");1553MODULE_LICENSE("GPL");1554 1555MODULE_DEVICE_TABLE(mdio, mtk_socphy_tbl);1556