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