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