blob: 6d9663c8176a8402aefb51810786cb5ff2eb3b1c [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
developerd2ec38e2022-11-27 01:15:29 +0800163#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
164#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
165#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
166#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
167#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
168#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
169#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
170#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
171#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
172#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
173
developer68f6e102022-11-22 17:35:00 +0800174#define MTK_PHY_RG_DEV1E_REG234 (0x234)
developerd2ec38e2022-11-27 01:15:29 +0800175#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
176#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
177
178#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
179
180#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
181#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
182#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
183#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800184
developerc50c2352021-12-01 10:45:35 +0800185#define MTK_PHY_RG_DEV1E_REG53D (0x53d)
186#define MTK_PHY_DA_TX_R50_A_NORMAL_MASK GENMASK(13, 8)
187#define MTK_PHY_DA_TX_R50_A_TBT_MASK GENMASK(5, 0)
188
189#define MTK_PHY_RG_DEV1E_REG53E (0x53e)
190#define MTK_PHY_DA_TX_R50_B_NORMAL_MASK GENMASK(13, 8)
191#define MTK_PHY_DA_TX_R50_B_TBT_MASK GENMASK(5, 0)
192
193#define MTK_PHY_RG_DEV1E_REG53F (0x53f)
194#define MTK_PHY_DA_TX_R50_C_NORMAL_MASK GENMASK(13, 8)
195#define MTK_PHY_DA_TX_R50_C_TBT_MASK GENMASK(5, 0)
196
197#define MTK_PHY_RG_DEV1E_REG540 (0x540)
198#define MTK_PHY_DA_TX_R50_D_NORMAL_MASK GENMASK(13, 8)
199#define MTK_PHY_DA_TX_R50_D_TBT_MASK GENMASK(5, 0)
200
201
202/* Registers on MDIO_MMD_VEND2 */
developer23021292022-10-21 19:10:10 +0800203#define MTK_PHY_LED0_ON_CTRL (0x24)
204#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
205#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
206#define MTK_PHY_LED0_ON_LINK100 BIT(1)
207#define MTK_PHY_LED0_ON_LINK10 BIT(2)
208#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
209#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
210#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
211#define MTK_PHY_LED0_FORCE_ON BIT(6)
212#define MTK_PHY_LED0_POLARITY BIT(14)
213#define MTK_PHY_LED0_ENABLE BIT(15)
214
developer8bc5dca2022-10-24 17:15:12 +0800215#define MTK_PHY_LED0_BLINK_CTRL (0x25)
216#define MTK_PHY_LED0_1000TX BIT(0)
217#define MTK_PHY_LED0_1000RX BIT(1)
218#define MTK_PHY_LED0_100TX BIT(2)
219#define MTK_PHY_LED0_100RX BIT(3)
220#define MTK_PHY_LED0_10TX BIT(4)
221#define MTK_PHY_LED0_10RX BIT(5)
222#define MTK_PHY_LED0_COLLISION BIT(6)
223#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
224#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
225#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
226
developerc50c2352021-12-01 10:45:35 +0800227#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
228#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
229
230#define MTK_PHY_RG_DEV1F_REG110 (0x110)
231#define MTK_PHY_RG_TST_DMY2_MASK GENMASK(5, 0)
232#define MTK_PHY_RG_TANA_RESERVE_MASK GENMASK(13, 8)
233
234#define MTK_PHY_RG_DEV1F_REG115 (0x115)
235#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
236
237/*
238 * These macro privides efuse parsing for internal phy.
239 */
240#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
241#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
242#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
243#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
244#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
245
246#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
247#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
248#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
249#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
250#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
251
252#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
253#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
254#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
255#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
256
257#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
258#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
259
260typedef enum {
261 PAIR_A,
262 PAIR_B,
263 PAIR_C,
264 PAIR_D,
265} phy_cal_pair_t;
266
developer23021292022-10-21 19:10:10 +0800267enum {
268 GPHY_PORT0,
269 GPHY_PORT1,
270 GPHY_PORT2,
271 GPHY_PORT3,
272};
273
developerc50c2352021-12-01 10:45:35 +0800274const u8 mt798x_zcal_to_r50[64] = {
275 7, 8, 9, 9, 10, 10, 11, 11,
276 12, 13, 13, 14, 14, 15, 16, 16,
277 17, 18, 18, 19, 20, 21, 21, 22,
278 23, 24, 24, 25, 26, 27, 28, 29,
279 30, 31, 32, 33, 34, 35, 36, 37,
280 38, 40, 41, 42, 43, 45, 46, 48,
281 49, 51, 52, 54, 55, 57, 59, 61,
282 62, 63, 63, 63, 63, 63, 63, 63
283};
284
285const char pair[4] = {'A', 'B', 'C', 'D'};
286
287#define CAL_NO_PAIR(cal_item, cal_mode, ...) \
288 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__);
289
290#define CAL_PAIR_A_TO_A(cal_item, cal_mode, ...) \
291 for(i=PAIR_A; i<=PAIR_A; i++) { \
292 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
293 if(cal_ret) break; \
294 }
295
296#define CAL_PAIR_A_TO_D(cal_item, cal_mode, ...) \
297 for(i=PAIR_A; i<=PAIR_D; i++) { \
298 cal_ret = cal_item##_cal_##cal_mode(phydev, ##__VA_ARGS__, i);\
299 if(cal_ret) break; \
300 }
301
developerc6e131e2021-12-08 12:36:24 +0800302#define SW_CAL(cal_item, cal_mode_get, pair_mode) \
303 if(ret || (!ret && strcmp("sw", cal_mode_get) == 0)) { \
304 CAL_##pair_mode(cal_item, sw) \
305 }
developerc50c2352021-12-01 10:45:35 +0800306
307#define SW_EFUSE_CAL(cal_item, cal_mode_get, pair_mode,...) \
developerc6e131e2021-12-08 12:36:24 +0800308 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800309 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800310 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc6e131e2021-12-08 12:36:24 +0800311 } else if ((!efs_valid && ret) || \
312 (!ret && strcmp("sw", cal_mode_get) == 0)) { \
developerc50c2352021-12-01 10:45:35 +0800313 CAL_##pair_mode(cal_item, sw) \
developerc50c2352021-12-01 10:45:35 +0800314 }
315
316#define EFUSE_CAL(cal_item, cal_mode_get, pair_mode, ...) \
317 if ((efs_valid && ret) || \
developer5736bab2022-08-10 17:32:07 +0800318 (efs_valid && !ret && strcmp("efuse", cal_mode_get) == 0)) {\
developerc50c2352021-12-01 10:45:35 +0800319 CAL_##pair_mode(cal_item, efuse, ##__VA_ARGS__) \
developerc50c2352021-12-01 10:45:35 +0800320 }
321
322#define CAL_FLOW(cal_item, cal_mode, cal_mode_get, pair_mode,...) \
323 ret = of_property_read_string(phydev->mdio.dev.of_node, \
324 #cal_item, &cal_mode_get); \
325 cal_mode##_CAL(cal_item, cal_mode_get, pair_mode, ##__VA_ARGS__)\
developerc6e131e2021-12-08 12:36:24 +0800326 else { \
327 dev_info(&phydev->mdio.dev, "%s cal mode %s%s," \
328 " use default value," \
329 " efs-valid: %s", \
330 #cal_item, \
331 ret? "" : cal_mode_get, \
332 ret? "not specified" : " not supported", \
333 efs_valid? "yes" : "no"); \
334 } \
developerc50c2352021-12-01 10:45:35 +0800335 if(cal_ret) { \
developer02d84422021-12-24 11:48:07 +0800336 dev_err(&phydev->mdio.dev, "%s cal failed\n", #cal_item);\
developerc50c2352021-12-01 10:45:35 +0800337 ret = -EIO; \
338 goto out; \
339 }
340
341static int mtk_gephy_read_page(struct phy_device *phydev)
342{
343 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
344}
345
346static int mtk_gephy_write_page(struct phy_device *phydev, int page)
347{
348 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
349}
350
351/*
352 * One calibration cycle consists of:
353 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
354 * until AD_CAL_COMP is ready to output calibration result.
355 * 2.Wait until DA_CAL_CLK is available.
356 * 3.Fetch AD_CAL_COMP_OUT.
357 */
358static int cal_cycle(struct phy_device *phydev, int devad,
359 u32 regnum, u16 mask, u16 cal_val)
360{
361 unsigned long timeout;
362 int reg_val;
363 int ret;
364
365 phy_modify_mmd(phydev, devad, regnum,
366 mask, cal_val);
367 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
368 MTK_PHY_DA_CALIN_FLAG);
369
370 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
371 do{
372 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17B);
373 } while(time_before(jiffies, timeout) && !(reg_val & BIT(0)));
374
375 if(!(reg_val & BIT(0))) {
376 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
377 return -ETIMEDOUT;
378 }
379
380 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17C,
381 MTK_PHY_DA_CALIN_FLAG);
382 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17A) >>
383 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
384 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
385
386 return ret;
387}
388
389static int rext_fill_result(struct phy_device *phydev, u16 *buf)
390{
391 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
392 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
393 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG115,
394 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
395
396 return 0;
397}
398
399static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
400{
401 u16 rext_cal_val[2];
402
403 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
404 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
405 rext_fill_result(phydev, rext_cal_val);
406
407 return 0;
408}
409
410static int rext_cal_sw(struct phy_device *phydev)
411{
412 u8 rg_zcal_ctrl_def;
413 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
414 u8 lower_ret, upper_ret;
415 u16 rext_cal_val[2];
416 int ret;
417
418 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
419 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
420 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
421 MTK_PHY_RG_TXVOS_CALEN);
422 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
423 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
424 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
425 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
426
427 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
428 MTK_PHY_RG_ZCAL_CTRL_MASK;
429 zcal_lower = ZCAL_CTRL_MIN;
430 zcal_upper = ZCAL_CTRL_MAX;
431
432 dev_dbg(&phydev->mdio.dev, "Start REXT SW cal.\n");
433 while((zcal_upper-zcal_lower) > 1) {
434 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
435 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
436 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800437 if(ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800438 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800439 upper_ret = ret;
440 } else if(ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800441 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800442 lower_ret = ret;
443 } else
developerc50c2352021-12-01 10:45:35 +0800444 goto restore;
445 }
446
developer78aa7b92021-12-29 15:22:10 +0800447 if(zcal_lower == ZCAL_CTRL_MIN) {
448 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
449 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
450 } else if(zcal_upper == ZCAL_CTRL_MAX) {
451 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
452 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
453 }
454 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800455 goto restore;
456
457 ret = upper_ret-lower_ret;
458 if (ret == 1) {
459 rext_cal_val[0] = zcal_upper;
460 rext_cal_val[1] = zcal_upper >> 3;
developer78aa7b92021-12-29 15:22:10 +0800461 rext_fill_result(phydev, rext_cal_val);
developerc50c2352021-12-01 10:45:35 +0800462 dev_info(&phydev->mdio.dev, "REXT SW cal result: 0x%x\n", zcal_upper);
463 ret = 0;
464 } else
465 ret = -EINVAL;
466
467restore:
468 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
469 MTK_PHY_ANA_TEST_MODE_MASK);
470 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
471 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN | MTK_PHY_RG_REXT_CALEN);
472 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
473 MTK_PHY_RG_TST_DMY2_MASK);
474 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
475 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
476
477 return ret;
478}
479
480static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
481{
482 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
483 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
484 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG172,
485 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
486 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
487 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
488 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG173,
489 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
490
491 return 0;
492}
493
494static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
495{
496 u16 tx_offset_cal_val[4];
497
498 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
499 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
500 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
501 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
502
503 tx_offset_fill_result(phydev, tx_offset_cal_val);
504
505 return 0;
506}
507
508static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
509{
developerd2ec38e2022-11-27 01:15:29 +0800510 int i;
developer87c89d12022-08-19 17:46:34 +0800511 int bias[16] = {0};
512 switch(phydev->drv->phy_id) {
513 case 0x03a29461:
514 {
developerd2ec38e2022-11-27 01:15:29 +0800515 /* We add some calibration to efuse values
516 * due to board level influence.
developer87c89d12022-08-19 17:46:34 +0800517 * GBE: +7, TBT: +1, HBT: +4, TST: +7
518 */
519 int tmp[16] = { 7, 1, 4, 7,
520 7, 1, 4, 7,
521 7, 1, 4, 7,
522 7, 1, 4, 7 };
523 memcpy(bias, (const void *)tmp, sizeof(bias));
524 break;
525 }
526 case 0x03a29481:
527 {
528 int tmp[16] = { 10, 6, 6, 10,
529 10, 6, 6, 10,
530 10, 6, 6, 10,
531 10, 6, 6, 10 };
532 memcpy(bias, (const void *)tmp, sizeof(bias));
533 break;
534 }
535 default:
536 break;
537 }
developerd2ec38e2022-11-27 01:15:29 +0800538
539 for (i = 0; i < 12; i += 4) {
540 if (likely(buf[i>>2] + bias[i] >= 32)) {
541 bias[i] -= 13;
542 } else {
543 phy_modify_mmd(phydev, MDIO_MMD_VEND1, 0x5c,
544 0xf << (12-i), 0x6 << (12-i));
545 bias[i+1] += 13;
546 bias[i+2] += 13;
547 bias[i+3] += 13;
548 }
549 }
550
developerc50c2352021-12-01 10:45:35 +0800551 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800552 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800553 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800554 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800555 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800556 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800557 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800558 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800559
560 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800561 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800562 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800563 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800564 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800565 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800566 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800567 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800568
569 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800570 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800571 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800572 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800573 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800574 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800575 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800576 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800577
578 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800579 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800580 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800581 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800582 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800583 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800584 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800585 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800586
587 return 0;
588}
589
590static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
591{
592 u16 tx_amp_cal_val[4];
593
594 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
595 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
596 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
597 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
598 tx_amp_fill_result(phydev, tx_amp_cal_val);
599
600 return 0;
601}
602
603static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
604 phy_cal_pair_t txg_calen_x)
605{
developer87c89d12022-08-19 17:46:34 +0800606 int bias[4] = {0};
607 switch(phydev->drv->phy_id) {
608 case 0x03a29481:
609 {
developerec2b8552022-10-17 15:30:59 +0800610 int tmp[16] = { -1, -1, -1, -1 };
developer87c89d12022-08-19 17:46:34 +0800611 memcpy(bias, (const void *)tmp, sizeof(bias));
612 break;
613 }
614 /* 0x03a29461 enters default case */
615 default:
616 break;
617 }
618
developerc50c2352021-12-01 10:45:35 +0800619 switch(txg_calen_x) {
620 case PAIR_A:
621 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800622 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800623 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800624 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800625 break;
626 case PAIR_B:
627 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800628 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800629 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800630 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800631 break;
632 case PAIR_C:
633 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800634 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800635 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800636 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800637 break;
638 case PAIR_D:
639 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800640 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800641 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800642 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800643 break;
644 }
645 return 0;
646}
647
648static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
649 phy_cal_pair_t txg_calen_x)
650{
651 u16 tx_r50_cal_val[1];
652
653 switch(txg_calen_x) {
654 case PAIR_A:
655 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
656 break;
657 case PAIR_B:
658 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
659 break;
660 case PAIR_C:
661 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
662 break;
663 case PAIR_D:
664 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
665 break;
666 }
667 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
668
669 return 0;
670}
671
672static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
673{
674 u8 rg_zcal_ctrl_def;
675 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
676 u8 lower_ret, upper_ret;
677 u16 tx_r50_cal_val[1];
678 int ret;
679
680 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
681 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
682 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
683 MTK_PHY_RG_TXVOS_CALEN);
684 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
685 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
686 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
687 BIT(txg_calen_x * 4));
688 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
689 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
690
691 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
692 MTK_PHY_RG_ZCAL_CTRL_MASK;
693 zcal_lower = ZCAL_CTRL_MIN;
694 zcal_upper = ZCAL_CTRL_MAX;
695
developer02d84422021-12-24 11:48:07 +0800696 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800697 while((zcal_upper-zcal_lower) > 1) {
698 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
699 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
700 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800701 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800702 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800703 upper_ret = ret;
704 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800705 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800706 lower_ret = ret;
707 } else
developerc50c2352021-12-01 10:45:35 +0800708 goto restore;
709 }
710
developer78aa7b92021-12-29 15:22:10 +0800711 if(zcal_lower == ZCAL_CTRL_MIN) {
712 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800713 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800714 } else if(zcal_upper == ZCAL_CTRL_MAX) {
715 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800716 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800717 }
718 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800719 goto restore;
720
721 ret = upper_ret-lower_ret;
722 if (ret == 1) {
723 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
724 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800725 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800726 pair[txg_calen_x], zcal_lower);
727 ret = 0;
728 } else
729 ret = -EINVAL;
730
731restore:
732 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
733 MTK_PHY_ANA_TEST_MODE_MASK);
734 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
735 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
736 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
737 BIT(txg_calen_x * 4));
738 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
739 MTK_PHY_RG_TST_DMY2_MASK);
740 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
741 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
742
743 return ret;
744}
745
746static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
747{
748 u8 lower_idx, upper_idx, txreserve_val;
749 u8 lower_ret, upper_ret;
750 int ret;
751
752 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
753 MTK_PHY_RG_ANA_CALEN);
754 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
755 MTK_PHY_RG_CAL_CKINV);
756 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
757 MTK_PHY_RG_TXVOS_CALEN);
758
759 switch(rg_txreserve_x) {
760 case PAIR_A:
761 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
762 MTK_PHY_DASN_DAC_IN0_A_MASK);
763 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
764 MTK_PHY_DASN_DAC_IN1_A_MASK);
765 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
766 MTK_PHY_RG_ZCALEN_A);
767 break;
768 case PAIR_B:
769 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
770 MTK_PHY_DASN_DAC_IN0_B_MASK);
771 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
772 MTK_PHY_DASN_DAC_IN1_B_MASK);
773 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
774 MTK_PHY_RG_ZCALEN_B);
775 break;
776 case PAIR_C:
777 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
778 MTK_PHY_DASN_DAC_IN0_C_MASK);
779 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
780 MTK_PHY_DASN_DAC_IN1_C_MASK);
781 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
782 MTK_PHY_RG_ZCALEN_C);
783 break;
784 case PAIR_D:
785 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
786 MTK_PHY_DASN_DAC_IN0_D_MASK);
787 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
788 MTK_PHY_DASN_DAC_IN1_D_MASK);
789 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
790 MTK_PHY_RG_ZCALEN_D);
791 break;
792 default:
793 ret = -EINVAL;
794 goto restore;
795 }
796
797 lower_idx = TXRESERVE_MIN;
798 upper_idx = TXRESERVE_MAX;
799
800 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
801 while((upper_idx-lower_idx) > 1) {
802 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
803 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
804 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
805 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
806 txreserve_val << 12 | txreserve_val << 8 |
807 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800808 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800809 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800810 upper_ret = ret;
811 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800812 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800813 lower_ret = ret;
814 } else
developerc50c2352021-12-01 10:45:35 +0800815 goto restore;
816 }
817
developer78aa7b92021-12-29 15:22:10 +0800818 if(lower_idx == TXRESERVE_MIN) {
819 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800820 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
821 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
822 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800823 } else if(upper_idx == TXRESERVE_MAX) {
824 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800825 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
826 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
827 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800828 }
829 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800830 goto restore;
831
developer78aa7b92021-12-29 15:22:10 +0800832 /* We calibrate TX-VCM in different logic. Check upper index and then
833 * lower index. If this calibration is valid, apply lower index's result.
834 */
developerc50c2352021-12-01 10:45:35 +0800835 ret = upper_ret-lower_ret;
836 if (ret == 1) {
837 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800838 /* Make sure we use upper_idx in our calibration system */
839 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
840 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
841 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
842 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800843 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
844 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
845 ret = 0;
846 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
847 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
848 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
849 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
850 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
851 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
852 ret = 0;
853 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
854 } else
855 ret = -EINVAL;
856
857restore:
858 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
859 MTK_PHY_RG_ANA_CALEN);
860 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
861 MTK_PHY_RG_TXVOS_CALEN);
862 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
863 MTK_PHY_RG_ZCALEN_A);
864 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
865 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
866
867 return ret;
868}
869
870static void mtk_gephy_config_init(struct phy_device *phydev)
871{
872 /* Disable EEE */
873 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
874
875 /* Enable HW auto downshift */
876 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
877
878 /* Increase SlvDPSready time */
879 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
880 __phy_write(phydev, 0x10, 0xafae);
881 __phy_write(phydev, 0x12, 0x2f);
882 __phy_write(phydev, 0x10, 0x8fae);
883 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
884
885 /* Adjust 100_mse_threshold */
886 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
887
888 /* Disable mcc */
889 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
890}
891
892static int mt7530_phy_config_init(struct phy_device *phydev)
893{
894 mtk_gephy_config_init(phydev);
895
896 /* Increase post_update_timer */
897 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
898
899 return 0;
900}
901
902static int mt7531_phy_config_init(struct phy_device *phydev)
903{
904 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
905 return -EINVAL;
906
907 mtk_gephy_config_init(phydev);
908
909 /* PHY link down power saving enable */
910 phy_set_bits(phydev, 0x17, BIT(4));
911 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
912
913 /* Set TX Pair delay selection */
914 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
915 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
916
917 return 0;
918}
919
developerf35532c2022-08-05 18:37:26 +0800920static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800921{
developerd2ec38e2022-11-27 01:15:29 +0800922 u32 i;
developer02d84422021-12-24 11:48:07 +0800923 /* 100M eye finetune:
924 * Keep middle level of TX MLT3 shapper as default.
925 * Only change TX MLT3 overshoot level here.
926 */
927 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
928 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
929 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
930 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
931 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
932 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
933 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
934 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800935
developer02d84422021-12-24 11:48:07 +0800936 /* TX-AMP finetune:
937 * 100M +4, 1000M +6 to default value.
938 * If efuse values aren't valid, TX-AMP uses the below values.
939 */
940 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
941 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
942 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
943 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
944 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
945 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
946 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
947 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
developer68f6e102022-11-22 17:35:00 +0800948
developerd2ec38e2022-11-27 01:15:29 +0800949 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
950 /* EnabRandUpdTrig = 1 */
951 __phy_write(phydev, 0x11, 0x2f00);
952 __phy_write(phydev, 0x12, 0xe);
953 __phy_write(phydev, 0x10, 0x8fb0);
954
955 /* SlvDSPreadyTime = 0xc */
956 __phy_write(phydev, 0x11, 0x671);
957 __phy_write(phydev, 0x12, 0xc);
958 __phy_write(phydev, 0x10, 0x8fae);
959
960 /* NormMseLoThresh = 85 */
961 __phy_write(phydev, 0x11, 0x55a0);
962 __phy_write(phydev, 0x12, 0x0);
963 __phy_write(phydev, 0x10, 0x83aa);
964
965 /* InhibitDisableDfeTail1000 = 1 */
966 __phy_write(phydev, 0x11, 0x2b);
967 __phy_write(phydev, 0x12, 0x0);
968 __phy_write(phydev, 0x10, 0x8f80);
969
970 /* SSTr related */
971 __phy_write(phydev, 0x11, 0xbaef);
972 __phy_write(phydev, 0x12, 0x2e);
973 __phy_write(phydev, 0x10, 0x968c);
974
975 /* VcoSlicerThreshBitsHigh */
976 __phy_write(phydev, 0x11, 0x5555);
977 __phy_write(phydev, 0x12, 0x55);
978 __phy_write(phydev, 0x10, 0x8ec0);
979
980 /* ResetSyncOffset = 6 */
981 __phy_write(phydev, 0x11, 0x600);
982 __phy_write(phydev, 0x12, 0x0);
983 __phy_write(phydev, 0x10, 0x8fc0);
984
985 /* VgaDecRate = 1 */
986 __phy_write(phydev, 0x11, 0x4c2a);
987 __phy_write(phydev, 0x12, 0x3e);
988 __phy_write(phydev, 0x10, 0x8fa4);
989
990 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
991
992 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +0800993 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerd2ec38e2022-11-27 01:15:29 +0800994 MTK_PHY_TR_OPEN_LOOP_EN_MASK & MTK_PHY_LPF_X_AVERAGE_MASK,
995 BIT(0) & (0x9 << 4));
996
997 /* rg_tr_lpf_cnt_val = 512 */
998 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
999
1000 /* IIR2 related */
1001 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1002 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1003 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1004 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1005 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1006 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1007 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1008 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1009 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1010 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1011
1012 /* FFE peaking */
1013 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1014 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1015 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1016 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1017
1018 /* TX shape */
1019 /* 10/100/1000 TX shaper is enabled by default */
1020 for (i = 0x202; i < 0x230; i += 2) {
1021 if (i == 0x20c || i == 0x218 || i == 0x224)
1022 continue;
1023 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1024 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1025 }
developer02d84422021-12-24 11:48:07 +08001026}
1027
developerf35532c2022-08-05 18:37:26 +08001028static inline void mt7988_phy_finetune(struct phy_device *phydev)
1029{
1030 int i;
1031 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
1032 0x020d, 0x0206, 0x0384, 0x03d0,
1033 0x03c6, 0x030a, 0x0011, 0x0005};
1034
1035 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
1036 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
1037 }
developer6de96aa2022-09-29 16:46:18 +08001038
developer57374032022-10-11 16:43:24 +08001039 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001040 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001041
1042 /* Disable TX power saving */
1043 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +08001044 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001045
1046 /* Slave mode finetune, Kp=3/Kf=2 */
1047 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
1048 __phy_write(phydev, 0x12, 0x0);
1049 __phy_write(phydev, 0x11, 0x750);
1050 __phy_write(phydev, 0x10, 0x9686);
1051 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerf35532c2022-08-05 18:37:26 +08001052}
1053
1054static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001055{
1056 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +08001057 int i, ret;
1058 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +08001059 u32 *buf;
1060 bool efs_valid = true;
1061 size_t len;
1062 struct nvmem_cell *cell;
1063
1064 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1065 return -EINVAL;
1066
1067 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1068 if (IS_ERR(cell)) {
1069 if (PTR_ERR(cell) == -EPROBE_DEFER)
1070 return PTR_ERR(cell);
1071 return 0;
1072 }
1073
1074 buf = (u32 *)nvmem_cell_read(cell, &len);
1075 if (IS_ERR(buf))
1076 return PTR_ERR(buf);
1077 nvmem_cell_put(cell);
1078
1079 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
1080 efs_valid = false;
1081
1082 if (len < 4 * sizeof(u32)) {
1083 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1084 ret = -EINVAL;
1085 goto out;
1086 }
1087
1088 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1089 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1090 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1091 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
1092 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +08001093 ret = 0;
developerc50c2352021-12-01 10:45:35 +08001094
1095out:
1096 kfree(buf);
1097 return ret;
1098}
1099
developer68f6e102022-11-22 17:35:00 +08001100static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001101{
1102 mt7981_phy_finetune(phydev);
1103
1104 return mt798x_phy_calibration(phydev);
1105}
1106
developer68f6e102022-11-22 17:35:00 +08001107static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001108{
developer23021292022-10-21 19:10:10 +08001109 struct device_node *np;
1110 void __iomem *boottrap;
1111 u32 reg;
1112 int port;
1113
1114 /* Setup LED polarity according to boottrap's polarity */
1115 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1116 if (!np)
1117 return -ENOENT;
1118 boottrap = of_iomap(np, 0);
1119 if (!boottrap)
1120 return -ENOMEM;
1121 reg = readl(boottrap);
1122 port = phydev->mdio.addr;
1123 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1124 (port == GPHY_PORT1 && reg & BIT(9)) ||
1125 (port == GPHY_PORT2 && reg & BIT(10)) ||
1126 (port == GPHY_PORT3 && reg & BIT(11))) {
1127 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1128 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1129 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1130 } else {
1131 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1132 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1133 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1134 MTK_PHY_LED0_ON_LINK1000);
1135 }
developer8bc5dca2022-10-24 17:15:12 +08001136 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1137 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1138 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1139 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001140
developerf35532c2022-08-05 18:37:26 +08001141 mt7988_phy_finetune(phydev);
1142
1143 return mt798x_phy_calibration(phydev);
1144}
1145
developerc50c2352021-12-01 10:45:35 +08001146static struct phy_driver mtk_gephy_driver[] = {
1147#if 0
1148 {
1149 PHY_ID_MATCH_EXACT(0x03a29412),
1150 .name = "MediaTek MT7530 PHY",
1151 .config_init = mt7530_phy_config_init,
1152 /* Interrupts are handled by the switch, not the PHY
1153 * itself.
1154 */
1155 .config_intr = genphy_no_config_intr,
1156 .handle_interrupt = genphy_no_ack_interrupt,
1157 .suspend = genphy_suspend,
1158 .resume = genphy_resume,
1159 .read_page = mtk_gephy_read_page,
1160 .write_page = mtk_gephy_write_page,
1161 },
1162 {
1163 PHY_ID_MATCH_EXACT(0x03a29441),
1164 .name = "MediaTek MT7531 PHY",
1165 .config_init = mt7531_phy_config_init,
1166 /* Interrupts are handled by the switch, not the PHY
1167 * itself.
1168 */
1169 .config_intr = genphy_no_config_intr,
1170 .handle_interrupt = genphy_no_ack_interrupt,
1171 .suspend = genphy_suspend,
1172 .resume = genphy_resume,
1173 .read_page = mtk_gephy_read_page,
1174 .write_page = mtk_gephy_write_page,
1175 },
1176#endif
1177 {
1178 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001179 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001180 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001181 /* Interrupts are handled by the switch, not the PHY
1182 * itself.
1183 */
1184 .config_intr = genphy_no_config_intr,
1185 .handle_interrupt = genphy_no_ack_interrupt,
1186 .suspend = genphy_suspend,
1187 .resume = genphy_resume,
1188 .read_page = mtk_gephy_read_page,
1189 .write_page = mtk_gephy_write_page,
1190 },
1191 {
1192 PHY_ID_MATCH_EXACT(0x03a29481),
1193 .name = "MediaTek MT7988 PHY",
1194 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001195 /* Interrupts are handled by the switch, not the PHY
1196 * itself.
1197 */
1198 .config_intr = genphy_no_config_intr,
1199 .handle_interrupt = genphy_no_ack_interrupt,
1200 .suspend = genphy_suspend,
1201 .resume = genphy_resume,
1202 .read_page = mtk_gephy_read_page,
1203 .write_page = mtk_gephy_write_page,
1204 },
1205};
1206
1207module_phy_driver(mtk_gephy_driver);
1208
1209static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1210 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1211 { }
1212};
1213
1214MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1215MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1216MODULE_LICENSE("GPL");
1217
1218MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);