blob: fd3022fc830449f53c67574c9d14d74e2c7e046d [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
developer8bc5dca2022-10-24 17:15:12 +0800193#define MTK_PHY_LED0_BLINK_CTRL (0x25)
194#define MTK_PHY_LED0_1000TX BIT(0)
195#define MTK_PHY_LED0_1000RX BIT(1)
196#define MTK_PHY_LED0_100TX BIT(2)
197#define MTK_PHY_LED0_100RX BIT(3)
198#define MTK_PHY_LED0_10TX BIT(4)
199#define MTK_PHY_LED0_10RX BIT(5)
200#define MTK_PHY_LED0_COLLISION BIT(6)
201#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
202#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
203#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
204
developerc50c2352021-12-01 10:45:35 +0800205#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
206#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
207
208#define MTK_PHY_RG_DEV1F_REG110 (0x110)
209#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
210#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
211
212#define MTK_PHY_RG_DEV1F_REG115 (0x115)
213#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
214
215/*
216 * These macro privides efuse parsing for internal phy.
217 */
218#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
219#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
220#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
221#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
222#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
223
224#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
225#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
226#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
227#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
228#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
229
230#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
231#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
232#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
233#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
234
235#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
236#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
237
238typedef enum {
239 PAIR_A,
240 PAIR_B,
241 PAIR_C,
242 PAIR_D,
243} phy_cal_pair_t;
244
developer23021292022-10-21 19:10:10 +0800245enum {
246 GPHY_PORT0,
247 GPHY_PORT1,
248 GPHY_PORT2,
249 GPHY_PORT3,
250};
251
developerc50c2352021-12-01 10:45:35 +0800252const u8 mt798x_zcal_to_r50[64] = {
253 7, 8, 9, 9, 10, 10, 11, 11,
254 12, 13, 13, 14, 14, 15, 16, 16,
255 17, 18, 18, 19, 20, 21, 21, 22,
256 23, 24, 24, 25, 26, 27, 28, 29,
257 30, 31, 32, 33, 34, 35, 36, 37,
258 38, 40, 41, 42, 43, 45, 46, 48,
259 49, 51, 52, 54, 55, 57, 59, 61,
260 62, 63, 63, 63, 63, 63, 63, 63
261};
262
263const char pair[4] = {'A', 'B', 'C', 'D'};
264
265#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
266 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
267
268#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
269 for(i=PAIR_A; i<=PAIR_A; i++) { \
270 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
271 if(cal_ret) break; \
272 }
273
274#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
275 for(i=PAIR_A; i<=PAIR_D; i++) { \
276 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
277 if(cal_ret) break; \
278 }
279
developerc6e131e2021-12-08 12:36:24 +0800280#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
281 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
282 CAL_##pair_mode(cal_item, sw) \
283 }
developerc50c2352021-12-01 10:45:35 +0800284
285#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800286 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800287 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800288 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800289 } else if ((!efs_valid && ret) || \
290 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800291 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800292 }
293
294#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
295 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800296 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800297 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800298 }
299
300#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
301 ret = of_property_read_string(phydev->mdio.dev.of_node, \
302 #cal_item, &cal_mode_get); \
303 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800304 else { \
305 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
306 " use default value," \
307 " efs-valid: %s", \
308 #cal_item, \
309 ret? "" : cal_mode_get, \
310 ret? "not specified" : " not supported", \
311 efs_valid? "yes" : "no"); \
312 } \
developerc50c2352021-12-01 10:45:35 +0800313 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800314 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800315 ret = -EIO; \
316 goto out; \
317 }
318
319static int mtk_gephy_read_page(struct phy_device *phydev)
320{
321 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
322}
323
324static int mtk_gephy_write_page(struct phy_device *phydev, int page)
325{
326 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
327}
328
329/*
330 * One calibration cycle consists of:
331 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
332 * until AD_CAL_COMP is ready to output calibration result.
333 * 2.Wait until DA_CAL_CLK is available.
334 * 3.Fetch AD_CAL_COMP_OUT.
335 */
336static int cal_cycle(struct phy_device *phydev, int devad,
337 u32 regnum, u16 mask, u16 cal_val)
338{
339 unsigned long timeout;
340 int reg_val;
341 int ret;
342
343 phy_modify_mmd(phydev, devad, regnum,
344 mask, cal_val);
345 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
346 MTK_PHY_DA_CALIN_FLAG);
347
348 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
349 do{
350 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
351 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
352
353 if(!(reg_val & BIT(0))) {
354 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
355 return -ETIMEDOUT;
356 }
357
358 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
359 MTK_PHY_DA_CALIN_FLAG);
360 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
361 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
362 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
363
364 return ret;
365}
366
367static int rext_fill_result(struct phy_device *phydev, u16 *buf)
368{
369 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
370 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
371 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
372 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
373
374 return 0;
375}
376
377static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
378{
379 u16 rext_cal_val[2];
380
381 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
382 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
383 rext_fill_result(phydev, rext_cal_val);
384
385 return 0;
386}
387
388static int rext_cal_sw(struct phy_device *phydev)
389{
390 u8 rg_zcal_ctrl_def;
391 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
392 u8 lower_ret, upper_ret;
393 u16 rext_cal_val[2];
394 int ret;
395
396 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
397 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
398 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
399 MTK_PHY_RG_TXVOS_CALEN);
400 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
401 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
402 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
403 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
404
405 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
406 MTK_PHY_RG_ZCAL_CTRL_MASK;
407 zcal_lower = ZCAL_CTRL_MIN;
408 zcal_upper = ZCAL_CTRL_MAX;
409
410 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
411 while((zcal_upper-zcal_lower) > 1) {
412 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
413 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
414 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800415 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800416 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800417 upper_ret = ret;
418 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800419 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800420 lower_ret = ret;
421 } else
developerc50c2352021-12-01 10:45:35 +0800422 goto restore;
423 }
424
developer78aa7b92021-12-29 15:22:10 +0800425 if(zcal_lower == ZCAL_CTRL_MIN) {
426 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
427 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
428 } else if(zcal_upper == ZCAL_CTRL_MAX) {
429 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
430 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
431 }
432 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800433 goto restore;
434
435 ret = upper_ret-lower_ret;
436 if (ret == 1) {
437 rext_cal_val[0] = zcal_upper;
438 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800439 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800440 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
441 ret = 0;
442 } else
443 ret = -EINVAL;
444
445restore:
446 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
447 MTK_PHY_ANA_TEST_MODE_MASK);
448 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
449 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
450 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
451 MTK_PHY_RG_TST_DMY2_MASK);
452 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
453 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
454
455 return ret;
456}
457
458static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
459{
460 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
461 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
462 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
463 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
464 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
465 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
466 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
467 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
468
469 return 0;
470}
471
472static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
473{
474 u16 tx_offset_cal_val[4];
475
476 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
477 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
478 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
479 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
480
481 tx_offset_fill_result(phydev, tx_offset_cal_val);
482
483 return 0;
484}
485
486static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
487{
developer87c89d12022-08-19 17:46:34 +0800488 int bias[16] = {0};
489 switch(phydev->drv->phy_id) {
490 case 0x03a29461:
491 {
492 /* We add some calibration to efuse values:
493 * GBE: +7, TBT: +1, HBT: +4, TST: +7
494 */
495 int tmp[16] = { 7, 1, 4, 7,
496 7, 1, 4, 7,
497 7, 1, 4, 7,
498 7, 1, 4, 7 };
499 memcpy(bias, (const void *)tmp, sizeof(bias));
500 break;
501 }
502 case 0x03a29481:
503 {
504 int tmp[16] = { 10, 6, 6, 10,
505 10, 6, 6, 10,
506 10, 6, 6, 10,
507 10, 6, 6, 10 };
508 memcpy(bias, (const void *)tmp, sizeof(bias));
509 break;
510 }
511 default:
512 break;
513 }
developerc50c2352021-12-01 10:45:35 +0800514 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800515 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800516 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800517 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800518 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800519 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800520 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800521 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800522
523 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800524 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800525 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800526 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800527 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800528 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800529 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800530 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800531
532 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800533 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800534 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800535 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800536 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800537 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800538 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800539 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800540
541 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800542 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800543 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800544 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800545 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800546 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800547 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800548 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800549
550 return 0;
551}
552
553static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
554{
555 u16 tx_amp_cal_val[4];
556
557 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
558 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
559 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
560 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
561 tx_amp_fill_result(phydev, tx_amp_cal_val);
562
563 return 0;
564}
565
566static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
567 phy_cal_pair_t txg_calen_x)
568{
developer87c89d12022-08-19 17:46:34 +0800569 int bias[4] = {0};
570 switch(phydev->drv->phy_id) {
571 case 0x03a29481:
572 {
developerec2b8552022-10-17 15:30:59 +0800573 int tmp[16] = { -1, -1, -1, -1 };
developer87c89d12022-08-19 17:46:34 +0800574 memcpy(bias, (const void *)tmp, sizeof(bias));
575 break;
576 }
577 /* 0x03a29461 enters default case */
578 default:
579 break;
580 }
581
developerc50c2352021-12-01 10:45:35 +0800582 switch(txg_calen_x) {
583 case PAIR_A:
584 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800585 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800586 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800587 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800588 break;
589 case PAIR_B:
590 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800591 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800592 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800593 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800594 break;
595 case PAIR_C:
596 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800597 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800598 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800599 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800600 break;
601 case PAIR_D:
602 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800603 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800604 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800605 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800606 break;
607 }
608 return 0;
609}
610
611static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
612 phy_cal_pair_t txg_calen_x)
613{
614 u16 tx_r50_cal_val[1];
615
616 switch(txg_calen_x) {
617 case PAIR_A:
618 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
619 break;
620 case PAIR_B:
621 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
622 break;
623 case PAIR_C:
624 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
625 break;
626 case PAIR_D:
627 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
628 break;
629 }
630 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
631
632 return 0;
633}
634
635static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
636{
637 u8 rg_zcal_ctrl_def;
638 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
639 u8 lower_ret, upper_ret;
640 u16 tx_r50_cal_val[1];
641 int ret;
642
643 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
644 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
645 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
646 MTK_PHY_RG_TXVOS_CALEN);
647 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
648 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
649 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
650 BIT(txg_calen_x * 4));
651 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
652 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
653
654 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
655 MTK_PHY_RG_ZCAL_CTRL_MASK;
656 zcal_lower = ZCAL_CTRL_MIN;
657 zcal_upper = ZCAL_CTRL_MAX;
658
developer02d84422021-12-24 11:48:07 +0800659 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800660 while((zcal_upper-zcal_lower) > 1) {
661 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
662 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
663 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800664 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800665 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800666 upper_ret = ret;
667 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800668 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800669 lower_ret = ret;
670 } else
developerc50c2352021-12-01 10:45:35 +0800671 goto restore;
672 }
673
developer78aa7b92021-12-29 15:22:10 +0800674 if(zcal_lower == ZCAL_CTRL_MIN) {
675 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800676 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800677 } else if(zcal_upper == ZCAL_CTRL_MAX) {
678 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800679 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800680 }
681 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800682 goto restore;
683
684 ret = upper_ret-lower_ret;
685 if (ret == 1) {
686 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
687 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800688 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800689 pair[txg_calen_x], zcal_lower);
690 ret = 0;
691 } else
692 ret = -EINVAL;
693
694restore:
695 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
696 MTK_PHY_ANA_TEST_MODE_MASK);
697 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
698 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
699 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
700 BIT(txg_calen_x * 4));
701 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
702 MTK_PHY_RG_TST_DMY2_MASK);
703 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
704 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
705
706 return ret;
707}
708
709static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
710{
711 u8 lower_idx, upper_idx, txreserve_val;
712 u8 lower_ret, upper_ret;
713 int ret;
714
715 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
716 MTK_PHY_RG_ANA_CALEN);
717 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
718 MTK_PHY_RG_CAL_CKINV);
719 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
720 MTK_PHY_RG_TXVOS_CALEN);
721
722 switch(rg_txreserve_x) {
723 case PAIR_A:
724 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
725 MTK_PHY_DASN_DAC_IN0_A_MASK);
726 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
727 MTK_PHY_DASN_DAC_IN1_A_MASK);
728 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
729 MTK_PHY_RG_ZCALEN_A);
730 break;
731 case PAIR_B:
732 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
733 MTK_PHY_DASN_DAC_IN0_B_MASK);
734 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
735 MTK_PHY_DASN_DAC_IN1_B_MASK);
736 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
737 MTK_PHY_RG_ZCALEN_B);
738 break;
739 case PAIR_C:
740 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
741 MTK_PHY_DASN_DAC_IN0_C_MASK);
742 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
743 MTK_PHY_DASN_DAC_IN1_C_MASK);
744 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
745 MTK_PHY_RG_ZCALEN_C);
746 break;
747 case PAIR_D:
748 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
749 MTK_PHY_DASN_DAC_IN0_D_MASK);
750 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
751 MTK_PHY_DASN_DAC_IN1_D_MASK);
752 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
753 MTK_PHY_RG_ZCALEN_D);
754 break;
755 default:
756 ret = -EINVAL;
757 goto restore;
758 }
759
760 lower_idx = TXRESERVE_MIN;
761 upper_idx = TXRESERVE_MAX;
762
763 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
764 while((upper_idx-lower_idx) > 1) {
765 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
766 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
767 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
768 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
769 txreserve_val << 12 | txreserve_val << 8 |
770 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800771 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800772 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800773 upper_ret = ret;
774 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800775 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800776 lower_ret = ret;
777 } else
developerc50c2352021-12-01 10:45:35 +0800778 goto restore;
779 }
780
developer78aa7b92021-12-29 15:22:10 +0800781 if(lower_idx == TXRESERVE_MIN) {
782 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800783 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
784 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
785 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800786 } else if(upper_idx == TXRESERVE_MAX) {
787 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800788 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
789 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
790 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800791 }
792 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800793 goto restore;
794
developer78aa7b92021-12-29 15:22:10 +0800795 /* We calibrate TX-VCM in different logic. Check upper index and then
796 * lower index. If this calibration is valid, apply lower index's result.
797 */
developerc50c2352021-12-01 10:45:35 +0800798 ret = upper_ret-lower_ret;
799 if (ret == 1) {
800 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800801 /* Make sure we use upper_idx in our calibration system */
802 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
803 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
804 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
805 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800806 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
807 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
808 ret = 0;
809 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
810 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
811 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
812 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
813 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
814 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
815 ret = 0;
816 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
817 } else
818 ret = -EINVAL;
819
820restore:
821 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
822 MTK_PHY_RG_ANA_CALEN);
823 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
824 MTK_PHY_RG_TXVOS_CALEN);
825 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
826 MTK_PHY_RG_ZCALEN_A);
827 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
828 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
829
830 return ret;
831}
832
833static void mtk_gephy_config_init(struct phy_device *phydev)
834{
835 /* Disable EEE */
836 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
837
838 /* Enable HW auto downshift */
839 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
840
841 /* Increase SlvDPSready time */
842 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
843 __phy_write(phydev, 0x10, 0xafae);
844 __phy_write(phydev, 0x12, 0x2f);
845 __phy_write(phydev, 0x10, 0x8fae);
846 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
847
848 /* Adjust 100_mse_threshold */
849 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
850
851 /* Disable mcc */
852 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
853}
854
855static int mt7530_phy_config_init(struct phy_device *phydev)
856{
857 mtk_gephy_config_init(phydev);
858
859 /* Increase post_update_timer */
860 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
861
862 return 0;
863}
864
865static int mt7531_phy_config_init(struct phy_device *phydev)
866{
867 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
868 return -EINVAL;
869
870 mtk_gephy_config_init(phydev);
871
872 /* PHY link down power saving enable */
873 phy_set_bits(phydev, 0x17, BIT(4));
874 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
875
876 /* Set TX Pair delay selection */
877 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
878 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
879
880 return 0;
881}
882
developerf35532c2022-08-05 18:37:26 +0800883static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800884{
885 /* 100M eye finetune:
886 * Keep middle level of TX MLT3 shapper as default.
887 * Only change TX MLT3 overshoot level here.
888 */
889 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
890 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
891 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
892 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
893 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
894 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
895 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
896 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800897
developer02d84422021-12-24 11:48:07 +0800898 /* TX-AMP finetune:
899 * 100M +4, 1000M +6 to default value.
900 * If efuse values aren't valid, TX-AMP uses the below values.
901 */
902 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
903 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
904 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
905 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
906 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
907 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
908 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
909 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
910}
911
developerf35532c2022-08-05 18:37:26 +0800912static inline void mt7988_phy_finetune(struct phy_device *phydev)
913{
914 int i;
915 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
916 0x020d, 0x0206, 0x0384, 0x03d0,
917 0x03c6, 0x030a, 0x0011, 0x0005};
918
919 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
920 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
921 }
developer6de96aa2022-09-29 16:46:18 +0800922
developer57374032022-10-11 16:43:24 +0800923 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800924 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800925
926 /* Disable TX power saving */
927 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +0800928 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +0800929
930 /* Slave mode finetune, Kp=3/Kf=2 */
931 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
932 __phy_write(phydev, 0x12, 0x0);
933 __phy_write(phydev, 0x11, 0x750);
934 __phy_write(phydev, 0x10, 0x9686);
935 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerf35532c2022-08-05 18:37:26 +0800936}
937
938static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800939{
940 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800941 int i, ret;
942 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800943 u32 *buf;
944 bool efs_valid = true;
945 size_t len;
946 struct nvmem_cell *cell;
947
948 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
949 return -EINVAL;
950
951 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
952 if (IS_ERR(cell)) {
953 if (PTR_ERR(cell) == -EPROBE_DEFER)
954 return PTR_ERR(cell);
955 return 0;
956 }
957
958 buf = (u32 *)nvmem_cell_read(cell, &len);
959 if (IS_ERR(buf))
960 return PTR_ERR(buf);
961 nvmem_cell_put(cell);
962
963 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
964 efs_valid = false;
965
966 if (len < 4 * sizeof(u32)) {
967 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
968 ret = -EINVAL;
969 goto out;
970 }
971
972 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
973 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
974 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
975 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
976 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800977 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800978
979out:
980 kfree(buf);
981 return ret;
982}
983
developerf35532c2022-08-05 18:37:26 +0800984static int mt7981_phy_config_init(struct phy_device *phydev)
985{
986 mt7981_phy_finetune(phydev);
987
988 return mt798x_phy_calibration(phydev);
989}
990
991static int mt7988_phy_config_init(struct phy_device *phydev)
992{
developer23021292022-10-21 19:10:10 +0800993 struct device_node *np;
994 void __iomem *boottrap;
995 u32 reg;
996 int port;
997
998 /* Setup LED polarity according to boottrap's polarity */
999 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1000 if (!np)
1001 return -ENOENT;
1002 boottrap = of_iomap(np, 0);
1003 if (!boottrap)
1004 return -ENOMEM;
1005 reg = readl(boottrap);
1006 port = phydev->mdio.addr;
1007 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1008 (port == GPHY_PORT1 && reg & BIT(9)) ||
1009 (port == GPHY_PORT2 && reg & BIT(10)) ||
1010 (port == GPHY_PORT3 && reg & BIT(11))) {
1011 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1012 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1013 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1014 } else {
1015 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1016 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1017 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1018 MTK_PHY_LED0_ON_LINK1000);
1019 }
developer8bc5dca2022-10-24 17:15:12 +08001020 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1021 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1022 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1023 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001024
developerf35532c2022-08-05 18:37:26 +08001025 mt7988_phy_finetune(phydev);
1026
1027 return mt798x_phy_calibration(phydev);
1028}
1029
1030static int mt7988_phy_probe(struct phy_device *phydev)
1031{
1032 return mt7988_phy_config_init(phydev);
1033}
1034
developerc50c2352021-12-01 10:45:35 +08001035static struct phy_driver mtk_gephy_driver[] = {
1036#if 0
1037 {
1038 PHY_ID_MATCH_EXACT(0x03a29412),
1039 .name = "MediaTek MT7530 PHY",
1040 .config_init = mt7530_phy_config_init,
1041 /* Interrupts are handled by the switch, not the PHY
1042 * itself.
1043 */
1044 .config_intr = genphy_no_config_intr,
1045 .handle_interrupt = genphy_no_ack_interrupt,
1046 .suspend = genphy_suspend,
1047 .resume = genphy_resume,
1048 .read_page = mtk_gephy_read_page,
1049 .write_page = mtk_gephy_write_page,
1050 },
1051 {
1052 PHY_ID_MATCH_EXACT(0x03a29441),
1053 .name = "MediaTek MT7531 PHY",
1054 .config_init = mt7531_phy_config_init,
1055 /* Interrupts are handled by the switch, not the PHY
1056 * itself.
1057 */
1058 .config_intr = genphy_no_config_intr,
1059 .handle_interrupt = genphy_no_ack_interrupt,
1060 .suspend = genphy_suspend,
1061 .resume = genphy_resume,
1062 .read_page = mtk_gephy_read_page,
1063 .write_page = mtk_gephy_write_page,
1064 },
1065#endif
1066 {
1067 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001068 .name = "MediaTek MT7981 PHY",
1069 .config_init = mt7981_phy_config_init,
1070 /* Interrupts are handled by the switch, not the PHY
1071 * itself.
1072 */
1073 .config_intr = genphy_no_config_intr,
1074 .handle_interrupt = genphy_no_ack_interrupt,
1075 .suspend = genphy_suspend,
1076 .resume = genphy_resume,
1077 .read_page = mtk_gephy_read_page,
1078 .write_page = mtk_gephy_write_page,
1079 },
1080 {
1081 PHY_ID_MATCH_EXACT(0x03a29481),
1082 .name = "MediaTek MT7988 PHY",
1083 .probe = mt7988_phy_probe,
1084 .config_init = mt7988_phy_config_init,
developerc50c2352021-12-01 10:45:35 +08001085 /* Interrupts are handled by the switch, not the PHY
1086 * itself.
1087 */
1088 .config_intr = genphy_no_config_intr,
1089 .handle_interrupt = genphy_no_ack_interrupt,
1090 .suspend = genphy_suspend,
1091 .resume = genphy_resume,
1092 .read_page = mtk_gephy_read_page,
1093 .write_page = mtk_gephy_write_page,
1094 },
1095};
1096
1097module_phy_driver(mtk_gephy_driver);
1098
1099static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1100 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1101 { }
1102};
1103
1104MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1105MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1106MODULE_LICENSE("GPL");
1107
1108MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);