blob: 35ec82f4c296aab60bfd7b9b8a3a68cdc367ef2a [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));
developer47e925d2022-12-21 20:10:49 +0800533 for (i = 0; i <= 12; i += 4) {
534 if (likely(buf[i>>2] + bias[i] >= 32)) {
535 bias[i] -= 13;
536 } else {
537 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
538 0x5c, 0x7 << i, bias[i] << i);
539 bias[i+1] += 13;
540 bias[i+2] += 13;
541 bias[i+3] += 13;
542 }
543 }
developer87c89d12022-08-19 17:46:34 +0800544 break;
545 }
546 case 0x03a29481:
547 {
548 int tmp[16] = { 10, 6, 6, 10,
549 10, 6, 6, 10,
550 10, 6, 6, 10,
551 10, 6, 6, 10 };
552 memcpy(bias, (const void *)tmp, sizeof(bias));
553 break;
554 }
555 default:
556 break;
557 }
developerd2ec38e2022-11-27 01:15:29 +0800558
developerdc3e9502022-12-02 18:10:42 +0800559 /* Prevent overflow */
560 for (i = 0; i < 12; i++) {
561 if (buf[i>>2] + bias[i] > 63) {
562 buf[i>>2] = 63;
563 bias[i] = 0;
564 } else if (buf[i>>2] + bias[i] < 0) {
565 /* Bias caused by board design may change in the future.
566 * So check negative cases, too.
567 */
568 buf[i>>2] = 0;
569 bias[i] = 0;
570 }
571 }
572
developerc50c2352021-12-01 10:45:35 +0800573 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800574 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800575 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800576 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800577 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800578 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800579 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800580 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800581
582 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800583 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800584 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800585 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800586 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800587 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800588 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800589 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800590
591 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800592 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800593 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800594 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800595 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800596 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800597 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800598 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800599
600 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800601 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800602 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800603 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800604 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800605 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800606 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800607 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800608
609 return 0;
610}
611
612static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
613{
614 u16 tx_amp_cal_val[4];
615
616 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
617 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
618 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
619 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
620 tx_amp_fill_result(phydev, tx_amp_cal_val);
621
622 return 0;
623}
624
625static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
626 phy_cal_pair_t txg_calen_x)
627{
developer87c89d12022-08-19 17:46:34 +0800628 int bias[4] = {0};
developerdc3e9502022-12-02 18:10:42 +0800629 int i;
developer87c89d12022-08-19 17:46:34 +0800630 switch(phydev->drv->phy_id) {
631 case 0x03a29481:
632 {
developerce268312022-12-20 16:26:11 +0800633 int tmp[16] = { -2, -2, -2, -2 };
developer87c89d12022-08-19 17:46:34 +0800634 memcpy(bias, (const void *)tmp, sizeof(bias));
635 break;
636 }
637 /* 0x03a29461 enters default case */
638 default:
639 break;
640 }
641
developerdc3e9502022-12-02 18:10:42 +0800642 for (i = 0; i < 4; i++) {
643 if (buf[i>>2] + bias[i] > 63) {
644 buf[i>>2] = 63;
645 bias[i] = 0;
646 } else if (buf[i>>2] + bias[i] < 0) {
647 buf[i>>2] = 0;
648 bias[i] = 0;
649 }
650 }
developerc50c2352021-12-01 10:45:35 +0800651 switch(txg_calen_x) {
652 case PAIR_A:
653 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800654 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800655 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800656 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800657 break;
658 case PAIR_B:
659 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800660 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800661 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800662 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800663 break;
664 case PAIR_C:
665 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800666 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800667 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800668 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800669 break;
670 case PAIR_D:
671 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800672 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800673 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800674 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800675 break;
676 }
677 return 0;
678}
679
680static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
681 phy_cal_pair_t txg_calen_x)
682{
683 u16 tx_r50_cal_val[1];
684
685 switch(txg_calen_x) {
686 case PAIR_A:
687 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
688 break;
689 case PAIR_B:
690 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
691 break;
692 case PAIR_C:
693 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
694 break;
695 case PAIR_D:
696 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
697 break;
698 }
699 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
700
701 return 0;
702}
703
704static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
705{
706 u8 rg_zcal_ctrl_def;
707 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
708 u8 lower_ret, upper_ret;
709 u16 tx_r50_cal_val[1];
710 int ret;
711
712 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
713 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
714 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
715 MTK_PHY_RG_TXVOS_CALEN);
716 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
717 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
718 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
719 BIT(txg_calen_x * 4));
720 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
721 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
722
723 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
724 MTK_PHY_RG_ZCAL_CTRL_MASK;
725 zcal_lower = ZCAL_CTRL_MIN;
726 zcal_upper = ZCAL_CTRL_MAX;
727
developer02d84422021-12-24 11:48:07 +0800728 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800729 while((zcal_upper-zcal_lower) > 1) {
730 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
731 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
732 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800733 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800734 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800735 upper_ret = ret;
736 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800737 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800738 lower_ret = ret;
739 } else
developerc50c2352021-12-01 10:45:35 +0800740 goto restore;
741 }
742
developer78aa7b92021-12-29 15:22:10 +0800743 if(zcal_lower == ZCAL_CTRL_MIN) {
744 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800745 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800746 } else if(zcal_upper == ZCAL_CTRL_MAX) {
747 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800748 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800749 }
750 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800751 goto restore;
752
753 ret = upper_ret-lower_ret;
754 if (ret == 1) {
755 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
756 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800757 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800758 pair[txg_calen_x], zcal_lower);
759 ret = 0;
760 } else
761 ret = -EINVAL;
762
763restore:
764 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
765 MTK_PHY_ANA_TEST_MODE_MASK);
766 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
767 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
768 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
769 BIT(txg_calen_x * 4));
770 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
771 MTK_PHY_RG_TST_DMY2_MASK);
772 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
773 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
774
775 return ret;
776}
777
778static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
779{
780 u8 lower_idx, upper_idx, txreserve_val;
781 u8 lower_ret, upper_ret;
782 int ret;
783
784 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
785 MTK_PHY_RG_ANA_CALEN);
786 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
787 MTK_PHY_RG_CAL_CKINV);
788 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
789 MTK_PHY_RG_TXVOS_CALEN);
790
791 switch(rg_txreserve_x) {
792 case PAIR_A:
793 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
794 MTK_PHY_DASN_DAC_IN0_A_MASK);
795 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
796 MTK_PHY_DASN_DAC_IN1_A_MASK);
797 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
798 MTK_PHY_RG_ZCALEN_A);
799 break;
800 case PAIR_B:
801 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
802 MTK_PHY_DASN_DAC_IN0_B_MASK);
803 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
804 MTK_PHY_DASN_DAC_IN1_B_MASK);
805 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
806 MTK_PHY_RG_ZCALEN_B);
807 break;
808 case PAIR_C:
809 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
810 MTK_PHY_DASN_DAC_IN0_C_MASK);
811 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
812 MTK_PHY_DASN_DAC_IN1_C_MASK);
813 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
814 MTK_PHY_RG_ZCALEN_C);
815 break;
816 case PAIR_D:
817 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
818 MTK_PHY_DASN_DAC_IN0_D_MASK);
819 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
820 MTK_PHY_DASN_DAC_IN1_D_MASK);
821 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
822 MTK_PHY_RG_ZCALEN_D);
823 break;
824 default:
825 ret = -EINVAL;
826 goto restore;
827 }
828
829 lower_idx = TXRESERVE_MIN;
830 upper_idx = TXRESERVE_MAX;
831
832 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
833 while((upper_idx-lower_idx) > 1) {
834 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
835 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
836 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
837 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
838 txreserve_val << 12 | txreserve_val << 8 |
839 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800840 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800841 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800842 upper_ret = ret;
843 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800844 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800845 lower_ret = ret;
846 } else
developerc50c2352021-12-01 10:45:35 +0800847 goto restore;
848 }
849
developer78aa7b92021-12-29 15:22:10 +0800850 if(lower_idx == TXRESERVE_MIN) {
851 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800852 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
853 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
854 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800855 } else if(upper_idx == TXRESERVE_MAX) {
856 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800857 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
858 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
859 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800860 }
861 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800862 goto restore;
863
developer78aa7b92021-12-29 15:22:10 +0800864 /* We calibrate TX-VCM in different logic. Check upper index and then
865 * lower index. If this calibration is valid, apply lower index's result.
866 */
developerc50c2352021-12-01 10:45:35 +0800867 ret = upper_ret-lower_ret;
868 if (ret == 1) {
869 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800870 /* Make sure we use upper_idx in our calibration system */
871 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
872 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
873 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
874 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800875 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
876 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
877 ret = 0;
878 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
879 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
880 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
881 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
882 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
883 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
884 ret = 0;
885 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
886 } else
887 ret = -EINVAL;
888
889restore:
890 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
891 MTK_PHY_RG_ANA_CALEN);
892 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
893 MTK_PHY_RG_TXVOS_CALEN);
894 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
895 MTK_PHY_RG_ZCALEN_A);
896 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
897 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
898
899 return ret;
900}
901
902static void mtk_gephy_config_init(struct phy_device *phydev)
903{
904 /* Disable EEE */
905 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
906
907 /* Enable HW auto downshift */
908 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
909
910 /* Increase SlvDPSready time */
911 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
912 __phy_write(phydev, 0x10, 0xafae);
913 __phy_write(phydev, 0x12, 0x2f);
914 __phy_write(phydev, 0x10, 0x8fae);
915 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
916
917 /* Adjust 100_mse_threshold */
918 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
919
920 /* Disable mcc */
921 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
922}
923
924static int mt7530_phy_config_init(struct phy_device *phydev)
925{
926 mtk_gephy_config_init(phydev);
927
928 /* Increase post_update_timer */
929 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
930
931 return 0;
932}
933
934static int mt7531_phy_config_init(struct phy_device *phydev)
935{
936 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
937 return -EINVAL;
938
939 mtk_gephy_config_init(phydev);
940
941 /* PHY link down power saving enable */
942 phy_set_bits(phydev, 0x17, BIT(4));
943 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
944
945 /* Set TX Pair delay selection */
946 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
947 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
948
949 return 0;
950}
951
developerf35532c2022-08-05 18:37:26 +0800952static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800953{
developerd2ec38e2022-11-27 01:15:29 +0800954 u32 i;
developer02d84422021-12-24 11:48:07 +0800955 /* 100M eye finetune:
956 * Keep middle level of TX MLT3 shapper as default.
957 * Only change TX MLT3 overshoot level here.
958 */
959 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
960 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
961 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
962 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
963 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
964 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
965 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
966 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800967
developer02d84422021-12-24 11:48:07 +0800968 /* TX-AMP finetune:
969 * 100M +4, 1000M +6 to default value.
970 * If efuse values aren't valid, TX-AMP uses the below values.
971 */
972 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
973 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
974 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
975 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
976 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
977 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
978 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
979 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
developer68f6e102022-11-22 17:35:00 +0800980
developerd2ec38e2022-11-27 01:15:29 +0800981 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
982 /* EnabRandUpdTrig = 1 */
983 __phy_write(phydev, 0x11, 0x2f00);
984 __phy_write(phydev, 0x12, 0xe);
985 __phy_write(phydev, 0x10, 0x8fb0);
986
987 /* SlvDSPreadyTime = 0xc */
988 __phy_write(phydev, 0x11, 0x671);
989 __phy_write(phydev, 0x12, 0xc);
990 __phy_write(phydev, 0x10, 0x8fae);
991
992 /* NormMseLoThresh = 85 */
993 __phy_write(phydev, 0x11, 0x55a0);
994 __phy_write(phydev, 0x12, 0x0);
995 __phy_write(phydev, 0x10, 0x83aa);
996
997 /* InhibitDisableDfeTail1000 = 1 */
998 __phy_write(phydev, 0x11, 0x2b);
999 __phy_write(phydev, 0x12, 0x0);
1000 __phy_write(phydev, 0x10, 0x8f80);
1001
1002 /* SSTr related */
1003 __phy_write(phydev, 0x11, 0xbaef);
1004 __phy_write(phydev, 0x12, 0x2e);
1005 __phy_write(phydev, 0x10, 0x968c);
1006
1007 /* VcoSlicerThreshBitsHigh */
1008 __phy_write(phydev, 0x11, 0x5555);
1009 __phy_write(phydev, 0x12, 0x55);
1010 __phy_write(phydev, 0x10, 0x8ec0);
1011
1012 /* ResetSyncOffset = 6 */
1013 __phy_write(phydev, 0x11, 0x600);
1014 __phy_write(phydev, 0x12, 0x0);
1015 __phy_write(phydev, 0x10, 0x8fc0);
1016
1017 /* VgaDecRate = 1 */
1018 __phy_write(phydev, 0x11, 0x4c2a);
1019 __phy_write(phydev, 0x12, 0x3e);
1020 __phy_write(phydev, 0x10, 0x8fa4);
1021
1022 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerd2ec38e2022-11-27 01:15:29 +08001023 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +08001024 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerb5c72b02022-12-21 15:51:07 +08001025 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1026 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerd2ec38e2022-11-27 01:15:29 +08001027
1028 /* rg_tr_lpf_cnt_val = 512 */
1029 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1030
1031 /* IIR2 related */
1032 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1033 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1034 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1035 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1036 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1037 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1038 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1039 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1040 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1041 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1042
1043 /* FFE peaking */
1044 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1045 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1046 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1047 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1048
1049 /* TX shape */
1050 /* 10/100/1000 TX shaper is enabled by default */
1051 for (i = 0x202; i < 0x230; i += 2) {
1052 if (i == 0x20c || i == 0x218 || i == 0x224)
1053 continue;
1054 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1055 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1056 }
developer02d84422021-12-24 11:48:07 +08001057}
1058
developerf35532c2022-08-05 18:37:26 +08001059static inline void mt7988_phy_finetune(struct phy_device *phydev)
1060{
1061 int i;
1062 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
1063 0x020d, 0x0206, 0x0384, 0x03d0,
1064 0x03c6, 0x030a, 0x0011, 0x0005};
1065
1066 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
1067 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
1068 }
developer6de96aa2022-09-29 16:46:18 +08001069
developer57374032022-10-11 16:43:24 +08001070 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001071 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001072
1073 /* Disable TX power saving */
1074 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +08001075 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001076
developerec2b8552022-10-17 15:30:59 +08001077 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +08001078 /* EnabRandUpdTrig = 1 */
1079 __phy_write(phydev, 0x11, 0x2f00);
1080 __phy_write(phydev, 0x12, 0xe);
1081 __phy_write(phydev, 0x10, 0x8fb0);
1082
1083 /* SlvDSPreadyTime = 0xc */
1084 __phy_write(phydev, 0x11, 0x671);
1085 __phy_write(phydev, 0x12, 0xc);
1086 __phy_write(phydev, 0x10, 0x8fae);
1087
1088 /* NormMseLoThresh = 85 */
1089 __phy_write(phydev, 0x11, 0x55a0);
developerec2b8552022-10-17 15:30:59 +08001090 __phy_write(phydev, 0x12, 0x0);
developerce73ad62022-12-07 22:43:45 +08001091 __phy_write(phydev, 0x10, 0x83aa);
1092
1093 /* InhibitDisableDfeTail1000 = 1 */
1094 __phy_write(phydev, 0x11, 0x2b);
1095 __phy_write(phydev, 0x12, 0x0);
1096 __phy_write(phydev, 0x10, 0x8f80);
1097
1098 /* SSTr related */
1099 __phy_write(phydev, 0x11, 0xbaef);
1100 __phy_write(phydev, 0x12, 0x2e);
1101 __phy_write(phydev, 0x10, 0x968c);
1102
1103 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
1104 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
1105 */
1106 __phy_write(phydev, 0x11, 0xd10a);
1107 __phy_write(phydev, 0x12, 0x34);
1108 __phy_write(phydev, 0x10, 0x8f82);
1109
1110 /* VcoSlicerThreshBitsHigh */
1111 __phy_write(phydev, 0x11, 0x5555);
1112 __phy_write(phydev, 0x12, 0x55);
1113 __phy_write(phydev, 0x10, 0x8ec0);
1114
developerce268312022-12-20 16:26:11 +08001115 /* ResetSyncOffset = 5 */
1116 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +08001117 __phy_write(phydev, 0x12, 0x0);
1118 __phy_write(phydev, 0x10, 0x8fc0);
developerb5c72b02022-12-21 15:51:07 +08001119 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001120
developerce268312022-12-20 16:26:11 +08001121 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
1122 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +08001123 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developerce268312022-12-20 16:26:11 +08001124 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +08001125 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +08001126
1127 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
1128 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerb5c72b02022-12-21 15:51:07 +08001129 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
1130 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerce73ad62022-12-07 22:43:45 +08001131
1132 /* rg_tr_lpf_cnt_val = 512 */
1133 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1134
1135 /* IIR2 related */
1136 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1137 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1138 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1139 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1140 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1141 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1142 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1143 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1144 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1145 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1146
1147 /* FFE peaking */
1148 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1149 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1150 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1151 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1152
1153 /* TX shape */
1154 /* 10/100/1000 TX shaper is enabled by default */
1155 for (i = 0x202; i < 0x230; i += 2) {
1156 if (i == 0x20c || i == 0x218 || i == 0x224)
1157 continue;
1158 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1159 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1160 }
developerce268312022-12-20 16:26:11 +08001161
1162 /* Disable LDO pump */
1163 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
1164 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
1165
1166 /* Adjust LDO output voltage */
developerb5c72b02022-12-21 15:51:07 +08001167 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developerf35532c2022-08-05 18:37:26 +08001168}
1169
1170static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001171{
1172 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +08001173 int i, ret;
1174 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +08001175 u32 *buf;
1176 bool efs_valid = true;
1177 size_t len;
1178 struct nvmem_cell *cell;
1179
1180 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1181 return -EINVAL;
1182
1183 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1184 if (IS_ERR(cell)) {
1185 if (PTR_ERR(cell) == -EPROBE_DEFER)
1186 return PTR_ERR(cell);
1187 return 0;
1188 }
1189
1190 buf = (u32 *)nvmem_cell_read(cell, &len);
1191 if (IS_ERR(buf))
1192 return PTR_ERR(buf);
1193 nvmem_cell_put(cell);
1194
1195 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
1196 efs_valid = false;
1197
1198 if (len < 4 * sizeof(u32)) {
1199 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1200 ret = -EINVAL;
1201 goto out;
1202 }
1203
1204 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1205 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1206 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1207 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
1208 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +08001209 ret = 0;
developerc50c2352021-12-01 10:45:35 +08001210
1211out:
1212 kfree(buf);
1213 return ret;
1214}
1215
developer68f6e102022-11-22 17:35:00 +08001216static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001217{
1218 mt7981_phy_finetune(phydev);
1219
1220 return mt798x_phy_calibration(phydev);
1221}
1222
developer68f6e102022-11-22 17:35:00 +08001223static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001224{
developer23021292022-10-21 19:10:10 +08001225 struct device_node *np;
1226 void __iomem *boottrap;
1227 u32 reg;
1228 int port;
1229
1230 /* Setup LED polarity according to boottrap's polarity */
1231 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1232 if (!np)
1233 return -ENOENT;
1234 boottrap = of_iomap(np, 0);
1235 if (!boottrap)
1236 return -ENOMEM;
1237 reg = readl(boottrap);
1238 port = phydev->mdio.addr;
1239 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1240 (port == GPHY_PORT1 && reg & BIT(9)) ||
1241 (port == GPHY_PORT2 && reg & BIT(10)) ||
1242 (port == GPHY_PORT3 && reg & BIT(11))) {
1243 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1244 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1245 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1246 } else {
1247 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1248 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1249 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1250 MTK_PHY_LED0_ON_LINK1000);
1251 }
developer8bc5dca2022-10-24 17:15:12 +08001252 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1253 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1254 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1255 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001256
developerf35532c2022-08-05 18:37:26 +08001257 mt7988_phy_finetune(phydev);
1258
1259 return mt798x_phy_calibration(phydev);
1260}
1261
developerc50c2352021-12-01 10:45:35 +08001262static struct phy_driver mtk_gephy_driver[] = {
1263#if 0
1264 {
1265 PHY_ID_MATCH_EXACT(0x03a29412),
1266 .name = "MediaTek MT7530 PHY",
1267 .config_init = mt7530_phy_config_init,
1268 /* Interrupts are handled by the switch, not the PHY
1269 * itself.
1270 */
1271 .config_intr = genphy_no_config_intr,
1272 .handle_interrupt = genphy_no_ack_interrupt,
1273 .suspend = genphy_suspend,
1274 .resume = genphy_resume,
1275 .read_page = mtk_gephy_read_page,
1276 .write_page = mtk_gephy_write_page,
1277 },
1278 {
1279 PHY_ID_MATCH_EXACT(0x03a29441),
1280 .name = "MediaTek MT7531 PHY",
1281 .config_init = mt7531_phy_config_init,
1282 /* Interrupts are handled by the switch, not the PHY
1283 * itself.
1284 */
1285 .config_intr = genphy_no_config_intr,
1286 .handle_interrupt = genphy_no_ack_interrupt,
1287 .suspend = genphy_suspend,
1288 .resume = genphy_resume,
1289 .read_page = mtk_gephy_read_page,
1290 .write_page = mtk_gephy_write_page,
1291 },
1292#endif
1293 {
1294 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001295 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001296 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001297 /* Interrupts are handled by the switch, not the PHY
1298 * itself.
1299 */
1300 .config_intr = genphy_no_config_intr,
1301 .handle_interrupt = genphy_no_ack_interrupt,
1302 .suspend = genphy_suspend,
1303 .resume = genphy_resume,
1304 .read_page = mtk_gephy_read_page,
1305 .write_page = mtk_gephy_write_page,
1306 },
1307 {
1308 PHY_ID_MATCH_EXACT(0x03a29481),
1309 .name = "MediaTek MT7988 PHY",
1310 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001311 /* Interrupts are handled by the switch, not the PHY
1312 * itself.
1313 */
1314 .config_intr = genphy_no_config_intr,
1315 .handle_interrupt = genphy_no_ack_interrupt,
1316 .suspend = genphy_suspend,
1317 .resume = genphy_resume,
1318 .read_page = mtk_gephy_read_page,
1319 .write_page = mtk_gephy_write_page,
1320 },
1321};
1322
1323module_phy_driver(mtk_gephy_driver);
1324
1325static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1326 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1327 { }
1328};
1329
1330MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1331MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1332MODULE_LICENSE("GPL");
1333
1334MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);