blob: 27d13b9f5b7d254353f8aec03c08156b59f633a4 [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 */
developer87c89d12022-08-19 17:46:34 +080024enum {
developerf35532c2022-08-05 18:37:26 +080025 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
26 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
27 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
28 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
29 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
30 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
31 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
32 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
33 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
34 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
35 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
36 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
37 MTK_PHY_TX_MLT3_END,
38};
developer02d84422021-12-24 11:48:07 +080039
developerc50c2352021-12-01 10:45:35 +080040#define MTK_PHY_TXVLD_DA_RG (0x12)
41#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
42#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
43
44#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
45#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
46#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
47
48#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
49#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
50#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
51
52#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
53#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
54#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
55
56#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
57#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
58#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
59
60#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
61#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
62#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
63
64#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
65#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
66#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
67
68#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
69#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
70#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
71
72
73#define MTK_PHY_RESERVE_RG_0 (0x27)
74#define MTK_PHY_RESERVE_RG_1 (0x28)
75
76#define MTK_PHY_RG_ANA_TEST_POWERUP_TX (0x3b)
77#define MTK_PHY_TANA_CAL_MODE (0xc1)
78#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
79
developer57374032022-10-11 16:43:24 +080080#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
81#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
82
developerc50c2352021-12-01 10:45:35 +080083#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
84#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
85#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
86#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
87#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
88
89#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
90#define MTK_PHY_RG_CAL_CKINV BIT(12)
91#define MTK_PHY_RG_ANA_CALEN BIT(8)
92#define MTK_PHY_RG_REXT_CALEN BIT(4)
93#define MTK_PHY_RG_ZCALEN_A BIT(0)
94
95#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
96#define MTK_PHY_RG_ZCALEN_B BIT(12)
97#define MTK_PHY_RG_ZCALEN_C BIT(8)
98#define MTK_PHY_RG_ZCALEN_D BIT(4)
99#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
100
101#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
102#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
103#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
104#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
105#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
106
107#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
108#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
109#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
110
developer6de96aa2022-09-29 16:46:18 +0800111#define MTK_PHY_RG_TX_FILTER (0xfe)
112
developerc50c2352021-12-01 10:45:35 +0800113#define MTK_PHY_RG_DEV1E_REG172 (0x172)
114#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
115#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
116
117#define MTK_PHY_RG_DEV1E_REG173 (0x173)
118#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
119#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
120
121#define MTK_PHY_RG_DEV1E_REG174 (0x174)
122#define MTK_PHY_RSEL_TX_A_MASK GENMASK(14, 8)
123#define MTK_PHY_RSEL_TX_B_MASK GENMASK(6, 0)
124
125#define MTK_PHY_RG_DEV1E_REG175 (0x175)
126#define MTK_PHY_RSEL_TX_C_MASK GENMASK(14, 8)
127#define MTK_PHY_RSEL_TX_D_MASK GENMASK(6, 0)
128
129#define MTK_PHY_RG_DEV1E_REG17A (0x17a)
130#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
131
132#define MTK_PHY_RG_DEV1E_REG17B (0x17b)
133#define MTK_PHY_DA_CAL_CLK BIT(0)
134
135#define MTK_PHY_RG_DEV1E_REG17C (0x17c)
136#define MTK_PHY_DA_CALIN_FLAG BIT(0)
137
138#define MTK_PHY_RG_DEV1E_REG17D (0x17d)
139#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
140
141#define MTK_PHY_RG_DEV1E_REG17E (0x17e)
142#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
143
144#define MTK_PHY_RG_DEV1E_REG17F (0x17f)
145#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
146
147#define MTK_PHY_RG_DEV1E_REG180 (0x180)
148#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
149
150#define MTK_PHY_RG_DEV1E_REG181 (0x181)
151#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
152
153#define MTK_PHY_RG_DEV1E_REG182 (0x182)
154#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
155
156#define MTK_PHY_RG_DEV1E_REG183 (0x183)
157#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
158
159#define MTK_PHY_RG_DEV1E_REG184 (0x180)
160#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
161
162#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
163#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
164#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
165
166#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
167#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
168#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
169
170#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
171#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
172#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
173
174#define MTK_PHY_RG_DEV1E_REG540 (0x540)
175#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
176#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
177
178
179/* Registers on MDIO_MMD_VEND2 */
180#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
181#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
182
183#define MTK_PHY_RG_DEV1F_REG110 (0x110)
184#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
185#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
186
187#define MTK_PHY_RG_DEV1F_REG115 (0x115)
188#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
189
190/*
191 * These macro privides efuse parsing for internal phy.
192 */
193#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
194#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
195#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
196#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
197#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
198
199#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
200#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
201#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
202#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
203#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
204
205#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
206#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
207#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
208#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
209
210#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
211#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
212
213typedef enum {
214 PAIR_A,
215 PAIR_B,
216 PAIR_C,
217 PAIR_D,
218} phy_cal_pair_t;
219
220const u8 mt798x_zcal_to_r50[64] = {
221 7, 8, 9, 9, 10, 10, 11, 11,
222 12, 13, 13, 14, 14, 15, 16, 16,
223 17, 18, 18, 19, 20, 21, 21, 22,
224 23, 24, 24, 25, 26, 27, 28, 29,
225 30, 31, 32, 33, 34, 35, 36, 37,
226 38, 40, 41, 42, 43, 45, 46, 48,
227 49, 51, 52, 54, 55, 57, 59, 61,
228 62, 63, 63, 63, 63, 63, 63, 63
229};
230
231const char pair[4] = {'A', 'B', 'C', 'D'};
232
233#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
234 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
235
236#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
237 for(i=PAIR_A; i<=PAIR_A; i++) { \
238 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
239 if(cal_ret) break; \
240 }
241
242#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
243 for(i=PAIR_A; i<=PAIR_D; i++) { \
244 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
245 if(cal_ret) break; \
246 }
247
developerc6e131e2021-12-08 12:36:24 +0800248#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
249 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
250 CAL_##pair_mode(cal_item, sw) \
251 }
developerc50c2352021-12-01 10:45:35 +0800252
253#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800254 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800255 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800256 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800257 } else if ((!efs_valid && ret) || \
258 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800259 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800260 }
261
262#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
263 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800264 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800265 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800266 }
267
268#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
269 ret = of_property_read_string(phydev->mdio.dev.of_node, \
270 #cal_item, &cal_mode_get); \
271 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800272 else { \
273 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
274 " use default value," \
275 " efs-valid: %s", \
276 #cal_item, \
277 ret? "" : cal_mode_get, \
278 ret? "not specified" : " not supported", \
279 efs_valid? "yes" : "no"); \
280 } \
developerc50c2352021-12-01 10:45:35 +0800281 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800282 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800283 ret = -EIO; \
284 goto out; \
285 }
286
287static int mtk_gephy_read_page(struct phy_device *phydev)
288{
289 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
290}
291
292static int mtk_gephy_write_page(struct phy_device *phydev, int page)
293{
294 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
295}
296
297/*
298 * One calibration cycle consists of:
299 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
300 * until AD_CAL_COMP is ready to output calibration result.
301 * 2.Wait until DA_CAL_CLK is available.
302 * 3.Fetch AD_CAL_COMP_OUT.
303 */
304static int cal_cycle(struct phy_device *phydev, int devad,
305 u32 regnum, u16 mask, u16 cal_val)
306{
307 unsigned long timeout;
308 int reg_val;
309 int ret;
310
311 phy_modify_mmd(phydev, devad, regnum,
312 mask, cal_val);
313 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
314 MTK_PHY_DA_CALIN_FLAG);
315
316 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
317 do{
318 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
319 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
320
321 if(!(reg_val & BIT(0))) {
322 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
323 return -ETIMEDOUT;
324 }
325
326 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
327 MTK_PHY_DA_CALIN_FLAG);
328 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
329 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
330 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
331
332 return ret;
333}
334
335static int rext_fill_result(struct phy_device *phydev, u16 *buf)
336{
337 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
338 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
339 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
340 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
341
342 return 0;
343}
344
345static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
346{
347 u16 rext_cal_val[2];
348
349 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
350 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
351 rext_fill_result(phydev, rext_cal_val);
352
353 return 0;
354}
355
356static int rext_cal_sw(struct phy_device *phydev)
357{
358 u8 rg_zcal_ctrl_def;
359 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
360 u8 lower_ret, upper_ret;
361 u16 rext_cal_val[2];
362 int ret;
363
364 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
365 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
366 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
367 MTK_PHY_RG_TXVOS_CALEN);
368 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
369 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
370 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
371 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
372
373 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
374 MTK_PHY_RG_ZCAL_CTRL_MASK;
375 zcal_lower = ZCAL_CTRL_MIN;
376 zcal_upper = ZCAL_CTRL_MAX;
377
378 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
379 while((zcal_upper-zcal_lower) > 1) {
380 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
381 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
382 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800383 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800384 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800385 upper_ret = ret;
386 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800387 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800388 lower_ret = ret;
389 } else
developerc50c2352021-12-01 10:45:35 +0800390 goto restore;
391 }
392
developer78aa7b92021-12-29 15:22:10 +0800393 if(zcal_lower == ZCAL_CTRL_MIN) {
394 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
395 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
396 } else if(zcal_upper == ZCAL_CTRL_MAX) {
397 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
398 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
399 }
400 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800401 goto restore;
402
403 ret = upper_ret-lower_ret;
404 if (ret == 1) {
405 rext_cal_val[0] = zcal_upper;
406 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800407 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800408 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
409 ret = 0;
410 } else
411 ret = -EINVAL;
412
413restore:
414 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
415 MTK_PHY_ANA_TEST_MODE_MASK);
416 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
417 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
418 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
419 MTK_PHY_RG_TST_DMY2_MASK);
420 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
421 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
422
423 return ret;
424}
425
426static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
427{
428 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
429 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
430 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
431 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
432 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
433 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
434 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
435 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
436
437 return 0;
438}
439
440static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
441{
442 u16 tx_offset_cal_val[4];
443
444 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
445 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
446 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
447 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
448
449 tx_offset_fill_result(phydev, tx_offset_cal_val);
450
451 return 0;
452}
453
454static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
455{
developer87c89d12022-08-19 17:46:34 +0800456 int bias[16] = {0};
457 switch(phydev->drv->phy_id) {
458 case 0x03a29461:
459 {
460 /* We add some calibration to efuse values:
461 * GBE: +7, TBT: +1, HBT: +4, TST: +7
462 */
463 int tmp[16] = { 7, 1, 4, 7,
464 7, 1, 4, 7,
465 7, 1, 4, 7,
466 7, 1, 4, 7 };
467 memcpy(bias, (const void *)tmp, sizeof(bias));
468 break;
469 }
470 case 0x03a29481:
471 {
472 int tmp[16] = { 10, 6, 6, 10,
473 10, 6, 6, 10,
474 10, 6, 6, 10,
475 10, 6, 6, 10 };
476 memcpy(bias, (const void *)tmp, sizeof(bias));
477 break;
478 }
479 default:
480 break;
481 }
developerc50c2352021-12-01 10:45:35 +0800482 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800483 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800484 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800485 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800486 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800487 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800488 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800489 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800490
491 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800492 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800493 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800494 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800495 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800496 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800497 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800498 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800499
500 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800501 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800502 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800503 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800504 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800505 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800506 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800507 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800508
509 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800510 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800511 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800512 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800513 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800514 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800515 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800516 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800517
518 return 0;
519}
520
521static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
522{
523 u16 tx_amp_cal_val[4];
524
525 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
526 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
527 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
528 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
529 tx_amp_fill_result(phydev, tx_amp_cal_val);
530
531 return 0;
532}
533
534static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
535 phy_cal_pair_t txg_calen_x)
536{
developer87c89d12022-08-19 17:46:34 +0800537 int bias[4] = {0};
538 switch(phydev->drv->phy_id) {
539 case 0x03a29481:
540 {
541 int tmp[16] = { 1, 1, 1, 1 };
542 memcpy(bias, (const void *)tmp, sizeof(bias));
543 break;
544 }
545 /* 0x03a29461 enters default case */
546 default:
547 break;
548 }
549
developerc50c2352021-12-01 10:45:35 +0800550 switch(txg_calen_x) {
551 case PAIR_A:
552 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800553 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800554 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800555 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800556 break;
557 case PAIR_B:
558 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800559 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800560 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800561 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800562 break;
563 case PAIR_C:
564 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800565 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800566 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800567 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800568 break;
569 case PAIR_D:
570 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800571 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800572 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800573 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800574 break;
575 }
576 return 0;
577}
578
579static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
580 phy_cal_pair_t txg_calen_x)
581{
582 u16 tx_r50_cal_val[1];
583
584 switch(txg_calen_x) {
585 case PAIR_A:
586 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
587 break;
588 case PAIR_B:
589 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
590 break;
591 case PAIR_C:
592 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
593 break;
594 case PAIR_D:
595 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
596 break;
597 }
598 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
599
600 return 0;
601}
602
603static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
604{
605 u8 rg_zcal_ctrl_def;
606 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
607 u8 lower_ret, upper_ret;
608 u16 tx_r50_cal_val[1];
609 int ret;
610
611 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
612 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
613 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
614 MTK_PHY_RG_TXVOS_CALEN);
615 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
616 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
617 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
618 BIT(txg_calen_x * 4));
619 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
620 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
621
622 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
623 MTK_PHY_RG_ZCAL_CTRL_MASK;
624 zcal_lower = ZCAL_CTRL_MIN;
625 zcal_upper = ZCAL_CTRL_MAX;
626
developer02d84422021-12-24 11:48:07 +0800627 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800628 while((zcal_upper-zcal_lower) > 1) {
629 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
630 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
631 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800632 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800633 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800634 upper_ret = ret;
635 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800636 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800637 lower_ret = ret;
638 } else
developerc50c2352021-12-01 10:45:35 +0800639 goto restore;
640 }
641
developer78aa7b92021-12-29 15:22:10 +0800642 if(zcal_lower == ZCAL_CTRL_MIN) {
643 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800644 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800645 } else if(zcal_upper == ZCAL_CTRL_MAX) {
646 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800647 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800648 }
649 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800650 goto restore;
651
652 ret = upper_ret-lower_ret;
653 if (ret == 1) {
654 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
655 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800656 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800657 pair[txg_calen_x], zcal_lower);
658 ret = 0;
659 } else
660 ret = -EINVAL;
661
662restore:
663 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
664 MTK_PHY_ANA_TEST_MODE_MASK);
665 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
666 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
667 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
668 BIT(txg_calen_x * 4));
669 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
670 MTK_PHY_RG_TST_DMY2_MASK);
671 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
672 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
673
674 return ret;
675}
676
677static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
678{
679 u8 lower_idx, upper_idx, txreserve_val;
680 u8 lower_ret, upper_ret;
681 int ret;
682
683 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
684 MTK_PHY_RG_ANA_CALEN);
685 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
686 MTK_PHY_RG_CAL_CKINV);
687 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
688 MTK_PHY_RG_TXVOS_CALEN);
689
690 switch(rg_txreserve_x) {
691 case PAIR_A:
692 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
693 MTK_PHY_DASN_DAC_IN0_A_MASK);
694 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
695 MTK_PHY_DASN_DAC_IN1_A_MASK);
696 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
697 MTK_PHY_RG_ZCALEN_A);
698 break;
699 case PAIR_B:
700 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
701 MTK_PHY_DASN_DAC_IN0_B_MASK);
702 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
703 MTK_PHY_DASN_DAC_IN1_B_MASK);
704 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
705 MTK_PHY_RG_ZCALEN_B);
706 break;
707 case PAIR_C:
708 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
709 MTK_PHY_DASN_DAC_IN0_C_MASK);
710 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
711 MTK_PHY_DASN_DAC_IN1_C_MASK);
712 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
713 MTK_PHY_RG_ZCALEN_C);
714 break;
715 case PAIR_D:
716 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
717 MTK_PHY_DASN_DAC_IN0_D_MASK);
718 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
719 MTK_PHY_DASN_DAC_IN1_D_MASK);
720 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
721 MTK_PHY_RG_ZCALEN_D);
722 break;
723 default:
724 ret = -EINVAL;
725 goto restore;
726 }
727
728 lower_idx = TXRESERVE_MIN;
729 upper_idx = TXRESERVE_MAX;
730
731 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
732 while((upper_idx-lower_idx) > 1) {
733 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
734 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
735 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
736 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
737 txreserve_val << 12 | txreserve_val << 8 |
738 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800739 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800740 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800741 upper_ret = ret;
742 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800743 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800744 lower_ret = ret;
745 } else
developerc50c2352021-12-01 10:45:35 +0800746 goto restore;
747 }
748
developer78aa7b92021-12-29 15:22:10 +0800749 if(lower_idx == TXRESERVE_MIN) {
750 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800751 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
752 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
753 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800754 } else if(upper_idx == TXRESERVE_MAX) {
755 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800756 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
757 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
758 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800759 }
760 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800761 goto restore;
762
developer78aa7b92021-12-29 15:22:10 +0800763 /* We calibrate TX-VCM in different logic. Check upper index and then
764 * lower index. If this calibration is valid, apply lower index's result.
765 */
developerc50c2352021-12-01 10:45:35 +0800766 ret = upper_ret-lower_ret;
767 if (ret == 1) {
768 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800769 /* Make sure we use upper_idx in our calibration system */
770 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
771 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
772 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
773 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800774 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
775 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
776 ret = 0;
777 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
778 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
779 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
780 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
781 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
782 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
783 ret = 0;
784 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
785 } else
786 ret = -EINVAL;
787
788restore:
789 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
790 MTK_PHY_RG_ANA_CALEN);
791 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
792 MTK_PHY_RG_TXVOS_CALEN);
793 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
794 MTK_PHY_RG_ZCALEN_A);
795 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
796 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
797
798 return ret;
799}
800
801static void mtk_gephy_config_init(struct phy_device *phydev)
802{
803 /* Disable EEE */
804 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
805
806 /* Enable HW auto downshift */
807 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
808
809 /* Increase SlvDPSready time */
810 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
811 __phy_write(phydev, 0x10, 0xafae);
812 __phy_write(phydev, 0x12, 0x2f);
813 __phy_write(phydev, 0x10, 0x8fae);
814 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
815
816 /* Adjust 100_mse_threshold */
817 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
818
819 /* Disable mcc */
820 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
821}
822
823static int mt7530_phy_config_init(struct phy_device *phydev)
824{
825 mtk_gephy_config_init(phydev);
826
827 /* Increase post_update_timer */
828 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
829
830 return 0;
831}
832
833static int mt7531_phy_config_init(struct phy_device *phydev)
834{
835 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
836 return -EINVAL;
837
838 mtk_gephy_config_init(phydev);
839
840 /* PHY link down power saving enable */
841 phy_set_bits(phydev, 0x17, BIT(4));
842 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
843
844 /* Set TX Pair delay selection */
845 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
846 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
847
848 return 0;
849}
850
developerf35532c2022-08-05 18:37:26 +0800851static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800852{
853 /* 100M eye finetune:
854 * Keep middle level of TX MLT3 shapper as default.
855 * Only change TX MLT3 overshoot level here.
856 */
857 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
858 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
859 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
860 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
861 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
862 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
863 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
864 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800865
developer02d84422021-12-24 11:48:07 +0800866 /* TX-AMP finetune:
867 * 100M +4, 1000M +6 to default value.
868 * If efuse values aren't valid, TX-AMP uses the below values.
869 */
870 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
871 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
872 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
873 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
874 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
875 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
876 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
877 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
878}
879
developerf35532c2022-08-05 18:37:26 +0800880static inline void mt7988_phy_finetune(struct phy_device *phydev)
881{
882 int i;
883 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
884 0x020d, 0x0206, 0x0384, 0x03d0,
885 0x03c6, 0x030a, 0x0011, 0x0005};
886
887 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
888 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
889 }
developer6de96aa2022-09-29 16:46:18 +0800890
developer57374032022-10-11 16:43:24 +0800891 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800892 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800893
894 /* Disable TX power saving */
895 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
896 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3);
897
898 /* Slave mode finetune*/
899 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
900 __phy_write(phydev, 0x12, 0x0);
901 __phy_write(phydev, 0x11, 0x700);
902 __phy_write(phydev, 0x10, 0x9686);
903
904 __phy_write(phydev, 0x12, 0x0);
905 __phy_write(phydev, 0x11, 0x64);
906 __phy_write(phydev, 0x10, 0x8f82);
907 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
908
developerf35532c2022-08-05 18:37:26 +0800909}
910
911static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800912{
913 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800914 int i, ret;
915 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800916 u32 *buf;
917 bool efs_valid = true;
918 size_t len;
919 struct nvmem_cell *cell;
920
921 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
922 return -EINVAL;
923
924 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
925 if (IS_ERR(cell)) {
926 if (PTR_ERR(cell) == -EPROBE_DEFER)
927 return PTR_ERR(cell);
928 return 0;
929 }
930
931 buf = (u32 *)nvmem_cell_read(cell, &len);
932 if (IS_ERR(buf))
933 return PTR_ERR(buf);
934 nvmem_cell_put(cell);
935
936 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
937 efs_valid = false;
938
939 if (len < 4 * sizeof(u32)) {
940 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
941 ret = -EINVAL;
942 goto out;
943 }
944
945 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
946 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
947 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
948 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
949 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800950 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800951
952out:
953 kfree(buf);
954 return ret;
955}
956
developerf35532c2022-08-05 18:37:26 +0800957static int mt7981_phy_config_init(struct phy_device *phydev)
958{
959 mt7981_phy_finetune(phydev);
960
961 return mt798x_phy_calibration(phydev);
962}
963
964static int mt7988_phy_config_init(struct phy_device *phydev)
965{
966 mt7988_phy_finetune(phydev);
967
968 return mt798x_phy_calibration(phydev);
969}
970
971static int mt7988_phy_probe(struct phy_device *phydev)
972{
973 return mt7988_phy_config_init(phydev);
974}
975
developerc50c2352021-12-01 10:45:35 +0800976static struct phy_driver mtk_gephy_driver[] = {
977#if 0
978 {
979 PHY_ID_MATCH_EXACT(0x03a29412),
980 .name = "MediaTek MT7530 PHY",
981 .config_init = mt7530_phy_config_init,
982 /* Interrupts are handled by the switch, not the PHY
983 * itself.
984 */
985 .config_intr = genphy_no_config_intr,
986 .handle_interrupt = genphy_no_ack_interrupt,
987 .suspend = genphy_suspend,
988 .resume = genphy_resume,
989 .read_page = mtk_gephy_read_page,
990 .write_page = mtk_gephy_write_page,
991 },
992 {
993 PHY_ID_MATCH_EXACT(0x03a29441),
994 .name = "MediaTek MT7531 PHY",
995 .config_init = mt7531_phy_config_init,
996 /* Interrupts are handled by the switch, not the PHY
997 * itself.
998 */
999 .config_intr = genphy_no_config_intr,
1000 .handle_interrupt = genphy_no_ack_interrupt,
1001 .suspend = genphy_suspend,
1002 .resume = genphy_resume,
1003 .read_page = mtk_gephy_read_page,
1004 .write_page = mtk_gephy_write_page,
1005 },
1006#endif
1007 {
1008 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001009 .name = "MediaTek MT7981 PHY",
1010 .config_init = mt7981_phy_config_init,
1011 /* Interrupts are handled by the switch, not the PHY
1012 * itself.
1013 */
1014 .config_intr = genphy_no_config_intr,
1015 .handle_interrupt = genphy_no_ack_interrupt,
1016 .suspend = genphy_suspend,
1017 .resume = genphy_resume,
1018 .read_page = mtk_gephy_read_page,
1019 .write_page = mtk_gephy_write_page,
1020 },
1021 {
1022 PHY_ID_MATCH_EXACT(0x03a29481),
1023 .name = "MediaTek MT7988 PHY",
1024 .probe = mt7988_phy_probe,
1025 .config_init = mt7988_phy_config_init,
developerc50c2352021-12-01 10:45:35 +08001026 /* Interrupts are handled by the switch, not the PHY
1027 * itself.
1028 */
1029 .config_intr = genphy_no_config_intr,
1030 .handle_interrupt = genphy_no_ack_interrupt,
1031 .suspend = genphy_suspend,
1032 .resume = genphy_resume,
1033 .read_page = mtk_gephy_read_page,
1034 .write_page = mtk_gephy_write_page,
1035 },
1036};
1037
1038module_phy_driver(mtk_gephy_driver);
1039
1040static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1041 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1042 { }
1043};
1044
1045MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1046MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1047MODULE_LICENSE("GPL");
1048
1049MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);