blob: d8f9d6aaac79fd918b8c1f20abdc3bf54df7524b [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 */
developer02d84422021-12-24 11:48:07 +080024#define MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1 (0x1)
25#define MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1 (0x2)
26#define MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0 (0x4)
27#define MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0 (0x5)
28#define MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1 (0x7) /* N means negative */
29#define MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1 (0x8)
30#define MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0 (0xa)
31#define MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0 (0xb)
32
developerc50c2352021-12-01 10:45:35 +080033#define MTK_PHY_TXVLD_DA_RG (0x12)
34#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
35#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
36
37#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
38#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
39#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
40
41#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
42#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
43#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
44
45#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
46#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
47#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
48
49#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
50#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
51#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
52
53#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
54#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
55#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
56
57#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
58#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
59#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
60
61#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
62#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
63#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
64
65
66#define MTK_PHY_RESERVE_RG_0 (0x27)
67#define MTK_PHY_RESERVE_RG_1 (0x28)
68
69#define MTK_PHY_RG_ANA_TEST_POWERUP_TX (0x3b)
70#define MTK_PHY_TANA_CAL_MODE (0xc1)
71#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
72
73#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
74#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
75#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
76#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
77#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
78
79#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
80#define MTK_PHY_RG_CAL_CKINV BIT(12)
81#define MTK_PHY_RG_ANA_CALEN BIT(8)
82#define MTK_PHY_RG_REXT_CALEN BIT(4)
83#define MTK_PHY_RG_ZCALEN_A BIT(0)
84
85#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
86#define MTK_PHY_RG_ZCALEN_B BIT(12)
87#define MTK_PHY_RG_ZCALEN_C BIT(8)
88#define MTK_PHY_RG_ZCALEN_D BIT(4)
89#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
90
91#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
92#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
93#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
94#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
95#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
96
97#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
98#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
99#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
100
101#define MTK_PHY_RG_DEV1E_REG172 (0x172)
102#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
103#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
104
105#define MTK_PHY_RG_DEV1E_REG173 (0x173)
106#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
107#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
108
109#define MTK_PHY_RG_DEV1E_REG174 (0x174)
110#define MTK_PHY_RSEL_TX_A_MASK GENMASK(14, 8)
111#define MTK_PHY_RSEL_TX_B_MASK GENMASK(6, 0)
112
113#define MTK_PHY_RG_DEV1E_REG175 (0x175)
114#define MTK_PHY_RSEL_TX_C_MASK GENMASK(14, 8)
115#define MTK_PHY_RSEL_TX_D_MASK GENMASK(6, 0)
116
117#define MTK_PHY_RG_DEV1E_REG17A (0x17a)
118#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
119
120#define MTK_PHY_RG_DEV1E_REG17B (0x17b)
121#define MTK_PHY_DA_CAL_CLK BIT(0)
122
123#define MTK_PHY_RG_DEV1E_REG17C (0x17c)
124#define MTK_PHY_DA_CALIN_FLAG BIT(0)
125
126#define MTK_PHY_RG_DEV1E_REG17D (0x17d)
127#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
128
129#define MTK_PHY_RG_DEV1E_REG17E (0x17e)
130#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
131
132#define MTK_PHY_RG_DEV1E_REG17F (0x17f)
133#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
134
135#define MTK_PHY_RG_DEV1E_REG180 (0x180)
136#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
137
138#define MTK_PHY_RG_DEV1E_REG181 (0x181)
139#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
140
141#define MTK_PHY_RG_DEV1E_REG182 (0x182)
142#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
143
144#define MTK_PHY_RG_DEV1E_REG183 (0x183)
145#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
146
147#define MTK_PHY_RG_DEV1E_REG184 (0x180)
148#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
149
150#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
151#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
152#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
153
154#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
155#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
156#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
157
158#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
159#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
160#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
161
162#define MTK_PHY_RG_DEV1E_REG540 (0x540)
163#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
164#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
165
166
167/* Registers on MDIO_MMD_VEND2 */
168#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
169#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
170
171#define MTK_PHY_RG_DEV1F_REG110 (0x110)
172#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
173#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
174
175#define MTK_PHY_RG_DEV1F_REG115 (0x115)
176#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
177
178/*
179 * These macro privides efuse parsing for internal phy.
180 */
181#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
182#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
183#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
184#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
185#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
186
187#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
188#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
189#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
190#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
191#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
192
193#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
194#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
195#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
196#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
197
198#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
199#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
200
201typedef enum {
202 PAIR_A,
203 PAIR_B,
204 PAIR_C,
205 PAIR_D,
206} phy_cal_pair_t;
207
208const u8 mt798x_zcal_to_r50[64] = {
209 7, 8, 9, 9, 10, 10, 11, 11,
210 12, 13, 13, 14, 14, 15, 16, 16,
211 17, 18, 18, 19, 20, 21, 21, 22,
212 23, 24, 24, 25, 26, 27, 28, 29,
213 30, 31, 32, 33, 34, 35, 36, 37,
214 38, 40, 41, 42, 43, 45, 46, 48,
215 49, 51, 52, 54, 55, 57, 59, 61,
216 62, 63, 63, 63, 63, 63, 63, 63
217};
218
219const char pair[4] = {'A', 'B', 'C', 'D'};
220
221#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
222 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
223
224#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
225 for(i=PAIR_A; i<=PAIR_A; i++) { \
226 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
227 if(cal_ret) break; \
228 }
229
230#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
231 for(i=PAIR_A; i<=PAIR_D; i++) { \
232 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
233 if(cal_ret) break; \
234 }
235
developerc6e131e2021-12-08 12:36:24 +0800236#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
237 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
238 CAL_##pair_mode(cal_item, sw) \
239 }
developerc50c2352021-12-01 10:45:35 +0800240
241#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800242 if ((efs_valid && ret) || \
243 (!ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800244 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800245 } else if ((!efs_valid && ret) || \
246 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800247 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800248 }
249
250#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
251 if ((efs_valid && ret) || \
developerc6e131e2021-12-08 12:36:24 +0800252 (!ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800253 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800254 }
255
256#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
257 ret = of_property_read_string(phydev->mdio.dev.of_node, \
258 #cal_item, &cal_mode_get); \
259 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800260 else { \
261 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
262 " use default value," \
263 " efs-valid: %s", \
264 #cal_item, \
265 ret? "" : cal_mode_get, \
266 ret? "not specified" : " not supported", \
267 efs_valid? "yes" : "no"); \
268 } \
developerc50c2352021-12-01 10:45:35 +0800269 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800270 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800271 ret = -EIO; \
272 goto out; \
273 }
274
275static int mtk_gephy_read_page(struct phy_device *phydev)
276{
277 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
278}
279
280static int mtk_gephy_write_page(struct phy_device *phydev, int page)
281{
282 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
283}
284
285/*
286 * One calibration cycle consists of:
287 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
288 * until AD_CAL_COMP is ready to output calibration result.
289 * 2.Wait until DA_CAL_CLK is available.
290 * 3.Fetch AD_CAL_COMP_OUT.
291 */
292static int cal_cycle(struct phy_device *phydev, int devad,
293 u32 regnum, u16 mask, u16 cal_val)
294{
295 unsigned long timeout;
296 int reg_val;
297 int ret;
298
299 phy_modify_mmd(phydev, devad, regnum,
300 mask, cal_val);
301 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
302 MTK_PHY_DA_CALIN_FLAG);
303
304 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
305 do{
306 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
307 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
308
309 if(!(reg_val & BIT(0))) {
310 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
311 return -ETIMEDOUT;
312 }
313
314 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
315 MTK_PHY_DA_CALIN_FLAG);
316 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
317 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
318 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
319
320 return ret;
321}
322
323static int rext_fill_result(struct phy_device *phydev, u16 *buf)
324{
325 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
326 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
327 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
328 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
329
330 return 0;
331}
332
333static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
334{
335 u16 rext_cal_val[2];
336
337 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
338 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
339 rext_fill_result(phydev, rext_cal_val);
340
341 return 0;
342}
343
344static int rext_cal_sw(struct phy_device *phydev)
345{
346 u8 rg_zcal_ctrl_def;
347 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
348 u8 lower_ret, upper_ret;
349 u16 rext_cal_val[2];
350 int ret;
351
352 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
353 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
354 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
355 MTK_PHY_RG_TXVOS_CALEN);
356 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
357 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
358 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
359 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
360
361 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
362 MTK_PHY_RG_ZCAL_CTRL_MASK;
363 zcal_lower = ZCAL_CTRL_MIN;
364 zcal_upper = ZCAL_CTRL_MAX;
365
366 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
367 while((zcal_upper-zcal_lower) > 1) {
368 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
369 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
370 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800371 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800372 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800373 upper_ret = ret;
374 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800375 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800376 lower_ret = ret;
377 } else
developerc50c2352021-12-01 10:45:35 +0800378 goto restore;
379 }
380
developer78aa7b92021-12-29 15:22:10 +0800381 if(zcal_lower == ZCAL_CTRL_MIN) {
382 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
383 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
384 } else if(zcal_upper == ZCAL_CTRL_MAX) {
385 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
386 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
387 }
388 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800389 goto restore;
390
391 ret = upper_ret-lower_ret;
392 if (ret == 1) {
393 rext_cal_val[0] = zcal_upper;
394 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800395 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800396 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
397 ret = 0;
398 } else
399 ret = -EINVAL;
400
401restore:
402 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
403 MTK_PHY_ANA_TEST_MODE_MASK);
404 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
405 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
406 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
407 MTK_PHY_RG_TST_DMY2_MASK);
408 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
409 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
410
411 return ret;
412}
413
414static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
415{
416 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
417 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
418 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
419 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
420 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
421 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
422 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
423 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
424
425 return 0;
426}
427
428static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
429{
430 u16 tx_offset_cal_val[4];
431
432 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
433 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
434 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
435 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
436
437 tx_offset_fill_result(phydev, tx_offset_cal_val);
438
439 return 0;
440}
441
442static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
443{
developer02d84422021-12-24 11:48:07 +0800444 /* We add some calibration to efuse values:
445 * GBE: +7, TBT: +1, HBT: +4, TST: +7
446 */
developerc50c2352021-12-01 10:45:35 +0800447 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800448 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + 7) << 10);
developerc50c2352021-12-01 10:45:35 +0800449 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer02d84422021-12-24 11:48:07 +0800450 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + 1);
developerc50c2352021-12-01 10:45:35 +0800451 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800452 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + 4) << 10);
developerc50c2352021-12-01 10:45:35 +0800453 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer02d84422021-12-24 11:48:07 +0800454 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + 7);
developerc50c2352021-12-01 10:45:35 +0800455
456 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800457 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800458 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer02d84422021-12-24 11:48:07 +0800459 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + 1);
developerc50c2352021-12-01 10:45:35 +0800460 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800461 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + 4 ) << 8);
developerc50c2352021-12-01 10:45:35 +0800462 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer02d84422021-12-24 11:48:07 +0800463 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + 7);
developerc50c2352021-12-01 10:45:35 +0800464
465 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800466 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800467 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer02d84422021-12-24 11:48:07 +0800468 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + 1);
developerc50c2352021-12-01 10:45:35 +0800469 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800470 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800471 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer02d84422021-12-24 11:48:07 +0800472 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + 7);
developerc50c2352021-12-01 10:45:35 +0800473
474 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800475 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + 7) << 8);
developerc50c2352021-12-01 10:45:35 +0800476 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer02d84422021-12-24 11:48:07 +0800477 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + 1);
developerc50c2352021-12-01 10:45:35 +0800478 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800479 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + 4) << 8);
developerc50c2352021-12-01 10:45:35 +0800480 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer02d84422021-12-24 11:48:07 +0800481 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + 7);
developerc50c2352021-12-01 10:45:35 +0800482
483 return 0;
484}
485
486static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
487{
488 u16 tx_amp_cal_val[4];
489
490 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
491 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
492 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
493 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
494 tx_amp_fill_result(phydev, tx_amp_cal_val);
495
496 return 0;
497}
498
499static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
500 phy_cal_pair_t txg_calen_x)
501{
502 switch(txg_calen_x) {
503 case PAIR_A:
504 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
505 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, buf[0] << 8);
506 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
507 MTK_PHY_DA_TX_R50_A_TBT_MASK, buf[0]);
508 break;
509 case PAIR_B:
510 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
511 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, buf[0] << 8);
512 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
513 MTK_PHY_DA_TX_R50_B_TBT_MASK, buf[0]);
514 break;
515 case PAIR_C:
516 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
517 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, buf[0] << 8);
518 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
519 MTK_PHY_DA_TX_R50_C_TBT_MASK, buf[0]);
520 break;
521 case PAIR_D:
522 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
523 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, buf[0] << 8);
524 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
525 MTK_PHY_DA_TX_R50_D_TBT_MASK, buf[0]);
526 break;
527 }
528 return 0;
529}
530
531static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
532 phy_cal_pair_t txg_calen_x)
533{
534 u16 tx_r50_cal_val[1];
535
536 switch(txg_calen_x) {
537 case PAIR_A:
538 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
539 break;
540 case PAIR_B:
541 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
542 break;
543 case PAIR_C:
544 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
545 break;
546 case PAIR_D:
547 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
548 break;
549 }
550 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
551
552 return 0;
553}
554
555static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
556{
557 u8 rg_zcal_ctrl_def;
558 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
559 u8 lower_ret, upper_ret;
560 u16 tx_r50_cal_val[1];
561 int ret;
562
563 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
564 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
565 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
566 MTK_PHY_RG_TXVOS_CALEN);
567 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
568 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
569 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
570 BIT(txg_calen_x * 4));
571 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
572 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
573
574 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
575 MTK_PHY_RG_ZCAL_CTRL_MASK;
576 zcal_lower = ZCAL_CTRL_MIN;
577 zcal_upper = ZCAL_CTRL_MAX;
578
developer02d84422021-12-24 11:48:07 +0800579 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800580 while((zcal_upper-zcal_lower) > 1) {
581 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
582 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
583 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800584 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800585 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800586 upper_ret = ret;
587 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800588 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800589 lower_ret = ret;
590 } else
developerc50c2352021-12-01 10:45:35 +0800591 goto restore;
592 }
593
developer78aa7b92021-12-29 15:22:10 +0800594 if(zcal_lower == ZCAL_CTRL_MIN) {
595 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800596 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800597 } else if(zcal_upper == ZCAL_CTRL_MAX) {
598 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800599 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800600 }
601 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800602 goto restore;
603
604 ret = upper_ret-lower_ret;
605 if (ret == 1) {
606 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
607 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800608 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800609 pair[txg_calen_x], zcal_lower);
610 ret = 0;
611 } else
612 ret = -EINVAL;
613
614restore:
615 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
616 MTK_PHY_ANA_TEST_MODE_MASK);
617 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
618 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
619 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
620 BIT(txg_calen_x * 4));
621 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
622 MTK_PHY_RG_TST_DMY2_MASK);
623 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
624 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
625
626 return ret;
627}
628
629static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
630{
631 u8 lower_idx, upper_idx, txreserve_val;
632 u8 lower_ret, upper_ret;
633 int ret;
634
635 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
636 MTK_PHY_RG_ANA_CALEN);
637 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
638 MTK_PHY_RG_CAL_CKINV);
639 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
640 MTK_PHY_RG_TXVOS_CALEN);
641
642 switch(rg_txreserve_x) {
643 case PAIR_A:
644 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
645 MTK_PHY_DASN_DAC_IN0_A_MASK);
646 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
647 MTK_PHY_DASN_DAC_IN1_A_MASK);
648 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
649 MTK_PHY_RG_ZCALEN_A);
650 break;
651 case PAIR_B:
652 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
653 MTK_PHY_DASN_DAC_IN0_B_MASK);
654 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
655 MTK_PHY_DASN_DAC_IN1_B_MASK);
656 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
657 MTK_PHY_RG_ZCALEN_B);
658 break;
659 case PAIR_C:
660 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
661 MTK_PHY_DASN_DAC_IN0_C_MASK);
662 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
663 MTK_PHY_DASN_DAC_IN1_C_MASK);
664 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
665 MTK_PHY_RG_ZCALEN_C);
666 break;
667 case PAIR_D:
668 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
669 MTK_PHY_DASN_DAC_IN0_D_MASK);
670 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
671 MTK_PHY_DASN_DAC_IN1_D_MASK);
672 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
673 MTK_PHY_RG_ZCALEN_D);
674 break;
675 default:
676 ret = -EINVAL;
677 goto restore;
678 }
679
680 lower_idx = TXRESERVE_MIN;
681 upper_idx = TXRESERVE_MAX;
682
683 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
684 while((upper_idx-lower_idx) > 1) {
685 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
686 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
687 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
688 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
689 txreserve_val << 12 | txreserve_val << 8 |
690 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800691 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800692 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800693 upper_ret = ret;
694 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800695 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800696 lower_ret = ret;
697 } else
developerc50c2352021-12-01 10:45:35 +0800698 goto restore;
699 }
700
developer78aa7b92021-12-29 15:22:10 +0800701 if(lower_idx == TXRESERVE_MIN) {
702 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800703 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
704 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
705 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800706 } else if(upper_idx == TXRESERVE_MAX) {
707 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800708 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
709 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
710 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800711 }
712 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800713 goto restore;
714
developer78aa7b92021-12-29 15:22:10 +0800715 /* We calibrate TX-VCM in different logic. Check upper index and then
716 * lower index. If this calibration is valid, apply lower index's result.
717 */
developerc50c2352021-12-01 10:45:35 +0800718 ret = upper_ret-lower_ret;
719 if (ret == 1) {
720 ret = 0;
721 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
722 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
723 ret = 0;
724 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
725 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
726 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
727 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
728 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
729 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
730 ret = 0;
731 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
732 } else
733 ret = -EINVAL;
734
735restore:
736 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
737 MTK_PHY_RG_ANA_CALEN);
738 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
739 MTK_PHY_RG_TXVOS_CALEN);
740 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
741 MTK_PHY_RG_ZCALEN_A);
742 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
743 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
744
745 return ret;
746}
747
748static void mtk_gephy_config_init(struct phy_device *phydev)
749{
750 /* Disable EEE */
751 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
752
753 /* Enable HW auto downshift */
754 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
755
756 /* Increase SlvDPSready time */
757 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
758 __phy_write(phydev, 0x10, 0xafae);
759 __phy_write(phydev, 0x12, 0x2f);
760 __phy_write(phydev, 0x10, 0x8fae);
761 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
762
763 /* Adjust 100_mse_threshold */
764 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
765
766 /* Disable mcc */
767 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
768}
769
770static int mt7530_phy_config_init(struct phy_device *phydev)
771{
772 mtk_gephy_config_init(phydev);
773
774 /* Increase post_update_timer */
775 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
776
777 return 0;
778}
779
780static int mt7531_phy_config_init(struct phy_device *phydev)
781{
782 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
783 return -EINVAL;
784
785 mtk_gephy_config_init(phydev);
786
787 /* PHY link down power saving enable */
788 phy_set_bits(phydev, 0x17, BIT(4));
789 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
790
791 /* Set TX Pair delay selection */
792 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
793 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
794
795 return 0;
796}
797
developer02d84422021-12-24 11:48:07 +0800798static inline void mt798x_phy_finetune(struct phy_device *phydev)
799{
800 /* 100M eye finetune:
801 * Keep middle level of TX MLT3 shapper as default.
802 * Only change TX MLT3 overshoot level here.
803 */
804 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
805 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
806 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
807 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
808 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
809 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
810 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
811 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
812#
813 /* TX-AMP finetune:
814 * 100M +4, 1000M +6 to default value.
815 * If efuse values aren't valid, TX-AMP uses the below values.
816 */
817 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
818 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
819 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
820 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
821 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
822 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
823 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
824 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
825}
826
developerc50c2352021-12-01 10:45:35 +0800827static int mt798x_phy_config_init(struct phy_device *phydev)
828{
829 const char *cal_mode_from_dts;
830 int i, ret, cal_ret;
831 u32 *buf;
832 bool efs_valid = true;
833 size_t len;
834 struct nvmem_cell *cell;
835
836 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
837 return -EINVAL;
838
developer02d84422021-12-24 11:48:07 +0800839 mt798x_phy_finetune(phydev);
840
developerc50c2352021-12-01 10:45:35 +0800841 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
842 if (IS_ERR(cell)) {
843 if (PTR_ERR(cell) == -EPROBE_DEFER)
844 return PTR_ERR(cell);
845 return 0;
846 }
847
848 buf = (u32 *)nvmem_cell_read(cell, &len);
849 if (IS_ERR(buf))
850 return PTR_ERR(buf);
851 nvmem_cell_put(cell);
852
853 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
854 efs_valid = false;
855
856 if (len < 4 * sizeof(u32)) {
857 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
858 ret = -EINVAL;
859 goto out;
860 }
861
862 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
863 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
864 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
865 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
866 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800867 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800868
869out:
870 kfree(buf);
871 return ret;
872}
873
874static struct phy_driver mtk_gephy_driver[] = {
875#if 0
876 {
877 PHY_ID_MATCH_EXACT(0x03a29412),
878 .name = "MediaTek MT7530 PHY",
879 .config_init = mt7530_phy_config_init,
880 /* Interrupts are handled by the switch, not the PHY
881 * itself.
882 */
883 .config_intr = genphy_no_config_intr,
884 .handle_interrupt = genphy_no_ack_interrupt,
885 .suspend = genphy_suspend,
886 .resume = genphy_resume,
887 .read_page = mtk_gephy_read_page,
888 .write_page = mtk_gephy_write_page,
889 },
890 {
891 PHY_ID_MATCH_EXACT(0x03a29441),
892 .name = "MediaTek MT7531 PHY",
893 .config_init = mt7531_phy_config_init,
894 /* Interrupts are handled by the switch, not the PHY
895 * itself.
896 */
897 .config_intr = genphy_no_config_intr,
898 .handle_interrupt = genphy_no_ack_interrupt,
899 .suspend = genphy_suspend,
900 .resume = genphy_resume,
901 .read_page = mtk_gephy_read_page,
902 .write_page = mtk_gephy_write_page,
903 },
904#endif
905 {
906 PHY_ID_MATCH_EXACT(0x03a29461),
907 .name = "MediaTek MT798x PHY",
908 .config_init = mt798x_phy_config_init,
909 /* Interrupts are handled by the switch, not the PHY
910 * itself.
911 */
912 .config_intr = genphy_no_config_intr,
913 .handle_interrupt = genphy_no_ack_interrupt,
914 .suspend = genphy_suspend,
915 .resume = genphy_resume,
916 .read_page = mtk_gephy_read_page,
917 .write_page = mtk_gephy_write_page,
918 },
919};
920
921module_phy_driver(mtk_gephy_driver);
922
923static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
924 { PHY_ID_MATCH_VENDOR(0x03a29400) },
925 { }
926};
927
928MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
929MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
930MODULE_LICENSE("GPL");
931
932MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);