blob: d62d6bc489f3eb6209a9c71c6d6cd0be61f981e8 [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>
7#include <linux/phy.h>
8
developerc50c2352021-12-01 10:45:35 +08009#define MTK_EXT_PAGE_ACCESS 0x1f
10#define MTK_PHY_PAGE_STANDARD 0x0000
11#define MTK_PHY_PAGE_EXTENDED 0x0001
12#define MTK_PHY_PAGE_EXTENDED_2 0x0002
13#define MTK_PHY_PAGE_EXTENDED_3 0x0003
14#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
15#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
16
developer2149cd92023-03-10 19:01:41 +080017#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
18#define ZCAL_CTRL_MIN (0)
19#define ZCAL_CTRL_MAX (63)
20#define TXRESERVE_MIN (0)
21#define TXRESERVE_MAX (7)
22
23#define MTK_PHY_ANARG_RG (0x10)
24#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
25
developerc50c2352021-12-01 10:45:35 +080026/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080027enum {
developerf35532c2022-08-05 18:37:26 +080028 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
29 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
30 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
31 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
32 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
33 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
34 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
35 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
36 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
37 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
38 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
39 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
40 MTK_PHY_TX_MLT3_END,
41};
developer02d84422021-12-24 11:48:07 +080042
developer2149cd92023-03-10 19:01:41 +080043#define MTK_PHY_TXVLD_DA_RG (0x12)
developerc50c2352021-12-01 10:45:35 +080044#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
45#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
46
developer2149cd92023-03-10 19:01:41 +080047#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
developerc50c2352021-12-01 10:45:35 +080048#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
49#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
50
developer2149cd92023-03-10 19:01:41 +080051#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
developerc50c2352021-12-01 10:45:35 +080052#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
53#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
54
developer2149cd92023-03-10 19:01:41 +080055#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
developerc50c2352021-12-01 10:45:35 +080056#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
57#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
58
developer2149cd92023-03-10 19:01:41 +080059#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
developerc50c2352021-12-01 10:45:35 +080060#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
61#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
62
developer2149cd92023-03-10 19:01:41 +080063#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
developerc50c2352021-12-01 10:45:35 +080064#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
65#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
66
developer2149cd92023-03-10 19:01:41 +080067#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
developerc50c2352021-12-01 10:45:35 +080068#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
69#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
70
developer2149cd92023-03-10 19:01:41 +080071#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
developerc50c2352021-12-01 10:45:35 +080072#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
73#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
74
developer2149cd92023-03-10 19:01:41 +080075#define MTK_PHY_TANA_CAL_MODE (0xc1)
76#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +080077
developer2149cd92023-03-10 19:01:41 +080078#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
developer57374032022-10-11 16:43:24 +080079#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
80
developer2149cd92023-03-10 19:01:41 +080081#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
82#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
83#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
84#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
85#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +080086
developer2149cd92023-03-10 19:01:41 +080087#define MTK_PHY_LDO_OUTPUT_V (0xd7)
developerce268312022-12-20 16:26:11 +080088
developer2149cd92023-03-10 19:01:41 +080089#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
90#define MTK_PHY_RG_CAL_CKINV BIT(12)
91#define MTK_PHY_RG_ANA_CALEN BIT(8)
92#define MTK_PHY_RG_REXT_CALEN BIT(4)
93#define MTK_PHY_RG_ZCALEN_A BIT(0)
developerc50c2352021-12-01 10:45:35 +080094
developer2149cd92023-03-10 19:01:41 +080095#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
96#define MTK_PHY_RG_ZCALEN_B BIT(12)
97#define MTK_PHY_RG_ZCALEN_C BIT(8)
98#define MTK_PHY_RG_ZCALEN_D BIT(4)
99#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
developerc50c2352021-12-01 10:45:35 +0800100
developer2149cd92023-03-10 19:01:41 +0800101#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
102#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
103#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
104#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
105#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
developerc50c2352021-12-01 10:45:35 +0800106
developer2149cd92023-03-10 19:01:41 +0800107#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
108#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
109#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800110
developer2149cd92023-03-10 19:01:41 +0800111#define MTK_PHY_RG_TX_FILTER (0xfe)
developer6de96aa2022-09-29 16:46:18 +0800112
developer2149cd92023-03-10 19:01:41 +0800113#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B (0x172)
developerc50c2352021-12-01 10:45:35 +0800114#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
115#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
116
developer2149cd92023-03-10 19:01:41 +0800117#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D (0x173)
developerc50c2352021-12-01 10:45:35 +0800118#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
119#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
120
developer2149cd92023-03-10 19:01:41 +0800121#define MTK_PHY_RG_AD_CAL_COMP (0x17a)
122#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +0800123
developer2149cd92023-03-10 19:01:41 +0800124#define MTK_PHY_RG_AD_CAL_CLK (0x17b)
125#define MTK_PHY_DA_CAL_CLK BIT(0)
developerc50c2352021-12-01 10:45:35 +0800126
developer2149cd92023-03-10 19:01:41 +0800127#define MTK_PHY_RG_AD_CALIN (0x17c)
128#define MTK_PHY_DA_CALIN_FLAG BIT(0)
developerc50c2352021-12-01 10:45:35 +0800129
developer2149cd92023-03-10 19:01:41 +0800130#define MTK_PHY_RG_DASN_DAC_IN0_A (0x17d)
131#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800132
developer2149cd92023-03-10 19:01:41 +0800133#define MTK_PHY_RG_DASN_DAC_IN0_B (0x17e)
134#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800135
developer2149cd92023-03-10 19:01:41 +0800136#define MTK_PHY_RG_DASN_DAC_IN0_C (0x17f)
137#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800138
developer2149cd92023-03-10 19:01:41 +0800139#define MTK_PHY_RG_DASN_DAC_IN0_D (0x180)
140#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800141
developer2149cd92023-03-10 19:01:41 +0800142#define MTK_PHY_RG_DASN_DAC_IN1_A (0x181)
143#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800144
developer2149cd92023-03-10 19:01:41 +0800145#define MTK_PHY_RG_DASN_DAC_IN1_B (0x182)
146#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800147
developer2149cd92023-03-10 19:01:41 +0800148#define MTK_PHY_RG_DASN_DAC_IN1_C (0x183)
149#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800150
developer2149cd92023-03-10 19:01:41 +0800151#define MTK_PHY_RG_DASN_DAC_IN1_D (0x180)
152#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800153
developer2149cd92023-03-10 19:01:41 +0800154#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
155#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
156#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
157#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
158#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
159#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
160#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
161#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
162#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
163#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
developer75819992023-03-08 20:49:03 +0800164
developer2149cd92023-03-10 19:01:41 +0800165#define MTK_PHY_RG_DEV1E_REG234 (0x234)
166#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
167#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
developerd2ec38e2022-11-27 01:15:29 +0800168
developer2149cd92023-03-10 19:01:41 +0800169#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
developerd2ec38e2022-11-27 01:15:29 +0800170
developer2149cd92023-03-10 19:01:41 +0800171#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
developerd2ec38e2022-11-27 01:15:29 +0800172#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
developer2149cd92023-03-10 19:01:41 +0800173#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
developerd2ec38e2022-11-27 01:15:29 +0800174#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800175
developer2149cd92023-03-10 19:01:41 +0800176#define MTK_PHY_LDO_PUMP_EN_PAIRAB (0x502)
177#define MTK_PHY_LDO_PUMP_EN_PAIRCD (0x503)
developer75819992023-03-08 20:49:03 +0800178
developer2149cd92023-03-10 19:01:41 +0800179#define MTK_PHY_DA_TX_R50_PAIR_A (0x53d)
180#define MTK_PHY_DA_TX_R50_PAIR_B (0x53e)
181#define MTK_PHY_DA_TX_R50_PAIR_C (0x53f)
182#define MTK_PHY_DA_TX_R50_PAIR_D (0x540)
developerc50c2352021-12-01 10:45:35 +0800183
184/* Registers on MDIO_MMD_VEND2 */
developer2149cd92023-03-10 19:01:41 +0800185#define MTK_PHY_LED0_ON_CTRL (0x24)
developer23021292022-10-21 19:10:10 +0800186#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
developer2149cd92023-03-10 19:01:41 +0800187#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
188#define MTK_PHY_LED0_ON_LINK100 BIT(1)
189#define MTK_PHY_LED0_ON_LINK10 BIT(2)
190#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
191#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
192#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
193#define MTK_PHY_LED0_FORCE_ON BIT(6)
194#define MTK_PHY_LED0_POLARITY BIT(14)
195#define MTK_PHY_LED0_ENABLE BIT(15)
developer23021292022-10-21 19:10:10 +0800196
developer2149cd92023-03-10 19:01:41 +0800197#define MTK_PHY_LED0_BLINK_CTRL (0x25)
198#define MTK_PHY_LED0_1000TX BIT(0)
199#define MTK_PHY_LED0_1000RX BIT(1)
200#define MTK_PHY_LED0_100TX BIT(2)
201#define MTK_PHY_LED0_100RX BIT(3)
202#define MTK_PHY_LED0_10TX BIT(4)
203#define MTK_PHY_LED0_10RX BIT(5)
204#define MTK_PHY_LED0_COLLISION BIT(6)
205#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
206#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
207#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
developer8bc5dca2022-10-24 17:15:12 +0800208
developer2149cd92023-03-10 19:01:41 +0800209#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
developerc50c2352021-12-01 10:45:35 +0800210#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
211
developer2149cd92023-03-10 19:01:41 +0800212#define MTK_PHY_RG_DASN_TXT_DMY2 (0x110)
213#define MTK_PHY_TST_DMY2_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800214
developer2149cd92023-03-10 19:01:41 +0800215#define MTK_PHY_RG_BG_RASEL (0x115)
216#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +0800217
developer2149cd92023-03-10 19:01:41 +0800218/* These macro privides efuse parsing for internal phy. */
219#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
220#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
221#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
222#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
223#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800224
developer2149cd92023-03-10 19:01:41 +0800225#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
226#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
227#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
228#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
229#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800230
developer2149cd92023-03-10 19:01:41 +0800231#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
232#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
233#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
234#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800235
developer2149cd92023-03-10 19:01:41 +0800236#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
237#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800238
developer2149cd92023-03-10 19:01:41 +0800239enum {
240 NO_PAIR,
developerc50c2352021-12-01 10:45:35 +0800241 PAIR_A,
242 PAIR_B,
243 PAIR_C,
244 PAIR_D,
developer2149cd92023-03-10 19:01:41 +0800245};
developerc50c2352021-12-01 10:45:35 +0800246
developer23021292022-10-21 19:10:10 +0800247enum {
248 GPHY_PORT0,
249 GPHY_PORT1,
250 GPHY_PORT2,
251 GPHY_PORT3,
252};
253
developer2149cd92023-03-10 19:01:41 +0800254enum calibration_mode {
255 EFUSE_K,
256 SW_K
257};
258
259enum CAL_ITEM {
260 REXT,
261 TX_OFFSET,
262 TX_AMP,
263 TX_R50,
264 TX_VCM
265};
266
267enum CAL_MODE {
268 SW_EFUSE_M,
269 EFUSE_M,
270 SW_M
271};
272
developerc50c2352021-12-01 10:45:35 +0800273const u8 mt798x_zcal_to_r50[64] = {
274 7, 8, 9, 9, 10, 10, 11, 11,
275 12, 13, 13, 14, 14, 15, 16, 16,
276 17, 18, 18, 19, 20, 21, 21, 22,
277 23, 24, 24, 25, 26, 27, 28, 29,
278 30, 31, 32, 33, 34, 35, 36, 37,
279 38, 40, 41, 42, 43, 45, 46, 48,
280 49, 51, 52, 54, 55, 57, 59, 61,
281 62, 63, 63, 63, 63, 63, 63, 63
282};
283
284const char pair[4] = {'A', 'B', 'C', 'D'};
285
developer2149cd92023-03-10 19:01:41 +0800286static int mtk_gephy_read_page(struct phy_device *phydev)
287{
288 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
289}
developerc50c2352021-12-01 10:45:35 +0800290
developer2149cd92023-03-10 19:01:41 +0800291static int mtk_gephy_write_page(struct phy_device *phydev, int page)
292{
293 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
294}
developerc50c2352021-12-01 10:45:35 +0800295
developer2149cd92023-03-10 19:01:41 +0800296static void mtk_gephy_config_init(struct phy_device *phydev)
297{
298 /* Disable EEE */
299 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
developerc50c2352021-12-01 10:45:35 +0800300
developer2149cd92023-03-10 19:01:41 +0800301 /* Enable HW auto downshift */
302 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
developerc50c2352021-12-01 10:45:35 +0800303
developer2149cd92023-03-10 19:01:41 +0800304 /* Increase SlvDPSready time */
305 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
306 __phy_write(phydev, 0x10, 0xafae);
307 __phy_write(phydev, 0x12, 0x2f);
308 __phy_write(phydev, 0x10, 0x8fae);
309 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerc50c2352021-12-01 10:45:35 +0800310
developer2149cd92023-03-10 19:01:41 +0800311 /* Adjust 100_mse_threshold */
312 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
developerc50c2352021-12-01 10:45:35 +0800313
developer2149cd92023-03-10 19:01:41 +0800314 /* Disable mcc */
315 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
316}
developerc50c2352021-12-01 10:45:35 +0800317
developer2149cd92023-03-10 19:01:41 +0800318static int mt7530_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800319{
developer2149cd92023-03-10 19:01:41 +0800320 mtk_gephy_config_init(phydev);
321
322 /* Increase post_update_timer */
323 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
324
325 return 0;
developerc50c2352021-12-01 10:45:35 +0800326}
327
developer2149cd92023-03-10 19:01:41 +0800328static int mt7531_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800329{
developer2149cd92023-03-10 19:01:41 +0800330 mtk_gephy_config_init(phydev);
331
332 /* PHY link down power saving enable */
333 phy_set_bits(phydev, 0x17, BIT(4));
334 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
335
336 /* Set TX Pair delay selection */
337 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
338 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
339
340 return 0;
developerc50c2352021-12-01 10:45:35 +0800341}
342
developer2149cd92023-03-10 19:01:41 +0800343#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
344/* One calibration cycle consists of:
developerc50c2352021-12-01 10:45:35 +0800345 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
346 * until AD_CAL_COMP is ready to output calibration result.
347 * 2.Wait until DA_CAL_CLK is available.
348 * 3.Fetch AD_CAL_COMP_OUT.
349 */
350static int cal_cycle(struct phy_device *phydev, int devad,
developer2149cd92023-03-10 19:01:41 +0800351 u32 regnum, u16 mask, u16 cal_val)
developerc50c2352021-12-01 10:45:35 +0800352{
353 unsigned long timeout;
354 int reg_val;
355 int ret;
356
357 phy_modify_mmd(phydev, devad, regnum,
developer2149cd92023-03-10 19:01:41 +0800358 mask, cal_val);
359 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
360 MTK_PHY_DA_CALIN_FLAG);
developerc50c2352021-12-01 10:45:35 +0800361
362 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
developer2149cd92023-03-10 19:01:41 +0800363 do {
364 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
365 MTK_PHY_RG_AD_CAL_CLK);
366 } while (time_before(jiffies, timeout) && !(reg_val & BIT(0)));
developerc50c2352021-12-01 10:45:35 +0800367
developer2149cd92023-03-10 19:01:41 +0800368 if (!(reg_val & BIT(0))) {
developerc50c2352021-12-01 10:45:35 +0800369 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
370 return -ETIMEDOUT;
371 }
372
developer2149cd92023-03-10 19:01:41 +0800373 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
374 MTK_PHY_DA_CALIN_FLAG);
375 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
376 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
developerc50c2352021-12-01 10:45:35 +0800377 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
378
379 return ret;
380}
381
382static int rext_fill_result(struct phy_device *phydev, u16 *buf)
383{
384 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800385 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
386 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
387 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
developerc50c2352021-12-01 10:45:35 +0800388
389 return 0;
390}
391
392static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
393{
394 u16 rext_cal_val[2];
395
396 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
397 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
398 rext_fill_result(phydev, rext_cal_val);
399
400 return 0;
401}
402
403static int rext_cal_sw(struct phy_device *phydev)
404{
405 u8 rg_zcal_ctrl_def;
406 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
407 u8 lower_ret, upper_ret;
408 u16 rext_cal_val[2];
409 int ret;
410
411 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800412 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
developerc50c2352021-12-01 10:45:35 +0800413 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800414 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800415 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800416 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN |
417 MTK_PHY_RG_REXT_CALEN);
418 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
419 MTK_PHY_TST_DMY2_MASK, 0x1);
developerc50c2352021-12-01 10:45:35 +0800420
developer2149cd92023-03-10 19:01:41 +0800421 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1,
422 MTK_PHY_RG_ANA_CAL_RG5) &
developerc50c2352021-12-01 10:45:35 +0800423 MTK_PHY_RG_ZCAL_CTRL_MASK;
424 zcal_lower = ZCAL_CTRL_MIN;
425 zcal_upper = ZCAL_CTRL_MAX;
426
427 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800428 while ((zcal_upper - zcal_lower) > 1) {
429 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower + zcal_upper, 2);
developerc50c2352021-12-01 10:45:35 +0800430 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
431 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer2149cd92023-03-10 19:01:41 +0800432 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800433 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800434 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800435 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800436 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800437 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800438 } else {
developerc50c2352021-12-01 10:45:35 +0800439 goto restore;
developer2149cd92023-03-10 19:01:41 +0800440 }
developerc50c2352021-12-01 10:45:35 +0800441 }
442
developer2149cd92023-03-10 19:01:41 +0800443 if (zcal_lower == ZCAL_CTRL_MIN) {
444 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
445 MTK_PHY_RG_ANA_CAL_RG5,
446 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
447 ret = lower_ret;
448 } else if (zcal_upper == ZCAL_CTRL_MAX) {
449 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
450 MTK_PHY_RG_ANA_CAL_RG5,
451 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
452 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800453 }
454 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800455 goto restore;
456
developer2149cd92023-03-10 19:01:41 +0800457 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800458 if (ret == 1) {
459 rext_cal_val[0] = zcal_upper;
460 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800461 rext_fill_result(phydev, rext_cal_val);
developer2149cd92023-03-10 19:01:41 +0800462 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n",
463 zcal_upper);
developerc50c2352021-12-01 10:45:35 +0800464 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800465 } else {
developerc50c2352021-12-01 10:45:35 +0800466 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800467 }
developerc50c2352021-12-01 10:45:35 +0800468
469restore:
developer2149cd92023-03-10 19:01:41 +0800470 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
471 MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developerc50c2352021-12-01 10:45:35 +0800472 MTK_PHY_ANA_TEST_MODE_MASK);
473 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800474 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN |
475 MTK_PHY_RG_REXT_CALEN);
476 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
477 MTK_PHY_TST_DMY2_MASK);
developerc50c2352021-12-01 10:45:35 +0800478 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
479 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
480
481 return ret;
482}
483
484static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
485{
developer2149cd92023-03-10 19:01:41 +0800486 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800487 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
developer2149cd92023-03-10 19:01:41 +0800488 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800489 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
developer2149cd92023-03-10 19:01:41 +0800490 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800491 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
developer2149cd92023-03-10 19:01:41 +0800492 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800493 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
494
495 return 0;
496}
497
498static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
499{
500 u16 tx_offset_cal_val[4];
501
502 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
503 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
504 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
505 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
506
507 tx_offset_fill_result(phydev, tx_offset_cal_val);
508
509 return 0;
510}
511
512static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
513{
developerd2ec38e2022-11-27 01:15:29 +0800514 int i;
developer87c89d12022-08-19 17:46:34 +0800515 int bias[16] = {0};
developer2149cd92023-03-10 19:01:41 +0800516 const int vals_9461[16] = { 7, 1, 4, 7,
517 7, 1, 4, 7,
518 7, 1, 4, 7,
519 7, 1, 4, 7 };
520 const int vals_9481[16] = { 10, 6, 6, 10,
521 10, 6, 6, 10,
522 10, 6, 6, 10,
523 10, 6, 6, 10 };
524
525 switch (phydev->drv->phy_id) {
526 case 0x03a29461:
527 /* We add some calibration to efuse values
528 * due to board level influence.
529 * GBE: +7, TBT: +1, HBT: +4, TST: +7
530 */
531 memcpy(bias, (const void *)vals_9461, sizeof(bias));
532 for (i = 0; i <= 12; i += 4) {
533 if (likely(buf[i >> 2] + bias[i] >= 32)) {
534 bias[i] -= 13;
535 } else {
536 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
537 0x5c, 0x7 << i, bias[i] << i);
538 bias[i + 1] += 13;
539 bias[i + 2] += 13;
540 bias[i + 3] += 13;
541 }
developer87c89d12022-08-19 17:46:34 +0800542 }
developer2149cd92023-03-10 19:01:41 +0800543 break;
544 case 0x03a29481:
545 memcpy(bias, (const void *)vals_9481, sizeof(bias));
546 break;
547 default:
548 break;
developer87c89d12022-08-19 17:46:34 +0800549 }
developerd2ec38e2022-11-27 01:15:29 +0800550
developerdc3e9502022-12-02 18:10:42 +0800551 /* Prevent overflow */
552 for (i = 0; i < 12; i++) {
developer2149cd92023-03-10 19:01:41 +0800553 if (buf[i >> 2] + bias[i] > 63) {
554 buf[i >> 2] = 63;
developerdc3e9502022-12-02 18:10:42 +0800555 bias[i] = 0;
developer2149cd92023-03-10 19:01:41 +0800556 } else if (buf[i >> 2] + bias[i] < 0) {
developerdc3e9502022-12-02 18:10:42 +0800557 /* Bias caused by board design may change in the future.
558 * So check negative cases, too.
559 */
developer2149cd92023-03-10 19:01:41 +0800560 buf[i >> 2] = 0;
developerdc3e9502022-12-02 18:10:42 +0800561 bias[i] = 0;
562 }
563 }
564
developerc50c2352021-12-01 10:45:35 +0800565 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800566 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800567 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800568 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800569 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800570 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800571 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800572 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800573
574 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800575 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800576 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800577 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800578 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800579 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800580 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800581 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800582
583 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800584 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800585 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800586 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800587 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800588 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800589 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800590 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800591
592 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800593 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800594 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800595 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800596 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800597 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800598 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800599 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800600
601 return 0;
602}
603
604static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
605{
606 u16 tx_amp_cal_val[4];
607
608 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
609 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
610 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
611 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
612 tx_amp_fill_result(phydev, tx_amp_cal_val);
613
614 return 0;
615}
616
developer2149cd92023-03-10 19:01:41 +0800617static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
618 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800619{
developer2149cd92023-03-10 19:01:41 +0800620 int bias = 0;
621 u16 reg, val;
developer87c89d12022-08-19 17:46:34 +0800622
developer2149cd92023-03-10 19:01:41 +0800623 switch (phydev->drv->phy_id) {
624 case 0x03a29481:
625 {
626 bias = -2;
627 break;
developerdc3e9502022-12-02 18:10:42 +0800628 }
developer2149cd92023-03-10 19:01:41 +0800629 /* 0x03a29461 enters default case */
630 default:
631 break;
632 }
633
634 val = clamp_val(bias + tx_r50_cal_val, 0, 63);
635
636 switch (txg_calen_x) {
637 case PAIR_A:
638 reg = MTK_PHY_DA_TX_R50_PAIR_A;
639 break;
640 case PAIR_B:
641 reg = MTK_PHY_DA_TX_R50_PAIR_B;
642 break;
643 case PAIR_C:
644 reg = MTK_PHY_DA_TX_R50_PAIR_C;
645 break;
646 case PAIR_D:
647 reg = MTK_PHY_DA_TX_R50_PAIR_D;
648 break;
developerc50c2352021-12-01 10:45:35 +0800649 }
developer2149cd92023-03-10 19:01:41 +0800650
651 phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
652
developerc50c2352021-12-01 10:45:35 +0800653 return 0;
654}
655
656static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
developer2149cd92023-03-10 19:01:41 +0800657 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800658{
developer2149cd92023-03-10 19:01:41 +0800659 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800660
developer2149cd92023-03-10 19:01:41 +0800661 switch (txg_calen_x) {
662 case PAIR_A:
663 tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
664 break;
665 case PAIR_B:
666 tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
667 break;
668 case PAIR_C:
669 tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
670 break;
671 case PAIR_D:
672 tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
673 break;
developerc50c2352021-12-01 10:45:35 +0800674 }
675 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
676
677 return 0;
678}
679
developer2149cd92023-03-10 19:01:41 +0800680static int tx_r50_cal_sw(struct phy_device *phydev, u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800681{
developerc50c2352021-12-01 10:45:35 +0800682 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
683 u8 lower_ret, upper_ret;
developer2149cd92023-03-10 19:01:41 +0800684 u8 rg_zcal_ctrl_def;
685 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800686 int ret;
687
688 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800689 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
developerc50c2352021-12-01 10:45:35 +0800690 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800691 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800692 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800693 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800694 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
developer2149cd92023-03-10 19:01:41 +0800695 BIT(txg_calen_x * 4));
696 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
697 MTK_PHY_TST_DMY2_MASK, 0x1);
developerc50c2352021-12-01 10:45:35 +0800698
developer2149cd92023-03-10 19:01:41 +0800699 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1,
700 MTK_PHY_RG_ANA_CAL_RG5) &
701 MTK_PHY_RG_ZCAL_CTRL_MASK;
developerc50c2352021-12-01 10:45:35 +0800702 zcal_lower = ZCAL_CTRL_MIN;
703 zcal_upper = ZCAL_CTRL_MAX;
704
developer2149cd92023-03-10 19:01:41 +0800705 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n",
706 pair[txg_calen_x]);
707 while ((zcal_upper - zcal_lower) > 1) {
708 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower + zcal_upper, 2);
developerc50c2352021-12-01 10:45:35 +0800709 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
710 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer2149cd92023-03-10 19:01:41 +0800711 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800712 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800713 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800714 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800715 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800716 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800717 } else {
developerc50c2352021-12-01 10:45:35 +0800718 goto restore;
developer2149cd92023-03-10 19:01:41 +0800719 }
developerc50c2352021-12-01 10:45:35 +0800720 }
721
developer2149cd92023-03-10 19:01:41 +0800722 if (zcal_lower == ZCAL_CTRL_MIN) {
723 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
724 MTK_PHY_RG_ANA_CAL_RG5,
725 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
726 ret = lower_ret;
727 } else if (zcal_upper == ZCAL_CTRL_MAX) {
728 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
729 MTK_PHY_RG_ANA_CAL_RG5,
730 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
731 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800732 }
733 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800734 goto restore;
735
developer2149cd92023-03-10 19:01:41 +0800736 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800737 if (ret == 1) {
developer2149cd92023-03-10 19:01:41 +0800738 tx_r50_cal_val = mt798x_zcal_to_r50[zcal_upper];
developerc50c2352021-12-01 10:45:35 +0800739 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer2149cd92023-03-10 19:01:41 +0800740 dev_info(&phydev->mdio.dev,
741 "TX-R50 Pair%c SW cal result: 0x%x\n",
742 pair[txg_calen_x], zcal_lower);
developerc50c2352021-12-01 10:45:35 +0800743 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800744 } else {
developerc50c2352021-12-01 10:45:35 +0800745 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800746 }
developerc50c2352021-12-01 10:45:35 +0800747
748restore:
749 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800750 MTK_PHY_ANA_TEST_MODE_MASK);
developerc50c2352021-12-01 10:45:35 +0800751 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800752 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800753 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
developer2149cd92023-03-10 19:01:41 +0800754 BIT(txg_calen_x * 4));
755 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
756 MTK_PHY_TST_DMY2_MASK);
developerc50c2352021-12-01 10:45:35 +0800757 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800758 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
developerc50c2352021-12-01 10:45:35 +0800759
760 return ret;
761}
762
developer2149cd92023-03-10 19:01:41 +0800763static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
developerc50c2352021-12-01 10:45:35 +0800764{
765 u8 lower_idx, upper_idx, txreserve_val;
766 u8 lower_ret, upper_ret;
767 int ret;
768
769 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800770 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800771 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800772 MTK_PHY_RG_CAL_CKINV);
developerc50c2352021-12-01 10:45:35 +0800773 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800774 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800775
developer2149cd92023-03-10 19:01:41 +0800776 switch (rg_txreserve_x) {
777 case PAIR_A:
778 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
779 MTK_PHY_RG_DASN_DAC_IN0_A,
780 MTK_PHY_DASN_DAC_IN0_A_MASK);
781 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
782 MTK_PHY_RG_DASN_DAC_IN1_A,
783 MTK_PHY_DASN_DAC_IN1_A_MASK);
784 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
785 MTK_PHY_RG_ANA_CAL_RG0,
786 MTK_PHY_RG_ZCALEN_A);
787 break;
788 case PAIR_B:
789 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
790 MTK_PHY_RG_DASN_DAC_IN0_B,
791 MTK_PHY_DASN_DAC_IN0_B_MASK);
792 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
793 MTK_PHY_RG_DASN_DAC_IN1_B,
794 MTK_PHY_DASN_DAC_IN1_B_MASK);
795 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
796 MTK_PHY_RG_ANA_CAL_RG1,
797 MTK_PHY_RG_ZCALEN_B);
798 break;
799 case PAIR_C:
800 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
801 MTK_PHY_RG_DASN_DAC_IN0_C,
802 MTK_PHY_DASN_DAC_IN0_C_MASK);
803 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
804 MTK_PHY_RG_DASN_DAC_IN1_C,
805 MTK_PHY_DASN_DAC_IN1_C_MASK);
806 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
807 MTK_PHY_RG_ANA_CAL_RG1,
808 MTK_PHY_RG_ZCALEN_C);
809 break;
810 case PAIR_D:
811 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
812 MTK_PHY_RG_DASN_DAC_IN0_D,
813 MTK_PHY_DASN_DAC_IN0_D_MASK);
814 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
815 MTK_PHY_RG_DASN_DAC_IN1_D,
816 MTK_PHY_DASN_DAC_IN1_D_MASK);
817 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
818 MTK_PHY_RG_ANA_CAL_RG1,
819 MTK_PHY_RG_ZCALEN_D);
820 break;
821 default:
822 ret = -EINVAL;
823 goto restore;
developerc50c2352021-12-01 10:45:35 +0800824 }
825
826 lower_idx = TXRESERVE_MIN;
827 upper_idx = TXRESERVE_MAX;
828
829 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800830 while ((upper_idx - lower_idx) > 1) {
831 txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
developerc50c2352021-12-01 10:45:35 +0800832 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800833 MTK_PHY_DA_RX_PSBN_TBT_MASK |
834 MTK_PHY_DA_RX_PSBN_HBT_MASK |
835 MTK_PHY_DA_RX_PSBN_GBE_MASK |
836 MTK_PHY_DA_RX_PSBN_LP_MASK,
developerc50c2352021-12-01 10:45:35 +0800837 txreserve_val << 12 | txreserve_val << 8 |
838 txreserve_val << 4 | txreserve_val);
developer2149cd92023-03-10 19:01:41 +0800839 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800840 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800841 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800842 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800843 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800844 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800845 } else {
developerc50c2352021-12-01 10:45:35 +0800846 goto restore;
developer2149cd92023-03-10 19:01:41 +0800847 }
developerc50c2352021-12-01 10:45:35 +0800848 }
849
developer2149cd92023-03-10 19:01:41 +0800850 if (lower_idx == TXRESERVE_MIN) {
851 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
852 MTK_PHY_RXADC_CTRL_RG9,
853 MTK_PHY_DA_RX_PSBN_TBT_MASK |
854 MTK_PHY_DA_RX_PSBN_HBT_MASK |
855 MTK_PHY_DA_RX_PSBN_GBE_MASK |
856 MTK_PHY_DA_RX_PSBN_LP_MASK,
857 lower_idx << 12 | lower_idx << 8 |
858 lower_idx << 4 | lower_idx);
859 ret = lower_ret;
860 } else if (upper_idx == TXRESERVE_MAX) {
861 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
862 MTK_PHY_RXADC_CTRL_RG9,
863 MTK_PHY_DA_RX_PSBN_TBT_MASK |
864 MTK_PHY_DA_RX_PSBN_HBT_MASK |
865 MTK_PHY_DA_RX_PSBN_GBE_MASK |
866 MTK_PHY_DA_RX_PSBN_LP_MASK,
867 upper_idx << 12 | upper_idx << 8 |
868 upper_idx << 4 | upper_idx);
869 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800870 }
871 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800872 goto restore;
873
developer78aa7b92021-12-29 15:22:10 +0800874 /* We calibrate TX-VCM in different logic. Check upper index and then
875 * lower index. If this calibration is valid, apply lower index's result.
876 */
developer2149cd92023-03-10 19:01:41 +0800877 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800878 if (ret == 1) {
879 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800880 /* Make sure we use upper_idx in our calibration system */
881 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800882 MTK_PHY_DA_RX_PSBN_TBT_MASK |
883 MTK_PHY_DA_RX_PSBN_HBT_MASK |
884 MTK_PHY_DA_RX_PSBN_GBE_MASK |
885 MTK_PHY_DA_RX_PSBN_LP_MASK,
886 upper_idx << 12 | upper_idx << 8 |
887 upper_idx << 4 | upper_idx);
888 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n",
889 upper_idx);
890 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
891 lower_ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800892 ret = 0;
893 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800894 MTK_PHY_DA_RX_PSBN_TBT_MASK |
895 MTK_PHY_DA_RX_PSBN_HBT_MASK |
896 MTK_PHY_DA_RX_PSBN_GBE_MASK |
897 MTK_PHY_DA_RX_PSBN_LP_MASK,
898 lower_idx << 12 | lower_idx << 8 |
899 lower_idx << 4 | lower_idx);
900 dev_warn(&phydev->mdio.dev,
901 "TX-VCM SW cal result at low margin 0x%x\n",
902 lower_idx);
903 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
904 lower_ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800905 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800906 dev_warn(&phydev->mdio.dev,
907 "TX-VCM SW cal result at high margin 0x%x\n",
908 upper_idx);
909 } else {
developerc50c2352021-12-01 10:45:35 +0800910 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800911 }
developerc50c2352021-12-01 10:45:35 +0800912
913restore:
914 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800915 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800916 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800917 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800918 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800919 MTK_PHY_RG_ZCALEN_A);
developerc50c2352021-12-01 10:45:35 +0800920 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800921 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
922 MTK_PHY_RG_ZCALEN_D);
developerc50c2352021-12-01 10:45:35 +0800923
924 return ret;
925}
926
developerf35532c2022-08-05 18:37:26 +0800927static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800928{
developerd2ec38e2022-11-27 01:15:29 +0800929 u32 i;
developer2149cd92023-03-10 19:01:41 +0800930
developer02d84422021-12-24 11:48:07 +0800931 /* 100M eye finetune:
932 * Keep middle level of TX MLT3 shapper as default.
933 * Only change TX MLT3 overshoot level here.
934 */
developer2149cd92023-03-10 19:01:41 +0800935 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
936 0x1ce);
937 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
938 0x1c1);
939 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
940 0x20f);
941 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
942 0x202);
943 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
944 0x3d0);
945 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
946 0x3c0);
947 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
948 0x13);
949 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
950 0x5);
developerf35532c2022-08-05 18:37:26 +0800951
developer02d84422021-12-24 11:48:07 +0800952 /* TX-AMP finetune:
953 * 100M +4, 1000M +6 to default value.
954 * If efuse values aren't valid, TX-AMP uses the below values.
955 */
956 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
developer2149cd92023-03-10 19:01:41 +0800957 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
958 0x9026);
959 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
960 0x2624);
961 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
962 0x2426);
963 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
964 0x2624);
965 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
966 0x2426);
967 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
968 0x2624);
969 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
970 0x2426);
developer68f6e102022-11-22 17:35:00 +0800971
developerd2ec38e2022-11-27 01:15:29 +0800972 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
973 /* EnabRandUpdTrig = 1 */
974 __phy_write(phydev, 0x11, 0x2f00);
975 __phy_write(phydev, 0x12, 0xe);
976 __phy_write(phydev, 0x10, 0x8fb0);
977
developer2149cd92023-03-10 19:01:41 +0800978 /* SlvDSPreadyTime = 0xc */
979 __phy_write(phydev, 0x11, 0x671);
developerd2ec38e2022-11-27 01:15:29 +0800980 __phy_write(phydev, 0x12, 0xc);
981 __phy_write(phydev, 0x10, 0x8fae);
982
983 /* NormMseLoThresh = 85 */
984 __phy_write(phydev, 0x11, 0x55a0);
985 __phy_write(phydev, 0x12, 0x0);
986 __phy_write(phydev, 0x10, 0x83aa);
987
988 /* InhibitDisableDfeTail1000 = 1 */
989 __phy_write(phydev, 0x11, 0x2b);
990 __phy_write(phydev, 0x12, 0x0);
991 __phy_write(phydev, 0x10, 0x8f80);
992
developer2149cd92023-03-10 19:01:41 +0800993 /* SSTr related */
developerd2ec38e2022-11-27 01:15:29 +0800994 __phy_write(phydev, 0x11, 0xbaef);
995 __phy_write(phydev, 0x12, 0x2e);
996 __phy_write(phydev, 0x10, 0x968c);
997
998 /* VcoSlicerThreshBitsHigh */
999 __phy_write(phydev, 0x11, 0x5555);
1000 __phy_write(phydev, 0x12, 0x55);
1001 __phy_write(phydev, 0x10, 0x8ec0);
1002
1003 /* ResetSyncOffset = 6 */
1004 __phy_write(phydev, 0x11, 0x600);
1005 __phy_write(phydev, 0x12, 0x0);
1006 __phy_write(phydev, 0x10, 0x8fc0);
1007
1008 /* VgaDecRate = 1 */
1009 __phy_write(phydev, 0x11, 0x4c2a);
1010 __phy_write(phydev, 0x12, 0x3e);
1011 __phy_write(phydev, 0x10, 0x8fa4);
1012
1013 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerd2ec38e2022-11-27 01:15:29 +08001014 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +08001015 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +08001016 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1017 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerd2ec38e2022-11-27 01:15:29 +08001018
1019 /* rg_tr_lpf_cnt_val = 512 */
1020 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1021
1022 /* IIR2 related */
1023 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1024 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1025 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1026 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1027 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1028 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1029 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1030 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1031 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1032 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1033
1034 /* FFE peaking */
1035 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +08001036 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerd2ec38e2022-11-27 01:15:29 +08001037 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +08001038 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerd2ec38e2022-11-27 01:15:29 +08001039
1040 /* TX shape */
1041 /* 10/100/1000 TX shaper is enabled by default */
1042 for (i = 0x202; i < 0x230; i += 2) {
1043 if (i == 0x20c || i == 0x218 || i == 0x224)
1044 continue;
1045 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +08001046 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerd2ec38e2022-11-27 01:15:29 +08001047 }
developer02d84422021-12-24 11:48:07 +08001048}
1049
developerf35532c2022-08-05 18:37:26 +08001050static inline void mt7988_phy_finetune(struct phy_device *phydev)
1051{
developer2149cd92023-03-10 19:01:41 +08001052 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
1053 0x020d, 0x0206, 0x0384, 0x03d0,
1054 0x03c6, 0x030a, 0x0011, 0x0005 };
developerf35532c2022-08-05 18:37:26 +08001055 int i;
developerf35532c2022-08-05 18:37:26 +08001056
developer2149cd92023-03-10 19:01:41 +08001057 for (i = 0; i < MTK_PHY_TX_MLT3_END; i++)
developerf35532c2022-08-05 18:37:26 +08001058 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
developer6de96aa2022-09-29 16:46:18 +08001059
developer57374032022-10-11 16:43:24 +08001060 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001061 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001062
1063 /* Disable TX power saving */
1064 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developer2149cd92023-03-10 19:01:41 +08001065 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001066
developerec2b8552022-10-17 15:30:59 +08001067 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +08001068 /* EnabRandUpdTrig = 1 */
1069 __phy_write(phydev, 0x11, 0x2f00);
1070 __phy_write(phydev, 0x12, 0xe);
1071 __phy_write(phydev, 0x10, 0x8fb0);
1072
developer2149cd92023-03-10 19:01:41 +08001073 /* SlvDSPreadyTime = 0xc */
developerce73ad62022-12-07 22:43:45 +08001074 __phy_write(phydev, 0x11, 0x671);
1075 __phy_write(phydev, 0x12, 0xc);
1076 __phy_write(phydev, 0x10, 0x8fae);
1077
1078 /* NormMseLoThresh = 85 */
1079 __phy_write(phydev, 0x11, 0x55a0);
developerec2b8552022-10-17 15:30:59 +08001080 __phy_write(phydev, 0x12, 0x0);
developerce73ad62022-12-07 22:43:45 +08001081 __phy_write(phydev, 0x10, 0x83aa);
1082
1083 /* InhibitDisableDfeTail1000 = 1 */
1084 __phy_write(phydev, 0x11, 0x2b);
1085 __phy_write(phydev, 0x12, 0x0);
1086 __phy_write(phydev, 0x10, 0x8f80);
1087
1088 /* SSTr related */
1089 __phy_write(phydev, 0x11, 0xbaef);
1090 __phy_write(phydev, 0x12, 0x2e);
1091 __phy_write(phydev, 0x10, 0x968c);
1092
1093 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
1094 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
1095 */
1096 __phy_write(phydev, 0x11, 0xd10a);
1097 __phy_write(phydev, 0x12, 0x34);
1098 __phy_write(phydev, 0x10, 0x8f82);
1099
1100 /* VcoSlicerThreshBitsHigh */
1101 __phy_write(phydev, 0x11, 0x5555);
1102 __phy_write(phydev, 0x12, 0x55);
1103 __phy_write(phydev, 0x10, 0x8ec0);
1104
developerce268312022-12-20 16:26:11 +08001105 /* ResetSyncOffset = 5 */
1106 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +08001107 __phy_write(phydev, 0x12, 0x0);
1108 __phy_write(phydev, 0x10, 0x8fc0);
developerb5c72b02022-12-21 15:51:07 +08001109 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001110
developerce268312022-12-20 16:26:11 +08001111 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
1112 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +08001113 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developer2149cd92023-03-10 19:01:41 +08001114 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +08001115 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001116
1117 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
1118 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +08001119 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1120 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerce73ad62022-12-07 22:43:45 +08001121
1122 /* rg_tr_lpf_cnt_val = 512 */
1123 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1124
1125 /* IIR2 related */
1126 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1127 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1128 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1129 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1130 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1131 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1132 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1133 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1134 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1135 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1136
1137 /* FFE peaking */
1138 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +08001139 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerce73ad62022-12-07 22:43:45 +08001140 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +08001141 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerce73ad62022-12-07 22:43:45 +08001142
1143 /* TX shape */
1144 /* 10/100/1000 TX shaper is enabled by default */
1145 for (i = 0x202; i < 0x230; i += 2) {
1146 if (i == 0x20c || i == 0x218 || i == 0x224)
1147 continue;
1148 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +08001149 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerce73ad62022-12-07 22:43:45 +08001150 }
developerce268312022-12-20 16:26:11 +08001151
1152 /* Disable LDO pump */
1153 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
1154 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
1155
1156 /* Adjust LDO output voltage */
developerb5c72b02022-12-21 15:51:07 +08001157 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developer2149cd92023-03-10 19:01:41 +08001158}
developer75819992023-03-08 20:49:03 +08001159
developer2149cd92023-03-10 19:01:41 +08001160static inline int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
1161 u8 start_pair, u8 end_pair)
1162{
1163 u8 pair_n;
1164 int ret;
1165
1166 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1167 /* TX_OFFSET & TX_AMP have no SW calibration. */
1168 switch (cal_item) {
1169 case REXT:
1170 ret = rext_cal_sw(phydev);
1171 break;
1172 case TX_R50:
1173 ret = tx_r50_cal_sw(phydev, pair_n);
1174 break;
1175 case TX_VCM:
1176 ret = tx_vcm_cal_sw(phydev, pair_n);
1177 break;
1178 default:
1179 return -EINVAL;
1180 }
1181 if (ret)
1182 return ret;
1183 }
1184 return 0;
developerf35532c2022-08-05 18:37:26 +08001185}
1186
developer2149cd92023-03-10 19:01:41 +08001187static inline int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
1188 u8 start_pair, u8 end_pair, u32 *buf)
1189{
1190 u8 pair_n;
1191 int ret;
1192
1193 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1194 /* TX_VCM has no efuse calibration. */
1195 switch (cal_item) {
1196 case REXT:
1197 ret = rext_cal_efuse(phydev, buf);
1198 break;
1199 case TX_OFFSET:
1200 ret = tx_offset_cal_efuse(phydev, buf);
1201 break;
1202 case TX_AMP:
1203 ret = tx_amp_cal_efuse(phydev, buf);
1204 break;
1205 case TX_R50:
1206 ret = tx_r50_cal_efuse(phydev, buf, pair_n);
1207 break;
1208 default:
1209 return -EINVAL;
1210 }
1211 if (ret)
1212 return ret;
1213 }
1214
1215 return 0;
1216}
1217
1218static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
1219 bool efs_valid, enum CAL_MODE cal_mode, u8 start_pair,
1220 u8 end_pair, u32 *buf)
1221{
1222 char cal_prop[5][20] = { "mediatek,rext", "mediatek,tx_offset",
1223 "mediatek,tx_amp", "mediatek,tx_r50",
1224 "mediatek,tx_vcm" };
1225 const char *dts_cal_mode;
1226 u8 final_cal_mode = 0;
1227 bool is_cal = true;
1228 int ret, cal_ret;
1229
1230 ret = of_property_read_string(phydev->mdio.dev.of_node,
1231 cal_prop[cal_item], &dts_cal_mode);
1232
1233 switch (cal_mode) {
1234 case SW_EFUSE_M:
1235 if ((efs_valid && ret) ||
1236 (efs_valid && !ret && strcmp("efuse", dts_cal_mode) == 0)) {
1237 cal_ret = cal_efuse(phydev, cal_item, start_pair,
1238 end_pair, buf);
1239 final_cal_mode = EFUSE_K;
1240 } else if ((!efs_valid && ret) ||
1241 (!ret && strcmp("sw", dts_cal_mode) == 0)) {
1242 cal_ret = cal_sw(phydev, cal_item, start_pair, end_pair);
1243 final_cal_mode = SW_K;
1244 } else {
1245 is_cal = false;
1246 }
1247 break;
1248 case EFUSE_M:
1249 if ((efs_valid && ret) ||
1250 (efs_valid && !ret && strcmp("efuse", dts_cal_mode) == 0)) {
1251 cal_ret = cal_efuse(phydev, cal_item, start_pair,
1252 end_pair, buf);
1253 final_cal_mode = EFUSE_K;
1254 } else {
1255 is_cal = false;
1256 }
1257 break;
1258 case SW_M:
1259 if (ret || (!ret && strcmp("sw", dts_cal_mode) == 0)) {
1260 cal_ret = cal_sw(phydev, cal_item, start_pair, end_pair);
1261 final_cal_mode = SW_K;
1262 } else {
1263 is_cal = false;
1264 }
1265 break;
1266 default:
1267 return -EINVAL;
1268 }
1269
1270 if (cal_ret) {
1271 dev_err(&phydev->mdio.dev, "[%s]cal failed\n", cal_prop[cal_item]);
1272 return -EIO;
1273 }
1274
1275 if (!is_cal) {
1276 dev_dbg(&phydev->mdio.dev, "[%s]K mode: %s(not supported)\n",
1277 cal_prop[cal_item], dts_cal_mode);
1278 return -EIO;
1279 }
1280
1281 dev_dbg(&phydev->mdio.dev, "[%s]K mode: %s(dts: %s), efs-valid: %s\n",
1282 cal_prop[cal_item],
1283 final_cal_mode ? "SW" : "EFUSE",
1284 ret ? "not set" : dts_cal_mode,
1285 efs_valid ? "yes" : "no");
1286 return 0;
1287}
1288
developerf35532c2022-08-05 18:37:26 +08001289static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001290{
developer2149cd92023-03-10 19:01:41 +08001291 int ret = 0;
developerc50c2352021-12-01 10:45:35 +08001292 u32 *buf;
1293 bool efs_valid = true;
1294 size_t len;
1295 struct nvmem_cell *cell;
1296
1297 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1298 return -EINVAL;
1299
1300 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1301 if (IS_ERR(cell)) {
1302 if (PTR_ERR(cell) == -EPROBE_DEFER)
1303 return PTR_ERR(cell);
1304 return 0;
1305 }
1306
1307 buf = (u32 *)nvmem_cell_read(cell, &len);
1308 if (IS_ERR(buf))
1309 return PTR_ERR(buf);
1310 nvmem_cell_put(cell);
1311
developer2149cd92023-03-10 19:01:41 +08001312 if (!buf[0] || !buf[1] || !buf[2] || !buf[3])
developerc50c2352021-12-01 10:45:35 +08001313 efs_valid = false;
1314
1315 if (len < 4 * sizeof(u32)) {
1316 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1317 ret = -EINVAL;
1318 goto out;
1319 }
1320
developer2149cd92023-03-10 19:01:41 +08001321 ret = start_cal(phydev, REXT, efs_valid, SW_EFUSE_M,
1322 NO_PAIR, NO_PAIR, buf);
1323 if (ret)
1324 goto out;
1325 ret = start_cal(phydev, TX_OFFSET, efs_valid, EFUSE_M,
1326 NO_PAIR, NO_PAIR, buf);
1327 if (ret)
1328 goto out;
1329 ret = start_cal(phydev, TX_AMP, efs_valid, EFUSE_M,
1330 NO_PAIR, NO_PAIR, buf);
1331 if (ret)
1332 goto out;
1333 ret = start_cal(phydev, TX_R50, efs_valid, EFUSE_M,
1334 PAIR_A, PAIR_D, buf);
1335 if (ret)
1336 goto out;
1337 ret = start_cal(phydev, TX_VCM, efs_valid, SW_M,
1338 PAIR_A, PAIR_A, buf);
1339 if (ret)
1340 goto out;
developerc50c2352021-12-01 10:45:35 +08001341
1342out:
1343 kfree(buf);
1344 return ret;
1345}
1346
developer68f6e102022-11-22 17:35:00 +08001347static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001348{
1349 mt7981_phy_finetune(phydev);
1350
1351 return mt798x_phy_calibration(phydev);
1352}
1353
developer68f6e102022-11-22 17:35:00 +08001354static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001355{
developer23021292022-10-21 19:10:10 +08001356 struct device_node *np;
1357 void __iomem *boottrap;
1358 u32 reg;
1359 int port;
1360
1361 /* Setup LED polarity according to boottrap's polarity */
1362 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1363 if (!np)
1364 return -ENOENT;
1365 boottrap = of_iomap(np, 0);
1366 if (!boottrap)
1367 return -ENOMEM;
1368 reg = readl(boottrap);
1369 port = phydev->mdio.addr;
1370 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1371 (port == GPHY_PORT1 && reg & BIT(9)) ||
1372 (port == GPHY_PORT2 && reg & BIT(10)) ||
1373 (port == GPHY_PORT3 && reg & BIT(11))) {
1374 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
developer2149cd92023-03-10 19:01:41 +08001375 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1376 MTK_PHY_LED0_ON_LINK100 |
1377 MTK_PHY_LED0_ON_LINK1000);
developer23021292022-10-21 19:10:10 +08001378 } else {
1379 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
developer2149cd92023-03-10 19:01:41 +08001380 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1381 MTK_PHY_LED0_ON_LINK10 |
1382 MTK_PHY_LED0_ON_LINK100 |
1383 MTK_PHY_LED0_ON_LINK1000);
developer23021292022-10-21 19:10:10 +08001384 }
developer8bc5dca2022-10-24 17:15:12 +08001385 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
developer2149cd92023-03-10 19:01:41 +08001386 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1387 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1388 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001389
developerf35532c2022-08-05 18:37:26 +08001390 mt7988_phy_finetune(phydev);
1391
1392 return mt798x_phy_calibration(phydev);
1393}
developer2149cd92023-03-10 19:01:41 +08001394#endif
developerf35532c2022-08-05 18:37:26 +08001395
developerc50c2352021-12-01 10:45:35 +08001396static struct phy_driver mtk_gephy_driver[] = {
developerc50c2352021-12-01 10:45:35 +08001397 {
1398 PHY_ID_MATCH_EXACT(0x03a29412),
1399 .name = "MediaTek MT7530 PHY",
1400 .config_init = mt7530_phy_config_init,
1401 /* Interrupts are handled by the switch, not the PHY
1402 * itself.
1403 */
1404 .config_intr = genphy_no_config_intr,
1405 .handle_interrupt = genphy_no_ack_interrupt,
1406 .suspend = genphy_suspend,
1407 .resume = genphy_resume,
1408 .read_page = mtk_gephy_read_page,
1409 .write_page = mtk_gephy_write_page,
1410 },
1411 {
1412 PHY_ID_MATCH_EXACT(0x03a29441),
1413 .name = "MediaTek MT7531 PHY",
1414 .config_init = mt7531_phy_config_init,
1415 /* Interrupts are handled by the switch, not the PHY
1416 * itself.
1417 */
1418 .config_intr = genphy_no_config_intr,
1419 .handle_interrupt = genphy_no_ack_interrupt,
1420 .suspend = genphy_suspend,
1421 .resume = genphy_resume,
1422 .read_page = mtk_gephy_read_page,
1423 .write_page = mtk_gephy_write_page,
1424 },
developer2149cd92023-03-10 19:01:41 +08001425#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
developerc50c2352021-12-01 10:45:35 +08001426 {
1427 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001428 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001429 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001430 .config_intr = genphy_no_config_intr,
1431 .handle_interrupt = genphy_no_ack_interrupt,
1432 .suspend = genphy_suspend,
1433 .resume = genphy_resume,
1434 .read_page = mtk_gephy_read_page,
1435 .write_page = mtk_gephy_write_page,
1436 },
1437 {
1438 PHY_ID_MATCH_EXACT(0x03a29481),
1439 .name = "MediaTek MT7988 PHY",
1440 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001441 .config_intr = genphy_no_config_intr,
1442 .handle_interrupt = genphy_no_ack_interrupt,
1443 .suspend = genphy_suspend,
1444 .resume = genphy_resume,
1445 .read_page = mtk_gephy_read_page,
1446 .write_page = mtk_gephy_write_page,
1447 },
developer2149cd92023-03-10 19:01:41 +08001448#endif
developerc50c2352021-12-01 10:45:35 +08001449};
1450
1451module_phy_driver(mtk_gephy_driver);
1452
1453static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1454 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1455 { }
1456};
1457
1458MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
developer2149cd92023-03-10 19:01:41 +08001459MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
1460MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
developerc50c2352021-12-01 10:45:35 +08001461MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1462MODULE_LICENSE("GPL");
1463
1464MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);