blob: 121002fc9028398f65157efab3fd999854e17fe1 [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
9#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
10#define ZCAL_CTRL_MIN (0)
11#define ZCAL_CTRL_MAX (63)
12#define TXRESERVE_MIN (0)
13#define TXRESERVE_MAX (7)
14
15
16#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
developerce268312022-12-20 16:26:11 +080021
developerc50c2352021-12-01 10:45:35 +080022#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
developerce268312022-12-20 16:26:11 +080023#define MTK_PHY_ANARG_RG (0x10)
24#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
25
developerc50c2352021-12-01 10:45:35 +080026#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
27
28/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080029enum {
developerf35532c2022-08-05 18:37:26 +080030 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
31 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
32 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
33 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
34 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
35 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
36 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
37 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
38 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
39 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
40 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
41 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
42 MTK_PHY_TX_MLT3_END,
43};
developer02d84422021-12-24 11:48:07 +080044
developerc50c2352021-12-01 10:45:35 +080045#define MTK_PHY_TXVLD_DA_RG (0x12)
46#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
47#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
48
49#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
50#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
51#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
52
53#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
54#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
55#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
56
57#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
58#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
59#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
60
61#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
62#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
63#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
64
65#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
66#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
67#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
68
69#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
70#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
71#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
72
73#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
74#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
75#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
76
77
78#define MTK_PHY_RESERVE_RG_0 (0x27)
79#define MTK_PHY_RESERVE_RG_1 (0x28)
80
81#define MTK_PHY_RG_ANA_TEST_POWERUP_TX (0x3b)
82#define MTK_PHY_TANA_CAL_MODE (0xc1)
83#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
84
developer57374032022-10-11 16:43:24 +080085#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
86#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
87
developerc50c2352021-12-01 10:45:35 +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)
93
developerb5c72b02022-12-21 15:51:07 +080094#define MTK_PHY_LDO_OUTPUT_V (0xd7)
developerce268312022-12-20 16:26:11 +080095
developerc50c2352021-12-01 10:45:35 +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)
101
102#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)
107
108#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)
113
114#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)
117
developer6de96aa2022-09-29 16:46:18 +0800118#define MTK_PHY_RG_TX_FILTER (0xfe)
119
developerc50c2352021-12-01 10:45:35 +0800120#define MTK_PHY_RG_DEV1E_REG172 (0x172)
121#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
124#define MTK_PHY_RG_DEV1E_REG173 (0x173)
125#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
128#define MTK_PHY_RG_DEV1E_REG174 (0x174)
129#define MTK_PHY_RSEL_TX_A_MASK GENMASK(14, 8)
130#define MTK_PHY_RSEL_TX_B_MASK GENMASK(6, 0)
131
132#define MTK_PHY_RG_DEV1E_REG175 (0x175)
133#define MTK_PHY_RSEL_TX_C_MASK GENMASK(14, 8)
134#define MTK_PHY_RSEL_TX_D_MASK GENMASK(6, 0)
135
136#define MTK_PHY_RG_DEV1E_REG17A (0x17a)
137#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
138
139#define MTK_PHY_RG_DEV1E_REG17B (0x17b)
140#define MTK_PHY_DA_CAL_CLK BIT(0)
141
142#define MTK_PHY_RG_DEV1E_REG17C (0x17c)
143#define MTK_PHY_DA_CALIN_FLAG BIT(0)
144
145#define MTK_PHY_RG_DEV1E_REG17D (0x17d)
146#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
147
148#define MTK_PHY_RG_DEV1E_REG17E (0x17e)
149#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
150
151#define MTK_PHY_RG_DEV1E_REG17F (0x17f)
152#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
153
154#define MTK_PHY_RG_DEV1E_REG180 (0x180)
155#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
156
157#define MTK_PHY_RG_DEV1E_REG181 (0x181)
158#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
159
160#define MTK_PHY_RG_DEV1E_REG182 (0x182)
161#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
162
163#define MTK_PHY_RG_DEV1E_REG183 (0x183)
164#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
165
166#define MTK_PHY_RG_DEV1E_REG184 (0x180)
167#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
168
developerd2ec38e2022-11-27 01:15:29 +0800169#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
170#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
171#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
172#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
173#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
174#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
175#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
176#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
177#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
178#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
179
developer68f6e102022-11-22 17:35:00 +0800180#define MTK_PHY_RG_DEV1E_REG234 (0x234)
developerd2ec38e2022-11-27 01:15:29 +0800181#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
182#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
183
184#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
185
186#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
187#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
188#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
189#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800190
developerce268312022-12-20 16:26:11 +0800191#define MTK_PHY_LDO_PUMP_EN_PAIRAB (0x502)
192#define MTK_PHY_LDO_PUMP_EN_PAIRCD (0x503)
193
developerc50c2352021-12-01 10:45:35 +0800194#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
195#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
196#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
197
198#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
199#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
200#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
201
202#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
203#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
204#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
205
206#define MTK_PHY_RG_DEV1E_REG540 (0x540)
207#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
208#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
209
210
211/* Registers on MDIO_MMD_VEND2 */
developer23021292022-10-21 19:10:10 +0800212#define MTK_PHY_LED0_ON_CTRL (0x24)
213#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
214#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
215#define MTK_PHY_LED0_ON_LINK100 BIT(1)
216#define MTK_PHY_LED0_ON_LINK10 BIT(2)
217#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
218#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
219#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
220#define MTK_PHY_LED0_FORCE_ON BIT(6)
221#define MTK_PHY_LED0_POLARITY BIT(14)
222#define MTK_PHY_LED0_ENABLE BIT(15)
223
developer8bc5dca2022-10-24 17:15:12 +0800224#define MTK_PHY_LED0_BLINK_CTRL (0x25)
225#define MTK_PHY_LED0_1000TX BIT(0)
226#define MTK_PHY_LED0_1000RX BIT(1)
227#define MTK_PHY_LED0_100TX BIT(2)
228#define MTK_PHY_LED0_100RX BIT(3)
229#define MTK_PHY_LED0_10TX BIT(4)
230#define MTK_PHY_LED0_10RX BIT(5)
231#define MTK_PHY_LED0_COLLISION BIT(6)
232#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
233#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
234#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
235
developerc50c2352021-12-01 10:45:35 +0800236#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
237#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
238
239#define MTK_PHY_RG_DEV1F_REG110 (0x110)
240#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
241#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
242
243#define MTK_PHY_RG_DEV1F_REG115 (0x115)
244#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
245
246/*
247 * These macro privides efuse parsing for internal phy.
248 */
249#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
250#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
251#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
252#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
253#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
254
255#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
256#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
257#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
258#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
259#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
260
261#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
262#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
263#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
264#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
265
266#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
267#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
268
269typedef enum {
270 PAIR_A,
271 PAIR_B,
272 PAIR_C,
273 PAIR_D,
274} phy_cal_pair_t;
275
developer23021292022-10-21 19:10:10 +0800276enum {
277 GPHY_PORT0,
278 GPHY_PORT1,
279 GPHY_PORT2,
280 GPHY_PORT3,
281};
282
developerc50c2352021-12-01 10:45:35 +0800283const u8 mt798x_zcal_to_r50[64] = {
284 7, 8, 9, 9, 10, 10, 11, 11,
285 12, 13, 13, 14, 14, 15, 16, 16,
286 17, 18, 18, 19, 20, 21, 21, 22,
287 23, 24, 24, 25, 26, 27, 28, 29,
288 30, 31, 32, 33, 34, 35, 36, 37,
289 38, 40, 41, 42, 43, 45, 46, 48,
290 49, 51, 52, 54, 55, 57, 59, 61,
291 62, 63, 63, 63, 63, 63, 63, 63
292};
293
294const char pair[4] = {'A', 'B', 'C', 'D'};
295
296#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
297 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
298
299#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
300 for(i=PAIR_A; i<=PAIR_A; i++) { \
301 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
302 if(cal_ret) break; \
303 }
304
305#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
306 for(i=PAIR_A; i<=PAIR_D; i++) { \
307 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
308 if(cal_ret) break; \
309 }
310
developerc6e131e2021-12-08 12:36:24 +0800311#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
312 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
313 CAL_##pair_mode(cal_item, sw) \
314 }
developerc50c2352021-12-01 10:45:35 +0800315
316#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800317 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800318 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800319 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800320 } else if ((!efs_valid && ret) || \
321 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800322 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800323 }
324
325#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
326 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800327 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800328 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800329 }
330
331#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
332 ret = of_property_read_string(phydev->mdio.dev.of_node, \
333 #cal_item, &cal_mode_get); \
334 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800335 else { \
336 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
337 " use default value," \
338 " efs-valid: %s", \
339 #cal_item, \
340 ret? "" : cal_mode_get, \
341 ret? "not specified" : " not supported", \
342 efs_valid? "yes" : "no"); \
343 } \
developerc50c2352021-12-01 10:45:35 +0800344 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800345 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800346 ret = -EIO; \
347 goto out; \
348 }
349
350static int mtk_gephy_read_page(struct phy_device *phydev)
351{
352 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
353}
354
355static int mtk_gephy_write_page(struct phy_device *phydev, int page)
356{
357 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
358}
359
360/*
361 * One calibration cycle consists of:
362 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
363 * until AD_CAL_COMP is ready to output calibration result.
364 * 2.Wait until DA_CAL_CLK is available.
365 * 3.Fetch AD_CAL_COMP_OUT.
366 */
367static int cal_cycle(struct phy_device *phydev, int devad,
368 u32 regnum, u16 mask, u16 cal_val)
369{
370 unsigned long timeout;
371 int reg_val;
372 int ret;
373
374 phy_modify_mmd(phydev, devad, regnum,
375 mask, cal_val);
376 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
377 MTK_PHY_DA_CALIN_FLAG);
378
379 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
380 do{
381 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
382 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
383
384 if(!(reg_val & BIT(0))) {
385 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
386 return -ETIMEDOUT;
387 }
388
389 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
390 MTK_PHY_DA_CALIN_FLAG);
391 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
392 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
393 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
394
395 return ret;
396}
397
398static int rext_fill_result(struct phy_device *phydev, u16 *buf)
399{
400 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
401 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
402 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
403 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
404
405 return 0;
406}
407
408static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
409{
410 u16 rext_cal_val[2];
411
412 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
413 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
414 rext_fill_result(phydev, rext_cal_val);
415
416 return 0;
417}
418
419static int rext_cal_sw(struct phy_device *phydev)
420{
421 u8 rg_zcal_ctrl_def;
422 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
423 u8 lower_ret, upper_ret;
424 u16 rext_cal_val[2];
425 int ret;
426
427 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
428 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
429 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
430 MTK_PHY_RG_TXVOS_CALEN);
431 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
432 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
433 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
434 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
435
436 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
437 MTK_PHY_RG_ZCAL_CTRL_MASK;
438 zcal_lower = ZCAL_CTRL_MIN;
439 zcal_upper = ZCAL_CTRL_MAX;
440
441 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
442 while((zcal_upper-zcal_lower) > 1) {
443 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
444 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
445 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800446 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800447 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800448 upper_ret = ret;
449 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800450 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800451 lower_ret = ret;
452 } else
developerc50c2352021-12-01 10:45:35 +0800453 goto restore;
454 }
455
developer78aa7b92021-12-29 15:22:10 +0800456 if(zcal_lower == ZCAL_CTRL_MIN) {
457 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
458 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
459 } else if(zcal_upper == ZCAL_CTRL_MAX) {
460 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
461 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
462 }
463 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800464 goto restore;
465
466 ret = upper_ret-lower_ret;
467 if (ret == 1) {
468 rext_cal_val[0] = zcal_upper;
469 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800470 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800471 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
472 ret = 0;
473 } else
474 ret = -EINVAL;
475
476restore:
477 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
478 MTK_PHY_ANA_TEST_MODE_MASK);
479 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
480 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
481 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
482 MTK_PHY_RG_TST_DMY2_MASK);
483 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
484 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
485
486 return ret;
487}
488
489static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
490{
491 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
492 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
493 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
494 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
495 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
496 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
497 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
498 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
499
500 return 0;
501}
502
503static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
504{
505 u16 tx_offset_cal_val[4];
506
507 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
508 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
509 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
510 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
511
512 tx_offset_fill_result(phydev, tx_offset_cal_val);
513
514 return 0;
515}
516
517static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
518{
developerd2ec38e2022-11-27 01:15:29 +0800519 int i;
developer87c89d12022-08-19 17:46:34 +0800520 int bias[16] = {0};
521 switch(phydev->drv->phy_id) {
522 case 0x03a29461:
523 {
developerd2ec38e2022-11-27 01:15:29 +0800524 /* We add some calibration to efuse values
525 * due to board level influence.
developer87c89d12022-08-19 17:46:34 +0800526 * GBE: +7, TBT: +1, HBT: +4, TST: +7
527 */
528 int tmp[16] = { 7, 1, 4, 7,
529 7, 1, 4, 7,
530 7, 1, 4, 7,
531 7, 1, 4, 7 };
532 memcpy(bias, (const void *)tmp, sizeof(bias));
533 break;
534 }
535 case 0x03a29481:
536 {
537 int tmp[16] = { 10, 6, 6, 10,
538 10, 6, 6, 10,
539 10, 6, 6, 10,
540 10, 6, 6, 10 };
541 memcpy(bias, (const void *)tmp, sizeof(bias));
542 break;
543 }
544 default:
545 break;
546 }
developerd2ec38e2022-11-27 01:15:29 +0800547
developerdc3e9502022-12-02 18:10:42 +0800548 /* Prevent overflow */
549 for (i = 0; i < 12; i++) {
550 if (buf[i>>2] + bias[i] > 63) {
551 buf[i>>2] = 63;
552 bias[i] = 0;
553 } else if (buf[i>>2] + bias[i] < 0) {
554 /* Bias caused by board design may change in the future.
555 * So check negative cases, too.
556 */
557 buf[i>>2] = 0;
558 bias[i] = 0;
559 }
560 }
561
developerc50c2352021-12-01 10:45:35 +0800562 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800563 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800564 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800565 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800566 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800567 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800568 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800569 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800570
571 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800572 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800573 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800574 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800575 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800576 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800577 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800578 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800579
580 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800581 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800582 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800583 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800584 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800585 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800586 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800587 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800588
589 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800590 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800591 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800592 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800593 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800594 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800595 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800596 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800597
598 return 0;
599}
600
601static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
602{
603 u16 tx_amp_cal_val[4];
604
605 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
606 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
607 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
608 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
609 tx_amp_fill_result(phydev, tx_amp_cal_val);
610
611 return 0;
612}
613
614static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
615 phy_cal_pair_t txg_calen_x)
616{
developer87c89d12022-08-19 17:46:34 +0800617 int bias[4] = {0};
developerdc3e9502022-12-02 18:10:42 +0800618 int i;
developer87c89d12022-08-19 17:46:34 +0800619 switch(phydev->drv->phy_id) {
620 case 0x03a29481:
621 {
developerce268312022-12-20 16:26:11 +0800622 int tmp[16] = { -2, -2, -2, -2 };
developer87c89d12022-08-19 17:46:34 +0800623 memcpy(bias, (const void *)tmp, sizeof(bias));
624 break;
625 }
626 /* 0x03a29461 enters default case */
627 default:
628 break;
629 }
630
developerdc3e9502022-12-02 18:10:42 +0800631 for (i = 0; i < 4; i++) {
632 if (buf[i>>2] + bias[i] > 63) {
633 buf[i>>2] = 63;
634 bias[i] = 0;
635 } else if (buf[i>>2] + bias[i] < 0) {
636 buf[i>>2] = 0;
637 bias[i] = 0;
638 }
639 }
developerc50c2352021-12-01 10:45:35 +0800640 switch(txg_calen_x) {
641 case PAIR_A:
642 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800643 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800644 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800645 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800646 break;
647 case PAIR_B:
648 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800649 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800650 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800651 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800652 break;
653 case PAIR_C:
654 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800655 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800656 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800657 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800658 break;
659 case PAIR_D:
660 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800661 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800662 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800663 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800664 break;
665 }
666 return 0;
667}
668
669static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
670 phy_cal_pair_t txg_calen_x)
671{
672 u16 tx_r50_cal_val[1];
673
674 switch(txg_calen_x) {
675 case PAIR_A:
676 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
677 break;
678 case PAIR_B:
679 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
680 break;
681 case PAIR_C:
682 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
683 break;
684 case PAIR_D:
685 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
686 break;
687 }
688 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
689
690 return 0;
691}
692
693static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
694{
695 u8 rg_zcal_ctrl_def;
696 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
697 u8 lower_ret, upper_ret;
698 u16 tx_r50_cal_val[1];
699 int ret;
700
701 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
702 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
703 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
704 MTK_PHY_RG_TXVOS_CALEN);
705 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
706 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
707 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
708 BIT(txg_calen_x * 4));
709 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
710 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
711
712 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
713 MTK_PHY_RG_ZCAL_CTRL_MASK;
714 zcal_lower = ZCAL_CTRL_MIN;
715 zcal_upper = ZCAL_CTRL_MAX;
716
developer02d84422021-12-24 11:48:07 +0800717 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800718 while((zcal_upper-zcal_lower) > 1) {
719 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
720 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
721 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800722 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800723 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800724 upper_ret = ret;
725 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800726 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800727 lower_ret = ret;
728 } else
developerc50c2352021-12-01 10:45:35 +0800729 goto restore;
730 }
731
developer78aa7b92021-12-29 15:22:10 +0800732 if(zcal_lower == ZCAL_CTRL_MIN) {
733 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800734 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800735 } else if(zcal_upper == ZCAL_CTRL_MAX) {
736 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800737 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800738 }
739 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800740 goto restore;
741
742 ret = upper_ret-lower_ret;
743 if (ret == 1) {
744 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
745 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800746 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800747 pair[txg_calen_x], zcal_lower);
748 ret = 0;
749 } else
750 ret = -EINVAL;
751
752restore:
753 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
754 MTK_PHY_ANA_TEST_MODE_MASK);
755 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
756 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
757 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
758 BIT(txg_calen_x * 4));
759 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
760 MTK_PHY_RG_TST_DMY2_MASK);
761 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
762 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
763
764 return ret;
765}
766
767static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
768{
769 u8 lower_idx, upper_idx, txreserve_val;
770 u8 lower_ret, upper_ret;
771 int ret;
772
773 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
774 MTK_PHY_RG_ANA_CALEN);
775 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
776 MTK_PHY_RG_CAL_CKINV);
777 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
778 MTK_PHY_RG_TXVOS_CALEN);
779
780 switch(rg_txreserve_x) {
781 case PAIR_A:
782 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
783 MTK_PHY_DASN_DAC_IN0_A_MASK);
784 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
785 MTK_PHY_DASN_DAC_IN1_A_MASK);
786 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
787 MTK_PHY_RG_ZCALEN_A);
788 break;
789 case PAIR_B:
790 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
791 MTK_PHY_DASN_DAC_IN0_B_MASK);
792 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
793 MTK_PHY_DASN_DAC_IN1_B_MASK);
794 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
795 MTK_PHY_RG_ZCALEN_B);
796 break;
797 case PAIR_C:
798 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
799 MTK_PHY_DASN_DAC_IN0_C_MASK);
800 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
801 MTK_PHY_DASN_DAC_IN1_C_MASK);
802 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
803 MTK_PHY_RG_ZCALEN_C);
804 break;
805 case PAIR_D:
806 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
807 MTK_PHY_DASN_DAC_IN0_D_MASK);
808 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
809 MTK_PHY_DASN_DAC_IN1_D_MASK);
810 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
811 MTK_PHY_RG_ZCALEN_D);
812 break;
813 default:
814 ret = -EINVAL;
815 goto restore;
816 }
817
818 lower_idx = TXRESERVE_MIN;
819 upper_idx = TXRESERVE_MAX;
820
821 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
822 while((upper_idx-lower_idx) > 1) {
823 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
824 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
825 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
826 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
827 txreserve_val << 12 | txreserve_val << 8 |
828 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800829 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800830 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800831 upper_ret = ret;
832 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800833 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800834 lower_ret = ret;
835 } else
developerc50c2352021-12-01 10:45:35 +0800836 goto restore;
837 }
838
developer78aa7b92021-12-29 15:22:10 +0800839 if(lower_idx == TXRESERVE_MIN) {
840 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800841 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
842 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
843 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800844 } else if(upper_idx == TXRESERVE_MAX) {
845 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800846 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
847 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
848 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800849 }
850 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800851 goto restore;
852
developer78aa7b92021-12-29 15:22:10 +0800853 /* We calibrate TX-VCM in different logic. Check upper index and then
854 * lower index. If this calibration is valid, apply lower index's result.
855 */
developerc50c2352021-12-01 10:45:35 +0800856 ret = upper_ret-lower_ret;
857 if (ret == 1) {
858 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800859 /* Make sure we use upper_idx in our calibration system */
860 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
861 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
862 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
863 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800864 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
865 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
866 ret = 0;
867 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
868 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
869 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
870 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
871 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
872 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
873 ret = 0;
874 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
875 } else
876 ret = -EINVAL;
877
878restore:
879 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
880 MTK_PHY_RG_ANA_CALEN);
881 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
882 MTK_PHY_RG_TXVOS_CALEN);
883 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
884 MTK_PHY_RG_ZCALEN_A);
885 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
886 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
887
888 return ret;
889}
890
891static void mtk_gephy_config_init(struct phy_device *phydev)
892{
893 /* Disable EEE */
894 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
895
896 /* Enable HW auto downshift */
897 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
898
899 /* Increase SlvDPSready time */
900 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
901 __phy_write(phydev, 0x10, 0xafae);
902 __phy_write(phydev, 0x12, 0x2f);
903 __phy_write(phydev, 0x10, 0x8fae);
904 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
905
906 /* Adjust 100_mse_threshold */
907 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
908
909 /* Disable mcc */
910 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
911}
912
913static int mt7530_phy_config_init(struct phy_device *phydev)
914{
915 mtk_gephy_config_init(phydev);
916
917 /* Increase post_update_timer */
918 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
919
920 return 0;
921}
922
923static int mt7531_phy_config_init(struct phy_device *phydev)
924{
925 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
926 return -EINVAL;
927
928 mtk_gephy_config_init(phydev);
929
930 /* PHY link down power saving enable */
931 phy_set_bits(phydev, 0x17, BIT(4));
932 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
933
934 /* Set TX Pair delay selection */
935 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
936 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
937
938 return 0;
939}
940
developerf35532c2022-08-05 18:37:26 +0800941static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800942{
developerd2ec38e2022-11-27 01:15:29 +0800943 u32 i;
developer02d84422021-12-24 11:48:07 +0800944 /* 100M eye finetune:
945 * Keep middle level of TX MLT3 shapper as default.
946 * Only change TX MLT3 overshoot level here.
947 */
948 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
949 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
950 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
951 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
952 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
953 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
954 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
955 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800956
developer02d84422021-12-24 11:48:07 +0800957 /* TX-AMP finetune:
958 * 100M +4, 1000M +6 to default value.
959 * If efuse values aren't valid, TX-AMP uses the below values.
960 */
961 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
962 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
963 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
964 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
965 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
966 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
967 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
968 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
developer68f6e102022-11-22 17:35:00 +0800969
developerd2ec38e2022-11-27 01:15:29 +0800970 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
971 /* EnabRandUpdTrig = 1 */
972 __phy_write(phydev, 0x11, 0x2f00);
973 __phy_write(phydev, 0x12, 0xe);
974 __phy_write(phydev, 0x10, 0x8fb0);
975
developercb32e042023-03-02 16:39:54 +0800976 /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
977 __phy_write(phydev, 0x11, 0xc71);
developerd2ec38e2022-11-27 01:15:29 +0800978 __phy_write(phydev, 0x12, 0xc);
979 __phy_write(phydev, 0x10, 0x8fae);
980
981 /* NormMseLoThresh = 85 */
982 __phy_write(phydev, 0x11, 0x55a0);
983 __phy_write(phydev, 0x12, 0x0);
984 __phy_write(phydev, 0x10, 0x83aa);
985
986 /* InhibitDisableDfeTail1000 = 1 */
987 __phy_write(phydev, 0x11, 0x2b);
988 __phy_write(phydev, 0x12, 0x0);
989 __phy_write(phydev, 0x10, 0x8f80);
990
developercb32e042023-03-02 16:39:54 +0800991 /* SSTrKp1000Slv = 5 */
developerd2ec38e2022-11-27 01:15:29 +0800992 __phy_write(phydev, 0x11, 0xbaef);
993 __phy_write(phydev, 0x12, 0x2e);
994 __phy_write(phydev, 0x10, 0x968c);
995
developercb32e042023-03-02 16:39:54 +0800996 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
997 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
998 */
999 __phy_write(phydev, 0x11, 0xd10a);
1000 __phy_write(phydev, 0x12, 0x34);
1001 __phy_write(phydev, 0x10, 0x8f82);
1002
1003 /* TrFreeze = 0 */
1004 __phy_write(phydev, 0x11, 0x0);
1005 __phy_write(phydev, 0x12, 0x0);
1006 __phy_write(phydev, 0x10, 0x9686);
1007
developerd2ec38e2022-11-27 01:15:29 +08001008 /* VcoSlicerThreshBitsHigh */
1009 __phy_write(phydev, 0x11, 0x5555);
1010 __phy_write(phydev, 0x12, 0x55);
1011 __phy_write(phydev, 0x10, 0x8ec0);
1012
1013 /* ResetSyncOffset = 6 */
1014 __phy_write(phydev, 0x11, 0x600);
1015 __phy_write(phydev, 0x12, 0x0);
1016 __phy_write(phydev, 0x10, 0x8fc0);
1017
1018 /* VgaDecRate = 1 */
1019 __phy_write(phydev, 0x11, 0x4c2a);
1020 __phy_write(phydev, 0x12, 0x3e);
1021 __phy_write(phydev, 0x10, 0x8fa4);
1022
developercb32e042023-03-02 16:39:54 +08001023 /* FfeUpdGainForce = 4 */
1024 __phy_write(phydev, 0x11, 0x240);
1025 __phy_write(phydev, 0x12, 0x0);
1026 __phy_write(phydev, 0x10, 0x9680);
1027
developerd2ec38e2022-11-27 01:15:29 +08001028 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerd2ec38e2022-11-27 01:15:29 +08001029 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +08001030 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerb5c72b02022-12-21 15:51:07 +08001031 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1032 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerd2ec38e2022-11-27 01:15:29 +08001033
1034 /* rg_tr_lpf_cnt_val = 512 */
1035 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1036
1037 /* IIR2 related */
1038 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1039 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1040 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1041 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1042 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1043 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1044 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1045 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1046 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1047 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1048
1049 /* FFE peaking */
1050 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1051 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1052 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1053 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1054
1055 /* TX shape */
1056 /* 10/100/1000 TX shaper is enabled by default */
1057 for (i = 0x202; i < 0x230; i += 2) {
1058 if (i == 0x20c || i == 0x218 || i == 0x224)
1059 continue;
1060 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1061 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1062 }
developercb32e042023-03-02 16:39:54 +08001063
1064 /* Disable LDO pump */
1065 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
1066 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
1067
1068 /* Adjust LDO output voltage */
1069 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developer02d84422021-12-24 11:48:07 +08001070}
1071
developerf35532c2022-08-05 18:37:26 +08001072static inline void mt7988_phy_finetune(struct phy_device *phydev)
1073{
1074 int i;
1075 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
1076 0x020d, 0x0206, 0x0384, 0x03d0,
1077 0x03c6, 0x030a, 0x0011, 0x0005};
1078
1079 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
1080 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
1081 }
developer6de96aa2022-09-29 16:46:18 +08001082
developer57374032022-10-11 16:43:24 +08001083 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001084 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001085
1086 /* Disable TX power saving */
1087 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +08001088 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001089
developerec2b8552022-10-17 15:30:59 +08001090 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +08001091 /* EnabRandUpdTrig = 1 */
1092 __phy_write(phydev, 0x11, 0x2f00);
1093 __phy_write(phydev, 0x12, 0xe);
1094 __phy_write(phydev, 0x10, 0x8fb0);
1095
developercb32e042023-03-02 16:39:54 +08001096 /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
developerce73ad62022-12-07 22:43:45 +08001097 __phy_write(phydev, 0x11, 0x671);
1098 __phy_write(phydev, 0x12, 0xc);
1099 __phy_write(phydev, 0x10, 0x8fae);
1100
1101 /* NormMseLoThresh = 85 */
1102 __phy_write(phydev, 0x11, 0x55a0);
developerec2b8552022-10-17 15:30:59 +08001103 __phy_write(phydev, 0x12, 0x0);
developerce73ad62022-12-07 22:43:45 +08001104 __phy_write(phydev, 0x10, 0x83aa);
1105
1106 /* InhibitDisableDfeTail1000 = 1 */
1107 __phy_write(phydev, 0x11, 0x2b);
1108 __phy_write(phydev, 0x12, 0x0);
1109 __phy_write(phydev, 0x10, 0x8f80);
1110
1111 /* SSTr related */
1112 __phy_write(phydev, 0x11, 0xbaef);
1113 __phy_write(phydev, 0x12, 0x2e);
1114 __phy_write(phydev, 0x10, 0x968c);
1115
1116 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
1117 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
1118 */
1119 __phy_write(phydev, 0x11, 0xd10a);
1120 __phy_write(phydev, 0x12, 0x34);
1121 __phy_write(phydev, 0x10, 0x8f82);
1122
1123 /* VcoSlicerThreshBitsHigh */
1124 __phy_write(phydev, 0x11, 0x5555);
1125 __phy_write(phydev, 0x12, 0x55);
1126 __phy_write(phydev, 0x10, 0x8ec0);
1127
developerce268312022-12-20 16:26:11 +08001128 /* ResetSyncOffset = 5 */
1129 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +08001130 __phy_write(phydev, 0x12, 0x0);
1131 __phy_write(phydev, 0x10, 0x8fc0);
developerb5c72b02022-12-21 15:51:07 +08001132 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001133
developerce268312022-12-20 16:26:11 +08001134 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
1135 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +08001136 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developerce268312022-12-20 16:26:11 +08001137 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +08001138 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001139
1140 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
1141 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerb5c72b02022-12-21 15:51:07 +08001142 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1143 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerce73ad62022-12-07 22:43:45 +08001144
1145 /* rg_tr_lpf_cnt_val = 512 */
1146 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1147
1148 /* IIR2 related */
1149 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1150 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1151 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1152 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1153 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1154 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1155 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1156 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1157 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1158 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1159
1160 /* FFE peaking */
1161 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1162 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1163 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1164 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1165
1166 /* TX shape */
1167 /* 10/100/1000 TX shaper is enabled by default */
1168 for (i = 0x202; i < 0x230; i += 2) {
1169 if (i == 0x20c || i == 0x218 || i == 0x224)
1170 continue;
1171 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1172 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1173 }
developerce268312022-12-20 16:26:11 +08001174
1175 /* Disable LDO pump */
1176 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
1177 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
1178
1179 /* Adjust LDO output voltage */
developerb5c72b02022-12-21 15:51:07 +08001180 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developerf35532c2022-08-05 18:37:26 +08001181}
1182
1183static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001184{
1185 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +08001186 int i, ret;
1187 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +08001188 u32 *buf;
1189 bool efs_valid = true;
1190 size_t len;
1191 struct nvmem_cell *cell;
1192
1193 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1194 return -EINVAL;
1195
1196 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1197 if (IS_ERR(cell)) {
1198 if (PTR_ERR(cell) == -EPROBE_DEFER)
1199 return PTR_ERR(cell);
1200 return 0;
1201 }
1202
1203 buf = (u32 *)nvmem_cell_read(cell, &len);
1204 if (IS_ERR(buf))
1205 return PTR_ERR(buf);
1206 nvmem_cell_put(cell);
1207
1208 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
1209 efs_valid = false;
1210
1211 if (len < 4 * sizeof(u32)) {
1212 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1213 ret = -EINVAL;
1214 goto out;
1215 }
1216
1217 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1218 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1219 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1220 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
1221 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +08001222 ret = 0;
developerc50c2352021-12-01 10:45:35 +08001223
1224out:
1225 kfree(buf);
1226 return ret;
1227}
1228
developer68f6e102022-11-22 17:35:00 +08001229static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001230{
1231 mt7981_phy_finetune(phydev);
1232
1233 return mt798x_phy_calibration(phydev);
1234}
1235
developer68f6e102022-11-22 17:35:00 +08001236static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001237{
developer23021292022-10-21 19:10:10 +08001238 struct device_node *np;
1239 void __iomem *boottrap;
1240 u32 reg;
1241 int port;
1242
1243 /* Setup LED polarity according to boottrap's polarity */
1244 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1245 if (!np)
1246 return -ENOENT;
1247 boottrap = of_iomap(np, 0);
1248 if (!boottrap)
1249 return -ENOMEM;
1250 reg = readl(boottrap);
1251 port = phydev->mdio.addr;
1252 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1253 (port == GPHY_PORT1 && reg & BIT(9)) ||
1254 (port == GPHY_PORT2 && reg & BIT(10)) ||
1255 (port == GPHY_PORT3 && reg & BIT(11))) {
1256 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1257 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1258 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1259 } else {
1260 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1261 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1262 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1263 MTK_PHY_LED0_ON_LINK1000);
1264 }
developer8bc5dca2022-10-24 17:15:12 +08001265 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1266 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1267 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1268 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001269
developerf35532c2022-08-05 18:37:26 +08001270 mt7988_phy_finetune(phydev);
1271
1272 return mt798x_phy_calibration(phydev);
1273}
1274
developerc50c2352021-12-01 10:45:35 +08001275static struct phy_driver mtk_gephy_driver[] = {
1276#if 0
1277 {
1278 PHY_ID_MATCH_EXACT(0x03a29412),
1279 .name = "MediaTek MT7530 PHY",
1280 .config_init = mt7530_phy_config_init,
1281 /* Interrupts are handled by the switch, not the PHY
1282 * itself.
1283 */
1284 .config_intr = genphy_no_config_intr,
1285 .handle_interrupt = genphy_no_ack_interrupt,
1286 .suspend = genphy_suspend,
1287 .resume = genphy_resume,
1288 .read_page = mtk_gephy_read_page,
1289 .write_page = mtk_gephy_write_page,
1290 },
1291 {
1292 PHY_ID_MATCH_EXACT(0x03a29441),
1293 .name = "MediaTek MT7531 PHY",
1294 .config_init = mt7531_phy_config_init,
1295 /* Interrupts are handled by the switch, not the PHY
1296 * itself.
1297 */
1298 .config_intr = genphy_no_config_intr,
1299 .handle_interrupt = genphy_no_ack_interrupt,
1300 .suspend = genphy_suspend,
1301 .resume = genphy_resume,
1302 .read_page = mtk_gephy_read_page,
1303 .write_page = mtk_gephy_write_page,
1304 },
1305#endif
1306 {
1307 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001308 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001309 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001310 /* Interrupts are handled by the switch, not the PHY
1311 * itself.
1312 */
1313 .config_intr = genphy_no_config_intr,
1314 .handle_interrupt = genphy_no_ack_interrupt,
1315 .suspend = genphy_suspend,
1316 .resume = genphy_resume,
1317 .read_page = mtk_gephy_read_page,
1318 .write_page = mtk_gephy_write_page,
1319 },
1320 {
1321 PHY_ID_MATCH_EXACT(0x03a29481),
1322 .name = "MediaTek MT7988 PHY",
1323 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001324 /* Interrupts are handled by the switch, not the PHY
1325 * itself.
1326 */
1327 .config_intr = genphy_no_config_intr,
1328 .handle_interrupt = genphy_no_ack_interrupt,
1329 .suspend = genphy_suspend,
1330 .resume = genphy_resume,
1331 .read_page = mtk_gephy_read_page,
1332 .write_page = mtk_gephy_write_page,
1333 },
1334};
1335
1336module_phy_driver(mtk_gephy_driver);
1337
1338static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1339 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1340 { }
1341};
1342
1343MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1344MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1345MODULE_LICENSE("GPL");
1346
1347MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);