blob: 146f15ff4f327880da8aeaa1db4607b0cfdd21b0 [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) || \
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{
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;
developerb5c76d42022-08-18 15:45:33 +0800728 /* Make sure we use upper_idx in our calibration system */
729 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 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800733 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
734 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
735 ret = 0;
736 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
737 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
738 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
739 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
740 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
741 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
742 ret = 0;
743 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
744 } else
745 ret = -EINVAL;
746
747restore:
748 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
749 MTK_PHY_RG_ANA_CALEN);
750 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
751 MTK_PHY_RG_TXVOS_CALEN);
752 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
753 MTK_PHY_RG_ZCALEN_A);
754 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
755 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
756
757 return ret;
758}
759
760static void mtk_gephy_config_init(struct phy_device *phydev)
761{
762 /* Disable EEE */
763 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
764
765 /* Enable HW auto downshift */
766 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
767
768 /* Increase SlvDPSready time */
769 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
770 __phy_write(phydev, 0x10, 0xafae);
771 __phy_write(phydev, 0x12, 0x2f);
772 __phy_write(phydev, 0x10, 0x8fae);
773 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
774
775 /* Adjust 100_mse_threshold */
776 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
777
778 /* Disable mcc */
779 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
780}
781
782static int mt7530_phy_config_init(struct phy_device *phydev)
783{
784 mtk_gephy_config_init(phydev);
785
786 /* Increase post_update_timer */
787 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
788
789 return 0;
790}
791
792static int mt7531_phy_config_init(struct phy_device *phydev)
793{
794 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
795 return -EINVAL;
796
797 mtk_gephy_config_init(phydev);
798
799 /* PHY link down power saving enable */
800 phy_set_bits(phydev, 0x17, BIT(4));
801 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
802
803 /* Set TX Pair delay selection */
804 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
805 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
806
807 return 0;
808}
809
developerf35532c2022-08-05 18:37:26 +0800810static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800811{
812 /* 100M eye finetune:
813 * Keep middle level of TX MLT3 shapper as default.
814 * Only change TX MLT3 overshoot level here.
815 */
816 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
817 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
818 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
819 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
820 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
821 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
822 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
823 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800824
developer02d84422021-12-24 11:48:07 +0800825 /* TX-AMP finetune:
826 * 100M +4, 1000M +6 to default value.
827 * If efuse values aren't valid, TX-AMP uses the below values.
828 */
829 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
830 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
831 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
832 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
833 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
834 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
835 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
836 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
837}
838
developerf35532c2022-08-05 18:37:26 +0800839static inline void mt7988_phy_finetune(struct phy_device *phydev)
840{
841 int i;
842 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
843 0x020d, 0x0206, 0x0384, 0x03d0,
844 0x03c6, 0x030a, 0x0011, 0x0005};
845
846 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
847 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
848 }
849}
850
851static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800852{
853 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800854 int i, ret;
855 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800856 u32 *buf;
857 bool efs_valid = true;
858 size_t len;
859 struct nvmem_cell *cell;
860
861 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
862 return -EINVAL;
863
864 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
865 if (IS_ERR(cell)) {
866 if (PTR_ERR(cell) == -EPROBE_DEFER)
867 return PTR_ERR(cell);
868 return 0;
869 }
870
871 buf = (u32 *)nvmem_cell_read(cell, &len);
872 if (IS_ERR(buf))
873 return PTR_ERR(buf);
874 nvmem_cell_put(cell);
875
876 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
877 efs_valid = false;
878
879 if (len < 4 * sizeof(u32)) {
880 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
881 ret = -EINVAL;
882 goto out;
883 }
884
885 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
886 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
887 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
888 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
889 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800890 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800891
892out:
893 kfree(buf);
894 return ret;
895}
896
developerf35532c2022-08-05 18:37:26 +0800897static int mt7981_phy_config_init(struct phy_device *phydev)
898{
899 mt7981_phy_finetune(phydev);
900
901 return mt798x_phy_calibration(phydev);
902}
903
904static int mt7988_phy_config_init(struct phy_device *phydev)
905{
906 mt7988_phy_finetune(phydev);
907
908 return mt798x_phy_calibration(phydev);
909}
910
911static int mt7988_phy_probe(struct phy_device *phydev)
912{
913 return mt7988_phy_config_init(phydev);
914}
915
developerc50c2352021-12-01 10:45:35 +0800916static struct phy_driver mtk_gephy_driver[] = {
917#if 0
918 {
919 PHY_ID_MATCH_EXACT(0x03a29412),
920 .name = "MediaTek MT7530 PHY",
921 .config_init = mt7530_phy_config_init,
922 /* Interrupts are handled by the switch, not the PHY
923 * itself.
924 */
925 .config_intr = genphy_no_config_intr,
926 .handle_interrupt = genphy_no_ack_interrupt,
927 .suspend = genphy_suspend,
928 .resume = genphy_resume,
929 .read_page = mtk_gephy_read_page,
930 .write_page = mtk_gephy_write_page,
931 },
932 {
933 PHY_ID_MATCH_EXACT(0x03a29441),
934 .name = "MediaTek MT7531 PHY",
935 .config_init = mt7531_phy_config_init,
936 /* Interrupts are handled by the switch, not the PHY
937 * itself.
938 */
939 .config_intr = genphy_no_config_intr,
940 .handle_interrupt = genphy_no_ack_interrupt,
941 .suspend = genphy_suspend,
942 .resume = genphy_resume,
943 .read_page = mtk_gephy_read_page,
944 .write_page = mtk_gephy_write_page,
945 },
946#endif
947 {
948 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +0800949 .name = "MediaTek MT7981 PHY",
950 .config_init = mt7981_phy_config_init,
951 /* Interrupts are handled by the switch, not the PHY
952 * itself.
953 */
954 .config_intr = genphy_no_config_intr,
955 .handle_interrupt = genphy_no_ack_interrupt,
956 .suspend = genphy_suspend,
957 .resume = genphy_resume,
958 .read_page = mtk_gephy_read_page,
959 .write_page = mtk_gephy_write_page,
960 },
961 {
962 PHY_ID_MATCH_EXACT(0x03a29481),
963 .name = "MediaTek MT7988 PHY",
964 .probe = mt7988_phy_probe,
965 .config_init = mt7988_phy_config_init,
developerc50c2352021-12-01 10:45:35 +0800966 /* Interrupts are handled by the switch, not the PHY
967 * itself.
968 */
969 .config_intr = genphy_no_config_intr,
970 .handle_interrupt = genphy_no_ack_interrupt,
971 .suspend = genphy_suspend,
972 .resume = genphy_resume,
973 .read_page = mtk_gephy_read_page,
974 .write_page = mtk_gephy_write_page,
975 },
976};
977
978module_phy_driver(mtk_gephy_driver);
979
980static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
981 { PHY_ID_MATCH_VENDOR(0x03a29400) },
982 { }
983};
984
985MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
986MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
987MODULE_LICENSE("GPL");
988
989MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);