blob: b6f3f5e21b0bcf93bc9e71bca103b3e05ed7f018 [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
developer043f7b92023-03-13 13:57:36 +08009#define MTK_GPHY_ID_MT7530 0x03a29412
10#define MTK_GPHY_ID_MT7531 0x03a29441
11#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
12#define MTK_GPHY_ID_MT7981 0x03a29461
13#define MTK_GPHY_ID_MT7988 0x03a29481
14#endif
15
developerc50c2352021-12-01 10:45:35 +080016#define MTK_EXT_PAGE_ACCESS 0x1f
17#define MTK_PHY_PAGE_STANDARD 0x0000
18#define MTK_PHY_PAGE_EXTENDED 0x0001
19#define MTK_PHY_PAGE_EXTENDED_2 0x0002
20#define MTK_PHY_PAGE_EXTENDED_3 0x0003
21#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
22#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
23
developer2149cd92023-03-10 19:01:41 +080024#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
25#define ZCAL_CTRL_MIN (0)
26#define ZCAL_CTRL_MAX (63)
27#define TXRESERVE_MIN (0)
28#define TXRESERVE_MAX (7)
29
30#define MTK_PHY_ANARG_RG (0x10)
31#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
32
developerc50c2352021-12-01 10:45:35 +080033/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080034enum {
developerf35532c2022-08-05 18:37:26 +080035 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
36 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
37 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
38 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
39 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
40 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
41 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
42 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
43 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
44 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
45 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
46 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
47 MTK_PHY_TX_MLT3_END,
48};
developer02d84422021-12-24 11:48:07 +080049
developer2149cd92023-03-10 19:01:41 +080050#define MTK_PHY_TXVLD_DA_RG (0x12)
developerc50c2352021-12-01 10:45:35 +080051#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
52#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
53
developer2149cd92023-03-10 19:01:41 +080054#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
developerc50c2352021-12-01 10:45:35 +080055#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
56#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
57
developer2149cd92023-03-10 19:01:41 +080058#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
developerc50c2352021-12-01 10:45:35 +080059#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
60#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
61
developer2149cd92023-03-10 19:01:41 +080062#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
developerc50c2352021-12-01 10:45:35 +080063#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
64#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
65
developer2149cd92023-03-10 19:01:41 +080066#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
developerc50c2352021-12-01 10:45:35 +080067#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
68#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
69
developer2149cd92023-03-10 19:01:41 +080070#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
developerc50c2352021-12-01 10:45:35 +080071#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
72#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
73
developer2149cd92023-03-10 19:01:41 +080074#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
developerc50c2352021-12-01 10:45:35 +080075#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
76#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
77
developer2149cd92023-03-10 19:01:41 +080078#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
developerc50c2352021-12-01 10:45:35 +080079#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
80#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
81
developer2149cd92023-03-10 19:01:41 +080082#define MTK_PHY_TANA_CAL_MODE (0xc1)
83#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +080084
developer2149cd92023-03-10 19:01:41 +080085#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
developer57374032022-10-11 16:43:24 +080086#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
87
developer2149cd92023-03-10 19:01:41 +080088#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
89#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
90#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
91#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
92#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +080093
developer2149cd92023-03-10 19:01:41 +080094#define MTK_PHY_LDO_OUTPUT_V (0xd7)
developerce268312022-12-20 16:26:11 +080095
developer2149cd92023-03-10 19:01:41 +080096#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
97#define MTK_PHY_RG_CAL_CKINV BIT(12)
98#define MTK_PHY_RG_ANA_CALEN BIT(8)
99#define MTK_PHY_RG_REXT_CALEN BIT(4)
100#define MTK_PHY_RG_ZCALEN_A BIT(0)
developerc50c2352021-12-01 10:45:35 +0800101
developer2149cd92023-03-10 19:01:41 +0800102#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
103#define MTK_PHY_RG_ZCALEN_B BIT(12)
104#define MTK_PHY_RG_ZCALEN_C BIT(8)
105#define MTK_PHY_RG_ZCALEN_D BIT(4)
106#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
developerc50c2352021-12-01 10:45:35 +0800107
developer2149cd92023-03-10 19:01:41 +0800108#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
109#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
110#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
111#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
112#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
developerc50c2352021-12-01 10:45:35 +0800113
developer2149cd92023-03-10 19:01:41 +0800114#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
115#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
116#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800117
developer2149cd92023-03-10 19:01:41 +0800118#define MTK_PHY_RG_TX_FILTER (0xfe)
developer6de96aa2022-09-29 16:46:18 +0800119
developer2149cd92023-03-10 19:01:41 +0800120#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B (0x172)
developerc50c2352021-12-01 10:45:35 +0800121#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
122#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
123
developer2149cd92023-03-10 19:01:41 +0800124#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D (0x173)
developerc50c2352021-12-01 10:45:35 +0800125#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
126#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
127
developer2149cd92023-03-10 19:01:41 +0800128#define MTK_PHY_RG_AD_CAL_COMP (0x17a)
129#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +0800130
developer2149cd92023-03-10 19:01:41 +0800131#define MTK_PHY_RG_AD_CAL_CLK (0x17b)
132#define MTK_PHY_DA_CAL_CLK BIT(0)
developerc50c2352021-12-01 10:45:35 +0800133
developer2149cd92023-03-10 19:01:41 +0800134#define MTK_PHY_RG_AD_CALIN (0x17c)
135#define MTK_PHY_DA_CALIN_FLAG BIT(0)
developerc50c2352021-12-01 10:45:35 +0800136
developer2149cd92023-03-10 19:01:41 +0800137#define MTK_PHY_RG_DASN_DAC_IN0_A (0x17d)
138#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800139
developer2149cd92023-03-10 19:01:41 +0800140#define MTK_PHY_RG_DASN_DAC_IN0_B (0x17e)
141#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800142
developer2149cd92023-03-10 19:01:41 +0800143#define MTK_PHY_RG_DASN_DAC_IN0_C (0x17f)
144#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800145
developer2149cd92023-03-10 19:01:41 +0800146#define MTK_PHY_RG_DASN_DAC_IN0_D (0x180)
147#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800148
developer2149cd92023-03-10 19:01:41 +0800149#define MTK_PHY_RG_DASN_DAC_IN1_A (0x181)
150#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800151
developer2149cd92023-03-10 19:01:41 +0800152#define MTK_PHY_RG_DASN_DAC_IN1_B (0x182)
153#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800154
developer2149cd92023-03-10 19:01:41 +0800155#define MTK_PHY_RG_DASN_DAC_IN1_C (0x183)
156#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800157
developer2149cd92023-03-10 19:01:41 +0800158#define MTK_PHY_RG_DASN_DAC_IN1_D (0x180)
159#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800160
developer2149cd92023-03-10 19:01:41 +0800161#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
162#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
163#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
164#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
165#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
166#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
167#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
168#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
169#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
170#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
developer75819992023-03-08 20:49:03 +0800171
developer2149cd92023-03-10 19:01:41 +0800172#define MTK_PHY_RG_DEV1E_REG234 (0x234)
173#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
174#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
developerd2ec38e2022-11-27 01:15:29 +0800175
developer2149cd92023-03-10 19:01:41 +0800176#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
developerd2ec38e2022-11-27 01:15:29 +0800177
developer2149cd92023-03-10 19:01:41 +0800178#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
developerd2ec38e2022-11-27 01:15:29 +0800179#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
developer2149cd92023-03-10 19:01:41 +0800180#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
developerd2ec38e2022-11-27 01:15:29 +0800181#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800182
developer2149cd92023-03-10 19:01:41 +0800183#define MTK_PHY_LDO_PUMP_EN_PAIRAB (0x502)
184#define MTK_PHY_LDO_PUMP_EN_PAIRCD (0x503)
developer75819992023-03-08 20:49:03 +0800185
developer2149cd92023-03-10 19:01:41 +0800186#define MTK_PHY_DA_TX_R50_PAIR_A (0x53d)
187#define MTK_PHY_DA_TX_R50_PAIR_B (0x53e)
188#define MTK_PHY_DA_TX_R50_PAIR_C (0x53f)
189#define MTK_PHY_DA_TX_R50_PAIR_D (0x540)
developerc50c2352021-12-01 10:45:35 +0800190
191/* Registers on MDIO_MMD_VEND2 */
developer2149cd92023-03-10 19:01:41 +0800192#define MTK_PHY_LED0_ON_CTRL (0x24)
developer23021292022-10-21 19:10:10 +0800193#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
developer2149cd92023-03-10 19:01:41 +0800194#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
195#define MTK_PHY_LED0_ON_LINK100 BIT(1)
196#define MTK_PHY_LED0_ON_LINK10 BIT(2)
197#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
198#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
199#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
200#define MTK_PHY_LED0_FORCE_ON BIT(6)
201#define MTK_PHY_LED0_POLARITY BIT(14)
202#define MTK_PHY_LED0_ENABLE BIT(15)
developer23021292022-10-21 19:10:10 +0800203
developer2149cd92023-03-10 19:01:41 +0800204#define MTK_PHY_LED0_BLINK_CTRL (0x25)
205#define MTK_PHY_LED0_1000TX BIT(0)
206#define MTK_PHY_LED0_1000RX BIT(1)
207#define MTK_PHY_LED0_100TX BIT(2)
208#define MTK_PHY_LED0_100RX BIT(3)
209#define MTK_PHY_LED0_10TX BIT(4)
210#define MTK_PHY_LED0_10RX BIT(5)
211#define MTK_PHY_LED0_COLLISION BIT(6)
212#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
213#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
214#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
developer8bc5dca2022-10-24 17:15:12 +0800215
developer2149cd92023-03-10 19:01:41 +0800216#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
developerc50c2352021-12-01 10:45:35 +0800217#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
218
developer2149cd92023-03-10 19:01:41 +0800219#define MTK_PHY_RG_DASN_TXT_DMY2 (0x110)
220#define MTK_PHY_TST_DMY2_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800221
developer2149cd92023-03-10 19:01:41 +0800222#define MTK_PHY_RG_BG_RASEL (0x115)
223#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +0800224
developer2149cd92023-03-10 19:01:41 +0800225/* These macro privides efuse parsing for internal phy. */
226#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
227#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
228#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
229#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
230#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800231
developer2149cd92023-03-10 19:01:41 +0800232#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
233#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
234#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
235#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
236#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800237
developer2149cd92023-03-10 19:01:41 +0800238#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
239#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
240#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
241#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800242
developer2149cd92023-03-10 19:01:41 +0800243#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
244#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800245
developer2149cd92023-03-10 19:01:41 +0800246enum {
247 NO_PAIR,
developerc50c2352021-12-01 10:45:35 +0800248 PAIR_A,
249 PAIR_B,
250 PAIR_C,
251 PAIR_D,
developer2149cd92023-03-10 19:01:41 +0800252};
developerc50c2352021-12-01 10:45:35 +0800253
developer23021292022-10-21 19:10:10 +0800254enum {
255 GPHY_PORT0,
256 GPHY_PORT1,
257 GPHY_PORT2,
258 GPHY_PORT3,
259};
260
developer2149cd92023-03-10 19:01:41 +0800261enum calibration_mode {
262 EFUSE_K,
263 SW_K
264};
265
266enum CAL_ITEM {
267 REXT,
268 TX_OFFSET,
269 TX_AMP,
270 TX_R50,
271 TX_VCM
272};
273
274enum CAL_MODE {
275 SW_EFUSE_M,
276 EFUSE_M,
277 SW_M
278};
279
developerc50c2352021-12-01 10:45:35 +0800280const u8 mt798x_zcal_to_r50[64] = {
281 7, 8, 9, 9, 10, 10, 11, 11,
282 12, 13, 13, 14, 14, 15, 16, 16,
283 17, 18, 18, 19, 20, 21, 21, 22,
284 23, 24, 24, 25, 26, 27, 28, 29,
285 30, 31, 32, 33, 34, 35, 36, 37,
286 38, 40, 41, 42, 43, 45, 46, 48,
287 49, 51, 52, 54, 55, 57, 59, 61,
288 62, 63, 63, 63, 63, 63, 63, 63
289};
290
291const char pair[4] = {'A', 'B', 'C', 'D'};
292
developer2149cd92023-03-10 19:01:41 +0800293static int mtk_gephy_read_page(struct phy_device *phydev)
294{
295 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
296}
developerc50c2352021-12-01 10:45:35 +0800297
developer2149cd92023-03-10 19:01:41 +0800298static int mtk_gephy_write_page(struct phy_device *phydev, int page)
299{
300 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
301}
developerc50c2352021-12-01 10:45:35 +0800302
developer2149cd92023-03-10 19:01:41 +0800303static void mtk_gephy_config_init(struct phy_device *phydev)
304{
305 /* Disable EEE */
306 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
developerc50c2352021-12-01 10:45:35 +0800307
developer2149cd92023-03-10 19:01:41 +0800308 /* Enable HW auto downshift */
309 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
developerc50c2352021-12-01 10:45:35 +0800310
developer2149cd92023-03-10 19:01:41 +0800311 /* Increase SlvDPSready time */
312 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
313 __phy_write(phydev, 0x10, 0xafae);
314 __phy_write(phydev, 0x12, 0x2f);
315 __phy_write(phydev, 0x10, 0x8fae);
316 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerc50c2352021-12-01 10:45:35 +0800317
developer2149cd92023-03-10 19:01:41 +0800318 /* Adjust 100_mse_threshold */
319 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
developerc50c2352021-12-01 10:45:35 +0800320
developer2149cd92023-03-10 19:01:41 +0800321 /* Disable mcc */
322 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
323}
developerc50c2352021-12-01 10:45:35 +0800324
developer2149cd92023-03-10 19:01:41 +0800325static int mt7530_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800326{
developer2149cd92023-03-10 19:01:41 +0800327 mtk_gephy_config_init(phydev);
328
329 /* Increase post_update_timer */
330 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
331
332 return 0;
developerc50c2352021-12-01 10:45:35 +0800333}
334
developer2149cd92023-03-10 19:01:41 +0800335static int mt7531_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800336{
developer2149cd92023-03-10 19:01:41 +0800337 mtk_gephy_config_init(phydev);
338
339 /* PHY link down power saving enable */
340 phy_set_bits(phydev, 0x17, BIT(4));
341 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
342
343 /* Set TX Pair delay selection */
344 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
345 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
346
347 return 0;
developerc50c2352021-12-01 10:45:35 +0800348}
349
developer2149cd92023-03-10 19:01:41 +0800350#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
351/* One calibration cycle consists of:
developerc50c2352021-12-01 10:45:35 +0800352 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
353 * until AD_CAL_COMP is ready to output calibration result.
354 * 2.Wait until DA_CAL_CLK is available.
355 * 3.Fetch AD_CAL_COMP_OUT.
356 */
357static int cal_cycle(struct phy_device *phydev, int devad,
developer2149cd92023-03-10 19:01:41 +0800358 u32 regnum, u16 mask, u16 cal_val)
developerc50c2352021-12-01 10:45:35 +0800359{
360 unsigned long timeout;
361 int reg_val;
362 int ret;
363
364 phy_modify_mmd(phydev, devad, regnum,
developer2149cd92023-03-10 19:01:41 +0800365 mask, cal_val);
366 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
367 MTK_PHY_DA_CALIN_FLAG);
developerc50c2352021-12-01 10:45:35 +0800368
369 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
developer2149cd92023-03-10 19:01:41 +0800370 do {
371 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
372 MTK_PHY_RG_AD_CAL_CLK);
373 } while (time_before(jiffies, timeout) && !(reg_val & BIT(0)));
developerc50c2352021-12-01 10:45:35 +0800374
developer2149cd92023-03-10 19:01:41 +0800375 if (!(reg_val & BIT(0))) {
developerc50c2352021-12-01 10:45:35 +0800376 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
377 return -ETIMEDOUT;
378 }
379
developer2149cd92023-03-10 19:01:41 +0800380 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
381 MTK_PHY_DA_CALIN_FLAG);
382 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
383 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
developerc50c2352021-12-01 10:45:35 +0800384 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
385
386 return ret;
387}
388
389static int rext_fill_result(struct phy_device *phydev, u16 *buf)
390{
391 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800392 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
393 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
394 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
developerc50c2352021-12-01 10:45:35 +0800395
396 return 0;
397}
398
399static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
400{
401 u16 rext_cal_val[2];
402
403 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
404 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
405 rext_fill_result(phydev, rext_cal_val);
406
407 return 0;
408}
409
410static int rext_cal_sw(struct phy_device *phydev)
411{
412 u8 rg_zcal_ctrl_def;
413 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
414 u8 lower_ret, upper_ret;
415 u16 rext_cal_val[2];
416 int ret;
417
418 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800419 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
developerc50c2352021-12-01 10:45:35 +0800420 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800421 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800422 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800423 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN |
424 MTK_PHY_RG_REXT_CALEN);
425 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
426 MTK_PHY_TST_DMY2_MASK, 0x1);
developerc50c2352021-12-01 10:45:35 +0800427
developer2149cd92023-03-10 19:01:41 +0800428 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1,
429 MTK_PHY_RG_ANA_CAL_RG5) &
developerc50c2352021-12-01 10:45:35 +0800430 MTK_PHY_RG_ZCAL_CTRL_MASK;
431 zcal_lower = ZCAL_CTRL_MIN;
432 zcal_upper = ZCAL_CTRL_MAX;
433
434 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800435 while ((zcal_upper - zcal_lower) > 1) {
436 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower + zcal_upper, 2);
developerc50c2352021-12-01 10:45:35 +0800437 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
438 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer2149cd92023-03-10 19:01:41 +0800439 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800440 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800441 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800442 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800443 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800444 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800445 } else {
developerc50c2352021-12-01 10:45:35 +0800446 goto restore;
developer2149cd92023-03-10 19:01:41 +0800447 }
developerc50c2352021-12-01 10:45:35 +0800448 }
449
developer2149cd92023-03-10 19:01:41 +0800450 if (zcal_lower == ZCAL_CTRL_MIN) {
451 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
452 MTK_PHY_RG_ANA_CAL_RG5,
453 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
454 ret = lower_ret;
455 } else if (zcal_upper == ZCAL_CTRL_MAX) {
456 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
457 MTK_PHY_RG_ANA_CAL_RG5,
458 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
459 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800460 }
461 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800462 goto restore;
463
developer2149cd92023-03-10 19:01:41 +0800464 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800465 if (ret == 1) {
466 rext_cal_val[0] = zcal_upper;
467 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800468 rext_fill_result(phydev, rext_cal_val);
developer2149cd92023-03-10 19:01:41 +0800469 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n",
470 zcal_upper);
developerc50c2352021-12-01 10:45:35 +0800471 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800472 } else {
developerc50c2352021-12-01 10:45:35 +0800473 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800474 }
developerc50c2352021-12-01 10:45:35 +0800475
476restore:
developer2149cd92023-03-10 19:01:41 +0800477 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
478 MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developerc50c2352021-12-01 10:45:35 +0800479 MTK_PHY_ANA_TEST_MODE_MASK);
480 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800481 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN |
482 MTK_PHY_RG_REXT_CALEN);
483 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
484 MTK_PHY_TST_DMY2_MASK);
developerc50c2352021-12-01 10:45:35 +0800485 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
486 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
487
488 return ret;
489}
490
491static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
492{
developer2149cd92023-03-10 19:01:41 +0800493 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800494 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
developer2149cd92023-03-10 19:01:41 +0800495 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800496 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
developer2149cd92023-03-10 19:01:41 +0800497 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800498 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
developer2149cd92023-03-10 19:01:41 +0800499 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800500 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
501
502 return 0;
503}
504
505static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
506{
507 u16 tx_offset_cal_val[4];
508
509 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
510 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
511 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
512 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
513
514 tx_offset_fill_result(phydev, tx_offset_cal_val);
515
516 return 0;
517}
518
519static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
520{
developerd2ec38e2022-11-27 01:15:29 +0800521 int i;
developer87c89d12022-08-19 17:46:34 +0800522 int bias[16] = {0};
developer2149cd92023-03-10 19:01:41 +0800523 const int vals_9461[16] = { 7, 1, 4, 7,
524 7, 1, 4, 7,
525 7, 1, 4, 7,
526 7, 1, 4, 7 };
527 const int vals_9481[16] = { 10, 6, 6, 10,
528 10, 6, 6, 10,
529 10, 6, 6, 10,
530 10, 6, 6, 10 };
531
532 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800533 case MTK_GPHY_ID_MT7981:
developer2149cd92023-03-10 19:01:41 +0800534 /* We add some calibration to efuse values
535 * due to board level influence.
536 * GBE: +7, TBT: +1, HBT: +4, TST: +7
537 */
538 memcpy(bias, (const void *)vals_9461, sizeof(bias));
539 for (i = 0; i <= 12; i += 4) {
540 if (likely(buf[i >> 2] + bias[i] >= 32)) {
541 bias[i] -= 13;
542 } else {
543 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
544 0x5c, 0x7 << i, bias[i] << i);
545 bias[i + 1] += 13;
546 bias[i + 2] += 13;
547 bias[i + 3] += 13;
548 }
developer87c89d12022-08-19 17:46:34 +0800549 }
developer2149cd92023-03-10 19:01:41 +0800550 break;
developer043f7b92023-03-13 13:57:36 +0800551 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800552 memcpy(bias, (const void *)vals_9481, sizeof(bias));
553 break;
554 default:
555 break;
developer87c89d12022-08-19 17:46:34 +0800556 }
developerd2ec38e2022-11-27 01:15:29 +0800557
developerdc3e9502022-12-02 18:10:42 +0800558 /* Prevent overflow */
559 for (i = 0; i < 12; i++) {
developer2149cd92023-03-10 19:01:41 +0800560 if (buf[i >> 2] + bias[i] > 63) {
561 buf[i >> 2] = 63;
developerdc3e9502022-12-02 18:10:42 +0800562 bias[i] = 0;
developer2149cd92023-03-10 19:01:41 +0800563 } else if (buf[i >> 2] + bias[i] < 0) {
developerdc3e9502022-12-02 18:10:42 +0800564 /* Bias caused by board design may change in the future.
565 * So check negative cases, too.
566 */
developer2149cd92023-03-10 19:01:41 +0800567 buf[i >> 2] = 0;
developerdc3e9502022-12-02 18:10:42 +0800568 bias[i] = 0;
569 }
570 }
571
developerc50c2352021-12-01 10:45:35 +0800572 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800573 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800574 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800575 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800576 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800577 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800578 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800579 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800580
581 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800582 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800583 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800584 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800585 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800586 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800587 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800588 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800589
590 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800591 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800592 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800593 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800594 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800595 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800596 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800597 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800598
599 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800600 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800601 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800602 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800603 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800604 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800605 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800606 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800607
608 return 0;
609}
610
611static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
612{
613 u16 tx_amp_cal_val[4];
614
615 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
616 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
617 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
618 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
619 tx_amp_fill_result(phydev, tx_amp_cal_val);
620
621 return 0;
622}
623
developer2149cd92023-03-10 19:01:41 +0800624static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
625 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800626{
developer2149cd92023-03-10 19:01:41 +0800627 int bias = 0;
628 u16 reg, val;
developer87c89d12022-08-19 17:46:34 +0800629
developer2149cd92023-03-10 19:01:41 +0800630 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800631 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800632 {
633 bias = -2;
634 break;
developerdc3e9502022-12-02 18:10:42 +0800635 }
developer043f7b92023-03-13 13:57:36 +0800636 /* MTK_GPHY_ID_MT7981 enters default case */
developer2149cd92023-03-10 19:01:41 +0800637 default:
638 break;
639 }
640
641 val = clamp_val(bias + tx_r50_cal_val, 0, 63);
642
643 switch (txg_calen_x) {
644 case PAIR_A:
645 reg = MTK_PHY_DA_TX_R50_PAIR_A;
646 break;
647 case PAIR_B:
648 reg = MTK_PHY_DA_TX_R50_PAIR_B;
649 break;
650 case PAIR_C:
651 reg = MTK_PHY_DA_TX_R50_PAIR_C;
652 break;
653 case PAIR_D:
654 reg = MTK_PHY_DA_TX_R50_PAIR_D;
655 break;
developerc50c2352021-12-01 10:45:35 +0800656 }
developer2149cd92023-03-10 19:01:41 +0800657
658 phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
659
developerc50c2352021-12-01 10:45:35 +0800660 return 0;
661}
662
663static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
developer2149cd92023-03-10 19:01:41 +0800664 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800665{
developer2149cd92023-03-10 19:01:41 +0800666 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800667
developer2149cd92023-03-10 19:01:41 +0800668 switch (txg_calen_x) {
669 case PAIR_A:
670 tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
671 break;
672 case PAIR_B:
673 tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
674 break;
675 case PAIR_C:
676 tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
677 break;
678 case PAIR_D:
679 tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
680 break;
developerc50c2352021-12-01 10:45:35 +0800681 }
682 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
683
684 return 0;
685}
686
developer2149cd92023-03-10 19:01:41 +0800687static int tx_r50_cal_sw(struct phy_device *phydev, u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800688{
developerc50c2352021-12-01 10:45:35 +0800689 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
690 u8 lower_ret, upper_ret;
developer2149cd92023-03-10 19:01:41 +0800691 u8 rg_zcal_ctrl_def;
692 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800693 int ret;
694
695 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800696 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
developerc50c2352021-12-01 10:45:35 +0800697 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800698 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800699 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800700 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800701 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
developer2149cd92023-03-10 19:01:41 +0800702 BIT(txg_calen_x * 4));
703 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
704 MTK_PHY_TST_DMY2_MASK, 0x1);
developerc50c2352021-12-01 10:45:35 +0800705
developer2149cd92023-03-10 19:01:41 +0800706 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1,
707 MTK_PHY_RG_ANA_CAL_RG5) &
708 MTK_PHY_RG_ZCAL_CTRL_MASK;
developerc50c2352021-12-01 10:45:35 +0800709 zcal_lower = ZCAL_CTRL_MIN;
710 zcal_upper = ZCAL_CTRL_MAX;
711
developer2149cd92023-03-10 19:01:41 +0800712 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n",
713 pair[txg_calen_x]);
714 while ((zcal_upper - zcal_lower) > 1) {
715 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower + zcal_upper, 2);
developerc50c2352021-12-01 10:45:35 +0800716 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
717 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer2149cd92023-03-10 19:01:41 +0800718 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800719 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800720 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800721 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800722 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800723 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800724 } else {
developerc50c2352021-12-01 10:45:35 +0800725 goto restore;
developer2149cd92023-03-10 19:01:41 +0800726 }
developerc50c2352021-12-01 10:45:35 +0800727 }
728
developer2149cd92023-03-10 19:01:41 +0800729 if (zcal_lower == ZCAL_CTRL_MIN) {
730 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
731 MTK_PHY_RG_ANA_CAL_RG5,
732 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
733 ret = lower_ret;
734 } else if (zcal_upper == ZCAL_CTRL_MAX) {
735 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
736 MTK_PHY_RG_ANA_CAL_RG5,
737 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
738 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800739 }
740 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800741 goto restore;
742
developer2149cd92023-03-10 19:01:41 +0800743 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800744 if (ret == 1) {
developer2149cd92023-03-10 19:01:41 +0800745 tx_r50_cal_val = mt798x_zcal_to_r50[zcal_upper];
developerc50c2352021-12-01 10:45:35 +0800746 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer2149cd92023-03-10 19:01:41 +0800747 dev_info(&phydev->mdio.dev,
748 "TX-R50 Pair%c SW cal result: 0x%x\n",
749 pair[txg_calen_x], zcal_lower);
developerc50c2352021-12-01 10:45:35 +0800750 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800751 } else {
developerc50c2352021-12-01 10:45:35 +0800752 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800753 }
developerc50c2352021-12-01 10:45:35 +0800754
755restore:
756 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
developer2149cd92023-03-10 19:01:41 +0800757 MTK_PHY_ANA_TEST_MODE_MASK);
developerc50c2352021-12-01 10:45:35 +0800758 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800759 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800760 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
developer2149cd92023-03-10 19:01:41 +0800761 BIT(txg_calen_x * 4));
762 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DASN_TXT_DMY2,
763 MTK_PHY_TST_DMY2_MASK);
developerc50c2352021-12-01 10:45:35 +0800764 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800765 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
developerc50c2352021-12-01 10:45:35 +0800766
767 return ret;
768}
769
developer2149cd92023-03-10 19:01:41 +0800770static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
developerc50c2352021-12-01 10:45:35 +0800771{
772 u8 lower_idx, upper_idx, txreserve_val;
773 u8 lower_ret, upper_ret;
774 int ret;
775
776 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800777 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800778 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800779 MTK_PHY_RG_CAL_CKINV);
developerc50c2352021-12-01 10:45:35 +0800780 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800781 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800782
developer2149cd92023-03-10 19:01:41 +0800783 switch (rg_txreserve_x) {
784 case PAIR_A:
785 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
786 MTK_PHY_RG_DASN_DAC_IN0_A,
787 MTK_PHY_DASN_DAC_IN0_A_MASK);
788 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
789 MTK_PHY_RG_DASN_DAC_IN1_A,
790 MTK_PHY_DASN_DAC_IN1_A_MASK);
791 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
792 MTK_PHY_RG_ANA_CAL_RG0,
793 MTK_PHY_RG_ZCALEN_A);
794 break;
795 case PAIR_B:
796 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
797 MTK_PHY_RG_DASN_DAC_IN0_B,
798 MTK_PHY_DASN_DAC_IN0_B_MASK);
799 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
800 MTK_PHY_RG_DASN_DAC_IN1_B,
801 MTK_PHY_DASN_DAC_IN1_B_MASK);
802 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
803 MTK_PHY_RG_ANA_CAL_RG1,
804 MTK_PHY_RG_ZCALEN_B);
805 break;
806 case PAIR_C:
807 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
808 MTK_PHY_RG_DASN_DAC_IN0_C,
809 MTK_PHY_DASN_DAC_IN0_C_MASK);
810 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
811 MTK_PHY_RG_DASN_DAC_IN1_C,
812 MTK_PHY_DASN_DAC_IN1_C_MASK);
813 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
814 MTK_PHY_RG_ANA_CAL_RG1,
815 MTK_PHY_RG_ZCALEN_C);
816 break;
817 case PAIR_D:
818 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
819 MTK_PHY_RG_DASN_DAC_IN0_D,
820 MTK_PHY_DASN_DAC_IN0_D_MASK);
821 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
822 MTK_PHY_RG_DASN_DAC_IN1_D,
823 MTK_PHY_DASN_DAC_IN1_D_MASK);
824 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
825 MTK_PHY_RG_ANA_CAL_RG1,
826 MTK_PHY_RG_ZCALEN_D);
827 break;
828 default:
829 ret = -EINVAL;
830 goto restore;
developerc50c2352021-12-01 10:45:35 +0800831 }
832
833 lower_idx = TXRESERVE_MIN;
834 upper_idx = TXRESERVE_MAX;
835
836 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800837 while ((upper_idx - lower_idx) > 1) {
838 txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
developerc50c2352021-12-01 10:45:35 +0800839 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800840 MTK_PHY_DA_RX_PSBN_TBT_MASK |
841 MTK_PHY_DA_RX_PSBN_HBT_MASK |
842 MTK_PHY_DA_RX_PSBN_GBE_MASK |
843 MTK_PHY_DA_RX_PSBN_LP_MASK,
developerc50c2352021-12-01 10:45:35 +0800844 txreserve_val << 12 | txreserve_val << 8 |
845 txreserve_val << 4 | txreserve_val);
developer2149cd92023-03-10 19:01:41 +0800846 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800847 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800848 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800849 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800850 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800851 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800852 } else {
developerc50c2352021-12-01 10:45:35 +0800853 goto restore;
developer2149cd92023-03-10 19:01:41 +0800854 }
developerc50c2352021-12-01 10:45:35 +0800855 }
856
developer2149cd92023-03-10 19:01:41 +0800857 if (lower_idx == TXRESERVE_MIN) {
858 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
859 MTK_PHY_RXADC_CTRL_RG9,
860 MTK_PHY_DA_RX_PSBN_TBT_MASK |
861 MTK_PHY_DA_RX_PSBN_HBT_MASK |
862 MTK_PHY_DA_RX_PSBN_GBE_MASK |
863 MTK_PHY_DA_RX_PSBN_LP_MASK,
864 lower_idx << 12 | lower_idx << 8 |
865 lower_idx << 4 | lower_idx);
866 ret = lower_ret;
867 } else if (upper_idx == TXRESERVE_MAX) {
868 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
869 MTK_PHY_RXADC_CTRL_RG9,
870 MTK_PHY_DA_RX_PSBN_TBT_MASK |
871 MTK_PHY_DA_RX_PSBN_HBT_MASK |
872 MTK_PHY_DA_RX_PSBN_GBE_MASK |
873 MTK_PHY_DA_RX_PSBN_LP_MASK,
874 upper_idx << 12 | upper_idx << 8 |
875 upper_idx << 4 | upper_idx);
876 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800877 }
878 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800879 goto restore;
880
developer78aa7b92021-12-29 15:22:10 +0800881 /* We calibrate TX-VCM in different logic. Check upper index and then
882 * lower index. If this calibration is valid, apply lower index's result.
883 */
developer2149cd92023-03-10 19:01:41 +0800884 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800885 if (ret == 1) {
886 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800887 /* Make sure we use upper_idx in our calibration system */
888 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800889 MTK_PHY_DA_RX_PSBN_TBT_MASK |
890 MTK_PHY_DA_RX_PSBN_HBT_MASK |
891 MTK_PHY_DA_RX_PSBN_GBE_MASK |
892 MTK_PHY_DA_RX_PSBN_LP_MASK,
893 upper_idx << 12 | upper_idx << 8 |
894 upper_idx << 4 | upper_idx);
895 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n",
896 upper_idx);
897 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
898 lower_ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800899 ret = 0;
900 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800901 MTK_PHY_DA_RX_PSBN_TBT_MASK |
902 MTK_PHY_DA_RX_PSBN_HBT_MASK |
903 MTK_PHY_DA_RX_PSBN_GBE_MASK |
904 MTK_PHY_DA_RX_PSBN_LP_MASK,
905 lower_idx << 12 | lower_idx << 8 |
906 lower_idx << 4 | lower_idx);
907 dev_warn(&phydev->mdio.dev,
908 "TX-VCM SW cal result at low margin 0x%x\n",
909 lower_idx);
910 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
911 lower_ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800912 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800913 dev_warn(&phydev->mdio.dev,
914 "TX-VCM SW cal result at high margin 0x%x\n",
915 upper_idx);
916 } else {
developerc50c2352021-12-01 10:45:35 +0800917 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800918 }
developerc50c2352021-12-01 10:45:35 +0800919
920restore:
921 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800922 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800923 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800924 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800925 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800926 MTK_PHY_RG_ZCALEN_A);
developerc50c2352021-12-01 10:45:35 +0800927 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800928 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
929 MTK_PHY_RG_ZCALEN_D);
developerc50c2352021-12-01 10:45:35 +0800930
931 return ret;
932}
933
developerf35532c2022-08-05 18:37:26 +0800934static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800935{
developerd2ec38e2022-11-27 01:15:29 +0800936 u32 i;
developer2149cd92023-03-10 19:01:41 +0800937
developer02d84422021-12-24 11:48:07 +0800938 /* 100M eye finetune:
939 * Keep middle level of TX MLT3 shapper as default.
940 * Only change TX MLT3 overshoot level here.
941 */
developer2149cd92023-03-10 19:01:41 +0800942 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
943 0x1ce);
944 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
945 0x1c1);
946 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
947 0x20f);
948 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
949 0x202);
950 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
951 0x3d0);
952 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
953 0x3c0);
954 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
955 0x13);
956 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
957 0x5);
developerf35532c2022-08-05 18:37:26 +0800958
developer02d84422021-12-24 11:48:07 +0800959 /* TX-AMP finetune:
960 * 100M +4, 1000M +6 to default value.
961 * If efuse values aren't valid, TX-AMP uses the below values.
962 */
963 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
developer2149cd92023-03-10 19:01:41 +0800964 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
965 0x9026);
966 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
967 0x2624);
968 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
969 0x2426);
970 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
971 0x2624);
972 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
973 0x2426);
974 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
975 0x2624);
976 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
977 0x2426);
developer68f6e102022-11-22 17:35:00 +0800978
developerd2ec38e2022-11-27 01:15:29 +0800979 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
980 /* EnabRandUpdTrig = 1 */
981 __phy_write(phydev, 0x11, 0x2f00);
982 __phy_write(phydev, 0x12, 0xe);
983 __phy_write(phydev, 0x10, 0x8fb0);
984
developer2149cd92023-03-10 19:01:41 +0800985 /* SlvDSPreadyTime = 0xc */
986 __phy_write(phydev, 0x11, 0x671);
developerd2ec38e2022-11-27 01:15:29 +0800987 __phy_write(phydev, 0x12, 0xc);
988 __phy_write(phydev, 0x10, 0x8fae);
989
990 /* NormMseLoThresh = 85 */
991 __phy_write(phydev, 0x11, 0x55a0);
992 __phy_write(phydev, 0x12, 0x0);
993 __phy_write(phydev, 0x10, 0x83aa);
994
995 /* InhibitDisableDfeTail1000 = 1 */
996 __phy_write(phydev, 0x11, 0x2b);
997 __phy_write(phydev, 0x12, 0x0);
998 __phy_write(phydev, 0x10, 0x8f80);
999
developer2149cd92023-03-10 19:01:41 +08001000 /* SSTr related */
developerd2ec38e2022-11-27 01:15:29 +08001001 __phy_write(phydev, 0x11, 0xbaef);
1002 __phy_write(phydev, 0x12, 0x2e);
1003 __phy_write(phydev, 0x10, 0x968c);
1004
1005 /* VcoSlicerThreshBitsHigh */
1006 __phy_write(phydev, 0x11, 0x5555);
1007 __phy_write(phydev, 0x12, 0x55);
1008 __phy_write(phydev, 0x10, 0x8ec0);
1009
1010 /* ResetSyncOffset = 6 */
1011 __phy_write(phydev, 0x11, 0x600);
1012 __phy_write(phydev, 0x12, 0x0);
1013 __phy_write(phydev, 0x10, 0x8fc0);
1014
1015 /* VgaDecRate = 1 */
1016 __phy_write(phydev, 0x11, 0x4c2a);
1017 __phy_write(phydev, 0x12, 0x3e);
1018 __phy_write(phydev, 0x10, 0x8fa4);
1019
1020 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerd2ec38e2022-11-27 01:15:29 +08001021 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +08001022 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +08001023 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1024 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerd2ec38e2022-11-27 01:15:29 +08001025
1026 /* rg_tr_lpf_cnt_val = 512 */
1027 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1028
1029 /* IIR2 related */
1030 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1031 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1032 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1033 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1034 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1035 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1036 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1037 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1038 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1039 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1040
1041 /* FFE peaking */
1042 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +08001043 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerd2ec38e2022-11-27 01:15:29 +08001044 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +08001045 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerd2ec38e2022-11-27 01:15:29 +08001046
1047 /* TX shape */
1048 /* 10/100/1000 TX shaper is enabled by default */
1049 for (i = 0x202; i < 0x230; i += 2) {
1050 if (i == 0x20c || i == 0x218 || i == 0x224)
1051 continue;
1052 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +08001053 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerd2ec38e2022-11-27 01:15:29 +08001054 }
developer02d84422021-12-24 11:48:07 +08001055}
1056
developerf35532c2022-08-05 18:37:26 +08001057static inline void mt7988_phy_finetune(struct phy_device *phydev)
1058{
developer2149cd92023-03-10 19:01:41 +08001059 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
1060 0x020d, 0x0206, 0x0384, 0x03d0,
1061 0x03c6, 0x030a, 0x0011, 0x0005 };
developerf35532c2022-08-05 18:37:26 +08001062 int i;
developerf35532c2022-08-05 18:37:26 +08001063
developer2149cd92023-03-10 19:01:41 +08001064 for (i = 0; i < MTK_PHY_TX_MLT3_END; i++)
developerf35532c2022-08-05 18:37:26 +08001065 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
developer6de96aa2022-09-29 16:46:18 +08001066
developer57374032022-10-11 16:43:24 +08001067 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001068 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001069
1070 /* Disable TX power saving */
1071 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developer2149cd92023-03-10 19:01:41 +08001072 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001073
developerec2b8552022-10-17 15:30:59 +08001074 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +08001075 /* EnabRandUpdTrig = 1 */
1076 __phy_write(phydev, 0x11, 0x2f00);
1077 __phy_write(phydev, 0x12, 0xe);
1078 __phy_write(phydev, 0x10, 0x8fb0);
1079
developer2149cd92023-03-10 19:01:41 +08001080 /* SlvDSPreadyTime = 0xc */
developerce73ad62022-12-07 22:43:45 +08001081 __phy_write(phydev, 0x11, 0x671);
1082 __phy_write(phydev, 0x12, 0xc);
1083 __phy_write(phydev, 0x10, 0x8fae);
1084
1085 /* NormMseLoThresh = 85 */
1086 __phy_write(phydev, 0x11, 0x55a0);
developerec2b8552022-10-17 15:30:59 +08001087 __phy_write(phydev, 0x12, 0x0);
developerce73ad62022-12-07 22:43:45 +08001088 __phy_write(phydev, 0x10, 0x83aa);
1089
1090 /* InhibitDisableDfeTail1000 = 1 */
1091 __phy_write(phydev, 0x11, 0x2b);
1092 __phy_write(phydev, 0x12, 0x0);
1093 __phy_write(phydev, 0x10, 0x8f80);
1094
1095 /* SSTr related */
1096 __phy_write(phydev, 0x11, 0xbaef);
1097 __phy_write(phydev, 0x12, 0x2e);
1098 __phy_write(phydev, 0x10, 0x968c);
1099
1100 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
1101 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
1102 */
1103 __phy_write(phydev, 0x11, 0xd10a);
1104 __phy_write(phydev, 0x12, 0x34);
1105 __phy_write(phydev, 0x10, 0x8f82);
1106
1107 /* VcoSlicerThreshBitsHigh */
1108 __phy_write(phydev, 0x11, 0x5555);
1109 __phy_write(phydev, 0x12, 0x55);
1110 __phy_write(phydev, 0x10, 0x8ec0);
1111
developerce268312022-12-20 16:26:11 +08001112 /* ResetSyncOffset = 5 */
1113 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +08001114 __phy_write(phydev, 0x12, 0x0);
1115 __phy_write(phydev, 0x10, 0x8fc0);
developerb5c72b02022-12-21 15:51:07 +08001116 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001117
developerce268312022-12-20 16:26:11 +08001118 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
1119 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +08001120 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developer2149cd92023-03-10 19:01:41 +08001121 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +08001122 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001123
1124 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
1125 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +08001126 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1127 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerce73ad62022-12-07 22:43:45 +08001128
1129 /* rg_tr_lpf_cnt_val = 512 */
1130 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1131
1132 /* IIR2 related */
1133 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1134 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1135 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1136 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1137 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1138 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1139 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1140 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1141 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1142 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1143
1144 /* FFE peaking */
1145 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +08001146 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerce73ad62022-12-07 22:43:45 +08001147 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +08001148 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerce73ad62022-12-07 22:43:45 +08001149
1150 /* TX shape */
1151 /* 10/100/1000 TX shaper is enabled by default */
1152 for (i = 0x202; i < 0x230; i += 2) {
1153 if (i == 0x20c || i == 0x218 || i == 0x224)
1154 continue;
1155 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +08001156 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerce73ad62022-12-07 22:43:45 +08001157 }
developerce268312022-12-20 16:26:11 +08001158
1159 /* Disable LDO pump */
1160 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
1161 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
1162
1163 /* Adjust LDO output voltage */
developerb5c72b02022-12-21 15:51:07 +08001164 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developer2149cd92023-03-10 19:01:41 +08001165}
developer75819992023-03-08 20:49:03 +08001166
developer2149cd92023-03-10 19:01:41 +08001167static inline int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
1168 u8 start_pair, u8 end_pair)
1169{
1170 u8 pair_n;
1171 int ret;
1172
1173 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1174 /* TX_OFFSET & TX_AMP have no SW calibration. */
1175 switch (cal_item) {
1176 case REXT:
1177 ret = rext_cal_sw(phydev);
1178 break;
1179 case TX_R50:
1180 ret = tx_r50_cal_sw(phydev, pair_n);
1181 break;
1182 case TX_VCM:
1183 ret = tx_vcm_cal_sw(phydev, pair_n);
1184 break;
1185 default:
1186 return -EINVAL;
1187 }
1188 if (ret)
1189 return ret;
1190 }
1191 return 0;
developerf35532c2022-08-05 18:37:26 +08001192}
1193
developer2149cd92023-03-10 19:01:41 +08001194static inline int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
1195 u8 start_pair, u8 end_pair, u32 *buf)
1196{
1197 u8 pair_n;
1198 int ret;
1199
1200 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1201 /* TX_VCM has no efuse calibration. */
1202 switch (cal_item) {
1203 case REXT:
1204 ret = rext_cal_efuse(phydev, buf);
1205 break;
1206 case TX_OFFSET:
1207 ret = tx_offset_cal_efuse(phydev, buf);
1208 break;
1209 case TX_AMP:
1210 ret = tx_amp_cal_efuse(phydev, buf);
1211 break;
1212 case TX_R50:
1213 ret = tx_r50_cal_efuse(phydev, buf, pair_n);
1214 break;
1215 default:
1216 return -EINVAL;
1217 }
1218 if (ret)
1219 return ret;
1220 }
1221
1222 return 0;
1223}
1224
1225static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
1226 bool efs_valid, enum CAL_MODE cal_mode, u8 start_pair,
1227 u8 end_pair, u32 *buf)
1228{
1229 char cal_prop[5][20] = { "mediatek,rext", "mediatek,tx_offset",
1230 "mediatek,tx_amp", "mediatek,tx_r50",
1231 "mediatek,tx_vcm" };
1232 const char *dts_cal_mode;
1233 u8 final_cal_mode = 0;
1234 bool is_cal = true;
1235 int ret, cal_ret;
1236
1237 ret = of_property_read_string(phydev->mdio.dev.of_node,
1238 cal_prop[cal_item], &dts_cal_mode);
1239
1240 switch (cal_mode) {
1241 case SW_EFUSE_M:
1242 if ((efs_valid && ret) ||
1243 (efs_valid && !ret && strcmp("efuse", dts_cal_mode) == 0)) {
1244 cal_ret = cal_efuse(phydev, cal_item, start_pair,
1245 end_pair, buf);
1246 final_cal_mode = EFUSE_K;
1247 } else if ((!efs_valid && ret) ||
1248 (!ret && strcmp("sw", dts_cal_mode) == 0)) {
1249 cal_ret = cal_sw(phydev, cal_item, start_pair, end_pair);
1250 final_cal_mode = SW_K;
1251 } else {
1252 is_cal = false;
1253 }
1254 break;
1255 case EFUSE_M:
1256 if ((efs_valid && ret) ||
1257 (efs_valid && !ret && strcmp("efuse", dts_cal_mode) == 0)) {
1258 cal_ret = cal_efuse(phydev, cal_item, start_pair,
1259 end_pair, buf);
1260 final_cal_mode = EFUSE_K;
1261 } else {
1262 is_cal = false;
1263 }
1264 break;
1265 case SW_M:
1266 if (ret || (!ret && strcmp("sw", dts_cal_mode) == 0)) {
1267 cal_ret = cal_sw(phydev, cal_item, start_pair, end_pair);
1268 final_cal_mode = SW_K;
1269 } else {
1270 is_cal = false;
1271 }
1272 break;
1273 default:
1274 return -EINVAL;
1275 }
1276
1277 if (cal_ret) {
1278 dev_err(&phydev->mdio.dev, "[%s]cal failed\n", cal_prop[cal_item]);
1279 return -EIO;
1280 }
1281
1282 if (!is_cal) {
1283 dev_dbg(&phydev->mdio.dev, "[%s]K mode: %s(not supported)\n",
1284 cal_prop[cal_item], dts_cal_mode);
1285 return -EIO;
1286 }
1287
1288 dev_dbg(&phydev->mdio.dev, "[%s]K mode: %s(dts: %s), efs-valid: %s\n",
1289 cal_prop[cal_item],
1290 final_cal_mode ? "SW" : "EFUSE",
1291 ret ? "not set" : dts_cal_mode,
1292 efs_valid ? "yes" : "no");
1293 return 0;
1294}
1295
developerf35532c2022-08-05 18:37:26 +08001296static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001297{
developer2149cd92023-03-10 19:01:41 +08001298 int ret = 0;
developerc50c2352021-12-01 10:45:35 +08001299 u32 *buf;
1300 bool efs_valid = true;
1301 size_t len;
1302 struct nvmem_cell *cell;
1303
1304 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1305 return -EINVAL;
1306
1307 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1308 if (IS_ERR(cell)) {
1309 if (PTR_ERR(cell) == -EPROBE_DEFER)
1310 return PTR_ERR(cell);
1311 return 0;
1312 }
1313
1314 buf = (u32 *)nvmem_cell_read(cell, &len);
1315 if (IS_ERR(buf))
1316 return PTR_ERR(buf);
1317 nvmem_cell_put(cell);
1318
developer2149cd92023-03-10 19:01:41 +08001319 if (!buf[0] || !buf[1] || !buf[2] || !buf[3])
developerc50c2352021-12-01 10:45:35 +08001320 efs_valid = false;
1321
1322 if (len < 4 * sizeof(u32)) {
1323 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1324 ret = -EINVAL;
1325 goto out;
1326 }
1327
developer2149cd92023-03-10 19:01:41 +08001328 ret = start_cal(phydev, REXT, efs_valid, SW_EFUSE_M,
1329 NO_PAIR, NO_PAIR, buf);
1330 if (ret)
1331 goto out;
1332 ret = start_cal(phydev, TX_OFFSET, efs_valid, EFUSE_M,
1333 NO_PAIR, NO_PAIR, buf);
1334 if (ret)
1335 goto out;
1336 ret = start_cal(phydev, TX_AMP, efs_valid, EFUSE_M,
1337 NO_PAIR, NO_PAIR, buf);
1338 if (ret)
1339 goto out;
1340 ret = start_cal(phydev, TX_R50, efs_valid, EFUSE_M,
1341 PAIR_A, PAIR_D, buf);
1342 if (ret)
1343 goto out;
1344 ret = start_cal(phydev, TX_VCM, efs_valid, SW_M,
1345 PAIR_A, PAIR_A, buf);
1346 if (ret)
1347 goto out;
developerc50c2352021-12-01 10:45:35 +08001348
1349out:
1350 kfree(buf);
1351 return ret;
1352}
1353
developer68f6e102022-11-22 17:35:00 +08001354static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001355{
1356 mt7981_phy_finetune(phydev);
1357
1358 return mt798x_phy_calibration(phydev);
1359}
1360
developer68f6e102022-11-22 17:35:00 +08001361static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001362{
1363 mt7988_phy_finetune(phydev);
1364
1365 return mt798x_phy_calibration(phydev);
1366}
developer2149cd92023-03-10 19:01:41 +08001367#endif
developerf35532c2022-08-05 18:37:26 +08001368
developerc50c2352021-12-01 10:45:35 +08001369static struct phy_driver mtk_gephy_driver[] = {
developerc50c2352021-12-01 10:45:35 +08001370 {
developer043f7b92023-03-13 13:57:36 +08001371 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
developerc50c2352021-12-01 10:45:35 +08001372 .name = "MediaTek MT7530 PHY",
1373 .config_init = mt7530_phy_config_init,
1374 /* Interrupts are handled by the switch, not the PHY
1375 * itself.
1376 */
1377 .config_intr = genphy_no_config_intr,
1378 .handle_interrupt = genphy_no_ack_interrupt,
1379 .suspend = genphy_suspend,
1380 .resume = genphy_resume,
1381 .read_page = mtk_gephy_read_page,
1382 .write_page = mtk_gephy_write_page,
1383 },
1384 {
developer043f7b92023-03-13 13:57:36 +08001385 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
developerc50c2352021-12-01 10:45:35 +08001386 .name = "MediaTek MT7531 PHY",
1387 .config_init = mt7531_phy_config_init,
1388 /* Interrupts are handled by the switch, not the PHY
1389 * itself.
1390 */
1391 .config_intr = genphy_no_config_intr,
1392 .handle_interrupt = genphy_no_ack_interrupt,
1393 .suspend = genphy_suspend,
1394 .resume = genphy_resume,
1395 .read_page = mtk_gephy_read_page,
1396 .write_page = mtk_gephy_write_page,
1397 },
developer2149cd92023-03-10 19:01:41 +08001398#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
developerc50c2352021-12-01 10:45:35 +08001399 {
developer043f7b92023-03-13 13:57:36 +08001400 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
developerf35532c2022-08-05 18:37:26 +08001401 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001402 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001403 .config_intr = genphy_no_config_intr,
1404 .handle_interrupt = genphy_no_ack_interrupt,
1405 .suspend = genphy_suspend,
1406 .resume = genphy_resume,
1407 .read_page = mtk_gephy_read_page,
1408 .write_page = mtk_gephy_write_page,
1409 },
1410 {
developer043f7b92023-03-13 13:57:36 +08001411 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
developerf35532c2022-08-05 18:37:26 +08001412 .name = "MediaTek MT7988 PHY",
1413 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001414 .config_intr = genphy_no_config_intr,
1415 .handle_interrupt = genphy_no_ack_interrupt,
1416 .suspend = genphy_suspend,
1417 .resume = genphy_resume,
1418 .read_page = mtk_gephy_read_page,
1419 .write_page = mtk_gephy_write_page,
1420 },
developer2149cd92023-03-10 19:01:41 +08001421#endif
developerc50c2352021-12-01 10:45:35 +08001422};
1423
1424module_phy_driver(mtk_gephy_driver);
1425
1426static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1427 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1428 { }
1429};
1430
1431MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
developer2149cd92023-03-10 19:01:41 +08001432MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
1433MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
developerc50c2352021-12-01 10:45:35 +08001434MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1435MODULE_LICENSE("GPL");
1436
1437MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);