mac80211: rt2x00: experimental improvements for MT7620 wifi
[openwrt/staging/ansuel.git] / package / kernel / mac80211 / patches / rt2x00 / 992-rt2x00-more-fixes.patch
1 From: Daniel Golle <daniel@makrotopia.org>
2 Date: Mon, 12 Sep 2022 21:33:13 +0100
3 Subject: [PATCH] rt2x00: various experimental fixes for MT7620
4
5 Serge Vasilugin reports:
6
7 To improve mt7620 built-in wifi performance some changes:
8 1. Correct BW20/BW40 switching (see comments with mark see commets with mark (1))
9 2. Correct TX_SW_CFG1 MAC reg from v3 of vendor driver see
10 https://gitlab.com/dm38/padavan-ng/-/blob/master/trunk/proprietary/rt_wifi/rtpci/3.0.X.X/mt76x2/chips/rt6352.c#L531
11 3. Set bbp66 for all chains.
12 4. US_CYC_CNT init based on Programming guide, default value was 33 (pci),
13 set chipset bus clock with fallback to cpu clock/3.
14 5. Don't overwrite default values for mt7620.
15 6. Correct some typos.
16 7. Add support for external LNA:
17 a) RF and BBP regs never be corrected for this mode
18 b) eLNA is driven the same way as ePA with mt7620's pin PA
19 but vendor driver explicitly pin PA to gpio mode (for forrect calibration?)
20 so I'm not sure that request for pa_pin in dts-file will be enough
21
22 First 5 changes (really 2) improve performance for boards w/o eLNA/ePA.
23 Changes 7 add support for eLNA
24
25 Configuration w/o eLAN/ePA and with eLNA show results
26 tx/rx (from router point of view) for each stream:
27 35-40/30-35 Mbps for HT20
28 65-70/60-65 Mbps for HT40
29
30 Yes. Max results for 2T2R client is 140-145/135-140
31 with peaks 160/150, It correspond to mediatek driver results.
32 Boards with ePA untested.
33
34 Reported-by: Serge Vasilugin <vasilugin@yandex.ru>
35 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
36 ---
37 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
38 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
39 @@ -137,6 +137,26 @@ static u8 rt2800_bbp_read(struct rt2x00_
40
41 return value;
42 }
43 +//serge: move here for use in test
44 +static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
45 + const u8 reg, const u8 value)
46 +{
47 + rt2800_bbp_write(rt2x00dev, 195, reg);
48 + rt2800_bbp_write(rt2x00dev, 196, value);
49 +}
50 +
51 +static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
52 + const u8 reg, const u8 value)
53 +{
54 + rt2800_bbp_write(rt2x00dev, 158, reg);
55 + rt2800_bbp_write(rt2x00dev, 159, value);
56 +}
57 +
58 +static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
59 +{
60 + rt2800_bbp_write(rt2x00dev, 158, reg);
61 + return rt2800_bbp_read(rt2x00dev, 159);
62 +}
63
64 static void rt2800_rfcsr_write(struct rt2x00_dev *rt2x00dev,
65 const unsigned int word, const u8 value)
66 @@ -284,6 +304,28 @@ static void rt2800_rf_write(struct rt2x0
67 mutex_unlock(&rt2x00dev->csr_mutex);
68 }
69
70 +void rt6352_enable_pa_pin(struct rt2x00_dev *rt2x00dev, int enable)
71 +{
72 + if (!rt2x00dev->pinctrl)
73 + return;
74 +
75 + if (enable) {
76 + if (!rt2x00dev->pins_default) {
77 + rt2x00_warn(rt2x00dev, "cannot enable PA pin! no default pinctrl\n");
78 + return;
79 + }
80 +
81 + pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_default);
82 + } else {
83 + if (!rt2x00dev->pins_pa_gpio) {
84 + rt2x00_warn(rt2x00dev, "cannot disable PA pin! no pa_gpio pinctrl\n");
85 + return;
86 + }
87 +
88 + pinctrl_select_state(rt2x00dev->pinctrl, rt2x00dev->pins_pa_gpio);
89 + }
90 +}
91 +
92 static const unsigned int rt2800_eeprom_map[EEPROM_WORD_COUNT] = {
93 [EEPROM_CHIP_ID] = 0x0000,
94 [EEPROM_VERSION] = 0x0001,
95 @@ -3801,6 +3843,20 @@ static void rt2800_config_channel_rf7620
96 rfcsr |= tx_agc_fc;
97 rt2800_rfcsr_write_bank(rt2x00dev, 7, 59, rfcsr);
98 }
99 +
100 + if (conf_is_ht40(conf)) {//serge:skipped this step (1)
101 + rt2800_bbp_write(rt2x00dev, 195, 141);
102 + rt2800_bbp_write(rt2x00dev, 196, 0x10);
103 + rt2800_bbp_write(rt2x00dev, 195, 157);
104 + rt2800_bbp_write(rt2x00dev, 196, 0x2f);
105 + //rt2800_bbp_write(rt2x00dev, 105, 0x3C);
106 + } else {
107 + rt2800_bbp_write(rt2x00dev, 195, 141);
108 + rt2800_bbp_write(rt2x00dev, 196, 0x1a);
109 + rt2800_bbp_write(rt2x00dev, 195, 157);
110 + rt2800_bbp_write(rt2x00dev, 196, 0x40);
111 + //rt2800_bbp_write(rt2x00dev, 105, 0x1C);
112 + }
113 }
114
115 static void rt2800_config_alc(struct rt2x00_dev *rt2x00dev,
116 @@ -4172,6 +4228,11 @@ static void rt2800_config_channel(struct
117 rt2800_bbp_write(rt2x00dev, 86, 0x46);
118 else
119 rt2800_bbp_write(rt2x00dev, 86, 0);
120 + } else if (rt2x00_rt(rt2x00dev, RT6352)) {//serge: don't overwite bbp r86 (5)
121 + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
122 + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
123 + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
124 + rt2800_bbp_write(rt2x00dev, 86, 0x38);
125 } else {
126 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
127 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
128 @@ -4377,7 +4438,8 @@ static void rt2800_config_channel(struct
129 reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain;
130 rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
131
132 - rt2800_iq_calibrate(rt2x00dev, rf->channel);
133 + if (!rt2x00_rt(rt2x00dev, RT6352))//serge: this function for rt5592 only, for rt6352 it switch off compensations (5)
134 + rt2800_iq_calibrate(rt2x00dev, rf->channel);
135 }
136
137 if (rt2x00_rt(rt2x00dev, RT6352)) {
138 @@ -4417,6 +4479,31 @@ static void rt2800_config_channel(struct
139 rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
140 0x6C6C6B6C);
141 }
142 +
143 + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {//serge: for support eLNA (7a)
144 + rt2x00_warn(rt2x00dev, "Correct RF/BBP for eLNA!\n");
145 + reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
146 + reg |= 0x00000101;
147 + rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
148 +
149 + reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
150 + reg |= 0x00000101;
151 + rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
152 +
153 + rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
154 + rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
155 + rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
156 + rt2800_bbp_write(rt2x00dev, 75, 0x68);//serge: move bbp eLNA init here?
157 + rt2800_bbp_write(rt2x00dev, 76, 0x4C);
158 + rt2800_bbp_write(rt2x00dev, 79, 0x1C);
159 + rt2800_bbp_write(rt2x00dev, 80, 0x0C);
160 + rt2800_bbp_write(rt2x00dev, 82, 0xB6);
161 + /* bank 0 RF reg 42 and glrt BBP reg 141
162 + will be set in config channel function
163 + in dependence of channel and HT20/HT40
164 + so don't touch it
165 + */
166 + }
167 }
168
169 bbp = rt2800_bbp_read(rt2x00dev, 4);
170 @@ -4457,6 +4544,9 @@ static void rt2800_config_channel(struct
171 rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
172 rt2800_bbp_write(rt2x00dev, 49, bbp);
173 }
174 +//serge:just print results after config channel - don't forget to remove nahren (c) <- this is copyright, not ref to comments :)
175 + bbp = rt2800_bbp_dcoc_read(rt2x00dev, 0x03);
176 + pr_info("BBP tx/rx compensation control=0x%02x\n", bbp);
177 }
178
179 static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
180 @@ -5527,7 +5617,7 @@ void rt2800_vco_calibration(struct rt2x0
181 }
182 rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
183
184 - if (rt2x00_rt(rt2x00dev, RT6352)) {
185 + if (rt2x00_rt(rt2x00dev, RT6352)) {//serge:remark - move all this code to rfcsr_6352 init?
186 if (rt2x00dev->default_ant.rx_chain_num == 1) {
187 rt2800_bbp_write(rt2x00dev, 91, 0x07);
188 rt2800_bbp_write(rt2x00dev, 95, 0x1A);
189 @@ -5695,7 +5785,8 @@ static inline void rt2800_set_vgc(struct
190 if (qual->vgc_level != vgc_level) {
191 if (rt2x00_rt(rt2x00dev, RT3572) ||
192 rt2x00_rt(rt2x00dev, RT3593) ||
193 - rt2x00_rt(rt2x00dev, RT3883)) {
194 + rt2x00_rt(rt2x00dev, RT3883) ||
195 + rt2x00_rt(rt2x00dev, RT6352)) {//serge: rt6352 too (3)
196 rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
197 vgc_level);
198 } else if (rt2x00_rt(rt2x00dev, RT5592)) {
199 @@ -5930,7 +6021,7 @@ static int rt2800_init_registers(struct
200 0x00550055);
201 } else {
202 rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
203 - rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
204 + rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0001);//serge:was 0x000C0000 (2)
205 rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
206 rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
207 rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
208 @@ -6195,6 +6286,29 @@ static int rt2800_init_registers(struct
209 reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
210 rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, 125);
211 rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
212 + } else if (rt2x00_is_soc(rt2x00dev)) {//serge:which value correct? (4)
213 + struct clk *clk = clk_get_sys("bus", NULL);
214 + int rate;
215 +
216 + if (IS_ERR(clk)) {
217 + rt2x00_warn(rt2x00dev, "system bus clock undefined\n");
218 + clk = clk_get_sys("cpu", NULL);
219 +
220 + if (IS_ERR(clk))
221 + rate = 125;
222 + else {
223 + rate = clk_get_rate(clk) / 3000000;
224 + clk_put(clk);
225 + }
226 + } else {
227 + rate = clk_get_rate(clk) / 1000000;
228 + clk_put(clk);
229 + }
230 +
231 + rt2x00_info(rt2x00dev, "set US_CYC=%dMHz\n", rate);
232 + reg = rt2800_register_read(rt2x00dev, US_CYC_CNT);
233 + rt2x00_set_field32(&reg, US_CYC_CNT_CLOCK_CYCLE, rate);
234 + rt2800_register_write(rt2x00dev, US_CYC_CNT, reg);
235 }
236
237 reg = rt2800_register_read(rt2x00dev, HT_FBK_CFG0);
238 @@ -6981,26 +7095,7 @@ static void rt2800_init_bbp_5592(struct
239 if (rt2x00_rt_rev_gte(rt2x00dev, RT5592, REV_RT5592C))
240 rt2800_bbp_write(rt2x00dev, 103, 0xc0);
241 }
242 -
243 -static void rt2800_bbp_glrt_write(struct rt2x00_dev *rt2x00dev,
244 - const u8 reg, const u8 value)
245 -{
246 - rt2800_bbp_write(rt2x00dev, 195, reg);
247 - rt2800_bbp_write(rt2x00dev, 196, value);
248 -}
249 -
250 -static void rt2800_bbp_dcoc_write(struct rt2x00_dev *rt2x00dev,
251 - const u8 reg, const u8 value)
252 -{
253 - rt2800_bbp_write(rt2x00dev, 158, reg);
254 - rt2800_bbp_write(rt2x00dev, 159, value);
255 -}
256 -
257 -static u8 rt2800_bbp_dcoc_read(struct rt2x00_dev *rt2x00dev, const u8 reg)
258 -{
259 - rt2800_bbp_write(rt2x00dev, 158, reg);
260 - return rt2800_bbp_read(rt2x00dev, 159);
261 -}
262 +//serge: move these function upper
263
264 static void rt2800_init_bbp_6352(struct rt2x00_dev *rt2x00dev)
265 {
266 @@ -8635,7 +8730,7 @@ static void rt2800_r_calibration(struct
267 r_cal_code = (u8)rcalcode;
268
269 rt2800_rfcsr_write_bank(rt2x00dev, 0, 7, r_cal_code);
270 -
271 + pr_info("RF bank 0 reg 5=0x%02x\n", r_cal_code);//serge: just for info to compare with vendor driver
272 rt2800_bbp_write(rt2x00dev, 22, 0x0);
273
274 bytevalue = rt2800_bbp_read(rt2x00dev, 21);
275 @@ -8693,7 +8788,7 @@ static void rt2800_rxdcoc_calibration(st
276 break;
277 }
278
279 - saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
280 + saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);//serge: was 0 - typo? (6)
281 saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
282 saverfb5r4 = saverfb5r4 & (~0x40);
283 saverfb7r4 = saverfb7r4 & (~0x40);
284 @@ -9022,13 +9117,15 @@ static void rt2800_rxiq_calibration(stru
285 rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx);
286
287 if ((ph_rx > 20) || (ph_rx < -20)) {
288 + rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL(ph_rx=%d out of [-20..20]", ph_rx);//serge:just to see value
289 ph_rx = 0;
290 - rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
291 + //rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
292 }
293
294 if ((g_imb > 12) || (g_imb < -12)) {
295 + rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL(g_imb=%d out of (-12..12]", g_imb);//serge:just to see the reason
296 g_imb = 0;
297 - rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
298 + //rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
299 }
300 }
301 else {
302 @@ -9039,11 +9136,21 @@ static void rt2800_rxiq_calibration(stru
303 }
304
305 if (ch_idx == 0) {
306 + //serge: just to see values
307 + pr_info("RXIQ RX0 g_imb (0x37, %2x) ph_rx (0x35, %2x)\n",
308 + g_imb & 0x3f,
309 + ph_rx & 0x3f
310 + );
311 rt2800_bbp_write(rt2x00dev, 158, 0x37);
312 rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
313 rt2800_bbp_write(rt2x00dev, 158, 0x35);
314 rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
315 } else {
316 + //serge: just to see values
317 + pr_info("RXIQ RX1 g_imb (0x55, %2x) ph_rx (0x53, %2x)\n",
318 + g_imb & 0x3f,
319 + ph_rx & 0x3f
320 + );
321 rt2800_bbp_write(rt2x00dev, 158, 0x55);
322 rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
323 rt2800_bbp_write(rt2x00dev, 158, 0x53);
324 @@ -9745,6 +9852,15 @@ void rt2800_loft_iq_calibration(struct r
325 }
326
327 for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
328 + //serge: just to see values
329 + pr_info("LOFT ALC (0xb0, %2x) I0 (0xb1, %2x) Q0 (0xb2, %2x) I1 (0xb8, %2x) Q1 (0xb9, %2x)\n",
330 + rf_alc_idx,
331 + loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00] & 0x3F,
332 + loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01] & 0x3F,
333 + loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00] & 0x3F,
334 + loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01] & 0x3F
335 + );
336 +
337 for (idx = 0; idx < 4; idx++) {
338 rt2800_bbp_write(rt2x00dev, 158, 0xB0);
339 bbp = (idx<<2) + rf_alc_idx;
340 @@ -10669,6 +10785,7 @@ static void rt2800_init_rfcsr_6352(struc
341 rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
342 }
343
344 + rt6352_enable_pa_pin(rt2x00dev, 0);//serge: vendor driver do it before calibration (7b)
345 rt2800_r_calibration(rt2x00dev);
346 rt2800_rf_self_txdc_cal(rt2x00dev);
347 rt2800_rxdcoc_calibration(rt2x00dev);
348 @@ -10676,6 +10793,29 @@ static void rt2800_init_rfcsr_6352(struc
349 rt2800_bw_filter_calibration(rt2x00dev, false);
350 rt2800_loft_iq_calibration(rt2x00dev);
351 rt2800_rxiq_calibration(rt2x00dev);
352 + rt6352_enable_pa_pin(rt2x00dev, 1);//serge: vendor driver do it after calibration (7b)
353 + /* Vendor driver restore iLNA/iPA before
354 + recalibration and set correct values after.
355 + Openwrt driver init iLNA and iPA but restore only
356 + ePA values after recalibration.
357 + So set eLNA values only
358 + */
359 + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {//serge: rf regs never corrected for eLNA (7a)
360 + rt2x00_info(rt2x00dev, "Correct RF/BBP for eLNA!\n");
361 + rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x66);
362 + rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x20);
363 + rt2800_rfcsr_write_chanreg(rt2x00dev, 18, 0x42);
364 + rt2800_bbp_write(rt2x00dev, 75, 0x68);//serge: move bbp eLNA init here?
365 + rt2800_bbp_write(rt2x00dev, 76, 0x4C);
366 + rt2800_bbp_write(rt2x00dev, 79, 0x1C);
367 + rt2800_bbp_write(rt2x00dev, 80, 0x0C);
368 + rt2800_bbp_write(rt2x00dev, 82, 0xB6);
369 + /* bank 0 RF reg 42 and glrt BBP reg 141
370 + will be set in config channel function
371 + in dependence of channel and HT20/HT40
372 + so don't touch it
373 + */
374 + }
375 }
376
377 static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
378 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
379 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
380 @@ -28,6 +28,7 @@
381 #include <linux/average.h>
382 #include <linux/usb.h>
383 #include <linux/clk.h>
384 +#include <linux/pinctrl/consumer.h>
385 #include <linux/rt2x00_platform.h>
386
387 #include <net/mac80211.h>
388 @@ -1029,6 +1030,11 @@ struct rt2x00_dev {
389
390 /* Clock for System On Chip devices. */
391 struct clk *clk;
392 +
393 + /* pinctrl and states for System On Chip devices with PA/LNA. */
394 + struct pinctrl *pinctrl;
395 + struct pinctrl_state *pins_default;
396 + struct pinctrl_state *pins_pa_gpio;
397 };
398
399 struct rt2x00_bar_list_entry {
400 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
401 +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c
402 @@ -97,6 +97,21 @@ int rt2x00soc_probe(struct platform_devi
403 if (retval)
404 goto exit_free_reg;
405
406 + rt2x00dev->pinctrl = devm_pinctrl_get(&pdev->dev);
407 + if (IS_ERR(rt2x00dev->pinctrl)) {
408 + rt2x00dev->pinctrl = NULL;
409 + rt2x00dev->pins_default = NULL;
410 + rt2x00dev->pins_pa_gpio = NULL;
411 + } else {
412 + rt2x00dev->pins_default = pinctrl_lookup_state(rt2x00dev->pinctrl, "default");
413 + if (IS_ERR(rt2x00dev->pins_default))
414 + rt2x00dev->pins_default = NULL;
415 +
416 + rt2x00dev->pins_pa_gpio = pinctrl_lookup_state(rt2x00dev->pinctrl, "pa_gpio");
417 + if (IS_ERR(rt2x00dev->pins_pa_gpio))
418 + rt2x00dev->pins_pa_gpio = NULL;
419 + }
420 +
421 return 0;
422
423 exit_free_reg: