5daa62b6b792303f18e27137a518fa7acf2625d5
[openwrt/staging/stintel.git] /
1 From f2195279c234c0f618946424b8236026126bc595 Mon Sep 17 00:00:00 2001
2 Message-ID: <f2195279c234c0f618946424b8236026126bc595.1706071311.git.daniel@makrotopia.org>
3 From: Daniel Golle <daniel@makrotopia.org>
4 Date: Wed, 24 Jan 2024 02:27:04 +0000
5 Subject: [PATCH net] net: phy: mediatek-ge-soc: sync driver with MediaTek SDK
6 To: Daniel Golle <daniel@makrotopia.org>,
7 Qingfang Deng <dqfext@gmail.com>,
8 SkyLake Huang <SkyLake.Huang@mediatek.com>,
9 Andrew Lunn <andrew@lunn.ch>,
10 Heiner Kallweit <hkallweit1@gmail.com>,
11 Russell King <linux@armlinux.org.uk>,
12 David S. Miller <davem@davemloft.net>,
13 Eric Dumazet <edumazet@google.com>,
14 Jakub Kicinski <kuba@kernel.org>,
15 Paolo Abeni <pabeni@redhat.com>,
16 Matthias Brugger <matthias.bgg@gmail.com>,
17 AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>,
18 netdev@vger.kernel.org,
19 linux-kernel@vger.kernel.org,
20 linux-arm-kernel@lists.infradead.org,
21 linux-mediatek@lists.infradead.org
22
23 Sync initialization and calibration routines with MediaTek's reference
24 driver. Improves compliance and resolves link stability issues with
25 CH340 IoT devices connected to MT798x built-in PHYs.
26
27 Fixes: 98c485eaf509 ("net: phy: add driver for MediaTek SoC built-in GE PHYs")
28 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
29 ---
30 drivers/net/phy/mediatek-ge-soc.c | 147 ++++++++++++++++--------------
31 1 file changed, 81 insertions(+), 66 deletions(-)
32
33 --- a/drivers/net/phy/mediatek-ge-soc.c
34 +++ b/drivers/net/phy/mediatek-ge-soc.c
35 @@ -491,7 +491,7 @@ static int tx_r50_fill_result(struct phy
36 u16 reg, val;
37
38 if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
39 - bias = -2;
40 + bias = -1;
41
42 val = clamp_val(bias + tx_r50_cal_val, 0, 63);
43
44 @@ -707,6 +707,11 @@ restore:
45 static void mt798x_phy_common_finetune(struct phy_device *phydev)
46 {
47 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
48 + /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
49 + __phy_write(phydev, 0x11, 0xc71);
50 + __phy_write(phydev, 0x12, 0xc);
51 + __phy_write(phydev, 0x10, 0x8fae);
52 +
53 /* EnabRandUpdTrig = 1 */
54 __phy_write(phydev, 0x11, 0x2f00);
55 __phy_write(phydev, 0x12, 0xe);
56 @@ -717,15 +722,56 @@ static void mt798x_phy_common_finetune(s
57 __phy_write(phydev, 0x12, 0x0);
58 __phy_write(phydev, 0x10, 0x83aa);
59
60 - /* TrFreeze = 0 */
61 + /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
62 + __phy_write(phydev, 0x11, 0x240);
63 + __phy_write(phydev, 0x12, 0x0);
64 + __phy_write(phydev, 0x10, 0x9680);
65 +
66 + /* TrFreeze = 0 (mt7988 default) */
67 __phy_write(phydev, 0x11, 0x0);
68 __phy_write(phydev, 0x12, 0x0);
69 __phy_write(phydev, 0x10, 0x9686);
70
71 + /* SSTrKp100 = 5 */
72 + /* SSTrKf100 = 6 */
73 + /* SSTrKp1000Mas = 5 */
74 + /* SSTrKf1000Mas = 6 */
75 /* SSTrKp1000Slv = 5 */
76 + /* SSTrKf1000Slv = 6 */
77 __phy_write(phydev, 0x11, 0xbaef);
78 __phy_write(phydev, 0x12, 0x2e);
79 __phy_write(phydev, 0x10, 0x968c);
80 + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
81 +}
82 +
83 +static void mt7981_phy_finetune(struct phy_device *phydev)
84 +{
85 + u16 val[8] = { 0x01ce, 0x01c1,
86 + 0x020f, 0x0202,
87 + 0x03d0, 0x03c0,
88 + 0x0013, 0x0005 };
89 + int i, k;
90 +
91 + /* 100M eye finetune:
92 + * Keep middle level of TX MLT3 shapper as default.
93 + * Only change TX MLT3 overshoot level here.
94 + */
95 + for (k = 0, i = 1; i < 12; i++) {
96 + if (i % 3 == 0)
97 + continue;
98 + phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
99 + }
100 +
101 + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
102 + /* ResetSyncOffset = 6 */
103 + __phy_write(phydev, 0x11, 0x600);
104 + __phy_write(phydev, 0x12, 0x0);
105 + __phy_write(phydev, 0x10, 0x8fc0);
106 +
107 + /* VgaDecRate = 1 */
108 + __phy_write(phydev, 0x11, 0x4c2a);
109 + __phy_write(phydev, 0x12, 0x3e);
110 + __phy_write(phydev, 0x10, 0x8fa4);
111
112 /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
113 * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
114 @@ -740,7 +786,7 @@ static void mt798x_phy_common_finetune(s
115 __phy_write(phydev, 0x10, 0x8ec0);
116 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
117
118 - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
119 + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
120 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
121 MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
122 BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
123 @@ -773,48 +819,6 @@ static void mt798x_phy_common_finetune(s
124 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
125 }
126
127 -static void mt7981_phy_finetune(struct phy_device *phydev)
128 -{
129 - u16 val[8] = { 0x01ce, 0x01c1,
130 - 0x020f, 0x0202,
131 - 0x03d0, 0x03c0,
132 - 0x0013, 0x0005 };
133 - int i, k;
134 -
135 - /* 100M eye finetune:
136 - * Keep middle level of TX MLT3 shapper as default.
137 - * Only change TX MLT3 overshoot level here.
138 - */
139 - for (k = 0, i = 1; i < 12; i++) {
140 - if (i % 3 == 0)
141 - continue;
142 - phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
143 - }
144 -
145 - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
146 - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
147 - __phy_write(phydev, 0x11, 0xc71);
148 - __phy_write(phydev, 0x12, 0xc);
149 - __phy_write(phydev, 0x10, 0x8fae);
150 -
151 - /* ResetSyncOffset = 6 */
152 - __phy_write(phydev, 0x11, 0x600);
153 - __phy_write(phydev, 0x12, 0x0);
154 - __phy_write(phydev, 0x10, 0x8fc0);
155 -
156 - /* VgaDecRate = 1 */
157 - __phy_write(phydev, 0x11, 0x4c2a);
158 - __phy_write(phydev, 0x12, 0x3e);
159 - __phy_write(phydev, 0x10, 0x8fa4);
160 -
161 - /* FfeUpdGainForce = 4 */
162 - __phy_write(phydev, 0x11, 0x240);
163 - __phy_write(phydev, 0x12, 0x0);
164 - __phy_write(phydev, 0x10, 0x9680);
165 -
166 - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
167 -}
168 -
169 static void mt7988_phy_finetune(struct phy_device *phydev)
170 {
171 u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182,
172 @@ -829,17 +833,7 @@ static void mt7988_phy_finetune(struct p
173 /* TCT finetune */
174 phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5);
175
176 - /* Disable TX power saving */
177 - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
178 - MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
179 -
180 phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
181 -
182 - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
183 - __phy_write(phydev, 0x11, 0x671);
184 - __phy_write(phydev, 0x12, 0xc);
185 - __phy_write(phydev, 0x10, 0x8fae);
186 -
187 /* ResetSyncOffset = 5 */
188 __phy_write(phydev, 0x11, 0x500);
189 __phy_write(phydev, 0x12, 0x0);
190 @@ -847,13 +841,27 @@ static void mt7988_phy_finetune(struct p
191
192 /* VgaDecRate is 1 at default on mt7988 */
193
194 - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
195 + /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
196 + * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
197 + */
198 + __phy_write(phydev, 0x11, 0xb90a);
199 + __phy_write(phydev, 0x12, 0x6f);
200 + __phy_write(phydev, 0x10, 0x8f82);
201 +
202 + /* RemAckCntLimitCtrl = 1 */
203 + __phy_write(phydev, 0x11, 0xfbba);
204 + __phy_write(phydev, 0x12, 0xc3);
205 + __phy_write(phydev, 0x10, 0x87f8);
206
207 - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
208 - /* TxClkOffset = 2 */
209 - __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
210 - FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
211 phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
212 +
213 + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
214 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
215 + MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
216 + BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
217 +
218 + /* rg_tr_lpf_cnt_val = 1023 */
219 + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
220 }
221
222 static void mt798x_phy_eee(struct phy_device *phydev)
223 @@ -886,11 +894,11 @@ static void mt798x_phy_eee(struct phy_de
224 MTK_PHY_LPI_SLV_SEND_TX_EN,
225 FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
226
227 - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
228 - MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
229 - MTK_PHY_LPI_TXPCS_LOC_RCV,
230 - FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
231 + /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
232 + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
233 + MTK_PHY_LPI_TXPCS_LOC_RCV);
234
235 + /* This also fixes some IoT issues, such as CH340 */
236 phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
237 MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
238 FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
239 @@ -924,7 +932,7 @@ static void mt798x_phy_eee(struct phy_de
240 __phy_write(phydev, 0x12, 0x0);
241 __phy_write(phydev, 0x10, 0x9690);
242
243 - /* REG_EEE_st2TrKf1000 = 3 */
244 + /* REG_EEE_st2TrKf1000 = 2 */
245 __phy_write(phydev, 0x11, 0x114f);
246 __phy_write(phydev, 0x12, 0x2);
247 __phy_write(phydev, 0x10, 0x969a);
248 @@ -949,7 +957,7 @@ static void mt798x_phy_eee(struct phy_de
249 __phy_write(phydev, 0x12, 0x0);
250 __phy_write(phydev, 0x10, 0x96b8);
251
252 - /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
253 + /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
254 __phy_write(phydev, 0x11, 0x1463);
255 __phy_write(phydev, 0x12, 0x0);
256 __phy_write(phydev, 0x10, 0x96ca);
257 @@ -1461,6 +1469,13 @@ static int mt7988_phy_probe(struct phy_d
258 if (err)
259 return err;
260
261 + /* Disable TX power saving at probing to:
262 + * 1. Meet common mode compliance test criteria
263 + * 2. Make sure that TX-VCM calibration works fine
264 + */
265 + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7,
266 + MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
267 +
268 return mt798x_phy_calibration(phydev);
269 }
270