blob: f149444ad8f1d27f38926c01eb1aa497314a5214 [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 */
developerf35532c2022-08-05 18:37:26 +080024typedef enum {
25 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) || \
250 (!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) || \
developerc6e131e2021-12-08 12:36:24 +0800259 (!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{
developer02d84422021-12-24 11:48:07 +0800451 /* We add some calibration to efuse values:
452 * GBE: +7, TBT: +1, HBT: +4, TST: +7
453 */
developerc50c2352021-12-01 10:45:35 +0800454 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800455 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + 7) << 10);
developerc50c2352021-12-01 10:45:35 +0800456 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800457 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + 1);
developerc50c2352021-12-01 10:45:35 +0800458 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800459 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + 4) << 10);
developerc50c2352021-12-01 10:45:35 +0800460 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800461 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + 7);
developerc50c2352021-12-01 10:45:35 +0800462
463 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800464 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800465 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800466 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + 1);
developerc50c2352021-12-01 10:45:35 +0800467 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800468 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + 4 ) << 8);
developerc50c2352021-12-01 10:45:35 +0800469 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800470 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + 7);
developerc50c2352021-12-01 10:45:35 +0800471
472 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800473 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800474 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800475 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + 1);
developerc50c2352021-12-01 10:45:35 +0800476 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800477 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800478 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800479 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + 7);
developerc50c2352021-12-01 10:45:35 +0800480
481 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800482 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800483 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800484 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + 1);
developerc50c2352021-12-01 10:45:35 +0800485 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800486 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800487 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800488 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + 7);
developerc50c2352021-12-01 10:45:35 +0800489
490 return 0;
491}
492
493static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
494{
495 u16 tx_amp_cal_val[4];
496
497 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
498 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
499 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
500 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
501 tx_amp_fill_result(phydev, tx_amp_cal_val);
502
503 return 0;
504}
505
506static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
507 phy_cal_pair_t txg_calen_x)
508{
509 switch(txg_calen_x) {
510 case PAIR_A:
511 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
512 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, buf[0] << 8);
513 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
514 MTK_PHY_DA_TX_R50_A_TBT_MASK, buf[0]);
515 break;
516 case PAIR_B:
517 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
518 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, buf[0] << 8);
519 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
520 MTK_PHY_DA_TX_R50_B_TBT_MASK, buf[0]);
521 break;
522 case PAIR_C:
523 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
524 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, buf[0] << 8);
525 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
526 MTK_PHY_DA_TX_R50_C_TBT_MASK, buf[0]);
527 break;
528 case PAIR_D:
529 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
530 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, buf[0] << 8);
531 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
532 MTK_PHY_DA_TX_R50_D_TBT_MASK, buf[0]);
533 break;
534 }
535 return 0;
536}
537
538static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
539 phy_cal_pair_t txg_calen_x)
540{
541 u16 tx_r50_cal_val[1];
542
543 switch(txg_calen_x) {
544 case PAIR_A:
545 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
546 break;
547 case PAIR_B:
548 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
549 break;
550 case PAIR_C:
551 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
552 break;
553 case PAIR_D:
554 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
555 break;
556 }
557 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
558
559 return 0;
560}
561
562static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
563{
564 u8 rg_zcal_ctrl_def;
565 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
566 u8 lower_ret, upper_ret;
567 u16 tx_r50_cal_val[1];
568 int ret;
569
570 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
571 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
572 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
573 MTK_PHY_RG_TXVOS_CALEN);
574 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
575 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
576 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
577 BIT(txg_calen_x * 4));
578 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
579 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
580
581 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
582 MTK_PHY_RG_ZCAL_CTRL_MASK;
583 zcal_lower = ZCAL_CTRL_MIN;
584 zcal_upper = ZCAL_CTRL_MAX;
585
developer02d84422021-12-24 11:48:07 +0800586 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800587 while((zcal_upper-zcal_lower) > 1) {
588 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
589 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
590 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800591 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800592 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800593 upper_ret = ret;
594 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800595 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800596 lower_ret = ret;
597 } else
developerc50c2352021-12-01 10:45:35 +0800598 goto restore;
599 }
600
developer78aa7b92021-12-29 15:22:10 +0800601 if(zcal_lower == ZCAL_CTRL_MIN) {
602 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800603 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800604 } else if(zcal_upper == ZCAL_CTRL_MAX) {
605 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800606 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800607 }
608 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800609 goto restore;
610
611 ret = upper_ret-lower_ret;
612 if (ret == 1) {
613 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
614 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800615 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800616 pair[txg_calen_x], zcal_lower);
617 ret = 0;
618 } else
619 ret = -EINVAL;
620
621restore:
622 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
623 MTK_PHY_ANA_TEST_MODE_MASK);
624 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
625 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
626 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
627 BIT(txg_calen_x * 4));
628 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
629 MTK_PHY_RG_TST_DMY2_MASK);
630 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
631 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
632
633 return ret;
634}
635
636static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
637{
638 u8 lower_idx, upper_idx, txreserve_val;
639 u8 lower_ret, upper_ret;
640 int ret;
641
642 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
643 MTK_PHY_RG_ANA_CALEN);
644 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
645 MTK_PHY_RG_CAL_CKINV);
646 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
647 MTK_PHY_RG_TXVOS_CALEN);
648
649 switch(rg_txreserve_x) {
650 case PAIR_A:
651 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
652 MTK_PHY_DASN_DAC_IN0_A_MASK);
653 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
654 MTK_PHY_DASN_DAC_IN1_A_MASK);
655 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
656 MTK_PHY_RG_ZCALEN_A);
657 break;
658 case PAIR_B:
659 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
660 MTK_PHY_DASN_DAC_IN0_B_MASK);
661 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
662 MTK_PHY_DASN_DAC_IN1_B_MASK);
663 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
664 MTK_PHY_RG_ZCALEN_B);
665 break;
666 case PAIR_C:
667 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
668 MTK_PHY_DASN_DAC_IN0_C_MASK);
669 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
670 MTK_PHY_DASN_DAC_IN1_C_MASK);
671 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
672 MTK_PHY_RG_ZCALEN_C);
673 break;
674 case PAIR_D:
675 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
676 MTK_PHY_DASN_DAC_IN0_D_MASK);
677 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
678 MTK_PHY_DASN_DAC_IN1_D_MASK);
679 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
680 MTK_PHY_RG_ZCALEN_D);
681 break;
682 default:
683 ret = -EINVAL;
684 goto restore;
685 }
686
687 lower_idx = TXRESERVE_MIN;
688 upper_idx = TXRESERVE_MAX;
689
690 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
691 while((upper_idx-lower_idx) > 1) {
692 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
693 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
694 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
695 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
696 txreserve_val << 12 | txreserve_val << 8 |
697 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800698 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800699 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800700 upper_ret = ret;
701 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800702 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800703 lower_ret = ret;
704 } else
developerc50c2352021-12-01 10:45:35 +0800705 goto restore;
706 }
707
developer78aa7b92021-12-29 15:22:10 +0800708 if(lower_idx == TXRESERVE_MIN) {
709 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800710 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
711 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
712 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800713 } else if(upper_idx == TXRESERVE_MAX) {
714 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800715 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
716 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
717 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800718 }
719 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800720 goto restore;
721
developer78aa7b92021-12-29 15:22:10 +0800722 /* We calibrate TX-VCM in different logic. Check upper index and then
723 * lower index. If this calibration is valid, apply lower index's result.
724 */
developerc50c2352021-12-01 10:45:35 +0800725 ret = upper_ret-lower_ret;
726 if (ret == 1) {
727 ret = 0;
728 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
729 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
730 ret = 0;
731 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
732 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
733 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
734 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
735 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
736 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
737 ret = 0;
738 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
739 } else
740 ret = -EINVAL;
741
742restore:
743 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
744 MTK_PHY_RG_ANA_CALEN);
745 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
746 MTK_PHY_RG_TXVOS_CALEN);
747 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
748 MTK_PHY_RG_ZCALEN_A);
749 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
750 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
751
752 return ret;
753}
754
755static void mtk_gephy_config_init(struct phy_device *phydev)
756{
757 /* Disable EEE */
758 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
759
760 /* Enable HW auto downshift */
761 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
762
763 /* Increase SlvDPSready time */
764 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
765 __phy_write(phydev, 0x10, 0xafae);
766 __phy_write(phydev, 0x12, 0x2f);
767 __phy_write(phydev, 0x10, 0x8fae);
768 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
769
770 /* Adjust 100_mse_threshold */
771 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
772
773 /* Disable mcc */
774 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
775}
776
777static int mt7530_phy_config_init(struct phy_device *phydev)
778{
779 mtk_gephy_config_init(phydev);
780
781 /* Increase post_update_timer */
782 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
783
784 return 0;
785}
786
787static int mt7531_phy_config_init(struct phy_device *phydev)
788{
789 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
790 return -EINVAL;
791
792 mtk_gephy_config_init(phydev);
793
794 /* PHY link down power saving enable */
795 phy_set_bits(phydev, 0x17, BIT(4));
796 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
797
798 /* Set TX Pair delay selection */
799 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
800 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
801
802 return 0;
803}
804
developerf35532c2022-08-05 18:37:26 +0800805static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800806{
807 /* 100M eye finetune:
808 * Keep middle level of TX MLT3 shapper as default.
809 * Only change TX MLT3 overshoot level here.
810 */
811 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
812 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
813 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
814 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
815 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
816 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
817 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
818 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800819
developer02d84422021-12-24 11:48:07 +0800820 /* TX-AMP finetune:
821 * 100M +4, 1000M +6 to default value.
822 * If efuse values aren't valid, TX-AMP uses the below values.
823 */
824 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
825 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
826 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
827 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
828 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
829 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
830 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
831 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
832}
833
developerf35532c2022-08-05 18:37:26 +0800834static inline void mt7988_phy_finetune(struct phy_device *phydev)
835{
836 int i;
837 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
838 0x020d, 0x0206, 0x0384, 0x03d0,
839 0x03c6, 0x030a, 0x0011, 0x0005};
840
841 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
842 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
843 }
844}
845
846static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800847{
848 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800849 int i, ret;
850 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800851 u32 *buf;
852 bool efs_valid = true;
853 size_t len;
854 struct nvmem_cell *cell;
855
856 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
857 return -EINVAL;
858
859 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
860 if (IS_ERR(cell)) {
861 if (PTR_ERR(cell) == -EPROBE_DEFER)
862 return PTR_ERR(cell);
863 return 0;
864 }
865
866 buf = (u32 *)nvmem_cell_read(cell, &len);
867 if (IS_ERR(buf))
868 return PTR_ERR(buf);
869 nvmem_cell_put(cell);
870
871 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
872 efs_valid = false;
873
874 if (len < 4 * sizeof(u32)) {
875 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
876 ret = -EINVAL;
877 goto out;
878 }
879
880 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
881 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
882 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
883 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
884 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800885 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800886
887out:
888 kfree(buf);
889 return ret;
890}
891
developerf35532c2022-08-05 18:37:26 +0800892static int mt7981_phy_config_init(struct phy_device *phydev)
893{
894 mt7981_phy_finetune(phydev);
895
896 return mt798x_phy_calibration(phydev);
897}
898
899static int mt7988_phy_config_init(struct phy_device *phydev)
900{
901 mt7988_phy_finetune(phydev);
902
903 return mt798x_phy_calibration(phydev);
904}
905
906static int mt7988_phy_probe(struct phy_device *phydev)
907{
908 return mt7988_phy_config_init(phydev);
909}
910
developerc50c2352021-12-01 10:45:35 +0800911static struct phy_driver mtk_gephy_driver[] = {
912#if 0
913 {
914 PHY_ID_MATCH_EXACT(0x03a29412),
915 .name = "MediaTek MT7530 PHY",
916 .config_init = mt7530_phy_config_init,
917 /* Interrupts are handled by the switch, not the PHY
918 * itself.
919 */
920 .config_intr = genphy_no_config_intr,
921 .handle_interrupt = genphy_no_ack_interrupt,
922 .suspend = genphy_suspend,
923 .resume = genphy_resume,
924 .read_page = mtk_gephy_read_page,
925 .write_page = mtk_gephy_write_page,
926 },
927 {
928 PHY_ID_MATCH_EXACT(0x03a29441),
929 .name = "MediaTek MT7531 PHY",
930 .config_init = mt7531_phy_config_init,
931 /* Interrupts are handled by the switch, not the PHY
932 * itself.
933 */
934 .config_intr = genphy_no_config_intr,
935 .handle_interrupt = genphy_no_ack_interrupt,
936 .suspend = genphy_suspend,
937 .resume = genphy_resume,
938 .read_page = mtk_gephy_read_page,
939 .write_page = mtk_gephy_write_page,
940 },
941#endif
942 {
943 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +0800944 .name = "MediaTek MT7981 PHY",
945 .config_init = mt7981_phy_config_init,
946 /* Interrupts are handled by the switch, not the PHY
947 * itself.
948 */
949 .config_intr = genphy_no_config_intr,
950 .handle_interrupt = genphy_no_ack_interrupt,
951 .suspend = genphy_suspend,
952 .resume = genphy_resume,
953 .read_page = mtk_gephy_read_page,
954 .write_page = mtk_gephy_write_page,
955 },
956 {
957 PHY_ID_MATCH_EXACT(0x03a29481),
958 .name = "MediaTek MT7988 PHY",
959 .probe = mt7988_phy_probe,
960 .config_init = mt7988_phy_config_init,
developerc50c2352021-12-01 10:45:35 +0800961 /* Interrupts are handled by the switch, not the PHY
962 * itself.
963 */
964 .config_intr = genphy_no_config_intr,
965 .handle_interrupt = genphy_no_ack_interrupt,
966 .suspend = genphy_suspend,
967 .resume = genphy_resume,
968 .read_page = mtk_gephy_read_page,
969 .write_page = mtk_gephy_write_page,
970 },
971};
972
973module_phy_driver(mtk_gephy_driver);
974
975static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
976 { PHY_ID_MATCH_VENDOR(0x03a29400) },
977 { }
978};
979
980MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
981MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
982MODULE_LICENSE("GPL");
983
984MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);