blob: d89d55f74c3a690d08ddb642831b811c703e4b10 [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>
5#include <linux/of_platform.h>
6#include <linux/phy.h>
7
8#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
9#define ZCAL_CTRL_MIN (0)
10#define ZCAL_CTRL_MAX (63)
11#define TXRESERVE_MIN (0)
12#define TXRESERVE_MAX (7)
13
14
15#define MTK_EXT_PAGE_ACCESS 0x1f
16#define MTK_PHY_PAGE_STANDARD 0x0000
17#define MTK_PHY_PAGE_EXTENDED 0x0001
18#define MTK_PHY_PAGE_EXTENDED_2 0x0002
19#define MTK_PHY_PAGE_EXTENDED_3 0x0003
20#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
21#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
22
23/* Registers on MDIO_MMD_VEND1 */
developer02d84422021-12-24 11:48:07 +080024#define MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1 (0x1)
25#define MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1 (0x2)
26#define MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0 (0x4)
27#define MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0 (0x5)
28#define MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1 (0x7) /* N means negative */
29#define MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1 (0x8)
30#define MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0 (0xa)
31#define MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0 (0xb)
32
developerc50c2352021-12-01 10:45:35 +080033#define MTK_PHY_TXVLD_DA_RG (0x12)
34#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
35#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
36
37#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
38#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
39#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
40
41#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
42#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
43#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
44
45#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
46#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
47#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
48
49#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
50#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
51#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
52
53#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
54#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
55#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
56
57#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
58#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
59#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
60
61#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
62#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
63#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
64
65
66#define MTK_PHY_RESERVE_RG_0 (0x27)
67#define MTK_PHY_RESERVE_RG_1 (0x28)
68
69#define MTK_PHY_RG_ANA_TEST_POWERUP_TX (0x3b)
70#define MTK_PHY_TANA_CAL_MODE (0xc1)
71#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
72
73#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
74#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
75#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
76#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
77#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
78
79#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
80#define MTK_PHY_RG_CAL_CKINV BIT(12)
81#define MTK_PHY_RG_ANA_CALEN BIT(8)
82#define MTK_PHY_RG_REXT_CALEN BIT(4)
83#define MTK_PHY_RG_ZCALEN_A BIT(0)
84
85#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
86#define MTK_PHY_RG_ZCALEN_B BIT(12)
87#define MTK_PHY_RG_ZCALEN_C BIT(8)
88#define MTK_PHY_RG_ZCALEN_D BIT(4)
89#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
90
91#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
92#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
93#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
94#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
95#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
96
97#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
98#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
99#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
100
101#define MTK_PHY_RG_DEV1E_REG172 (0x172)
102#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
103#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
104
105#define MTK_PHY_RG_DEV1E_REG173 (0x173)
106#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
107#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
108
109#define MTK_PHY_RG_DEV1E_REG174 (0x174)
110#define MTK_PHY_RSEL_TX_A_MASK GENMASK(14, 8)
111#define MTK_PHY_RSEL_TX_B_MASK GENMASK(6, 0)
112
113#define MTK_PHY_RG_DEV1E_REG175 (0x175)
114#define MTK_PHY_RSEL_TX_C_MASK GENMASK(14, 8)
115#define MTK_PHY_RSEL_TX_D_MASK GENMASK(6, 0)
116
117#define MTK_PHY_RG_DEV1E_REG17A (0x17a)
118#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
119
120#define MTK_PHY_RG_DEV1E_REG17B (0x17b)
121#define MTK_PHY_DA_CAL_CLK BIT(0)
122
123#define MTK_PHY_RG_DEV1E_REG17C (0x17c)
124#define MTK_PHY_DA_CALIN_FLAG BIT(0)
125
126#define MTK_PHY_RG_DEV1E_REG17D (0x17d)
127#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
128
129#define MTK_PHY_RG_DEV1E_REG17E (0x17e)
130#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
131
132#define MTK_PHY_RG_DEV1E_REG17F (0x17f)
133#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
134
135#define MTK_PHY_RG_DEV1E_REG180 (0x180)
136#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
137
138#define MTK_PHY_RG_DEV1E_REG181 (0x181)
139#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
140
141#define MTK_PHY_RG_DEV1E_REG182 (0x182)
142#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
143
144#define MTK_PHY_RG_DEV1E_REG183 (0x183)
145#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
146
147#define MTK_PHY_RG_DEV1E_REG184 (0x180)
148#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
149
150#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
151#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
152#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
153
154#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
155#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
156#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
157
158#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
159#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
160#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
161
162#define MTK_PHY_RG_DEV1E_REG540 (0x540)
163#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
164#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
165
166
167/* Registers on MDIO_MMD_VEND2 */
168#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
169#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
170
171#define MTK_PHY_RG_DEV1F_REG110 (0x110)
172#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
173#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
174
175#define MTK_PHY_RG_DEV1F_REG115 (0x115)
176#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
177
178/*
179 * These macro privides efuse parsing for internal phy.
180 */
181#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
182#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
183#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
184#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
185#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
186
187#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
188#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
189#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
190#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
191#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
192
193#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
194#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
195#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
196#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
197
198#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
199#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
200
201typedef enum {
202 PAIR_A,
203 PAIR_B,
204 PAIR_C,
205 PAIR_D,
206} phy_cal_pair_t;
207
208const u8 mt798x_zcal_to_r50[64] = {
209 7, 8, 9, 9, 10, 10, 11, 11,
210 12, 13, 13, 14, 14, 15, 16, 16,
211 17, 18, 18, 19, 20, 21, 21, 22,
212 23, 24, 24, 25, 26, 27, 28, 29,
213 30, 31, 32, 33, 34, 35, 36, 37,
214 38, 40, 41, 42, 43, 45, 46, 48,
215 49, 51, 52, 54, 55, 57, 59, 61,
216 62, 63, 63, 63, 63, 63, 63, 63
217};
218
219const char pair[4] = {'A', 'B', 'C', 'D'};
220
221#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
222 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
223
224#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
225 for(i=PAIR_A; i<=PAIR_A; i++) { \
226 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
227 if(cal_ret) break; \
228 }
229
230#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
231 for(i=PAIR_A; i<=PAIR_D; i++) { \
232 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
233 if(cal_ret) break; \
234 }
235
developerc6e131e2021-12-08 12:36:24 +0800236#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
237 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
238 CAL_##pair_mode(cal_item, sw) \
239 }
developerc50c2352021-12-01 10:45:35 +0800240
241#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800242 if ((efs_valid && ret) || \
243 (!ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800244 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800245 } else if ((!efs_valid && ret) || \
246 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800247 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800248 }
249
250#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
251 if ((efs_valid && ret) || \
developerc6e131e2021-12-08 12:36:24 +0800252 (!ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800253 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800254 }
255
256#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
257 ret = of_property_read_string(phydev->mdio.dev.of_node, \
258 #cal_item, &cal_mode_get); \
259 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800260 else { \
261 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
262 " use default value," \
263 " efs-valid: %s", \
264 #cal_item, \
265 ret? "" : cal_mode_get, \
266 ret? "not specified" : " not supported", \
267 efs_valid? "yes" : "no"); \
268 } \
developerc50c2352021-12-01 10:45:35 +0800269 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800270 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800271 ret = -EIO; \
272 goto out; \
273 }
274
275static int mtk_gephy_read_page(struct phy_device *phydev)
276{
277 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
278}
279
280static int mtk_gephy_write_page(struct phy_device *phydev, int page)
281{
282 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
283}
284
285/*
286 * One calibration cycle consists of:
287 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
288 * until AD_CAL_COMP is ready to output calibration result.
289 * 2.Wait until DA_CAL_CLK is available.
290 * 3.Fetch AD_CAL_COMP_OUT.
291 */
292static int cal_cycle(struct phy_device *phydev, int devad,
293 u32 regnum, u16 mask, u16 cal_val)
294{
295 unsigned long timeout;
296 int reg_val;
297 int ret;
298
299 phy_modify_mmd(phydev, devad, regnum,
300 mask, cal_val);
301 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
302 MTK_PHY_DA_CALIN_FLAG);
303
304 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
305 do{
306 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
307 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
308
309 if(!(reg_val & BIT(0))) {
310 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
311 return -ETIMEDOUT;
312 }
313
314 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
315 MTK_PHY_DA_CALIN_FLAG);
316 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
317 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
318 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
319
320 return ret;
321}
322
323static int rext_fill_result(struct phy_device *phydev, u16 *buf)
324{
325 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
326 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
327 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
328 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
329
330 return 0;
331}
332
333static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
334{
335 u16 rext_cal_val[2];
336
337 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
338 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
339 rext_fill_result(phydev, rext_cal_val);
340
341 return 0;
342}
343
344static int rext_cal_sw(struct phy_device *phydev)
345{
346 u8 rg_zcal_ctrl_def;
347 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
348 u8 lower_ret, upper_ret;
349 u16 rext_cal_val[2];
350 int ret;
351
352 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
353 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
354 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
355 MTK_PHY_RG_TXVOS_CALEN);
356 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
357 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
358 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
359 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
360
361 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
362 MTK_PHY_RG_ZCAL_CTRL_MASK;
363 zcal_lower = ZCAL_CTRL_MIN;
364 zcal_upper = ZCAL_CTRL_MAX;
365
366 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
367 while((zcal_upper-zcal_lower) > 1) {
368 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
369 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
370 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
371 if(ret==1)
372 zcal_upper = rg_zcal_ctrl;
373 else if(ret==0)
374 zcal_lower = rg_zcal_ctrl;
375 else
376 goto restore;
377 }
378
379 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
380 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
381 if(lower_ret < 0)
382 goto restore;
383
384 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
385 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
386 if(upper_ret < 0)
387 goto restore;
388
389 ret = upper_ret-lower_ret;
390 if (ret == 1) {
391 rext_cal_val[0] = zcal_upper;
392 rext_cal_val[1] = zcal_upper >> 3;
393 rext_fill_result(phydev, rext_cal_val);
394 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
395 ret = 0;
396 } else
397 ret = -EINVAL;
398
399restore:
400 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
401 MTK_PHY_ANA_TEST_MODE_MASK);
402 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
403 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
404 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
405 MTK_PHY_RG_TST_DMY2_MASK);
406 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
407 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
408
409 return ret;
410}
411
412static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
413{
414 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
415 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
416 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
417 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
418 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
419 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
420 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
421 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
422
423 return 0;
424}
425
426static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
427{
428 u16 tx_offset_cal_val[4];
429
430 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
431 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
432 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
433 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
434
435 tx_offset_fill_result(phydev, tx_offset_cal_val);
436
437 return 0;
438}
439
440static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
441{
developer02d84422021-12-24 11:48:07 +0800442 /* We add some calibration to efuse values:
443 * GBE: +7, TBT: +1, HBT: +4, TST: +7
444 */
developerc50c2352021-12-01 10:45:35 +0800445 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800446 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + 7) << 10);
developerc50c2352021-12-01 10:45:35 +0800447 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800448 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + 1);
developerc50c2352021-12-01 10:45:35 +0800449 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800450 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + 4) << 10);
developerc50c2352021-12-01 10:45:35 +0800451 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800452 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + 7);
developerc50c2352021-12-01 10:45:35 +0800453
454 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800455 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800456 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800457 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + 1);
developerc50c2352021-12-01 10:45:35 +0800458 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800459 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + 4 ) << 8);
developerc50c2352021-12-01 10:45:35 +0800460 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800461 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + 7);
developerc50c2352021-12-01 10:45:35 +0800462
463 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800464 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800465 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800466 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + 1);
developerc50c2352021-12-01 10:45:35 +0800467 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800468 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800469 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800470 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + 7);
developerc50c2352021-12-01 10:45:35 +0800471
472 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800473 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800474 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800475 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + 1);
developerc50c2352021-12-01 10:45:35 +0800476 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800477 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800478 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800479 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + 7);
developerc50c2352021-12-01 10:45:35 +0800480
481 return 0;
482}
483
484static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
485{
486 u16 tx_amp_cal_val[4];
487
488 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
489 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
490 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
491 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
492 tx_amp_fill_result(phydev, tx_amp_cal_val);
493
494 return 0;
495}
496
497static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
498 phy_cal_pair_t txg_calen_x)
499{
500 switch(txg_calen_x) {
501 case PAIR_A:
502 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
503 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, buf[0] << 8);
504 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
505 MTK_PHY_DA_TX_R50_A_TBT_MASK, buf[0]);
506 break;
507 case PAIR_B:
508 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
509 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, buf[0] << 8);
510 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
511 MTK_PHY_DA_TX_R50_B_TBT_MASK, buf[0]);
512 break;
513 case PAIR_C:
514 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
515 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, buf[0] << 8);
516 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
517 MTK_PHY_DA_TX_R50_C_TBT_MASK, buf[0]);
518 break;
519 case PAIR_D:
520 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
521 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, buf[0] << 8);
522 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
523 MTK_PHY_DA_TX_R50_D_TBT_MASK, buf[0]);
524 break;
525 }
526 return 0;
527}
528
529static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
530 phy_cal_pair_t txg_calen_x)
531{
532 u16 tx_r50_cal_val[1];
533
534 switch(txg_calen_x) {
535 case PAIR_A:
536 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
537 break;
538 case PAIR_B:
539 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
540 break;
541 case PAIR_C:
542 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
543 break;
544 case PAIR_D:
545 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
546 break;
547 }
548 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
549
550 return 0;
551}
552
553static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
554{
555 u8 rg_zcal_ctrl_def;
556 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
557 u8 lower_ret, upper_ret;
558 u16 tx_r50_cal_val[1];
559 int ret;
560
561 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
562 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
563 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
564 MTK_PHY_RG_TXVOS_CALEN);
565 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
566 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
567 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
568 BIT(txg_calen_x * 4));
569 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
570 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
571
572 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
573 MTK_PHY_RG_ZCAL_CTRL_MASK;
574 zcal_lower = ZCAL_CTRL_MIN;
575 zcal_upper = ZCAL_CTRL_MAX;
576
developer02d84422021-12-24 11:48:07 +0800577 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800578 while((zcal_upper-zcal_lower) > 1) {
579 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
580 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
581 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
582 if(ret==1)
583 zcal_upper = rg_zcal_ctrl;
584 else if(ret==0)
585 zcal_lower = rg_zcal_ctrl;
586 else
587 goto restore;
588 }
589
590 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
591 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
592 if(lower_ret < 0)
593 goto restore;
594
595 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
596 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
597 if(upper_ret < 0)
598 goto restore;
599
600 ret = upper_ret-lower_ret;
601 if (ret == 1) {
602 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
603 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800604 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800605 pair[txg_calen_x], zcal_lower);
606 ret = 0;
607 } else
608 ret = -EINVAL;
609
610restore:
611 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
612 MTK_PHY_ANA_TEST_MODE_MASK);
613 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
614 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
615 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
616 BIT(txg_calen_x * 4));
617 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
618 MTK_PHY_RG_TST_DMY2_MASK);
619 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
620 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
621
622 return ret;
623}
624
625static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
626{
627 u8 lower_idx, upper_idx, txreserve_val;
628 u8 lower_ret, upper_ret;
629 int ret;
630
631 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
632 MTK_PHY_RG_ANA_CALEN);
633 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
634 MTK_PHY_RG_CAL_CKINV);
635 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
636 MTK_PHY_RG_TXVOS_CALEN);
637
638 switch(rg_txreserve_x) {
639 case PAIR_A:
640 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
641 MTK_PHY_DASN_DAC_IN0_A_MASK);
642 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
643 MTK_PHY_DASN_DAC_IN1_A_MASK);
644 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
645 MTK_PHY_RG_ZCALEN_A);
646 break;
647 case PAIR_B:
648 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
649 MTK_PHY_DASN_DAC_IN0_B_MASK);
650 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
651 MTK_PHY_DASN_DAC_IN1_B_MASK);
652 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
653 MTK_PHY_RG_ZCALEN_B);
654 break;
655 case PAIR_C:
656 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
657 MTK_PHY_DASN_DAC_IN0_C_MASK);
658 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
659 MTK_PHY_DASN_DAC_IN1_C_MASK);
660 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
661 MTK_PHY_RG_ZCALEN_C);
662 break;
663 case PAIR_D:
664 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
665 MTK_PHY_DASN_DAC_IN0_D_MASK);
666 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
667 MTK_PHY_DASN_DAC_IN1_D_MASK);
668 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
669 MTK_PHY_RG_ZCALEN_D);
670 break;
671 default:
672 ret = -EINVAL;
673 goto restore;
674 }
675
676 lower_idx = TXRESERVE_MIN;
677 upper_idx = TXRESERVE_MAX;
678
679 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
680 while((upper_idx-lower_idx) > 1) {
681 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
682 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
683 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
684 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
685 txreserve_val << 12 | txreserve_val << 8 |
686 txreserve_val << 4 | txreserve_val);
687 if(ret==1)
688 upper_idx = txreserve_val;
689 else if(ret==0)
690 lower_idx = txreserve_val;
691 else
692 goto restore;
693 }
694
695 /* We calibrate TX-VCM in different logic. Check upper index and then
696 * lower index. If this calibration is valid, apply lower index's result.
697 */
698 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
699 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
700 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
701 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
702 if(lower_ret < 0)
703 goto restore;
704
705 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
706 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
707 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
708 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
709 if(upper_ret < 0)
710 goto restore;
711
712 ret = upper_ret-lower_ret;
713 if (ret == 1) {
714 ret = 0;
715 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
716 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
717 ret = 0;
718 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
719 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
720 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
721 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
722 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
723 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
724 ret = 0;
725 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
726 } else
727 ret = -EINVAL;
728
729restore:
730 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
731 MTK_PHY_RG_ANA_CALEN);
732 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
733 MTK_PHY_RG_TXVOS_CALEN);
734 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
735 MTK_PHY_RG_ZCALEN_A);
736 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
737 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
738
739 return ret;
740}
741
742static void mtk_gephy_config_init(struct phy_device *phydev)
743{
744 /* Disable EEE */
745 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
746
747 /* Enable HW auto downshift */
748 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
749
750 /* Increase SlvDPSready time */
751 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
752 __phy_write(phydev, 0x10, 0xafae);
753 __phy_write(phydev, 0x12, 0x2f);
754 __phy_write(phydev, 0x10, 0x8fae);
755 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
756
757 /* Adjust 100_mse_threshold */
758 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
759
760 /* Disable mcc */
761 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
762}
763
764static int mt7530_phy_config_init(struct phy_device *phydev)
765{
766 mtk_gephy_config_init(phydev);
767
768 /* Increase post_update_timer */
769 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
770
771 return 0;
772}
773
774static int mt7531_phy_config_init(struct phy_device *phydev)
775{
776 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
777 return -EINVAL;
778
779 mtk_gephy_config_init(phydev);
780
781 /* PHY link down power saving enable */
782 phy_set_bits(phydev, 0x17, BIT(4));
783 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
784
785 /* Set TX Pair delay selection */
786 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
787 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
788
789 return 0;
790}
791
developer02d84422021-12-24 11:48:07 +0800792static inline void mt798x_phy_finetune(struct phy_device *phydev)
793{
794 /* 100M eye finetune:
795 * Keep middle level of TX MLT3 shapper as default.
796 * Only change TX MLT3 overshoot level here.
797 */
798 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
799 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
800 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
801 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
802 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
803 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
804 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
805 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
806#
807 /* TX-AMP finetune:
808 * 100M +4, 1000M +6 to default value.
809 * If efuse values aren't valid, TX-AMP uses the below values.
810 */
811 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
812 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
813 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
814 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
815 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
816 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
817 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
818 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
819}
820
developerc50c2352021-12-01 10:45:35 +0800821static int mt798x_phy_config_init(struct phy_device *phydev)
822{
823 const char *cal_mode_from_dts;
824 int i, ret, cal_ret;
825 u32 *buf;
826 bool efs_valid = true;
827 size_t len;
828 struct nvmem_cell *cell;
829
830 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
831 return -EINVAL;
832
developer02d84422021-12-24 11:48:07 +0800833 mt798x_phy_finetune(phydev);
834
developerc50c2352021-12-01 10:45:35 +0800835 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
836 if (IS_ERR(cell)) {
837 if (PTR_ERR(cell) == -EPROBE_DEFER)
838 return PTR_ERR(cell);
839 return 0;
840 }
841
842 buf = (u32 *)nvmem_cell_read(cell, &len);
843 if (IS_ERR(buf))
844 return PTR_ERR(buf);
845 nvmem_cell_put(cell);
846
847 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
848 efs_valid = false;
849
850 if (len < 4 * sizeof(u32)) {
851 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
852 ret = -EINVAL;
853 goto out;
854 }
855
856 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
857 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
858 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
859 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
860 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800861 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800862
863out:
864 kfree(buf);
865 return ret;
866}
867
868static struct phy_driver mtk_gephy_driver[] = {
869#if 0
870 {
871 PHY_ID_MATCH_EXACT(0x03a29412),
872 .name = "MediaTek MT7530 PHY",
873 .config_init = mt7530_phy_config_init,
874 /* Interrupts are handled by the switch, not the PHY
875 * itself.
876 */
877 .config_intr = genphy_no_config_intr,
878 .handle_interrupt = genphy_no_ack_interrupt,
879 .suspend = genphy_suspend,
880 .resume = genphy_resume,
881 .read_page = mtk_gephy_read_page,
882 .write_page = mtk_gephy_write_page,
883 },
884 {
885 PHY_ID_MATCH_EXACT(0x03a29441),
886 .name = "MediaTek MT7531 PHY",
887 .config_init = mt7531_phy_config_init,
888 /* Interrupts are handled by the switch, not the PHY
889 * itself.
890 */
891 .config_intr = genphy_no_config_intr,
892 .handle_interrupt = genphy_no_ack_interrupt,
893 .suspend = genphy_suspend,
894 .resume = genphy_resume,
895 .read_page = mtk_gephy_read_page,
896 .write_page = mtk_gephy_write_page,
897 },
898#endif
899 {
900 PHY_ID_MATCH_EXACT(0x03a29461),
901 .name = "MediaTek MT798x PHY",
902 .config_init = mt798x_phy_config_init,
903 /* Interrupts are handled by the switch, not the PHY
904 * itself.
905 */
906 .config_intr = genphy_no_config_intr,
907 .handle_interrupt = genphy_no_ack_interrupt,
908 .suspend = genphy_suspend,
909 .resume = genphy_resume,
910 .read_page = mtk_gephy_read_page,
911 .write_page = mtk_gephy_write_page,
912 },
913};
914
915module_phy_driver(mtk_gephy_driver);
916
917static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
918 { PHY_ID_MATCH_VENDOR(0x03a29400) },
919 { }
920};
921
922MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
923MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
924MODULE_LICENSE("GPL");
925
926MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);