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