1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2/* Copyright(c) 2019-2022 Realtek Corporation
3 */
4
5#include "coex.h"
6#include "debug.h"
7#include "mac.h"
8#include "phy.h"
9#include "reg.h"
10#include "rtw8852b.h"
11#include "rtw8852b_rfk.h"
12#include "rtw8852b_rfk_table.h"
13#include "rtw8852b_table.h"
14
15#define RTW8852B_RXDCK_VER 0x1
16#define RTW8852B_IQK_VER 0x2a
17#define RTW8852B_IQK_SS 2
18#define RTW8852B_RXK_GROUP_NR 4
19#define RTW8852B_TSSI_PATH_NR 2
20#define RTW8852B_RF_REL_VERSION 34
21#define RTW8852B_DPK_VER 0x0d
22#define RTW8852B_DPK_RF_PATH 2
23#define RTW8852B_DPK_KIP_REG_NUM 2
24
25#define _TSSI_DE_MASK GENMASK(21, 12)
26#define ADDC_T_AVG 100
27#define DPK_TXAGC_LOWER 0x2e
28#define DPK_TXAGC_UPPER 0x3f
29#define DPK_TXAGC_INVAL 0xff
30#define RFREG_MASKRXBB 0x003e0
31#define RFREG_MASKMODE 0xf0000
32
33enum rtw8852b_dpk_id {
34 LBK_RXIQK = 0x06,
35 SYNC = 0x10,
36 MDPK_IDL = 0x11,
37 MDPK_MPA = 0x12,
38 GAIN_LOSS = 0x13,
39 GAIN_CAL = 0x14,
40 DPK_RXAGC = 0x15,
41 KIP_PRESET = 0x16,
42 KIP_RESTORE = 0x17,
43 DPK_TXAGC = 0x19,
44 D_KIP_PRESET = 0x28,
45 D_TXAGC = 0x29,
46 D_RXAGC = 0x2a,
47 D_SYNC = 0x2b,
48 D_GAIN_LOSS = 0x2c,
49 D_MDPK_IDL = 0x2d,
50 D_GAIN_NORM = 0x2f,
51 D_KIP_THERMAL = 0x30,
52 D_KIP_RESTORE = 0x31
53};
54
55enum dpk_agc_step {
56 DPK_AGC_STEP_SYNC_DGAIN,
57 DPK_AGC_STEP_GAIN_ADJ,
58 DPK_AGC_STEP_GAIN_LOSS_IDX,
59 DPK_AGC_STEP_GL_GT_CRITERION,
60 DPK_AGC_STEP_GL_LT_CRITERION,
61 DPK_AGC_STEP_SET_TX_GAIN,
62};
63
64enum rtw8852b_iqk_type {
65 ID_TXAGC = 0x0,
66 ID_FLOK_COARSE = 0x1,
67 ID_FLOK_FINE = 0x2,
68 ID_TXK = 0x3,
69 ID_RXAGC = 0x4,
70 ID_RXK = 0x5,
71 ID_NBTXK = 0x6,
72 ID_NBRXK = 0x7,
73 ID_FLOK_VBUFFER = 0x8,
74 ID_A_FLOK_COARSE = 0x9,
75 ID_G_FLOK_COARSE = 0xa,
76 ID_A_FLOK_FINE = 0xb,
77 ID_G_FLOK_FINE = 0xc,
78 ID_IQK_RESTORE = 0x10,
79};
80
81static const u32 _tssi_trigger[RTW8852B_TSSI_PATH_NR] = {0x5820, 0x7820};
82static const u32 _tssi_cw_rpt_addr[RTW8852B_TSSI_PATH_NR] = {0x1c18, 0x3c18};
83static const u32 _tssi_cw_default_addr[RTW8852B_TSSI_PATH_NR][4] = {
84 {0x5634, 0x5630, 0x5630, 0x5630},
85 {0x7634, 0x7630, 0x7630, 0x7630} };
86static const u32 _tssi_cw_default_mask[4] = {
87 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff};
88static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852B] = {0x5858, 0x7858};
89static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852B] = {0x5860, 0x7860};
90static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852B] = {0x5838, 0x7838};
91static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852B] = {0x5840, 0x7840};
92static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852B] = {0x5848, 0x7848};
93static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852B] = {0x5850, 0x7850};
94static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852B] = {0x5828, 0x7828};
95static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852B] = {0x5830, 0x7830};
96static const u32 _a_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x190, 0x198, 0x350, 0x352};
97static const u32 _a_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x0f, 0x0f, 0x3f, 0x7f};
98static const u32 _a_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x1, 0x0, 0x0};
99static const u32 _g_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x212, 0x21c, 0x350, 0x360};
100static const u32 _g_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x00, 0x00, 0x28, 0x5f};
101static const u32 _g_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x2, 0x1};
102static const u32 _a_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0};
103static const u32 _a_track_range[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x6, 0x6};
104static const u32 _a_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e};
105static const u32 _a_itqt[RTW8852B_RXK_GROUP_NR] = {0x12, 0x12, 0x12, 0x1b};
106static const u32 _g_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0};
107static const u32 _g_track_range[RTW8852B_RXK_GROUP_NR] = {0x4, 0x4, 0x6, 0x6};
108static const u32 _g_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e};
109static const u32 _g_itqt[RTW8852B_RXK_GROUP_NR] = {0x09, 0x12, 0x1b, 0x24};
110
111static const u32 rtw8852b_backup_bb_regs[] = {0x2344, 0x5800, 0x7800};
112static const u32 rtw8852b_backup_rf_regs[] = {
113 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x1e, 0x0, 0x2, 0x5, 0x10005
114};
115
116#define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852b_backup_bb_regs)
117#define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852b_backup_rf_regs)
118
119static const struct rtw89_reg3_def rtw8852b_set_nondbcc_path01[] = {
120 {0x20fc, 0xffff0000, 0x0303},
121 {0x5864, 0x18000000, 0x3},
122 {0x7864, 0x18000000, 0x3},
123 {0x12b8, 0x40000000, 0x1},
124 {0x32b8, 0x40000000, 0x1},
125 {0x030c, 0xff000000, 0x13},
126 {0x032c, 0xffff0000, 0x0041},
127 {0x12b8, 0x10000000, 0x1},
128 {0x58c8, 0x01000000, 0x1},
129 {0x78c8, 0x01000000, 0x1},
130 {0x5864, 0xc0000000, 0x3},
131 {0x7864, 0xc0000000, 0x3},
132 {0x2008, 0x01ffffff, 0x1ffffff},
133 {0x0c1c, 0x00000004, 0x1},
134 {0x0700, 0x08000000, 0x1},
135 {0x0c70, 0x000003ff, 0x3ff},
136 {0x0c60, 0x00000003, 0x3},
137 {0x0c6c, 0x00000001, 0x1},
138 {0x58ac, 0x08000000, 0x1},
139 {0x78ac, 0x08000000, 0x1},
140 {0x0c3c, 0x00000200, 0x1},
141 {0x2344, 0x80000000, 0x1},
142 {0x4490, 0x80000000, 0x1},
143 {0x12a0, 0x00007000, 0x7},
144 {0x12a0, 0x00008000, 0x1},
145 {0x12a0, 0x00070000, 0x3},
146 {0x12a0, 0x00080000, 0x1},
147 {0x32a0, 0x00070000, 0x3},
148 {0x32a0, 0x00080000, 0x1},
149 {0x0700, 0x01000000, 0x1},
150 {0x0700, 0x06000000, 0x2},
151 {0x20fc, 0xffff0000, 0x3333},
152};
153
154static const struct rtw89_reg3_def rtw8852b_restore_nondbcc_path01[] = {
155 {0x20fc, 0xffff0000, 0x0303},
156 {0x12b8, 0x40000000, 0x0},
157 {0x32b8, 0x40000000, 0x0},
158 {0x5864, 0xc0000000, 0x0},
159 {0x7864, 0xc0000000, 0x0},
160 {0x2008, 0x01ffffff, 0x0000000},
161 {0x0c1c, 0x00000004, 0x0},
162 {0x0700, 0x08000000, 0x0},
163 {0x0c70, 0x0000001f, 0x03},
164 {0x0c70, 0x000003e0, 0x03},
165 {0x12a0, 0x000ff000, 0x00},
166 {0x32a0, 0x000ff000, 0x00},
167 {0x0700, 0x07000000, 0x0},
168 {0x20fc, 0xffff0000, 0x0000},
169 {0x58c8, 0x01000000, 0x0},
170 {0x78c8, 0x01000000, 0x0},
171 {0x0c3c, 0x00000200, 0x0},
172 {0x2344, 0x80000000, 0x0},
173};
174
175static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[])
176{
177 u32 i;
178
179 for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
180 backup_bb_reg_val[i] =
181 rtw89_phy_read32_mask(rtwdev, addr: rtw8852b_backup_bb_regs[i],
182 MASKDWORD);
183 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
184 fmt: "[RFK]backup bb reg : %x, value =%x\n",
185 rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]);
186 }
187}
188
189static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[],
190 u8 rf_path)
191{
192 u32 i;
193
194 for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
195 backup_rf_reg_val[i] =
196 rtw89_read_rf(rtwdev, rf_path,
197 addr: rtw8852b_backup_rf_regs[i], RFREG_MASK);
198 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
199 fmt: "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path,
200 rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]);
201 }
202}
203
204static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev,
205 const u32 backup_bb_reg_val[])
206{
207 u32 i;
208
209 for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
210 rtw89_phy_write32_mask(rtwdev, addr: rtw8852b_backup_bb_regs[i],
211 MASKDWORD, data: backup_bb_reg_val[i]);
212 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
213 fmt: "[RFK]restore bb reg : %x, value =%x\n",
214 rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]);
215 }
216}
217
218static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev,
219 const u32 backup_rf_reg_val[], u8 rf_path)
220{
221 u32 i;
222
223 for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
224 rtw89_write_rf(rtwdev, rf_path, addr: rtw8852b_backup_rf_regs[i],
225 RFREG_MASK, data: backup_rf_reg_val[i]);
226
227 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
228 fmt: "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path,
229 rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]);
230 }
231}
232
233static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev,
234 enum rtw89_rf_path path, bool is_bybb)
235{
236 if (is_bybb)
237 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x1);
238 else
239 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0);
240}
241
242static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev,
243 enum rtw89_rf_path path, bool is_bybb)
244{
245 if (is_bybb)
246 rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x1);
247 else
248 rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x0);
249}
250
251static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path)
252{
253 bool fail = true;
254 u32 val;
255 int ret;
256
257 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
258 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0);
259 if (ret)
260 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]NCTL1 IQK timeout!!!\n");
261
262 udelay(200);
263
264 if (!ret)
265 fail = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
266 rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, data: 0x0);
267
268 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, ret=%d\n", path, ret);
269 val = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD);
270 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, 0x8008 = 0x%x\n", path, val);
271
272 return fail;
273}
274
275static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
276{
277 u8 val;
278
279 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]dbcc_en: %x,PHY%d\n",
280 rtwdev->dbcc_en, phy_idx);
281
282 if (!rtwdev->dbcc_en) {
283 val = RF_AB;
284 } else {
285 if (phy_idx == RTW89_PHY_0)
286 val = RF_A;
287 else
288 val = RF_B;
289 }
290 return val;
291}
292
293static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
294 enum rtw89_rf_path path)
295{
296 rtw89_write_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_CLR, data: 0x0);
297 rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_LV, data: 0x0);
298 rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_LV, data: 0x1);
299 mdelay(1);
300}
301
302static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
303{
304 u8 path, dck_tune;
305 u32 rf_reg5;
306
307 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
308 fmt: "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n",
309 RTW8852B_RXDCK_VER, rtwdev->hal.cv);
310
311 for (path = 0; path < RF_PATH_NUM_8852B; path++) {
312 rf_reg5 = rtw89_read_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK);
313 dck_tune = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_FINE);
314
315 if (rtwdev->is_tssi_mode[path])
316 rtw89_phy_write32_mask(rtwdev,
317 R_P0_TSSI_TRK + (path << 13),
318 B_P0_TSSI_TRK_EN, data: 0x1);
319
320 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0);
321 rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_FINE, data: 0x0);
322 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
323 _set_rx_dck(rtwdev, phy, path);
324 rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_FINE, data: dck_tune);
325 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK, data: rf_reg5);
326
327 if (rtwdev->is_tssi_mode[path])
328 rtw89_phy_write32_mask(rtwdev,
329 R_P0_TSSI_TRK + (path << 13),
330 B_P0_TSSI_TRK_EN, data: 0x0);
331 }
332}
333
334static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
335{
336 u32 rf_reg5;
337 u32 rck_val;
338 u32 val;
339 int ret;
340
341 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] ====== S%d RCK ======\n", path);
342
343 rf_reg5 = rtw89_read_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK);
344
345 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0);
346 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
347
348 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] RF0x00 = 0x%05x\n",
349 rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK));
350
351 /* RCK trigger */
352 rtw89_write_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK, data: 0x00240);
353
354 ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30,
355 false, rtwdev, path, RR_RCKS, BIT(3));
356
357 rck_val = rtw89_read_rf(rtwdev, rf_path: path, RR_RCKC, RR_RCKC_CA);
358
359 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] rck_val = 0x%x, ret = %d\n",
360 rck_val, ret);
361
362 rtw89_write_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK, data: rck_val);
363 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK, data: rf_reg5);
364
365 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] RF 0x1b = 0x%x\n",
366 rtw89_read_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK));
367}
368
369static void _afe_init(struct rtw89_dev *rtwdev)
370{
371 rtw89_write32(rtwdev, R_AX_PHYREG_SET, data: 0xf);
372
373 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_afe_init_defs_tbl);
374}
375
376static void _drck(struct rtw89_dev *rtwdev)
377{
378 u32 rck_d;
379 u32 val;
380 int ret;
381
382 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]Ddie RCK start!!!\n");
383 rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, data: 0x1);
384
385 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
386 false, rtwdev, R_DRCK_RS, B_DRCK_RS_DONE);
387 if (ret)
388 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DRCK timeout\n");
389
390 rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, data: 0x0);
391 rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, data: 0x1);
392 udelay(1);
393 rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, data: 0x0);
394 rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RS, B_DRCK_RS_LPS);
395 rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_SEL, data: 0x0);
396 rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_CV, data: rck_d);
397
398 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0xc0cc = 0x%x\n",
399 rtw89_phy_read32_mask(rtwdev, R_DRCK_V1, MASKDWORD));
400}
401
402static void _addck_backup(struct rtw89_dev *rtwdev)
403{
404 struct rtw89_dack_info *dack = &rtwdev->dack;
405
406 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, data: 0x0);
407 dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0);
408 dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1);
409
410 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, data: 0x0);
411 dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0);
412 dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1);
413}
414
415static void _addck_reload(struct rtw89_dev *rtwdev)
416{
417 struct rtw89_dack_info *dack = &rtwdev->dack;
418
419 /* S0 */
420 rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL, data: dack->addck_d[0][0]);
421 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_VAL, data: dack->addck_d[0][1] >> 6);
422 rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL2, data: dack->addck_d[0][1] & 0x3f);
423 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, data: 0x3);
424
425 /* S1 */
426 rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL, data: dack->addck_d[1][0]);
427 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK0_VAL, data: dack->addck_d[1][1] >> 6);
428 rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL2, data: dack->addck_d[1][1] & 0x3f);
429 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, data: 0x3);
430}
431
432static void _dack_backup_s0(struct rtw89_dev *rtwdev)
433{
434 struct rtw89_dack_info *dack = &rtwdev->dack;
435 u8 i;
436
437 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1);
438
439 for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
440 rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, data: i);
441 dack->msbk_d[0][0][i] =
442 rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0);
443 rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, data: i);
444 dack->msbk_d[0][1][i] =
445 rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1);
446 }
447
448 dack->biask_d[0][0] =
449 rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00);
450 dack->biask_d[0][1] =
451 rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01);
452
453 dack->dadck_d[0][0] =
454 rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00);
455 dack->dadck_d[0][1] =
456 rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01);
457}
458
459static void _dack_backup_s1(struct rtw89_dev *rtwdev)
460{
461 struct rtw89_dack_info *dack = &rtwdev->dack;
462 u8 i;
463
464 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1);
465
466 for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
467 rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, data: i);
468 dack->msbk_d[1][0][i] =
469 rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S);
470 rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, data: i);
471 dack->msbk_d[1][1][i] =
472 rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S);
473 }
474
475 dack->biask_d[1][0] =
476 rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10);
477 dack->biask_d[1][1] =
478 rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11);
479
480 dack->dadck_d[1][0] =
481 rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10);
482 dack->dadck_d[1][1] =
483 rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11);
484}
485
486static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
487{
488 s32 dc_re = 0, dc_im = 0;
489 u32 tmp;
490 u32 i;
491
492 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
493 &rtw8852b_check_addc_defs_a_tbl,
494 &rtw8852b_check_addc_defs_b_tbl);
495
496 for (i = 0; i < ADDC_T_AVG; i++) {
497 tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD);
498 dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), index: 11);
499 dc_im += sign_extend32(FIELD_GET(0xfff, tmp), index: 11);
500 }
501
502 dc_re /= ADDC_T_AVG;
503 dc_im /= ADDC_T_AVG;
504
505 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
506 fmt: "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im);
507}
508
509static void _addck(struct rtw89_dev *rtwdev)
510{
511 struct rtw89_dack_info *dack = &rtwdev->dack;
512 u32 val;
513 int ret;
514
515 /* S0 */
516 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, data: 0x0);
517 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, mask: 0x30, data: 0x0);
518 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1);
519 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, data: 0x0);
520 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, data: 0x0);
521 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, data: 0x1);
522 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0xf);
523 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, data: 0x0);
524 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), data: 0x1);
525 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0x3);
526
527 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]before S0 ADDCK\n");
528 _check_addc(rtwdev, path: RF_PATH_A);
529
530 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, data: 0x1);
531 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, data: 0x0);
532 udelay(1);
533 rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, data: 0x1);
534
535 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
536 false, rtwdev, R_ADDCKR0, BIT(0));
537 if (ret) {
538 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 ADDCK timeout\n");
539 dack->addck_timeout[0] = true;
540 }
541 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]ADDCK ret = %d\n", ret);
542 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S0 ADDCK\n");
543 _check_addc(rtwdev, path: RF_PATH_A);
544
545 rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), data: 0x0);
546 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, data: 0x1);
547 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0xc);
548 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, data: 0x1);
549 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x0);
550
551 /* S1 */
552 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1);
553 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, data: 0x0);
554 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, data: 0x0);
555 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, data: 0x1);
556 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0xf);
557 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, data: 0x0);
558 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), data: 0x1);
559 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0x3);
560
561 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]before S1 ADDCK\n");
562 _check_addc(rtwdev, path: RF_PATH_B);
563
564 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, data: 0x1);
565 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, data: 0x0);
566 udelay(1);
567 rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, data: 0x1);
568
569 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
570 false, rtwdev, R_ADDCKR1, BIT(0));
571 if (ret) {
572 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 ADDCK timeout\n");
573 dack->addck_timeout[1] = true;
574 }
575 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]ADDCK ret = %d\n", ret);
576 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S1 ADDCK\n");
577 _check_addc(rtwdev, path: RF_PATH_B);
578
579 rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), data: 0x0);
580 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, data: 0x1);
581 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, data: 0xc);
582 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, data: 0x1);
583 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x0);
584}
585
586static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
587{
588 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
589 &rtw8852b_check_dadc_en_defs_a_tbl,
590 &rtw8852b_check_dadc_en_defs_b_tbl);
591
592 _check_addc(rtwdev, path);
593
594 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
595 &rtw8852b_check_dadc_dis_defs_a_tbl,
596 &rtw8852b_check_dadc_dis_defs_b_tbl);
597}
598
599static bool _dack_s0_check_done(struct rtw89_dev *rtwdev, bool part1)
600{
601 if (part1) {
602 if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 ||
603 rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0)
604 return false;
605 } else {
606 if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 ||
607 rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0)
608 return false;
609 }
610
611 return true;
612}
613
614static void _dack_s0(struct rtw89_dev *rtwdev)
615{
616 struct rtw89_dack_info *dack = &rtwdev->dack;
617 bool done;
618 int ret;
619
620 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s0_1_defs_tbl);
621
622 ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000,
623 false, rtwdev, true);
624 if (ret) {
625 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 MSBK timeout\n");
626 dack->msbk_timeout[0] = true;
627 }
628 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK ret = %d\n", ret);
629
630 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s0_2_defs_tbl);
631
632 ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000,
633 false, rtwdev, false);
634 if (ret) {
635 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 DADCK timeout\n");
636 dack->dadck_timeout[0] = true;
637 }
638 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK ret = %d\n", ret);
639
640 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s0_3_defs_tbl);
641
642 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S0 DADCK\n");
643
644 _dack_backup_s0(rtwdev);
645 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x0);
646}
647
648static bool _dack_s1_check_done(struct rtw89_dev *rtwdev, bool part1)
649{
650 if (part1) {
651 if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 &&
652 rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0)
653 return false;
654 } else {
655 if (rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK_S1P2_OK) == 0 &&
656 rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK_S1P3_OK) == 0)
657 return false;
658 }
659
660 return true;
661}
662
663static void _dack_s1(struct rtw89_dev *rtwdev)
664{
665 struct rtw89_dack_info *dack = &rtwdev->dack;
666 bool done;
667 int ret;
668
669 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s1_1_defs_tbl);
670
671 ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000,
672 false, rtwdev, true);
673 if (ret) {
674 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 MSBK timeout\n");
675 dack->msbk_timeout[1] = true;
676 }
677 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK ret = %d\n", ret);
678
679 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s1_2_defs_tbl);
680
681 ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000,
682 false, rtwdev, false);
683 if (ret) {
684 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 DADCK timeout\n");
685 dack->dadck_timeout[1] = true;
686 }
687 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK ret = %d\n", ret);
688
689 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dack_s1_3_defs_tbl);
690
691 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S1 DADCK\n");
692
693 _check_dadc(rtwdev, path: RF_PATH_B);
694 _dack_backup_s1(rtwdev);
695 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x0);
696}
697
698static void _dack(struct rtw89_dev *rtwdev)
699{
700 _dack_s0(rtwdev);
701 _dack_s1(rtwdev);
702}
703
704static void _dack_dump(struct rtw89_dev *rtwdev)
705{
706 struct rtw89_dack_info *dack = &rtwdev->dack;
707 u8 i;
708 u8 t;
709
710 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
711 fmt: "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n",
712 dack->addck_d[0][0], dack->addck_d[0][1]);
713 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
714 fmt: "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n",
715 dack->addck_d[1][0], dack->addck_d[1][1]);
716 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
717 fmt: "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
718 dack->dadck_d[0][0], dack->dadck_d[0][1]);
719 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
720 fmt: "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
721 dack->dadck_d[1][0], dack->dadck_d[1][1]);
722 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
723 fmt: "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n",
724 dack->biask_d[0][0], dack->biask_d[0][1]);
725 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
726 fmt: "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n",
727 dack->biask_d[1][0], dack->biask_d[1][1]);
728
729 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 MSBK ic:\n");
730 for (i = 0; i < 0x10; i++) {
731 t = dack->msbk_d[0][0][i];
732 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n", t);
733 }
734
735 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 MSBK qc:\n");
736 for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
737 t = dack->msbk_d[0][1][i];
738 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n", t);
739 }
740
741 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 MSBK ic:\n");
742 for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
743 t = dack->msbk_d[1][0][i];
744 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n", t);
745 }
746
747 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 MSBK qc:\n");
748 for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
749 t = dack->msbk_d[1][1][i];
750 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n", t);
751 }
752}
753
754static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
755{
756 struct rtw89_dack_info *dack = &rtwdev->dack;
757 u32 rf0_0, rf1_0;
758
759 dack->dack_done = false;
760 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK 0x1\n");
761 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK start!!!\n");
762
763 rf0_0 = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK);
764 rf1_0 = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK);
765 _afe_init(rtwdev);
766 _drck(rtwdev);
767
768 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_RSV1, RR_RSV1_RST, data: 0x0);
769 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x0);
770 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK, data: 0x337e1);
771 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK, data: 0x337e1);
772 _addck(rtwdev);
773 _addck_backup(rtwdev);
774 _addck_reload(rtwdev);
775
776 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MODOPT, RFREG_MASK, data: 0x0);
777 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MODOPT, RFREG_MASK, data: 0x0);
778 _dack(rtwdev);
779 _dack_dump(rtwdev);
780 dack->dack_done = true;
781
782 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK, data: rf0_0);
783 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK, data: rf1_0);
784 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_RSV1, RR_RSV1_RST, data: 0x1);
785 rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x1);
786 dack->dack_cnt++;
787 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK finish!!!\n");
788}
789
790static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
791{
792 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
793 u32 tmp;
794
795 switch (iqk_info->iqk_band[path]) {
796 case RTW89_BAND_2G:
797 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc);
798 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_SEL2G, data: 0x1);
799 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_CFGCH, RFREG_MASK);
800 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV4, RFREG_MASK, data: tmp);
801 break;
802 case RTW89_BAND_5G:
803 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc);
804 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_SEL5G, data: 0x1);
805 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_CFGCH, RFREG_MASK);
806 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV4, RFREG_MASK, data: tmp);
807 break;
808 default:
809 break;
810 }
811}
812
813static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
814 u8 path, u8 ktype)
815{
816 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
817 u32 iqk_cmd;
818 bool fail;
819
820 switch (ktype) {
821 case ID_FLOK_COARSE:
822 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
823 iqk_cmd = 0x108 | (1 << (4 + path));
824 break;
825 case ID_FLOK_FINE:
826 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
827 iqk_cmd = 0x208 | (1 << (4 + path));
828 break;
829 case ID_FLOK_VBUFFER:
830 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
831 iqk_cmd = 0x308 | (1 << (4 + path));
832 break;
833 case ID_TXK:
834 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
835 iqk_cmd = 0x008 | (1 << (path + 4)) |
836 (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8);
837 break;
838 case ID_RXAGC:
839 iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1);
840 break;
841 case ID_RXK:
842 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
843 iqk_cmd = 0x008 | (1 << (path + 4)) |
844 (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8);
845 break;
846 case ID_NBTXK:
847 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
848 rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, data: 0x011);
849 iqk_cmd = 0x408 | (1 << (4 + path));
850 break;
851 case ID_NBRXK:
852 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
853 rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, data: 0x011);
854 iqk_cmd = 0x608 | (1 << (4 + path));
855 break;
856 default:
857 return false;
858 }
859
860 rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, data: iqk_cmd + 1);
861 udelay(1);
862 fail = _iqk_check_cal(rtwdev, path);
863 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
864
865 return fail;
866}
867
868static bool _rxk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
869 u8 path)
870{
871 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
872 bool kfail = false;
873 bool fail;
874 u8 gp;
875
876 for (gp = 0; gp < RTW8852B_RXK_GROUP_NR; gp++) {
877 switch (iqk_info->iqk_band[path]) {
878 case RTW89_BAND_2G:
879 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_RGM,
880 data: _g_idxrxgain[gp]);
881 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_C2G,
882 data: _g_idxattc2[gp]);
883 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_C1G,
884 data: _g_idxattc1[gp]);
885 break;
886 case RTW89_BAND_5G:
887 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_RGM,
888 data: _a_idxrxgain[gp]);
889 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_HATT,
890 data: _a_idxattc2[gp]);
891 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_CC2,
892 data: _a_idxattc1[gp]);
893 break;
894 default:
895 break;
896 }
897
898 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
899 B_CFIR_LUT_SEL, data: 0x1);
900 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
901 B_CFIR_LUT_SET, data: 0x0);
902 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
903 B_CFIR_LUT_GP_V1, data: gp);
904 fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_RXK);
905 rtw89_phy_write32_mask(rtwdev, R_IQKINF,
906 BIT(16 + gp + path * 4), data: fail);
907 kfail |= fail;
908 }
909 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_SEL5G, data: 0x0);
910
911 if (kfail) {
912 iqk_info->nb_rxcfir[path] = 0x40000002;
913 rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
914 B_IQK_RES_RXCFIR, data: 0x0);
915 iqk_info->is_wb_rxiqk[path] = false;
916 } else {
917 iqk_info->nb_rxcfir[path] = 0x40000000;
918 rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
919 B_IQK_RES_RXCFIR, data: 0x5);
920 iqk_info->is_wb_rxiqk[path] = true;
921 }
922
923 return kfail;
924}
925
926static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
927 u8 path)
928{
929 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
930 const u8 gp = 0x3;
931 bool kfail = false;
932 bool fail;
933
934 switch (iqk_info->iqk_band[path]) {
935 case RTW89_BAND_2G:
936 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_RGM,
937 data: _g_idxrxgain[gp]);
938 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_C2G,
939 data: _g_idxattc2[gp]);
940 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_C1G,
941 data: _g_idxattc1[gp]);
942 break;
943 case RTW89_BAND_5G:
944 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_RGM,
945 data: _a_idxrxgain[gp]);
946 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_HATT,
947 data: _a_idxattc2[gp]);
948 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_CC2,
949 data: _a_idxattc1[gp]);
950 break;
951 default:
952 break;
953 }
954
955 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, data: 0x1);
956 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, data: 0x0);
957 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, data: gp);
958 rtw89_write_rf(rtwdev, rf_path: path, RR_RXKPLL, RFREG_MASK, data: 0x80013);
959 udelay(1);
960
961 fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_NBRXK);
962 rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), data: fail);
963 kfail |= fail;
964 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_SEL5G, data: 0x0);
965
966 if (!kfail)
967 iqk_info->nb_rxcfir[path] =
968 rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD) | 0x2;
969 else
970 iqk_info->nb_rxcfir[path] = 0x40000002;
971
972 return kfail;
973}
974
975static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path)
976{
977 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
978
979 if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) {
980 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1);
981 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1);
982 udelay(1);
983 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x0f);
984 udelay(1);
985 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x03);
986 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0xa001);
987 udelay(1);
988 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0xa041);
989 rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, data: 0x2);
990 rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, data: 0x1);
991 rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, data: 0x2);
992 rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, data: 0x1);
993 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, data: 0x1);
994 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, data: 0x1);
995 } else {
996 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1);
997 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1);
998 udelay(1);
999 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x0f);
1000 udelay(1);
1001 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x03);
1002 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0xa001);
1003 udelay(1);
1004 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0xa041);
1005 rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, data: 0x1);
1006 rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, data: 0x1);
1007 rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, data: 0x1);
1008 rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, data: 0x1);
1009 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, data: 0x1);
1010 rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, data: 0x0);
1011 }
1012}
1013
1014static bool _txk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1015{
1016 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1017 bool kfail = false;
1018 bool fail;
1019 u8 gp;
1020
1021 for (gp = 0x0; gp < RTW8852B_RXK_GROUP_NR; gp++) {
1022 switch (iqk_info->iqk_band[path]) {
1023 case RTW89_BAND_2G:
1024 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0,
1025 data: _g_power_range[gp]);
1026 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1,
1027 data: _g_track_range[gp]);
1028 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG,
1029 data: _g_gain_bb[gp]);
1030 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1031 MASKDWORD, data: _g_itqt[gp]);
1032 break;
1033 case RTW89_BAND_5G:
1034 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0,
1035 data: _a_power_range[gp]);
1036 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1,
1037 data: _a_track_range[gp]);
1038 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG,
1039 data: _a_gain_bb[gp]);
1040 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1041 MASKDWORD, data: _a_itqt[gp]);
1042 break;
1043 default:
1044 break;
1045 }
1046
1047 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1048 B_CFIR_LUT_SEL, data: 0x1);
1049 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1050 B_CFIR_LUT_SET, data: 0x1);
1051 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1052 B_CFIR_LUT_G2, data: 0x0);
1053 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1054 B_CFIR_LUT_GP, data: gp);
1055 rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00);
1056 fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_TXK);
1057 rtw89_phy_write32_mask(rtwdev, R_IQKINF,
1058 BIT(8 + gp + path * 4), data: fail);
1059 kfail |= fail;
1060 }
1061
1062 if (kfail) {
1063 iqk_info->nb_txcfir[path] = 0x40000002;
1064 rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
1065 B_IQK_RES_TXCFIR, data: 0x0);
1066 iqk_info->is_wb_txiqk[path] = false;
1067 } else {
1068 iqk_info->nb_txcfir[path] = 0x40000000;
1069 rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
1070 B_IQK_RES_TXCFIR, data: 0x5);
1071 iqk_info->is_wb_txiqk[path] = true;
1072 }
1073
1074 return kfail;
1075}
1076
1077static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1078{
1079 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1080 bool kfail;
1081 u8 gp = 0x2;
1082
1083 switch (iqk_info->iqk_band[path]) {
1084 case RTW89_BAND_2G:
1085 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0,
1086 data: _g_power_range[gp]);
1087 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1,
1088 data: _g_track_range[gp]);
1089 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG,
1090 data: _g_gain_bb[gp]);
1091 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1092 MASKDWORD, data: _g_itqt[gp]);
1093 break;
1094 case RTW89_BAND_5G:
1095 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0,
1096 data: _a_power_range[gp]);
1097 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1,
1098 data: _a_track_range[gp]);
1099 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG,
1100 data: _a_gain_bb[gp]);
1101 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1102 MASKDWORD, data: _a_itqt[gp]);
1103 break;
1104 default:
1105 break;
1106 }
1107
1108 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, data: 0x1);
1109 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, data: 0x1);
1110 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, data: 0x0);
1111 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, data: gp);
1112 rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00);
1113 kfail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_NBTXK);
1114
1115 if (!kfail)
1116 iqk_info->nb_txcfir[path] =
1117 rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8),
1118 MASKDWORD) | 0x2;
1119 else
1120 iqk_info->nb_txcfir[path] = 0x40000002;
1121
1122 return kfail;
1123}
1124
1125static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias)
1126{
1127 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1128
1129 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===>%s\n", __func__);
1130 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, ibias = %x\n", path, ibias);
1131
1132 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RFREG_MASK, data: 0x2);
1133 if (iqk_info->iqk_band[path] == RTW89_BAND_2G)
1134 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RFREG_MASK, data: 0x0);
1135 else
1136 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RFREG_MASK, data: 0x1);
1137 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RFREG_MASK, data: ibias);
1138 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RFREG_MASK, data: 0x0);
1139 rtw89_write_rf(rtwdev, rf_path: path, RR_TXVBUF, RR_TXVBUF_DACEN, data: 0x1);
1140
1141 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, 0x7c = %x\n", path,
1142 rtw89_read_rf(rtwdev, rf_path: path, RR_TXVBUF, RFREG_MASK));
1143}
1144
1145static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
1146{
1147 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1148 bool is_fail1, is_fail2;
1149 u32 vbuff_i;
1150 u32 vbuff_q;
1151 u32 core_i;
1152 u32 core_q;
1153 u32 tmp;
1154 u8 ch;
1155
1156 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_TXMO, RFREG_MASK);
1157 core_i = FIELD_GET(RR_TXMO_COI, tmp);
1158 core_q = FIELD_GET(RR_TXMO_COQ, tmp);
1159 ch = (iqk_info->iqk_times / 2) % RTW89_IQK_CHS_NR;
1160
1161 if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d)
1162 is_fail1 = true;
1163 else
1164 is_fail1 = false;
1165
1166 iqk_info->lok_idac[ch][path] = tmp;
1167
1168 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_LOKVB, RFREG_MASK);
1169 vbuff_i = FIELD_GET(RR_LOKVB_COI, tmp);
1170 vbuff_q = FIELD_GET(RR_LOKVB_COQ, tmp);
1171
1172 if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d)
1173 is_fail2 = true;
1174 else
1175 is_fail2 = false;
1176
1177 iqk_info->lok_vbuf[ch][path] = tmp;
1178
1179 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1180 fmt: "[IQK]S%x, lok_idac[%x][%x] = 0x%x\n", path, ch, path,
1181 iqk_info->lok_idac[ch][path]);
1182 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1183 fmt: "[IQK]S%x, lok_vbuf[%x][%x] = 0x%x\n", path, ch, path,
1184 iqk_info->lok_vbuf[ch][path]);
1185
1186 return is_fail1 | is_fail2;
1187}
1188
1189static bool _iqk_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1190{
1191 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1192 bool tmp;
1193
1194 rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, data: 0x021);
1195
1196 switch (iqk_info->iqk_band[path]) {
1197 case RTW89_BAND_2G:
1198 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0);
1199 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x6);
1200 break;
1201 case RTW89_BAND_5G:
1202 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0);
1203 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x4);
1204 break;
1205 default:
1206 break;
1207 }
1208
1209 switch (iqk_info->iqk_band[path]) {
1210 case RTW89_BAND_2G:
1211 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x0);
1212 break;
1213 case RTW89_BAND_5G:
1214 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x0);
1215 break;
1216 default:
1217 break;
1218 }
1219
1220 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, data: 0x9);
1221 tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_COARSE);
1222 iqk_info->lok_cor_fail[0][path] = tmp;
1223
1224 switch (iqk_info->iqk_band[path]) {
1225 case RTW89_BAND_2G:
1226 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12);
1227 break;
1228 case RTW89_BAND_5G:
1229 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12);
1230 break;
1231 default:
1232 break;
1233 }
1234
1235 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, data: 0x24);
1236 tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_VBUFFER);
1237
1238 switch (iqk_info->iqk_band[path]) {
1239 case RTW89_BAND_2G:
1240 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x0);
1241 break;
1242 case RTW89_BAND_5G:
1243 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x0);
1244 break;
1245 default:
1246 break;
1247 }
1248
1249 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, data: 0x9);
1250 rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, data: 0x021);
1251 tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_FINE);
1252 iqk_info->lok_fin_fail[0][path] = tmp;
1253
1254 switch (iqk_info->iqk_band[path]) {
1255 case RTW89_BAND_2G:
1256 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12);
1257 break;
1258 case RTW89_BAND_5G:
1259 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12);
1260 break;
1261 default:
1262 break;
1263 }
1264
1265 rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, data: 0x24);
1266 _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_VBUFFER);
1267
1268 return _lok_finetune_check(rtwdev, path);
1269}
1270
1271static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path)
1272{
1273 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1274
1275 switch (iqk_info->iqk_band[path]) {
1276 case RTW89_BAND_2G:
1277 rtw89_write_rf(rtwdev, rf_path: path, RR_XALNA2, RR_XALNA2_SW2, data: 0x00);
1278 rtw89_write_rf(rtwdev, rf_path: path, RR_TXG1, RR_TXG1_ATT2, data: 0x0);
1279 rtw89_write_rf(rtwdev, rf_path: path, RR_TXG1, RR_TXG1_ATT1, data: 0x0);
1280 rtw89_write_rf(rtwdev, rf_path: path, RR_TXG2, RR_TXG2_ATT0, data: 0x1);
1281 rtw89_write_rf(rtwdev, rf_path: path, RR_TXGA, RR_TXGA_LOK_EXT, data: 0x0);
1282 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x1);
1283 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RR_LUTWA_M1, data: 0x00);
1284 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_IQK, data: 0x403e);
1285 udelay(1);
1286 break;
1287 case RTW89_BAND_5G:
1288 rtw89_write_rf(rtwdev, rf_path: path, RR_XGLNA2, RR_XGLNA2_SW, data: 0x00);
1289 rtw89_write_rf(rtwdev, rf_path: path, RR_BIASA, RR_BIASA_A, data: 0x1);
1290 rtw89_write_rf(rtwdev, rf_path: path, RR_TXGA, RR_TXGA_LOK_EXT, data: 0x0);
1291 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x1);
1292 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RR_LUTWA_M1, data: 0x80);
1293 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_IQK, data: 0x403e);
1294 udelay(1);
1295 break;
1296 default:
1297 break;
1298 }
1299}
1300
1301static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path)
1302{
1303 rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1);
1304 rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1);
1305 udelay(1);
1306 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x1f);
1307 udelay(1);
1308 rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x13);
1309 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0x0001);
1310 udelay(1);
1311 rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0x0041);
1312}
1313
1314static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1315{
1316 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1317 u32 tmp;
1318 bool flag;
1319
1320 flag = iqk_info->lok_cor_fail[0][path];
1321 rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), data: flag);
1322 flag = iqk_info->lok_fin_fail[0][path];
1323 rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), data: flag);
1324 flag = iqk_info->iqk_tx_fail[0][path];
1325 rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), data: flag);
1326 flag = iqk_info->iqk_rx_fail[0][path];
1327 rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), data: flag);
1328
1329 tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD);
1330 iqk_info->bp_iqkenable[path] = tmp;
1331 tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD);
1332 iqk_info->bp_txkresult[path] = tmp;
1333 tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD);
1334 iqk_info->bp_rxkresult[path] = tmp;
1335
1336 rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, data: iqk_info->iqk_times);
1337
1338 tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4));
1339 if (tmp)
1340 iqk_info->iqk_fail_cnt++;
1341 rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4),
1342 data: iqk_info->iqk_fail_cnt);
1343}
1344
1345static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1346{
1347 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1348 bool lok_is_fail = false;
1349 const int try = 3;
1350 u8 ibias = 0x1;
1351 u8 i;
1352
1353 _iqk_txclk_setting(rtwdev, path);
1354
1355 /* LOK */
1356 for (i = 0; i < try; i++) {
1357 _lok_res_table(rtwdev, path, ibias: ibias++);
1358 _iqk_txk_setting(rtwdev, path);
1359 lok_is_fail = _iqk_lok(rtwdev, phy_idx, path);
1360 if (!lok_is_fail)
1361 break;
1362 }
1363
1364 if (lok_is_fail)
1365 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK] LOK (%d) fail\n", path);
1366
1367 /* TXK */
1368 if (iqk_info->is_nbiqk)
1369 iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path);
1370 else
1371 iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path);
1372
1373 /* RX */
1374 _iqk_rxclk_setting(rtwdev, path);
1375 _iqk_rxk_setting(rtwdev, path);
1376 if (iqk_info->is_nbiqk)
1377 iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path);
1378 else
1379 iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path);
1380
1381 _iqk_info_iqk(rtwdev, phy_idx, path);
1382}
1383
1384static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path)
1385{
1386 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
1387 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1388 u32 reg_rf18;
1389 u32 reg_35c;
1390 u8 idx;
1391 u8 get_empty_table = false;
1392
1393 for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
1394 if (iqk_info->iqk_mcc_ch[idx][path] == 0) {
1395 get_empty_table = true;
1396 break;
1397 }
1398 }
1399 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK] (1)idx = %x\n", idx);
1400
1401 if (!get_empty_table) {
1402 idx = iqk_info->iqk_table_idx[path] + 1;
1403 if (idx > 1)
1404 idx = 0;
1405 }
1406 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK] (2)idx = %x\n", idx);
1407
1408 reg_rf18 = rtw89_read_rf(rtwdev, rf_path: path, RR_CFGCH, RFREG_MASK);
1409 reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN);
1410
1411 iqk_info->iqk_band[path] = chan->band_type;
1412 iqk_info->iqk_bw[path] = chan->band_width;
1413 iqk_info->iqk_ch[path] = chan->channel;
1414 iqk_info->iqk_mcc_ch[idx][path] = chan->channel;
1415 iqk_info->iqk_table_idx[path] = idx;
1416
1417 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, 0x18= 0x%x, idx = %x\n",
1418 path, reg_rf18, idx);
1419 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, 0x18= 0x%x\n",
1420 path, reg_rf18);
1421 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]times = 0x%x, ch =%x\n",
1422 iqk_info->iqk_times, idx);
1423 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n",
1424 idx, path, iqk_info->iqk_mcc_ch[idx][path]);
1425
1426 if (reg_35c == 0x01)
1427 iqk_info->syn1to2 = 0x1;
1428 else
1429 iqk_info->syn1to2 = 0x0;
1430
1431 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1432 fmt: "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", path,
1433 iqk_info->syn1to2);
1434
1435 rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852B_IQK_VER);
1436 /* 2GHz/5GHz/6GHz = 0/1/2 */
1437 rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16),
1438 data: iqk_info->iqk_band[path]);
1439 /* 20/40/80 = 0/1/2 */
1440 rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16),
1441 data: iqk_info->iqk_bw[path]);
1442 rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16),
1443 data: iqk_info->iqk_ch[path]);
1444}
1445
1446static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1447{
1448 _iqk_by_path(rtwdev, phy_idx, path);
1449}
1450
1451static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path)
1452{
1453 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1454 bool fail;
1455
1456 rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD,
1457 data: iqk_info->nb_txcfir[path]);
1458 rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD,
1459 data: iqk_info->nb_rxcfir[path]);
1460 rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD,
1461 data: 0x00000e19 + (path << 4));
1462 fail = _iqk_check_cal(rtwdev, path);
1463
1464 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "%s result =%x\n", __func__, fail);
1465
1466 rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00);
1467 rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, data: 0x00000000);
1468 rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, data: 0x80000000);
1469 rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS, B_IQK_RES_K, data: 0x0);
1470 rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K1, data: 0x0);
1471 rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, data: 0x0);
1472 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x0);
1473 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x0);
1474 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0x3);
1475 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x1);
1476 rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x1);
1477}
1478
1479static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
1480 enum rtw89_phy_idx phy_idx, u8 path)
1481{
1482 const struct rtw89_reg3_def *def;
1483 int size;
1484 u8 kpath;
1485 int i;
1486
1487 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "===> %s\n", __func__);
1488
1489 kpath = _kpath(rtwdev, phy_idx);
1490
1491 switch (kpath) {
1492 case RF_A:
1493 case RF_B:
1494 return;
1495 default:
1496 size = ARRAY_SIZE(rtw8852b_restore_nondbcc_path01);
1497 def = rtw8852b_restore_nondbcc_path01;
1498 break;
1499 }
1500
1501 for (i = 0; i < size; i++, def++)
1502 rtw89_phy_write32_mask(rtwdev, addr: def->addr, mask: def->mask, data: def->data);
1503}
1504
1505static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
1506{
1507 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1508 u8 idx;
1509
1510 idx = iqk_info->iqk_table_idx[path];
1511 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK] (3)idx = %x\n", idx);
1512
1513 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, data: idx);
1514 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, data: idx);
1515
1516 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0);
1517 rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x0);
1518 rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, data: 0x00000080);
1519 rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, data: 0x81ff010a);
1520
1521 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK](1)S%x, 0x8%x54 = 0x%x\n", path, 1 << path,
1522 rtw89_phy_read32_mask(rtwdev, R_CFIR_LUT + (path << 8), MASKDWORD));
1523 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK](1)S%x, 0x8%x04 = 0x%x\n", path, 1 << path,
1524 rtw89_phy_read32_mask(rtwdev, R_COEF_SEL + (path << 8), MASKDWORD));
1525}
1526
1527static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
1528 enum rtw89_phy_idx phy_idx, u8 path)
1529{
1530 const struct rtw89_reg3_def *def;
1531 int size;
1532 u8 kpath;
1533 int i;
1534
1535 kpath = _kpath(rtwdev, phy_idx);
1536
1537 switch (kpath) {
1538 case RF_A:
1539 case RF_B:
1540 return;
1541 default:
1542 size = ARRAY_SIZE(rtw8852b_set_nondbcc_path01);
1543 def = rtw8852b_set_nondbcc_path01;
1544 break;
1545 }
1546
1547 for (i = 0; i < size; i++, def++)
1548 rtw89_phy_write32_mask(rtwdev, addr: def->addr, mask: def->mask, data: def->data);
1549}
1550
1551static void _iqk_init(struct rtw89_dev *rtwdev)
1552{
1553 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1554 u8 idx, path;
1555
1556 rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, data: 0x0);
1557 if (iqk_info->is_iqk_init)
1558 return;
1559
1560 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===>%s\n", __func__);
1561 iqk_info->is_iqk_init = true;
1562 iqk_info->is_nbiqk = false;
1563 iqk_info->iqk_fft_en = false;
1564 iqk_info->iqk_sram_en = false;
1565 iqk_info->iqk_cfir_en = false;
1566 iqk_info->iqk_xym_en = false;
1567 iqk_info->iqk_times = 0x0;
1568
1569 for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
1570 iqk_info->iqk_channel[idx] = 0x0;
1571 for (path = 0; path < RTW8852B_IQK_SS; path++) {
1572 iqk_info->lok_cor_fail[idx][path] = false;
1573 iqk_info->lok_fin_fail[idx][path] = false;
1574 iqk_info->iqk_tx_fail[idx][path] = false;
1575 iqk_info->iqk_rx_fail[idx][path] = false;
1576 iqk_info->iqk_mcc_ch[idx][path] = 0x0;
1577 iqk_info->iqk_table_idx[path] = 0x0;
1578 }
1579 }
1580}
1581
1582static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
1583{
1584 u32 rf_mode;
1585 u8 path;
1586 int ret;
1587
1588 for (path = 0; path < RF_PATH_MAX; path++) {
1589 if (!(kpath & BIT(path)))
1590 continue;
1591
1592 ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode,
1593 rf_mode != 2, 2, 5000, false,
1594 rtwdev, path, RR_MOD, RR_MOD_MASK);
1595 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1596 fmt: "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret);
1597 }
1598}
1599
1600static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx,
1601 bool is_pause)
1602{
1603 if (!is_pause)
1604 return;
1605
1606 _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx: band_idx));
1607}
1608
1609static void _doiqk(struct rtw89_dev *rtwdev, bool force,
1610 enum rtw89_phy_idx phy_idx, u8 path)
1611{
1612 struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1613 u32 backup_bb_val[BACKUP_BB_REGS_NR];
1614 u32 backup_rf_val[RTW8852B_IQK_SS][BACKUP_RF_REGS_NR];
1615 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: RF_AB);
1616
1617 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_START);
1618
1619 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1620 fmt: "[IQK]==========IQK start!!!!!==========\n");
1621 iqk_info->iqk_times++;
1622 iqk_info->version = RTW8852B_IQK_VER;
1623
1624 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]Test Ver 0x%x\n", iqk_info->version);
1625 _iqk_get_ch_info(rtwdev, phy: phy_idx, path);
1626
1627 _rfk_backup_bb_reg(rtwdev, backup_bb_reg_val: &backup_bb_val[0]);
1628 _rfk_backup_rf_reg(rtwdev, backup_rf_reg_val: &backup_rf_val[path][0], rf_path: path);
1629 _iqk_macbb_setting(rtwdev, phy_idx, path);
1630 _iqk_preset(rtwdev, path);
1631 _iqk_start_iqk(rtwdev, phy_idx, path);
1632 _iqk_restore(rtwdev, path);
1633 _iqk_afebb_restore(rtwdev, phy_idx, path);
1634 _rfk_restore_bb_reg(rtwdev, backup_bb_reg_val: &backup_bb_val[0]);
1635 _rfk_restore_rf_reg(rtwdev, backup_rf_reg_val: &backup_rf_val[path][0], rf_path: path);
1636
1637 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_STOP);
1638}
1639
1640static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
1641{
1642 u8 kpath = _kpath(rtwdev, phy_idx);
1643
1644 switch (kpath) {
1645 case RF_A:
1646 _doiqk(rtwdev, force, phy_idx, path: RF_PATH_A);
1647 break;
1648 case RF_B:
1649 _doiqk(rtwdev, force, phy_idx, path: RF_PATH_B);
1650 break;
1651 case RF_AB:
1652 _doiqk(rtwdev, force, phy_idx, path: RF_PATH_A);
1653 _doiqk(rtwdev, force, phy_idx, path: RF_PATH_B);
1654 break;
1655 default:
1656 break;
1657 }
1658}
1659
1660static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[],
1661 u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path)
1662{
1663 u8 i;
1664
1665 for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) {
1666 reg_bkup[path][i] =
1667 rtw89_phy_read32_mask(rtwdev, addr: reg[i] + (path << 8), MASKDWORD);
1668 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Backup 0x%x = %x\n",
1669 reg[i] + (path << 8), reg_bkup[path][i]);
1670 }
1671}
1672
1673static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[],
1674 const u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path)
1675{
1676 u8 i;
1677
1678 for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) {
1679 rtw89_phy_write32_mask(rtwdev, addr: reg[i] + (path << 8), MASKDWORD,
1680 data: reg_bkup[path][i]);
1681 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Reload 0x%x = %x\n",
1682 reg[i] + (path << 8), reg_bkup[path][i]);
1683 }
1684}
1685
1686static u8 _dpk_order_convert(struct rtw89_dev *rtwdev)
1687{
1688 u8 order;
1689 u8 val;
1690
1691 order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP);
1692 val = 0x3 >> order;
1693
1694 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] convert MDPD order to 0x%x\n", val);
1695
1696 return val;
1697}
1698
1699static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off)
1700{
1701 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1702 u8 val, kidx = dpk->cur_idx[path];
1703
1704 val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok;
1705
1706 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
1707 MASKBYTE3, data: _dpk_order_convert(rtwdev) << 1 | val);
1708
1709 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d[%d] DPK %s !!!\n", path,
1710 kidx, dpk->is_dpk_enable && !off ? "enable" : "disable");
1711}
1712
1713static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
1714 enum rtw89_rf_path path, enum rtw8852b_dpk_id id)
1715{
1716 u16 dpk_cmd;
1717 u32 val;
1718 int ret;
1719
1720 dpk_cmd = (id << 8) | (0x19 + (path << 4));
1721 rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, data: dpk_cmd);
1722
1723 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
1724 1, 20000, false,
1725 rtwdev, 0xbff8, MASKBYTE0);
1726 if (ret)
1727 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] one-shot over 20ms!!!!\n");
1728
1729 udelay(1);
1730
1731 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, data: 0x00030000);
1732
1733 ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000,
1734 1, 2000, false,
1735 rtwdev, 0x80fc, MASKLWORD);
1736 if (ret)
1737 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] one-shot over 20ms!!!!\n");
1738
1739 rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, data: 0x0);
1740
1741 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1742 fmt: "[DPK] one-shot for %s = 0x%x\n",
1743 id == 0x06 ? "LBK_RXIQK" :
1744 id == 0x10 ? "SYNC" :
1745 id == 0x11 ? "MDPK_IDL" :
1746 id == 0x12 ? "MDPK_MPA" :
1747 id == 0x13 ? "GAIN_LOSS" :
1748 id == 0x14 ? "PWR_CAL" :
1749 id == 0x15 ? "DPK_RXAGC" :
1750 id == 0x16 ? "KIP_PRESET" :
1751 id == 0x17 ? "KIP_RESTORE" : "DPK_TXAGC",
1752 dpk_cmd);
1753}
1754
1755static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
1756 enum rtw89_rf_path path)
1757{
1758 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_EN_TIA_IDA, data: 0x3);
1759 _set_rx_dck(rtwdev, phy, path);
1760}
1761
1762static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
1763 enum rtw89_rf_path path)
1764{
1765 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
1766 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1767
1768 u8 kidx = dpk->cur_idx[path];
1769
1770 dpk->bp[path][kidx].band = chan->band_type;
1771 dpk->bp[path][kidx].ch = chan->channel;
1772 dpk->bp[path][kidx].bw = chan->band_width;
1773
1774 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1775 fmt: "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
1776 path, dpk->cur_idx[path], phy,
1777 rtwdev->is_tssi_mode[path] ? "on" : "off",
1778 rtwdev->dbcc_en ? "on" : "off",
1779 dpk->bp[path][kidx].band == 0 ? "2G" :
1780 dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
1781 dpk->bp[path][kidx].ch,
1782 dpk->bp[path][kidx].bw == 0 ? "20M" :
1783 dpk->bp[path][kidx].bw == 1 ? "40M" : "80M");
1784}
1785
1786static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
1787 enum rtw89_phy_idx phy,
1788 enum rtw89_rf_path path, u8 kpath)
1789{
1790 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
1791
1792 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dpk_afe_defs_tbl);
1793
1794 if (chan->band_width == RTW89_CHANNEL_WIDTH_80) {
1795 rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, data: 0x1);
1796 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, data: 0x1);
1797 }
1798
1799 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1800 fmt: "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath);
1801}
1802
1803static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev,
1804 enum rtw89_phy_idx phy,
1805 enum rtw89_rf_path path, u8 kpath)
1806{
1807 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
1808
1809 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dpk_afe_restore_defs_tbl);
1810
1811 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1812 fmt: "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath);
1813
1814 if (chan->band_width == RTW89_CHANNEL_WIDTH_80) {
1815 rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, data: 0x0);
1816 rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, data: 0x0);
1817 }
1818}
1819
1820static void _dpk_tssi_pause(struct rtw89_dev *rtwdev,
1821 enum rtw89_rf_path path, bool is_pause)
1822{
1823 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13),
1824 B_P0_TSSI_TRK_EN, data: is_pause);
1825
1826 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d TSSI %s\n", path,
1827 is_pause ? "pause" : "resume");
1828}
1829
1830static void _dpk_kip_restore(struct rtw89_dev *rtwdev,
1831 enum rtw89_rf_path path)
1832{
1833 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_dpk_kip_defs_tbl);
1834
1835 if (rtwdev->hal.cv > CHIP_CAV)
1836 rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), B_DPD_COM_OF, data: 0x1);
1837
1838 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d restore KIP\n", path);
1839}
1840
1841static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
1842 enum rtw89_rf_path path)
1843{
1844 u8 cur_rxbb;
1845 u32 tmp;
1846
1847 cur_rxbb = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASKRXBB);
1848
1849 rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, data: 0x1);
1850 rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, data: 0x0);
1851
1852 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_CFGCH, RFREG_MASK);
1853 rtw89_write_rf(rtwdev, rf_path: path, RR_RSV4, RFREG_MASK, data: tmp);
1854 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASKMODE, data: 0xd);
1855 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_PLLEN, data: 0x1);
1856
1857 if (cur_rxbb >= 0x11)
1858 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIQK, RR_TXIQK_ATT1, data: 0x13);
1859 else if (cur_rxbb <= 0xa)
1860 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIQK, RR_TXIQK_ATT1, data: 0x00);
1861 else
1862 rtw89_write_rf(rtwdev, rf_path: path, RR_TXIQK, RR_TXIQK_ATT1, data: 0x05);
1863
1864 rtw89_write_rf(rtwdev, rf_path: path, RR_XGLNA2, RR_XGLNA2_SW, data: 0x0);
1865 rtw89_write_rf(rtwdev, rf_path: path, RR_RXKPLL, RR_RXKPLL_POW, data: 0x0);
1866 rtw89_write_rf(rtwdev, rf_path: path, RR_RXKPLL, RFREG_MASK, data: 0x80014);
1867 udelay(70);
1868
1869 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
1870 rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, data: 0x025);
1871
1872 _dpk_one_shot(rtwdev, phy, path, id: LBK_RXIQK);
1873
1874 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d LBK RXIQC = 0x%x\n", path,
1875 rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD));
1876
1877 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
1878 rtw89_write_rf(rtwdev, rf_path: path, RR_RXK, RR_RXK_PLLEN, data: 0x0);
1879 rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, data: 0x0);
1880 rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, data: 0x0);
1881 rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, data: 0x1);
1882 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASKMODE, data: 0x5);
1883}
1884
1885static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path)
1886{
1887 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1888
1889 rtw89_write_rf(rtwdev, rf_path: path, RR_TM, RR_TM_TRI, data: 0x1);
1890 rtw89_write_rf(rtwdev, rf_path: path, RR_TM, RR_TM_TRI, data: 0x0);
1891 rtw89_write_rf(rtwdev, rf_path: path, RR_TM, RR_TM_TRI, data: 0x1);
1892
1893 udelay(200);
1894
1895 dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, rf_path: path, RR_TM, RR_TM_VAL);
1896
1897 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] thermal@DPK = 0x%x\n",
1898 dpk->bp[path][kidx].ther_dpk);
1899}
1900
1901static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain,
1902 enum rtw89_rf_path path, u8 kidx)
1903{
1904 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1905
1906 if (dpk->bp[path][kidx].band == RTW89_BAND_2G) {
1907 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, data: 0x50220);
1908 rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_FATT, data: 0xf2);
1909 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTDBG, RR_LUTDBG_TIA, data: 0x1);
1910 rtw89_write_rf(rtwdev, rf_path: path, RR_TIA, RR_TIA_N6, data: 0x1);
1911 } else {
1912 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, data: 0x50220);
1913 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RAA2_SWATT, data: 0x5);
1914 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTDBG, RR_LUTDBG_TIA, data: 0x1);
1915 rtw89_write_rf(rtwdev, rf_path: path, RR_TIA, RR_TIA_N6, data: 0x1);
1916 rtw89_write_rf(rtwdev, rf_path: path, RR_RXA_LNA, RFREG_MASK, data: 0x920FC);
1917 rtw89_write_rf(rtwdev, rf_path: path, RR_XALNA2, RFREG_MASK, data: 0x002C0);
1918 rtw89_write_rf(rtwdev, rf_path: path, RR_IQGEN, RFREG_MASK, data: 0x38800);
1919 }
1920
1921 rtw89_write_rf(rtwdev, rf_path: path, RR_RCKD, RR_RCKD_BW, data: 0x1);
1922 rtw89_write_rf(rtwdev, rf_path: path, RR_BTC, RR_BTC_TXBB, data: dpk->bp[path][kidx].bw + 1);
1923 rtw89_write_rf(rtwdev, rf_path: path, RR_BTC, RR_BTC_RXBB, data: 0x0);
1924
1925 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1926 fmt: "[DPK] ARF 0x0/0x11/0x1a = 0x%x/ 0x%x/ 0x%x\n",
1927 rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK),
1928 rtw89_read_rf(rtwdev, rf_path: path, RR_TXIG, RFREG_MASK),
1929 rtw89_read_rf(rtwdev, rf_path: path, RR_BTC, RFREG_MASK));
1930}
1931
1932static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev,
1933 enum rtw89_rf_path path, bool is_bypass)
1934{
1935 if (is_bypass) {
1936 rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
1937 B_RXIQC_BYPASS2, data: 0x1);
1938 rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
1939 B_RXIQC_BYPASS, data: 0x1);
1940 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1941 fmt: "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path,
1942 rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
1943 MASKDWORD));
1944 } else {
1945 rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2);
1946 rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS);
1947 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1948 fmt: "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path,
1949 rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
1950 MASKDWORD));
1951 }
1952}
1953
1954static
1955void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
1956{
1957 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1958
1959 if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80)
1960 rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F);
1961 else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40)
1962 rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x2);
1963 else
1964 rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x1);
1965
1966 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] TPG_Select for %s\n",
1967 dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" :
1968 dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M");
1969}
1970
1971static void _dpk_table_select(struct rtw89_dev *rtwdev,
1972 enum rtw89_rf_path path, u8 kidx, u8 gain)
1973{
1974 u8 val;
1975
1976 val = 0x80 + kidx * 0x20 + gain * 0x10;
1977 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, data: val);
1978 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1979 fmt: "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx,
1980 gain, val);
1981}
1982
1983static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
1984{
1985#define DPK_SYNC_TH_DC_I 200
1986#define DPK_SYNC_TH_DC_Q 200
1987#define DPK_SYNC_TH_CORR 170
1988 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
1989 u16 dc_i, dc_q;
1990 u8 corr_val, corr_idx;
1991
1992 rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL);
1993
1994 corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI);
1995 corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV);
1996
1997 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
1998 fmt: "[DPK] S%d Corr_idx / Corr_val = %d / %d\n",
1999 path, corr_idx, corr_val);
2000
2001 dpk->corr_idx[path][kidx] = corr_idx;
2002 dpk->corr_val[path][kidx] = corr_val;
2003
2004 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x9);
2005
2006 dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI);
2007 dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ);
2008
2009 dc_i = abs(sign_extend32(dc_i, 11));
2010 dc_q = abs(sign_extend32(dc_q, 11));
2011
2012 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d DC I/Q, = %d / %d\n",
2013 path, dc_i, dc_q);
2014
2015 dpk->dc_i[path][kidx] = dc_i;
2016 dpk->dc_q[path][kidx] = dc_q;
2017
2018 if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q ||
2019 corr_val < DPK_SYNC_TH_CORR)
2020 return true;
2021 else
2022 return false;
2023}
2024
2025static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2026 enum rtw89_rf_path path, u8 kidx)
2027{
2028 _dpk_one_shot(rtwdev, phy, path, id: SYNC);
2029
2030 return _dpk_sync_check(rtwdev, path, kidx);
2031}
2032
2033static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev)
2034{
2035 u16 dgain;
2036
2037 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x0);
2038
2039 dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI);
2040
2041 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] DGain = 0x%x\n", dgain);
2042
2043 return dgain;
2044}
2045
2046static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain)
2047{
2048 static const u16 bnd[15] = {
2049 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556,
2050 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220
2051 };
2052 s8 offset;
2053
2054 if (dgain >= bnd[0])
2055 offset = 0x6;
2056 else if (bnd[0] > dgain && dgain >= bnd[1])
2057 offset = 0x6;
2058 else if (bnd[1] > dgain && dgain >= bnd[2])
2059 offset = 0x5;
2060 else if (bnd[2] > dgain && dgain >= bnd[3])
2061 offset = 0x4;
2062 else if (bnd[3] > dgain && dgain >= bnd[4])
2063 offset = 0x3;
2064 else if (bnd[4] > dgain && dgain >= bnd[5])
2065 offset = 0x2;
2066 else if (bnd[5] > dgain && dgain >= bnd[6])
2067 offset = 0x1;
2068 else if (bnd[6] > dgain && dgain >= bnd[7])
2069 offset = 0x0;
2070 else if (bnd[7] > dgain && dgain >= bnd[8])
2071 offset = 0xff;
2072 else if (bnd[8] > dgain && dgain >= bnd[9])
2073 offset = 0xfe;
2074 else if (bnd[9] > dgain && dgain >= bnd[10])
2075 offset = 0xfd;
2076 else if (bnd[10] > dgain && dgain >= bnd[11])
2077 offset = 0xfc;
2078 else if (bnd[11] > dgain && dgain >= bnd[12])
2079 offset = 0xfb;
2080 else if (bnd[12] > dgain && dgain >= bnd[13])
2081 offset = 0xfa;
2082 else if (bnd[13] > dgain && dgain >= bnd[14])
2083 offset = 0xf9;
2084 else if (bnd[14] > dgain)
2085 offset = 0xf8;
2086 else
2087 offset = 0x0;
2088
2089 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] DGain offset = %d\n", offset);
2090
2091 return offset;
2092}
2093
2094static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev)
2095{
2096 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x6);
2097 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, data: 0x1);
2098
2099 return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL);
2100}
2101
2102static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2103 enum rtw89_rf_path path, u8 kidx)
2104{
2105 _dpk_table_select(rtwdev, path, kidx, gain: 1);
2106 _dpk_one_shot(rtwdev, phy, path, id: GAIN_LOSS);
2107}
2108
2109static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2110 enum rtw89_rf_path path, u8 kidx)
2111{
2112 _dpk_tpg_sel(rtwdev, path, kidx);
2113 _dpk_one_shot(rtwdev, phy, path, id: KIP_PRESET);
2114}
2115
2116static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev,
2117 enum rtw89_rf_path path)
2118{
2119 rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, data: 0x00000080);
2120 rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, data: 0x807f030a);
2121 rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, data: 0xce000a08);
2122
2123 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] KIP Power/CLK on\n");
2124}
2125
2126static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2127 enum rtw89_rf_path path, u8 txagc)
2128{
2129 rtw89_write_rf(rtwdev, rf_path: path, RR_TXAGC, RFREG_MASK, data: txagc);
2130 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
2131 _dpk_one_shot(rtwdev, phy, path, id: DPK_TXAGC);
2132 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
2133
2134 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] set TXAGC = 0x%x\n", txagc);
2135}
2136
2137static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2138 enum rtw89_rf_path path)
2139{
2140 u32 tmp;
2141
2142 tmp = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK);
2143 rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, data: tmp);
2144 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x1);
2145 _dpk_one_shot(rtwdev, phy, path, id: DPK_RXAGC);
2146 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, data: 0x0);
2147 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL_V1, data: 0x8);
2148
2149 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2150 fmt: "[DPK] set RXBB = 0x%x (RF0x0[9:5] = 0x%x)\n",
2151 rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB_V1),
2152 rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASKRXBB));
2153}
2154
2155static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2156 enum rtw89_rf_path path, s8 gain_offset)
2157{
2158 u8 txagc;
2159
2160 txagc = rtw89_read_rf(rtwdev, rf_path: path, RR_TXAGC, RFREG_MASK);
2161
2162 if (txagc - gain_offset < DPK_TXAGC_LOWER)
2163 txagc = DPK_TXAGC_LOWER;
2164 else if (txagc - gain_offset > DPK_TXAGC_UPPER)
2165 txagc = DPK_TXAGC_UPPER;
2166 else
2167 txagc = txagc - gain_offset;
2168
2169 _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
2170
2171 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] tmp_txagc (GL=%d) = 0x%x\n",
2172 gain_offset, txagc);
2173 return txagc;
2174}
2175
2176static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
2177{
2178 u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0;
2179 u8 i;
2180
2181 rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, data: 0x06);
2182 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, data: 0x0);
2183 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, data: 0x08);
2184
2185 if (is_check) {
2186 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: 0x00);
2187 val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
2188 val1_i = abs(sign_extend32(val1_i, 11));
2189 val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
2190 val1_q = abs(sign_extend32(val1_q, 11));
2191
2192 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: 0x1f);
2193 val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
2194 val2_i = abs(sign_extend32(val2_i, 11));
2195 val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
2196 val2_q = abs(sign_extend32(val2_q, 11));
2197
2198 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] PAS_delta = 0x%x\n",
2199 phy_div(val1_i * val1_i + val1_q * val1_q,
2200 val2_i * val2_i + val2_q * val2_q));
2201 } else {
2202 for (i = 0; i < 32; i++) {
2203 rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: i);
2204 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2205 fmt: "[DPK] PAS_Read[%02d]= 0x%08x\n", i,
2206 rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD));
2207 }
2208 }
2209
2210 if (val1_i * val1_i + val1_q * val1_q >=
2211 (val2_i * val2_i + val2_q * val2_q) * 8 / 5)
2212 return true;
2213
2214 return false;
2215}
2216
2217static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2218 enum rtw89_rf_path path, u8 kidx, u8 init_txagc,
2219 bool loss_only)
2220{
2221 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2222 u8 step = DPK_AGC_STEP_SYNC_DGAIN;
2223 u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
2224 u8 goout = 0, agc_cnt = 0, limited_rxbb = 0;
2225 u16 dgain = 0;
2226 s8 offset;
2227 int limit = 200;
2228
2229 tmp_txagc = init_txagc;
2230
2231 do {
2232 switch (step) {
2233 case DPK_AGC_STEP_SYNC_DGAIN:
2234 if (_dpk_sync(rtwdev, phy, path, kidx)) {
2235 tmp_txagc = 0xff;
2236 goout = 1;
2237 break;
2238 }
2239
2240 dgain = _dpk_dgain_read(rtwdev);
2241
2242 if (loss_only == 1 || limited_rxbb == 1)
2243 step = DPK_AGC_STEP_GAIN_LOSS_IDX;
2244 else
2245 step = DPK_AGC_STEP_GAIN_ADJ;
2246 break;
2247
2248 case DPK_AGC_STEP_GAIN_ADJ:
2249 tmp_rxbb = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD,
2250 RFREG_MASKRXBB);
2251 offset = _dpk_dgain_mapping(rtwdev, dgain);
2252
2253 if (tmp_rxbb + offset > 0x1f) {
2254 tmp_rxbb = 0x1f;
2255 limited_rxbb = 1;
2256 } else if (tmp_rxbb + offset < 0) {
2257 tmp_rxbb = 0;
2258 limited_rxbb = 1;
2259 } else {
2260 tmp_rxbb = tmp_rxbb + offset;
2261 }
2262
2263 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASKRXBB,
2264 data: tmp_rxbb);
2265 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2266 fmt: "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb);
2267 if (offset || agc_cnt == 0) {
2268 if (chan->band_width < RTW89_CHANNEL_WIDTH_80)
2269 _dpk_bypass_rxcfir(rtwdev, path, is_bypass: true);
2270 else
2271 _dpk_lbk_rxiqk(rtwdev, phy, path);
2272 }
2273 if (dgain > 1922 || dgain < 342)
2274 step = DPK_AGC_STEP_SYNC_DGAIN;
2275 else
2276 step = DPK_AGC_STEP_GAIN_LOSS_IDX;
2277
2278 agc_cnt++;
2279 break;
2280
2281 case DPK_AGC_STEP_GAIN_LOSS_IDX:
2282 _dpk_gainloss(rtwdev, phy, path, kidx);
2283 tmp_gl_idx = _dpk_gainloss_read(rtwdev);
2284
2285 if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, is_check: true)) ||
2286 tmp_gl_idx >= 7)
2287 step = DPK_AGC_STEP_GL_GT_CRITERION;
2288 else if (tmp_gl_idx == 0)
2289 step = DPK_AGC_STEP_GL_LT_CRITERION;
2290 else
2291 step = DPK_AGC_STEP_SET_TX_GAIN;
2292 break;
2293
2294 case DPK_AGC_STEP_GL_GT_CRITERION:
2295 if (tmp_txagc == 0x2e) {
2296 goout = 1;
2297 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2298 fmt: "[DPK] Txagc@lower bound!!\n");
2299 } else {
2300 tmp_txagc = _dpk_set_offset(rtwdev, phy, path, gain_offset: 0x3);
2301 }
2302 step = DPK_AGC_STEP_GAIN_LOSS_IDX;
2303 agc_cnt++;
2304 break;
2305
2306 case DPK_AGC_STEP_GL_LT_CRITERION:
2307 if (tmp_txagc == 0x3f) {
2308 goout = 1;
2309 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2310 fmt: "[DPK] Txagc@upper bound!!\n");
2311 } else {
2312 tmp_txagc = _dpk_set_offset(rtwdev, phy, path, gain_offset: 0xfe);
2313 }
2314 step = DPK_AGC_STEP_GAIN_LOSS_IDX;
2315 agc_cnt++;
2316 break;
2317 case DPK_AGC_STEP_SET_TX_GAIN:
2318 tmp_txagc = _dpk_set_offset(rtwdev, phy, path, gain_offset: tmp_gl_idx);
2319 goout = 1;
2320 agc_cnt++;
2321 break;
2322
2323 default:
2324 goout = 1;
2325 break;
2326 }
2327 } while (!goout && agc_cnt < 6 && limit-- > 0);
2328
2329 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2330 fmt: "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc,
2331 tmp_rxbb);
2332
2333 return tmp_txagc;
2334}
2335
2336static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order)
2337{
2338 switch (order) {
2339 case 0:
2340 rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, data: order);
2341 rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, data: 0x3);
2342 rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, data: 0x1);
2343 break;
2344 case 1:
2345 rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, data: order);
2346 rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN);
2347 rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN);
2348 break;
2349 case 2:
2350 rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, data: order);
2351 rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN);
2352 rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN);
2353 break;
2354 default:
2355 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2356 fmt: "[DPK] Wrong MDPD order!!(0x%x)\n", order);
2357 break;
2358 }
2359
2360 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2361 fmt: "[DPK] Set MDPD order to 0x%x for IDL\n", order);
2362}
2363
2364static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2365 enum rtw89_rf_path path, u8 kidx, u8 gain)
2366{
2367 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2368
2369 if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 &&
2370 dpk->bp[path][kidx].band == RTW89_BAND_5G)
2371 _dpk_set_mdpd_para(rtwdev, order: 0x2);
2372 else
2373 _dpk_set_mdpd_para(rtwdev, order: 0x0);
2374
2375 _dpk_one_shot(rtwdev, phy, path, id: MDPK_IDL);
2376}
2377
2378static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2379 enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc)
2380{
2381 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2382 const u16 pwsf = 0x78;
2383 u8 gs = dpk->dpk_gs[phy];
2384
2385 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8),
2386 B_COEF_SEL_MDPD, data: kidx);
2387
2388 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2389 fmt: "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc,
2390 pwsf, gs);
2391
2392 dpk->bp[path][kidx].txagc_dpk = txagc;
2393 rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8),
2394 mask: 0x3F << ((gain << 3) + (kidx << 4)), data: txagc);
2395
2396 dpk->bp[path][kidx].pwsf = pwsf;
2397 rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2),
2398 mask: 0x1FF << (gain << 4), data: pwsf);
2399
2400 rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, data: 0x1);
2401 rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, data: 0x0);
2402
2403 dpk->bp[path][kidx].gs = gs;
2404 if (dpk->dpk_gs[phy] == 0x7f)
2405 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
2406 MASKDWORD, data: 0x007f7f7f);
2407 else
2408 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
2409 MASKDWORD, data: 0x005b5b5b);
2410
2411 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
2412 B_DPD_ORDER_V1, data: _dpk_order_convert(rtwdev));
2413 rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, data: 0x0);
2414 rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, data: 0x0);
2415}
2416
2417static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2418 enum rtw89_rf_path path)
2419{
2420 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2421 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2422 bool is_reload = false;
2423 u8 idx, cur_band, cur_ch;
2424
2425 cur_band = chan->band_type;
2426 cur_ch = chan->channel;
2427
2428 for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
2429 if (cur_band != dpk->bp[path][idx].band ||
2430 cur_ch != dpk->bp[path][idx].ch)
2431 continue;
2432
2433 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8),
2434 B_COEF_SEL_MDPD, data: idx);
2435 dpk->cur_idx[path] = idx;
2436 is_reload = true;
2437 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2438 fmt: "[DPK] reload S%d[%d] success\n", path, idx);
2439 }
2440
2441 return is_reload;
2442}
2443
2444static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2445 enum rtw89_rf_path path, u8 gain)
2446{
2447 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2448 u8 txagc = 0x38, kidx = dpk->cur_idx[path];
2449 bool is_fail = false;
2450
2451 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2452 fmt: "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx);
2453
2454 _rfk_rf_direct_cntrl(rtwdev, path, is_bybb: false);
2455 _rfk_drf_direct_cntrl(rtwdev, path, is_bybb: false);
2456
2457 _dpk_kip_pwr_clk_on(rtwdev, path);
2458 _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
2459 _dpk_rf_setting(rtwdev, gain, path, kidx);
2460 _dpk_rx_dck(rtwdev, phy, path);
2461
2462 _dpk_kip_preset(rtwdev, phy, path, kidx);
2463 _dpk_kip_set_rxagc(rtwdev, phy, path);
2464 _dpk_table_select(rtwdev, path, kidx, gain);
2465
2466 txagc = _dpk_agc(rtwdev, phy, path, kidx, init_txagc: txagc, loss_only: false);
2467 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Adjust txagc = 0x%x\n", txagc);
2468
2469 if (txagc == 0xff) {
2470 is_fail = true;
2471 } else {
2472 _dpk_get_thermal(rtwdev, kidx, path);
2473
2474 _dpk_idl_mpa(rtwdev, phy, path, kidx, gain);
2475
2476 rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
2477
2478 _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc);
2479 }
2480
2481 if (!is_fail)
2482 dpk->bp[path][kidx].path_ok = true;
2483 else
2484 dpk->bp[path][kidx].path_ok = false;
2485
2486 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d[%d] DPK %s\n", path, kidx,
2487 is_fail ? "Check" : "Success");
2488
2489 return is_fail;
2490}
2491
2492static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
2493 enum rtw89_phy_idx phy, u8 kpath)
2494{
2495 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2496 static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120};
2497 u32 kip_bkup[RTW8852B_DPK_RF_PATH][RTW8852B_DPK_KIP_REG_NUM] = {};
2498 u32 backup_rf_val[RTW8852B_DPK_RF_PATH][BACKUP_RF_REGS_NR];
2499 u32 backup_bb_val[BACKUP_BB_REGS_NR];
2500 bool is_fail = true, reloaded[RTW8852B_DPK_RF_PATH] = {};
2501 u8 path;
2502
2503 if (dpk->is_dpk_reload_en) {
2504 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
2505 reloaded[path] = _dpk_reload_check(rtwdev, phy, path);
2506 if (!reloaded[path] && dpk->bp[path][0].ch)
2507 dpk->cur_idx[path] = !dpk->cur_idx[path];
2508 else
2509 _dpk_onoff(rtwdev, path, off: false);
2510 }
2511 } else {
2512 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++)
2513 dpk->cur_idx[path] = 0;
2514 }
2515
2516 _rfk_backup_bb_reg(rtwdev, backup_bb_reg_val: &backup_bb_val[0]);
2517
2518 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
2519 _dpk_bkup_kip(rtwdev, reg: kip_reg, reg_bkup: kip_bkup, path);
2520 _rfk_backup_rf_reg(rtwdev, backup_rf_reg_val: &backup_rf_val[path][0], rf_path: path);
2521 _dpk_information(rtwdev, phy, path);
2522 if (rtwdev->is_tssi_mode[path])
2523 _dpk_tssi_pause(rtwdev, path, is_pause: true);
2524 }
2525
2526 _dpk_bb_afe_setting(rtwdev, phy, path, kpath);
2527
2528 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
2529 is_fail = _dpk_main(rtwdev, phy, path, gain: 1);
2530 _dpk_onoff(rtwdev, path, off: is_fail);
2531 }
2532
2533 _dpk_bb_afe_restore(rtwdev, phy, path, kpath);
2534 _rfk_restore_bb_reg(rtwdev, backup_bb_reg_val: &backup_bb_val[0]);
2535
2536 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
2537 _dpk_kip_restore(rtwdev, path);
2538 _dpk_reload_kip(rtwdev, reg: kip_reg, reg_bkup: kip_bkup, path);
2539 _rfk_restore_rf_reg(rtwdev, backup_rf_reg_val: &backup_rf_val[path][0], rf_path: path);
2540 if (rtwdev->is_tssi_mode[path])
2541 _dpk_tssi_pause(rtwdev, path, is_pause: false);
2542 }
2543}
2544
2545static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
2546{
2547 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2548 struct rtw89_fem_info *fem = &rtwdev->fem;
2549
2550 if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
2551 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2552 fmt: "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
2553 return true;
2554 } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) {
2555 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2556 fmt: "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
2557 return true;
2558 } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) {
2559 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2560 fmt: "[DPK] Skip DPK due to 6G_ext_PA exist!!\n");
2561 return true;
2562 }
2563
2564 return false;
2565}
2566
2567static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
2568{
2569 u8 path, kpath;
2570
2571 kpath = _kpath(rtwdev, phy_idx: phy);
2572
2573 for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
2574 if (kpath & BIT(path))
2575 _dpk_onoff(rtwdev, path, off: true);
2576 }
2577}
2578
2579static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
2580{
2581 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2582 fmt: "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n",
2583 RTW8852B_DPK_VER, rtwdev->hal.cv,
2584 RTW8852B_RF_REL_VERSION);
2585
2586 if (_dpk_bypass_check(rtwdev, phy))
2587 _dpk_force_bypass(rtwdev, phy);
2588 else
2589 _dpk_cal_select(rtwdev, force, phy, kpath: RF_AB);
2590}
2591
2592static void _dpk_track(struct rtw89_dev *rtwdev)
2593{
2594 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2595 s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst;
2596 s8 delta_ther[2] = {};
2597 u8 trk_idx, txagc_rf;
2598 u8 path, kidx;
2599 u16 pwsf[2];
2600 u8 cur_ther;
2601 u32 tmp;
2602
2603 for (path = 0; path < RF_PATH_NUM_8852B; path++) {
2604 kidx = dpk->cur_idx[path];
2605
2606 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2607 fmt: "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n",
2608 path, kidx, dpk->bp[path][kidx].ch);
2609
2610 cur_ther = ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]);
2611
2612 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2613 fmt: "[DPK_TRK] thermal now = %d\n", cur_ther);
2614
2615 if (dpk->bp[path][kidx].ch && cur_ther)
2616 delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther;
2617
2618 if (dpk->bp[path][kidx].band == RTW89_BAND_2G)
2619 delta_ther[path] = delta_ther[path] * 3 / 2;
2620 else
2621 delta_ther[path] = delta_ther[path] * 5 / 2;
2622
2623 txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
2624 mask: 0x0000003f);
2625
2626 if (rtwdev->is_tssi_mode[path]) {
2627 trk_idx = rtw89_read_rf(rtwdev, rf_path: path, RR_TXA, RR_TXA_TRK);
2628
2629 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2630 fmt: "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n",
2631 txagc_rf, trk_idx);
2632
2633 txagc_bb =
2634 rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
2635 MASKBYTE2);
2636 txagc_bb_tp =
2637 rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13),
2638 B_TXAGC_TP);
2639
2640 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2641 fmt: "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n",
2642 txagc_bb_tp, txagc_bb);
2643
2644 txagc_ofst =
2645 rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
2646 MASKBYTE3);
2647
2648 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2649 fmt: "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n",
2650 txagc_ofst, delta_ther[path]);
2651 tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8),
2652 B_DPD_COM_OF);
2653 if (tmp == 0x1) {
2654 txagc_ofst = 0;
2655 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2656 fmt: "[DPK_TRK] HW txagc offset mode\n");
2657 }
2658
2659 if (txagc_rf && cur_ther)
2660 ini_diff = txagc_ofst + (delta_ther[path]);
2661
2662 tmp = rtw89_phy_read32_mask(rtwdev,
2663 R_P0_TXDPD + (path << 13),
2664 B_P0_TXDPD);
2665 if (tmp == 0x0) {
2666 pwsf[0] = dpk->bp[path][kidx].pwsf +
2667 txagc_bb_tp - txagc_bb + ini_diff;
2668 pwsf[1] = dpk->bp[path][kidx].pwsf +
2669 txagc_bb_tp - txagc_bb + ini_diff;
2670 } else {
2671 pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff;
2672 pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff;
2673 }
2674
2675 } else {
2676 pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
2677 pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
2678 }
2679
2680 tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS);
2681 if (!tmp && txagc_rf) {
2682 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK,
2683 fmt: "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n",
2684 pwsf[0], pwsf[1]);
2685
2686 rtw89_phy_write32_mask(rtwdev,
2687 R_DPD_BND + (path << 8) + (kidx << 2),
2688 B_DPD_BND_0, data: pwsf[0]);
2689 rtw89_phy_write32_mask(rtwdev,
2690 R_DPD_BND + (path << 8) + (kidx << 2),
2691 B_DPD_BND_1, data: pwsf[1]);
2692 }
2693 }
2694}
2695
2696static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
2697{
2698 struct rtw89_dpk_info *dpk = &rtwdev->dpk;
2699 u8 tx_scale, ofdm_bkof, path, kpath;
2700
2701 kpath = _kpath(rtwdev, phy_idx: phy);
2702
2703 ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM);
2704 tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA);
2705
2706 if (ofdm_bkof + tx_scale >= 44) {
2707 /* move dpd backoff to bb, and set dpd backoff to 0 */
2708 dpk->dpk_gs[phy] = 0x7f;
2709 for (path = 0; path < RF_PATH_NUM_8852B; path++) {
2710 if (!(kpath & BIT(path)))
2711 continue;
2712
2713 rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8),
2714 B_DPD_CFG, data: 0x7f7f7f);
2715 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
2716 fmt: "[RFK] Set S%d DPD backoff to 0dB\n", path);
2717 }
2718 } else {
2719 dpk->dpk_gs[phy] = 0x5b;
2720 }
2721}
2722
2723static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2724 enum rtw89_rf_path path)
2725{
2726 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2727 enum rtw89_band band = chan->band_type;
2728
2729 if (band == RTW89_BAND_2G)
2730 rtw89_write_rf(rtwdev, rf_path: path, RR_TXPOW, RR_TXPOW_TXG, data: 0x1);
2731 else
2732 rtw89_write_rf(rtwdev, rf_path: path, RR_TXPOW, RR_TXPOW_TXA, data: 0x1);
2733}
2734
2735static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2736 enum rtw89_rf_path path)
2737{
2738 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2739 enum rtw89_band band = chan->band_type;
2740
2741 rtw89_rfk_parser(rtwdev, tbl: &rtw8852b_tssi_sys_defs_tbl);
2742
2743 if (path == RF_PATH_A)
2744 rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
2745 &rtw8852b_tssi_sys_a_defs_2g_tbl,
2746 &rtw8852b_tssi_sys_a_defs_5g_tbl);
2747 else
2748 rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
2749 &rtw8852b_tssi_sys_b_defs_2g_tbl,
2750 &rtw8852b_tssi_sys_b_defs_5g_tbl);
2751}
2752
2753static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev,
2754 enum rtw89_phy_idx phy,
2755 enum rtw89_rf_path path)
2756{
2757 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
2758 &rtw8852b_tssi_init_txpwr_defs_a_tbl,
2759 &rtw8852b_tssi_init_txpwr_defs_b_tbl);
2760}
2761
2762static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev,
2763 enum rtw89_phy_idx phy,
2764 enum rtw89_rf_path path)
2765{
2766 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
2767 &rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl,
2768 &rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl);
2769}
2770
2771static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2772 enum rtw89_rf_path path)
2773{
2774 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
2775 &rtw8852b_tssi_dck_defs_a_tbl,
2776 &rtw8852b_tssi_dck_defs_b_tbl);
2777}
2778
2779static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2780 enum rtw89_rf_path path)
2781{
2782#define RTW8852B_TSSI_GET_VAL(ptr, idx) \
2783({ \
2784 s8 *__ptr = (ptr); \
2785 u8 __idx = (idx), __i, __v; \
2786 u32 __val = 0; \
2787 for (__i = 0; __i < 4; __i++) { \
2788 __v = (__ptr[__idx + __i]); \
2789 __val |= (__v << (8 * __i)); \
2790 } \
2791 __val; \
2792})
2793 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
2794 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2795 u8 ch = chan->channel;
2796 u8 subband = chan->subband_type;
2797 const s8 *thm_up_a = NULL;
2798 const s8 *thm_down_a = NULL;
2799 const s8 *thm_up_b = NULL;
2800 const s8 *thm_down_b = NULL;
2801 u8 thermal = 0xff;
2802 s8 thm_ofst[64] = {0};
2803 u32 tmp = 0;
2804 u8 i, j;
2805
2806 switch (subband) {
2807 default:
2808 case RTW89_CH_2G:
2809 thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_p;
2810 thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_n;
2811 thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_p;
2812 thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_n;
2813 break;
2814 case RTW89_CH_5G_BAND_1:
2815 thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[0];
2816 thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[0];
2817 thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[0];
2818 thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[0];
2819 break;
2820 case RTW89_CH_5G_BAND_3:
2821 thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[1];
2822 thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[1];
2823 thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[1];
2824 thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[1];
2825 break;
2826 case RTW89_CH_5G_BAND_4:
2827 thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[2];
2828 thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[2];
2829 thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[2];
2830 thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[2];
2831 break;
2832 }
2833
2834 if (path == RF_PATH_A) {
2835 thermal = tssi_info->thermal[RF_PATH_A];
2836
2837 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2838 fmt: "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal);
2839
2840 rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, data: 0x0);
2841 rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, data: 0x1);
2842
2843 if (thermal == 0xff) {
2844 rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, data: 32);
2845 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, data: 32);
2846
2847 for (i = 0; i < 64; i += 4) {
2848 rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, data: 0x0);
2849
2850 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2851 fmt: "[TSSI] write 0x%x val=0x%08x\n",
2852 R_P0_TSSI_BASE + i, 0x0);
2853 }
2854
2855 } else {
2856 rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, data: thermal);
2857 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL,
2858 data: thermal);
2859
2860 i = 0;
2861 for (j = 0; j < 32; j++)
2862 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
2863 -thm_down_a[i++] :
2864 -thm_down_a[DELTA_SWINGIDX_SIZE - 1];
2865
2866 i = 1;
2867 for (j = 63; j >= 32; j--)
2868 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
2869 thm_up_a[i++] :
2870 thm_up_a[DELTA_SWINGIDX_SIZE - 1];
2871
2872 for (i = 0; i < 64; i += 4) {
2873 tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i);
2874 rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, data: tmp);
2875
2876 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2877 fmt: "[TSSI] write 0x%x val=0x%08x\n",
2878 0x5c00 + i, tmp);
2879 }
2880 }
2881 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, data: 0x1);
2882 rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, data: 0x0);
2883
2884 } else {
2885 thermal = tssi_info->thermal[RF_PATH_B];
2886
2887 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2888 fmt: "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal);
2889
2890 rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, data: 0x0);
2891 rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, data: 0x1);
2892
2893 if (thermal == 0xff) {
2894 rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, data: 32);
2895 rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, data: 32);
2896
2897 for (i = 0; i < 64; i += 4) {
2898 rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, data: 0x0);
2899
2900 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2901 fmt: "[TSSI] write 0x%x val=0x%08x\n",
2902 0x7c00 + i, 0x0);
2903 }
2904
2905 } else {
2906 rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, data: thermal);
2907 rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL,
2908 data: thermal);
2909
2910 i = 0;
2911 for (j = 0; j < 32; j++)
2912 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
2913 -thm_down_b[i++] :
2914 -thm_down_b[DELTA_SWINGIDX_SIZE - 1];
2915
2916 i = 1;
2917 for (j = 63; j >= 32; j--)
2918 thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
2919 thm_up_b[i++] :
2920 thm_up_b[DELTA_SWINGIDX_SIZE - 1];
2921
2922 for (i = 0; i < 64; i += 4) {
2923 tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i);
2924 rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, data: tmp);
2925
2926 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
2927 fmt: "[TSSI] write 0x%x val=0x%08x\n",
2928 0x7c00 + i, tmp);
2929 }
2930 }
2931 rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, data: 0x1);
2932 rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, data: 0x0);
2933 }
2934#undef RTW8852B_TSSI_GET_VAL
2935}
2936
2937static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2938 enum rtw89_rf_path path)
2939{
2940 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
2941 &rtw8852b_tssi_dac_gain_defs_a_tbl,
2942 &rtw8852b_tssi_dac_gain_defs_b_tbl);
2943}
2944
2945static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2946 enum rtw89_rf_path path)
2947{
2948 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2949 enum rtw89_band band = chan->band_type;
2950
2951 if (path == RF_PATH_A)
2952 rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
2953 &rtw8852b_tssi_slope_a_defs_2g_tbl,
2954 &rtw8852b_tssi_slope_a_defs_5g_tbl);
2955 else
2956 rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
2957 &rtw8852b_tssi_slope_b_defs_2g_tbl,
2958 &rtw8852b_tssi_slope_b_defs_5g_tbl);
2959}
2960
2961static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
2962 enum rtw89_rf_path path, bool all)
2963{
2964 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
2965 enum rtw89_band band = chan->band_type;
2966 const struct rtw89_rfk_tbl *tbl = NULL;
2967 u8 ch = chan->channel;
2968
2969 if (path == RF_PATH_A) {
2970 if (band == RTW89_BAND_2G) {
2971 if (all)
2972 tbl = &rtw8852b_tssi_align_a_2g_all_defs_tbl;
2973 else
2974 tbl = &rtw8852b_tssi_align_a_2g_part_defs_tbl;
2975 } else if (ch >= 36 && ch <= 64) {
2976 if (all)
2977 tbl = &rtw8852b_tssi_align_a_5g1_all_defs_tbl;
2978 else
2979 tbl = &rtw8852b_tssi_align_a_5g1_part_defs_tbl;
2980 } else if (ch >= 100 && ch <= 144) {
2981 if (all)
2982 tbl = &rtw8852b_tssi_align_a_5g2_all_defs_tbl;
2983 else
2984 tbl = &rtw8852b_tssi_align_a_5g2_part_defs_tbl;
2985 } else if (ch >= 149 && ch <= 177) {
2986 if (all)
2987 tbl = &rtw8852b_tssi_align_a_5g3_all_defs_tbl;
2988 else
2989 tbl = &rtw8852b_tssi_align_a_5g3_part_defs_tbl;
2990 }
2991 } else {
2992 if (ch >= 1 && ch <= 14) {
2993 if (all)
2994 tbl = &rtw8852b_tssi_align_b_2g_all_defs_tbl;
2995 else
2996 tbl = &rtw8852b_tssi_align_b_2g_part_defs_tbl;
2997 } else if (ch >= 36 && ch <= 64) {
2998 if (all)
2999 tbl = &rtw8852b_tssi_align_b_5g1_all_defs_tbl;
3000 else
3001 tbl = &rtw8852b_tssi_align_b_5g1_part_defs_tbl;
3002 } else if (ch >= 100 && ch <= 144) {
3003 if (all)
3004 tbl = &rtw8852b_tssi_align_b_5g2_all_defs_tbl;
3005 else
3006 tbl = &rtw8852b_tssi_align_b_5g2_part_defs_tbl;
3007 } else if (ch >= 149 && ch <= 177) {
3008 if (all)
3009 tbl = &rtw8852b_tssi_align_b_5g3_all_defs_tbl;
3010 else
3011 tbl = &rtw8852b_tssi_align_b_5g3_part_defs_tbl;
3012 }
3013 }
3014
3015 if (tbl)
3016 rtw89_rfk_parser(rtwdev, tbl);
3017}
3018
3019static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3020 enum rtw89_rf_path path)
3021{
3022 rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
3023 &rtw8852b_tssi_slope_defs_a_tbl,
3024 &rtw8852b_tssi_slope_defs_b_tbl);
3025}
3026
3027static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3028 enum rtw89_rf_path path)
3029{
3030 if (path == RF_PATH_A)
3031 rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, data: 0x0);
3032 else
3033 rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, data: 0x0);
3034}
3035
3036static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev,
3037 enum rtw89_phy_idx phy,
3038 enum rtw89_rf_path path)
3039{
3040 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "======>%s path=%d\n", __func__,
3041 path);
3042
3043 if (path == RF_PATH_A)
3044 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_MIX, data: 0x010);
3045 else
3046 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_RFCTM_DEL, data: 0x010);
3047}
3048
3049static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
3050{
3051 u8 i;
3052
3053 for (i = 0; i < RF_PATH_NUM_8852B; i++) {
3054 _tssi_set_tssi_track(rtwdev, phy, path: i);
3055 _tssi_set_txagc_offset_mv_avg(rtwdev, phy, path: i);
3056
3057 if (i == RF_PATH_A) {
3058 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG,
3059 B_P0_TSSI_MV_CLR, data: 0x0);
3060 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
3061 B_P0_TSSI_EN, data: 0x0);
3062 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
3063 B_P0_TSSI_EN, data: 0x1);
3064 rtw89_write_rf(rtwdev, rf_path: i, RR_TXGA_V1,
3065 RR_TXGA_V1_TRK_EN, data: 0x1);
3066 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
3067 B_P0_TSSI_RFC, data: 0x3);
3068
3069 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
3070 B_P0_TSSI_OFT, data: 0xc0);
3071 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
3072 B_P0_TSSI_OFT_EN, data: 0x0);
3073 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
3074 B_P0_TSSI_OFT_EN, data: 0x1);
3075
3076 rtwdev->is_tssi_mode[RF_PATH_A] = true;
3077 } else {
3078 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG,
3079 B_P1_TSSI_MV_CLR, data: 0x0);
3080 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
3081 B_P1_TSSI_EN, data: 0x0);
3082 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
3083 B_P1_TSSI_EN, data: 0x1);
3084 rtw89_write_rf(rtwdev, rf_path: i, RR_TXGA_V1,
3085 RR_TXGA_V1_TRK_EN, data: 0x1);
3086 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
3087 B_P1_TSSI_RFC, data: 0x3);
3088
3089 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
3090 B_P1_TSSI_OFT, data: 0xc0);
3091 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
3092 B_P1_TSSI_OFT_EN, data: 0x0);
3093 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
3094 B_P1_TSSI_OFT_EN, data: 0x1);
3095
3096 rtwdev->is_tssi_mode[RF_PATH_B] = true;
3097 }
3098 }
3099}
3100
3101static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
3102{
3103 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, data: 0x0);
3104 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, data: 0x1);
3105 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, data: 0x1);
3106 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, data: 0x0);
3107 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, data: 0x1);
3108 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, data: 0x1);
3109
3110 rtwdev->is_tssi_mode[RF_PATH_A] = false;
3111 rtwdev->is_tssi_mode[RF_PATH_B] = false;
3112}
3113
3114static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch)
3115{
3116 switch (ch) {
3117 case 1 ... 2:
3118 return 0;
3119 case 3 ... 5:
3120 return 1;
3121 case 6 ... 8:
3122 return 2;
3123 case 9 ... 11:
3124 return 3;
3125 case 12 ... 13:
3126 return 4;
3127 case 14:
3128 return 5;
3129 }
3130
3131 return 0;
3132}
3133
3134#define TSSI_EXTRA_GROUP_BIT (BIT(31))
3135#define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx))
3136#define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT)
3137#define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT)
3138#define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1)
3139
3140static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch)
3141{
3142 switch (ch) {
3143 case 1 ... 2:
3144 return 0;
3145 case 3 ... 5:
3146 return 1;
3147 case 6 ... 8:
3148 return 2;
3149 case 9 ... 11:
3150 return 3;
3151 case 12 ... 14:
3152 return 4;
3153 case 36 ... 40:
3154 return 5;
3155 case 41 ... 43:
3156 return TSSI_EXTRA_GROUP(5);
3157 case 44 ... 48:
3158 return 6;
3159 case 49 ... 51:
3160 return TSSI_EXTRA_GROUP(6);
3161 case 52 ... 56:
3162 return 7;
3163 case 57 ... 59:
3164 return TSSI_EXTRA_GROUP(7);
3165 case 60 ... 64:
3166 return 8;
3167 case 100 ... 104:
3168 return 9;
3169 case 105 ... 107:
3170 return TSSI_EXTRA_GROUP(9);
3171 case 108 ... 112:
3172 return 10;
3173 case 113 ... 115:
3174 return TSSI_EXTRA_GROUP(10);
3175 case 116 ... 120:
3176 return 11;
3177 case 121 ... 123:
3178 return TSSI_EXTRA_GROUP(11);
3179 case 124 ... 128:
3180 return 12;
3181 case 129 ... 131:
3182 return TSSI_EXTRA_GROUP(12);
3183 case 132 ... 136:
3184 return 13;
3185 case 137 ... 139:
3186 return TSSI_EXTRA_GROUP(13);
3187 case 140 ... 144:
3188 return 14;
3189 case 149 ... 153:
3190 return 15;
3191 case 154 ... 156:
3192 return TSSI_EXTRA_GROUP(15);
3193 case 157 ... 161:
3194 return 16;
3195 case 162 ... 164:
3196 return TSSI_EXTRA_GROUP(16);
3197 case 165 ... 169:
3198 return 17;
3199 case 170 ... 172:
3200 return TSSI_EXTRA_GROUP(17);
3201 case 173 ... 177:
3202 return 18;
3203 }
3204
3205 return 0;
3206}
3207
3208static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
3209{
3210 switch (ch) {
3211 case 1 ... 8:
3212 return 0;
3213 case 9 ... 14:
3214 return 1;
3215 case 36 ... 48:
3216 return 2;
3217 case 52 ... 64:
3218 return 3;
3219 case 100 ... 112:
3220 return 4;
3221 case 116 ... 128:
3222 return 5;
3223 case 132 ... 144:
3224 return 6;
3225 case 149 ... 177:
3226 return 7;
3227 }
3228
3229 return 0;
3230}
3231
3232static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3233 enum rtw89_rf_path path)
3234{
3235 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3236 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3237 u8 ch = chan->channel;
3238 u32 gidx, gidx_1st, gidx_2nd;
3239 s8 de_1st;
3240 s8 de_2nd;
3241 s8 val;
3242
3243 gidx = _tssi_get_ofdm_group(rtwdev, ch);
3244
3245 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3246 fmt: "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx);
3247
3248 if (IS_TSSI_EXTRA_GROUP(gidx)) {
3249 gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx);
3250 gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx);
3251 de_1st = tssi_info->tssi_mcs[path][gidx_1st];
3252 de_2nd = tssi_info->tssi_mcs[path][gidx_2nd];
3253 val = (de_1st + de_2nd) / 2;
3254
3255 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3256 fmt: "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n",
3257 path, val, de_1st, de_2nd);
3258 } else {
3259 val = tssi_info->tssi_mcs[path][gidx];
3260
3261 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3262 fmt: "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val);
3263 }
3264
3265 return val;
3266}
3267
3268static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3269 enum rtw89_rf_path path)
3270{
3271 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3272 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3273 u8 ch = chan->channel;
3274 u32 tgidx, tgidx_1st, tgidx_2nd;
3275 s8 tde_1st;
3276 s8 tde_2nd;
3277 s8 val;
3278
3279 tgidx = _tssi_get_trim_group(rtwdev, ch);
3280
3281 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3282 fmt: "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n",
3283 path, tgidx);
3284
3285 if (IS_TSSI_EXTRA_GROUP(tgidx)) {
3286 tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx);
3287 tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx);
3288 tde_1st = tssi_info->tssi_trim[path][tgidx_1st];
3289 tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd];
3290 val = (tde_1st + tde_2nd) / 2;
3291
3292 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3293 fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n",
3294 path, val, tde_1st, tde_2nd);
3295 } else {
3296 val = tssi_info->tssi_trim[path][tgidx];
3297
3298 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3299 fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d\n",
3300 path, val);
3301 }
3302
3303 return val;
3304}
3305
3306static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
3307{
3308 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3309 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3310 u8 ch = chan->channel;
3311 u8 gidx;
3312 s8 ofdm_de;
3313 s8 trim_de;
3314 s32 val;
3315 u32 i;
3316
3317 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "[TSSI][TRIM]: phy=%d ch=%d\n",
3318 phy, ch);
3319
3320 for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
3321 gidx = _tssi_get_cck_group(rtwdev, ch);
3322 trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, path: i);
3323 val = tssi_info->tssi_cck[i][gidx] + trim_de;
3324
3325 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3326 fmt: "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n",
3327 i, gidx, tssi_info->tssi_cck[i][gidx], trim_de);
3328
3329 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_cck_long[i], _TSSI_DE_MASK, data: val);
3330 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_cck_short[i], _TSSI_DE_MASK, data: val);
3331
3332 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3333 fmt: "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n",
3334 _tssi_de_cck_long[i],
3335 rtw89_phy_read32_mask(rtwdev, addr: _tssi_de_cck_long[i],
3336 _TSSI_DE_MASK));
3337
3338 ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, path: i);
3339 trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, path: i);
3340 val = ofdm_de + trim_de;
3341
3342 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3343 fmt: "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n",
3344 i, ofdm_de, trim_de);
3345
3346 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_20m[i], _TSSI_DE_MASK, data: val);
3347 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_40m[i], _TSSI_DE_MASK, data: val);
3348 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_80m[i], _TSSI_DE_MASK, data: val);
3349 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, data: val);
3350 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_5m[i], _TSSI_DE_MASK, data: val);
3351 rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_10m[i], _TSSI_DE_MASK, data: val);
3352
3353 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI,
3354 fmt: "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n",
3355 _tssi_de_mcs_20m[i],
3356 rtw89_phy_read32_mask(rtwdev, addr: _tssi_de_mcs_20m[i],
3357 _TSSI_DE_MASK));
3358 }
3359}
3360
3361static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
3362{
3363 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3364 fmt: "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n"
3365 "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n",
3366 R_TSSI_PA_K1 + (path << 13),
3367 rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD),
3368 R_TSSI_PA_K2 + (path << 13),
3369 rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD),
3370 R_P0_TSSI_ALIM1 + (path << 13),
3371 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD),
3372 R_P0_TSSI_ALIM3 + (path << 13),
3373 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD),
3374 R_TSSI_PA_K5 + (path << 13),
3375 rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD),
3376 R_P0_TSSI_ALIM2 + (path << 13),
3377 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD),
3378 R_P0_TSSI_ALIM4 + (path << 13),
3379 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD),
3380 R_TSSI_PA_K8 + (path << 13),
3381 rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD));
3382}
3383
3384static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
3385 enum rtw89_phy_idx phy, enum rtw89_rf_path path)
3386{
3387 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3388 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3389 u8 channel = chan->channel;
3390 u8 band;
3391
3392 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3393 fmt: "======>%s phy=%d path=%d\n", __func__, phy, path);
3394
3395 if (channel >= 1 && channel <= 14)
3396 band = TSSI_ALIMK_2G;
3397 else if (channel >= 36 && channel <= 64)
3398 band = TSSI_ALIMK_5GL;
3399 else if (channel >= 100 && channel <= 144)
3400 band = TSSI_ALIMK_5GM;
3401 else if (channel >= 149 && channel <= 177)
3402 band = TSSI_ALIMK_5GH;
3403 else
3404 band = TSSI_ALIMK_2G;
3405
3406 if (tssi_info->alignment_done[path][band]) {
3407 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD,
3408 data: tssi_info->alignment_value[path][band][0]);
3409 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD,
3410 data: tssi_info->alignment_value[path][band][1]);
3411 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD,
3412 data: tssi_info->alignment_value[path][band][2]);
3413 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD,
3414 data: tssi_info->alignment_value[path][band][3]);
3415 }
3416
3417 _tssi_alimentk_dump_result(rtwdev, path);
3418}
3419
3420static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3421 enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm,
3422 u8 enable)
3423{
3424 enum rtw89_rf_path_bit rx_path;
3425
3426 if (path == RF_PATH_A)
3427 rx_path = RF_A;
3428 else if (path == RF_PATH_B)
3429 rx_path = RF_B;
3430 else if (path == RF_PATH_AB)
3431 rx_path = RF_AB;
3432 else
3433 rx_path = RF_ABCD; /* don't change path, but still set others */
3434
3435 if (enable) {
3436 rtw8852b_bb_set_plcp_tx(rtwdev);
3437 rtw8852b_bb_cfg_tx_path(rtwdev, tx_path: path);
3438 rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path);
3439 rtw8852b_bb_set_power(rtwdev, pwr_dbm, idx: phy);
3440 }
3441
3442 rtw8852b_bb_set_pmac_pkt_tx(rtwdev, enable, tx_cnt: cnt, period, tx_time: 20, idx: phy);
3443}
3444
3445static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev,
3446 enum rtw89_phy_idx phy, const u32 reg[],
3447 u32 reg_backup[], u32 reg_num)
3448{
3449 u32 i;
3450
3451 for (i = 0; i < reg_num; i++) {
3452 reg_backup[i] = rtw89_phy_read32_mask(rtwdev, addr: reg[i], MASKDWORD);
3453
3454 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3455 fmt: "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i],
3456 reg_backup[i]);
3457 }
3458}
3459
3460static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev,
3461 enum rtw89_phy_idx phy, const u32 reg[],
3462 u32 reg_backup[], u32 reg_num)
3463
3464{
3465 u32 i;
3466
3467 for (i = 0; i < reg_num; i++) {
3468 rtw89_phy_write32_mask(rtwdev, addr: reg[i], MASKDWORD, data: reg_backup[i]);
3469
3470 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3471 fmt: "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i],
3472 reg_backup[i]);
3473 }
3474}
3475
3476static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel)
3477{
3478 u8 channel_index;
3479
3480 if (channel >= 1 && channel <= 14)
3481 channel_index = channel - 1;
3482 else if (channel >= 36 && channel <= 64)
3483 channel_index = (channel - 36) / 2 + 14;
3484 else if (channel >= 100 && channel <= 144)
3485 channel_index = ((channel - 100) / 2) + 15 + 14;
3486 else if (channel >= 149 && channel <= 177)
3487 channel_index = ((channel - 149) / 2) + 38 + 14;
3488 else
3489 channel_index = 0;
3490
3491 return channel_index;
3492}
3493
3494static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3495 enum rtw89_rf_path path, const s16 *power,
3496 u32 *tssi_cw_rpt)
3497{
3498 u32 tx_counter, tx_counter_tmp;
3499 const int retry = 100;
3500 u32 tmp;
3501 int j, k;
3502
3503 for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) {
3504 rtw89_phy_write32_mask(rtwdev, addr: _tssi_trigger[path], B_P0_TSSI_EN, data: 0x0);
3505 rtw89_phy_write32_mask(rtwdev, addr: _tssi_trigger[path], B_P0_TSSI_EN, data: 0x1);
3506
3507 tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
3508
3509 tmp = rtw89_phy_read32_mask(rtwdev, addr: _tssi_trigger[path], MASKDWORD);
3510 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3511 fmt: "[TSSI PA K] 0x%x = 0x%08x path=%d\n",
3512 _tssi_trigger[path], tmp, path);
3513
3514 if (j == 0)
3515 _tssi_hw_tx(rtwdev, phy, path, cnt: 100, period: 5000, pwr_dbm: power[j], enable: true);
3516 else
3517 _tssi_hw_tx(rtwdev, phy, path: RF_PATH_ABCD, cnt: 100, period: 5000, pwr_dbm: power[j], enable: true);
3518
3519 tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
3520 tx_counter_tmp -= tx_counter;
3521
3522 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3523 fmt: "[TSSI PA K] First HWTXcounter=%d path=%d\n",
3524 tx_counter_tmp, path);
3525
3526 for (k = 0; k < retry; k++) {
3527 tmp = rtw89_phy_read32_mask(rtwdev, addr: _tssi_cw_rpt_addr[path],
3528 B_TSSI_CWRPT_RDY);
3529 if (tmp)
3530 break;
3531
3532 udelay(30);
3533
3534 tx_counter_tmp =
3535 rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
3536 tx_counter_tmp -= tx_counter;
3537
3538 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3539 fmt: "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n",
3540 k, tx_counter_tmp, path);
3541 }
3542
3543 if (k >= retry) {
3544 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3545 fmt: "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n",
3546 k, path);
3547
3548 _tssi_hw_tx(rtwdev, phy, path, cnt: 100, period: 5000, pwr_dbm: power[j], enable: false);
3549 return false;
3550 }
3551
3552 tssi_cw_rpt[j] =
3553 rtw89_phy_read32_mask(rtwdev, addr: _tssi_cw_rpt_addr[path], B_TSSI_CWRPT);
3554
3555 _tssi_hw_tx(rtwdev, phy, path, cnt: 100, period: 5000, pwr_dbm: power[j], enable: false);
3556
3557 tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
3558 tx_counter_tmp -= tx_counter;
3559
3560 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3561 fmt: "[TSSI PA K] Final HWTXcounter=%d path=%d\n",
3562 tx_counter_tmp, path);
3563 }
3564
3565 return true;
3566}
3567
3568static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3569 enum rtw89_rf_path path)
3570{
3571 static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4,
3572 0x78e4, 0x49c0, 0x0d18, 0x0d80};
3573 static const s16 power_2g[4] = {48, 20, 4, 4};
3574 static const s16 power_5g[4] = {48, 20, 4, 4};
3575 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3576 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3577 s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3;
3578 u32 tssi_cw_rpt[RTW8852B_TSSI_PATH_NR] = {0};
3579 u8 channel = chan->channel;
3580 u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
3581 struct rtw8852b_bb_tssi_bak tssi_bak;
3582 s32 aliment_diff, tssi_cw_default;
3583 u32 start_time, finish_time;
3584 u32 bb_reg_backup[8] = {0};
3585 const s16 *power;
3586 u8 band;
3587 bool ok;
3588 u32 tmp;
3589 u8 j;
3590
3591 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3592 fmt: "======> %s channel=%d path=%d\n", __func__, channel,
3593 path);
3594
3595 if (tssi_info->check_backup_aligmk[path][ch_idx]) {
3596 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD,
3597 data: tssi_info->alignment_backup_by_ch[path][ch_idx][0]);
3598 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD,
3599 data: tssi_info->alignment_backup_by_ch[path][ch_idx][1]);
3600 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD,
3601 data: tssi_info->alignment_backup_by_ch[path][ch_idx][2]);
3602 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD,
3603 data: tssi_info->alignment_backup_by_ch[path][ch_idx][3]);
3604
3605 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3606 fmt: "======> %s Reload TSSI Alignment !!!\n", __func__);
3607 _tssi_alimentk_dump_result(rtwdev, path);
3608 return;
3609 }
3610
3611 start_time = ktime_get_ns();
3612
3613 if (chan->band_type == RTW89_BAND_2G)
3614 power = power_2g;
3615 else
3616 power = power_5g;
3617
3618 if (channel >= 1 && channel <= 14)
3619 band = TSSI_ALIMK_2G;
3620 else if (channel >= 36 && channel <= 64)
3621 band = TSSI_ALIMK_5GL;
3622 else if (channel >= 100 && channel <= 144)
3623 band = TSSI_ALIMK_5GM;
3624 else if (channel >= 149 && channel <= 177)
3625 band = TSSI_ALIMK_5GH;
3626 else
3627 band = TSSI_ALIMK_2G;
3628
3629 rtw8852b_bb_backup_tssi(rtwdev, idx: phy, bak: &tssi_bak);
3630 _tssi_backup_bb_registers(rtwdev, phy, reg: bb_reg, reg_backup: bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
3631
3632 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, data: 0x8);
3633 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, data: 0x8);
3634 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, data: 0x2);
3635 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, data: 0x2);
3636
3637 ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt);
3638 if (!ok)
3639 goto out;
3640
3641 for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) {
3642 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3643 fmt: "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j,
3644 power[j], j, tssi_cw_rpt[j]);
3645 }
3646
3647 tmp = rtw89_phy_read32_mask(rtwdev, addr: _tssi_cw_default_addr[path][1],
3648 mask: _tssi_cw_default_mask[1]);
3649 tssi_cw_default = sign_extend32(value: tmp, index: 8);
3650 tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) -
3651 tssi_cw_rpt[1] + tssi_cw_default;
3652 aliment_diff = tssi_alim_offset_1 - tssi_cw_default;
3653
3654 tmp = rtw89_phy_read32_mask(rtwdev, addr: _tssi_cw_default_addr[path][2],
3655 mask: _tssi_cw_default_mask[2]);
3656 tssi_cw_default = sign_extend32(value: tmp, index: 8);
3657 tssi_alim_offset_2 = tssi_cw_default + aliment_diff;
3658
3659 tmp = rtw89_phy_read32_mask(rtwdev, addr: _tssi_cw_default_addr[path][3],
3660 mask: _tssi_cw_default_mask[3]);
3661 tssi_cw_default = sign_extend32(value: tmp, index: 8);
3662 tssi_alim_offset_3 = tssi_cw_default + aliment_diff;
3663
3664 if (path == RF_PATH_A) {
3665 tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
3666 FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
3667 FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
3668
3669 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, data: tmp);
3670 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, data: tmp);
3671
3672 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3673 fmt: "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
3674 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31),
3675 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11),
3676 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12),
3677 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13));
3678 } else {
3679 tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
3680 FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
3681 FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
3682
3683 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, data: tmp);
3684 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, data: tmp);
3685
3686 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3687 fmt: "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
3688 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31),
3689 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11),
3690 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12),
3691 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13));
3692 }
3693
3694 tssi_info->alignment_done[path][band] = true;
3695 tssi_info->alignment_value[path][band][0] =
3696 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
3697 tssi_info->alignment_value[path][band][1] =
3698 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
3699 tssi_info->alignment_value[path][band][2] =
3700 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
3701 tssi_info->alignment_value[path][band][3] =
3702 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
3703
3704 tssi_info->check_backup_aligmk[path][ch_idx] = true;
3705 tssi_info->alignment_backup_by_ch[path][ch_idx][0] =
3706 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
3707 tssi_info->alignment_backup_by_ch[path][ch_idx][1] =
3708 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
3709 tssi_info->alignment_backup_by_ch[path][ch_idx][2] =
3710 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
3711 tssi_info->alignment_backup_by_ch[path][ch_idx][3] =
3712 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
3713
3714 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3715 fmt: "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n",
3716 path, band, R_P0_TSSI_ALIM1 + (path << 13),
3717 tssi_info->alignment_value[path][band][0]);
3718 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3719 fmt: "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n",
3720 path, band, R_P0_TSSI_ALIM3 + (path << 13),
3721 tssi_info->alignment_value[path][band][1]);
3722 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3723 fmt: "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n",
3724 path, band, R_P0_TSSI_ALIM2 + (path << 13),
3725 tssi_info->alignment_value[path][band][2]);
3726 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3727 fmt: "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n",
3728 path, band, R_P0_TSSI_ALIM4 + (path << 13),
3729 tssi_info->alignment_value[path][band][3]);
3730
3731out:
3732 _tssi_reload_bb_registers(rtwdev, phy, reg: bb_reg, reg_backup: bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
3733 rtw8852b_bb_restore_tssi(rtwdev, idx: phy, bak: &tssi_bak);
3734 rtw8852b_bb_tx_mode_switch(rtwdev, idx: phy, mode: 0);
3735
3736 finish_time = ktime_get_ns();
3737 tssi_info->tssi_alimk_time += finish_time - start_time;
3738
3739 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3740 fmt: "[TSSI PA K] %s processing time = %d ms\n", __func__,
3741 tssi_info->tssi_alimk_time);
3742}
3743
3744void rtw8852b_dpk_init(struct rtw89_dev *rtwdev)
3745{
3746 _set_dpd_backoff(rtwdev, phy: RTW89_PHY_0);
3747}
3748
3749void rtw8852b_rck(struct rtw89_dev *rtwdev)
3750{
3751 u8 path;
3752
3753 for (path = 0; path < RF_PATH_NUM_8852B; path++)
3754 _rck(rtwdev, path);
3755}
3756
3757void rtw8852b_dack(struct rtw89_dev *rtwdev)
3758{
3759 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx: RTW89_PHY_0, paths: 0);
3760
3761 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_START);
3762 _dac_cal(rtwdev, force: false);
3763 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_STOP);
3764}
3765
3766void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
3767{
3768 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0);
3769 u32 tx_en;
3770
3771 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_START);
3772 rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL);
3773 _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx));
3774
3775 _iqk_init(rtwdev);
3776 _iqk(rtwdev, phy_idx, force: false);
3777
3778 rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en);
3779 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_STOP);
3780}
3781
3782void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
3783{
3784 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0);
3785 u32 tx_en;
3786
3787 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_RXDCK, state: BTC_WRFK_START);
3788 rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL);
3789 _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx));
3790
3791 _rx_dck(rtwdev, phy: phy_idx);
3792
3793 rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en);
3794 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_RXDCK, state: BTC_WRFK_STOP);
3795}
3796
3797void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
3798{
3799 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0);
3800 u32 tx_en;
3801
3802 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DPK, state: BTC_WRFK_START);
3803 rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL);
3804 _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx));
3805
3806 rtwdev->dpk.is_dpk_enable = true;
3807 rtwdev->dpk.is_dpk_reload_en = false;
3808 _dpk(rtwdev, phy: phy_idx, force: false);
3809
3810 rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en);
3811 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DPK, state: BTC_WRFK_STOP);
3812}
3813
3814void rtw8852b_dpk_track(struct rtw89_dev *rtwdev)
3815{
3816 _dpk_track(rtwdev);
3817}
3818
3819void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en)
3820{
3821 u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx: phy, paths: RF_AB);
3822 u32 tx_en;
3823 u8 i;
3824
3825 rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "[TSSI] %s: phy=%d\n", __func__, phy);
3826 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_START);
3827
3828 _tssi_disable(rtwdev, phy);
3829
3830 for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
3831 _tssi_rf_setting(rtwdev, phy, path: i);
3832 _tssi_set_sys(rtwdev, phy, path: i);
3833 _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, path: i);
3834 _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, path: i);
3835 _tssi_set_dck(rtwdev, phy, path: i);
3836 _tssi_set_tmeter_tbl(rtwdev, phy, path: i);
3837 _tssi_set_dac_gain_tbl(rtwdev, phy, path: i);
3838 _tssi_slope_cal_org(rtwdev, phy, path: i);
3839 _tssi_alignment_default(rtwdev, phy, path: i, all: true);
3840 _tssi_set_tssi_slope(rtwdev, phy, path: i);
3841
3842 rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL);
3843 _tmac_tx_pause(rtwdev, band_idx: phy, is_pause: true);
3844 if (hwtx_en)
3845 _tssi_alimentk(rtwdev, phy, path: i);
3846 _tmac_tx_pause(rtwdev, band_idx: phy, is_pause: false);
3847 rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy, tx_en);
3848 }
3849
3850 _tssi_enable(rtwdev, phy);
3851 _tssi_set_efuse_to_de(rtwdev, phy);
3852
3853 rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_STOP);
3854}
3855
3856void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
3857{
3858 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3859 struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
3860 u8 channel = chan->channel;
3861 u8 band;
3862 u32 i;
3863
3864 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3865 fmt: "======>%s phy=%d channel=%d\n", __func__, phy, channel);
3866
3867 if (channel >= 1 && channel <= 14)
3868 band = TSSI_ALIMK_2G;
3869 else if (channel >= 36 && channel <= 64)
3870 band = TSSI_ALIMK_5GL;
3871 else if (channel >= 100 && channel <= 144)
3872 band = TSSI_ALIMK_5GM;
3873 else if (channel >= 149 && channel <= 177)
3874 band = TSSI_ALIMK_5GH;
3875 else
3876 band = TSSI_ALIMK_2G;
3877
3878 _tssi_disable(rtwdev, phy);
3879
3880 for (i = RF_PATH_A; i < RTW8852B_TSSI_PATH_NR; i++) {
3881 _tssi_rf_setting(rtwdev, phy, path: i);
3882 _tssi_set_sys(rtwdev, phy, path: i);
3883 _tssi_set_tmeter_tbl(rtwdev, phy, path: i);
3884
3885 if (tssi_info->alignment_done[i][band])
3886 _tssi_alimentk_done(rtwdev, phy, path: i);
3887 else
3888 _tssi_alignment_default(rtwdev, phy, path: i, all: true);
3889 }
3890
3891 _tssi_enable(rtwdev, phy);
3892 _tssi_set_efuse_to_de(rtwdev, phy);
3893}
3894
3895static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
3896 enum rtw89_phy_idx phy, bool enable)
3897{
3898 const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0);
3899 u8 channel = chan->channel;
3900
3901 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "======> %s ch=%d\n",
3902 __func__, channel);
3903
3904 if (enable) {
3905 if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B])
3906 rtw8852b_tssi(rtwdev, phy, hwtx_en: true);
3907 return;
3908 }
3909
3910 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3911 fmt: "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
3912 __func__,
3913 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
3914 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
3915
3916 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, data: 0xc0);
3917 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, data: 0xc0);
3918 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, data: 0x0);
3919 rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, data: 0x1);
3920 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, data: 0x0);
3921 rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, data: 0x1);
3922
3923 _tssi_alimentk_done(rtwdev, phy, path: RF_PATH_A);
3924 _tssi_alimentk_done(rtwdev, phy, path: RF_PATH_B);
3925
3926 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3927 fmt: "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
3928 __func__,
3929 rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
3930 rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
3931
3932 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3933 fmt: "======> %s SCAN_END\n", __func__);
3934}
3935
3936void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
3937 enum rtw89_phy_idx phy_idx)
3938{
3939 if (scan_start)
3940 rtw8852b_tssi_default_txagc(rtwdev, phy: phy_idx, enable: true);
3941 else
3942 rtw8852b_tssi_default_txagc(rtwdev, phy: phy_idx, enable: false);
3943}
3944
3945static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
3946 enum rtw89_bandwidth bw, bool dav)
3947{
3948 u32 rf_reg18;
3949 u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
3950
3951 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===> %s\n", __func__);
3952
3953 rf_reg18 = rtw89_read_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK);
3954 if (rf_reg18 == INV_RF_DATA) {
3955 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
3956 fmt: "[RFK]Invalid RF_0x18 for Path-%d\n", path);
3957 return;
3958 }
3959 rf_reg18 &= ~RR_CFGCH_BW;
3960
3961 switch (bw) {
3962 case RTW89_CHANNEL_WIDTH_5:
3963 case RTW89_CHANNEL_WIDTH_10:
3964 case RTW89_CHANNEL_WIDTH_20:
3965 rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M);
3966 break;
3967 case RTW89_CHANNEL_WIDTH_40:
3968 rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M);
3969 break;
3970 case RTW89_CHANNEL_WIDTH_80:
3971 rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M);
3972 break;
3973 default:
3974 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]Fail to set CH\n");
3975 }
3976
3977 rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
3978 RR_CFGCH_BW2) & RFREG_MASK;
3979 rf_reg18 |= RR_CFGCH_BW2;
3980 rtw89_write_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK, data: rf_reg18);
3981
3982 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK] set %x at path%d, %x =0x%x\n",
3983 bw, path, reg18_addr,
3984 rtw89_read_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK));
3985}
3986
3987static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
3988 enum rtw89_bandwidth bw)
3989{
3990 _bw_setting(rtwdev, path: RF_PATH_A, bw, dav: true);
3991 _bw_setting(rtwdev, path: RF_PATH_B, bw, dav: true);
3992 _bw_setting(rtwdev, path: RF_PATH_A, bw, dav: false);
3993 _bw_setting(rtwdev, path: RF_PATH_B, bw, dav: false);
3994}
3995
3996static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val)
3997{
3998 u32 bak;
3999 u32 tmp;
4000 int ret;
4001
4002 bak = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_LDO, RFREG_MASK);
4003 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LDO, RR_LDO_SEL, data: 0x1);
4004 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_CFGCH, RFREG_MASK, data: val);
4005
4006 ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000,
4007 false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY);
4008 if (ret)
4009 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[LCK]LCK timeout\n");
4010
4011 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LDO, RFREG_MASK, data: bak);
4012
4013 return !!ret;
4014}
4015
4016static void _lck_check(struct rtw89_dev *rtwdev)
4017{
4018 u32 tmp;
4019
4020 if (rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
4021 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[LCK]SYN MMD reset\n");
4022
4023 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MMD, RR_MMD_RST_EN, data: 0x1);
4024 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, data: 0x0);
4025 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, data: 0x1);
4026 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MMD, RR_MMD_RST_EN, data: 0x0);
4027 }
4028
4029 udelay(10);
4030
4031 if (rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
4032 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[LCK]re-set RF 0x18\n");
4033
4034 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x1);
4035 tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_CFGCH, RFREG_MASK);
4036 _set_s0_arfc18(rtwdev, val: tmp);
4037 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x0);
4038 }
4039
4040 if (rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
4041 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[LCK]SYN off/on\n");
4042
4043 tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_POW, RFREG_MASK);
4044 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_POW, RFREG_MASK, data: tmp);
4045 tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_SX, RFREG_MASK);
4046 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_SX, RFREG_MASK, data: tmp);
4047
4048 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, data: 0x1);
4049 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_POW, RR_POW_SYN, data: 0x0);
4050 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_POW, RR_POW_SYN, data: 0x3);
4051 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, data: 0x0);
4052
4053 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x1);
4054 tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_CFGCH, RFREG_MASK);
4055 _set_s0_arfc18(rtwdev, val: tmp);
4056 rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x0);
4057
4058 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[LCK]0xb2=%x, 0xc5=%x\n",
4059 rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_VCO, RFREG_MASK),
4060 rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_SYNFB, RFREG_MASK));
4061 }
4062}
4063
4064static void _set_ch(struct rtw89_dev *rtwdev, u32 val)
4065{
4066 bool timeout;
4067
4068 timeout = _set_s0_arfc18(rtwdev, val);
4069 if (!timeout)
4070 _lck_check(rtwdev);
4071}
4072
4073static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
4074 u8 central_ch, bool dav)
4075{
4076 u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
4077 bool is_2g_ch = central_ch <= 14;
4078 u32 rf_reg18;
4079
4080 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===> %s\n", __func__);
4081
4082 rf_reg18 = rtw89_read_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK);
4083 rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH |
4084 RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH);
4085 rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch);
4086
4087 if (!is_2g_ch)
4088 rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) |
4089 FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G);
4090
4091 rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
4092 RR_CFGCH_BW2) & RFREG_MASK;
4093 rf_reg18 |= RR_CFGCH_BW2;
4094
4095 if (path == RF_PATH_A && dav)
4096 _set_ch(rtwdev, val: rf_reg18);
4097 else
4098 rtw89_write_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK, data: rf_reg18);
4099
4100 rtw89_write_rf(rtwdev, rf_path: path, RR_LCKST, RR_LCKST_BIN, data: 0);
4101 rtw89_write_rf(rtwdev, rf_path: path, RR_LCKST, RR_LCKST_BIN, data: 1);
4102
4103 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK,
4104 fmt: "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n",
4105 central_ch, path, reg18_addr,
4106 rtw89_read_rf(rtwdev, rf_path: path, addr: reg18_addr, RFREG_MASK));
4107}
4108
4109static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch)
4110{
4111 _ch_setting(rtwdev, path: RF_PATH_A, central_ch, dav: true);
4112 _ch_setting(rtwdev, path: RF_PATH_B, central_ch, dav: true);
4113 _ch_setting(rtwdev, path: RF_PATH_A, central_ch, dav: false);
4114 _ch_setting(rtwdev, path: RF_PATH_B, central_ch, dav: false);
4115}
4116
4117static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw,
4118 enum rtw89_rf_path path)
4119{
4120 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE2, RR_LUTWE2_RTXBW, data: 0x1);
4121 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RR_LUTWA_M2, data: 0x12);
4122
4123 if (bw == RTW89_CHANNEL_WIDTH_20)
4124 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB, data: 0x1b);
4125 else if (bw == RTW89_CHANNEL_WIDTH_40)
4126 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB, data: 0x13);
4127 else if (bw == RTW89_CHANNEL_WIDTH_80)
4128 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB, data: 0xb);
4129 else
4130 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB, data: 0x3);
4131
4132 rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path,
4133 rtw89_read_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB));
4134
4135 rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE2, RR_LUTWE2_RTXBW, data: 0x0);
4136}
4137
4138static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
4139 enum rtw89_bandwidth bw)
4140{
4141 u8 kpath, path;
4142
4143 kpath = _kpath(rtwdev, phy_idx: phy);
4144
4145 for (path = 0; path < RF_PATH_NUM_8852B; path++) {
4146 if (!(kpath & BIT(path)))
4147 continue;
4148
4149 _set_rxbb_bw(rtwdev, bw, path);
4150 }
4151}
4152
4153static void rtw8852b_ctrl_bw_ch(struct rtw89_dev *rtwdev,
4154 enum rtw89_phy_idx phy, u8 central_ch,
4155 enum rtw89_band band, enum rtw89_bandwidth bw)
4156{
4157 _ctrl_ch(rtwdev, central_ch);
4158 _ctrl_bw(rtwdev, phy, bw);
4159 _rxbb_bw(rtwdev, phy, bw);
4160}
4161
4162void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
4163 const struct rtw89_chan *chan,
4164 enum rtw89_phy_idx phy_idx)
4165{
4166 rtw8852b_ctrl_bw_ch(rtwdev, phy: phy_idx, central_ch: chan->channel, band: chan->band_type,
4167 bw: chan->band_width);
4168}
4169

source code of linux/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c