blob: 90265356d76b838fc1b4b4bce77a342ab71d9203 [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
developer68f6e102022-11-22 17:35:00 +0800163#define MTK_PHY_RG_DEV1E_REG234 (0x234)
164#define MTK_PHY_TR_OPEN_LOOP_EN GENMASK(0, 0)
165
developerc50c2352021-12-01 10:45:35 +0800166#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
167#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
168#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
169
170#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
171#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
172#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
173
174#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
175#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
176#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
177
178#define MTK_PHY_RG_DEV1E_REG540 (0x540)
179#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
180#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
181
182
183/* Registers on MDIO_MMD_VEND2 */
developer23021292022-10-21 19:10:10 +0800184#define MTK_PHY_LED0_ON_CTRL (0x24)
185#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
186#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
187#define MTK_PHY_LED0_ON_LINK100 BIT(1)
188#define MTK_PHY_LED0_ON_LINK10 BIT(2)
189#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
190#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
191#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
192#define MTK_PHY_LED0_FORCE_ON BIT(6)
193#define MTK_PHY_LED0_POLARITY BIT(14)
194#define MTK_PHY_LED0_ENABLE BIT(15)
195
developer8bc5dca2022-10-24 17:15:12 +0800196#define MTK_PHY_LED0_BLINK_CTRL (0x25)
197#define MTK_PHY_LED0_1000TX BIT(0)
198#define MTK_PHY_LED0_1000RX BIT(1)
199#define MTK_PHY_LED0_100TX BIT(2)
200#define MTK_PHY_LED0_100RX BIT(3)
201#define MTK_PHY_LED0_10TX BIT(4)
202#define MTK_PHY_LED0_10RX BIT(5)
203#define MTK_PHY_LED0_COLLISION BIT(6)
204#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
205#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
206#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
207
developerc50c2352021-12-01 10:45:35 +0800208#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
209#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
210
211#define MTK_PHY_RG_DEV1F_REG110 (0x110)
212#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
213#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
214
215#define MTK_PHY_RG_DEV1F_REG115 (0x115)
216#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
217
218/*
219 * These macro privides efuse parsing for internal phy.
220 */
221#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
222#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
223#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
224#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
225#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
226
227#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
228#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
229#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
230#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
231#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
232
233#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
234#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
235#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
236#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
237
238#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
239#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
240
241typedef enum {
242 PAIR_A,
243 PAIR_B,
244 PAIR_C,
245 PAIR_D,
246} phy_cal_pair_t;
247
developer23021292022-10-21 19:10:10 +0800248enum {
249 GPHY_PORT0,
250 GPHY_PORT1,
251 GPHY_PORT2,
252 GPHY_PORT3,
253};
254
developerc50c2352021-12-01 10:45:35 +0800255const u8 mt798x_zcal_to_r50[64] = {
256 7, 8, 9, 9, 10, 10, 11, 11,
257 12, 13, 13, 14, 14, 15, 16, 16,
258 17, 18, 18, 19, 20, 21, 21, 22,
259 23, 24, 24, 25, 26, 27, 28, 29,
260 30, 31, 32, 33, 34, 35, 36, 37,
261 38, 40, 41, 42, 43, 45, 46, 48,
262 49, 51, 52, 54, 55, 57, 59, 61,
263 62, 63, 63, 63, 63, 63, 63, 63
264};
265
266const char pair[4] = {'A', 'B', 'C', 'D'};
267
268#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
269 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
270
271#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
272 for(i=PAIR_A; i<=PAIR_A; i++) { \
273 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
274 if(cal_ret) break; \
275 }
276
277#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
278 for(i=PAIR_A; i<=PAIR_D; i++) { \
279 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
280 if(cal_ret) break; \
281 }
282
developerc6e131e2021-12-08 12:36:24 +0800283#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
284 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
285 CAL_##pair_mode(cal_item, sw) \
286 }
developerc50c2352021-12-01 10:45:35 +0800287
288#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800289 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800290 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800291 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800292 } else if ((!efs_valid && ret) || \
293 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800294 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800295 }
296
297#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
298 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800299 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800300 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800301 }
302
303#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
304 ret = of_property_read_string(phydev->mdio.dev.of_node, \
305 #cal_item, &cal_mode_get); \
306 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800307 else { \
308 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
309 " use default value," \
310 " efs-valid: %s", \
311 #cal_item, \
312 ret? "" : cal_mode_get, \
313 ret? "not specified" : " not supported", \
314 efs_valid? "yes" : "no"); \
315 } \
developerc50c2352021-12-01 10:45:35 +0800316 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800317 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800318 ret = -EIO; \
319 goto out; \
320 }
321
322static int mtk_gephy_read_page(struct phy_device *phydev)
323{
324 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
325}
326
327static int mtk_gephy_write_page(struct phy_device *phydev, int page)
328{
329 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
330}
331
332/*
333 * One calibration cycle consists of:
334 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
335 * until AD_CAL_COMP is ready to output calibration result.
336 * 2.Wait until DA_CAL_CLK is available.
337 * 3.Fetch AD_CAL_COMP_OUT.
338 */
339static int cal_cycle(struct phy_device *phydev, int devad,
340 u32 regnum, u16 mask, u16 cal_val)
341{
342 unsigned long timeout;
343 int reg_val;
344 int ret;
345
346 phy_modify_mmd(phydev, devad, regnum,
347 mask, cal_val);
348 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
349 MTK_PHY_DA_CALIN_FLAG);
350
351 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
352 do{
353 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
354 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
355
356 if(!(reg_val & BIT(0))) {
357 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
358 return -ETIMEDOUT;
359 }
360
361 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
362 MTK_PHY_DA_CALIN_FLAG);
363 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
364 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
365 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
366
367 return ret;
368}
369
370static int rext_fill_result(struct phy_device *phydev, u16 *buf)
371{
372 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
373 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
374 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
375 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
376
377 return 0;
378}
379
380static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
381{
382 u16 rext_cal_val[2];
383
384 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
385 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
386 rext_fill_result(phydev, rext_cal_val);
387
388 return 0;
389}
390
391static int rext_cal_sw(struct phy_device *phydev)
392{
393 u8 rg_zcal_ctrl_def;
394 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
395 u8 lower_ret, upper_ret;
396 u16 rext_cal_val[2];
397 int ret;
398
399 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
400 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
401 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
402 MTK_PHY_RG_TXVOS_CALEN);
403 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
404 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
405 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
406 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
407
408 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
409 MTK_PHY_RG_ZCAL_CTRL_MASK;
410 zcal_lower = ZCAL_CTRL_MIN;
411 zcal_upper = ZCAL_CTRL_MAX;
412
413 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
414 while((zcal_upper-zcal_lower) > 1) {
415 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
416 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
417 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800418 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800419 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800420 upper_ret = ret;
421 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800422 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800423 lower_ret = ret;
424 } else
developerc50c2352021-12-01 10:45:35 +0800425 goto restore;
426 }
427
developer78aa7b92021-12-29 15:22:10 +0800428 if(zcal_lower == ZCAL_CTRL_MIN) {
429 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
430 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
431 } else if(zcal_upper == ZCAL_CTRL_MAX) {
432 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
433 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
434 }
435 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800436 goto restore;
437
438 ret = upper_ret-lower_ret;
439 if (ret == 1) {
440 rext_cal_val[0] = zcal_upper;
441 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800442 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800443 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
444 ret = 0;
445 } else
446 ret = -EINVAL;
447
448restore:
449 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
450 MTK_PHY_ANA_TEST_MODE_MASK);
451 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
452 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
453 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
454 MTK_PHY_RG_TST_DMY2_MASK);
455 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
456 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
457
458 return ret;
459}
460
461static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
462{
463 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
464 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
465 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
466 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
467 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
468 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
469 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
470 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
471
472 return 0;
473}
474
475static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
476{
477 u16 tx_offset_cal_val[4];
478
479 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
480 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
481 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
482 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
483
484 tx_offset_fill_result(phydev, tx_offset_cal_val);
485
486 return 0;
487}
488
489static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
490{
developer87c89d12022-08-19 17:46:34 +0800491 int bias[16] = {0};
492 switch(phydev->drv->phy_id) {
493 case 0x03a29461:
494 {
495 /* We add some calibration to efuse values:
496 * GBE: +7, TBT: +1, HBT: +4, TST: +7
497 */
498 int tmp[16] = { 7, 1, 4, 7,
499 7, 1, 4, 7,
500 7, 1, 4, 7,
501 7, 1, 4, 7 };
502 memcpy(bias, (const void *)tmp, sizeof(bias));
503 break;
504 }
505 case 0x03a29481:
506 {
507 int tmp[16] = { 10, 6, 6, 10,
508 10, 6, 6, 10,
509 10, 6, 6, 10,
510 10, 6, 6, 10 };
511 memcpy(bias, (const void *)tmp, sizeof(bias));
512 break;
513 }
514 default:
515 break;
516 }
developerc50c2352021-12-01 10:45:35 +0800517 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800518 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800519 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800520 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800521 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800522 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800523 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800524 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800525
526 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800527 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800528 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800529 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800530 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800531 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800532 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800533 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800534
535 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800536 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800537 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800538 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800539 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800540 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800541 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800542 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800543
544 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800545 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800546 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800547 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800548 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800549 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800550 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800551 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800552
553 return 0;
554}
555
556static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
557{
558 u16 tx_amp_cal_val[4];
559
560 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
561 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
562 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
563 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
564 tx_amp_fill_result(phydev, tx_amp_cal_val);
565
566 return 0;
567}
568
569static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
570 phy_cal_pair_t txg_calen_x)
571{
developer87c89d12022-08-19 17:46:34 +0800572 int bias[4] = {0};
573 switch(phydev->drv->phy_id) {
574 case 0x03a29481:
575 {
developerec2b8552022-10-17 15:30:59 +0800576 int tmp[16] = { -1, -1, -1, -1 };
developer87c89d12022-08-19 17:46:34 +0800577 memcpy(bias, (const void *)tmp, sizeof(bias));
578 break;
579 }
580 /* 0x03a29461 enters default case */
581 default:
582 break;
583 }
584
developerc50c2352021-12-01 10:45:35 +0800585 switch(txg_calen_x) {
586 case PAIR_A:
587 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800588 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800589 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800590 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800591 break;
592 case PAIR_B:
593 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800594 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800595 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800596 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800597 break;
598 case PAIR_C:
599 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800600 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800601 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800602 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800603 break;
604 case PAIR_D:
605 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800606 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800607 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800608 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800609 break;
610 }
611 return 0;
612}
613
614static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
615 phy_cal_pair_t txg_calen_x)
616{
617 u16 tx_r50_cal_val[1];
618
619 switch(txg_calen_x) {
620 case PAIR_A:
621 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
622 break;
623 case PAIR_B:
624 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
625 break;
626 case PAIR_C:
627 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
628 break;
629 case PAIR_D:
630 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
631 break;
632 }
633 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
634
635 return 0;
636}
637
638static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
639{
640 u8 rg_zcal_ctrl_def;
641 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
642 u8 lower_ret, upper_ret;
643 u16 tx_r50_cal_val[1];
644 int ret;
645
646 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
647 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
648 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
649 MTK_PHY_RG_TXVOS_CALEN);
650 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
651 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
652 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
653 BIT(txg_calen_x * 4));
654 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
655 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
656
657 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
658 MTK_PHY_RG_ZCAL_CTRL_MASK;
659 zcal_lower = ZCAL_CTRL_MIN;
660 zcal_upper = ZCAL_CTRL_MAX;
661
developer02d84422021-12-24 11:48:07 +0800662 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800663 while((zcal_upper-zcal_lower) > 1) {
664 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
665 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
666 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800667 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800668 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800669 upper_ret = ret;
670 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800671 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800672 lower_ret = ret;
673 } else
developerc50c2352021-12-01 10:45:35 +0800674 goto restore;
675 }
676
developer78aa7b92021-12-29 15:22:10 +0800677 if(zcal_lower == ZCAL_CTRL_MIN) {
678 ret = lower_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_lower);
developer78aa7b92021-12-29 15:22:10 +0800680 } else if(zcal_upper == ZCAL_CTRL_MAX) {
681 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800682 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800683 }
684 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800685 goto restore;
686
687 ret = upper_ret-lower_ret;
688 if (ret == 1) {
689 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
690 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800691 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800692 pair[txg_calen_x], zcal_lower);
693 ret = 0;
694 } else
695 ret = -EINVAL;
696
697restore:
698 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
699 MTK_PHY_ANA_TEST_MODE_MASK);
700 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
701 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
702 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
703 BIT(txg_calen_x * 4));
704 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
705 MTK_PHY_RG_TST_DMY2_MASK);
706 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
707 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
708
709 return ret;
710}
711
712static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
713{
714 u8 lower_idx, upper_idx, txreserve_val;
715 u8 lower_ret, upper_ret;
716 int ret;
717
718 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
719 MTK_PHY_RG_ANA_CALEN);
720 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
721 MTK_PHY_RG_CAL_CKINV);
722 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
723 MTK_PHY_RG_TXVOS_CALEN);
724
725 switch(rg_txreserve_x) {
726 case PAIR_A:
727 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
728 MTK_PHY_DASN_DAC_IN0_A_MASK);
729 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
730 MTK_PHY_DASN_DAC_IN1_A_MASK);
731 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
732 MTK_PHY_RG_ZCALEN_A);
733 break;
734 case PAIR_B:
735 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
736 MTK_PHY_DASN_DAC_IN0_B_MASK);
737 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
738 MTK_PHY_DASN_DAC_IN1_B_MASK);
739 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
740 MTK_PHY_RG_ZCALEN_B);
741 break;
742 case PAIR_C:
743 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
744 MTK_PHY_DASN_DAC_IN0_C_MASK);
745 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
746 MTK_PHY_DASN_DAC_IN1_C_MASK);
747 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
748 MTK_PHY_RG_ZCALEN_C);
749 break;
750 case PAIR_D:
751 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
752 MTK_PHY_DASN_DAC_IN0_D_MASK);
753 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
754 MTK_PHY_DASN_DAC_IN1_D_MASK);
755 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
756 MTK_PHY_RG_ZCALEN_D);
757 break;
758 default:
759 ret = -EINVAL;
760 goto restore;
761 }
762
763 lower_idx = TXRESERVE_MIN;
764 upper_idx = TXRESERVE_MAX;
765
766 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
767 while((upper_idx-lower_idx) > 1) {
768 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
769 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
770 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
771 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
772 txreserve_val << 12 | txreserve_val << 8 |
773 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800774 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800775 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800776 upper_ret = ret;
777 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800778 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800779 lower_ret = ret;
780 } else
developerc50c2352021-12-01 10:45:35 +0800781 goto restore;
782 }
783
developer78aa7b92021-12-29 15:22:10 +0800784 if(lower_idx == TXRESERVE_MIN) {
785 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800786 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
787 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
788 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800789 } else if(upper_idx == TXRESERVE_MAX) {
790 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800791 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);
developer78aa7b92021-12-29 15:22:10 +0800794 }
795 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800796 goto restore;
797
developer78aa7b92021-12-29 15:22:10 +0800798 /* We calibrate TX-VCM in different logic. Check upper index and then
799 * lower index. If this calibration is valid, apply lower index's result.
800 */
developerc50c2352021-12-01 10:45:35 +0800801 ret = upper_ret-lower_ret;
802 if (ret == 1) {
803 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800804 /* Make sure we use upper_idx in our calibration system */
805 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
806 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
807 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
808 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800809 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
810 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
811 ret = 0;
812 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
813 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
814 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
815 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
816 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
817 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
818 ret = 0;
819 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
820 } else
821 ret = -EINVAL;
822
823restore:
824 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
825 MTK_PHY_RG_ANA_CALEN);
826 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
827 MTK_PHY_RG_TXVOS_CALEN);
828 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
829 MTK_PHY_RG_ZCALEN_A);
830 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
831 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
832
833 return ret;
834}
835
836static void mtk_gephy_config_init(struct phy_device *phydev)
837{
838 /* Disable EEE */
839 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
840
841 /* Enable HW auto downshift */
842 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
843
844 /* Increase SlvDPSready time */
845 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
846 __phy_write(phydev, 0x10, 0xafae);
847 __phy_write(phydev, 0x12, 0x2f);
848 __phy_write(phydev, 0x10, 0x8fae);
849 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
850
851 /* Adjust 100_mse_threshold */
852 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
853
854 /* Disable mcc */
855 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
856}
857
858static int mt7530_phy_config_init(struct phy_device *phydev)
859{
860 mtk_gephy_config_init(phydev);
861
862 /* Increase post_update_timer */
863 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
864
865 return 0;
866}
867
868static int mt7531_phy_config_init(struct phy_device *phydev)
869{
870 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
871 return -EINVAL;
872
873 mtk_gephy_config_init(phydev);
874
875 /* PHY link down power saving enable */
876 phy_set_bits(phydev, 0x17, BIT(4));
877 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
878
879 /* Set TX Pair delay selection */
880 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
881 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
882
883 return 0;
884}
885
developerf35532c2022-08-05 18:37:26 +0800886static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800887{
888 /* 100M eye finetune:
889 * Keep middle level of TX MLT3 shapper as default.
890 * Only change TX MLT3 overshoot level here.
891 */
892 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
893 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
894 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
895 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
896 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
897 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
898 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
899 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800900
developer02d84422021-12-24 11:48:07 +0800901 /* TX-AMP finetune:
902 * 100M +4, 1000M +6 to default value.
903 * If efuse values aren't valid, TX-AMP uses the below values.
904 */
905 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
906 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
907 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
908 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
909 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
910 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
911 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
912 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
developer68f6e102022-11-22 17:35:00 +0800913
914 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
915 MTK_PHY_TR_OPEN_LOOP_EN, 0x1);
developer02d84422021-12-24 11:48:07 +0800916}
917
developerf35532c2022-08-05 18:37:26 +0800918static inline void mt7988_phy_finetune(struct phy_device *phydev)
919{
920 int i;
921 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
922 0x020d, 0x0206, 0x0384, 0x03d0,
923 0x03c6, 0x030a, 0x0011, 0x0005};
924
925 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
926 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
927 }
developer6de96aa2022-09-29 16:46:18 +0800928
developer57374032022-10-11 16:43:24 +0800929 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800930 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800931
932 /* Disable TX power saving */
933 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +0800934 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +0800935
936 /* Slave mode finetune, Kp=3/Kf=2 */
937 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
938 __phy_write(phydev, 0x12, 0x0);
939 __phy_write(phydev, 0x11, 0x750);
940 __phy_write(phydev, 0x10, 0x9686);
941 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerf35532c2022-08-05 18:37:26 +0800942}
943
944static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800945{
946 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +0800947 int i, ret;
948 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +0800949 u32 *buf;
950 bool efs_valid = true;
951 size_t len;
952 struct nvmem_cell *cell;
953
954 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
955 return -EINVAL;
956
957 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
958 if (IS_ERR(cell)) {
959 if (PTR_ERR(cell) == -EPROBE_DEFER)
960 return PTR_ERR(cell);
961 return 0;
962 }
963
964 buf = (u32 *)nvmem_cell_read(cell, &len);
965 if (IS_ERR(buf))
966 return PTR_ERR(buf);
967 nvmem_cell_put(cell);
968
969 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
970 efs_valid = false;
971
972 if (len < 4 * sizeof(u32)) {
973 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
974 ret = -EINVAL;
975 goto out;
976 }
977
978 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
979 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
980 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
981 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
982 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +0800983 ret = 0;
developerc50c2352021-12-01 10:45:35 +0800984
985out:
986 kfree(buf);
987 return ret;
988}
989
developer68f6e102022-11-22 17:35:00 +0800990static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +0800991{
992 mt7981_phy_finetune(phydev);
993
994 return mt798x_phy_calibration(phydev);
995}
996
developer68f6e102022-11-22 17:35:00 +0800997static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +0800998{
developer23021292022-10-21 19:10:10 +0800999 struct device_node *np;
1000 void __iomem *boottrap;
1001 u32 reg;
1002 int port;
1003
1004 /* Setup LED polarity according to boottrap's polarity */
1005 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1006 if (!np)
1007 return -ENOENT;
1008 boottrap = of_iomap(np, 0);
1009 if (!boottrap)
1010 return -ENOMEM;
1011 reg = readl(boottrap);
1012 port = phydev->mdio.addr;
1013 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1014 (port == GPHY_PORT1 && reg & BIT(9)) ||
1015 (port == GPHY_PORT2 && reg & BIT(10)) ||
1016 (port == GPHY_PORT3 && reg & BIT(11))) {
1017 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1018 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1019 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1020 } else {
1021 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1022 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1023 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1024 MTK_PHY_LED0_ON_LINK1000);
1025 }
developer8bc5dca2022-10-24 17:15:12 +08001026 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1027 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1028 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1029 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001030
developerf35532c2022-08-05 18:37:26 +08001031 mt7988_phy_finetune(phydev);
1032
1033 return mt798x_phy_calibration(phydev);
1034}
1035
developerc50c2352021-12-01 10:45:35 +08001036static struct phy_driver mtk_gephy_driver[] = {
1037#if 0
1038 {
1039 PHY_ID_MATCH_EXACT(0x03a29412),
1040 .name = "MediaTek MT7530 PHY",
1041 .config_init = mt7530_phy_config_init,
1042 /* Interrupts are handled by the switch, not the PHY
1043 * itself.
1044 */
1045 .config_intr = genphy_no_config_intr,
1046 .handle_interrupt = genphy_no_ack_interrupt,
1047 .suspend = genphy_suspend,
1048 .resume = genphy_resume,
1049 .read_page = mtk_gephy_read_page,
1050 .write_page = mtk_gephy_write_page,
1051 },
1052 {
1053 PHY_ID_MATCH_EXACT(0x03a29441),
1054 .name = "MediaTek MT7531 PHY",
1055 .config_init = mt7531_phy_config_init,
1056 /* Interrupts are handled by the switch, not the PHY
1057 * itself.
1058 */
1059 .config_intr = genphy_no_config_intr,
1060 .handle_interrupt = genphy_no_ack_interrupt,
1061 .suspend = genphy_suspend,
1062 .resume = genphy_resume,
1063 .read_page = mtk_gephy_read_page,
1064 .write_page = mtk_gephy_write_page,
1065 },
1066#endif
1067 {
1068 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001069 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001070 .probe = mt7981_phy_probe,
1071 .read_status = mt798x_phy_read_status,
developerf35532c2022-08-05 18:37:26 +08001072 /* Interrupts are handled by the switch, not the PHY
1073 * itself.
1074 */
1075 .config_intr = genphy_no_config_intr,
1076 .handle_interrupt = genphy_no_ack_interrupt,
1077 .suspend = genphy_suspend,
1078 .resume = genphy_resume,
1079 .read_page = mtk_gephy_read_page,
1080 .write_page = mtk_gephy_write_page,
1081 },
1082 {
1083 PHY_ID_MATCH_EXACT(0x03a29481),
1084 .name = "MediaTek MT7988 PHY",
1085 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001086 /* Interrupts are handled by the switch, not the PHY
1087 * itself.
1088 */
1089 .config_intr = genphy_no_config_intr,
1090 .handle_interrupt = genphy_no_ack_interrupt,
1091 .suspend = genphy_suspend,
1092 .resume = genphy_resume,
1093 .read_page = mtk_gephy_read_page,
1094 .write_page = mtk_gephy_write_page,
1095 },
1096};
1097
1098module_phy_driver(mtk_gephy_driver);
1099
1100static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1101 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1102 { }
1103};
1104
1105MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1106MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1107MODULE_LICENSE("GPL");
1108
1109MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);