blob: a833c2a17e284c330dfbdbb79d0db6d497f511af [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
developerdc3e9502022-12-02 18:10:42 +0800551 /* Prevent overflow */
552 for (i = 0; i < 12; i++) {
553 if (buf[i>>2] + bias[i] > 63) {
554 buf[i>>2] = 63;
555 bias[i] = 0;
556 } else if (buf[i>>2] + bias[i] < 0) {
557 /* Bias caused by board design may change in the future.
558 * So check negative cases, too.
559 */
560 buf[i>>2] = 0;
561 bias[i] = 0;
562 }
563 }
564
developerc50c2352021-12-01 10:45:35 +0800565 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800566 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800567 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800568 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800569 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800570 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800571 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800572 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800573
574 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800575 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800576 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800577 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800578 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800579 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800580 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800581 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800582
583 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800584 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800585 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800586 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800587 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800588 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800589 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800590 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800591
592 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800593 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800594 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800595 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800596 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800597 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800598 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800599 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800600
601 return 0;
602}
603
604static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
605{
606 u16 tx_amp_cal_val[4];
607
608 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
609 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
610 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
611 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
612 tx_amp_fill_result(phydev, tx_amp_cal_val);
613
614 return 0;
615}
616
617static int tx_r50_fill_result(struct phy_device *phydev, u16 *buf,
618 phy_cal_pair_t txg_calen_x)
619{
developer87c89d12022-08-19 17:46:34 +0800620 int bias[4] = {0};
developerdc3e9502022-12-02 18:10:42 +0800621 int i;
developer87c89d12022-08-19 17:46:34 +0800622 switch(phydev->drv->phy_id) {
623 case 0x03a29481:
624 {
developerec2b8552022-10-17 15:30:59 +0800625 int tmp[16] = { -1, -1, -1, -1 };
developer87c89d12022-08-19 17:46:34 +0800626 memcpy(bias, (const void *)tmp, sizeof(bias));
627 break;
628 }
629 /* 0x03a29461 enters default case */
630 default:
631 break;
632 }
633
developerdc3e9502022-12-02 18:10:42 +0800634 for (i = 0; i < 4; i++) {
635 if (buf[i>>2] + bias[i] > 63) {
636 buf[i>>2] = 63;
637 bias[i] = 0;
638 } else if (buf[i>>2] + bias[i] < 0) {
639 buf[i>>2] = 0;
640 bias[i] = 0;
641 }
642 }
developerc50c2352021-12-01 10:45:35 +0800643 switch(txg_calen_x) {
644 case PAIR_A:
645 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800646 MTK_PHY_DA_TX_R50_A_NORMAL_MASK, (buf[0] + bias[0]) << 8);
developerc50c2352021-12-01 10:45:35 +0800647 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53D,
developer87c89d12022-08-19 17:46:34 +0800648 MTK_PHY_DA_TX_R50_A_TBT_MASK, (buf[0]) + bias[0]);
developerc50c2352021-12-01 10:45:35 +0800649 break;
650 case PAIR_B:
651 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800652 MTK_PHY_DA_TX_R50_B_NORMAL_MASK, (buf[0] + bias[1])<< 8);
developerc50c2352021-12-01 10:45:35 +0800653 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53E,
developer87c89d12022-08-19 17:46:34 +0800654 MTK_PHY_DA_TX_R50_B_TBT_MASK, (buf[0] + bias[1]));
developerc50c2352021-12-01 10:45:35 +0800655 break;
656 case PAIR_C:
657 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800658 MTK_PHY_DA_TX_R50_C_NORMAL_MASK, (buf[0] + bias[2])<< 8);
developerc50c2352021-12-01 10:45:35 +0800659 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG53F,
developer87c89d12022-08-19 17:46:34 +0800660 MTK_PHY_DA_TX_R50_C_TBT_MASK, (buf[0] + bias[2]));
developerc50c2352021-12-01 10:45:35 +0800661 break;
662 case PAIR_D:
663 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800664 MTK_PHY_DA_TX_R50_D_NORMAL_MASK, (buf[0] + bias[3])<< 8);
developerc50c2352021-12-01 10:45:35 +0800665 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG540,
developer87c89d12022-08-19 17:46:34 +0800666 MTK_PHY_DA_TX_R50_D_TBT_MASK, (buf[0] + bias[3]));
developerc50c2352021-12-01 10:45:35 +0800667 break;
668 }
669 return 0;
670}
671
672static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
673 phy_cal_pair_t txg_calen_x)
674{
675 u16 tx_r50_cal_val[1];
676
677 switch(txg_calen_x) {
678 case PAIR_A:
679 tx_r50_cal_val[0] = EFS_DA_TX_R50_A(buf[1]);
680 break;
681 case PAIR_B:
682 tx_r50_cal_val[0] = EFS_DA_TX_R50_B(buf[1]);
683 break;
684 case PAIR_C:
685 tx_r50_cal_val[0] = EFS_DA_TX_R50_C(buf[2]);
686 break;
687 case PAIR_D:
688 tx_r50_cal_val[0] = EFS_DA_TX_R50_D(buf[2]);
689 break;
690 }
691 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
692
693 return 0;
694}
695
696static int tx_r50_cal_sw(struct phy_device *phydev, phy_cal_pair_t txg_calen_x)
697{
698 u8 rg_zcal_ctrl_def;
699 u8 zcal_lower, zcal_upper, rg_zcal_ctrl;
700 u8 lower_ret, upper_ret;
701 u16 tx_r50_cal_val[1];
702 int ret;
703
704 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
705 MTK_PHY_ANA_TEST_MODE_MASK, MTK_PHY_TANA_CAL_MODE << 8);
706 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
707 MTK_PHY_RG_TXVOS_CALEN);
708 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
709 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
710 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
711 BIT(txg_calen_x * 4));
712 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
713 MTK_PHY_RG_TST_DMY2_MASK, 0x1);
714
715 rg_zcal_ctrl_def = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5) &
716 MTK_PHY_RG_ZCAL_CTRL_MASK;
717 zcal_lower = ZCAL_CTRL_MIN;
718 zcal_upper = ZCAL_CTRL_MAX;
719
developer02d84422021-12-24 11:48:07 +0800720 dev_dbg(&phydev->mdio.dev, "Start TX-R50 Pair%c SW cal.\n", pair[txg_calen_x]);
developerc50c2352021-12-01 10:45:35 +0800721 while((zcal_upper-zcal_lower) > 1) {
722 rg_zcal_ctrl = DIV_ROUND_CLOSEST(zcal_lower+zcal_upper, 2);
723 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
724 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl);
developer78aa7b92021-12-29 15:22:10 +0800725 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800726 zcal_upper = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800727 upper_ret = ret;
728 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800729 zcal_lower = rg_zcal_ctrl;
developer78aa7b92021-12-29 15:22:10 +0800730 lower_ret = ret;
731 } else
developerc50c2352021-12-01 10:45:35 +0800732 goto restore;
733 }
734
developer78aa7b92021-12-29 15:22:10 +0800735 if(zcal_lower == ZCAL_CTRL_MIN) {
736 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800737 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_lower);
developer78aa7b92021-12-29 15:22:10 +0800738 } else if(zcal_upper == ZCAL_CTRL_MAX) {
739 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developerc50c2352021-12-01 10:45:35 +0800740 MTK_PHY_RG_ZCAL_CTRL_MASK, zcal_upper);
developer78aa7b92021-12-29 15:22:10 +0800741 }
742 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800743 goto restore;
744
745 ret = upper_ret-lower_ret;
746 if (ret == 1) {
747 tx_r50_cal_val[0] = mt798x_zcal_to_r50[zcal_upper];
748 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
developer02d84422021-12-24 11:48:07 +0800749 dev_info(&phydev->mdio.dev, "TX-R50 Pair%c SW cal result: 0x%x\n",
developerc50c2352021-12-01 10:45:35 +0800750 pair[txg_calen_x], zcal_lower);
751 ret = 0;
752 } else
753 ret = -EINVAL;
754
755restore:
756 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_ANA_TEST_BUS_CTRL_RG,
757 MTK_PHY_ANA_TEST_MODE_MASK);
758 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
759 MTK_PHY_RG_CAL_CKINV | MTK_PHY_RG_ANA_CALEN);
760 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG2,
761 BIT(txg_calen_x * 4));
762 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_DEV1F_REG110,
763 MTK_PHY_RG_TST_DMY2_MASK);
764 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
765 MTK_PHY_RG_ZCAL_CTRL_MASK, rg_zcal_ctrl_def);
766
767 return ret;
768}
769
770static int tx_vcm_cal_sw(struct phy_device *phydev, phy_cal_pair_t rg_txreserve_x)
771{
772 u8 lower_idx, upper_idx, txreserve_val;
773 u8 lower_ret, upper_ret;
774 int ret;
775
776 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
777 MTK_PHY_RG_ANA_CALEN);
778 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
779 MTK_PHY_RG_CAL_CKINV);
780 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
781 MTK_PHY_RG_TXVOS_CALEN);
782
783 switch(rg_txreserve_x) {
784 case PAIR_A:
785 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17D,
786 MTK_PHY_DASN_DAC_IN0_A_MASK);
787 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG181,
788 MTK_PHY_DASN_DAC_IN1_A_MASK);
789 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
790 MTK_PHY_RG_ZCALEN_A);
791 break;
792 case PAIR_B:
793 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17E,
794 MTK_PHY_DASN_DAC_IN0_B_MASK);
795 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG182,
796 MTK_PHY_DASN_DAC_IN1_B_MASK);
797 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
798 MTK_PHY_RG_ZCALEN_B);
799 break;
800 case PAIR_C:
801 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG17F,
802 MTK_PHY_DASN_DAC_IN0_C_MASK);
803 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG183,
804 MTK_PHY_DASN_DAC_IN1_C_MASK);
805 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
806 MTK_PHY_RG_ZCALEN_C);
807 break;
808 case PAIR_D:
809 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG180,
810 MTK_PHY_DASN_DAC_IN0_D_MASK);
811 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG184,
812 MTK_PHY_DASN_DAC_IN1_D_MASK);
813 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
814 MTK_PHY_RG_ZCALEN_D);
815 break;
816 default:
817 ret = -EINVAL;
818 goto restore;
819 }
820
821 lower_idx = TXRESERVE_MIN;
822 upper_idx = TXRESERVE_MAX;
823
824 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
825 while((upper_idx-lower_idx) > 1) {
826 txreserve_val = DIV_ROUND_CLOSEST(lower_idx+upper_idx, 2);
827 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
828 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
829 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
830 txreserve_val << 12 | txreserve_val << 8 |
831 txreserve_val << 4 | txreserve_val);
developer78aa7b92021-12-29 15:22:10 +0800832 if(ret==1) {
developerc50c2352021-12-01 10:45:35 +0800833 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800834 upper_ret = ret;
835 } else if(ret==0) {
developerc50c2352021-12-01 10:45:35 +0800836 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800837 lower_ret = ret;
838 } else
developerc50c2352021-12-01 10:45:35 +0800839 goto restore;
840 }
841
developer78aa7b92021-12-29 15:22:10 +0800842 if(lower_idx == TXRESERVE_MIN) {
843 ret = lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800844 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
845 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
846 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
developer78aa7b92021-12-29 15:22:10 +0800847 } else if(upper_idx == TXRESERVE_MAX) {
848 ret = upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developerc50c2352021-12-01 10:45:35 +0800849 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
850 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
851 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developer78aa7b92021-12-29 15:22:10 +0800852 }
853 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800854 goto restore;
855
developer78aa7b92021-12-29 15:22:10 +0800856 /* We calibrate TX-VCM in different logic. Check upper index and then
857 * lower index. If this calibration is valid, apply lower index's result.
858 */
developerc50c2352021-12-01 10:45:35 +0800859 ret = upper_ret-lower_ret;
860 if (ret == 1) {
861 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800862 /* Make sure we use upper_idx in our calibration system */
863 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
864 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
865 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
866 upper_idx << 12 | upper_idx << 8 | upper_idx << 4 | upper_idx);
developerc50c2352021-12-01 10:45:35 +0800867 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n", upper_idx);
868 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 && lower_ret == 1) {
869 ret = 0;
870 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
871 MTK_PHY_DA_RX_PSBN_TBT_MASK | MTK_PHY_DA_RX_PSBN_HBT_MASK |
872 MTK_PHY_DA_RX_PSBN_GBE_MASK | MTK_PHY_DA_RX_PSBN_LP_MASK,
873 lower_idx << 12 | lower_idx << 8 | lower_idx << 4 | lower_idx);
874 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at low margin 0x%x\n", lower_idx);
875 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 && lower_ret == 0) {
876 ret = 0;
877 dev_warn(&phydev->mdio.dev, "TX-VCM SW cal result at high margin 0x%x\n", upper_idx);
878 } else
879 ret = -EINVAL;
880
881restore:
882 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
883 MTK_PHY_RG_ANA_CALEN);
884 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
885 MTK_PHY_RG_TXVOS_CALEN);
886 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
887 MTK_PHY_RG_ZCALEN_A);
888 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
889 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C | MTK_PHY_RG_ZCALEN_D);
890
891 return ret;
892}
893
894static void mtk_gephy_config_init(struct phy_device *phydev)
895{
896 /* Disable EEE */
897 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
898
899 /* Enable HW auto downshift */
900 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
901
902 /* Increase SlvDPSready time */
903 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
904 __phy_write(phydev, 0x10, 0xafae);
905 __phy_write(phydev, 0x12, 0x2f);
906 __phy_write(phydev, 0x10, 0x8fae);
907 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
908
909 /* Adjust 100_mse_threshold */
910 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
911
912 /* Disable mcc */
913 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
914}
915
916static int mt7530_phy_config_init(struct phy_device *phydev)
917{
918 mtk_gephy_config_init(phydev);
919
920 /* Increase post_update_timer */
921 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
922
923 return 0;
924}
925
926static int mt7531_phy_config_init(struct phy_device *phydev)
927{
928 if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
929 return -EINVAL;
930
931 mtk_gephy_config_init(phydev);
932
933 /* PHY link down power saving enable */
934 phy_set_bits(phydev, 0x17, BIT(4));
935 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
936
937 /* Set TX Pair delay selection */
938 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
939 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
940
941 return 0;
942}
943
developerf35532c2022-08-05 18:37:26 +0800944static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800945{
developerd2ec38e2022-11-27 01:15:29 +0800946 u32 i;
developer02d84422021-12-24 11:48:07 +0800947 /* 100M eye finetune:
948 * Keep middle level of TX MLT3 shapper as default.
949 * Only change TX MLT3 overshoot level here.
950 */
951 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1, 0x1ce);
952 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1, 0x1c1);
953 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0, 0x20f);
954 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0, 0x202);
955 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1, 0x3d0);
956 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1, 0x3c0);
957 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0, 0x13);
958 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0, 0x5);
developerf35532c2022-08-05 18:37:26 +0800959
developer02d84422021-12-24 11:48:07 +0800960 /* TX-AMP finetune:
961 * 100M +4, 1000M +6 to default value.
962 * If efuse values aren't valid, TX-AMP uses the below values.
963 */
964 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
965 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2, 0x9026);
966 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1, 0x2624);
967 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2, 0x2426);
968 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1, 0x2624);
969 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2, 0x2426);
970 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1, 0x2624);
971 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2, 0x2426);
developer68f6e102022-11-22 17:35:00 +0800972
developerd2ec38e2022-11-27 01:15:29 +0800973 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
974 /* EnabRandUpdTrig = 1 */
975 __phy_write(phydev, 0x11, 0x2f00);
976 __phy_write(phydev, 0x12, 0xe);
977 __phy_write(phydev, 0x10, 0x8fb0);
978
979 /* SlvDSPreadyTime = 0xc */
980 __phy_write(phydev, 0x11, 0x671);
981 __phy_write(phydev, 0x12, 0xc);
982 __phy_write(phydev, 0x10, 0x8fae);
983
984 /* NormMseLoThresh = 85 */
985 __phy_write(phydev, 0x11, 0x55a0);
986 __phy_write(phydev, 0x12, 0x0);
987 __phy_write(phydev, 0x10, 0x83aa);
988
989 /* InhibitDisableDfeTail1000 = 1 */
990 __phy_write(phydev, 0x11, 0x2b);
991 __phy_write(phydev, 0x12, 0x0);
992 __phy_write(phydev, 0x10, 0x8f80);
993
994 /* SSTr related */
995 __phy_write(phydev, 0x11, 0xbaef);
996 __phy_write(phydev, 0x12, 0x2e);
997 __phy_write(phydev, 0x10, 0x968c);
998
999 /* VcoSlicerThreshBitsHigh */
1000 __phy_write(phydev, 0x11, 0x5555);
1001 __phy_write(phydev, 0x12, 0x55);
1002 __phy_write(phydev, 0x10, 0x8ec0);
1003
1004 /* ResetSyncOffset = 6 */
1005 __phy_write(phydev, 0x11, 0x600);
1006 __phy_write(phydev, 0x12, 0x0);
1007 __phy_write(phydev, 0x10, 0x8fc0);
1008
1009 /* VgaDecRate = 1 */
1010 __phy_write(phydev, 0x11, 0x4c2a);
1011 __phy_write(phydev, 0x12, 0x3e);
1012 __phy_write(phydev, 0x10, 0x8fa4);
1013
1014 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
1015
1016 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +08001017 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developerd2ec38e2022-11-27 01:15:29 +08001018 MTK_PHY_TR_OPEN_LOOP_EN_MASK & MTK_PHY_LPF_X_AVERAGE_MASK,
1019 BIT(0) & (0x9 << 4));
1020
1021 /* rg_tr_lpf_cnt_val = 512 */
1022 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
1023
1024 /* IIR2 related */
1025 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
1026 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
1027 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
1028 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
1029 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
1030 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
1031 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
1032 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
1033 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
1034 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
1035
1036 /* FFE peaking */
1037 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
1038 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
1039 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
1040 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
1041
1042 /* TX shape */
1043 /* 10/100/1000 TX shaper is enabled by default */
1044 for (i = 0x202; i < 0x230; i += 2) {
1045 if (i == 0x20c || i == 0x218 || i == 0x224)
1046 continue;
1047 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
1048 phy_write_mmd(phydev, MDIO_MMD_VEND2, i+1, 0x23);
1049 }
developer02d84422021-12-24 11:48:07 +08001050}
1051
developerf35532c2022-08-05 18:37:26 +08001052static inline void mt7988_phy_finetune(struct phy_device *phydev)
1053{
1054 int i;
1055 u16 val[12] = {0x0187, 0x01cd, 0x01c8, 0x0182,
1056 0x020d, 0x0206, 0x0384, 0x03d0,
1057 0x03c6, 0x030a, 0x0011, 0x0005};
1058
1059 for(i=0; i<MTK_PHY_TX_MLT3_END; i++) {
1060 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
1061 }
developer6de96aa2022-09-29 16:46:18 +08001062
developer57374032022-10-11 16:43:24 +08001063 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +08001064 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +08001065
1066 /* Disable TX power saving */
1067 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developerd1ea1152022-10-13 18:24:48 +08001068 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +08001069
1070 /* Slave mode finetune, Kp=3/Kf=2 */
1071 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
1072 __phy_write(phydev, 0x12, 0x0);
1073 __phy_write(phydev, 0x11, 0x750);
1074 __phy_write(phydev, 0x10, 0x9686);
1075 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerf35532c2022-08-05 18:37:26 +08001076}
1077
1078static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001079{
1080 const char *cal_mode_from_dts;
developerf35532c2022-08-05 18:37:26 +08001081 int i, ret;
1082 int cal_ret = 0;
developerc50c2352021-12-01 10:45:35 +08001083 u32 *buf;
1084 bool efs_valid = true;
1085 size_t len;
1086 struct nvmem_cell *cell;
1087
1088 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1089 return -EINVAL;
1090
1091 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1092 if (IS_ERR(cell)) {
1093 if (PTR_ERR(cell) == -EPROBE_DEFER)
1094 return PTR_ERR(cell);
1095 return 0;
1096 }
1097
1098 buf = (u32 *)nvmem_cell_read(cell, &len);
1099 if (IS_ERR(buf))
1100 return PTR_ERR(buf);
1101 nvmem_cell_put(cell);
1102
1103 if(!buf[0] && !buf[1] && !buf[2] && !buf[3])
1104 efs_valid = false;
1105
1106 if (len < 4 * sizeof(u32)) {
1107 dev_err(&phydev->mdio.dev, "invalid calibration data\n");
1108 ret = -EINVAL;
1109 goto out;
1110 }
1111
1112 CAL_FLOW(rext, SW_EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1113 CAL_FLOW(tx_offset, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1114 CAL_FLOW(tx_amp, EFUSE, cal_mode_from_dts, NO_PAIR, buf)
1115 CAL_FLOW(tx_r50, SW_EFUSE, cal_mode_from_dts, PAIR_A_TO_D, buf)
1116 CAL_FLOW(tx_vcm, SW, cal_mode_from_dts, PAIR_A_TO_A)
developer6bd23712021-12-02 18:02:39 +08001117 ret = 0;
developerc50c2352021-12-01 10:45:35 +08001118
1119out:
1120 kfree(buf);
1121 return ret;
1122}
1123
developer68f6e102022-11-22 17:35:00 +08001124static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001125{
1126 mt7981_phy_finetune(phydev);
1127
1128 return mt798x_phy_calibration(phydev);
1129}
1130
developer68f6e102022-11-22 17:35:00 +08001131static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001132{
developer23021292022-10-21 19:10:10 +08001133 struct device_node *np;
1134 void __iomem *boottrap;
1135 u32 reg;
1136 int port;
1137
1138 /* Setup LED polarity according to boottrap's polarity */
1139 np = of_find_compatible_node(NULL, NULL, "mediatek,boottrap");
1140 if (!np)
1141 return -ENOENT;
1142 boottrap = of_iomap(np, 0);
1143 if (!boottrap)
1144 return -ENOMEM;
1145 reg = readl(boottrap);
1146 port = phydev->mdio.addr;
1147 if ((port == GPHY_PORT0 && reg & BIT(8)) ||
1148 (port == GPHY_PORT1 && reg & BIT(9)) ||
1149 (port == GPHY_PORT2 && reg & BIT(10)) ||
1150 (port == GPHY_PORT3 && reg & BIT(11))) {
1151 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1152 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_ON_LINK10 |
1153 MTK_PHY_LED0_ON_LINK100 | MTK_PHY_LED0_ON_LINK1000);
1154 } else {
1155 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
1156 MTK_PHY_LED0_ENABLE | MTK_PHY_LED0_POLARITY |
1157 MTK_PHY_LED0_ON_LINK10 | MTK_PHY_LED0_ON_LINK100 |
1158 MTK_PHY_LED0_ON_LINK1000);
1159 }
developer8bc5dca2022-10-24 17:15:12 +08001160 phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
1161 MTK_PHY_LED0_1000TX | MTK_PHY_LED0_1000RX |
1162 MTK_PHY_LED0_100TX | MTK_PHY_LED0_100RX |
1163 MTK_PHY_LED0_10TX | MTK_PHY_LED0_10RX);
developer23021292022-10-21 19:10:10 +08001164
developerf35532c2022-08-05 18:37:26 +08001165 mt7988_phy_finetune(phydev);
1166
1167 return mt798x_phy_calibration(phydev);
1168}
1169
developerc50c2352021-12-01 10:45:35 +08001170static struct phy_driver mtk_gephy_driver[] = {
1171#if 0
1172 {
1173 PHY_ID_MATCH_EXACT(0x03a29412),
1174 .name = "MediaTek MT7530 PHY",
1175 .config_init = mt7530_phy_config_init,
1176 /* Interrupts are handled by the switch, not the PHY
1177 * itself.
1178 */
1179 .config_intr = genphy_no_config_intr,
1180 .handle_interrupt = genphy_no_ack_interrupt,
1181 .suspend = genphy_suspend,
1182 .resume = genphy_resume,
1183 .read_page = mtk_gephy_read_page,
1184 .write_page = mtk_gephy_write_page,
1185 },
1186 {
1187 PHY_ID_MATCH_EXACT(0x03a29441),
1188 .name = "MediaTek MT7531 PHY",
1189 .config_init = mt7531_phy_config_init,
1190 /* Interrupts are handled by the switch, not the PHY
1191 * itself.
1192 */
1193 .config_intr = genphy_no_config_intr,
1194 .handle_interrupt = genphy_no_ack_interrupt,
1195 .suspend = genphy_suspend,
1196 .resume = genphy_resume,
1197 .read_page = mtk_gephy_read_page,
1198 .write_page = mtk_gephy_write_page,
1199 },
1200#endif
1201 {
1202 PHY_ID_MATCH_EXACT(0x03a29461),
developerf35532c2022-08-05 18:37:26 +08001203 .name = "MediaTek MT7981 PHY",
developer68f6e102022-11-22 17:35:00 +08001204 .probe = mt7981_phy_probe,
developerf35532c2022-08-05 18:37:26 +08001205 /* Interrupts are handled by the switch, not the PHY
1206 * itself.
1207 */
1208 .config_intr = genphy_no_config_intr,
1209 .handle_interrupt = genphy_no_ack_interrupt,
1210 .suspend = genphy_suspend,
1211 .resume = genphy_resume,
1212 .read_page = mtk_gephy_read_page,
1213 .write_page = mtk_gephy_write_page,
1214 },
1215 {
1216 PHY_ID_MATCH_EXACT(0x03a29481),
1217 .name = "MediaTek MT7988 PHY",
1218 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001219 /* Interrupts are handled by the switch, not the PHY
1220 * itself.
1221 */
1222 .config_intr = genphy_no_config_intr,
1223 .handle_interrupt = genphy_no_ack_interrupt,
1224 .suspend = genphy_suspend,
1225 .resume = genphy_resume,
1226 .read_page = mtk_gephy_read_page,
1227 .write_page = mtk_gephy_write_page,
1228 },
1229};
1230
1231module_phy_driver(mtk_gephy_driver);
1232
1233static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1234 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1235 { }
1236};
1237
1238MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
1239MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1240MODULE_LICENSE("GPL");
1241
1242MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);