blob: 5520b37a7c2e5ebefe7360ed27606e22a977e8ef [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
developer043f7b92023-03-13 13:57:36 +08009#define MTK_GPHY_ID_MT7530 0x03a29412
10#define MTK_GPHY_ID_MT7531 0x03a29441
11#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
12#define MTK_GPHY_ID_MT7981 0x03a29461
13#define MTK_GPHY_ID_MT7988 0x03a29481
14#endif
15
developerc50c2352021-12-01 10:45:35 +080016#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
developer2149cd92023-03-10 19:01:41 +080024#define ANALOG_INTERNAL_OPERATION_MAX_US (20)
25#define ZCAL_CTRL_MIN (0)
26#define ZCAL_CTRL_MAX (63)
27#define TXRESERVE_MIN (0)
28#define TXRESERVE_MAX (7)
29
30#define MTK_PHY_ANARG_RG (0x10)
31#define MTK_PHY_TCLKOFFSET_MASK GENMASK(12, 8)
32
developerc50c2352021-12-01 10:45:35 +080033/* Registers on MDIO_MMD_VEND1 */
developer87c89d12022-08-19 17:46:34 +080034enum {
developerf35532c2022-08-05 18:37:26 +080035 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TO1 = 0,
36 MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
37 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
38 MTK_PHY_MIDDLE_LEVEL_SHAPPER_1TO0,
39 MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
40 MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
41 MTK_PHY_MIDDLE_LEVEL_SHAPPER_0TON1, /* N means negative */
42 MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
43 MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
44 MTK_PHY_MIDDLE_LEVEL_SHAPPER_N1TO0,
45 MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
46 MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
47 MTK_PHY_TX_MLT3_END,
48};
developer02d84422021-12-24 11:48:07 +080049
developer2149cd92023-03-10 19:01:41 +080050#define MTK_PHY_TXVLD_DA_RG (0x12)
developerc50c2352021-12-01 10:45:35 +080051#define MTK_PHY_DA_TX_I2MPB_A_GBE_MASK GENMASK(15, 10)
52#define MTK_PHY_DA_TX_I2MPB_A_TBT_MASK GENMASK(5, 0)
53
developer2149cd92023-03-10 19:01:41 +080054#define MTK_PHY_TX_I2MPB_TEST_MODE_A2 (0x16)
developerc50c2352021-12-01 10:45:35 +080055#define MTK_PHY_DA_TX_I2MPB_A_HBT_MASK GENMASK(15, 10)
56#define MTK_PHY_DA_TX_I2MPB_A_TST_MASK GENMASK(5, 0)
57
developer2149cd92023-03-10 19:01:41 +080058#define MTK_PHY_TX_I2MPB_TEST_MODE_B1 (0x17)
developerc50c2352021-12-01 10:45:35 +080059#define MTK_PHY_DA_TX_I2MPB_B_GBE_MASK GENMASK(13, 8)
60#define MTK_PHY_DA_TX_I2MPB_B_TBT_MASK GENMASK(5, 0)
61
developer2149cd92023-03-10 19:01:41 +080062#define MTK_PHY_TX_I2MPB_TEST_MODE_B2 (0x18)
developerc50c2352021-12-01 10:45:35 +080063#define MTK_PHY_DA_TX_I2MPB_B_HBT_MASK GENMASK(13, 8)
64#define MTK_PHY_DA_TX_I2MPB_B_TST_MASK GENMASK(5, 0)
65
developer2149cd92023-03-10 19:01:41 +080066#define MTK_PHY_TX_I2MPB_TEST_MODE_C1 (0x19)
developerc50c2352021-12-01 10:45:35 +080067#define MTK_PHY_DA_TX_I2MPB_C_GBE_MASK GENMASK(13, 8)
68#define MTK_PHY_DA_TX_I2MPB_C_TBT_MASK GENMASK(5, 0)
69
developer2149cd92023-03-10 19:01:41 +080070#define MTK_PHY_TX_I2MPB_TEST_MODE_C2 (0x20)
developerc50c2352021-12-01 10:45:35 +080071#define MTK_PHY_DA_TX_I2MPB_C_HBT_MASK GENMASK(13, 8)
72#define MTK_PHY_DA_TX_I2MPB_C_TST_MASK GENMASK(5, 0)
73
developer2149cd92023-03-10 19:01:41 +080074#define MTK_PHY_TX_I2MPB_TEST_MODE_D1 (0x21)
developerc50c2352021-12-01 10:45:35 +080075#define MTK_PHY_DA_TX_I2MPB_D_GBE_MASK GENMASK(13, 8)
76#define MTK_PHY_DA_TX_I2MPB_D_TBT_MASK GENMASK(5, 0)
77
developer2149cd92023-03-10 19:01:41 +080078#define MTK_PHY_TX_I2MPB_TEST_MODE_D2 (0x22)
developerc50c2352021-12-01 10:45:35 +080079#define MTK_PHY_DA_TX_I2MPB_D_HBT_MASK GENMASK(13, 8)
80#define MTK_PHY_DA_TX_I2MPB_D_TST_MASK GENMASK(5, 0)
81
developer2149cd92023-03-10 19:01:41 +080082#define MTK_PHY_TANA_CAL_MODE (0xc1)
83#define MTK_PHY_TANA_CAL_MODE_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +080084
developer2149cd92023-03-10 19:01:41 +080085#define MTK_PHY_RXADC_CTRL_RG7 (0xc6)
developer57374032022-10-11 16:43:24 +080086#define MTK_PHY_DA_AD_BUF_BIAS_LP_MASK GENMASK(9, 8)
87
developer2149cd92023-03-10 19:01:41 +080088#define MTK_PHY_RXADC_CTRL_RG9 (0xc8)
89#define MTK_PHY_DA_RX_PSBN_TBT_MASK GENMASK(14, 12)
90#define MTK_PHY_DA_RX_PSBN_HBT_MASK GENMASK(10, 8)
91#define MTK_PHY_DA_RX_PSBN_GBE_MASK GENMASK(6, 4)
92#define MTK_PHY_DA_RX_PSBN_LP_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +080093
developer2149cd92023-03-10 19:01:41 +080094#define MTK_PHY_LDO_OUTPUT_V (0xd7)
developerce268312022-12-20 16:26:11 +080095
developer2149cd92023-03-10 19:01:41 +080096#define MTK_PHY_RG_ANA_CAL_RG0 (0xdb)
97#define MTK_PHY_RG_CAL_CKINV BIT(12)
98#define MTK_PHY_RG_ANA_CALEN BIT(8)
99#define MTK_PHY_RG_REXT_CALEN BIT(4)
100#define MTK_PHY_RG_ZCALEN_A BIT(0)
developerc50c2352021-12-01 10:45:35 +0800101
developer2149cd92023-03-10 19:01:41 +0800102#define MTK_PHY_RG_ANA_CAL_RG1 (0xdc)
103#define MTK_PHY_RG_ZCALEN_B BIT(12)
104#define MTK_PHY_RG_ZCALEN_C BIT(8)
105#define MTK_PHY_RG_ZCALEN_D BIT(4)
106#define MTK_PHY_RG_TXVOS_CALEN BIT(0)
developerc50c2352021-12-01 10:45:35 +0800107
developer2149cd92023-03-10 19:01:41 +0800108#define MTK_PHY_RG_ANA_CAL_RG2 (0xdd)
109#define MTK_PHY_RG_TXG_CALEN_A BIT(12)
110#define MTK_PHY_RG_TXG_CALEN_B BIT(8)
111#define MTK_PHY_RG_TXG_CALEN_C BIT(4)
112#define MTK_PHY_RG_TXG_CALEN_D BIT(0)
developerc50c2352021-12-01 10:45:35 +0800113
developer2149cd92023-03-10 19:01:41 +0800114#define MTK_PHY_RG_ANA_CAL_RG5 (0xe0)
115#define MTK_PHY_RG_REXT_TRIM_MASK GENMASK(13, 8)
116#define MTK_PHY_RG_ZCAL_CTRL_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800117
developer2149cd92023-03-10 19:01:41 +0800118#define MTK_PHY_RG_TX_FILTER (0xfe)
developer6de96aa2022-09-29 16:46:18 +0800119
developer2149cd92023-03-10 19:01:41 +0800120#define MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B (0x172)
developerc50c2352021-12-01 10:45:35 +0800121#define MTK_PHY_CR_TX_AMP_OFFSET_A_MASK GENMASK(13, 8)
122#define MTK_PHY_CR_TX_AMP_OFFSET_B_MASK GENMASK(6, 0)
123
developer2149cd92023-03-10 19:01:41 +0800124#define MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D (0x173)
developerc50c2352021-12-01 10:45:35 +0800125#define MTK_PHY_CR_TX_AMP_OFFSET_C_MASK GENMASK(13, 8)
126#define MTK_PHY_CR_TX_AMP_OFFSET_D_MASK GENMASK(6, 0)
127
developer2149cd92023-03-10 19:01:41 +0800128#define MTK_PHY_RG_AD_CAL_COMP (0x17a)
129#define MTK_PHY_AD_CAL_COMP_OUT_SHIFT (8)
developerc50c2352021-12-01 10:45:35 +0800130
developer2149cd92023-03-10 19:01:41 +0800131#define MTK_PHY_RG_AD_CAL_CLK (0x17b)
132#define MTK_PHY_DA_CAL_CLK BIT(0)
developerc50c2352021-12-01 10:45:35 +0800133
developer2149cd92023-03-10 19:01:41 +0800134#define MTK_PHY_RG_AD_CALIN (0x17c)
135#define MTK_PHY_DA_CALIN_FLAG BIT(0)
developerc50c2352021-12-01 10:45:35 +0800136
developer2149cd92023-03-10 19:01:41 +0800137#define MTK_PHY_RG_DASN_DAC_IN0_A (0x17d)
138#define MTK_PHY_DASN_DAC_IN0_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800139
developer2149cd92023-03-10 19:01:41 +0800140#define MTK_PHY_RG_DASN_DAC_IN0_B (0x17e)
141#define MTK_PHY_DASN_DAC_IN0_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800142
developer2149cd92023-03-10 19:01:41 +0800143#define MTK_PHY_RG_DASN_DAC_IN0_C (0x17f)
144#define MTK_PHY_DASN_DAC_IN0_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800145
developer2149cd92023-03-10 19:01:41 +0800146#define MTK_PHY_RG_DASN_DAC_IN0_D (0x180)
147#define MTK_PHY_DASN_DAC_IN0_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800148
developer2149cd92023-03-10 19:01:41 +0800149#define MTK_PHY_RG_DASN_DAC_IN1_A (0x181)
150#define MTK_PHY_DASN_DAC_IN1_A_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800151
developer2149cd92023-03-10 19:01:41 +0800152#define MTK_PHY_RG_DASN_DAC_IN1_B (0x182)
153#define MTK_PHY_DASN_DAC_IN1_B_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800154
developer2149cd92023-03-10 19:01:41 +0800155#define MTK_PHY_RG_DASN_DAC_IN1_C (0x183)
156#define MTK_PHY_DASN_DAC_IN1_C_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800157
developer2149cd92023-03-10 19:01:41 +0800158#define MTK_PHY_RG_DASN_DAC_IN1_D (0x180)
159#define MTK_PHY_DASN_DAC_IN1_D_MASK GENMASK(9, 0)
developerc50c2352021-12-01 10:45:35 +0800160
developer2149cd92023-03-10 19:01:41 +0800161#define MTK_PHY_RG_LP_IIR2_K1_L (0x22a)
162#define MTK_PHY_RG_LP_IIR2_K1_U (0x22b)
163#define MTK_PHY_RG_LP_IIR2_K2_L (0x22c)
164#define MTK_PHY_RG_LP_IIR2_K2_U (0x22d)
165#define MTK_PHY_RG_LP_IIR2_K3_L (0x22e)
166#define MTK_PHY_RG_LP_IIR2_K3_U (0x22f)
167#define MTK_PHY_RG_LP_IIR2_K4_L (0x230)
168#define MTK_PHY_RG_LP_IIR2_K4_U (0x231)
169#define MTK_PHY_RG_LP_IIR2_K5_L (0x232)
170#define MTK_PHY_RG_LP_IIR2_K5_U (0x233)
developer75819992023-03-08 20:49:03 +0800171
developer2149cd92023-03-10 19:01:41 +0800172#define MTK_PHY_RG_DEV1E_REG234 (0x234)
173#define MTK_PHY_TR_OPEN_LOOP_EN_MASK GENMASK(0, 0)
174#define MTK_PHY_LPF_X_AVERAGE_MASK GENMASK(7, 4)
developerd2ec38e2022-11-27 01:15:29 +0800175
developer2149cd92023-03-10 19:01:41 +0800176#define MTK_PHY_RG_LPF_CNT_VAL (0x235)
developerd2ec38e2022-11-27 01:15:29 +0800177
developer2149cd92023-03-10 19:01:41 +0800178#define MTK_PHY_RG_DEV1E_REG27C (0x27c)
developerd2ec38e2022-11-27 01:15:29 +0800179#define MTK_PHY_VGASTATE_FFE_THR_ST1_MASK GENMASK(12, 8)
developer2149cd92023-03-10 19:01:41 +0800180#define MTK_PHY_RG_DEV1E_REG27D (0x27d)
developerd2ec38e2022-11-27 01:15:29 +0800181#define MTK_PHY_VGASTATE_FFE_THR_ST2_MASK GENMASK(4, 0)
developer68f6e102022-11-22 17:35:00 +0800182
developer2149cd92023-03-10 19:01:41 +0800183#define MTK_PHY_LDO_PUMP_EN_PAIRAB (0x502)
184#define MTK_PHY_LDO_PUMP_EN_PAIRCD (0x503)
developer75819992023-03-08 20:49:03 +0800185
developer2149cd92023-03-10 19:01:41 +0800186#define MTK_PHY_DA_TX_R50_PAIR_A (0x53d)
187#define MTK_PHY_DA_TX_R50_PAIR_B (0x53e)
188#define MTK_PHY_DA_TX_R50_PAIR_C (0x53f)
189#define MTK_PHY_DA_TX_R50_PAIR_D (0x540)
developerc50c2352021-12-01 10:45:35 +0800190
191/* Registers on MDIO_MMD_VEND2 */
developer2149cd92023-03-10 19:01:41 +0800192#define MTK_PHY_LED0_ON_CTRL (0x24)
developer23021292022-10-21 19:10:10 +0800193#define MTK_PHY_LED0_ON_MASK GENMASK(6, 0)
developer2149cd92023-03-10 19:01:41 +0800194#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
195#define MTK_PHY_LED0_ON_LINK100 BIT(1)
196#define MTK_PHY_LED0_ON_LINK10 BIT(2)
197#define MTK_PHY_LED0_ON_LINKDOWN BIT(3)
198#define MTK_PHY_LED0_ON_FDX BIT(4) /* Full duplex */
199#define MTK_PHY_LED0_ON_HDX BIT(5) /* Half duplex */
200#define MTK_PHY_LED0_FORCE_ON BIT(6)
201#define MTK_PHY_LED0_POLARITY BIT(14)
202#define MTK_PHY_LED0_ENABLE BIT(15)
developer23021292022-10-21 19:10:10 +0800203
developer2149cd92023-03-10 19:01:41 +0800204#define MTK_PHY_LED0_BLINK_CTRL (0x25)
205#define MTK_PHY_LED0_1000TX BIT(0)
206#define MTK_PHY_LED0_1000RX BIT(1)
207#define MTK_PHY_LED0_100TX BIT(2)
208#define MTK_PHY_LED0_100RX BIT(3)
209#define MTK_PHY_LED0_10TX BIT(4)
210#define MTK_PHY_LED0_10RX BIT(5)
211#define MTK_PHY_LED0_COLLISION BIT(6)
212#define MTK_PHY_LED0_RX_CRC_ERR BIT(7)
213#define MTK_PHY_LED0_RX_IDLE_ERR BIT(8)
214#define MTK_PHY_LED0_FORCE_BLINK BIT(9)
developer8bc5dca2022-10-24 17:15:12 +0800215
developer2149cd92023-03-10 19:01:41 +0800216#define MTK_PHY_ANA_TEST_BUS_CTRL_RG (0x100)
developerc50c2352021-12-01 10:45:35 +0800217#define MTK_PHY_ANA_TEST_MODE_MASK GENMASK(15, 8)
218
developer2149cd92023-03-10 19:01:41 +0800219#define MTK_PHY_RG_DASN_TXT_DMY2 (0x110)
220#define MTK_PHY_TST_DMY2_MASK GENMASK(5, 0)
developerc50c2352021-12-01 10:45:35 +0800221
developer2149cd92023-03-10 19:01:41 +0800222#define MTK_PHY_RG_BG_RASEL (0x115)
223#define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0)
developerc50c2352021-12-01 10:45:35 +0800224
developer2149cd92023-03-10 19:01:41 +0800225/* These macro privides efuse parsing for internal phy. */
226#define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0))
227#define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0))
228#define EFS_DA_TX_I2MPB_C(x) (((x) >> 12) & GENMASK(5, 0))
229#define EFS_DA_TX_I2MPB_D(x) (((x) >> 18) & GENMASK(5, 0))
230#define EFS_DA_TX_AMP_OFFSET_A(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800231
developer2149cd92023-03-10 19:01:41 +0800232#define EFS_DA_TX_AMP_OFFSET_B(x) (((x) >> 0) & GENMASK(5, 0))
233#define EFS_DA_TX_AMP_OFFSET_C(x) (((x) >> 6) & GENMASK(5, 0))
234#define EFS_DA_TX_AMP_OFFSET_D(x) (((x) >> 12) & GENMASK(5, 0))
235#define EFS_DA_TX_R50_A(x) (((x) >> 18) & GENMASK(5, 0))
236#define EFS_DA_TX_R50_B(x) (((x) >> 24) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800237
developer2149cd92023-03-10 19:01:41 +0800238#define EFS_DA_TX_R50_C(x) (((x) >> 0) & GENMASK(5, 0))
239#define EFS_DA_TX_R50_D(x) (((x) >> 6) & GENMASK(5, 0))
240#define EFS_DA_TX_R50_A_10M(x) (((x) >> 12) & GENMASK(5, 0))
241#define EFS_DA_TX_R50_B_10M(x) (((x) >> 18) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800242
developer2149cd92023-03-10 19:01:41 +0800243#define EFS_RG_BG_RASEL(x) (((x) >> 4) & GENMASK(2, 0))
244#define EFS_RG_REXT_TRIM(x) (((x) >> 7) & GENMASK(5, 0))
developerc50c2352021-12-01 10:45:35 +0800245
developer2149cd92023-03-10 19:01:41 +0800246enum {
247 NO_PAIR,
developerc50c2352021-12-01 10:45:35 +0800248 PAIR_A,
249 PAIR_B,
250 PAIR_C,
251 PAIR_D,
developer2149cd92023-03-10 19:01:41 +0800252};
developerc50c2352021-12-01 10:45:35 +0800253
developer23021292022-10-21 19:10:10 +0800254enum {
255 GPHY_PORT0,
256 GPHY_PORT1,
257 GPHY_PORT2,
258 GPHY_PORT3,
259};
260
developer2149cd92023-03-10 19:01:41 +0800261enum calibration_mode {
262 EFUSE_K,
263 SW_K
264};
265
266enum CAL_ITEM {
267 REXT,
268 TX_OFFSET,
269 TX_AMP,
270 TX_R50,
271 TX_VCM
272};
273
274enum CAL_MODE {
developer2149cd92023-03-10 19:01:41 +0800275 EFUSE_M,
276 SW_M
277};
278
developerc50c2352021-12-01 10:45:35 +0800279const u8 mt798x_zcal_to_r50[64] = {
280 7, 8, 9, 9, 10, 10, 11, 11,
281 12, 13, 13, 14, 14, 15, 16, 16,
282 17, 18, 18, 19, 20, 21, 21, 22,
283 23, 24, 24, 25, 26, 27, 28, 29,
284 30, 31, 32, 33, 34, 35, 36, 37,
285 38, 40, 41, 42, 43, 45, 46, 48,
286 49, 51, 52, 54, 55, 57, 59, 61,
287 62, 63, 63, 63, 63, 63, 63, 63
288};
289
290const char pair[4] = {'A', 'B', 'C', 'D'};
291
developer2149cd92023-03-10 19:01:41 +0800292static int mtk_gephy_read_page(struct phy_device *phydev)
293{
294 return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
295}
developerc50c2352021-12-01 10:45:35 +0800296
developer2149cd92023-03-10 19:01:41 +0800297static int mtk_gephy_write_page(struct phy_device *phydev, int page)
298{
299 return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
300}
developerc50c2352021-12-01 10:45:35 +0800301
developer2149cd92023-03-10 19:01:41 +0800302static void mtk_gephy_config_init(struct phy_device *phydev)
303{
304 /* Disable EEE */
305 phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
developerc50c2352021-12-01 10:45:35 +0800306
developer2149cd92023-03-10 19:01:41 +0800307 /* Enable HW auto downshift */
308 phy_modify_paged(phydev, MTK_PHY_PAGE_EXTENDED, 0x14, 0, BIT(4));
developerc50c2352021-12-01 10:45:35 +0800309
developer2149cd92023-03-10 19:01:41 +0800310 /* Increase SlvDPSready time */
311 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
312 __phy_write(phydev, 0x10, 0xafae);
313 __phy_write(phydev, 0x12, 0x2f);
314 __phy_write(phydev, 0x10, 0x8fae);
315 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerc50c2352021-12-01 10:45:35 +0800316
developer2149cd92023-03-10 19:01:41 +0800317 /* Adjust 100_mse_threshold */
318 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x123, 0xffff);
developerc50c2352021-12-01 10:45:35 +0800319
developer2149cd92023-03-10 19:01:41 +0800320 /* Disable mcc */
321 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0xa6, 0x300);
322}
developerc50c2352021-12-01 10:45:35 +0800323
developer2149cd92023-03-10 19:01:41 +0800324static int mt7530_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800325{
developer2149cd92023-03-10 19:01:41 +0800326 mtk_gephy_config_init(phydev);
327
328 /* Increase post_update_timer */
329 phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3, 0x11, 0x4b);
330
331 return 0;
developerc50c2352021-12-01 10:45:35 +0800332}
333
developer2149cd92023-03-10 19:01:41 +0800334static int mt7531_phy_config_init(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +0800335{
developer2149cd92023-03-10 19:01:41 +0800336 mtk_gephy_config_init(phydev);
337
338 /* PHY link down power saving enable */
339 phy_set_bits(phydev, 0x17, BIT(4));
340 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, 0xc6, 0x300);
341
342 /* Set TX Pair delay selection */
343 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x13, 0x404);
344 phy_write_mmd(phydev, MDIO_MMD_VEND1, 0x14, 0x404);
345
346 return 0;
developerc50c2352021-12-01 10:45:35 +0800347}
348
developer2149cd92023-03-10 19:01:41 +0800349#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
350/* One calibration cycle consists of:
developerc50c2352021-12-01 10:45:35 +0800351 * 1.Set DA_CALIN_FLAG high to start calibration. Keep it high
352 * until AD_CAL_COMP is ready to output calibration result.
353 * 2.Wait until DA_CAL_CLK is available.
354 * 3.Fetch AD_CAL_COMP_OUT.
355 */
356static int cal_cycle(struct phy_device *phydev, int devad,
developer2149cd92023-03-10 19:01:41 +0800357 u32 regnum, u16 mask, u16 cal_val)
developerc50c2352021-12-01 10:45:35 +0800358{
359 unsigned long timeout;
360 int reg_val;
361 int ret;
362
363 phy_modify_mmd(phydev, devad, regnum,
developer2149cd92023-03-10 19:01:41 +0800364 mask, cal_val);
365 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
366 MTK_PHY_DA_CALIN_FLAG);
developerc50c2352021-12-01 10:45:35 +0800367
368 timeout = jiffies + usecs_to_jiffies(ANALOG_INTERNAL_OPERATION_MAX_US);
developer2149cd92023-03-10 19:01:41 +0800369 do {
370 reg_val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
371 MTK_PHY_RG_AD_CAL_CLK);
372 } while (time_before(jiffies, timeout) && !(reg_val & BIT(0)));
developerc50c2352021-12-01 10:45:35 +0800373
developer2149cd92023-03-10 19:01:41 +0800374 if (!(reg_val & BIT(0))) {
developerc50c2352021-12-01 10:45:35 +0800375 dev_err(&phydev->mdio.dev, "Calibration cycle timeout\n");
376 return -ETIMEDOUT;
377 }
378
developer2149cd92023-03-10 19:01:41 +0800379 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CALIN,
380 MTK_PHY_DA_CALIN_FLAG);
381 ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_AD_CAL_COMP) >>
382 MTK_PHY_AD_CAL_COMP_OUT_SHIFT;
developerc50c2352021-12-01 10:45:35 +0800383 dev_dbg(&phydev->mdio.dev, "cal_val: 0x%x, ret: %d\n", cal_val, ret);
384
385 return ret;
386}
387
388static int rext_fill_result(struct phy_device *phydev, u16 *buf)
389{
390 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG5,
developer2149cd92023-03-10 19:01:41 +0800391 MTK_PHY_RG_REXT_TRIM_MASK, buf[0] << 8);
392 phy_modify_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_RG_BG_RASEL,
393 MTK_PHY_RG_BG_RASEL_MASK, buf[1]);
developerc50c2352021-12-01 10:45:35 +0800394
395 return 0;
396}
397
398static int rext_cal_efuse(struct phy_device *phydev, u32 *buf)
399{
400 u16 rext_cal_val[2];
401
402 rext_cal_val[0] = EFS_RG_REXT_TRIM(buf[3]);
403 rext_cal_val[1] = EFS_RG_BG_RASEL(buf[3]);
404 rext_fill_result(phydev, rext_cal_val);
405
406 return 0;
407}
408
developerc50c2352021-12-01 10:45:35 +0800409static int tx_offset_fill_result(struct phy_device *phydev, u16 *buf)
410{
developer2149cd92023-03-10 19:01:41 +0800411 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800412 MTK_PHY_CR_TX_AMP_OFFSET_A_MASK, buf[0] << 8);
developer2149cd92023-03-10 19:01:41 +0800413 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_A_B,
developerc50c2352021-12-01 10:45:35 +0800414 MTK_PHY_CR_TX_AMP_OFFSET_B_MASK, buf[1]);
developer2149cd92023-03-10 19:01:41 +0800415 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800416 MTK_PHY_CR_TX_AMP_OFFSET_C_MASK, buf[2] << 8);
developer2149cd92023-03-10 19:01:41 +0800417 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_CR_TX_AMP_OFFSET_C_D,
developerc50c2352021-12-01 10:45:35 +0800418 MTK_PHY_CR_TX_AMP_OFFSET_D_MASK, buf[3]);
419
420 return 0;
421}
422
423static int tx_offset_cal_efuse(struct phy_device *phydev, u32 *buf)
424{
425 u16 tx_offset_cal_val[4];
426
427 tx_offset_cal_val[0] = EFS_DA_TX_AMP_OFFSET_A(buf[0]);
428 tx_offset_cal_val[1] = EFS_DA_TX_AMP_OFFSET_B(buf[1]);
429 tx_offset_cal_val[2] = EFS_DA_TX_AMP_OFFSET_C(buf[1]);
430 tx_offset_cal_val[3] = EFS_DA_TX_AMP_OFFSET_D(buf[1]);
431
432 tx_offset_fill_result(phydev, tx_offset_cal_val);
433
434 return 0;
435}
436
437static int tx_amp_fill_result(struct phy_device *phydev, u16 *buf)
438{
developerd2ec38e2022-11-27 01:15:29 +0800439 int i;
developer87c89d12022-08-19 17:46:34 +0800440 int bias[16] = {0};
developer2149cd92023-03-10 19:01:41 +0800441 const int vals_9461[16] = { 7, 1, 4, 7,
442 7, 1, 4, 7,
443 7, 1, 4, 7,
444 7, 1, 4, 7 };
445 const int vals_9481[16] = { 10, 6, 6, 10,
446 10, 6, 6, 10,
447 10, 6, 6, 10,
448 10, 6, 6, 10 };
449
450 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800451 case MTK_GPHY_ID_MT7981:
developer2149cd92023-03-10 19:01:41 +0800452 /* We add some calibration to efuse values
453 * due to board level influence.
454 * GBE: +7, TBT: +1, HBT: +4, TST: +7
455 */
456 memcpy(bias, (const void *)vals_9461, sizeof(bias));
457 for (i = 0; i <= 12; i += 4) {
458 if (likely(buf[i >> 2] + bias[i] >= 32)) {
459 bias[i] -= 13;
460 } else {
461 phy_modify_mmd(phydev, MDIO_MMD_VEND1,
462 0x5c, 0x7 << i, bias[i] << i);
463 bias[i + 1] += 13;
464 bias[i + 2] += 13;
465 bias[i + 3] += 13;
466 }
developer87c89d12022-08-19 17:46:34 +0800467 }
developer2149cd92023-03-10 19:01:41 +0800468 break;
developer043f7b92023-03-13 13:57:36 +0800469 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800470 memcpy(bias, (const void *)vals_9481, sizeof(bias));
471 break;
472 default:
473 break;
developer87c89d12022-08-19 17:46:34 +0800474 }
developerd2ec38e2022-11-27 01:15:29 +0800475
developerdc3e9502022-12-02 18:10:42 +0800476 /* Prevent overflow */
477 for (i = 0; i < 12; i++) {
developer2149cd92023-03-10 19:01:41 +0800478 if (buf[i >> 2] + bias[i] > 63) {
479 buf[i >> 2] = 63;
developerdc3e9502022-12-02 18:10:42 +0800480 bias[i] = 0;
developer2149cd92023-03-10 19:01:41 +0800481 } else if (buf[i >> 2] + bias[i] < 0) {
developerdc3e9502022-12-02 18:10:42 +0800482 /* Bias caused by board design may change in the future.
483 * So check negative cases, too.
484 */
developer2149cd92023-03-10 19:01:41 +0800485 buf[i >> 2] = 0;
developerdc3e9502022-12-02 18:10:42 +0800486 bias[i] = 0;
487 }
488 }
489
developerc50c2352021-12-01 10:45:35 +0800490 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800491 MTK_PHY_DA_TX_I2MPB_A_GBE_MASK, (buf[0] + bias[0]) << 10);
developerc50c2352021-12-01 10:45:35 +0800492 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG,
developer87c89d12022-08-19 17:46:34 +0800493 MTK_PHY_DA_TX_I2MPB_A_TBT_MASK, buf[0] + bias[1]);
developerc50c2352021-12-01 10:45:35 +0800494 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800495 MTK_PHY_DA_TX_I2MPB_A_HBT_MASK, (buf[0] + bias[2]) << 10);
developerc50c2352021-12-01 10:45:35 +0800496 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
developer87c89d12022-08-19 17:46:34 +0800497 MTK_PHY_DA_TX_I2MPB_A_TST_MASK, buf[0] + bias[3]);
developerc50c2352021-12-01 10:45:35 +0800498
499 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800500 MTK_PHY_DA_TX_I2MPB_B_GBE_MASK, (buf[1] + bias[4]) << 8);
developerc50c2352021-12-01 10:45:35 +0800501 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
developer87c89d12022-08-19 17:46:34 +0800502 MTK_PHY_DA_TX_I2MPB_B_TBT_MASK, buf[1] + bias[5]);
developerc50c2352021-12-01 10:45:35 +0800503 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800504 MTK_PHY_DA_TX_I2MPB_B_HBT_MASK, (buf[1] + bias[6]) << 8);
developerc50c2352021-12-01 10:45:35 +0800505 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
developer87c89d12022-08-19 17:46:34 +0800506 MTK_PHY_DA_TX_I2MPB_B_TST_MASK, buf[1] + bias[7]);
developerc50c2352021-12-01 10:45:35 +0800507
508 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800509 MTK_PHY_DA_TX_I2MPB_C_GBE_MASK, (buf[2] + bias[8]) << 8);
developerc50c2352021-12-01 10:45:35 +0800510 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
developer87c89d12022-08-19 17:46:34 +0800511 MTK_PHY_DA_TX_I2MPB_C_TBT_MASK, buf[2] + bias[9]);
developerc50c2352021-12-01 10:45:35 +0800512 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800513 MTK_PHY_DA_TX_I2MPB_C_HBT_MASK, (buf[2] + bias[10]) << 8);
developerc50c2352021-12-01 10:45:35 +0800514 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
developer87c89d12022-08-19 17:46:34 +0800515 MTK_PHY_DA_TX_I2MPB_C_TST_MASK, buf[2] + bias[11]);
developerc50c2352021-12-01 10:45:35 +0800516
517 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800518 MTK_PHY_DA_TX_I2MPB_D_GBE_MASK, (buf[3] + bias[12]) << 8);
developerc50c2352021-12-01 10:45:35 +0800519 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
developer87c89d12022-08-19 17:46:34 +0800520 MTK_PHY_DA_TX_I2MPB_D_TBT_MASK, buf[3] + bias[13]);
developerc50c2352021-12-01 10:45:35 +0800521 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800522 MTK_PHY_DA_TX_I2MPB_D_HBT_MASK, (buf[3] + bias[14]) << 8);
developerc50c2352021-12-01 10:45:35 +0800523 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
developer87c89d12022-08-19 17:46:34 +0800524 MTK_PHY_DA_TX_I2MPB_D_TST_MASK, buf[3] + bias[15]);
developerc50c2352021-12-01 10:45:35 +0800525
526 return 0;
527}
528
529static int tx_amp_cal_efuse(struct phy_device *phydev, u32 *buf)
530{
531 u16 tx_amp_cal_val[4];
532
533 tx_amp_cal_val[0] = EFS_DA_TX_I2MPB_A(buf[0]);
534 tx_amp_cal_val[1] = EFS_DA_TX_I2MPB_B(buf[0]);
535 tx_amp_cal_val[2] = EFS_DA_TX_I2MPB_C(buf[0]);
536 tx_amp_cal_val[3] = EFS_DA_TX_I2MPB_D(buf[0]);
537 tx_amp_fill_result(phydev, tx_amp_cal_val);
538
539 return 0;
540}
541
developer2149cd92023-03-10 19:01:41 +0800542static int tx_r50_fill_result(struct phy_device *phydev, u16 tx_r50_cal_val,
543 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800544{
developer2149cd92023-03-10 19:01:41 +0800545 int bias = 0;
546 u16 reg, val;
developer87c89d12022-08-19 17:46:34 +0800547
developer2149cd92023-03-10 19:01:41 +0800548 switch (phydev->drv->phy_id) {
developer043f7b92023-03-13 13:57:36 +0800549 case MTK_GPHY_ID_MT7988:
developer2149cd92023-03-10 19:01:41 +0800550 {
551 bias = -2;
552 break;
developerdc3e9502022-12-02 18:10:42 +0800553 }
developer043f7b92023-03-13 13:57:36 +0800554 /* MTK_GPHY_ID_MT7981 enters default case */
developer2149cd92023-03-10 19:01:41 +0800555 default:
556 break;
557 }
558
559 val = clamp_val(bias + tx_r50_cal_val, 0, 63);
560
561 switch (txg_calen_x) {
562 case PAIR_A:
563 reg = MTK_PHY_DA_TX_R50_PAIR_A;
564 break;
565 case PAIR_B:
566 reg = MTK_PHY_DA_TX_R50_PAIR_B;
567 break;
568 case PAIR_C:
569 reg = MTK_PHY_DA_TX_R50_PAIR_C;
570 break;
571 case PAIR_D:
572 reg = MTK_PHY_DA_TX_R50_PAIR_D;
573 break;
developerc50c2352021-12-01 10:45:35 +0800574 }
developer2149cd92023-03-10 19:01:41 +0800575
576 phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, val | val << 8);
577
developerc50c2352021-12-01 10:45:35 +0800578 return 0;
579}
580
581static int tx_r50_cal_efuse(struct phy_device *phydev, u32 *buf,
developer2149cd92023-03-10 19:01:41 +0800582 u8 txg_calen_x)
developerc50c2352021-12-01 10:45:35 +0800583{
developer2149cd92023-03-10 19:01:41 +0800584 u16 tx_r50_cal_val;
developerc50c2352021-12-01 10:45:35 +0800585
developer2149cd92023-03-10 19:01:41 +0800586 switch (txg_calen_x) {
587 case PAIR_A:
588 tx_r50_cal_val = EFS_DA_TX_R50_A(buf[1]);
589 break;
590 case PAIR_B:
591 tx_r50_cal_val = EFS_DA_TX_R50_B(buf[1]);
592 break;
593 case PAIR_C:
594 tx_r50_cal_val = EFS_DA_TX_R50_C(buf[2]);
595 break;
596 case PAIR_D:
597 tx_r50_cal_val = EFS_DA_TX_R50_D(buf[2]);
598 break;
developerc50c2352021-12-01 10:45:35 +0800599 }
600 tx_r50_fill_result(phydev, tx_r50_cal_val, txg_calen_x);
601
602 return 0;
603}
604
developer2149cd92023-03-10 19:01:41 +0800605static int tx_vcm_cal_sw(struct phy_device *phydev, u8 rg_txreserve_x)
developerc50c2352021-12-01 10:45:35 +0800606{
607 u8 lower_idx, upper_idx, txreserve_val;
608 u8 lower_ret, upper_ret;
609 int ret;
610
611 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800612 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800613 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800614 MTK_PHY_RG_CAL_CKINV);
developerc50c2352021-12-01 10:45:35 +0800615 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800616 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800617
developer2149cd92023-03-10 19:01:41 +0800618 switch (rg_txreserve_x) {
619 case PAIR_A:
620 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
621 MTK_PHY_RG_DASN_DAC_IN0_A,
622 MTK_PHY_DASN_DAC_IN0_A_MASK);
623 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
624 MTK_PHY_RG_DASN_DAC_IN1_A,
625 MTK_PHY_DASN_DAC_IN1_A_MASK);
626 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
627 MTK_PHY_RG_ANA_CAL_RG0,
628 MTK_PHY_RG_ZCALEN_A);
629 break;
630 case PAIR_B:
631 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
632 MTK_PHY_RG_DASN_DAC_IN0_B,
633 MTK_PHY_DASN_DAC_IN0_B_MASK);
634 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
635 MTK_PHY_RG_DASN_DAC_IN1_B,
636 MTK_PHY_DASN_DAC_IN1_B_MASK);
637 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
638 MTK_PHY_RG_ANA_CAL_RG1,
639 MTK_PHY_RG_ZCALEN_B);
640 break;
641 case PAIR_C:
642 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
643 MTK_PHY_RG_DASN_DAC_IN0_C,
644 MTK_PHY_DASN_DAC_IN0_C_MASK);
645 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
646 MTK_PHY_RG_DASN_DAC_IN1_C,
647 MTK_PHY_DASN_DAC_IN1_C_MASK);
648 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
649 MTK_PHY_RG_ANA_CAL_RG1,
650 MTK_PHY_RG_ZCALEN_C);
651 break;
652 case PAIR_D:
653 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
654 MTK_PHY_RG_DASN_DAC_IN0_D,
655 MTK_PHY_DASN_DAC_IN0_D_MASK);
656 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
657 MTK_PHY_RG_DASN_DAC_IN1_D,
658 MTK_PHY_DASN_DAC_IN1_D_MASK);
659 phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
660 MTK_PHY_RG_ANA_CAL_RG1,
661 MTK_PHY_RG_ZCALEN_D);
662 break;
663 default:
664 ret = -EINVAL;
665 goto restore;
developerc50c2352021-12-01 10:45:35 +0800666 }
667
668 lower_idx = TXRESERVE_MIN;
669 upper_idx = TXRESERVE_MAX;
670
671 dev_dbg(&phydev->mdio.dev, "Start TX-VCM SW cal.\n");
developer2149cd92023-03-10 19:01:41 +0800672 while ((upper_idx - lower_idx) > 1) {
673 txreserve_val = DIV_ROUND_CLOSEST(lower_idx + upper_idx, 2);
developerc50c2352021-12-01 10:45:35 +0800674 ret = cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800675 MTK_PHY_DA_RX_PSBN_TBT_MASK |
676 MTK_PHY_DA_RX_PSBN_HBT_MASK |
677 MTK_PHY_DA_RX_PSBN_GBE_MASK |
678 MTK_PHY_DA_RX_PSBN_LP_MASK,
developerc50c2352021-12-01 10:45:35 +0800679 txreserve_val << 12 | txreserve_val << 8 |
680 txreserve_val << 4 | txreserve_val);
developer2149cd92023-03-10 19:01:41 +0800681 if (ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800682 upper_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800683 upper_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800684 } else if (ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800685 lower_idx = txreserve_val;
developer78aa7b92021-12-29 15:22:10 +0800686 lower_ret = ret;
developer2149cd92023-03-10 19:01:41 +0800687 } else {
developerc50c2352021-12-01 10:45:35 +0800688 goto restore;
developer2149cd92023-03-10 19:01:41 +0800689 }
developerc50c2352021-12-01 10:45:35 +0800690 }
691
developer2149cd92023-03-10 19:01:41 +0800692 if (lower_idx == TXRESERVE_MIN) {
693 lower_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
694 MTK_PHY_RXADC_CTRL_RG9,
695 MTK_PHY_DA_RX_PSBN_TBT_MASK |
696 MTK_PHY_DA_RX_PSBN_HBT_MASK |
697 MTK_PHY_DA_RX_PSBN_GBE_MASK |
698 MTK_PHY_DA_RX_PSBN_LP_MASK,
699 lower_idx << 12 | lower_idx << 8 |
700 lower_idx << 4 | lower_idx);
701 ret = lower_ret;
702 } else if (upper_idx == TXRESERVE_MAX) {
703 upper_ret = cal_cycle(phydev, MDIO_MMD_VEND1,
704 MTK_PHY_RXADC_CTRL_RG9,
705 MTK_PHY_DA_RX_PSBN_TBT_MASK |
706 MTK_PHY_DA_RX_PSBN_HBT_MASK |
707 MTK_PHY_DA_RX_PSBN_GBE_MASK |
708 MTK_PHY_DA_RX_PSBN_LP_MASK,
709 upper_idx << 12 | upper_idx << 8 |
710 upper_idx << 4 | upper_idx);
711 ret = upper_ret;
developer78aa7b92021-12-29 15:22:10 +0800712 }
713 if (ret < 0)
developerc50c2352021-12-01 10:45:35 +0800714 goto restore;
715
developer78aa7b92021-12-29 15:22:10 +0800716 /* We calibrate TX-VCM in different logic. Check upper index and then
717 * lower index. If this calibration is valid, apply lower index's result.
718 */
developer2149cd92023-03-10 19:01:41 +0800719 ret = upper_ret - lower_ret;
developerc50c2352021-12-01 10:45:35 +0800720 if (ret == 1) {
721 ret = 0;
developerb5c76d42022-08-18 15:45:33 +0800722 /* Make sure we use upper_idx in our calibration system */
723 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800724 MTK_PHY_DA_RX_PSBN_TBT_MASK |
725 MTK_PHY_DA_RX_PSBN_HBT_MASK |
726 MTK_PHY_DA_RX_PSBN_GBE_MASK |
727 MTK_PHY_DA_RX_PSBN_LP_MASK,
728 upper_idx << 12 | upper_idx << 8 |
729 upper_idx << 4 | upper_idx);
730 dev_info(&phydev->mdio.dev, "TX-VCM SW cal result: 0x%x\n",
731 upper_idx);
732 } else if (lower_idx == TXRESERVE_MIN && upper_ret == 1 &&
733 lower_ret == 1) {
developerc50c2352021-12-01 10:45:35 +0800734 ret = 0;
735 cal_cycle(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG9,
developer2149cd92023-03-10 19:01:41 +0800736 MTK_PHY_DA_RX_PSBN_TBT_MASK |
737 MTK_PHY_DA_RX_PSBN_HBT_MASK |
738 MTK_PHY_DA_RX_PSBN_GBE_MASK |
739 MTK_PHY_DA_RX_PSBN_LP_MASK,
740 lower_idx << 12 | lower_idx << 8 |
741 lower_idx << 4 | lower_idx);
742 dev_warn(&phydev->mdio.dev,
743 "TX-VCM SW cal result at low margin 0x%x\n",
744 lower_idx);
745 } else if (upper_idx == TXRESERVE_MAX && upper_ret == 0 &&
746 lower_ret == 0) {
developerc50c2352021-12-01 10:45:35 +0800747 ret = 0;
developer2149cd92023-03-10 19:01:41 +0800748 dev_warn(&phydev->mdio.dev,
749 "TX-VCM SW cal result at high margin 0x%x\n",
750 upper_idx);
751 } else {
developerc50c2352021-12-01 10:45:35 +0800752 ret = -EINVAL;
developer2149cd92023-03-10 19:01:41 +0800753 }
developerc50c2352021-12-01 10:45:35 +0800754
755restore:
756 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800757 MTK_PHY_RG_ANA_CALEN);
developerc50c2352021-12-01 10:45:35 +0800758 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800759 MTK_PHY_RG_TXVOS_CALEN);
developerc50c2352021-12-01 10:45:35 +0800760 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG0,
developer2149cd92023-03-10 19:01:41 +0800761 MTK_PHY_RG_ZCALEN_A);
developerc50c2352021-12-01 10:45:35 +0800762 phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_ANA_CAL_RG1,
developer2149cd92023-03-10 19:01:41 +0800763 MTK_PHY_RG_ZCALEN_B | MTK_PHY_RG_ZCALEN_C |
764 MTK_PHY_RG_ZCALEN_D);
developerc50c2352021-12-01 10:45:35 +0800765
766 return ret;
767}
768
developerf35532c2022-08-05 18:37:26 +0800769static inline void mt7981_phy_finetune(struct phy_device *phydev)
developer02d84422021-12-24 11:48:07 +0800770{
developerd2ec38e2022-11-27 01:15:29 +0800771 u32 i;
developer2149cd92023-03-10 19:01:41 +0800772
developer02d84422021-12-24 11:48:07 +0800773 /* 100M eye finetune:
774 * Keep middle level of TX MLT3 shapper as default.
775 * Only change TX MLT3 overshoot level here.
776 */
developer2149cd92023-03-10 19:01:41 +0800777 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TO1,
778 0x1ce);
779 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TO1,
780 0x1c1);
781 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_1TO0,
782 0x20f);
783 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_1TO0,
784 0x202);
785 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_0TON1,
786 0x3d0);
787 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_0TON1,
788 0x3c0);
789 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_1st_OVERSHOOT_LEVEL_N1TO0,
790 0x13);
791 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_2nd_OVERSHOOT_LEVEL_N1TO0,
792 0x5);
developerf35532c2022-08-05 18:37:26 +0800793
developer02d84422021-12-24 11:48:07 +0800794 /* TX-AMP finetune:
795 * 100M +4, 1000M +6 to default value.
796 * If efuse values aren't valid, TX-AMP uses the below values.
797 */
798 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TXVLD_DA_RG, 0x9824);
developer2149cd92023-03-10 19:01:41 +0800799 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_A2,
800 0x9026);
801 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B1,
802 0x2624);
803 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_B2,
804 0x2426);
805 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C1,
806 0x2624);
807 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_C2,
808 0x2426);
809 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D1,
810 0x2624);
811 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_TX_I2MPB_TEST_MODE_D2,
812 0x2426);
developer68f6e102022-11-22 17:35:00 +0800813
developerd2ec38e2022-11-27 01:15:29 +0800814 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
815 /* EnabRandUpdTrig = 1 */
816 __phy_write(phydev, 0x11, 0x2f00);
817 __phy_write(phydev, 0x12, 0xe);
818 __phy_write(phydev, 0x10, 0x8fb0);
819
developer2149cd92023-03-10 19:01:41 +0800820 /* SlvDSPreadyTime = 0xc */
821 __phy_write(phydev, 0x11, 0x671);
developerd2ec38e2022-11-27 01:15:29 +0800822 __phy_write(phydev, 0x12, 0xc);
823 __phy_write(phydev, 0x10, 0x8fae);
824
825 /* NormMseLoThresh = 85 */
826 __phy_write(phydev, 0x11, 0x55a0);
827 __phy_write(phydev, 0x12, 0x0);
828 __phy_write(phydev, 0x10, 0x83aa);
829
830 /* InhibitDisableDfeTail1000 = 1 */
831 __phy_write(phydev, 0x11, 0x2b);
832 __phy_write(phydev, 0x12, 0x0);
833 __phy_write(phydev, 0x10, 0x8f80);
834
developer2149cd92023-03-10 19:01:41 +0800835 /* SSTr related */
developerd2ec38e2022-11-27 01:15:29 +0800836 __phy_write(phydev, 0x11, 0xbaef);
837 __phy_write(phydev, 0x12, 0x2e);
838 __phy_write(phydev, 0x10, 0x968c);
839
840 /* VcoSlicerThreshBitsHigh */
841 __phy_write(phydev, 0x11, 0x5555);
842 __phy_write(phydev, 0x12, 0x55);
843 __phy_write(phydev, 0x10, 0x8ec0);
844
845 /* ResetSyncOffset = 6 */
846 __phy_write(phydev, 0x11, 0x600);
847 __phy_write(phydev, 0x12, 0x0);
848 __phy_write(phydev, 0x10, 0x8fc0);
849
850 /* VgaDecRate = 1 */
851 __phy_write(phydev, 0x11, 0x4c2a);
852 __phy_write(phydev, 0x12, 0x3e);
853 __phy_write(phydev, 0x10, 0x8fa4);
854
855 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerd2ec38e2022-11-27 01:15:29 +0800856 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
developer68f6e102022-11-22 17:35:00 +0800857 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +0800858 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
859 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerd2ec38e2022-11-27 01:15:29 +0800860
861 /* rg_tr_lpf_cnt_val = 512 */
862 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
863
864 /* IIR2 related */
865 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
866 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
867 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
868 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
869 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
870 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
871 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
872 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
873 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
874 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
875
876 /* FFE peaking */
877 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +0800878 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerd2ec38e2022-11-27 01:15:29 +0800879 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +0800880 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerd2ec38e2022-11-27 01:15:29 +0800881
882 /* TX shape */
883 /* 10/100/1000 TX shaper is enabled by default */
884 for (i = 0x202; i < 0x230; i += 2) {
885 if (i == 0x20c || i == 0x218 || i == 0x224)
886 continue;
887 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +0800888 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerd2ec38e2022-11-27 01:15:29 +0800889 }
developer02d84422021-12-24 11:48:07 +0800890}
891
developerf35532c2022-08-05 18:37:26 +0800892static inline void mt7988_phy_finetune(struct phy_device *phydev)
893{
developer2149cd92023-03-10 19:01:41 +0800894 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
895 0x020d, 0x0206, 0x0384, 0x03d0,
896 0x03c6, 0x030a, 0x0011, 0x0005 };
developerf35532c2022-08-05 18:37:26 +0800897 int i;
developerf35532c2022-08-05 18:37:26 +0800898
developer2149cd92023-03-10 19:01:41 +0800899 for (i = 0; i < MTK_PHY_TX_MLT3_END; i++)
developerf35532c2022-08-05 18:37:26 +0800900 phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[i]);
developer6de96aa2022-09-29 16:46:18 +0800901
developer57374032022-10-11 16:43:24 +0800902 /* TCT finetune */
developer6de96aa2022-09-29 16:46:18 +0800903 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
developer57374032022-10-11 16:43:24 +0800904
905 /* Disable TX power saving */
906 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
developer2149cd92023-03-10 19:01:41 +0800907 MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
developerec2b8552022-10-17 15:30:59 +0800908
developerec2b8552022-10-17 15:30:59 +0800909 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
developerce73ad62022-12-07 22:43:45 +0800910 /* EnabRandUpdTrig = 1 */
911 __phy_write(phydev, 0x11, 0x2f00);
912 __phy_write(phydev, 0x12, 0xe);
913 __phy_write(phydev, 0x10, 0x8fb0);
914
developer2149cd92023-03-10 19:01:41 +0800915 /* SlvDSPreadyTime = 0xc */
developerce73ad62022-12-07 22:43:45 +0800916 __phy_write(phydev, 0x11, 0x671);
917 __phy_write(phydev, 0x12, 0xc);
918 __phy_write(phydev, 0x10, 0x8fae);
919
920 /* NormMseLoThresh = 85 */
921 __phy_write(phydev, 0x11, 0x55a0);
developerec2b8552022-10-17 15:30:59 +0800922 __phy_write(phydev, 0x12, 0x0);
developerce73ad62022-12-07 22:43:45 +0800923 __phy_write(phydev, 0x10, 0x83aa);
924
925 /* InhibitDisableDfeTail1000 = 1 */
926 __phy_write(phydev, 0x11, 0x2b);
927 __phy_write(phydev, 0x12, 0x0);
928 __phy_write(phydev, 0x10, 0x8f80);
929
930 /* SSTr related */
931 __phy_write(phydev, 0x11, 0xbaef);
932 __phy_write(phydev, 0x12, 0x2e);
933 __phy_write(phydev, 0x10, 0x968c);
934
935 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
936 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
937 */
938 __phy_write(phydev, 0x11, 0xd10a);
939 __phy_write(phydev, 0x12, 0x34);
940 __phy_write(phydev, 0x10, 0x8f82);
941
942 /* VcoSlicerThreshBitsHigh */
943 __phy_write(phydev, 0x11, 0x5555);
944 __phy_write(phydev, 0x12, 0x55);
945 __phy_write(phydev, 0x10, 0x8ec0);
946
developerce268312022-12-20 16:26:11 +0800947 /* ResetSyncOffset = 5 */
948 __phy_write(phydev, 0x11, 0x500);
developerce73ad62022-12-07 22:43:45 +0800949 __phy_write(phydev, 0x12, 0x0);
950 __phy_write(phydev, 0x10, 0x8fc0);
developerb5c72b02022-12-21 15:51:07 +0800951 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +0800952
developerce268312022-12-20 16:26:11 +0800953 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
954 /* TxClkOffset = 2 */
developerb5c72b02022-12-21 15:51:07 +0800955 __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
developer2149cd92023-03-10 19:01:41 +0800956 FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
developerec2b8552022-10-17 15:30:59 +0800957 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
developerce73ad62022-12-07 22:43:45 +0800958
959 /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
960 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
developer2149cd92023-03-10 19:01:41 +0800961 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
962 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
developerce73ad62022-12-07 22:43:45 +0800963
964 /* rg_tr_lpf_cnt_val = 512 */
965 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x200);
966
967 /* IIR2 related */
968 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_L, 0x82);
969 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K1_U, 0x0);
970 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_L, 0x103);
971 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K2_U, 0x0);
972 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_L, 0x82);
973 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K3_U, 0x0);
974 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_L, 0xd177);
975 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K4_U, 0x3);
976 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_L, 0x2c82);
977 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LP_IIR2_K5_U, 0xe);
978
979 /* FFE peaking */
980 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27C,
developer2149cd92023-03-10 19:01:41 +0800981 MTK_PHY_VGASTATE_FFE_THR_ST1_MASK, 0x1b << 8);
developerce73ad62022-12-07 22:43:45 +0800982 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG27D,
developer2149cd92023-03-10 19:01:41 +0800983 MTK_PHY_VGASTATE_FFE_THR_ST2_MASK, 0x1e);
developerce73ad62022-12-07 22:43:45 +0800984
985 /* TX shape */
986 /* 10/100/1000 TX shaper is enabled by default */
987 for (i = 0x202; i < 0x230; i += 2) {
988 if (i == 0x20c || i == 0x218 || i == 0x224)
989 continue;
990 phy_write_mmd(phydev, MDIO_MMD_VEND2, i, 0x2219);
developer2149cd92023-03-10 19:01:41 +0800991 phy_write_mmd(phydev, MDIO_MMD_VEND2, i + 1, 0x23);
developerce73ad62022-12-07 22:43:45 +0800992 }
developerce268312022-12-20 16:26:11 +0800993
994 /* Disable LDO pump */
995 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRAB, 0x0);
996 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
997
998 /* Adjust LDO output voltage */
developerb5c72b02022-12-21 15:51:07 +0800999 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
developer2149cd92023-03-10 19:01:41 +08001000}
developer75819992023-03-08 20:49:03 +08001001
developer2149cd92023-03-10 19:01:41 +08001002static inline int cal_sw(struct phy_device *phydev, enum CAL_ITEM cal_item,
1003 u8 start_pair, u8 end_pair)
1004{
1005 u8 pair_n;
1006 int ret;
1007
1008 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1009 /* TX_OFFSET & TX_AMP have no SW calibration. */
1010 switch (cal_item) {
developer2149cd92023-03-10 19:01:41 +08001011 case TX_VCM:
1012 ret = tx_vcm_cal_sw(phydev, pair_n);
1013 break;
1014 default:
1015 return -EINVAL;
1016 }
1017 if (ret)
1018 return ret;
1019 }
1020 return 0;
developerf35532c2022-08-05 18:37:26 +08001021}
1022
developer2149cd92023-03-10 19:01:41 +08001023static inline int cal_efuse(struct phy_device *phydev, enum CAL_ITEM cal_item,
1024 u8 start_pair, u8 end_pair, u32 *buf)
1025{
1026 u8 pair_n;
1027 int ret;
1028
1029 for (pair_n = start_pair; pair_n <= end_pair; pair_n++) {
1030 /* TX_VCM has no efuse calibration. */
1031 switch (cal_item) {
1032 case REXT:
1033 ret = rext_cal_efuse(phydev, buf);
1034 break;
1035 case TX_OFFSET:
1036 ret = tx_offset_cal_efuse(phydev, buf);
1037 break;
1038 case TX_AMP:
1039 ret = tx_amp_cal_efuse(phydev, buf);
1040 break;
1041 case TX_R50:
1042 ret = tx_r50_cal_efuse(phydev, buf, pair_n);
1043 break;
1044 default:
1045 return -EINVAL;
1046 }
1047 if (ret)
1048 return ret;
1049 }
1050
1051 return 0;
1052}
1053
1054static int start_cal(struct phy_device *phydev, enum CAL_ITEM cal_item,
developerc7b857b2023-03-28 22:37:02 +08001055 enum CAL_MODE cal_mode, u8 start_pair,
developer2149cd92023-03-10 19:01:41 +08001056 u8 end_pair, u32 *buf)
1057{
developerc7b857b2023-03-28 22:37:02 +08001058 int ret;
developer2149cd92023-03-10 19:01:41 +08001059 char cal_prop[5][20] = { "mediatek,rext", "mediatek,tx_offset",
1060 "mediatek,tx_amp", "mediatek,tx_r50",
1061 "mediatek,tx_vcm" };
developer2149cd92023-03-10 19:01:41 +08001062
1063 switch (cal_mode) {
developer2149cd92023-03-10 19:01:41 +08001064 case EFUSE_M:
developerc7b857b2023-03-28 22:37:02 +08001065 ret = cal_efuse(phydev, cal_item, start_pair,
1066 end_pair, buf);
developer2149cd92023-03-10 19:01:41 +08001067 break;
1068 case SW_M:
developerc7b857b2023-03-28 22:37:02 +08001069 ret = cal_sw(phydev, cal_item, start_pair, end_pair);
developer2149cd92023-03-10 19:01:41 +08001070 break;
1071 default:
1072 return -EINVAL;
1073 }
1074
developerc7b857b2023-03-28 22:37:02 +08001075 if (ret) {
developer2149cd92023-03-10 19:01:41 +08001076 dev_err(&phydev->mdio.dev, "[%s]cal failed\n", cal_prop[cal_item]);
1077 return -EIO;
1078 }
1079
developer2149cd92023-03-10 19:01:41 +08001080 return 0;
1081}
1082
developerf35532c2022-08-05 18:37:26 +08001083static int mt798x_phy_calibration(struct phy_device *phydev)
developerc50c2352021-12-01 10:45:35 +08001084{
developer2149cd92023-03-10 19:01:41 +08001085 int ret = 0;
developerc50c2352021-12-01 10:45:35 +08001086 u32 *buf;
developerc50c2352021-12-01 10:45:35 +08001087 size_t len;
1088 struct nvmem_cell *cell;
1089
1090 if (phydev->interface != PHY_INTERFACE_MODE_GMII)
1091 return -EINVAL;
1092
1093 cell = nvmem_cell_get(&phydev->mdio.dev, "phy-cal-data");
1094 if (IS_ERR(cell)) {
1095 if (PTR_ERR(cell) == -EPROBE_DEFER)
1096 return PTR_ERR(cell);
1097 return 0;
1098 }
1099
1100 buf = (u32 *)nvmem_cell_read(cell, &len);
1101 if (IS_ERR(buf))
1102 return PTR_ERR(buf);
1103 nvmem_cell_put(cell);
1104
developerc7b857b2023-03-28 22:37:02 +08001105 if (!buf[0] || !buf[1] || !buf[2] || !buf[3] || len < 4 * sizeof(u32)) {
1106 dev_err(&phydev->mdio.dev, "invalid efuse data\n");
developerc50c2352021-12-01 10:45:35 +08001107 ret = -EINVAL;
1108 goto out;
1109 }
1110
developerc7b857b2023-03-28 22:37:02 +08001111 ret = start_cal(phydev, REXT, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001112 if (ret)
1113 goto out;
developerc7b857b2023-03-28 22:37:02 +08001114 ret = start_cal(phydev, TX_OFFSET, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001115 if (ret)
1116 goto out;
developerc7b857b2023-03-28 22:37:02 +08001117 ret = start_cal(phydev, TX_AMP, EFUSE_M, NO_PAIR, NO_PAIR, buf);
developer2149cd92023-03-10 19:01:41 +08001118 if (ret)
1119 goto out;
developerc7b857b2023-03-28 22:37:02 +08001120 ret = start_cal(phydev, TX_R50, EFUSE_M, PAIR_A, PAIR_D, buf);
developer2149cd92023-03-10 19:01:41 +08001121 if (ret)
1122 goto out;
developerc7b857b2023-03-28 22:37:02 +08001123 ret = start_cal(phydev, TX_VCM, SW_M, PAIR_A, PAIR_A, buf);
developer2149cd92023-03-10 19:01:41 +08001124 if (ret)
1125 goto out;
developerc50c2352021-12-01 10:45:35 +08001126
1127out:
1128 kfree(buf);
1129 return ret;
1130}
1131
developer68f6e102022-11-22 17:35:00 +08001132static int mt7981_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001133{
1134 mt7981_phy_finetune(phydev);
1135
1136 return mt798x_phy_calibration(phydev);
1137}
1138
developer68f6e102022-11-22 17:35:00 +08001139static int mt7988_phy_probe(struct phy_device *phydev)
developerf35532c2022-08-05 18:37:26 +08001140{
1141 mt7988_phy_finetune(phydev);
1142
1143 return mt798x_phy_calibration(phydev);
1144}
developer2149cd92023-03-10 19:01:41 +08001145#endif
developerf35532c2022-08-05 18:37:26 +08001146
developerc50c2352021-12-01 10:45:35 +08001147static struct phy_driver mtk_gephy_driver[] = {
developerc50c2352021-12-01 10:45:35 +08001148 {
developer043f7b92023-03-13 13:57:36 +08001149 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
developerc50c2352021-12-01 10:45:35 +08001150 .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 {
developer043f7b92023-03-13 13:57:36 +08001163 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7531),
developerc50c2352021-12-01 10:45:35 +08001164 .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 },
developer2149cd92023-03-10 19:01:41 +08001176#ifdef CONFIG_MEDIATEK_GE_PHY_SOC
developerc50c2352021-12-01 10:45:35 +08001177 {
developer043f7b92023-03-13 13:57:36 +08001178 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
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 .config_intr = genphy_no_config_intr,
1182 .handle_interrupt = genphy_no_ack_interrupt,
1183 .suspend = genphy_suspend,
1184 .resume = genphy_resume,
1185 .read_page = mtk_gephy_read_page,
1186 .write_page = mtk_gephy_write_page,
1187 },
1188 {
developer043f7b92023-03-13 13:57:36 +08001189 PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
developerf35532c2022-08-05 18:37:26 +08001190 .name = "MediaTek MT7988 PHY",
1191 .probe = mt7988_phy_probe,
developerc50c2352021-12-01 10:45:35 +08001192 .config_intr = genphy_no_config_intr,
1193 .handle_interrupt = genphy_no_ack_interrupt,
1194 .suspend = genphy_suspend,
1195 .resume = genphy_resume,
1196 .read_page = mtk_gephy_read_page,
1197 .write_page = mtk_gephy_write_page,
1198 },
developer2149cd92023-03-10 19:01:41 +08001199#endif
developerc50c2352021-12-01 10:45:35 +08001200};
1201
1202module_phy_driver(mtk_gephy_driver);
1203
1204static struct mdio_device_id __maybe_unused mtk_gephy_tbl[] = {
1205 { PHY_ID_MATCH_VENDOR(0x03a29400) },
1206 { }
1207};
1208
1209MODULE_DESCRIPTION("MediaTek Gigabit Ethernet PHY driver");
developer2149cd92023-03-10 19:01:41 +08001210MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
1211MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
developerc50c2352021-12-01 10:45:35 +08001212MODULE_AUTHOR("DENG, Qingfang <dqfext@gmail.com>");
1213MODULE_LICENSE("GPL");
1214
1215MODULE_DEVICE_TABLE(mdio, mtk_gephy_tbl);