blob: c11d482168eacb008180785857efc16554a73a75 [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>
developer23021292022-10-21 19:10:10 +08005#include <linux/of_address.h>
developerc50c2352021-12-01 10:45:35 +08006#include <linux/of_platform.h>
7#include <linux/phy.h>
8
9#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
10#define ZCAL_CTRL_MIN (0)
11#define ZCAL_CTRL_MAX (63)
12#define TXRESERVE_MIN (0)
13#define TXRESERVE_MAX (7)
14
15
16#define MTK_EXT_PAGE_ACCESS 0x1f
17#define MTK_PHY_PAGE_STANDARD 0x0000
18#define MTK_PHY_PAGE_EXTENDED 0x0001
19#define MTK_PHY_PAGE_EXTENDED_2 0x0002
20#define MTK_PHY_PAGE_EXTENDED_3 0x0003
21#define MTK_PHY_PAGE_EXTENDED_2A30 0x2a30
22#define MTK_PHY_PAGE_EXTENDED_52B5 0x52b5
23
24/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080025enum {
developerf35532c2022-08-05 18:37:26 +080026 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
27 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
28 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
29 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
30 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
31 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
32 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
33 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
34 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
35 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
36 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
37 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
38 MTK_PHY_TX_MLT3_END,
39};
developer02d84422021-12-24 11:48:07 +080040
developerc50c2352021-12-01 10:45:35 +080041#define MTK_PHY_TXVLD_DA_RG (0x12)
42#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
43#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
44
45#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
46#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
47#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
48
49#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
50#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
51#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
52
53#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
54#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
55#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
56
57#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
58#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
59#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
60
61#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
62#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
63#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
64
65#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
66#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
67#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
68
69#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
70#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
71#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
72
73
74#define MTK_PHY_RESERVE_RG_0 (0x27)
75#define MTK_PHY_RESERVE_RG_1 (0x28)
76
77#define MTK_PHY_RG_ANA_TEST_POWERUP_TX (0x3b)
78#define MTK_PHY_TANA_CAL_MODE (0xc1)
79#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
80
developer57374032022-10-11 16:43:24 +080081#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
82#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
83
developerc50c2352021-12-01 10:45:35 +080084#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
85#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
86#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
87#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
88#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
89
90#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
91#define MTK_PHY_RG_CAL_CKINV BIT(12)
92#define MTK_PHY_RG_ANA_CALEN BIT(8)
93#define MTK_PHY_RG_REXT_CALEN BIT(4)
94#define MTK_PHY_RG_ZCALEN_A BIT(0)
95
96#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
97#define MTK_PHY_RG_ZCALEN_B BIT(12)
98#define MTK_PHY_RG_ZCALEN_C BIT(8)
99#define MTK_PHY_RG_ZCALEN_D BIT(4)
100#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
101
102#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
103#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
104#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
105#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
106#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
107
108#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
109#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
110#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
111
developer6de96aa2022-09-29 16:46:18 +0800112#define MTK_PHY_RG_TX_FILTER (0xfe)
113
developerc50c2352021-12-01 10:45:35 +0800114#define MTK_PHY_RG_DEV1E_REG172 (0x172)
115#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
116#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
117
118#define MTK_PHY_RG_DEV1E_REG173 (0x173)
119#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
120#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
121
122#define MTK_PHY_RG_DEV1E_REG174 (0x174)
123#define MTK_PHY_RSEL_TX_A_MASK GENMASK(14, 8)
124#define MTK_PHY_RSEL_TX_B_MASK GENMASK(6, 0)
125
126#define MTK_PHY_RG_DEV1E_REG175 (0x175)
127#define MTK_PHY_RSEL_TX_C_MASK GENMASK(14, 8)
128#define MTK_PHY_RSEL_TX_D_MASK GENMASK(6, 0)
129
130#define MTK_PHY_RG_DEV1E_REG17A (0x17a)
131#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
132
133#define MTK_PHY_RG_DEV1E_REG17B (0x17b)
134#define MTK_PHY_DA_CAL_CLK BIT(0)
135
136#define MTK_PHY_RG_DEV1E_REG17C (0x17c)
137#define MTK_PHY_DA_CALIN_FLAG BIT(0)
138
139#define MTK_PHY_RG_DEV1E_REG17D (0x17d)
140#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
141
142#define MTK_PHY_RG_DEV1E_REG17E (0x17e)
143#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
144
145#define MTK_PHY_RG_DEV1E_REG17F (0x17f)
146#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
147
148#define MTK_PHY_RG_DEV1E_REG180 (0x180)
149#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
150
151#define MTK_PHY_RG_DEV1E_REG181 (0x181)
152#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
153
154#define MTK_PHY_RG_DEV1E_REG182 (0x182)
155#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
156
157#define MTK_PHY_RG_DEV1E_REG183 (0x183)
158#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
159
160#define MTK_PHY_RG_DEV1E_REG184 (0x180)
161#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
162
163#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
164#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
165#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
166
167#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
168#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
169#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
170
171#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
172#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
173#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
174
175#define MTK_PHY_RG_DEV1E_REG540 (0x540)
176#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
177#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
178
179
180/* Registers on MDIO_MMD_VEND2 */
developer23021292022-10-21 19:10:10 +0800181#define MTK_PHY_LED0_ON_CTRL (0x24)
182#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
183#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
184#define MTK_PHY_LED0_ON_LINK100 BIT(1)
185#define MTK_PHY_LED0_ON_LINK10 BIT(2)
186#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
187#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
188#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
189#define MTK_PHY_LED0_FORCE_ON BIT(6)
190#define MTK_PHY_LED0_POLARITY BIT(14)
191#define MTK_PHY_LED0_ENABLE BIT(15)
192
developerc50c2352021-12-01 10:45:35 +0800193#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
194#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
195
196#define MTK_PHY_RG_DEV1F_REG110 (0x110)
197#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
198#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
199
200#define MTK_PHY_RG_DEV1F_REG115 (0x115)
201#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
202
203/*
204 * These macro privides efuse parsing for internal phy.
205 */
206#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
207#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
208#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
209#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
210#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
211
212#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
213#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
214#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
215#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
216#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
217
218#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
219#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
220#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
221#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
222
223#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
224#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
225
226typedef enum {
227 PAIR_A,
228 PAIR_B,
229 PAIR_C,
230 PAIR_D,
231} phy_cal_pair_t;
232
developer23021292022-10-21 19:10:10 +0800233enum {
234 GPHY_PORT0,
235 GPHY_PORT1,
236 GPHY_PORT2,
237 GPHY_PORT3,
238};
239
developerc50c2352021-12-01 10:45:35 +0800240const u8 mt798x_zcal_to_r50[64] = {
241 7, 8, 9, 9, 10, 10, 11, 11,
242 12, 13, 13, 14, 14, 15, 16, 16,
243 17, 18, 18, 19, 20, 21, 21, 22,
244 23, 24, 24, 25, 26, 27, 28, 29,
245 30, 31, 32, 33, 34, 35, 36, 37,
246 38, 40, 41, 42, 43, 45, 46, 48,
247 49, 51, 52, 54, 55, 57, 59, 61,
248 62, 63, 63, 63, 63, 63, 63, 63
249};
250
251const char pair[4] = {'A', 'B', 'C', 'D'};
252
253#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
254 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
255
256#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
257 for(i=PAIR_A; i<=PAIR_A; i++) { \
258 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
259 if(cal_ret) break; \
260 }
261
262#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
263 for(i=PAIR_A; i<=PAIR_D; i++) { \
264 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
265 if(cal_ret) break; \
266 }
267
developerc6e131e2021-12-08 12:36:24 +0800268#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
269 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
270 CAL_##pair_mode(cal_item, sw) \
271 }
developerc50c2352021-12-01 10:45:35 +0800272
273#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800274 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800275 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800276 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800277 } else if ((!efs_valid && ret) || \
278 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800279 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800280 }
281
282#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
283 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800284 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800285 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800286 }
287
288#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
289 ret = of_property_read_string(phydev->mdio.dev.of_node, \
290 #cal_item, &cal_mode_get); \
291 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800292 else { \
293 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
294 " use default value," \
295 " efs-valid: %s", \
296 #cal_item, \
297 ret? "" : cal_mode_get, \
298 ret? "not specified" : " not supported", \
299 efs_valid? "yes" : "no"); \
300 } \
developerc50c2352021-12-01 10:45:35 +0800301 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800302 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800303 ret = -EIO; \
304 goto out; \
305 }
306
307static int mtk_gephy_read_page(struct phy_device *phydev)
308{
309 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
310}
311
312static int mtk_gephy_write_page(struct phy_device *phydev, int page)
313{
314 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
315}
316
317/*
318 * One calibration cycle consists of:
319 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
320 * until AD_CAL_COMP is ready to output calibration result.
321 * 2.Wait until DA_CAL_CLK is available.
322 * 3.Fetch AD_CAL_COMP_OUT.
323 */
324static int cal_cycle(struct phy_device *phydev, int devad,
325 u32 regnum, u16 mask, u16 cal_val)
326{
327 unsigned long timeout;
328 int reg_val;
329 int ret;
330
331 phy_modify_mmd(phydev, devad, regnum,
332 mask, cal_val);
333 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
334 MTK_PHY_DA_CALIN_FLAG);
335
336 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
337 do{
338 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
339 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
340
341 if(!(reg_val & BIT(0))) {
342 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
343 return -ETIMEDOUT;
344 }
345
346 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
347 MTK_PHY_DA_CALIN_FLAG);
348 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
349 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
350 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
351
352 return ret;
353}
354
355static int rext_fill_result(struct phy_device *phydev, u16 *buf)
356{
357 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
358 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
359 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
360 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
361
362 return 0;
363}
364
365static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
366{
367 u16 rext_cal_val[2];
368
369 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
370 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
371 rext_fill_result(phydev, rext_cal_val);
372
373 return 0;
374}
375
376static int rext_cal_sw(struct phy_device *phydev)
377{
378 u8 rg_zcal_ctrl_def;
379 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
380 u8 lower_ret, upper_ret;
381 u16 rext_cal_val[2];
382 int ret;
383
384 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
385 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
386 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
387 MTK_PHY_RG_TXVOS_CALEN);
388 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
389 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
390 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
391 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
392
393 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
394 MTK_PHY_RG_ZCAL_CTRL_MASK;
395 zcal_lower = ZCAL_CTRL_MIN;
396 zcal_upper = ZCAL_CTRL_MAX;
397
398 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
399 while((zcal_upper-zcal_lower) > 1) {
400 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
401 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
402 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800403 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800404 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800405 upper_ret = ret;
406 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800407 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800408 lower_ret = ret;
409 } else
developerc50c2352021-12-01 10:45:35 +0800410 goto restore;
411 }
412
developer78aa7b92021-12-29 15:22:10 +0800413 if(zcal_lower == ZCAL_CTRL_MIN) {
414 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
415 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
416 } else if(zcal_upper == ZCAL_CTRL_MAX) {
417 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
418 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
419 }
420 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800421 goto restore;
422
423 ret = upper_ret-lower_ret;
424 if (ret == 1) {
425 rext_cal_val[0] = zcal_upper;
426 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800427 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800428 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
429 ret = 0;
430 } else
431 ret = -EINVAL;
432
433restore:
434 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
435 MTK_PHY_ANA_TEST_MODE_MASK);
436 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
437 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
438 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
439 MTK_PHY_RG_TST_DMY2_MASK);
440 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
441 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
442
443 return ret;
444}
445
446static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
447{
448 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
449 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
450 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
451 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
452 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
453 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
454 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
455 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
456
457 return 0;
458}
459
460static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
461{
462 u16 tx_offset_cal_val[4];
463
464 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
465 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
466 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
467 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
468
469 tx_offset_fill_result(phydev, tx_offset_cal_val);
470
471 return 0;
472}
473
474static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
475{
developer87c89d12022-08-19 17:46:34 +0800476 int bias[16] = {0};
477 switch(phydev->drv->phy_id) {
478 case 0x03a29461:
479 {
480 /* We add some calibration to efuse values:
481 * GBE: +7, TBT: +1, HBT: +4, TST: +7
482 */
483 int tmp[16] = { 7, 1, 4, 7,
484 7, 1, 4, 7,
485 7, 1, 4, 7,
486 7, 1, 4, 7 };
487 memcpy(bias, (const void *)tmp, sizeof(bias));
488 break;
489 }
490 case 0x03a29481:
491 {
492 int tmp[16] = { 10, 6, 6, 10,
493 10, 6, 6, 10,
494 10, 6, 6, 10,
495 10, 6, 6, 10 };
496 memcpy(bias, (const void *)tmp, sizeof(bias));
497 break;
498 }
499 default:
500 break;
501 }
developerc50c2352021-12-01 10:45:35 +0800502 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800503 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800504 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800505 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800506 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800507 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800508 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800509 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800510
511 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800512 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800513 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800514 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800515 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800516 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800517 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800518 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800519
520 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800521 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800522 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800523 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800524 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800525 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800526 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800527 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800528
529 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800530 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800531 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800532 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800533 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800534 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800535 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800536 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800537
538 return 0;
539}
540
541static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
542{
543 u16 tx_amp_cal_val[4];
544
545 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
546 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
547 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
548 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
549 tx_amp_fill_result(phydev, tx_amp_cal_val);
550
551 return 0;
552}
553
554static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
555 phy_cal_pair_t txg_calen_x)
556{
developer87c89d12022-08-19 17:46:34 +0800557 int bias[4] = {0};
558 switch(phydev->drv->phy_id) {
559 case 0x03a29481:
560 {
developerec2b8552022-10-17 15:30:59 +0800561 int tmp[16] = { -1, -1, -1, -1 };
developer87c89d12022-08-19 17:46:34 +0800562 memcpy(bias, (const void *)tmp, sizeof(bias));
563 break;
564 }
565 /* 0x03a29461 enters default case */
566 default:
567 break;
568 }
569
developerc50c2352021-12-01 10:45:35 +0800570 switch(txg_calen_x) {
571 case PAIR_A:
572 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800573 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800574 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800575 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800576 break;
577 case PAIR_B:
578 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800579 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800580 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800581 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800582 break;
583 case PAIR_C:
584 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800585 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800586 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800587 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800588 break;
589 case PAIR_D:
590 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800591 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800592 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800593 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800594 break;
595 }
596 return 0;
597}
598
599static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
600 phy_cal_pair_t txg_calen_x)
601{
602 u16 tx_r50_cal_val[1];
603
604 switch(txg_calen_x) {
605 case PAIR_A:
606 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
607 break;
608 case PAIR_B:
609 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
610 break;
611 case PAIR_C:
612 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
613 break;
614 case PAIR_D:
615 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
616 break;
617 }
618 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
619
620 return 0;
621}
622
623static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
624{
625 u8 rg_zcal_ctrl_def;
626 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
627 u8 lower_ret, upper_ret;
628 u16 tx_r50_cal_val[1];
629 int ret;
630
631 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
632 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
633 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
634 MTK_PHY_RG_TXVOS_CALEN);
635 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
636 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
637 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
638 BIT(txg_calen_x * 4));
639 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
640 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
641
642 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
643 MTK_PHY_RG_ZCAL_CTRL_MASK;
644 zcal_lower = ZCAL_CTRL_MIN;
645 zcal_upper = ZCAL_CTRL_MAX;
646
developer02d84422021-12-24 11:48:07 +0800647 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800648 while((zcal_upper-zcal_lower) > 1) {
649 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
650 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
651 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800652 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800653 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800654 upper_ret = ret;
655 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800656 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800657 lower_ret = ret;
658 } else
developerc50c2352021-12-01 10:45:35 +0800659 goto restore;
660 }
661
developer78aa7b92021-12-29 15:22:10 +0800662 if(zcal_lower == ZCAL_CTRL_MIN) {
663 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800664 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800665 } else if(zcal_upper == ZCAL_CTRL_MAX) {
666 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800667 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800668 }
669 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800670 goto restore;
671
672 ret = upper_ret-lower_ret;
673 if (ret == 1) {
674 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
675 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800676 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800677 pair[txg_calen_x], zcal_lower);
678 ret = 0;
679 } else
680 ret = -EINVAL;
681
682restore:
683 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
684 MTK_PHY_ANA_TEST_MODE_MASK);
685 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
686 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
687 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
688 BIT(txg_calen_x * 4));
689 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
690 MTK_PHY_RG_TST_DMY2_MASK);
691 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
692 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
693
694 return ret;
695}
696
697static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
698{
699 u8 lower_idx, upper_idx, txreserve_val;
700 u8 lower_ret, upper_ret;
701 int ret;
702
703 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
704 MTK_PHY_RG_ANA_CALEN);
705 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
706 MTK_PHY_RG_CAL_CKINV);
707 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
708 MTK_PHY_RG_TXVOS_CALEN);
709
710 switch(rg_txreserve_x) {
711 case PAIR_A:
712 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
713 MTK_PHY_DASN_DAC_IN0_A_MASK);
714 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
715 MTK_PHY_DASN_DAC_IN1_A_MASK);
716 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
717 MTK_PHY_RG_ZCALEN_A);
718 break;
719 case PAIR_B:
720 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
721 MTK_PHY_DASN_DAC_IN0_B_MASK);
722 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
723 MTK_PHY_DASN_DAC_IN1_B_MASK);
724 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
725 MTK_PHY_RG_ZCALEN_B);
726 break;
727 case PAIR_C:
728 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
729 MTK_PHY_DASN_DAC_IN0_C_MASK);
730 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
731 MTK_PHY_DASN_DAC_IN1_C_MASK);
732 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
733 MTK_PHY_RG_ZCALEN_C);
734 break;
735 case PAIR_D:
736 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
737 MTK_PHY_DASN_DAC_IN0_D_MASK);
738 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
739 MTK_PHY_DASN_DAC_IN1_D_MASK);
740 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
741 MTK_PHY_RG_ZCALEN_D);
742 break;
743 default:
744 ret = -EINVAL;
745 goto restore;
746 }
747
748 lower_idx = TXRESERVE_MIN;
749 upper_idx = TXRESERVE_MAX;
750
751 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
752 while((upper_idx-lower_idx) > 1) {
753 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
754 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
755 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
756 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
757 txreserve_val << 12 | txreserve_val << 8 |
758 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800759 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800760 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800761 upper_ret = ret;
762 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800763 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800764 lower_ret = ret;
765 } else
developerc50c2352021-12-01 10:45:35 +0800766 goto restore;
767 }
768
developer78aa7b92021-12-29 15:22:10 +0800769 if(lower_idx == TXRESERVE_MIN) {
770 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800771 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
772 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
773 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800774 } else if(upper_idx == TXRESERVE_MAX) {
775 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800776 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
777 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
778 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800779 }
780 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800781 goto restore;
782
developer78aa7b92021-12-29 15:22:10 +0800783 /* We calibrate TX-VCM in different logic. Check upper index and then
784 * lower index. If this calibration is valid, apply lower index's result.
785 */
developerc50c2352021-12-01 10:45:35 +0800786 ret = upper_ret-lower_ret;
787 if (ret == 1) {
788 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800789 /* Make sure we use upper_idx in our calibration system */
790 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
791 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
792 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
793 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800794 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
795 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
796 ret = 0;
797 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
798 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
799 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
800 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
801 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
802 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
803 ret = 0;
804 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
805 } else
806 ret = -EINVAL;
807
808restore:
809 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
810 MTK_PHY_RG_ANA_CALEN);
811 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
812 MTK_PHY_RG_TXVOS_CALEN);
813 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
814 MTK_PHY_RG_ZCALEN_A);
815 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
816 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
817
818 return ret;
819}
820
821static void mtk_gephy_config_init(struct phy_device *phydev)
822{
823 /* Disable EEE */
824 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
825
826 /* Enable HW auto downshift */
827 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
828
829 /* Increase SlvDPSready time */
830 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
831 __phy_write(phydev, 0x10, 0xafae);
832 __phy_write(phydev, 0x12, 0x2f);
833 __phy_write(phydev, 0x10, 0x8fae);
834 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
835
836 /* Adjust 100_mse_threshold */
837 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
838
839 /* Disable mcc */
840 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
841}
842
843static int mt7530_phy_config_init(struct phy_device *phydev)
844{
845 mtk_gephy_config_init(phydev);
846
847 /* Increase post_update_timer */
848 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
849
850 return 0;
851}
852
853static int mt7531_phy_config_init(struct phy_device *phydev)
854{
855 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
856 return -EINVAL;
857
858 mtk_gephy_config_init(phydev);
859
860 /* PHY link down power saving enable */
861 phy_set_bits(phydev, 0x17, BIT(4));
862 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
863
864 /* Set TX Pair delay selection */
865 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
866 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
867
868 return 0;
869}
870
developerf35532c2022-08-05 18:37:26 +0800871static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800872{
873 /* 100M eye finetune:
874 * Keep middle level of TX MLT3 shapper as default.
875 * Only change TX MLT3 overshoot level here.
876 */
877 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
878 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
879 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
880 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
881 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
882 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
883 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
884 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800885
developer02d84422021-12-24 11:48:07 +0800886 /* TX-AMP finetune:
887 * 100M +4, 1000M +6 to default value.
888 * If efuse values aren't valid, TX-AMP uses the below values.
889 */
890 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
891 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
892 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
893 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
894 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
895 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
896 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
897 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
898}
899
developerf35532c2022-08-05 18:37:26 +0800900static inline void mt7988_phy_finetune(struct phy_device *phydev)
901{
902 int i;
903 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
904 0x020d, 0x0206, 0x0384, 0x03d0,
905 0x03c6, 0x030a, 0x0011, 0x0005};
906
907 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
908 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
909 }
developer6de96aa2022-09-29 16:46:18 +0800910
developer57374032022-10-11 16:43:24 +0800911 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800912 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800913
914 /* Disable TX power saving */
915 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +0800916 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +0800917
918 /* Slave mode finetune, Kp=3/Kf=2 */
919 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
920 __phy_write(phydev, 0x12, 0x0);
921 __phy_write(phydev, 0x11, 0x750);
922 __phy_write(phydev, 0x10, 0x9686);
923 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerf35532c2022-08-05 18:37:26 +0800924}
925
926static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800927{
928 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800929 int i, ret;
930 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800931 u32 *buf;
932 bool efs_valid = true;
933 size_t len;
934 struct nvmem_cell *cell;
935
936 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
937 return -EINVAL;
938
939 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
940 if (IS_ERR(cell)) {
941 if (PTR_ERR(cell) == -EPROBE_DEFER)
942 return PTR_ERR(cell);
943 return 0;
944 }
945
946 buf = (u32 *)nvmem_cell_read(cell, &len);
947 if (IS_ERR(buf))
948 return PTR_ERR(buf);
949 nvmem_cell_put(cell);
950
951 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
952 efs_valid = false;
953
954 if (len < 4 * sizeof(u32)) {
955 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
956 ret = -EINVAL;
957 goto out;
958 }
959
960 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
961 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
962 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
963 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
964 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800965 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800966
967out:
968 kfree(buf);
969 return ret;
970}
971
developerf35532c2022-08-05 18:37:26 +0800972static int mt7981_phy_config_init(struct phy_device *phydev)
973{
974 mt7981_phy_finetune(phydev);
975
976 return mt798x_phy_calibration(phydev);
977}
978
979static int mt7988_phy_config_init(struct phy_device *phydev)
980{
developer23021292022-10-21 19:10:10 +0800981 struct device_node *np;
982 void __iomem *boottrap;
983 u32 reg;
984 int port;
985
986 /* Setup LED polarity according to boottrap's polarity */
987 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
988 if (!np)
989 return -ENOENT;
990 boottrap = of_iomap(np, 0);
991 if (!boottrap)
992 return -ENOMEM;
993 reg = readl(boottrap);
994 port = phydev->mdio.addr;
995 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
996 (port == GPHY_PORT1 && reg & BIT(9)) ||
997 (port == GPHY_PORT2 && reg & BIT(10)) ||
998 (port == GPHY_PORT3 && reg & BIT(11))) {
999 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1000 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1001 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1002 } else {
1003 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1004 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1005 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1006 MTK_PHY_LED0_ON_LINK1000);
1007 }
1008
developerf35532c2022-08-05 18:37:26 +08001009 mt7988_phy_finetune(phydev);
1010
1011 return mt798x_phy_calibration(phydev);
1012}
1013
1014static int mt7988_phy_probe(struct phy_device *phydev)
1015{
1016 return mt7988_phy_config_init(phydev);
1017}
1018
developerc50c2352021-12-01 10:45:35 +08001019static struct phy_driver mtk_gephy_driver[] = {
1020#if 0
1021 {
1022 PHY_ID_MATCH_EXACT(0x03a29412),
1023 .name = "MediaTek MT7530 PHY",
1024 .config_init = mt7530_phy_config_init,
1025 /* Interrupts are handled by the switch, not the PHY
1026 * itself.
1027 */
1028 .config_intr = genphy_no_config_intr,
1029 .handle_interrupt = genphy_no_ack_interrupt,
1030 .suspend = genphy_suspend,
1031 .resume = genphy_resume,
1032 .read_page = mtk_gephy_read_page,
1033 .write_page = mtk_gephy_write_page,
1034 },
1035 {
1036 PHY_ID_MATCH_EXACT(0x03a29441),
1037 .name = "MediaTek MT7531 PHY",
1038 .config_init = mt7531_phy_config_init,
1039 /* Interrupts are handled by the switch, not the PHY
1040 * itself.
1041 */
1042 .config_intr = genphy_no_config_intr,
1043 .handle_interrupt = genphy_no_ack_interrupt,
1044 .suspend = genphy_suspend,
1045 .resume = genphy_resume,
1046 .read_page = mtk_gephy_read_page,
1047 .write_page = mtk_gephy_write_page,
1048 },
1049#endif
1050 {
1051 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001052 .name = "MediaTek MT7981 PHY",
1053 .config_init = mt7981_phy_config_init,
1054 /* Interrupts are handled by the switch, not the PHY
1055 * itself.
1056 */
1057 .config_intr = genphy_no_config_intr,
1058 .handle_interrupt = genphy_no_ack_interrupt,
1059 .suspend = genphy_suspend,
1060 .resume = genphy_resume,
1061 .read_page = mtk_gephy_read_page,
1062 .write_page = mtk_gephy_write_page,
1063 },
1064 {
1065 PHY_ID_MATCH_EXACT(0x03a29481),
1066 .name = "MediaTek MT7988 PHY",
1067 .probe = mt7988_phy_probe,
1068 .config_init = mt7988_phy_config_init,
developerc50c2352021-12-01 10:45:35 +08001069 /* Interrupts are handled by the switch, not the PHY
1070 * itself.
1071 */
1072 .config_intr = genphy_no_config_intr,
1073 .handle_interrupt = genphy_no_ack_interrupt,
1074 .suspend = genphy_suspend,
1075 .resume = genphy_resume,
1076 .read_page = mtk_gephy_read_page,
1077 .write_page = mtk_gephy_write_page,
1078 },
1079};
1080
1081module_phy_driver(mtk_gephy_driver);
1082
1083static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1084 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1085 { }
1086};
1087
1088MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1089MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1090MODULE_LICENSE("GPL");
1091
1092MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);