blob: 7a1233a4c3ef97839dc7d1e5e5913b43efcab73e [file] [log] [blame]
developerc50c2352021-12-01 10:45:35 +08001// SPDX-License-Identifier: GPL-2.0+
2#include <linux/bitfield.h>
3#include <linux/module.h>
4#include <linux/nvmem-consumer.h>
developer23021292022-10-21 19:10:10 +08005#include <linux/of_address.h>
developerc50c2352021-12-01 10:45:35 +08006#include <linux/of_platform.h>
developer941468f2023-04-10 15:21:02 +08007#include <linux/pinctrl/consumer.h>
developerc50c2352021-12-01 10:45:35 +08008#include <linux/phy.h>
9
developer043f7b92023-03-13 13:57:36 +080010#define MTK_GPHY_ID_MT7530 0x03a29412
11#define MTK_GPHY_ID_MT7531 0x03a29441
12#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
13#define MTK_GPHY_ID_MT7981 0x03a29461
14#define MTK_GPHY_ID_MT7988 0x03a29481
15#endif
16
developerc50c2352021-12-01 10:45:35 +080017#define MTK_EXT_PAGE_ACCESS 0x1f
18#define MTK_PHY_PAGE_STANDARD 0x0000
19#define MTK_PHY_PAGE_EXTENDED 0x0001
20#define MTK_PHY_PAGE_EXTENDED_2 0x0002
21#define MTK_PHY_PAGE_EXTENDED_3 0x0003
developer7fbc5262023-03-28 23:44:26 +080022/* Registers on Page 3 */
23#define MTK_PHY_LPI_REG_14 (0x14)
24#define MTK_PHY_LPI_WAKE_TIMER_1000_MASK GENMASK(8, 0)
25
26#define MTK_PHY_LPI_REG_1c (0x1c)
27#define MTK_PHY_SMI_DET_ON_THRESH_MASK GENMASK(13, 8)
28/*******************************/
29
developerc50c2352021-12-01 10:45:35 +080030#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
31#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
32
developer2149cd92023-03-10 19:01:41 +080033#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
34#define ZCAL_CTRL_MIN (0)
35#define ZCAL_CTRL_MAX (63)
36#define TXRESERVE_MIN (0)
37#define TXRESERVE_MAX (7)
38
39#define MTK_PHY_ANARG_RG (0x10)
40#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
41
developerc50c2352021-12-01 10:45:35 +080042/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080043enum {
developerf35532c2022-08-05 18:37:26 +080044 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
45 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
46 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
47 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
48 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
49 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
50 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
51 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
52 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
53 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
54 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
55 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
56 MTK_PHY_TX_MLT3_END,
57};
developer02d84422021-12-24 11:48:07 +080058
developer2149cd92023-03-10 19:01:41 +080059#define MTK_PHY_TXVLD_DA_RG (0x12)
developerc50c2352021-12-01 10:45:35 +080060#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
61#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
62
developer2149cd92023-03-10 19:01:41 +080063#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
developerc50c2352021-12-01 10:45:35 +080064#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
65#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
66
developer2149cd92023-03-10 19:01:41 +080067#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
developerc50c2352021-12-01 10:45:35 +080068#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
69#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
70
developer2149cd92023-03-10 19:01:41 +080071#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
developerc50c2352021-12-01 10:45:35 +080072#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
73#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
74
developer2149cd92023-03-10 19:01:41 +080075#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
developerc50c2352021-12-01 10:45:35 +080076#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
77#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
78
developer2149cd92023-03-10 19:01:41 +080079#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
developerc50c2352021-12-01 10:45:35 +080080#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
81#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
82
developer2149cd92023-03-10 19:01:41 +080083#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
developerc50c2352021-12-01 10:45:35 +080084#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
85#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
86
developer2149cd92023-03-10 19:01:41 +080087#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
developerc50c2352021-12-01 10:45:35 +080088#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
89#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
90
developer2149cd92023-03-10 19:01:41 +080091#define MTK_PHY_TANA_CAL_MODE (0xc1)
92#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +080093
developer2149cd92023-03-10 19:01:41 +080094#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
developer57374032022-10-11 16:43:24 +080095#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
96
developer2149cd92023-03-10 19:01:41 +080097#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
98#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
99#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
100#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
101#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +0800102
developer2149cd92023-03-10 19:01:41 +0800103#define MTK_PHY_LDO_OUTPUT_V (0xd7)
developerce268312022-12-20 16:26:11 +0800104
developer2149cd92023-03-10 19:01:41 +0800105#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
106#define MTK_PHY_RG_CAL_CKINV BIT(12)
107#define MTK_PHY_RG_ANA_CALEN BIT(8)
108#define MTK_PHY_RG_REXT_CALEN BIT(4)
109#define MTK_PHY_RG_ZCALEN_A BIT(0)
developerc50c2352021-12-01 10:45:35 +0800110
developer2149cd92023-03-10 19:01:41 +0800111#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
112#define MTK_PHY_RG_ZCALEN_B BIT(12)
113#define MTK_PHY_RG_ZCALEN_C BIT(8)
114#define MTK_PHY_RG_ZCALEN_D BIT(4)
115#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
developerc50c2352021-12-01 10:45:35 +0800116
developer2149cd92023-03-10 19:01:41 +0800117#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
118#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
119#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
120#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
121#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
developerc50c2352021-12-01 10:45:35 +0800122
developer2149cd92023-03-10 19:01:41 +0800123#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
124#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
125#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800126
developer2149cd92023-03-10 19:01:41 +0800127#define MTK_PHY_RG_TX_FILTER (0xfe)
developer6de96aa2022-09-29 16:46:18 +0800128
developer7fbc5262023-03-28 23:44:26 +0800129#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120 (0x120)
130#define MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK GENMASK(12, 8)
131#define MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK GENMASK(4, 0)
132
133#define MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122 (0x122)
134#define MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK GENMASK(7, 0)
135
136#define MTK_PHY_RG_TESTMUX_ADC_CTRL (0x144)
137#define MTK_PHY_RG_TXEN_DIG_MASK GENMASK(5, 5)
138
developer2149cd92023-03-10 19:01:41 +0800139#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B (0x172)
developerc50c2352021-12-01 10:45:35 +0800140#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
141#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
142
developer2149cd92023-03-10 19:01:41 +0800143#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D (0x173)
developerc50c2352021-12-01 10:45:35 +0800144#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
145#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
146
developer2149cd92023-03-10 19:01:41 +0800147#define MTK_PHY_RG_AD_CAL_COMP (0x17a)
148#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +0800149
developer2149cd92023-03-10 19:01:41 +0800150#define MTK_PHY_RG_AD_CAL_CLK (0x17b)
151#define MTK_PHY_DA_CAL_CLK BIT(0)
developerc50c2352021-12-01 10:45:35 +0800152
developer2149cd92023-03-10 19:01:41 +0800153#define MTK_PHY_RG_AD_CALIN (0x17c)
154#define MTK_PHY_DA_CALIN_FLAG BIT(0)
developerc50c2352021-12-01 10:45:35 +0800155
developer2149cd92023-03-10 19:01:41 +0800156#define MTK_PHY_RG_DASN_DAC_IN0_A (0x17d)
developer510f5ed2023-04-10 11:42:19 +0800157#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800158
developer2149cd92023-03-10 19:01:41 +0800159#define MTK_PHY_RG_DASN_DAC_IN0_B (0x17e)
developer510f5ed2023-04-10 11:42:19 +0800160#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800161
developer2149cd92023-03-10 19:01:41 +0800162#define MTK_PHY_RG_DASN_DAC_IN0_C (0x17f)
developer510f5ed2023-04-10 11:42:19 +0800163#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800164
developer2149cd92023-03-10 19:01:41 +0800165#define MTK_PHY_RG_DASN_DAC_IN0_D (0x180)
developer510f5ed2023-04-10 11:42:19 +0800166#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800167
developer2149cd92023-03-10 19:01:41 +0800168#define MTK_PHY_RG_DASN_DAC_IN1_A (0x181)
developer510f5ed2023-04-10 11:42:19 +0800169#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800170
developer2149cd92023-03-10 19:01:41 +0800171#define MTK_PHY_RG_DASN_DAC_IN1_B (0x182)
developer510f5ed2023-04-10 11:42:19 +0800172#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800173
developer2149cd92023-03-10 19:01:41 +0800174#define MTK_PHY_RG_DASN_DAC_IN1_C (0x183)
developer510f5ed2023-04-10 11:42:19 +0800175#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800176
developer7fbc5262023-03-28 23:44:26 +0800177#define MTK_PHY_RG_DASN_DAC_IN1_D (0x184)
developer510f5ed2023-04-10 11:42:19 +0800178#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800179
developer7fbc5262023-03-28 23:44:26 +0800180#define MTK_PHY_RG_DEV1E_REG19b (0x19b)
181#define MTK_PHY_BYPASS_DSP_LPI_READY BIT(8)
182
developer2149cd92023-03-10 19:01:41 +0800183#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
184#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
185#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
186#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
187#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
188#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
189#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
190#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
191#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
192#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
developer75819992023-03-08 20:49:03 +0800193
developer2149cd92023-03-10 19:01:41 +0800194#define MTK_PHY_RG_DEV1E_REG234 (0x234)
195#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
196#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
developer7fbc5262023-03-28 23:44:26 +0800197#define MTK_PHY_TR_LP_IIR_EEE_EN BIT(12)
developerd2ec38e2022-11-27 01:15:29 +0800198
developer2149cd92023-03-10 19:01:41 +0800199#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
developerd2ec38e2022-11-27 01:15:29 +0800200
developer7fbc5262023-03-28 23:44:26 +0800201#define MTK_PHY_RG_DEV1E_REG238 (0x238)
202#define MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK GENMASK(8, 0)
203#define MTK_PHY_LPI_SLV_SEND_TX_EN BIT(12)
204
205#define MTK_PHY_RG_DEV1E_REG239 (0x239)
206#define MTK_PHY_LPI_SEND_LOC_TIMER_MASK GENMASK(8, 0)
207#define MTK_PHY_LPI_TXPCS_LOC_RCV BIT(12)
208
developer2149cd92023-03-10 19:01:41 +0800209#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
developerd2ec38e2022-11-27 01:15:29 +0800210#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
developer2149cd92023-03-10 19:01:41 +0800211#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
developerd2ec38e2022-11-27 01:15:29 +0800212#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800213
developer7fbc5262023-03-28 23:44:26 +0800214#define MTK_PHY_RG_DEV1E_REG2C7 (0x2c7)
215#define MTK_PHY_MAX_GAIN_MASK GENMASK(4, 0)
216#define MTK_PHY_MIN_GAIN_MASK GENMASK(12, 8)
217
218#define MTK_PHY_RG_DEV1E_REG2D1 (0x2d1)
219#define MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK GENMASK(7, 0)
220#define MTK_PHY_LPI_SKIP_SD_SLV_TR BIT(8)
221#define MTK_PHY_LPI_TR_READY BIT(9)
222#define MTK_PHY_LPI_VCO_EEE_STG0_EN BIT(10)
223
224#define MTK_PHY_RG_DEV1E_REG323 (0x323)
225#define MTK_PHY_EEE_WAKE_MAS_INT_DC BIT(0)
226#define MTK_PHY_EEE_WAKE_SLV_INT_DC BIT(4)
227
228#define MTK_PHY_RG_DEV1E_REG324 (0x324)
229#define MTK_PHY_SMI_DETCNT_MAX_MASK GENMASK(5, 0)
230#define MTK_PHY_SMI_DET_MAX_EN BIT(8)
231
232#define MTK_PHY_RG_DEV1E_REG326 (0x326)
233#define MTK_PHY_LPI_MODE_SD_ON BIT(0)
234#define MTK_PHY_RESET_RANDUPD_CNT BIT(1)
235#define MTK_PHY_TREC_UPDATE_ENAB_CLR BIT(2)
236#define MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF BIT(4)
237#define MTK_PHY_TR_READY_SKIP_AFE_WAKEUP BIT(5)
238
developer2149cd92023-03-10 19:01:41 +0800239#define MTK_PHY_LDO_PUMP_EN_PAIRAB (0x502)
240#define MTK_PHY_LDO_PUMP_EN_PAIRCD (0x503)
developer75819992023-03-08 20:49:03 +0800241
developer2149cd92023-03-10 19:01:41 +0800242#define MTK_PHY_DA_TX_R50_PAIR_A (0x53d)
243#define MTK_PHY_DA_TX_R50_PAIR_B (0x53e)
244#define MTK_PHY_DA_TX_R50_PAIR_C (0x53f)
245#define MTK_PHY_DA_TX_R50_PAIR_D (0x540)
developerc50c2352021-12-01 10:45:35 +0800246
247/* Registers on MDIO_MMD_VEND2 */
developer2149cd92023-03-10 19:01:41 +0800248#define MTK_PHY_LED0_ON_CTRL (0x24)
developer23021292022-10-21 19:10:10 +0800249#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
developer2149cd92023-03-10 19:01:41 +0800250#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
251#define MTK_PHY_LED0_ON_LINK100 BIT(1)
252#define MTK_PHY_LED0_ON_LINK10 BIT(2)
253#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
254#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
255#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
256#define MTK_PHY_LED0_FORCE_ON BIT(6)
257#define MTK_PHY_LED0_POLARITY BIT(14)
258#define MTK_PHY_LED0_ENABLE BIT(15)
developer23021292022-10-21 19:10:10 +0800259
developer2149cd92023-03-10 19:01:41 +0800260#define MTK_PHY_LED0_BLINK_CTRL (0x25)
261#define MTK_PHY_LED0_1000TX BIT(0)
262#define MTK_PHY_LED0_1000RX BIT(1)
263#define MTK_PHY_LED0_100TX BIT(2)
264#define MTK_PHY_LED0_100RX BIT(3)
265#define MTK_PHY_LED0_10TX BIT(4)
266#define MTK_PHY_LED0_10RX BIT(5)
267#define MTK_PHY_LED0_COLLISION BIT(6)
268#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
269#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
270#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
developer8bc5dca2022-10-24 17:15:12 +0800271
developer2149cd92023-03-10 19:01:41 +0800272#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
developerc50c2352021-12-01 10:45:35 +0800273#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
274
developer2149cd92023-03-10 19:01:41 +0800275#define MTK_PHY_RG_DASN_TXT_DMY2 (0x110)
276#define MTK_PHY_TST_DMY2_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800277
developer2149cd92023-03-10 19:01:41 +0800278#define MTK_PHY_RG_BG_RASEL (0x115)
279#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +0800280
developer2149cd92023-03-10 19:01:41 +0800281/* These macro privides efuse parsing for internal phy. */
282#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
283#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
284#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
285#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
286#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800287
developer2149cd92023-03-10 19:01:41 +0800288#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
289#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
290#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
291#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
292#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800293
developer2149cd92023-03-10 19:01:41 +0800294#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
295#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
296#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
297#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800298
developer2149cd92023-03-10 19:01:41 +0800299#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
300#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800301
developer2149cd92023-03-10 19:01:41 +0800302enum {
303 NO_PAIR,
developerc50c2352021-12-01 10:45:35 +0800304 PAIR_A,
305 PAIR_B,
306 PAIR_C,
307 PAIR_D,
developer2149cd92023-03-10 19:01:41 +0800308};
developerc50c2352021-12-01 10:45:35 +0800309
developer23021292022-10-21 19:10:10 +0800310enum {
311 GPHY_PORT0,
312 GPHY_PORT1,
313 GPHY_PORT2,
314 GPHY_PORT3,
315};
316
developer2149cd92023-03-10 19:01:41 +0800317enum calibration_mode {
318 EFUSE_K,
319 SW_K
320};
321
322enum CAL_ITEM {
323 REXT,
324 TX_OFFSET,
325 TX_AMP,
326 TX_R50,
327 TX_VCM
328};
329
330enum CAL_MODE {
developer2149cd92023-03-10 19:01:41 +0800331 EFUSE_M,
332 SW_M
333};
334
developerc50c2352021-12-01 10:45:35 +0800335const u8 mt798x_zcal_to_r50[64] = {
336 7, 8, 9, 9, 10, 10, 11, 11,
337 12, 13, 13, 14, 14, 15, 16, 16,
338 17, 18, 18, 19, 20, 21, 21, 22,
339 23, 24, 24, 25, 26, 27, 28, 29,
340 30, 31, 32, 33, 34, 35, 36, 37,
341 38, 40, 41, 42, 43, 45, 46, 48,
342 49, 51, 52, 54, 55, 57, 59, 61,
343 62, 63, 63, 63, 63, 63, 63, 63
344};
345
346const char pair[4] = {'A', 'B', 'C', 'D'};
347
developer2149cd92023-03-10 19:01:41 +0800348static int mtk_gephy_read_page(struct phy_device *phydev)
349{
350 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
351}
developerc50c2352021-12-01 10:45:35 +0800352
developer2149cd92023-03-10 19:01:41 +0800353static int mtk_gephy_write_page(struct phy_device *phydev, int page)
354{
355 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
356}
developerc50c2352021-12-01 10:45:35 +0800357
developer2149cd92023-03-10 19:01:41 +0800358static void mtk_gephy_config_init(struct phy_device *phydev)
359{
360 /* Disable EEE */
361 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
developerc50c2352021-12-01 10:45:35 +0800362
developer2149cd92023-03-10 19:01:41 +0800363 /* Enable HW auto downshift */
364 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
developerc50c2352021-12-01 10:45:35 +0800365
developer2149cd92023-03-10 19:01:41 +0800366 /* Increase SlvDPSready time */
367 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
368 __phy_write(phydev, 0x10, 0xafae);
369 __phy_write(phydev, 0x12, 0x2f);
370 __phy_write(phydev, 0x10, 0x8fae);
371 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerc50c2352021-12-01 10:45:35 +0800372
developer2149cd92023-03-10 19:01:41 +0800373 /* Adjust 100_mse_threshold */
374 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
developerc50c2352021-12-01 10:45:35 +0800375
developer2149cd92023-03-10 19:01:41 +0800376 /* Disable mcc */
377 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
378}
developerc50c2352021-12-01 10:45:35 +0800379
developer2149cd92023-03-10 19:01:41 +0800380static int mt7530_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800381{
developer2149cd92023-03-10 19:01:41 +0800382 mtk_gephy_config_init(phydev);
383
384 /* Increase post_update_timer */
385 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
386
387 return 0;
developerc50c2352021-12-01 10:45:35 +0800388}
389
developer2149cd92023-03-10 19:01:41 +0800390static int mt7531_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800391{
developer2149cd92023-03-10 19:01:41 +0800392 mtk_gephy_config_init(phydev);
393
394 /* PHY link down power saving enable */
395 phy_set_bits(phydev, 0x17, BIT(4));
396 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
397
398 /* Set TX Pair delay selection */
399 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
400 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
401
402 return 0;
developerc50c2352021-12-01 10:45:35 +0800403}
404
developer2149cd92023-03-10 19:01:41 +0800405#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
406/* One calibration cycle consists of:
developerc50c2352021-12-01 10:45:35 +0800407 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
408 * until AD_CAL_COMP is ready to output calibration result.
409 * 2.Wait until DA_CAL_CLK is available.
410 * 3.Fetch AD_CAL_COMP_OUT.
411 */
412static int cal_cycle(struct phy_device *phydev, int devad,
developer2149cd92023-03-10 19:01:41 +0800413 u32 regnum, u16 mask, u16 cal_val)
developerc50c2352021-12-01 10:45:35 +0800414{
415 unsigned long timeout;
416 int reg_val;
417 int ret;
418
419 phy_modify_mmd(phydev, devad, regnum,
developer2149cd92023-03-10 19:01:41 +0800420 mask, cal_val);
421 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
422 MTK_PHY_DA_CALIN_FLAG);
developerc50c2352021-12-01 10:45:35 +0800423
424 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
developer2149cd92023-03-10 19:01:41 +0800425 do {
426 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
427 MTK_PHY_RG_AD_CAL_CLK);
428 } while (time_before(jiffies, timeout) && !(reg_val & BIT(0)));
developerc50c2352021-12-01 10:45:35 +0800429
developer2149cd92023-03-10 19:01:41 +0800430 if (!(reg_val & BIT(0))) {
developerc50c2352021-12-01 10:45:35 +0800431 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
432 return -ETIMEDOUT;
433 }
434
developer2149cd92023-03-10 19:01:41 +0800435 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
436 MTK_PHY_DA_CALIN_FLAG);
437 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
438 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
developerc50c2352021-12-01 10:45:35 +0800439 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
440
441 return ret;
442}
443
444static int rext_fill_result(struct phy_device *phydev, u16 *buf)
445{
446 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800447 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
448 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
449 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
developerc50c2352021-12-01 10:45:35 +0800450
451 return 0;
452}
453
454static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
455{
456 u16 rext_cal_val[2];
457
458 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
459 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
460 rext_fill_result(phydev, rext_cal_val);
461
462 return 0;
463}
464
developerc50c2352021-12-01 10:45:35 +0800465static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
466{
developer2149cd92023-03-10 19:01:41 +0800467 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800468 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
developer2149cd92023-03-10 19:01:41 +0800469 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800470 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
developer2149cd92023-03-10 19:01:41 +0800471 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800472 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
developer2149cd92023-03-10 19:01:41 +0800473 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800474 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
475
476 return 0;
477}
478
479static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
480{
481 u16 tx_offset_cal_val[4];
482
483 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
484 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
485 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
486 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
487
488 tx_offset_fill_result(phydev, tx_offset_cal_val);
489
490 return 0;
491}
492
493static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
494{
developerd2ec38e2022-11-27 01:15:29 +0800495 int i;
developer87c89d12022-08-19 17:46:34 +0800496 int bias[16] = {0};
developer2149cd92023-03-10 19:01:41 +0800497 const int vals_9461[16] = { 7, 1, 4, 7,
498 7, 1, 4, 7,
499 7, 1, 4, 7,
500 7, 1, 4, 7 };
501 const int vals_9481[16] = { 10, 6, 6, 10,
502 10, 6, 6, 10,
503 10, 6, 6, 10,
504 10, 6, 6, 10 };
505
506 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800507 case MTK_GPHY_ID_MT7981:
developer2149cd92023-03-10 19:01:41 +0800508 /* We add some calibration to efuse values
509 * due to board level influence.
510 * GBE: +7, TBT: +1, HBT: +4, TST: +7
511 */
512 memcpy(bias, (const void *)vals_9461, sizeof(bias));
developer2149cd92023-03-10 19:01:41 +0800513 break;
developer043f7b92023-03-13 13:57:36 +0800514 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800515 memcpy(bias, (const void *)vals_9481, sizeof(bias));
516 break;
517 default:
518 break;
developer87c89d12022-08-19 17:46:34 +0800519 }
developerd2ec38e2022-11-27 01:15:29 +0800520
developerdc3e9502022-12-02 18:10:42 +0800521 /* Prevent overflow */
522 for (i = 0; i < 12; i++) {
developer2149cd92023-03-10 19:01:41 +0800523 if (buf[i >> 2] + bias[i] > 63) {
524 buf[i >> 2] = 63;
developerdc3e9502022-12-02 18:10:42 +0800525 bias[i] = 0;
developer2149cd92023-03-10 19:01:41 +0800526 } else if (buf[i >> 2] + bias[i] < 0) {
developerdc3e9502022-12-02 18:10:42 +0800527 /* Bias caused by board design may change in the future.
528 * So check negative cases, too.
529 */
developer2149cd92023-03-10 19:01:41 +0800530 buf[i >> 2] = 0;
developerdc3e9502022-12-02 18:10:42 +0800531 bias[i] = 0;
532 }
533 }
534
developerc50c2352021-12-01 10:45:35 +0800535 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800536 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800537 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800538 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800539 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800540 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800541 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800542 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800543
544 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800545 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800546 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800547 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800548 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800549 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800550 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800551 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800552
553 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800554 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800555 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800556 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800557 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800558 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800559 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800560 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800561
562 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800563 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800564 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800565 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800566 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800567 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800568 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800569 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800570
571 return 0;
572}
573
574static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
575{
576 u16 tx_amp_cal_val[4];
577
578 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
579 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
580 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
581 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
582 tx_amp_fill_result(phydev, tx_amp_cal_val);
583
584 return 0;
585}
586
developer2149cd92023-03-10 19:01:41 +0800587static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
588 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800589{
developer2149cd92023-03-10 19:01:41 +0800590 int bias = 0;
591 u16 reg, val;
developer87c89d12022-08-19 17:46:34 +0800592
developer2149cd92023-03-10 19:01:41 +0800593 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800594 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800595 {
596 bias = -2;
597 break;
developerdc3e9502022-12-02 18:10:42 +0800598 }
developer043f7b92023-03-13 13:57:36 +0800599 /* MTK_GPHY_ID_MT7981 enters default case */
developer2149cd92023-03-10 19:01:41 +0800600 default:
601 break;
602 }
603
604 val = clamp_val(bias + tx_r50_cal_val, 0, 63);
605
606 switch (txg_calen_x) {
607 case PAIR_A:
608 reg = MTK_PHY_DA_TX_R50_PAIR_A;
609 break;
610 case PAIR_B:
611 reg = MTK_PHY_DA_TX_R50_PAIR_B;
612 break;
613 case PAIR_C:
614 reg = MTK_PHY_DA_TX_R50_PAIR_C;
615 break;
616 case PAIR_D:
617 reg = MTK_PHY_DA_TX_R50_PAIR_D;
618 break;
developerc50c2352021-12-01 10:45:35 +0800619 }
developer2149cd92023-03-10 19:01:41 +0800620
621 phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
622
developerc50c2352021-12-01 10:45:35 +0800623 return 0;
624}
625
626static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
developer2149cd92023-03-10 19:01:41 +0800627 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800628{
developer2149cd92023-03-10 19:01:41 +0800629 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800630
developer2149cd92023-03-10 19:01:41 +0800631 switch (txg_calen_x) {
632 case PAIR_A:
633 tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
634 break;
635 case PAIR_B:
636 tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
637 break;
638 case PAIR_C:
639 tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
640 break;
641 case PAIR_D:
642 tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
643 break;
developerc50c2352021-12-01 10:45:35 +0800644 }
645 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
646
647 return 0;
648}
649
developer2149cd92023-03-10 19:01:41 +0800650static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
developerc50c2352021-12-01 10:45:35 +0800651{
652 u8 lower_idx, upper_idx, txreserve_val;
653 u8 lower_ret, upper_ret;
654 int ret;
655
656 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800657 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800658 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800659 MTK_PHY_RG_CAL_CKINV);
developerc50c2352021-12-01 10:45:35 +0800660 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800661 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800662
developer2149cd92023-03-10 19:01:41 +0800663 switch (rg_txreserve_x) {
664 case PAIR_A:
developer510f5ed2023-04-10 11:42:19 +0800665 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
666 MTK_PHY_RG_DASN_DAC_IN0_A,
667 MTK_PHY_DASN_DAC_IN0_A_MASK);
668 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
669 MTK_PHY_RG_DASN_DAC_IN1_A,
670 MTK_PHY_DASN_DAC_IN1_A_MASK);
developer2149cd92023-03-10 19:01:41 +0800671 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
672 MTK_PHY_RG_ANA_CAL_RG0,
673 MTK_PHY_RG_ZCALEN_A);
674 break;
675 case PAIR_B:
developer510f5ed2023-04-10 11:42:19 +0800676 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
677 MTK_PHY_RG_DASN_DAC_IN0_B,
678 MTK_PHY_DASN_DAC_IN0_B_MASK);
679 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
680 MTK_PHY_RG_DASN_DAC_IN1_B,
681 MTK_PHY_DASN_DAC_IN1_B_MASK);
developer2149cd92023-03-10 19:01:41 +0800682 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
683 MTK_PHY_RG_ANA_CAL_RG1,
684 MTK_PHY_RG_ZCALEN_B);
685 break;
686 case PAIR_C:
developer510f5ed2023-04-10 11:42:19 +0800687 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
688 MTK_PHY_RG_DASN_DAC_IN0_C,
689 MTK_PHY_DASN_DAC_IN0_C_MASK);
690 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
691 MTK_PHY_RG_DASN_DAC_IN1_C,
692 MTK_PHY_DASN_DAC_IN1_C_MASK);
developer2149cd92023-03-10 19:01:41 +0800693 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
694 MTK_PHY_RG_ANA_CAL_RG1,
695 MTK_PHY_RG_ZCALEN_C);
696 break;
697 case PAIR_D:
developer510f5ed2023-04-10 11:42:19 +0800698 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
699 MTK_PHY_RG_DASN_DAC_IN0_D,
700 MTK_PHY_DASN_DAC_IN0_D_MASK);
701 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
702 MTK_PHY_RG_DASN_DAC_IN1_D,
703 MTK_PHY_DASN_DAC_IN1_D_MASK);
developer2149cd92023-03-10 19:01:41 +0800704 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
705 MTK_PHY_RG_ANA_CAL_RG1,
706 MTK_PHY_RG_ZCALEN_D);
707 break;
708 default:
709 ret = -EINVAL;
710 goto restore;
developerc50c2352021-12-01 10:45:35 +0800711 }
712
713 lower_idx = TXRESERVE_MIN;
714 upper_idx = TXRESERVE_MAX;
715
716 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800717 while ((upper_idx - lower_idx) > 1) {
718 txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
developerc50c2352021-12-01 10:45:35 +0800719 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800720 MTK_PHY_DA_RX_PSBN_TBT_MASK |
721 MTK_PHY_DA_RX_PSBN_HBT_MASK |
722 MTK_PHY_DA_RX_PSBN_GBE_MASK |
723 MTK_PHY_DA_RX_PSBN_LP_MASK,
developerc50c2352021-12-01 10:45:35 +0800724 txreserve_val << 12 | txreserve_val << 8 |
725 txreserve_val << 4 | txreserve_val);
developer2149cd92023-03-10 19:01:41 +0800726 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800727 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800728 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800729 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800730 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800731 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800732 } else {
developerc50c2352021-12-01 10:45:35 +0800733 goto restore;
developer2149cd92023-03-10 19:01:41 +0800734 }
developerc50c2352021-12-01 10:45:35 +0800735 }
736
developer2149cd92023-03-10 19:01:41 +0800737 if (lower_idx == TXRESERVE_MIN) {
738 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
739 MTK_PHY_RXADC_CTRL_RG9,
740 MTK_PHY_DA_RX_PSBN_TBT_MASK |
741 MTK_PHY_DA_RX_PSBN_HBT_MASK |
742 MTK_PHY_DA_RX_PSBN_GBE_MASK |
743 MTK_PHY_DA_RX_PSBN_LP_MASK,
744 lower_idx << 12 | lower_idx << 8 |
745 lower_idx << 4 | lower_idx);
746 ret = lower_ret;
747 } else if (upper_idx == TXRESERVE_MAX) {
748 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
749 MTK_PHY_RXADC_CTRL_RG9,
750 MTK_PHY_DA_RX_PSBN_TBT_MASK |
751 MTK_PHY_DA_RX_PSBN_HBT_MASK |
752 MTK_PHY_DA_RX_PSBN_GBE_MASK |
753 MTK_PHY_DA_RX_PSBN_LP_MASK,
754 upper_idx << 12 | upper_idx << 8 |
755 upper_idx << 4 | upper_idx);
756 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800757 }
758 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800759 goto restore;
760
developer78aa7b92021-12-29 15:22:10 +0800761 /* We calibrate TX-VCM in different logic. Check upper index and then
762 * lower index. If this calibration is valid, apply lower index's result.
763 */
developer2149cd92023-03-10 19:01:41 +0800764 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800765 if (ret == 1) {
766 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800767 /* Make sure we use upper_idx in our calibration system */
768 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800769 MTK_PHY_DA_RX_PSBN_TBT_MASK |
770 MTK_PHY_DA_RX_PSBN_HBT_MASK |
771 MTK_PHY_DA_RX_PSBN_GBE_MASK |
772 MTK_PHY_DA_RX_PSBN_LP_MASK,
773 upper_idx << 12 | upper_idx << 8 |
774 upper_idx << 4 | upper_idx);
775 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n",
776 upper_idx);
777 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
778 lower_ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800779 ret = 0;
780 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800781 MTK_PHY_DA_RX_PSBN_TBT_MASK |
782 MTK_PHY_DA_RX_PSBN_HBT_MASK |
783 MTK_PHY_DA_RX_PSBN_GBE_MASK |
784 MTK_PHY_DA_RX_PSBN_LP_MASK,
785 lower_idx << 12 | lower_idx << 8 |
786 lower_idx << 4 | lower_idx);
787 dev_warn(&phydev->mdio.dev,
788 "TX-VCM SW cal result at low margin 0x%x\n",
789 lower_idx);
790 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
791 lower_ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800792 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800793 dev_warn(&phydev->mdio.dev,
794 "TX-VCM SW cal result at high margin 0x%x\n",
795 upper_idx);
796 } else {
developerc50c2352021-12-01 10:45:35 +0800797 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800798 }
developerc50c2352021-12-01 10:45:35 +0800799
800restore:
801 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800802 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800803 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800804 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800805 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800806 MTK_PHY_RG_ZCALEN_A);
developerc50c2352021-12-01 10:45:35 +0800807 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800808 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
809 MTK_PHY_RG_ZCALEN_D);
developerc50c2352021-12-01 10:45:35 +0800810
811 return ret;
812}
813
developerdd598562023-03-28 23:57:03 +0800814static inline void mt798x_phy_common_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800815{
developerd2ec38e2022-11-27 01:15:29 +0800816 u32 i;
developer2149cd92023-03-10 19:01:41 +0800817
developerdd598562023-03-28 23:57:03 +0800818 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
819 /* EnabRandUpdTrig = 1 */
820 __phy_write(phydev, 0x11, 0x2f00);
821 __phy_write(phydev, 0x12, 0xe);
822 __phy_write(phydev, 0x10, 0x8fb0);
823
824 /* NormMseLoThresh = 85 */
825 __phy_write(phydev, 0x11, 0x55a0);
826 __phy_write(phydev, 0x12, 0x0);
827 __phy_write(phydev, 0x10, 0x83aa);
828
developer7d141402023-04-06 20:10:38 +0800829 /* TrFreeze = 0 */
830 __phy_write(phydev, 0x11, 0x0);
831 __phy_write(phydev, 0x12, 0x0);
832 __phy_write(phydev, 0x10, 0x9686);
833
developerdd598562023-03-28 23:57:03 +0800834 /* SSTrKp1000Slv = 5 */
835 __phy_write(phydev, 0x11, 0xbaef);
836 __phy_write(phydev, 0x12, 0x2e);
837 __phy_write(phydev, 0x10, 0x968c);
838
839 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
840 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
841 */
842 __phy_write(phydev, 0x11, 0xd10a);
843 __phy_write(phydev, 0x12, 0x34);
844 __phy_write(phydev, 0x10, 0x8f82);
845
846 /* VcoSlicerThreshBitsHigh */
847 __phy_write(phydev, 0x11, 0x5555);
848 __phy_write(phydev, 0x12, 0x55);
849 __phy_write(phydev, 0x10, 0x8ec0);
850 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
851
developer50fe2af2023-03-31 18:32:24 +0800852 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
853 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
854 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
855 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
856
developerdd598562023-03-28 23:57:03 +0800857 /* rg_tr_lpf_cnt_val = 512 */
858 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
859
860 /* IIR2 related */
861 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
862 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
863 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
864 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
865 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
866 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
867 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
868 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
869 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
870 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
871
872 /* FFE peaking */
873 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
874 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
875 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
876 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
877
developerdd598562023-03-28 23:57:03 +0800878 /* Disable LDO pump */
879 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
880 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
881 /* Adjust LDO output voltage */
882 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
883}
884
885static inline void mt7981_phy_finetune(struct phy_device *phydev)
886{
developer02d84422021-12-24 11:48:07 +0800887 /* 100M eye finetune:
888 * Keep middle level of TX MLT3 shapper as default.
889 * Only change TX MLT3 overshoot level here.
890 */
developer2149cd92023-03-10 19:01:41 +0800891 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
892 0x1ce);
893 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
894 0x1c1);
895 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
896 0x20f);
897 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
898 0x202);
899 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
900 0x3d0);
901 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
902 0x3c0);
903 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
904 0x13);
905 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
906 0x5);
developerf35532c2022-08-05 18:37:26 +0800907
developerd2ec38e2022-11-27 01:15:29 +0800908 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developer7fbc5262023-03-28 23:44:26 +0800909 /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
910 __phy_write(phydev, 0x11, 0xc71);
developerd2ec38e2022-11-27 01:15:29 +0800911 __phy_write(phydev, 0x12, 0xc);
912 __phy_write(phydev, 0x10, 0x8fae);
913
developerd2ec38e2022-11-27 01:15:29 +0800914 /* ResetSyncOffset = 6 */
915 __phy_write(phydev, 0x11, 0x600);
916 __phy_write(phydev, 0x12, 0x0);
917 __phy_write(phydev, 0x10, 0x8fc0);
918
919 /* VgaDecRate = 1 */
920 __phy_write(phydev, 0x11, 0x4c2a);
921 __phy_write(phydev, 0x12, 0x3e);
922 __phy_write(phydev, 0x10, 0x8fa4);
923
developer7fbc5262023-03-28 23:44:26 +0800924 /* FfeUpdGainForce = 4 */
925 __phy_write(phydev, 0x11, 0x240);
926 __phy_write(phydev, 0x12, 0x0);
927 __phy_write(phydev, 0x10, 0x9680);
928
developerd2ec38e2022-11-27 01:15:29 +0800929 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developer02d84422021-12-24 11:48:07 +0800930}
931
developerf35532c2022-08-05 18:37:26 +0800932static inline void mt7988_phy_finetune(struct phy_device *phydev)
933{
developer2149cd92023-03-10 19:01:41 +0800934 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
935 0x020d, 0x0206, 0x0384, 0x03d0,
936 0x03c6, 0x030a, 0x0011, 0x0005 };
developerf35532c2022-08-05 18:37:26 +0800937 int i;
developerf35532c2022-08-05 18:37:26 +0800938
developer2149cd92023-03-10 19:01:41 +0800939 for (i = 0; i < MTK_PHY_TX_MLT3_END; i++)
developerf35532c2022-08-05 18:37:26 +0800940 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
developer6de96aa2022-09-29 16:46:18 +0800941
developer57374032022-10-11 16:43:24 +0800942 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800943 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800944
945 /* Disable TX power saving */
946 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developer2149cd92023-03-10 19:01:41 +0800947 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +0800948
developerec2b8552022-10-17 15:30:59 +0800949 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +0800950
developer7fbc5262023-03-28 23:44:26 +0800951 /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
developerce73ad62022-12-07 22:43:45 +0800952 __phy_write(phydev, 0x11, 0x671);
953 __phy_write(phydev, 0x12, 0xc);
954 __phy_write(phydev, 0x10, 0x8fae);
955
developerce268312022-12-20 16:26:11 +0800956 /* ResetSyncOffset = 5 */
957 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +0800958 __phy_write(phydev, 0x12, 0x0);
959 __phy_write(phydev, 0x10, 0x8fc0);
developer50fe2af2023-03-31 18:32:24 +0800960
961 /* VgaDecRate is 1 at default on mt7988 */
962
developerb5c72b02022-12-21 15:51:07 +0800963 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +0800964
developerce268312022-12-20 16:26:11 +0800965 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
966 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +0800967 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developer2149cd92023-03-10 19:01:41 +0800968 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +0800969 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developer2149cd92023-03-10 19:01:41 +0800970}
developer75819992023-03-08 20:49:03 +0800971
developer7fbc5262023-03-28 23:44:26 +0800972static inline void mt798x_phy_eee(struct phy_device *phydev)
973{
974 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +0800975 MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG120,
976 MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK |
977 MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK,
978 FIELD_PREP(MTK_PHY_LPI_SIG_EN_LO_THRESH1000_MASK, 0x0) |
979 FIELD_PREP(MTK_PHY_LPI_SIG_EN_HI_THRESH1000_MASK, 0x14));
developer7fbc5262023-03-28 23:44:26 +0800980
981 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +0800982 MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
983 MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
984 FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
985 0xff));
developer7fbc5262023-03-28 23:44:26 +0800986
987 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +0800988 MTK_PHY_RG_TESTMUX_ADC_CTRL,
989 MTK_PHY_RG_TXEN_DIG_MASK);
developer7fbc5262023-03-28 23:44:26 +0800990
991 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +0800992 MTK_PHY_RG_DEV1E_REG19b, MTK_PHY_BYPASS_DSP_LPI_READY);
developer7fbc5262023-03-28 23:44:26 +0800993
994 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +0800995 MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_LP_IIR_EEE_EN);
developer7fbc5262023-03-28 23:44:26 +0800996
997 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG238,
developer7fa37692023-03-29 17:05:33 +0800998 MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK |
999 MTK_PHY_LPI_SLV_SEND_TX_EN,
1000 FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
developer7fbc5262023-03-28 23:44:26 +08001001
1002 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
developer7fa37692023-03-29 17:05:33 +08001003 MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
1004 MTK_PHY_LPI_TXPCS_LOC_RCV,
1005 FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
developer7fbc5262023-03-28 23:44:26 +08001006
1007 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
developer7fa37692023-03-29 17:05:33 +08001008 MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
1009 FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
1010 FIELD_PREP(MTK_PHY_MIN_GAIN_MASK, 0x13));
developer7fbc5262023-03-28 23:44:26 +08001011
1012 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2D1,
developer7fa37692023-03-29 17:05:33 +08001013 MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
1014 FIELD_PREP(MTK_PHY_VCO_SLICER_THRESH_BITS_HIGH_EEE_MASK,
1015 0x33) |
1016 MTK_PHY_LPI_SKIP_SD_SLV_TR | MTK_PHY_LPI_TR_READY |
1017 MTK_PHY_LPI_VCO_EEE_STG0_EN);
developer7fbc5262023-03-28 23:44:26 +08001018
1019 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG323,
developer7fa37692023-03-29 17:05:33 +08001020 MTK_PHY_EEE_WAKE_MAS_INT_DC |
1021 MTK_PHY_EEE_WAKE_SLV_INT_DC);
developer7fbc5262023-03-28 23:44:26 +08001022
1023 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG324,
developer7fa37692023-03-29 17:05:33 +08001024 MTK_PHY_SMI_DETCNT_MAX_MASK,
1025 FIELD_PREP(MTK_PHY_SMI_DETCNT_MAX_MASK, 0x3f) |
1026 MTK_PHY_SMI_DET_MAX_EN);
developer7fbc5262023-03-28 23:44:26 +08001027
1028 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG326,
developer7fa37692023-03-29 17:05:33 +08001029 MTK_PHY_LPI_MODE_SD_ON | MTK_PHY_RESET_RANDUPD_CNT |
1030 MTK_PHY_TREC_UPDATE_ENAB_CLR |
1031 MTK_PHY_LPI_QUIT_WAIT_DFE_SIG_DET_OFF |
1032 MTK_PHY_TR_READY_SKIP_AFE_WAKEUP);
developer7fbc5262023-03-28 23:44:26 +08001033
1034 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
1035 /* Regsigdet_sel_1000 = 0 */
1036 __phy_write(phydev, 0x11, 0xb);
1037 __phy_write(phydev, 0x12, 0x0);
1038 __phy_write(phydev, 0x10, 0x9690);
1039
1040 /* REG_EEE_st2TrKf1000 = 3 */
1041 __phy_write(phydev, 0x11, 0x114f);
1042 __phy_write(phydev, 0x12, 0x2);
1043 __phy_write(phydev, 0x10, 0x969a);
1044
1045 /* RegEEE_slv_wake_tr_timer_tar = 6, RegEEE_slv_remtx_timer_tar = 20 */
1046 __phy_write(phydev, 0x11, 0x3028);
1047 __phy_write(phydev, 0x12, 0x0);
1048 __phy_write(phydev, 0x10, 0x969e);
1049
1050 /* RegEEE_slv_wake_int_timer_tar = 8 */
1051 __phy_write(phydev, 0x11, 0x5010);
1052 __phy_write(phydev, 0x12, 0x0);
1053 __phy_write(phydev, 0x10, 0x96a0);
1054
1055 /* RegEEE_trfreeze_timer2 = 586 */
1056 __phy_write(phydev, 0x11, 0x24a);
1057 __phy_write(phydev, 0x12, 0x0);
1058 __phy_write(phydev, 0x10, 0x96a8);
1059
1060 /* RegEEE100Stg1_tar = 16 */
1061 __phy_write(phydev, 0x11, 0x3210);
1062 __phy_write(phydev, 0x12, 0x0);
1063 __phy_write(phydev, 0x10, 0x96b8);
1064
1065 /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
1066 __phy_write(phydev, 0x11, 0x1463);
1067 __phy_write(phydev, 0x12, 0x0);
1068 __phy_write(phydev, 0x10, 0x96ca);
1069
1070 /* DfeTailEnableVgaThresh1000 = 27 */
developer7d141402023-04-06 20:10:38 +08001071 __phy_write(phydev, 0x11, 0x36);
developer7fbc5262023-03-28 23:44:26 +08001072 __phy_write(phydev, 0x12, 0x0);
1073 __phy_write(phydev, 0x10, 0x8f80);
1074 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
1075
1076 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_3);
1077 __phy_modify(phydev, MTK_PHY_LPI_REG_14, MTK_PHY_LPI_WAKE_TIMER_1000_MASK,
developer7fa37692023-03-29 17:05:33 +08001078 FIELD_PREP(MTK_PHY_LPI_WAKE_TIMER_1000_MASK, 0x19c));
developer7fbc5262023-03-28 23:44:26 +08001079
1080 __phy_modify(phydev, MTK_PHY_LPI_REG_1c, MTK_PHY_SMI_DET_ON_THRESH_MASK,
developer7fa37692023-03-29 17:05:33 +08001081 FIELD_PREP(MTK_PHY_SMI_DET_ON_THRESH_MASK, 0xc));
developer7fbc5262023-03-28 23:44:26 +08001082 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
1083
1084 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
developer7fa37692023-03-29 17:05:33 +08001085 MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG122,
1086 MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK,
1087 FIELD_PREP(MTK_PHY_LPI_NORM_MSE_HI_THRESH1000_MASK, 0xff));
developer7fbc5262023-03-28 23:44:26 +08001088}
1089
developer2149cd92023-03-10 19:01:41 +08001090static inline int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
1091 u8 start_pair, u8 end_pair)
1092{
1093 u8 pair_n;
1094 int ret;
1095
1096 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1097 /* TX_OFFSET & TX_AMP have no SW calibration. */
1098 switch (cal_item) {
developer2149cd92023-03-10 19:01:41 +08001099 case TX_VCM:
1100 ret = tx_vcm_cal_sw(phydev, pair_n);
1101 break;
1102 default:
1103 return -EINVAL;
1104 }
1105 if (ret)
1106 return ret;
1107 }
1108 return 0;
developerf35532c2022-08-05 18:37:26 +08001109}
1110
developer2149cd92023-03-10 19:01:41 +08001111static inline int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
1112 u8 start_pair, u8 end_pair, u32 *buf)
1113{
1114 u8 pair_n;
1115 int ret;
1116
1117 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1118 /* TX_VCM has no efuse calibration. */
1119 switch (cal_item) {
1120 case REXT:
1121 ret = rext_cal_efuse(phydev, buf);
1122 break;
1123 case TX_OFFSET:
1124 ret = tx_offset_cal_efuse(phydev, buf);
1125 break;
1126 case TX_AMP:
1127 ret = tx_amp_cal_efuse(phydev, buf);
1128 break;
1129 case TX_R50:
1130 ret = tx_r50_cal_efuse(phydev, buf, pair_n);
1131 break;
1132 default:
1133 return -EINVAL;
1134 }
1135 if (ret)
1136 return ret;
1137 }
1138
1139 return 0;
1140}
1141
1142static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
developerc7b857b2023-03-28 22:37:02 +08001143 enum CAL_MODE cal_mode, u8 start_pair,
developer2149cd92023-03-10 19:01:41 +08001144 u8 end_pair, u32 *buf)
1145{
developerc7b857b2023-03-28 22:37:02 +08001146 int ret;
developer2149cd92023-03-10 19:01:41 +08001147 char cal_prop[5][20] = { "mediatek,rext", "mediatek,tx_offset",
1148 "mediatek,tx_amp", "mediatek,tx_r50",
1149 "mediatek,tx_vcm" };
developer2149cd92023-03-10 19:01:41 +08001150
1151 switch (cal_mode) {
developer2149cd92023-03-10 19:01:41 +08001152 case EFUSE_M:
developerc7b857b2023-03-28 22:37:02 +08001153 ret = cal_efuse(phydev, cal_item, start_pair,
developer7fa37692023-03-29 17:05:33 +08001154 end_pair, buf);
developer2149cd92023-03-10 19:01:41 +08001155 break;
1156 case SW_M:
developerc7b857b2023-03-28 22:37:02 +08001157 ret = cal_sw(phydev, cal_item, start_pair, end_pair);
developer2149cd92023-03-10 19:01:41 +08001158 break;
1159 default:
1160 return -EINVAL;
1161 }
1162
developerc7b857b2023-03-28 22:37:02 +08001163 if (ret) {
developer2149cd92023-03-10 19:01:41 +08001164 dev_err(&phydev->mdio.dev, "[%s]cal failed\n", cal_prop[cal_item]);
1165 return -EIO;
1166 }
1167
developer2149cd92023-03-10 19:01:41 +08001168 return 0;
1169}
1170
developerf35532c2022-08-05 18:37:26 +08001171static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001172{
developer2149cd92023-03-10 19:01:41 +08001173 int ret = 0;
developerc50c2352021-12-01 10:45:35 +08001174 u32 *buf;
developerc50c2352021-12-01 10:45:35 +08001175 size_t len;
1176 struct nvmem_cell *cell;
1177
1178 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1179 return -EINVAL;
1180
1181 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1182 if (IS_ERR(cell)) {
1183 if (PTR_ERR(cell) == -EPROBE_DEFER)
1184 return PTR_ERR(cell);
1185 return 0;
1186 }
1187
1188 buf = (u32 *)nvmem_cell_read(cell, &len);
1189 if (IS_ERR(buf))
1190 return PTR_ERR(buf);
1191 nvmem_cell_put(cell);
1192
developerc7b857b2023-03-28 22:37:02 +08001193 if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
1194 dev_err(&phydev->mdio.dev, "invalid efuse data\n");
developerc50c2352021-12-01 10:45:35 +08001195 ret = -EINVAL;
1196 goto out;
1197 }
1198
developerc7b857b2023-03-28 22:37:02 +08001199 ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001200 if (ret)
1201 goto out;
developer7fa37692023-03-29 17:05:33 +08001202 ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001203 if (ret)
1204 goto out;
developerc7b857b2023-03-28 22:37:02 +08001205 ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001206 if (ret)
1207 goto out;
developerc7b857b2023-03-28 22:37:02 +08001208 ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
developer2149cd92023-03-10 19:01:41 +08001209 if (ret)
1210 goto out;
developerc7b857b2023-03-28 22:37:02 +08001211 ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
developer2149cd92023-03-10 19:01:41 +08001212 if (ret)
1213 goto out;
developerc50c2352021-12-01 10:45:35 +08001214
1215out:
1216 kfree(buf);
1217 return ret;
1218}
1219
developer68f6e102022-11-22 17:35:00 +08001220static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001221{
developerdd598562023-03-28 23:57:03 +08001222 mt798x_phy_common_finetune(phydev);
developerf35532c2022-08-05 18:37:26 +08001223 mt7981_phy_finetune(phydev);
developer7fbc5262023-03-28 23:44:26 +08001224 mt798x_phy_eee(phydev);
developerf35532c2022-08-05 18:37:26 +08001225
1226 return mt798x_phy_calibration(phydev);
1227}
1228
developer68f6e102022-11-22 17:35:00 +08001229static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001230{
developer941468f2023-04-10 15:21:02 +08001231 struct device_node *np;
1232 void __iomem *boottrap;
1233 u32 reg;
1234 int port;
1235 int ret;
1236 struct pinctrl *pinctrl;
1237
1238 /* Setup LED polarity according to boottrap's polarity */
1239 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1240 if (!np)
1241 return -ENOENT;
1242 boottrap = of_iomap(np, 0);
1243 if (!boottrap)
1244 return -ENOMEM;
1245 reg = readl(boottrap);
1246 port = phydev->mdio.addr;
1247 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1248 (port == GPHY_PORT1 && reg & BIT(9)) ||
1249 (port == GPHY_PORT2 && reg & BIT(10)) ||
1250 (port == GPHY_PORT3 && reg & BIT(11))) {
1251 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1252 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1253 MTK_PHY_LED0_ON_LINK100 |
1254 MTK_PHY_LED0_ON_LINK1000);
1255 } else {
1256 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1257 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1258 MTK_PHY_LED0_ON_LINK10 |
1259 MTK_PHY_LED0_ON_LINK100 |
1260 MTK_PHY_LED0_ON_LINK1000);
1261 }
1262 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1263 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1264 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1265 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
1266
1267 if (port == GPHY_PORT3) {
1268 pinctrl = devm_pinctrl_get_select_default(&phydev->mdio.bus->dev);
1269 if (IS_ERR(pinctrl)) {
1270 ret = PTR_ERR(pinctrl);
1271 dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
1272 return -EINVAL;
1273 }
1274 }
1275
developerdd598562023-03-28 23:57:03 +08001276 mt798x_phy_common_finetune(phydev);
developerf35532c2022-08-05 18:37:26 +08001277 mt7988_phy_finetune(phydev);
developer7fbc5262023-03-28 23:44:26 +08001278 mt798x_phy_eee(phydev);
developerf35532c2022-08-05 18:37:26 +08001279
1280 return mt798x_phy_calibration(phydev);
1281}
developer2149cd92023-03-10 19:01:41 +08001282#endif
developerf35532c2022-08-05 18:37:26 +08001283
developerc50c2352021-12-01 10:45:35 +08001284static struct phy_driver mtk_gephy_driver[] = {
developerc50c2352021-12-01 10:45:35 +08001285 {
developer043f7b92023-03-13 13:57:36 +08001286 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
developerc50c2352021-12-01 10:45:35 +08001287 .name = "MediaTek MT7530 PHY",
1288 .config_init = mt7530_phy_config_init,
1289 /* Interrupts are handled by the switch, not the PHY
1290 * itself.
1291 */
1292 .config_intr = genphy_no_config_intr,
1293 .handle_interrupt = genphy_no_ack_interrupt,
1294 .suspend = genphy_suspend,
1295 .resume = genphy_resume,
1296 .read_page = mtk_gephy_read_page,
1297 .write_page = mtk_gephy_write_page,
1298 },
1299 {
developer043f7b92023-03-13 13:57:36 +08001300 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
developerc50c2352021-12-01 10:45:35 +08001301 .name = "MediaTek MT7531 PHY",
1302 .config_init = mt7531_phy_config_init,
1303 /* Interrupts are handled by the switch, not the PHY
1304 * itself.
1305 */
1306 .config_intr = genphy_no_config_intr,
1307 .handle_interrupt = genphy_no_ack_interrupt,
1308 .suspend = genphy_suspend,
1309 .resume = genphy_resume,
1310 .read_page = mtk_gephy_read_page,
1311 .write_page = mtk_gephy_write_page,
1312 },
developer2149cd92023-03-10 19:01:41 +08001313#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
developerc50c2352021-12-01 10:45:35 +08001314 {
developer043f7b92023-03-13 13:57:36 +08001315 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
developerf35532c2022-08-05 18:37:26 +08001316 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001317 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001318 .config_intr = genphy_no_config_intr,
1319 .handle_interrupt = genphy_no_ack_interrupt,
1320 .suspend = genphy_suspend,
1321 .resume = genphy_resume,
1322 .read_page = mtk_gephy_read_page,
1323 .write_page = mtk_gephy_write_page,
1324 },
1325 {
developer043f7b92023-03-13 13:57:36 +08001326 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
developerf35532c2022-08-05 18:37:26 +08001327 .name = "MediaTek MT7988 PHY",
1328 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001329 .config_intr = genphy_no_config_intr,
1330 .handle_interrupt = genphy_no_ack_interrupt,
1331 .suspend = genphy_suspend,
1332 .resume = genphy_resume,
1333 .read_page = mtk_gephy_read_page,
1334 .write_page = mtk_gephy_write_page,
1335 },
developer2149cd92023-03-10 19:01:41 +08001336#endif
developerc50c2352021-12-01 10:45:35 +08001337};
1338
1339module_phy_driver(mtk_gephy_driver);
1340
1341static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1342 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1343 { }
1344};
1345
1346MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
developer2149cd92023-03-10 19:01:41 +08001347MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
1348MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
developerc50c2352021-12-01 10:45:35 +08001349MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1350MODULE_LICENSE("GPL");
1351
1352MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);