1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause |
2 | /* Copyright(c) 2019-2022 Realtek Corporation |
3 | */ |
4 | |
5 | #include "chan.h" |
6 | #include "coex.h" |
7 | #include "debug.h" |
8 | #include "phy.h" |
9 | #include "reg.h" |
10 | #include "rtw8852c.h" |
11 | #include "rtw8852c_rfk.h" |
12 | #include "rtw8852c_rfk_table.h" |
13 | #include "rtw8852c_table.h" |
14 | |
15 | struct rxck_def { |
16 | u32 ctl; |
17 | u32 en; |
18 | u32 bw0; |
19 | u32 bw1; |
20 | u32 mul; |
21 | u32 lp; |
22 | }; |
23 | |
24 | #define _TSSI_DE_MASK GENMASK(21, 12) |
25 | static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852C] = {0x5858, 0x7858}; |
26 | static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852C] = {0x5860, 0x7860}; |
27 | static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852C] = {0x5838, 0x7838}; |
28 | static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852C] = {0x5840, 0x7840}; |
29 | static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852C] = {0x5848, 0x7848}; |
30 | static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852C] = {0x5850, 0x7850}; |
31 | static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852C] = {0x5828, 0x7828}; |
32 | static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852C] = {0x5830, 0x7830}; |
33 | |
34 | static const u32 rtw8852c_backup_bb_regs[] = { |
35 | 0x8120, 0xc0d4, 0xc0d8, 0xc0e8, 0x8220, 0xc1d4, 0xc1d8, 0xc1e8 |
36 | }; |
37 | |
38 | static const u32 rtw8852c_backup_rf_regs[] = { |
39 | 0xdf, 0x5f, 0x8f, 0x97, 0xa3, 0x5, 0x10005 |
40 | }; |
41 | |
42 | #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852c_backup_bb_regs) |
43 | #define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852c_backup_rf_regs) |
44 | |
45 | #define RXK_GROUP_NR 4 |
46 | static const u32 _rxk_a6_idxrxgain[RXK_GROUP_NR] = {0x190, 0x196, 0x290, 0x316}; |
47 | static const u32 _rxk_a6_idxattc2[RXK_GROUP_NR] = {0x00, 0x0, 0x00, 0x00}; |
48 | static const u32 _rxk_a_idxrxgain[RXK_GROUP_NR] = {0x190, 0x198, 0x310, 0x318}; |
49 | static const u32 _rxk_a_idxattc2[RXK_GROUP_NR] = {0x00, 0x00, 0x00, 0x00}; |
50 | static const u32 _rxk_g_idxrxgain[RXK_GROUP_NR] = {0x252, 0x26c, 0x350, 0x360}; |
51 | static const u32 _rxk_g_idxattc2[RXK_GROUP_NR] = {0x00, 0x07, 0x00, 0x3}; |
52 | |
53 | #define TXK_GROUP_NR 3 |
54 | static const u32 _txk_a6_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; |
55 | static const u32 _txk_a6_track_range[TXK_GROUP_NR] = {0x6, 0x7, 0x7}; |
56 | static const u32 _txk_a6_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; |
57 | static const u32 _txk_a6_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; |
58 | static const u32 _txk_a_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; |
59 | static const u32 _txk_a_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x7}; |
60 | static const u32 _txk_a_gain_bb[TXK_GROUP_NR] = {0x12, 0x09, 0x0e}; |
61 | static const u32 _txk_a_itqt[TXK_GROUP_NR] = {0x12, 0x12, 0x12}; |
62 | static const u32 _txk_g_power_range[TXK_GROUP_NR] = {0x0, 0x0, 0x0}; |
63 | static const u32 _txk_g_track_range[TXK_GROUP_NR] = {0x5, 0x6, 0x6}; |
64 | static const u32 _txk_g_gain_bb[TXK_GROUP_NR] = {0x0e, 0x0a, 0x0e}; |
65 | static const u32 _txk_g_itqt[TXK_GROUP_NR] = { 0x12, 0x12, 0x12}; |
66 | |
67 | static const u32 dpk_par_regs[RTW89_DPK_RF_PATH][4] = { |
68 | {0x8190, 0x8194, 0x8198, 0x81a4}, |
69 | {0x81a8, 0x81c4, 0x81c8, 0x81e8}, |
70 | }; |
71 | |
72 | static const u8 _dck_addr_bs[RF_PATH_NUM_8852C] = {0x0, 0x10}; |
73 | static const u8 _dck_addr[RF_PATH_NUM_8852C] = {0xc, 0x1c}; |
74 | |
75 | static const struct rxck_def _ck480M = {0x8, 0x2, 0x3, 0xf, 0x0, 0x9}; |
76 | static const struct rxck_def _ck960M = {0x8, 0x2, 0x2, 0x8, 0x0, 0x9}; |
77 | static const struct rxck_def _ck1920M = {0x8, 0x0, 0x2, 0x4, 0x6, 0x9}; |
78 | |
79 | static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) |
80 | { |
81 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]dbcc_en: %x, PHY%d\n" , |
82 | rtwdev->dbcc_en, phy_idx); |
83 | |
84 | if (!rtwdev->dbcc_en) |
85 | return RF_AB; |
86 | |
87 | if (phy_idx == RTW89_PHY_0) |
88 | return RF_A; |
89 | else |
90 | return RF_B; |
91 | } |
92 | |
93 | static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) |
94 | { |
95 | u32 i; |
96 | |
97 | for (i = 0; i < BACKUP_BB_REGS_NR; i++) { |
98 | backup_bb_reg_val[i] = |
99 | rtw89_phy_read32_mask(rtwdev, addr: rtw8852c_backup_bb_regs[i], |
100 | MASKDWORD); |
101 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
102 | fmt: "[IQK]backup bb reg : %x, value =%x\n" , |
103 | rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); |
104 | } |
105 | } |
106 | |
107 | static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], |
108 | u8 rf_path) |
109 | { |
110 | u32 i; |
111 | |
112 | for (i = 0; i < BACKUP_RF_REGS_NR; i++) { |
113 | backup_rf_reg_val[i] = |
114 | rtw89_read_rf(rtwdev, rf_path, |
115 | addr: rtw8852c_backup_rf_regs[i], RFREG_MASK); |
116 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
117 | fmt: "[IQK]backup rf S%d reg : %x, value =%x\n" , rf_path, |
118 | rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); |
119 | } |
120 | } |
121 | |
122 | static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) |
123 | { |
124 | u32 i; |
125 | |
126 | for (i = 0; i < BACKUP_BB_REGS_NR; i++) { |
127 | rtw89_phy_write32_mask(rtwdev, addr: rtw8852c_backup_bb_regs[i], |
128 | MASKDWORD, data: backup_bb_reg_val[i]); |
129 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
130 | fmt: "[IQK]restore bb reg : %x, value =%x\n" , |
131 | rtw8852c_backup_bb_regs[i], backup_bb_reg_val[i]); |
132 | } |
133 | } |
134 | |
135 | static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], |
136 | u8 rf_path) |
137 | { |
138 | u32 i; |
139 | |
140 | for (i = 0; i < BACKUP_RF_REGS_NR; i++) { |
141 | rtw89_write_rf(rtwdev, rf_path, addr: rtw8852c_backup_rf_regs[i], |
142 | RFREG_MASK, data: backup_rf_reg_val[i]); |
143 | |
144 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
145 | fmt: "[IQK]restore rf S%d reg: %x, value =%x\n" , rf_path, |
146 | rtw8852c_backup_rf_regs[i], backup_rf_reg_val[i]); |
147 | } |
148 | } |
149 | |
150 | static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) |
151 | { |
152 | u8 path; |
153 | u32 rf_mode; |
154 | int ret; |
155 | |
156 | for (path = 0; path < RF_PATH_MAX; path++) { |
157 | if (!(kpath & BIT(path))) |
158 | continue; |
159 | |
160 | ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, |
161 | 2, 5000, false, rtwdev, path, 0x00, |
162 | RR_MOD_MASK); |
163 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
164 | fmt: "[RFK] Wait S%d to Rx mode!! (ret = %d)\n" , |
165 | path, ret); |
166 | } |
167 | } |
168 | |
169 | static void _dack_dump(struct rtw89_dev *rtwdev) |
170 | { |
171 | struct rtw89_dack_info *dack = &rtwdev->dack; |
172 | u8 i; |
173 | u8 t; |
174 | |
175 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
176 | fmt: "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n" , |
177 | dack->addck_d[0][0], dack->addck_d[0][1]); |
178 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
179 | fmt: "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n" , |
180 | dack->addck_d[1][0], dack->addck_d[1][1]); |
181 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
182 | fmt: "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n" , |
183 | dack->dadck_d[0][0], dack->dadck_d[0][1]); |
184 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
185 | fmt: "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n" , |
186 | dack->dadck_d[1][0], dack->dadck_d[1][1]); |
187 | |
188 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
189 | fmt: "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n" , |
190 | dack->biask_d[0][0], dack->biask_d[0][1]); |
191 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
192 | fmt: "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n" , |
193 | dack->biask_d[1][0], dack->biask_d[1][1]); |
194 | |
195 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 MSBK ic:\n" ); |
196 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
197 | t = dack->msbk_d[0][0][i]; |
198 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n" , t); |
199 | } |
200 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 MSBK qc:\n" ); |
201 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
202 | t = dack->msbk_d[0][1][i]; |
203 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n" , t); |
204 | } |
205 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 MSBK ic:\n" ); |
206 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
207 | t = dack->msbk_d[1][0][i]; |
208 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n" , t); |
209 | } |
210 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 MSBK qc:\n" ); |
211 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
212 | t = dack->msbk_d[1][1][i]; |
213 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x\n" , t); |
214 | } |
215 | } |
216 | |
217 | static void _addck_backup(struct rtw89_dev *rtwdev) |
218 | { |
219 | struct rtw89_dack_info *dack = &rtwdev->dack; |
220 | |
221 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, data: 0x0); |
222 | dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, |
223 | B_ADDCKR0_A0); |
224 | dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, |
225 | B_ADDCKR0_A1); |
226 | |
227 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, data: 0x0); |
228 | dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, |
229 | B_ADDCKR1_A0); |
230 | dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, |
231 | B_ADDCKR1_A1); |
232 | } |
233 | |
234 | static void _addck_reload(struct rtw89_dev *rtwdev) |
235 | { |
236 | struct rtw89_dack_info *dack = &rtwdev->dack; |
237 | |
238 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, |
239 | data: dack->addck_d[0][0]); |
240 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, |
241 | data: dack->addck_d[0][1]); |
242 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, data: 0x3); |
243 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL1, |
244 | data: dack->addck_d[1][0]); |
245 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RL0, |
246 | data: dack->addck_d[1][1]); |
247 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1_RL, B_ADDCK1_RLS, data: 0x3); |
248 | } |
249 | |
250 | static void _dack_backup_s0(struct rtw89_dev *rtwdev) |
251 | { |
252 | struct rtw89_dack_info *dack = &rtwdev->dack; |
253 | u8 i; |
254 | |
255 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x1); |
256 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
257 | rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, data: i); |
258 | dack->msbk_d[0][0][i] = rtw89_phy_read32_mask(rtwdev, |
259 | R_DACK_S0P2, |
260 | B_DACK_S0M0); |
261 | rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, data: i); |
262 | dack->msbk_d[0][1][i] = rtw89_phy_read32_mask(rtwdev, |
263 | R_DACK_S0P3, |
264 | B_DACK_S0M1); |
265 | } |
266 | dack->biask_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, |
267 | B_DACK_BIAS00); |
268 | dack->biask_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, |
269 | B_DACK_BIAS01); |
270 | dack->dadck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, |
271 | B_DACK_DADCK00); |
272 | dack->dadck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, |
273 | B_DACK_DADCK01); |
274 | } |
275 | |
276 | static void _dack_backup_s1(struct rtw89_dev *rtwdev) |
277 | { |
278 | struct rtw89_dack_info *dack = &rtwdev->dack; |
279 | u8 i; |
280 | |
281 | rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x1); |
282 | for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { |
283 | rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, data: i); |
284 | dack->msbk_d[1][0][i] = rtw89_phy_read32_mask(rtwdev, |
285 | R_DACK10S, |
286 | B_DACK10S); |
287 | rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, data: i); |
288 | dack->msbk_d[1][1][i] = rtw89_phy_read32_mask(rtwdev, |
289 | R_DACK11S, |
290 | B_DACK11S); |
291 | } |
292 | dack->biask_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, |
293 | B_DACK_BIAS10); |
294 | dack->biask_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, |
295 | B_DACK_BIAS11); |
296 | dack->dadck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, |
297 | B_DACK_DADCK10); |
298 | dack->dadck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, |
299 | B_DACK_DADCK11); |
300 | } |
301 | |
302 | static void _dack_reload_by_path(struct rtw89_dev *rtwdev, |
303 | enum rtw89_rf_path path, u8 index) |
304 | { |
305 | struct rtw89_dack_info *dack = &rtwdev->dack; |
306 | u32 idx_offset, path_offset; |
307 | u32 val32, offset, addr; |
308 | u8 i; |
309 | |
310 | idx_offset = (index == 0 ? 0 : 0x14); |
311 | path_offset = (path == RF_PATH_A ? 0 : 0x28); |
312 | offset = idx_offset + path_offset; |
313 | |
314 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_dack_reload_defs_tbl); |
315 | |
316 | /* msbk_d: 15/14/13/12 */ |
317 | val32 = 0x0; |
318 | for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) |
319 | val32 |= dack->msbk_d[path][index][i + 12] << (i * 8); |
320 | addr = 0xc200 + offset; |
321 | rtw89_phy_write32(rtwdev, addr, data: val32); |
322 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x=0x%x\n" , addr, |
323 | rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); |
324 | |
325 | /* msbk_d: 11/10/9/8 */ |
326 | val32 = 0x0; |
327 | for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) |
328 | val32 |= dack->msbk_d[path][index][i + 8] << (i * 8); |
329 | addr = 0xc204 + offset; |
330 | rtw89_phy_write32(rtwdev, addr, data: val32); |
331 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x=0x%x\n" , addr, |
332 | rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); |
333 | |
334 | /* msbk_d: 7/6/5/4 */ |
335 | val32 = 0x0; |
336 | for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) |
337 | val32 |= dack->msbk_d[path][index][i + 4] << (i * 8); |
338 | addr = 0xc208 + offset; |
339 | rtw89_phy_write32(rtwdev, addr, data: val32); |
340 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x=0x%x\n" , addr, |
341 | rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); |
342 | |
343 | /* msbk_d: 3/2/1/0 */ |
344 | val32 = 0x0; |
345 | for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) |
346 | val32 |= dack->msbk_d[path][index][i] << (i * 8); |
347 | addr = 0xc20c + offset; |
348 | rtw89_phy_write32(rtwdev, addr, data: val32); |
349 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0x%x=0x%x\n" , addr, |
350 | rtw89_phy_read32_mask(rtwdev, addr, MASKDWORD)); |
351 | |
352 | /* dadak_d/biask_d */ |
353 | val32 = (dack->biask_d[path][index] << 22) | |
354 | (dack->dadck_d[path][index] << 14); |
355 | addr = 0xc210 + offset; |
356 | rtw89_phy_write32(rtwdev, addr, data: val32); |
357 | rtw89_phy_write32_set(rtwdev, addr, BIT(0)); |
358 | } |
359 | |
360 | static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) |
361 | { |
362 | u8 i; |
363 | |
364 | for (i = 0; i < 2; i++) |
365 | _dack_reload_by_path(rtwdev, path, index: i); |
366 | } |
367 | |
368 | static void _addck(struct rtw89_dev *rtwdev) |
369 | { |
370 | struct rtw89_dack_info *dack = &rtwdev->dack; |
371 | u32 val; |
372 | int ret; |
373 | |
374 | /* S0 */ |
375 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, data: 0x1); |
376 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, data: 0x1); |
377 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, data: 0x0); |
378 | fsleep(usecs: 1); |
379 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, data: 0x1); |
380 | |
381 | ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, |
382 | 1, 10000, false, rtwdev, 0xc0fc, BIT(0)); |
383 | if (ret) { |
384 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 ADDCK timeout\n" ); |
385 | dack->addck_timeout[0] = true; |
386 | } |
387 | |
388 | rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, data: 0x0); |
389 | |
390 | /* S1 */ |
391 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, data: 0x1); |
392 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, data: 0x1); |
393 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_EN, data: 0x0); |
394 | udelay(1); |
395 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, data: 0x1); |
396 | |
397 | ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, |
398 | 1, 10000, false, rtwdev, 0xc1fc, BIT(0)); |
399 | if (ret) { |
400 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 ADDCK timeout\n" ); |
401 | dack->addck_timeout[0] = true; |
402 | } |
403 | rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_RST, data: 0x0); |
404 | } |
405 | |
406 | static void _dack_reset(struct rtw89_dev *rtwdev, u8 path) |
407 | { |
408 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
409 | &rtw8852c_dack_reset_defs_a_tbl, |
410 | &rtw8852c_dack_reset_defs_b_tbl); |
411 | } |
412 | |
413 | enum adc_ck { |
414 | ADC_NA = 0, |
415 | ADC_480M = 1, |
416 | ADC_960M = 2, |
417 | ADC_1920M = 3, |
418 | }; |
419 | |
420 | enum dac_ck { |
421 | DAC_40M = 0, |
422 | DAC_80M = 1, |
423 | DAC_120M = 2, |
424 | DAC_160M = 3, |
425 | DAC_240M = 4, |
426 | DAC_320M = 5, |
427 | DAC_480M = 6, |
428 | DAC_960M = 7, |
429 | }; |
430 | |
431 | enum rf_mode { |
432 | RF_SHUT_DOWN = 0x0, |
433 | RF_STANDBY = 0x1, |
434 | RF_TX = 0x2, |
435 | RF_RX = 0x3, |
436 | RF_TXIQK = 0x4, |
437 | RF_DPK = 0x5, |
438 | RF_RXK1 = 0x6, |
439 | RF_RXK2 = 0x7, |
440 | }; |
441 | |
442 | static void rtw8852c_txck_force(struct rtw89_dev *rtwdev, u8 path, bool force, |
443 | enum dac_ck ck) |
444 | { |
445 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, data: 0x0); |
446 | |
447 | if (!force) |
448 | return; |
449 | |
450 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_VAL, data: ck); |
451 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_TXCK_ON, data: 0x1); |
452 | } |
453 | |
454 | static void rtw8852c_rxck_force(struct rtw89_dev *rtwdev, u8 path, bool force, |
455 | enum adc_ck ck) |
456 | { |
457 | const struct rxck_def *def; |
458 | |
459 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, data: 0x0); |
460 | |
461 | if (!force) |
462 | return; |
463 | |
464 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_VAL, data: ck); |
465 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK | (path << 13), B_P0_RXCK_ON, data: 0x1); |
466 | |
467 | switch (ck) { |
468 | case ADC_480M: |
469 | def = &_ck480M; |
470 | break; |
471 | case ADC_960M: |
472 | def = &_ck960M; |
473 | break; |
474 | case ADC_1920M: |
475 | default: |
476 | def = &_ck1920M; |
477 | break; |
478 | } |
479 | |
480 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_CTL, data: def->ctl); |
481 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_EN, data: def->en); |
482 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data: def->bw0); |
483 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data: def->bw1); |
484 | rtw89_phy_write32_mask(rtwdev, R_DRCK | (path << 8), B_DRCK_MUL, data: def->mul); |
485 | rtw89_phy_write32_mask(rtwdev, R_ADCMOD | (path << 8), B_ADCMOD_LP, data: def->lp); |
486 | } |
487 | |
488 | static bool _check_dack_done(struct rtw89_dev *rtwdev, bool s0) |
489 | { |
490 | if (s0) { |
491 | if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || |
492 | rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || |
493 | rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || |
494 | rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) |
495 | return false; |
496 | } else { |
497 | if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 || |
498 | rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0 || |
499 | rtw89_phy_read32_mask(rtwdev, R_DACK_S1P2, B_DACK_S1P2_OK) == 0 || |
500 | rtw89_phy_read32_mask(rtwdev, R_DACK_S1P3, B_DACK_S1P3_OK) == 0) |
501 | return false; |
502 | } |
503 | |
504 | return true; |
505 | } |
506 | |
507 | static void _dack_s0(struct rtw89_dev *rtwdev) |
508 | { |
509 | struct rtw89_dack_info *dack = &rtwdev->dack; |
510 | bool done; |
511 | int ret; |
512 | |
513 | rtw8852c_txck_force(rtwdev, path: RF_PATH_A, force: true, ck: DAC_160M); |
514 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_dack_defs_s0_tbl); |
515 | |
516 | _dack_reset(rtwdev, path: RF_PATH_A); |
517 | |
518 | rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, data: 0x1); |
519 | ret = read_poll_timeout_atomic(_check_dack_done, done, done, |
520 | 1, 10000, false, rtwdev, true); |
521 | if (ret) { |
522 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S0 DACK timeout\n" ); |
523 | dack->msbk_timeout[0] = true; |
524 | } |
525 | rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, data: 0x0); |
526 | rtw8852c_txck_force(rtwdev, path: RF_PATH_A, force: false, ck: DAC_960M); |
527 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S0 DADCK\n" ); |
528 | |
529 | _dack_backup_s0(rtwdev); |
530 | _dack_reload(rtwdev, path: RF_PATH_A); |
531 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, data: 0x0); |
532 | } |
533 | |
534 | static void _dack_s1(struct rtw89_dev *rtwdev) |
535 | { |
536 | struct rtw89_dack_info *dack = &rtwdev->dack; |
537 | bool done; |
538 | int ret; |
539 | |
540 | rtw8852c_txck_force(rtwdev, path: RF_PATH_B, force: true, ck: DAC_160M); |
541 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_dack_defs_s1_tbl); |
542 | |
543 | _dack_reset(rtwdev, path: RF_PATH_B); |
544 | |
545 | rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, data: 0x1); |
546 | ret = read_poll_timeout_atomic(_check_dack_done, done, done, |
547 | 1, 10000, false, rtwdev, false); |
548 | if (ret) { |
549 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]S1 DACK timeout\n" ); |
550 | dack->msbk_timeout[0] = true; |
551 | } |
552 | rtw89_phy_write32_mask(rtwdev, R_DACK1_K, B_DACK1_EN, data: 0x0); |
553 | rtw8852c_txck_force(rtwdev, path: RF_PATH_B, force: false, ck: DAC_960M); |
554 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]after S1 DADCK\n" ); |
555 | |
556 | _dack_backup_s1(rtwdev); |
557 | _dack_reload(rtwdev, path: RF_PATH_B); |
558 | rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, data: 0x0); |
559 | } |
560 | |
561 | static void _dack(struct rtw89_dev *rtwdev) |
562 | { |
563 | _dack_s0(rtwdev); |
564 | _dack_s1(rtwdev); |
565 | } |
566 | |
567 | static void _drck(struct rtw89_dev *rtwdev) |
568 | { |
569 | u32 val; |
570 | int ret; |
571 | |
572 | rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, data: 0x1); |
573 | ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, |
574 | 1, 10000, false, rtwdev, 0xc0c8, BIT(3)); |
575 | if (ret) |
576 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DRCK timeout\n" ); |
577 | |
578 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_drck_defs_tbl); |
579 | |
580 | val = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, B_DRCK_RES); |
581 | rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, data: 0x0); |
582 | rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, data: val); |
583 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]0xc0c4 = 0x%x\n" , |
584 | rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); |
585 | } |
586 | |
587 | static void _dac_cal(struct rtw89_dev *rtwdev, bool force) |
588 | { |
589 | struct rtw89_dack_info *dack = &rtwdev->dack; |
590 | u32 rf0_0, rf1_0; |
591 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx: RTW89_PHY_0, paths: RF_AB); |
592 | |
593 | dack->dack_done = false; |
594 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK b\n" ); |
595 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK start!!!\n" ); |
596 | rf0_0 = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK); |
597 | rf1_0 = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK); |
598 | _drck(rtwdev); |
599 | |
600 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_RSV1, RR_RSV1_RST, data: 0x0); |
601 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x0); |
602 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK, data: 0x337e1); |
603 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK, data: 0x337e1); |
604 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_ONESHOT_START); |
605 | _addck(rtwdev); |
606 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_ONESHOT_STOP); |
607 | |
608 | _addck_backup(rtwdev); |
609 | _addck_reload(rtwdev); |
610 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MODOPT, RFREG_MASK, data: 0x0); |
611 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MODOPT, RFREG_MASK, data: 0x0); |
612 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_ONESHOT_START); |
613 | _dack(rtwdev); |
614 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_ONESHOT_STOP); |
615 | |
616 | _dack_dump(rtwdev); |
617 | dack->dack_done = true; |
618 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_MOD, RFREG_MASK, data: rf0_0); |
619 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_MOD, RFREG_MASK, data: rf1_0); |
620 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_A, RR_RSV1, RR_RSV1_RST, data: 0x1); |
621 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x1); |
622 | dack->dack_cnt++; |
623 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DACK]DACK finish!!!\n" ); |
624 | } |
625 | |
626 | #define RTW8852C_NCTL_VER 0xd |
627 | #define RTW8852C_IQK_VER 0x2a |
628 | #define RTW8852C_IQK_SS 2 |
629 | #define RTW8852C_IQK_THR_REK 8 |
630 | #define RTW8852C_IQK_CFIR_GROUP_NR 4 |
631 | |
632 | enum rtw8852c_iqk_type { |
633 | ID_TXAGC, |
634 | ID_G_FLOK_COARSE, |
635 | ID_A_FLOK_COARSE, |
636 | ID_G_FLOK_FINE, |
637 | ID_A_FLOK_FINE, |
638 | ID_FLOK_VBUFFER, |
639 | ID_TXK, |
640 | ID_RXAGC, |
641 | ID_RXK, |
642 | ID_NBTXK, |
643 | ID_NBRXK, |
644 | }; |
645 | |
646 | static void rtw8852c_disable_rxagc(struct rtw89_dev *rtwdev, u8 path, u8 en_rxgac) |
647 | { |
648 | if (path == RF_PATH_A) |
649 | rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, data: en_rxgac); |
650 | else |
651 | rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, data: en_rxgac); |
652 | } |
653 | |
654 | static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) |
655 | { |
656 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
657 | |
658 | if (path == RF_PATH_A) |
659 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, data: 0x0101); |
660 | else |
661 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, data: 0x0202); |
662 | |
663 | switch (iqk_info->iqk_bw[path]) { |
664 | case RTW89_CHANNEL_WIDTH_20: |
665 | case RTW89_CHANNEL_WIDTH_40: |
666 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, data: 0x1); |
667 | rtw8852c_rxck_force(rtwdev, path, force: true, ck: ADC_480M); |
668 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, data: 0x0); |
669 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_CKT, data: 0x1); |
670 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, data: 0x1); |
671 | break; |
672 | case RTW89_CHANNEL_WIDTH_80: |
673 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, data: 0x1); |
674 | rtw8852c_rxck_force(rtwdev, path, force: true, ck: ADC_960M); |
675 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, data: 0x1); |
676 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_CKT, data: 0x1); |
677 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, data: 0x1); |
678 | break; |
679 | case RTW89_CHANNEL_WIDTH_160: |
680 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_DPD_GDIS, data: 0x1); |
681 | rtw8852c_rxck_force(rtwdev, path, force: true, ck: ADC_1920M); |
682 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_ACK_VAL, data: 0x2); |
683 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_CKT, data: 0x1); |
684 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, data: 0x1); |
685 | break; |
686 | default: |
687 | break; |
688 | } |
689 | |
690 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_iqk_rxk_cfg_defs_tbl); |
691 | |
692 | if (path == RF_PATH_A) |
693 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, data: 0x1101); |
694 | else |
695 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, data: 0x2202); |
696 | } |
697 | |
698 | static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) |
699 | { |
700 | u32 tmp; |
701 | u32 val; |
702 | int ret; |
703 | |
704 | ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, |
705 | 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0); |
706 | if (ret) |
707 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]IQK timeout!!!\n" ); |
708 | |
709 | rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); |
710 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%x, ret=%d\n" , path, ret); |
711 | tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); |
712 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
713 | fmt: "[IQK]S%x, type= %x, 0x8008 = 0x%x\n" , path, ktype, tmp); |
714 | |
715 | return false; |
716 | } |
717 | |
718 | static bool _iqk_one_shot(struct rtw89_dev *rtwdev, |
719 | enum rtw89_phy_idx phy_idx, u8 path, u8 ktype) |
720 | { |
721 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
722 | u32 addr_rfc_ctl = R_UPD_CLK + (path << 13); |
723 | u32 iqk_cmd; |
724 | bool fail; |
725 | |
726 | switch (ktype) { |
727 | case ID_TXAGC: |
728 | iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); |
729 | break; |
730 | case ID_A_FLOK_COARSE: |
731 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
732 | iqk_cmd = 0x008 | (1 << (4 + path)); |
733 | break; |
734 | case ID_G_FLOK_COARSE: |
735 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
736 | iqk_cmd = 0x108 | (1 << (4 + path)); |
737 | break; |
738 | case ID_A_FLOK_FINE: |
739 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
740 | iqk_cmd = 0x508 | (1 << (4 + path)); |
741 | break; |
742 | case ID_G_FLOK_FINE: |
743 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
744 | iqk_cmd = 0x208 | (1 << (4 + path)); |
745 | break; |
746 | case ID_FLOK_VBUFFER: |
747 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
748 | iqk_cmd = 0x308 | (1 << (4 + path)); |
749 | break; |
750 | case ID_TXK: |
751 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x0); |
752 | iqk_cmd = 0x008 | (1 << (4 + path)) | ((0x8 + iqk_info->iqk_bw[path]) << 8); |
753 | break; |
754 | case ID_RXAGC: |
755 | iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); |
756 | break; |
757 | case ID_RXK: |
758 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
759 | iqk_cmd = 0x008 | (1 << (4 + path)) | ((0xc + iqk_info->iqk_bw[path]) << 8); |
760 | break; |
761 | case ID_NBTXK: |
762 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x0); |
763 | iqk_cmd = 0x408 | (1 << (4 + path)); |
764 | break; |
765 | case ID_NBRXK: |
766 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x1); |
767 | iqk_cmd = 0x608 | (1 << (4 + path)); |
768 | break; |
769 | default: |
770 | return false; |
771 | } |
772 | |
773 | rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, data: iqk_cmd + 1); |
774 | fsleep(usecs: 15); |
775 | fail = _iqk_check_cal(rtwdev, path, ktype); |
776 | rtw89_phy_write32_mask(rtwdev, addr: addr_rfc_ctl, mask: 0x00000002, data: 0x0); |
777 | |
778 | return fail; |
779 | } |
780 | |
781 | static bool _rxk_group_sel(struct rtw89_dev *rtwdev, |
782 | enum rtw89_phy_idx phy_idx, u8 path) |
783 | { |
784 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
785 | bool fail; |
786 | u32 tmp; |
787 | u32 bkrf0; |
788 | u8 gp; |
789 | |
790 | bkrf0 = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW); |
791 | if (path == RF_PATH_B) { |
792 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, data: 0x3); |
793 | tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_CHTR, RR_CHTR_MOD); |
794 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV4, RR_RSV4_AGH, data: tmp); |
795 | tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); |
796 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, data: tmp); |
797 | } |
798 | |
799 | switch (iqk_info->iqk_band[path]) { |
800 | case RTW89_BAND_2G: |
801 | default: |
802 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
803 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
804 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXG, RR_RXG_IQKMOD, data: 0x9); |
805 | break; |
806 | case RTW89_BAND_5G: |
807 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
808 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
809 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXAE, RR_RXAE_IQKMOD, data: 0x8); |
810 | break; |
811 | case RTW89_BAND_6G: |
812 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
813 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
814 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXAE, RR_RXAE_IQKMOD, data: 0x9); |
815 | break; |
816 | } |
817 | |
818 | fsleep(usecs: 10); |
819 | |
820 | for (gp = 0; gp < RXK_GROUP_NR; gp++) { |
821 | switch (iqk_info->iqk_band[path]) { |
822 | case RTW89_BAND_2G: |
823 | default: |
824 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, |
825 | data: _rxk_g_idxrxgain[gp]); |
826 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_VOBUF, |
827 | data: _rxk_g_idxattc2[gp]); |
828 | break; |
829 | case RTW89_BAND_5G: |
830 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, |
831 | data: _rxk_a_idxrxgain[gp]); |
832 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_IATT, |
833 | data: _rxk_a_idxattc2[gp]); |
834 | break; |
835 | case RTW89_BAND_6G: |
836 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, |
837 | data: _rxk_a6_idxrxgain[gp]); |
838 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_IATT, |
839 | data: _rxk_a6_idxattc2[gp]); |
840 | break; |
841 | } |
842 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
843 | B_CFIR_LUT_SEL, data: 0x1); |
844 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
845 | B_CFIR_LUT_SET, data: 0x0); |
846 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
847 | B_CFIR_LUT_GP_V1, data: gp); |
848 | fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_RXK); |
849 | } |
850 | |
851 | if (path == RF_PATH_B) |
852 | rtw89_write_rf(rtwdev, rf_path: path, RR_IQKPLL, RR_IQKPLL_MOD, data: 0x0); |
853 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: bkrf0); |
854 | |
855 | if (fail) { |
856 | iqk_info->nb_rxcfir[path] = 0x40000002; |
857 | iqk_info->is_wb_rxiqk[path] = false; |
858 | } else { |
859 | iqk_info->nb_rxcfir[path] = 0x40000000; |
860 | iqk_info->is_wb_rxiqk[path] = true; |
861 | } |
862 | |
863 | return false; |
864 | } |
865 | |
866 | static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, |
867 | enum rtw89_phy_idx phy_idx, u8 path) |
868 | { |
869 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
870 | bool fail; |
871 | u32 tmp; |
872 | u32 bkrf0; |
873 | u8 gp = 0x2; |
874 | |
875 | bkrf0 = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW); |
876 | if (path == RF_PATH_B) { |
877 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_IQKPLL, RR_IQKPLL_MOD, data: 0x3); |
878 | tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_CHTR, RR_CHTR_MOD); |
879 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV4, RR_RSV4_AGH, data: tmp); |
880 | tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_CHTR, RR_CHTR_TXRX); |
881 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV4, RR_RSV4_PLLCH, data: tmp); |
882 | } |
883 | |
884 | switch (iqk_info->iqk_band[path]) { |
885 | case RTW89_BAND_2G: |
886 | default: |
887 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
888 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
889 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXG, RR_RXG_IQKMOD, data: 0x9); |
890 | break; |
891 | case RTW89_BAND_5G: |
892 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
893 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
894 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXAE, RR_RXAE_IQKMOD, data: 0x8); |
895 | break; |
896 | case RTW89_BAND_6G: |
897 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: 0xc); |
898 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: 0x0); |
899 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXAE, RR_RXAE_IQKMOD, data: 0x9); |
900 | break; |
901 | } |
902 | |
903 | fsleep(usecs: 10); |
904 | |
905 | switch (iqk_info->iqk_band[path]) { |
906 | case RTW89_BAND_2G: |
907 | default: |
908 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, data: _rxk_g_idxrxgain[gp]); |
909 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_VOBUF, data: _rxk_g_idxattc2[gp]); |
910 | break; |
911 | case RTW89_BAND_5G: |
912 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, data: _rxk_a_idxrxgain[gp]); |
913 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_IATT, data: _rxk_a_idxattc2[gp]); |
914 | break; |
915 | case RTW89_BAND_6G: |
916 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXG, data: _rxk_a6_idxrxgain[gp]); |
917 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_IATT, data: _rxk_a6_idxattc2[gp]); |
918 | break; |
919 | } |
920 | |
921 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, data: 0x1); |
922 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, data: 0x0); |
923 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, data: gp); |
924 | fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_RXK); |
925 | |
926 | if (path == RF_PATH_B) |
927 | rtw89_write_rf(rtwdev, rf_path: path, RR_IQKPLL, RR_IQKPLL_MOD, data: 0x0); |
928 | |
929 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_NBW, data: bkrf0); |
930 | |
931 | if (fail) |
932 | iqk_info->nb_rxcfir[path] = |
933 | rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), |
934 | MASKDWORD) | 0x2; |
935 | else |
936 | iqk_info->nb_rxcfir[path] = 0x40000002; |
937 | |
938 | iqk_info->is_wb_rxiqk[path] = false; |
939 | return fail; |
940 | } |
941 | |
942 | static bool _txk_group_sel(struct rtw89_dev *rtwdev, |
943 | enum rtw89_phy_idx phy_idx, u8 path) |
944 | { |
945 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
946 | bool fail; |
947 | u8 gp; |
948 | |
949 | for (gp = 0; gp < TXK_GROUP_NR; gp++) { |
950 | switch (iqk_info->iqk_band[path]) { |
951 | case RTW89_BAND_2G: |
952 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, |
953 | data: _txk_g_power_range[gp]); |
954 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, |
955 | data: _txk_g_track_range[gp]); |
956 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, |
957 | data: _txk_g_gain_bb[gp]); |
958 | rtw89_phy_write32_mask(rtwdev, |
959 | R_KIP_IQP + (path << 8), |
960 | MASKDWORD, data: _txk_g_itqt[gp]); |
961 | break; |
962 | case RTW89_BAND_5G: |
963 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, |
964 | data: _txk_a_power_range[gp]); |
965 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, |
966 | data: _txk_a_track_range[gp]); |
967 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, |
968 | data: _txk_a_gain_bb[gp]); |
969 | rtw89_phy_write32_mask(rtwdev, |
970 | R_KIP_IQP + (path << 8), |
971 | MASKDWORD, data: _txk_a_itqt[gp]); |
972 | break; |
973 | case RTW89_BAND_6G: |
974 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, |
975 | data: _txk_a6_power_range[gp]); |
976 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, |
977 | data: _txk_a6_track_range[gp]); |
978 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, |
979 | data: _txk_a6_gain_bb[gp]); |
980 | rtw89_phy_write32_mask(rtwdev, |
981 | R_KIP_IQP + (path << 8), |
982 | MASKDWORD, data: _txk_a6_itqt[gp]); |
983 | break; |
984 | default: |
985 | break; |
986 | } |
987 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
988 | B_CFIR_LUT_SEL, data: 0x1); |
989 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
990 | B_CFIR_LUT_SET, data: 0x1); |
991 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
992 | B_CFIR_LUT_G2, data: 0x0); |
993 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), |
994 | B_CFIR_LUT_GP, data: gp + 1); |
995 | rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, data: 0x00b); |
996 | rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00); |
997 | fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_TXK); |
998 | } |
999 | |
1000 | if (fail) { |
1001 | iqk_info->nb_txcfir[path] = 0x40000002; |
1002 | iqk_info->is_wb_txiqk[path] = false; |
1003 | } else { |
1004 | iqk_info->nb_txcfir[path] = 0x40000000; |
1005 | iqk_info->is_wb_txiqk[path] = true; |
1006 | } |
1007 | |
1008 | return fail; |
1009 | } |
1010 | |
1011 | static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, |
1012 | enum rtw89_phy_idx phy_idx, u8 path) |
1013 | { |
1014 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1015 | bool fail; |
1016 | u8 gp = 0x2; |
1017 | |
1018 | switch (iqk_info->iqk_band[path]) { |
1019 | case RTW89_BAND_2G: |
1020 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: _txk_g_power_range[gp]); |
1021 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: _txk_g_track_range[gp]); |
1022 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: _txk_g_gain_bb[gp]); |
1023 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1024 | MASKDWORD, data: _txk_g_itqt[gp]); |
1025 | break; |
1026 | case RTW89_BAND_5G: |
1027 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: _txk_a_power_range[gp]); |
1028 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: _txk_a_track_range[gp]); |
1029 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: _txk_a_gain_bb[gp]); |
1030 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1031 | MASKDWORD, data: _txk_a_itqt[gp]); |
1032 | break; |
1033 | case RTW89_BAND_6G: |
1034 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: _txk_a6_power_range[gp]); |
1035 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: _txk_a6_track_range[gp]); |
1036 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: _txk_a6_gain_bb[gp]); |
1037 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1038 | MASKDWORD, data: _txk_a6_itqt[gp]); |
1039 | break; |
1040 | default: |
1041 | break; |
1042 | } |
1043 | |
1044 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, data: 0x1); |
1045 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, data: 0x1); |
1046 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, data: 0x0); |
1047 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, data: gp + 1); |
1048 | rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, data: 0x00b); |
1049 | rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00); |
1050 | fail = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_NBTXK); |
1051 | |
1052 | if (!fail) |
1053 | iqk_info->nb_txcfir[path] = |
1054 | rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), |
1055 | MASKDWORD) | 0x2; |
1056 | else |
1057 | iqk_info->nb_txcfir[path] = 0x40000002; |
1058 | |
1059 | iqk_info->is_wb_txiqk[path] = false; |
1060 | |
1061 | return fail; |
1062 | } |
1063 | |
1064 | static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) |
1065 | { |
1066 | struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; |
1067 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1068 | u8 idx = rfk_mcc->table_idx; |
1069 | bool is_fail1, is_fail2; |
1070 | u32 val; |
1071 | u32 core_i; |
1072 | u32 core_q; |
1073 | u32 vbuff_i; |
1074 | u32 vbuff_q; |
1075 | |
1076 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===>%s\n" , __func__); |
1077 | val = rtw89_read_rf(rtwdev, rf_path: path, RR_TXMO, RFREG_MASK); |
1078 | core_i = FIELD_GET(RR_TXMO_COI, val); |
1079 | core_q = FIELD_GET(RR_TXMO_COQ, val); |
1080 | |
1081 | if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) |
1082 | is_fail1 = true; |
1083 | else |
1084 | is_fail1 = false; |
1085 | |
1086 | iqk_info->lok_idac[idx][path] = val; |
1087 | |
1088 | val = rtw89_read_rf(rtwdev, rf_path: path, RR_LOKVB, RFREG_MASK); |
1089 | vbuff_i = FIELD_GET(RR_LOKVB_COI, val); |
1090 | vbuff_q = FIELD_GET(RR_LOKVB_COQ, val); |
1091 | |
1092 | if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d) |
1093 | is_fail2 = true; |
1094 | else |
1095 | is_fail2 = false; |
1096 | |
1097 | iqk_info->lok_vbuf[idx][path] = val; |
1098 | |
1099 | return is_fail1 || is_fail2; |
1100 | } |
1101 | |
1102 | static bool _iqk_lok(struct rtw89_dev *rtwdev, |
1103 | enum rtw89_phy_idx phy_idx, u8 path) |
1104 | { |
1105 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1106 | u8 tmp_id = 0x0; |
1107 | bool fail = false; |
1108 | bool tmp = false; |
1109 | |
1110 | /* Step 0: Init RF gain & tone idx= 8.25Mhz */ |
1111 | rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, IQK_DF4_TXT_8_25MHZ); |
1112 | |
1113 | /* Step 1 START: _lok_coarse_fine_wi_swap */ |
1114 | switch (iqk_info->iqk_band[path]) { |
1115 | case RTW89_BAND_2G: |
1116 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1117 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1118 | B_KIP_IQP_IQSW, data: 0x9); |
1119 | tmp_id = ID_G_FLOK_COARSE; |
1120 | break; |
1121 | case RTW89_BAND_5G: |
1122 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1123 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1124 | B_KIP_IQP_IQSW, data: 0x9); |
1125 | tmp_id = ID_A_FLOK_COARSE; |
1126 | break; |
1127 | case RTW89_BAND_6G: |
1128 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1129 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1130 | B_KIP_IQP_IQSW, data: 0x9); |
1131 | tmp_id = ID_A_FLOK_COARSE; |
1132 | break; |
1133 | default: |
1134 | break; |
1135 | } |
1136 | tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: tmp_id); |
1137 | iqk_info->lok_cor_fail[0][path] = tmp; |
1138 | |
1139 | /* Step 2 */ |
1140 | switch (iqk_info->iqk_band[path]) { |
1141 | case RTW89_BAND_2G: |
1142 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1143 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1144 | B_KIP_IQP_IQSW, data: 0x1b); |
1145 | break; |
1146 | case RTW89_BAND_5G: |
1147 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1148 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1149 | B_KIP_IQP_IQSW, data: 0x1b); |
1150 | break; |
1151 | case RTW89_BAND_6G: |
1152 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1153 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1154 | B_KIP_IQP_IQSW, data: 0x1b); |
1155 | break; |
1156 | default: |
1157 | break; |
1158 | } |
1159 | tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_VBUFFER); |
1160 | |
1161 | /* Step 3 */ |
1162 | switch (iqk_info->iqk_band[path]) { |
1163 | case RTW89_BAND_2G: |
1164 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1165 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1166 | B_KIP_IQP_IQSW, data: 0x9); |
1167 | tmp_id = ID_G_FLOK_FINE; |
1168 | break; |
1169 | case RTW89_BAND_5G: |
1170 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1171 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1172 | B_KIP_IQP_IQSW, data: 0x9); |
1173 | tmp_id = ID_A_FLOK_FINE; |
1174 | break; |
1175 | case RTW89_BAND_6G: |
1176 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x6); |
1177 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1178 | B_KIP_IQP_IQSW, data: 0x9); |
1179 | tmp_id = ID_A_FLOK_FINE; |
1180 | break; |
1181 | default: |
1182 | break; |
1183 | } |
1184 | tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: tmp_id); |
1185 | iqk_info->lok_fin_fail[0][path] = tmp; |
1186 | |
1187 | /* Step 4 large rf gain */ |
1188 | switch (iqk_info->iqk_band[path]) { |
1189 | case RTW89_BAND_2G: |
1190 | default: |
1191 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1192 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1193 | B_KIP_IQP_IQSW, data: 0x1b); |
1194 | break; |
1195 | case RTW89_BAND_5G: |
1196 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1197 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1198 | B_KIP_IQP_IQSW, data: 0x1b); |
1199 | break; |
1200 | case RTW89_BAND_6G: |
1201 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0x12); |
1202 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), |
1203 | B_KIP_IQP_IQSW, data: 0x1b); |
1204 | break; |
1205 | } |
1206 | tmp = _iqk_one_shot(rtwdev, phy_idx, path, ktype: ID_FLOK_VBUFFER); |
1207 | fail = _lok_finetune_check(rtwdev, path); |
1208 | |
1209 | return fail; |
1210 | } |
1211 | |
1212 | static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) |
1213 | { |
1214 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1215 | |
1216 | switch (iqk_info->iqk_band[path]) { |
1217 | case RTW89_BAND_2G: |
1218 | default: |
1219 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXG1, RR_TXG1_ATT2, data: 0x0); |
1220 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXG1, RR_TXG1_ATT1, data: 0x0); |
1221 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXG2, RR_TXG2_ATT0, data: 0x1); |
1222 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXA2, RR_TXA2_LDO, data: 0xf); |
1223 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXGA, RR_TXGA_LOK_EXT, data: 0x0); |
1224 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x1); |
1225 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, |
1226 | data: 0x403e0 | iqk_info->syn1to2); |
1227 | fsleep(usecs: 10); |
1228 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0); |
1229 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x6); |
1230 | break; |
1231 | case RTW89_BAND_5G: |
1232 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXATANK, RR_TXATANK_LBSW2, data: 0x0); |
1233 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXPOW, RR_TXPOW_TXAS, data: 0x1); |
1234 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXA2, RR_TXA2_LDO, data: 0xf); |
1235 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXGA, RR_TXGA_LOK_EXT, data: 0x0); |
1236 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x1); |
1237 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, |
1238 | data: 0x403e0 | iqk_info->syn1to2); |
1239 | fsleep(usecs: 10); |
1240 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0); |
1241 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x6); |
1242 | break; |
1243 | case RTW89_BAND_6G: |
1244 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXATANK, RR_TXATANK_LBSW2, data: 0x0); |
1245 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXPOW, RR_TXPOW_TXAS, data: 0x1); |
1246 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXA2, RR_TXA2_LDO, data: 0xf); |
1247 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXGA, RR_TXGA_LOK_EXT, data: 0x0); |
1248 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x1); |
1249 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, |
1250 | data: 0x403e0 | iqk_info->syn1to2); |
1251 | fsleep(usecs: 10); |
1252 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0); |
1253 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x6); |
1254 | break; |
1255 | } |
1256 | } |
1257 | |
1258 | static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, |
1259 | u8 path) |
1260 | { |
1261 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1262 | u32 tmp; |
1263 | bool flag; |
1264 | |
1265 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%d_thermal = %lu\n" , path, |
1266 | ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path])); |
1267 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%d_LOK_COR_fail= %d\n" , path, |
1268 | iqk_info->lok_cor_fail[0][path]); |
1269 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%d_LOK_FIN_fail= %d\n" , path, |
1270 | iqk_info->lok_fin_fail[0][path]); |
1271 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%d_TXIQK_fail = %d\n" , path, |
1272 | iqk_info->iqk_tx_fail[0][path]); |
1273 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]S%d_RXIQK_fail= %d,\n" , path, |
1274 | iqk_info->iqk_rx_fail[0][path]); |
1275 | |
1276 | flag = iqk_info->lok_cor_fail[0][path]; |
1277 | rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), data: flag); |
1278 | flag = iqk_info->lok_fin_fail[0][path]; |
1279 | rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), data: flag); |
1280 | flag = iqk_info->iqk_tx_fail[0][path]; |
1281 | rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), data: flag); |
1282 | flag = iqk_info->iqk_rx_fail[0][path]; |
1283 | rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), data: flag); |
1284 | |
1285 | tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); |
1286 | iqk_info->bp_iqkenable[path] = tmp; |
1287 | tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); |
1288 | iqk_info->bp_txkresult[path] = tmp; |
1289 | tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); |
1290 | iqk_info->bp_rxkresult[path] = tmp; |
1291 | |
1292 | rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, |
1293 | data: iqk_info->iqk_times); |
1294 | |
1295 | tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4)); |
1296 | if (tmp != 0x0) |
1297 | iqk_info->iqk_fail_cnt++; |
1298 | rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4), |
1299 | data: iqk_info->iqk_fail_cnt); |
1300 | } |
1301 | |
1302 | static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path) |
1303 | { |
1304 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1305 | |
1306 | _iqk_txk_setting(rtwdev, path); |
1307 | iqk_info->lok_fail[path] = _iqk_lok(rtwdev, phy_idx, path); |
1308 | |
1309 | if (iqk_info->is_nbiqk) |
1310 | iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path); |
1311 | else |
1312 | iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path); |
1313 | |
1314 | _iqk_rxk_setting(rtwdev, path); |
1315 | if (iqk_info->is_nbiqk) |
1316 | iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path); |
1317 | else |
1318 | iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path); |
1319 | |
1320 | _iqk_info_iqk(rtwdev, phy_idx, path); |
1321 | } |
1322 | |
1323 | static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, |
1324 | enum rtw89_phy_idx phy, u8 path) |
1325 | { |
1326 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
1327 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1328 | |
1329 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===>%s\n" , __func__); |
1330 | |
1331 | iqk_info->iqk_band[path] = chan->band_type; |
1332 | iqk_info->iqk_bw[path] = chan->band_width; |
1333 | iqk_info->iqk_ch[path] = chan->channel; |
1334 | |
1335 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1336 | fmt: "[IQK]iqk_info->iqk_band[%x] = 0x%x\n" , path, |
1337 | iqk_info->iqk_band[path]); |
1338 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n" , |
1339 | path, iqk_info->iqk_bw[path]); |
1340 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n" , |
1341 | path, iqk_info->iqk_ch[path]); |
1342 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1343 | fmt: "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n" , path, phy, |
1344 | rtwdev->dbcc_en ? "on" : "off" , |
1345 | iqk_info->iqk_band[path] == 0 ? "2G" : |
1346 | iqk_info->iqk_band[path] == 1 ? "5G" : "6G" , |
1347 | iqk_info->iqk_ch[path], |
1348 | iqk_info->iqk_bw[path] == 0 ? "20M" : |
1349 | iqk_info->iqk_bw[path] == 1 ? "40M" : "80M" ); |
1350 | if (!rtwdev->dbcc_en) |
1351 | iqk_info->syn1to2 = 0x1; |
1352 | else |
1353 | iqk_info->syn1to2 = 0x3; |
1354 | |
1355 | rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852C_IQK_VER); |
1356 | rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16), |
1357 | data: iqk_info->iqk_band[path]); |
1358 | rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16), |
1359 | data: iqk_info->iqk_bw[path]); |
1360 | rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16), |
1361 | data: iqk_info->iqk_ch[path]); |
1362 | |
1363 | rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_NCTLV, RTW8852C_NCTL_VER); |
1364 | } |
1365 | |
1366 | static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, |
1367 | u8 path) |
1368 | { |
1369 | _iqk_by_path(rtwdev, phy_idx, path); |
1370 | } |
1371 | |
1372 | static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) |
1373 | { |
1374 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1375 | bool fail; |
1376 | |
1377 | rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, |
1378 | data: iqk_info->nb_txcfir[path]); |
1379 | rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, |
1380 | data: iqk_info->nb_rxcfir[path]); |
1381 | rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, |
1382 | data: 0x00001219 + (path << 4)); |
1383 | fsleep(usecs: 200); |
1384 | fail = _iqk_check_cal(rtwdev, path, ktype: 0x12); |
1385 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK] restore fail = %x\n" , fail); |
1386 | |
1387 | rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, data: 0x00); |
1388 | rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, data: 0x00000000); |
1389 | rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, data: 0x80000000); |
1390 | |
1391 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE, RR_LUTWE_LOK, data: 0x0); |
1392 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); |
1393 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x1); |
1394 | } |
1395 | |
1396 | static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, |
1397 | enum rtw89_phy_idx phy_idx, u8 path) |
1398 | { |
1399 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
1400 | &rtw8852c_iqk_afebb_restore_defs_a_tbl, |
1401 | &rtw8852c_iqk_afebb_restore_defs_b_tbl); |
1402 | |
1403 | rtw8852c_disable_rxagc(rtwdev, path, en_rxgac: 0x1); |
1404 | } |
1405 | |
1406 | static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) |
1407 | { |
1408 | struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; |
1409 | u8 idx = 0; |
1410 | |
1411 | idx = rfk_mcc->table_idx; |
1412 | rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, data: idx); |
1413 | rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, data: idx); |
1414 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0); |
1415 | rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, data: 0x00000080); |
1416 | rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, data: 0x81ff010a); |
1417 | } |
1418 | |
1419 | static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, |
1420 | enum rtw89_phy_idx phy_idx, u8 path) |
1421 | { |
1422 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===> %s\n" , __func__); |
1423 | |
1424 | /* 01_BB_AFE_for DPK_S0_20210820 */ |
1425 | rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x0); |
1426 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, data: 0x1); |
1427 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, data: 0x0); |
1428 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, data: 0x1); |
1429 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, data: 0x0); |
1430 | |
1431 | /* disable rxgac */ |
1432 | rtw8852c_disable_rxagc(rtwdev, path, en_rxgac: 0x0); |
1433 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), MASKDWORD, data: 0xf801fffd); |
1434 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_DIS, data: 0x1); |
1435 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DAC_VAL, data: 0x1); |
1436 | |
1437 | rtw8852c_txck_force(rtwdev, path, force: true, ck: DAC_960M); |
1438 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_DPD_GDIS, data: 0x1); |
1439 | |
1440 | rtw8852c_rxck_force(rtwdev, path, force: true, ck: ADC_1920M); |
1441 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK | (path << 13), B_ACK_VAL, data: 0x2); |
1442 | |
1443 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW | (path << 13), B_P0_NRBW_DBG, data: 0x1); |
1444 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x1f); |
1445 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, data: 0x13); |
1446 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0x0001); |
1447 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, data: 0x0041); |
1448 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, data: 0x1); |
1449 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, data: 0x1); |
1450 | } |
1451 | |
1452 | static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) |
1453 | { |
1454 | u32 rf_reg5, rck_val = 0; |
1455 | u32 val; |
1456 | int ret; |
1457 | |
1458 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] ====== S%d RCK ======\n" , path); |
1459 | |
1460 | rf_reg5 = rtw89_read_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK); |
1461 | |
1462 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0); |
1463 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); |
1464 | |
1465 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] RF0x00 = 0x%x\n" , |
1466 | rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK)); |
1467 | |
1468 | /* RCK trigger */ |
1469 | rtw89_write_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK, data: 0x00240); |
1470 | |
1471 | ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, |
1472 | false, rtwdev, path, 0x1c, BIT(3)); |
1473 | if (ret) |
1474 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RCK] RCK timeout\n" ); |
1475 | |
1476 | rck_val = rtw89_read_rf(rtwdev, rf_path: path, RR_RCKC, RR_RCKC_CA); |
1477 | rtw89_write_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK, data: rck_val); |
1478 | |
1479 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK, data: rf_reg5); |
1480 | |
1481 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1482 | fmt: "[RCK] RF 0x1b / 0x1c = 0x%x / 0x%x\n" , |
1483 | rtw89_read_rf(rtwdev, rf_path: path, RR_RCKC, RFREG_MASK), |
1484 | rtw89_read_rf(rtwdev, rf_path: path, RR_RCKS, RFREG_MASK)); |
1485 | } |
1486 | |
1487 | static void _iqk_init(struct rtw89_dev *rtwdev) |
1488 | { |
1489 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1490 | u8 ch, path; |
1491 | |
1492 | rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); |
1493 | if (iqk_info->is_iqk_init) |
1494 | return; |
1495 | |
1496 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]===>%s\n" , __func__); |
1497 | iqk_info->is_iqk_init = true; |
1498 | iqk_info->is_nbiqk = false; |
1499 | iqk_info->iqk_fft_en = false; |
1500 | iqk_info->iqk_sram_en = false; |
1501 | iqk_info->iqk_cfir_en = false; |
1502 | iqk_info->iqk_xym_en = false; |
1503 | iqk_info->iqk_times = 0x0; |
1504 | |
1505 | for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { |
1506 | iqk_info->iqk_channel[ch] = 0x0; |
1507 | for (path = 0; path < RTW8852C_IQK_SS; path++) { |
1508 | iqk_info->lok_cor_fail[ch][path] = false; |
1509 | iqk_info->lok_fin_fail[ch][path] = false; |
1510 | iqk_info->iqk_tx_fail[ch][path] = false; |
1511 | iqk_info->iqk_rx_fail[ch][path] = false; |
1512 | iqk_info->iqk_mcc_ch[ch][path] = 0x0; |
1513 | iqk_info->iqk_table_idx[path] = 0x0; |
1514 | } |
1515 | } |
1516 | } |
1517 | |
1518 | static void _doiqk(struct rtw89_dev *rtwdev, bool force, |
1519 | enum rtw89_phy_idx phy_idx, u8 path) |
1520 | { |
1521 | struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; |
1522 | u32 backup_bb_val[BACKUP_BB_REGS_NR]; |
1523 | u32 backup_rf_val[RTW8852C_IQK_SS][BACKUP_RF_REGS_NR]; |
1524 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: RF_AB); |
1525 | |
1526 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_START); |
1527 | |
1528 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1529 | fmt: "[IQK]==========IQK start!!!!!==========\n" ); |
1530 | iqk_info->iqk_times++; |
1531 | iqk_info->version = RTW8852C_IQK_VER; |
1532 | |
1533 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[IQK]Test Ver 0x%x\n" , iqk_info->version); |
1534 | _iqk_get_ch_info(rtwdev, phy: phy_idx, path); |
1535 | _rfk_backup_bb_reg(rtwdev, backup_bb_reg_val: backup_bb_val); |
1536 | _rfk_backup_rf_reg(rtwdev, backup_rf_reg_val: backup_rf_val[path], rf_path: path); |
1537 | _iqk_macbb_setting(rtwdev, phy_idx, path); |
1538 | _iqk_preset(rtwdev, path); |
1539 | _iqk_start_iqk(rtwdev, phy_idx, path); |
1540 | _iqk_restore(rtwdev, path); |
1541 | _iqk_afebb_restore(rtwdev, phy_idx, path); |
1542 | _rfk_restore_bb_reg(rtwdev, backup_bb_reg_val: backup_bb_val); |
1543 | _rfk_restore_rf_reg(rtwdev, backup_rf_reg_val: backup_rf_val[path], rf_path: path); |
1544 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_ONESHOT_STOP); |
1545 | } |
1546 | |
1547 | static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force) |
1548 | { |
1549 | switch (_kpath(rtwdev, phy_idx)) { |
1550 | case RF_A: |
1551 | _doiqk(rtwdev, force, phy_idx, path: RF_PATH_A); |
1552 | break; |
1553 | case RF_B: |
1554 | _doiqk(rtwdev, force, phy_idx, path: RF_PATH_B); |
1555 | break; |
1556 | case RF_AB: |
1557 | _doiqk(rtwdev, force, phy_idx, path: RF_PATH_A); |
1558 | _doiqk(rtwdev, force, phy_idx, path: RF_PATH_B); |
1559 | break; |
1560 | default: |
1561 | break; |
1562 | } |
1563 | } |
1564 | |
1565 | static void _rx_dck_value_rewrite(struct rtw89_dev *rtwdev, u8 path, u8 addr, |
1566 | u8 val_i, u8 val_q) |
1567 | { |
1568 | u32 ofst_val; |
1569 | |
1570 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1571 | fmt: "[RX_DCK] rewrite val_i = 0x%x, val_q = 0x%x\n" , val_i, val_q); |
1572 | |
1573 | /* val_i and val_q are 7 bits, and target is 6 bits. */ |
1574 | ofst_val = u32_encode_bits(v: val_q >> 1, RR_LUTWD0_MB) | |
1575 | u32_encode_bits(v: val_i >> 1, RR_LUTWD0_LB); |
1576 | |
1577 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTPLL, RR_CAL_RW, data: 0x1); |
1578 | rtw89_write_rf(rtwdev, rf_path: path, RR_RFC, RR_WCAL, data: 0x1); |
1579 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_FINE, data: 0x1); |
1580 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, MASKBYTE0, data: addr); |
1581 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RFREG_MASK, data: ofst_val); |
1582 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RFREG_MASK, data: ofst_val); |
1583 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_FINE, data: 0x0); |
1584 | rtw89_write_rf(rtwdev, rf_path: path, RR_RFC, RR_WCAL, data: 0x0); |
1585 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTPLL, RR_CAL_RW, data: 0x0); |
1586 | |
1587 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RX_DCK] Final val_i = 0x%x, val_q = 0x%x\n" , |
1588 | u32_get_bits(v: ofst_val, RR_LUTWD0_LB) << 1, |
1589 | u32_get_bits(v: ofst_val, RR_LUTWD0_MB) << 1); |
1590 | } |
1591 | |
1592 | static bool _rx_dck_rek_check(struct rtw89_dev *rtwdev, u8 path) |
1593 | { |
1594 | u8 i_even_bs, q_even_bs; |
1595 | u8 i_odd_bs, q_odd_bs; |
1596 | u8 i_even, q_even; |
1597 | u8 i_odd, q_odd; |
1598 | const u8 th = 10; |
1599 | u8 i; |
1600 | |
1601 | for (i = 0; i < RF_PATH_NUM_8852C; i++) { |
1602 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr_bs[i]); |
1603 | i_even_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1604 | q_even_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1605 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1606 | fmt: "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n" , |
1607 | _dck_addr_bs[i], i_even_bs, q_even_bs); |
1608 | |
1609 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr[i]); |
1610 | i_even = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1611 | q_even = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1612 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1613 | fmt: "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n" , |
1614 | _dck_addr[i], i_even, q_even); |
1615 | |
1616 | if (abs(i_even_bs - i_even) > th || abs(q_even_bs - q_even) > th) |
1617 | return true; |
1618 | |
1619 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr_bs[i] + 1); |
1620 | i_odd_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1621 | q_odd_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1622 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1623 | fmt: "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n" , |
1624 | _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); |
1625 | |
1626 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr[i] + 1); |
1627 | i_odd = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1628 | q_odd = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1629 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1630 | fmt: "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n" , |
1631 | _dck_addr[i] + 1, i_odd, q_odd); |
1632 | |
1633 | if (abs(i_odd_bs - i_odd) > th || abs(q_odd_bs - q_odd) > th) |
1634 | return true; |
1635 | } |
1636 | |
1637 | return false; |
1638 | } |
1639 | |
1640 | static void _rx_dck_fix_if_need(struct rtw89_dev *rtwdev, u8 path, u8 addr, |
1641 | u8 val_i_bs, u8 val_q_bs, u8 val_i, u8 val_q) |
1642 | { |
1643 | const u8 th = 10; |
1644 | |
1645 | if ((abs(val_i_bs - val_i) < th) && (abs(val_q_bs - val_q) <= th)) { |
1646 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RX_DCK] offset check PASS!!\n" ); |
1647 | return; |
1648 | } |
1649 | |
1650 | if (abs(val_i_bs - val_i) > th) { |
1651 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1652 | fmt: "[RX_DCK] val_i over TH (0x%x / 0x%x)\n" , val_i_bs, val_i); |
1653 | val_i = val_i_bs; |
1654 | } |
1655 | |
1656 | if (abs(val_q_bs - val_q) > th) { |
1657 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1658 | fmt: "[RX_DCK] val_q over TH (0x%x / 0x%x)\n" , val_q_bs, val_q); |
1659 | val_q = val_q_bs; |
1660 | } |
1661 | |
1662 | _rx_dck_value_rewrite(rtwdev, path, addr, val_i, val_q); |
1663 | } |
1664 | |
1665 | static void _rx_dck_recover(struct rtw89_dev *rtwdev, u8 path) |
1666 | { |
1667 | u8 i_even_bs, q_even_bs; |
1668 | u8 i_odd_bs, q_odd_bs; |
1669 | u8 i_even, q_even; |
1670 | u8 i_odd, q_odd; |
1671 | u8 i; |
1672 | |
1673 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RX_DCK] ===> recovery\n" ); |
1674 | |
1675 | for (i = 0; i < RF_PATH_NUM_8852C; i++) { |
1676 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr_bs[i]); |
1677 | i_even_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1678 | q_even_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1679 | |
1680 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr_bs[i] + 1); |
1681 | i_odd_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1682 | q_odd_bs = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1683 | |
1684 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1685 | fmt: "[RX_DCK] Gain[0x%x] i_even_bs/ q_even_bs = 0x%x/ 0x%x\n" , |
1686 | _dck_addr_bs[i], i_even_bs, q_even_bs); |
1687 | |
1688 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr[i]); |
1689 | i_even = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1690 | q_even = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1691 | |
1692 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1693 | fmt: "[RX_DCK] Gain[0x%x] i_even/ q_even = 0x%x/ 0x%x\n" , |
1694 | _dck_addr[i], i_even, q_even); |
1695 | _rx_dck_fix_if_need(rtwdev, path, addr: _dck_addr[i], |
1696 | val_i_bs: i_even_bs, val_q_bs: q_even_bs, val_i: i_even, val_q: q_even); |
1697 | |
1698 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1699 | fmt: "[RX_DCK] Gain[0x%x] i_odd_bs/ q_odd_bs = 0x%x/ 0x%x\n" , |
1700 | _dck_addr_bs[i] + 1, i_odd_bs, q_odd_bs); |
1701 | |
1702 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_DCK, data: _dck_addr[i] + 1); |
1703 | i_odd = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_TIA); |
1704 | q_odd = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_TIA); |
1705 | |
1706 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1707 | fmt: "[RX_DCK] Gain[0x%x] i_odd/ q_odd = 0x%x/ 0x%x\n" , |
1708 | _dck_addr[i] + 1, i_odd, q_odd); |
1709 | _rx_dck_fix_if_need(rtwdev, path, addr: _dck_addr[i] + 1, |
1710 | val_i_bs: i_odd_bs, val_q_bs: q_odd_bs, val_i: i_odd, val_q: q_odd); |
1711 | } |
1712 | } |
1713 | |
1714 | static void _rx_dck_toggle(struct rtw89_dev *rtwdev, u8 path) |
1715 | { |
1716 | int ret; |
1717 | u32 val; |
1718 | |
1719 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_LV, data: 0x0); |
1720 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_LV, data: 0x1); |
1721 | |
1722 | ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, |
1723 | 2, 2000, false, rtwdev, path, |
1724 | RR_DCK1, RR_DCK1_DONE); |
1725 | if (ret) |
1726 | rtw89_warn(rtwdev, "[RX_DCK] S%d RXDCK timeout\n" , path); |
1727 | else |
1728 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RX_DCK] S%d RXDCK finish\n" , path); |
1729 | |
1730 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_LV, data: 0x0); |
1731 | } |
1732 | |
1733 | static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path, |
1734 | bool is_afe) |
1735 | { |
1736 | u8 res; |
1737 | |
1738 | rtw89_write_rf(rtwdev, rf_path: path, RR_DCK1, RR_DCK1_CLR, data: 0x0); |
1739 | |
1740 | _rx_dck_toggle(rtwdev, path); |
1741 | if (rtw89_read_rf(rtwdev, rf_path: path, RR_DCKC, RR_DCKC_CHK) == 0) |
1742 | return; |
1743 | res = rtw89_read_rf(rtwdev, rf_path: path, RR_DCK, RR_DCK_DONE); |
1744 | if (res > 1) { |
1745 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_IDAC, data: res); |
1746 | _rx_dck_toggle(rtwdev, path); |
1747 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_IDAC, data: 0x1); |
1748 | } |
1749 | } |
1750 | |
1751 | static |
1752 | u8 _rx_dck_channel_calc(struct rtw89_dev *rtwdev, const struct rtw89_chan *chan) |
1753 | { |
1754 | u8 target_ch = 0; |
1755 | |
1756 | if (chan->band_type == RTW89_BAND_5G) { |
1757 | if (chan->channel >= 36 && chan->channel <= 64) { |
1758 | target_ch = 100; |
1759 | } else if (chan->channel >= 100 && chan->channel <= 144) { |
1760 | target_ch = chan->channel + 32; |
1761 | if (target_ch > 144) |
1762 | target_ch = chan->channel + 33; |
1763 | } else if (chan->channel >= 149 && chan->channel <= 177) { |
1764 | target_ch = chan->channel - 33; |
1765 | } |
1766 | } else if (chan->band_type == RTW89_BAND_6G) { |
1767 | if (chan->channel >= 1 && chan->channel <= 125) |
1768 | target_ch = chan->channel + 32; |
1769 | else |
1770 | target_ch = chan->channel - 32; |
1771 | } else { |
1772 | target_ch = chan->channel; |
1773 | } |
1774 | |
1775 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1776 | fmt: "[RX_DCK] cur_ch / target_ch = %d / %d\n" , |
1777 | chan->channel, target_ch); |
1778 | |
1779 | return target_ch; |
1780 | } |
1781 | |
1782 | #define RTW8852C_RF_REL_VERSION 34 |
1783 | #define RTW8852C_DPK_VER 0xf |
1784 | #define RTW8852C_DPK_TH_AVG_NUM 4 |
1785 | #define RTW8852C_DPK_RF_PATH 2 |
1786 | #define RTW8852C_DPK_KIP_REG_NUM 7 |
1787 | #define RTW8852C_DPK_RXSRAM_DBG 0 |
1788 | |
1789 | enum rtw8852c_dpk_id { |
1790 | LBK_RXIQK = 0x06, |
1791 | SYNC = 0x10, |
1792 | MDPK_IDL = 0x11, |
1793 | MDPK_MPA = 0x12, |
1794 | GAIN_LOSS = 0x13, |
1795 | GAIN_CAL = 0x14, |
1796 | DPK_RXAGC = 0x15, |
1797 | KIP_PRESET = 0x16, |
1798 | KIP_RESTORE = 0x17, |
1799 | DPK_TXAGC = 0x19, |
1800 | D_KIP_PRESET = 0x28, |
1801 | D_TXAGC = 0x29, |
1802 | D_RXAGC = 0x2a, |
1803 | D_SYNC = 0x2b, |
1804 | D_GAIN_LOSS = 0x2c, |
1805 | D_MDPK_IDL = 0x2d, |
1806 | D_GAIN_NORM = 0x2f, |
1807 | D_KIP_THERMAL = 0x30, |
1808 | D_KIP_RESTORE = 0x31 |
1809 | }; |
1810 | |
1811 | #define DPK_TXAGC_LOWER 0x2e |
1812 | #define DPK_TXAGC_UPPER 0x3f |
1813 | #define DPK_TXAGC_INVAL 0xff |
1814 | |
1815 | enum dpk_agc_step { |
1816 | DPK_AGC_STEP_SYNC_DGAIN, |
1817 | DPK_AGC_STEP_GAIN_LOSS_IDX, |
1818 | DPK_AGC_STEP_GL_GT_CRITERION, |
1819 | DPK_AGC_STEP_GL_LT_CRITERION, |
1820 | DPK_AGC_STEP_SET_TX_GAIN, |
1821 | }; |
1822 | |
1823 | enum dpk_pas_result { |
1824 | DPK_PAS_NOR, |
1825 | DPK_PAS_GT, |
1826 | DPK_PAS_LT, |
1827 | }; |
1828 | |
1829 | static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, |
1830 | enum rtw89_rf_path path, bool is_bybb) |
1831 | { |
1832 | if (is_bybb) |
1833 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x1); |
1834 | else |
1835 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0); |
1836 | } |
1837 | |
1838 | static void _dpk_onoff(struct rtw89_dev *rtwdev, |
1839 | enum rtw89_rf_path path, bool off); |
1840 | |
1841 | static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[], |
1842 | u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) |
1843 | { |
1844 | u8 i; |
1845 | |
1846 | for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { |
1847 | reg_bkup[path][i] = |
1848 | rtw89_phy_read32_mask(rtwdev, addr: reg[i] + (path << 8), MASKDWORD); |
1849 | |
1850 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Backup 0x%x = %x\n" , |
1851 | reg[i] + (path << 8), reg_bkup[path][i]); |
1852 | } |
1853 | } |
1854 | |
1855 | static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[], |
1856 | u32 reg_bkup[][RTW8852C_DPK_KIP_REG_NUM], u8 path) |
1857 | { |
1858 | u8 i; |
1859 | |
1860 | for (i = 0; i < RTW8852C_DPK_KIP_REG_NUM; i++) { |
1861 | rtw89_phy_write32_mask(rtwdev, addr: reg[i] + (path << 8), |
1862 | MASKDWORD, data: reg_bkup[path][i]); |
1863 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Reload 0x%x = %x\n" , |
1864 | reg[i] + (path << 8), reg_bkup[path][i]); |
1865 | } |
1866 | } |
1867 | |
1868 | static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
1869 | enum rtw89_rf_path path, enum rtw8852c_dpk_id id) |
1870 | { |
1871 | u16 dpk_cmd; |
1872 | u32 val; |
1873 | int ret; |
1874 | |
1875 | dpk_cmd = (u16)((id << 8) | (0x19 + path * 0x12)); |
1876 | |
1877 | rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, data: dpk_cmd); |
1878 | |
1879 | ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, |
1880 | 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); |
1881 | udelay(10); |
1882 | rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); |
1883 | |
1884 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1885 | fmt: "[DPK] one-shot for %s = 0x%x (ret=%d)\n" , |
1886 | id == 0x06 ? "LBK_RXIQK" : |
1887 | id == 0x10 ? "SYNC" : |
1888 | id == 0x11 ? "MDPK_IDL" : |
1889 | id == 0x12 ? "MDPK_MPA" : |
1890 | id == 0x13 ? "GAIN_LOSS" : "PWR_CAL" , |
1891 | dpk_cmd, ret); |
1892 | |
1893 | if (ret) { |
1894 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1895 | fmt: "[DPK] one-shot over 20ms!!!!\n" ); |
1896 | return 1; |
1897 | } |
1898 | |
1899 | return 0; |
1900 | } |
1901 | |
1902 | static void _dpk_information(struct rtw89_dev *rtwdev, |
1903 | enum rtw89_phy_idx phy, |
1904 | enum rtw89_rf_path path) |
1905 | { |
1906 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
1907 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
1908 | |
1909 | u8 kidx = dpk->cur_idx[path]; |
1910 | |
1911 | dpk->bp[path][kidx].band = chan->band_type; |
1912 | dpk->bp[path][kidx].ch = chan->channel; |
1913 | dpk->bp[path][kidx].bw = chan->band_width; |
1914 | |
1915 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
1916 | fmt: "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n" , |
1917 | path, dpk->cur_idx[path], phy, |
1918 | rtwdev->is_tssi_mode[path] ? "on" : "off" , |
1919 | rtwdev->dbcc_en ? "on" : "off" , |
1920 | dpk->bp[path][kidx].band == 0 ? "2G" : |
1921 | dpk->bp[path][kidx].band == 1 ? "5G" : "6G" , |
1922 | dpk->bp[path][kidx].ch, |
1923 | dpk->bp[path][kidx].bw == 0 ? "20M" : |
1924 | dpk->bp[path][kidx].bw == 1 ? "40M" : "80M" ); |
1925 | } |
1926 | |
1927 | static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, |
1928 | enum rtw89_phy_idx phy, |
1929 | enum rtw89_rf_path path, u8 kpath) |
1930 | { |
1931 | /*1. Keep ADC_fifo reset*/ |
1932 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, data: 0x1); |
1933 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, data: 0x0); |
1934 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, data: 0x1); |
1935 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, data: 0x0); |
1936 | |
1937 | /*2. BB for IQK DBG mode*/ |
1938 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, data: 0xd801dffd); |
1939 | |
1940 | /*3.Set DAC clk*/ |
1941 | rtw8852c_txck_force(rtwdev, path, force: true, ck: DAC_960M); |
1942 | |
1943 | /*4. Set ADC clk*/ |
1944 | rtw8852c_rxck_force(rtwdev, path, force: true, ck: ADC_1920M); |
1945 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), |
1946 | B_P0_NRBW_DBG, data: 0x1); |
1947 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, data: 0x1f); |
1948 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, MASKBYTE3, data: 0x13); |
1949 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, data: 0x0001); |
1950 | rtw89_phy_write32_mask(rtwdev, R_ANAPAR, MASKHWORD, data: 0x0041); |
1951 | |
1952 | /*5. ADDA fifo rst*/ |
1953 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, data: 0x1); |
1954 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, data: 0x1); |
1955 | |
1956 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d BB/AFE setting\n" , path); |
1957 | } |
1958 | |
1959 | static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, u8 path) |
1960 | { |
1961 | rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), |
1962 | B_P0_NRBW_DBG, data: 0x0); |
1963 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, data: 0x1); |
1964 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A1 << path, data: 0x0); |
1965 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, data: 0x1); |
1966 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A3 << path, data: 0x0); |
1967 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, data: 0x00000000); |
1968 | rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, data: 0x00); |
1969 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A0 << path, data: 0x0); |
1970 | rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_A2 << path, data: 0x0); |
1971 | |
1972 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d BB/AFE restore\n" , path); |
1973 | } |
1974 | |
1975 | static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, |
1976 | enum rtw89_rf_path path, bool is_pause) |
1977 | { |
1978 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), |
1979 | B_P0_TSSI_TRK_EN, data: is_pause); |
1980 | |
1981 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d TSSI %s\n" , path, |
1982 | is_pause ? "pause" : "resume" ); |
1983 | } |
1984 | |
1985 | static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, u8 path, bool ctrl_by_kip) |
1986 | { |
1987 | rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), B_IQK_RFC_ON, data: ctrl_by_kip); |
1988 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] RFC is controlled by %s\n" , |
1989 | ctrl_by_kip ? "KIP" : "BB" ); |
1990 | } |
1991 | |
1992 | static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, u8 path, bool force) |
1993 | { |
1994 | rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, data: force); |
1995 | rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, data: force); |
1996 | |
1997 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d txpwr_bb_force %s\n" , |
1998 | path, force ? "on" : "off" ); |
1999 | } |
2000 | |
2001 | static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2002 | enum rtw89_rf_path path) |
2003 | { |
2004 | _dpk_one_shot(rtwdev, phy, path, id: D_KIP_RESTORE); |
2005 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2006 | _dpk_txpwr_bb_force(rtwdev, path, force: false); |
2007 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d restore KIP\n" , path); |
2008 | } |
2009 | |
2010 | static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, |
2011 | enum rtw89_phy_idx phy, |
2012 | enum rtw89_rf_path path) |
2013 | { |
2014 | #define RX_TONE_IDX 0x00250025 /* Q.2 9.25MHz */ |
2015 | u8 cur_rxbb; |
2016 | u32 rf_11, reg_81cc; |
2017 | |
2018 | rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, data: 0x1); |
2019 | rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, data: 0x1); |
2020 | |
2021 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2022 | |
2023 | cur_rxbb = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXBB); |
2024 | rf_11 = rtw89_read_rf(rtwdev, rf_path: path, RR_TXIG, RFREG_MASK); |
2025 | reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), |
2026 | B_KIP_IQP_SW); |
2027 | |
2028 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR0, data: 0x0); |
2029 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_GR1, data: 0x3); |
2030 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RR_TXIG_TG, data: 0xd); |
2031 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXBB, data: 0x1f); |
2032 | |
2033 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, data: 0x12); |
2034 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, data: 0x3); |
2035 | |
2036 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: true); |
2037 | |
2038 | rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, RX_TONE_IDX); |
2039 | |
2040 | _dpk_one_shot(rtwdev, phy, path, id: LBK_RXIQK); |
2041 | |
2042 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d LBK RXIQC = 0x%x\n" , path, |
2043 | rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); |
2044 | |
2045 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2046 | |
2047 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIG, RFREG_MASK, data: rf_11); |
2048 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXBB, data: cur_rxbb); |
2049 | rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, data: reg_81cc); |
2050 | |
2051 | rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, data: 0x0); |
2052 | rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, data: 0x0); |
2053 | rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, data: 0x1); |
2054 | |
2055 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: true); |
2056 | } |
2057 | |
2058 | static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, |
2059 | enum rtw89_rf_path path, u8 kidx) |
2060 | { |
2061 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2062 | |
2063 | if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { |
2064 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, |
2065 | data: 0x50121 | BIT(rtwdev->dbcc_en)); |
2066 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD_V1, RR_MOD_MASK, data: RF_DPK); |
2067 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_ATTC, data: 0x2); |
2068 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB, RR_RXBB_ATTR, data: 0x4); |
2069 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTDBG, RR_LUTDBG_TIA, data: 0x1); |
2070 | rtw89_write_rf(rtwdev, rf_path: path, RR_TIA, RR_TIA_N6, data: 0x1); |
2071 | |
2072 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2073 | fmt: "[DPK] RF 0x0/0x83/0x9e/0x1a/0xdf/0x1001a = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n" , |
2074 | rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK), |
2075 | rtw89_read_rf(rtwdev, rf_path: path, RR_RXBB, RFREG_MASK), |
2076 | rtw89_read_rf(rtwdev, rf_path: path, RR_TIA, RFREG_MASK), |
2077 | rtw89_read_rf(rtwdev, rf_path: path, RR_BTC, RFREG_MASK), |
2078 | rtw89_read_rf(rtwdev, rf_path: path, RR_LUTDBG, RFREG_MASK), |
2079 | rtw89_read_rf(rtwdev, rf_path: path, addr: 0x1001a, RFREG_MASK)); |
2080 | } else { |
2081 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK, |
2082 | data: 0x50101 | BIT(rtwdev->dbcc_en)); |
2083 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD_V1, RR_MOD_MASK, data: RF_DPK); |
2084 | |
2085 | if (dpk->bp[path][kidx].band == RTW89_BAND_6G && dpk->bp[path][kidx].ch >= 161) |
2086 | rtw89_write_rf(rtwdev, rf_path: path, RR_IQGEN, RR_IQGEN_BIAS, data: 0x8); |
2087 | |
2088 | rtw89_write_rf(rtwdev, rf_path: path, RR_LOGEN, RR_LOGEN_RPT, data: 0xd); |
2089 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXAC, RR_TXAC_IQG, data: 0x8); |
2090 | |
2091 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXA2, RR_RXA2_ATT, data: 0x0); |
2092 | rtw89_write_rf(rtwdev, rf_path: path, RR_TXIQK, RR_TXIQK_ATT2, data: 0x3); |
2093 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTDBG, RR_LUTDBG_TIA, data: 0x1); |
2094 | rtw89_write_rf(rtwdev, rf_path: path, RR_TIA, RR_TIA_N6, data: 0x1); |
2095 | |
2096 | if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) |
2097 | rtw89_write_rf(rtwdev, rf_path: path, RR_RXBB2, RR_RXBB2_EBW, data: 0x0); |
2098 | } |
2099 | } |
2100 | |
2101 | static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) |
2102 | { |
2103 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2104 | |
2105 | if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160) { |
2106 | rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x3); |
2107 | rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, data: 0x0180ff30); |
2108 | } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { |
2109 | rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x0); |
2110 | rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, data: 0xffe0fa00); |
2111 | } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { |
2112 | rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x2); |
2113 | rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, data: 0xff4009e0); |
2114 | } else { |
2115 | rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, data: 0x1); |
2116 | rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, data: 0xf9f007d0); |
2117 | } |
2118 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] TPG_Select for %s\n" , |
2119 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_160 ? "160M" : |
2120 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : |
2121 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M" ); |
2122 | } |
2123 | |
2124 | static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) |
2125 | { |
2126 | #define DPK_SYNC_TH_DC_I 200 |
2127 | #define DPK_SYNC_TH_DC_Q 200 |
2128 | #define DPK_SYNC_TH_CORR 170 |
2129 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2130 | u16 dc_i, dc_q; |
2131 | u8 corr_val, corr_idx, rxbb; |
2132 | u8 rxbb_ov; |
2133 | |
2134 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x0); |
2135 | |
2136 | corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); |
2137 | corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); |
2138 | |
2139 | dpk->corr_idx[path][kidx] = corr_idx; |
2140 | dpk->corr_val[path][kidx] = corr_val; |
2141 | |
2142 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x9); |
2143 | |
2144 | dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); |
2145 | dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); |
2146 | |
2147 | dc_i = abs(sign_extend32(dc_i, 11)); |
2148 | dc_q = abs(sign_extend32(dc_q, 11)); |
2149 | |
2150 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2151 | fmt: "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n" , |
2152 | path, corr_idx, corr_val, dc_i, dc_q); |
2153 | |
2154 | dpk->dc_i[path][kidx] = dc_i; |
2155 | dpk->dc_q[path][kidx] = dc_q; |
2156 | |
2157 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x8); |
2158 | rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); |
2159 | |
2160 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x31); |
2161 | rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); |
2162 | |
2163 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2164 | fmt: "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n" , |
2165 | path, rxbb, |
2166 | rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), |
2167 | rxbb_ov); |
2168 | |
2169 | if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || |
2170 | corr_val < DPK_SYNC_TH_CORR) |
2171 | return true; |
2172 | else |
2173 | return false; |
2174 | } |
2175 | |
2176 | static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) |
2177 | { |
2178 | u16 dgain = 0x0; |
2179 | |
2180 | rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); |
2181 | |
2182 | dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); |
2183 | |
2184 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] DGain = 0x%x (%d)\n" , dgain, dgain); |
2185 | |
2186 | return dgain; |
2187 | } |
2188 | |
2189 | static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) |
2190 | { |
2191 | u8 result; |
2192 | |
2193 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x6); |
2194 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, data: 0x1); |
2195 | |
2196 | result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); |
2197 | |
2198 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] tmp GL = %d\n" , result); |
2199 | |
2200 | return result; |
2201 | } |
2202 | |
2203 | static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) |
2204 | { |
2205 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2206 | |
2207 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, data: 0x10); |
2208 | dpk->cur_k_set = |
2209 | rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), mask: 0xE0000000) - 1; |
2210 | } |
2211 | |
2212 | static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2213 | enum rtw89_rf_path path, u8 dbm, bool set_from_bb) |
2214 | { |
2215 | if (set_from_bb) { |
2216 | dbm = clamp_t(u8, dbm, 7, 24); |
2217 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] set S%d txagc to %ddBm\n" , path, dbm); |
2218 | rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_VAL, data: dbm << 2); |
2219 | } |
2220 | _dpk_one_shot(rtwdev, phy, path, id: D_TXAGC); |
2221 | _dpk_kset_query(rtwdev, path); |
2222 | } |
2223 | |
2224 | static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2225 | enum rtw89_rf_path path, u8 kidx) |
2226 | { |
2227 | _dpk_one_shot(rtwdev, phy, path, id: D_GAIN_LOSS); |
2228 | _dpk_kip_set_txagc(rtwdev, phy, path, dbm: 0xff, set_from_bb: false); |
2229 | |
2230 | rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, data: 0x0); |
2231 | rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, data: 0x0); |
2232 | |
2233 | return _dpk_gainloss_read(rtwdev); |
2234 | } |
2235 | |
2236 | static enum dpk_pas_result _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) |
2237 | { |
2238 | u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; |
2239 | u32 val1_sqrt_sum, val2_sqrt_sum; |
2240 | u8 i; |
2241 | |
2242 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, data: 0x06); |
2243 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, data: 0x0); |
2244 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, data: 0x08); |
2245 | |
2246 | if (is_check) { |
2247 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: 0x00); |
2248 | val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); |
2249 | val1_i = abs(sign_extend32(val1_i, 11)); |
2250 | val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); |
2251 | val1_q = abs(sign_extend32(val1_q, 11)); |
2252 | |
2253 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: 0x1f); |
2254 | val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); |
2255 | val2_i = abs(sign_extend32(val2_i, 11)); |
2256 | val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); |
2257 | val2_q = abs(sign_extend32(val2_q, 11)); |
2258 | |
2259 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] PAS_delta = 0x%x\n" , |
2260 | phy_div(val1_i * val1_i + val1_q * val1_q, |
2261 | val2_i * val2_i + val2_q * val2_q)); |
2262 | } else { |
2263 | for (i = 0; i < 32; i++) { |
2264 | rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, data: i); |
2265 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] PAS_Read[%02d]= 0x%08x\n" , i, |
2266 | rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); |
2267 | } |
2268 | } |
2269 | |
2270 | val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; |
2271 | val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; |
2272 | |
2273 | if (val1_sqrt_sum < val2_sqrt_sum) |
2274 | return DPK_PAS_LT; |
2275 | else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) |
2276 | return DPK_PAS_GT; |
2277 | else |
2278 | return DPK_PAS_NOR; |
2279 | } |
2280 | |
2281 | static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2282 | enum rtw89_rf_path path, u8 kidx) |
2283 | { |
2284 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2285 | rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, |
2286 | data: rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK)); |
2287 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: true); |
2288 | |
2289 | _dpk_one_shot(rtwdev, phy, path, id: D_RXAGC); |
2290 | |
2291 | return _dpk_sync_check(rtwdev, path, kidx); |
2292 | } |
2293 | |
2294 | static void _dpk_read_rxsram(struct rtw89_dev *rtwdev) |
2295 | { |
2296 | u32 addr; |
2297 | |
2298 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_read_rxsram_pre_defs_tbl); |
2299 | |
2300 | for (addr = 0; addr < 0x200; addr++) { |
2301 | rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, data: 0x00010000 | addr); |
2302 | |
2303 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] RXSRAM[%03d] = 0x%07x\n" , addr, |
2304 | rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); |
2305 | } |
2306 | |
2307 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_read_rxsram_post_defs_tbl); |
2308 | } |
2309 | |
2310 | static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) |
2311 | { |
2312 | rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, data: 0x1); |
2313 | rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, data: 0x40000002); |
2314 | |
2315 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Bypass RXIQC\n" ); |
2316 | } |
2317 | |
2318 | static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2319 | enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) |
2320 | { |
2321 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2322 | u8 step = DPK_AGC_STEP_SYNC_DGAIN; |
2323 | u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; |
2324 | u8 tmp_rxbb; |
2325 | u8 goout = 0, agc_cnt = 0; |
2326 | enum dpk_pas_result pas; |
2327 | u16 dgain = 0; |
2328 | bool is_fail = false; |
2329 | int limit = 200; |
2330 | |
2331 | do { |
2332 | switch (step) { |
2333 | case DPK_AGC_STEP_SYNC_DGAIN: |
2334 | is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); |
2335 | |
2336 | if (RTW8852C_DPK_RXSRAM_DBG) |
2337 | _dpk_read_rxsram(rtwdev); |
2338 | |
2339 | if (is_fail) { |
2340 | goout = 1; |
2341 | break; |
2342 | } |
2343 | |
2344 | dgain = _dpk_dgain_read(rtwdev); |
2345 | |
2346 | if (dgain > 0x5fc || dgain < 0x556) { |
2347 | _dpk_one_shot(rtwdev, phy, path, id: D_SYNC); |
2348 | dgain = _dpk_dgain_read(rtwdev); |
2349 | } |
2350 | |
2351 | if (agc_cnt == 0) { |
2352 | if (dpk->bp[path][kidx].band == RTW89_BAND_2G) |
2353 | _dpk_bypass_rxiqc(rtwdev, path); |
2354 | else |
2355 | _dpk_lbk_rxiqk(rtwdev, phy, path); |
2356 | } |
2357 | step = DPK_AGC_STEP_GAIN_LOSS_IDX; |
2358 | break; |
2359 | |
2360 | case DPK_AGC_STEP_GAIN_LOSS_IDX: |
2361 | tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); |
2362 | pas = _dpk_pas_read(rtwdev, is_check: true); |
2363 | |
2364 | if (pas == DPK_PAS_LT && tmp_gl_idx > 0) |
2365 | step = DPK_AGC_STEP_GL_LT_CRITERION; |
2366 | else if (pas == DPK_PAS_GT && tmp_gl_idx == 0) |
2367 | step = DPK_AGC_STEP_GL_GT_CRITERION; |
2368 | else if (tmp_gl_idx >= 7) |
2369 | step = DPK_AGC_STEP_GL_GT_CRITERION; |
2370 | else if (tmp_gl_idx == 0) |
2371 | step = DPK_AGC_STEP_GL_LT_CRITERION; |
2372 | else |
2373 | step = DPK_AGC_STEP_SET_TX_GAIN; |
2374 | break; |
2375 | |
2376 | case DPK_AGC_STEP_GL_GT_CRITERION: |
2377 | if (tmp_dbm <= 7) { |
2378 | goout = 1; |
2379 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Txagc@lower bound!!\n" ); |
2380 | } else { |
2381 | tmp_dbm = max_t(u8, tmp_dbm - 3, 7); |
2382 | _dpk_kip_set_txagc(rtwdev, phy, path, dbm: tmp_dbm, set_from_bb: true); |
2383 | } |
2384 | step = DPK_AGC_STEP_SYNC_DGAIN; |
2385 | agc_cnt++; |
2386 | break; |
2387 | |
2388 | case DPK_AGC_STEP_GL_LT_CRITERION: |
2389 | if (tmp_dbm >= 24) { |
2390 | goout = 1; |
2391 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Txagc@upper bound!!\n" ); |
2392 | } else { |
2393 | tmp_dbm = min_t(u8, tmp_dbm + 2, 24); |
2394 | _dpk_kip_set_txagc(rtwdev, phy, path, dbm: tmp_dbm, set_from_bb: true); |
2395 | } |
2396 | step = DPK_AGC_STEP_SYNC_DGAIN; |
2397 | agc_cnt++; |
2398 | break; |
2399 | |
2400 | case DPK_AGC_STEP_SET_TX_GAIN: |
2401 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2402 | tmp_rxbb = rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXBB); |
2403 | if (tmp_rxbb + tmp_gl_idx > 0x1f) |
2404 | tmp_rxbb = 0x1f; |
2405 | else |
2406 | tmp_rxbb = tmp_rxbb + tmp_gl_idx; |
2407 | |
2408 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_M_RXBB, data: tmp_rxbb); |
2409 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Adjust RXBB (%+d) = 0x%x\n" , |
2410 | tmp_gl_idx, tmp_rxbb); |
2411 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: true); |
2412 | goout = 1; |
2413 | break; |
2414 | default: |
2415 | goout = 1; |
2416 | break; |
2417 | } |
2418 | } while (!goout && agc_cnt < 6 && --limit > 0); |
2419 | |
2420 | if (limit <= 0) |
2421 | rtw89_warn(rtwdev, "[DPK] exceed loop limit\n" ); |
2422 | |
2423 | return is_fail; |
2424 | } |
2425 | |
2426 | static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) |
2427 | { |
2428 | static const struct rtw89_rfk_tbl *order_tbls[] = { |
2429 | &rtw8852c_dpk_mdpd_order0_defs_tbl, |
2430 | &rtw8852c_dpk_mdpd_order1_defs_tbl, |
2431 | &rtw8852c_dpk_mdpd_order2_defs_tbl, |
2432 | &rtw8852c_dpk_mdpd_order3_defs_tbl, |
2433 | }; |
2434 | |
2435 | if (order >= ARRAY_SIZE(order_tbls)) { |
2436 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Wrong MDPD order!!(0x%x)\n" , order); |
2437 | return; |
2438 | } |
2439 | |
2440 | rtw89_rfk_parser(rtwdev, tbl: order_tbls[order]); |
2441 | |
2442 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Set %s for IDL\n" , |
2443 | order == 0x0 ? "(5,3,1)" : |
2444 | order == 0x1 ? "(5,3,0)" : |
2445 | order == 0x2 ? "(5,0,0)" : "(7,3,1)" ); |
2446 | } |
2447 | |
2448 | static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2449 | enum rtw89_rf_path path, u8 kidx) |
2450 | { |
2451 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2452 | u8 cnt; |
2453 | u8 ov_flag; |
2454 | u32 dpk_sync; |
2455 | |
2456 | rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, data: 0x1); |
2457 | |
2458 | if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T2) == 0x1) |
2459 | _dpk_set_mdpd_para(rtwdev, order: 0x2); |
2460 | else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T1) == 0x1) |
2461 | _dpk_set_mdpd_para(rtwdev, order: 0x1); |
2462 | else if (rtw89_phy_read32_mask(rtwdev, R_DPK_MPA, B_DPK_MPA_T0) == 0x1) |
2463 | _dpk_set_mdpd_para(rtwdev, order: 0x0); |
2464 | else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_5 || |
2465 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_10 || |
2466 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_20) |
2467 | _dpk_set_mdpd_para(rtwdev, order: 0x2); |
2468 | else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 || |
2469 | dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) |
2470 | _dpk_set_mdpd_para(rtwdev, order: 0x1); |
2471 | else |
2472 | _dpk_set_mdpd_para(rtwdev, order: 0x0); |
2473 | |
2474 | rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, data: 0x0); |
2475 | fsleep(usecs: 1000); |
2476 | |
2477 | _dpk_one_shot(rtwdev, phy, path, id: D_MDPK_IDL); |
2478 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0x0); |
2479 | dpk_sync = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); |
2480 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] dpk_sync = 0x%x\n" , dpk_sync); |
2481 | |
2482 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0xf); |
2483 | ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); |
2484 | for (cnt = 0; cnt < 5 && ov_flag == 0x1; cnt++) { |
2485 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] ReK due to MDPK ov!!!\n" ); |
2486 | _dpk_one_shot(rtwdev, phy, path, id: D_MDPK_IDL); |
2487 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, data: 0xf); |
2488 | ov_flag = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); |
2489 | } |
2490 | |
2491 | if (ov_flag) { |
2492 | _dpk_set_mdpd_para(rtwdev, order: 0x2); |
2493 | _dpk_one_shot(rtwdev, phy, path, id: D_MDPK_IDL); |
2494 | } |
2495 | } |
2496 | |
2497 | static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2498 | enum rtw89_rf_path path) |
2499 | { |
2500 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2501 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2502 | bool is_reload = false; |
2503 | u8 idx, cur_band, cur_ch; |
2504 | |
2505 | cur_band = chan->band_type; |
2506 | cur_ch = chan->channel; |
2507 | |
2508 | for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { |
2509 | if (cur_band != dpk->bp[path][idx].band || |
2510 | cur_ch != dpk->bp[path][idx].ch) |
2511 | continue; |
2512 | |
2513 | rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), |
2514 | B_COEF_SEL_MDPD, data: idx); |
2515 | dpk->cur_idx[path] = idx; |
2516 | is_reload = true; |
2517 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2518 | fmt: "[DPK] reload S%d[%d] success\n" , path, idx); |
2519 | } |
2520 | |
2521 | return is_reload; |
2522 | } |
2523 | |
2524 | static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) |
2525 | { |
2526 | rtw89_rfk_parser(rtwdev, tbl: turn_on ? &rtw8852c_dpk_kip_pwr_clk_on_defs_tbl : |
2527 | &rtw8852c_dpk_kip_pwr_clk_off_defs_tbl); |
2528 | } |
2529 | |
2530 | static void _dpk_kip_preset_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2531 | enum rtw89_rf_path path, u8 kidx) |
2532 | { |
2533 | rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, |
2534 | data: rtw89_read_rf(rtwdev, rf_path: path, RR_MOD, RFREG_MASK)); |
2535 | |
2536 | if (rtwdev->hal.cv == CHIP_CAV) |
2537 | rtw89_phy_write32_mask(rtwdev, |
2538 | R_DPD_CH0A + (path << 8) + (kidx << 2), |
2539 | B_DPD_SEL, data: 0x01); |
2540 | else |
2541 | rtw89_phy_write32_mask(rtwdev, |
2542 | R_DPD_CH0A + (path << 8) + (kidx << 2), |
2543 | B_DPD_SEL, data: 0x0c); |
2544 | |
2545 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: true); |
2546 | rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, data: kidx); |
2547 | |
2548 | _dpk_one_shot(rtwdev, phy, path, id: D_KIP_PRESET); |
2549 | } |
2550 | |
2551 | static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) |
2552 | { |
2553 | #define _DPK_PARA_TXAGC GENMASK(15, 10) |
2554 | #define _DPK_PARA_THER GENMASK(31, 26) |
2555 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2556 | u32 para; |
2557 | |
2558 | para = rtw89_phy_read32_mask(rtwdev, addr: dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), |
2559 | MASKDWORD); |
2560 | |
2561 | dpk->bp[path][kidx].txagc_dpk = FIELD_GET(_DPK_PARA_TXAGC, para); |
2562 | dpk->bp[path][kidx].ther_dpk = FIELD_GET(_DPK_PARA_THER, para); |
2563 | |
2564 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n" , |
2565 | dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, dpk->bp[path][kidx].txagc_dpk); |
2566 | } |
2567 | |
2568 | static void _dpk_gain_normalize_8852c(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2569 | enum rtw89_rf_path path, u8 kidx, bool is_execute) |
2570 | { |
2571 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2572 | |
2573 | if (is_execute) { |
2574 | rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_AG, data: 0x200); |
2575 | rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), B_DPK_GN_EN, data: 0x3); |
2576 | |
2577 | _dpk_one_shot(rtwdev, phy, path, id: D_GAIN_NORM); |
2578 | } else { |
2579 | rtw89_phy_write32_mask(rtwdev, addr: dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), |
2580 | mask: 0x0000007F, data: 0x5b); |
2581 | } |
2582 | dpk->bp[path][kidx].gs = |
2583 | rtw89_phy_read32_mask(rtwdev, addr: dpk_par_regs[kidx][dpk->cur_k_set] + (path << 8), |
2584 | mask: 0x0000007F); |
2585 | } |
2586 | |
2587 | static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) |
2588 | { |
2589 | u32 val32 = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); |
2590 | u8 val; |
2591 | |
2592 | switch (val32) { |
2593 | case 0: |
2594 | val = 0x6; |
2595 | break; |
2596 | case 1: |
2597 | val = 0x2; |
2598 | break; |
2599 | case 2: |
2600 | val = 0x0; |
2601 | break; |
2602 | case 3: |
2603 | val = 0x7; |
2604 | break; |
2605 | default: |
2606 | val = 0xff; |
2607 | break; |
2608 | } |
2609 | |
2610 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] convert MDPD order to 0x%x\n" , val); |
2611 | |
2612 | return val; |
2613 | } |
2614 | |
2615 | static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2616 | enum rtw89_rf_path path, u8 kidx) |
2617 | { |
2618 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2619 | |
2620 | rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, data: 0x1); |
2621 | rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, data: 0x0); |
2622 | rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), |
2623 | B_DPD_ORDER, data: _dpk_order_convert(rtwdev)); |
2624 | |
2625 | dpk->bp[path][kidx].mdpd_en = BIT(dpk->cur_k_set); |
2626 | dpk->bp[path][kidx].path_ok = true; |
2627 | |
2628 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d[%d] path_ok = 0x%x\n" , |
2629 | path, kidx, dpk->bp[path][kidx].mdpd_en); |
2630 | |
2631 | rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), |
2632 | B_DPD_MEN, data: dpk->bp[path][kidx].mdpd_en); |
2633 | |
2634 | _dpk_gain_normalize_8852c(rtwdev, phy, path, kidx, is_execute: false); |
2635 | } |
2636 | |
2637 | static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2638 | enum rtw89_rf_path path, u8 gain) |
2639 | { |
2640 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2641 | u8 kidx = dpk->cur_idx[path]; |
2642 | u8 init_xdbm = 15; |
2643 | bool is_fail; |
2644 | |
2645 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2646 | fmt: "[DPK] ========= S%d[%d] DPK Start =========\n" , path, kidx); |
2647 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2648 | _rf_direct_cntrl(rtwdev, path, is_bybb: false); |
2649 | rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RFREG_MASK, data: 0x03ffd); |
2650 | _dpk_rf_setting(rtwdev, gain, path, kidx); |
2651 | _set_rx_dck(rtwdev, phy, path, is_afe: false); |
2652 | _dpk_kip_pwr_clk_onoff(rtwdev, turn_on: true); |
2653 | _dpk_kip_preset_8852c(rtwdev, phy, path, kidx); |
2654 | _dpk_txpwr_bb_force(rtwdev, path, force: true); |
2655 | _dpk_kip_set_txagc(rtwdev, phy, path, dbm: init_xdbm, set_from_bb: true); |
2656 | _dpk_tpg_sel(rtwdev, path, kidx); |
2657 | |
2658 | is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, loss_only: false); |
2659 | if (is_fail) |
2660 | goto _error; |
2661 | |
2662 | _dpk_idl_mpa(rtwdev, phy, path, kidx); |
2663 | _dpk_para_query(rtwdev, path, kidx); |
2664 | _dpk_on(rtwdev, phy, path, kidx); |
2665 | |
2666 | _error: |
2667 | _dpk_kip_control_rfc(rtwdev, path, ctrl_by_kip: false); |
2668 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, data: RF_RX); |
2669 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d[%d]_K%d %s\n" , path, kidx, |
2670 | dpk->cur_k_set, is_fail ? "need Check" : "is Success" ); |
2671 | |
2672 | return is_fail; |
2673 | } |
2674 | |
2675 | static void _dpk_init(struct rtw89_dev *rtwdev, u8 path) |
2676 | { |
2677 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2678 | u8 kidx = dpk->cur_idx[path]; |
2679 | |
2680 | dpk->bp[path][kidx].path_ok = false; |
2681 | } |
2682 | |
2683 | static void _dpk_drf_direct_cntrl(struct rtw89_dev *rtwdev, u8 path, bool is_bybb) |
2684 | { |
2685 | if (is_bybb) |
2686 | rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x1); |
2687 | else |
2688 | rtw89_write_rf(rtwdev, rf_path: path, RR_BBDC, RR_BBDC_SEL, data: 0x0); |
2689 | } |
2690 | |
2691 | static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, |
2692 | enum rtw89_phy_idx phy, u8 kpath) |
2693 | { |
2694 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2695 | static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120, 0xc0c4, 0xc0e8, 0xc0d4, 0xc0d8}; |
2696 | u32 backup_rf_val[RTW8852C_DPK_RF_PATH][BACKUP_RF_REGS_NR]; |
2697 | u32 kip_bkup[RTW8852C_DPK_RF_PATH][RTW8852C_DPK_KIP_REG_NUM] = {}; |
2698 | u8 path; |
2699 | bool is_fail = true, reloaded[RTW8852C_DPK_RF_PATH] = {false}; |
2700 | |
2701 | static_assert(ARRAY_SIZE(kip_reg) == RTW8852C_DPK_KIP_REG_NUM); |
2702 | |
2703 | if (dpk->is_dpk_reload_en) { |
2704 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2705 | if (!(kpath & BIT(path))) |
2706 | continue; |
2707 | |
2708 | reloaded[path] = _dpk_reload_check(rtwdev, phy, path); |
2709 | if (!reloaded[path] && dpk->bp[path][0].ch != 0) |
2710 | dpk->cur_idx[path] = !dpk->cur_idx[path]; |
2711 | else |
2712 | _dpk_onoff(rtwdev, path, off: false); |
2713 | } |
2714 | } else { |
2715 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) |
2716 | dpk->cur_idx[path] = 0; |
2717 | } |
2718 | |
2719 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2720 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2721 | fmt: "[DPK] ========= S%d[%d] DPK Init =========\n" , |
2722 | path, dpk->cur_idx[path]); |
2723 | _dpk_bkup_kip(rtwdev, reg: kip_reg, reg_bkup: kip_bkup, path); |
2724 | _rfk_backup_rf_reg(rtwdev, backup_rf_reg_val: backup_rf_val[path], rf_path: path); |
2725 | _dpk_information(rtwdev, phy, path); |
2726 | _dpk_init(rtwdev, path); |
2727 | if (rtwdev->is_tssi_mode[path]) |
2728 | _dpk_tssi_pause(rtwdev, path, is_pause: true); |
2729 | } |
2730 | |
2731 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2732 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2733 | fmt: "[DPK] ========= S%d[%d] DPK Start =========\n" , |
2734 | path, dpk->cur_idx[path]); |
2735 | rtw8852c_disable_rxagc(rtwdev, path, en_rxgac: 0x0); |
2736 | _dpk_drf_direct_cntrl(rtwdev, path, is_bybb: false); |
2737 | _dpk_bb_afe_setting(rtwdev, phy, path, kpath); |
2738 | is_fail = _dpk_main(rtwdev, phy, path, gain: 1); |
2739 | _dpk_onoff(rtwdev, path, off: is_fail); |
2740 | } |
2741 | |
2742 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2743 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2744 | fmt: "[DPK] ========= S%d[%d] DPK Restore =========\n" , |
2745 | path, dpk->cur_idx[path]); |
2746 | _dpk_kip_restore(rtwdev, phy, path); |
2747 | _dpk_reload_kip(rtwdev, reg: kip_reg, reg_bkup: kip_bkup, path); |
2748 | _rfk_restore_rf_reg(rtwdev, backup_rf_reg_val: backup_rf_val[path], rf_path: path); |
2749 | _dpk_bb_afe_restore(rtwdev, path); |
2750 | rtw8852c_disable_rxagc(rtwdev, path, en_rxgac: 0x1); |
2751 | if (rtwdev->is_tssi_mode[path]) |
2752 | _dpk_tssi_pause(rtwdev, path, is_pause: false); |
2753 | } |
2754 | |
2755 | _dpk_kip_pwr_clk_onoff(rtwdev, turn_on: false); |
2756 | } |
2757 | |
2758 | static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
2759 | { |
2760 | struct rtw89_fem_info *fem = &rtwdev->fem; |
2761 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2762 | u8 band = chan->band_type; |
2763 | |
2764 | if (rtwdev->hal.cv == CHIP_CAV && band != RTW89_BAND_2G) { |
2765 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Skip DPK due to CAV & not 2G!!\n" ); |
2766 | return true; |
2767 | } else if (fem->epa_2g && band == RTW89_BAND_2G) { |
2768 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Skip DPK due to 2G_ext_PA exist!!\n" ); |
2769 | return true; |
2770 | } else if (fem->epa_5g && band == RTW89_BAND_5G) { |
2771 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Skip DPK due to 5G_ext_PA exist!!\n" ); |
2772 | return true; |
2773 | } else if (fem->epa_6g && band == RTW89_BAND_6G) { |
2774 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] Skip DPK due to 6G_ext_PA exist!!\n" ); |
2775 | return true; |
2776 | } |
2777 | |
2778 | return false; |
2779 | } |
2780 | |
2781 | static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
2782 | { |
2783 | u8 path, kpath; |
2784 | |
2785 | kpath = _kpath(rtwdev, phy_idx: phy); |
2786 | |
2787 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2788 | if (kpath & BIT(path)) |
2789 | _dpk_onoff(rtwdev, path, off: true); |
2790 | } |
2791 | } |
2792 | |
2793 | static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force) |
2794 | { |
2795 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
2796 | fmt: "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n" , |
2797 | RTW8852C_DPK_VER, rtwdev->hal.cv, |
2798 | RTW8852C_RF_REL_VERSION); |
2799 | |
2800 | if (_dpk_bypass_check(rtwdev, phy)) |
2801 | _dpk_force_bypass(rtwdev, phy); |
2802 | else |
2803 | _dpk_cal_select(rtwdev, force, phy, kpath: _kpath(rtwdev, phy_idx: phy)); |
2804 | |
2805 | if (rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_DCKC, RR_DCKC_CHK) == 0x1) |
2806 | rtw8852c_rx_dck(rtwdev, phy_idx: phy, is_afe: false); |
2807 | } |
2808 | |
2809 | static void _dpk_onoff(struct rtw89_dev *rtwdev, |
2810 | enum rtw89_rf_path path, bool off) |
2811 | { |
2812 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2813 | u8 val, kidx = dpk->cur_idx[path]; |
2814 | |
2815 | val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok ? |
2816 | dpk->bp[path][kidx].mdpd_en : 0; |
2817 | |
2818 | rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), |
2819 | B_DPD_MEN, data: val); |
2820 | |
2821 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[DPK] S%d[%d] DPK %s !!!\n" , path, |
2822 | kidx, dpk->is_dpk_enable && !off ? "enable" : "disable" ); |
2823 | } |
2824 | |
2825 | static void _dpk_track(struct rtw89_dev *rtwdev) |
2826 | { |
2827 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
2828 | u8 path, kidx; |
2829 | u8 txagc_rf = 0; |
2830 | s8 txagc_bb = 0, txagc_bb_tp = 0, txagc_ofst = 0; |
2831 | u8 cur_ther; |
2832 | s8 delta_ther = 0; |
2833 | s16 pwsf_tssi_ofst; |
2834 | |
2835 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) { |
2836 | kidx = dpk->cur_idx[path]; |
2837 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2838 | fmt: "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n" , |
2839 | path, kidx, dpk->bp[path][kidx].ch); |
2840 | |
2841 | txagc_rf = |
2842 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), mask: 0x0000003f); |
2843 | txagc_bb = |
2844 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), MASKBYTE2); |
2845 | txagc_bb_tp = |
2846 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), B_TXAGC_BTP); |
2847 | |
2848 | /* report from KIP */ |
2849 | rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, data: 0xf); |
2850 | cur_ther = |
2851 | rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TH); |
2852 | txagc_ofst = |
2853 | rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_OF); |
2854 | pwsf_tssi_ofst = |
2855 | rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_TSSI); |
2856 | pwsf_tssi_ofst = sign_extend32(value: pwsf_tssi_ofst, index: 12); |
2857 | |
2858 | cur_ther = ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]); |
2859 | |
2860 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2861 | fmt: "[DPK_TRK] thermal now = %d\n" , cur_ther); |
2862 | |
2863 | if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) |
2864 | delta_ther = dpk->bp[path][kidx].ther_dpk - cur_ther; |
2865 | |
2866 | delta_ther = delta_ther * 1 / 2; |
2867 | |
2868 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2869 | fmt: "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n" , |
2870 | delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); |
2871 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2872 | fmt: "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n" , |
2873 | txagc_rf - dpk->bp[path][kidx].txagc_dpk, txagc_rf, |
2874 | dpk->bp[path][kidx].txagc_dpk); |
2875 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2876 | fmt: "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n" , |
2877 | txagc_ofst, pwsf_tssi_ofst); |
2878 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2879 | fmt: "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n" , |
2880 | txagc_bb_tp, txagc_bb); |
2881 | |
2882 | if (rtw89_phy_read32_mask(rtwdev, R_DPK_WR, B_DPK_WR_ST) == 0x0 && |
2883 | txagc_rf != 0 && rtwdev->hal.cv == CHIP_CAV) { |
2884 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
2885 | fmt: "[DPK_TRK] New pwsf = 0x%x\n" , 0x78 - delta_ther); |
2886 | |
2887 | rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), |
2888 | mask: 0x07FC0000, data: 0x78 - delta_ther); |
2889 | } |
2890 | } |
2891 | } |
2892 | |
2893 | static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2894 | enum rtw89_rf_path path) |
2895 | { |
2896 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2897 | enum rtw89_bandwidth bw = chan->band_width; |
2898 | enum rtw89_band band = chan->band_type; |
2899 | u32 clk = 0x0; |
2900 | |
2901 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_tssi_sys_defs_tbl); |
2902 | |
2903 | switch (bw) { |
2904 | case RTW89_CHANNEL_WIDTH_80: |
2905 | clk = 0x1; |
2906 | break; |
2907 | case RTW89_CHANNEL_WIDTH_80_80: |
2908 | case RTW89_CHANNEL_WIDTH_160: |
2909 | clk = 0x2; |
2910 | break; |
2911 | default: |
2912 | break; |
2913 | } |
2914 | |
2915 | if (path == RF_PATH_A) { |
2916 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ADC_CLK, |
2917 | B_P0_TSSI_ADC_CLK, data: clk); |
2918 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
2919 | &rtw8852c_tssi_sys_defs_2g_a_tbl, |
2920 | &rtw8852c_tssi_sys_defs_5g_a_tbl); |
2921 | } else { |
2922 | rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ADC_CLK, |
2923 | B_P1_TSSI_ADC_CLK, data: clk); |
2924 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
2925 | &rtw8852c_tssi_sys_defs_2g_b_tbl, |
2926 | &rtw8852c_tssi_sys_defs_5g_b_tbl); |
2927 | } |
2928 | } |
2929 | |
2930 | static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2931 | enum rtw89_rf_path path) |
2932 | { |
2933 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
2934 | &rtw8852c_tssi_txpwr_ctrl_bb_defs_a_tbl, |
2935 | &rtw8852c_tssi_txpwr_ctrl_bb_defs_b_tbl); |
2936 | } |
2937 | |
2938 | static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, |
2939 | enum rtw89_phy_idx phy, |
2940 | enum rtw89_rf_path path) |
2941 | { |
2942 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
2943 | &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, |
2944 | &rtw8852c_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); |
2945 | } |
2946 | |
2947 | static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2948 | enum rtw89_rf_path path) |
2949 | { |
2950 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2951 | enum rtw89_band band = chan->band_type; |
2952 | |
2953 | if (path == RF_PATH_A) { |
2954 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_tssi_dck_defs_a_tbl); |
2955 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
2956 | &rtw8852c_tssi_dck_defs_2g_a_tbl, |
2957 | &rtw8852c_tssi_dck_defs_5g_a_tbl); |
2958 | } else { |
2959 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_tssi_dck_defs_b_tbl); |
2960 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
2961 | &rtw8852c_tssi_dck_defs_2g_b_tbl, |
2962 | &rtw8852c_tssi_dck_defs_5g_b_tbl); |
2963 | } |
2964 | } |
2965 | |
2966 | static void _tssi_set_bbgain_split(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2967 | enum rtw89_rf_path path) |
2968 | { |
2969 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
2970 | &rtw8852c_tssi_set_bbgain_split_a_tbl, |
2971 | &rtw8852c_tssi_set_bbgain_split_b_tbl); |
2972 | } |
2973 | |
2974 | static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
2975 | enum rtw89_rf_path path) |
2976 | { |
2977 | #define RTW8852C_TSSI_GET_VAL(ptr, idx) \ |
2978 | ({ \ |
2979 | s8 *__ptr = (ptr); \ |
2980 | u8 __idx = (idx), __i, __v; \ |
2981 | u32 __val = 0; \ |
2982 | for (__i = 0; __i < 4; __i++) { \ |
2983 | __v = (__ptr[__idx + __i]); \ |
2984 | __val |= (__v << (8 * __i)); \ |
2985 | } \ |
2986 | __val; \ |
2987 | }) |
2988 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
2989 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
2990 | u8 ch = chan->channel; |
2991 | u8 subband = chan->subband_type; |
2992 | const s8 *thm_up_a = NULL; |
2993 | const s8 *thm_down_a = NULL; |
2994 | const s8 *thm_up_b = NULL; |
2995 | const s8 *thm_down_b = NULL; |
2996 | u8 thermal = 0xff; |
2997 | s8 thm_ofst[64] = {0}; |
2998 | u32 tmp = 0; |
2999 | u8 i, j; |
3000 | |
3001 | switch (subband) { |
3002 | default: |
3003 | case RTW89_CH_2G: |
3004 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_p; |
3005 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_2ga_n; |
3006 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_p; |
3007 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_2gb_n; |
3008 | break; |
3009 | case RTW89_CH_5G_BAND_1: |
3010 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[0]; |
3011 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[0]; |
3012 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[0]; |
3013 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[0]; |
3014 | break; |
3015 | case RTW89_CH_5G_BAND_3: |
3016 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[1]; |
3017 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[1]; |
3018 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[1]; |
3019 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[1]; |
3020 | break; |
3021 | case RTW89_CH_5G_BAND_4: |
3022 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_p[2]; |
3023 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_5ga_n[2]; |
3024 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_p[2]; |
3025 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_5gb_n[2]; |
3026 | break; |
3027 | case RTW89_CH_6G_BAND_IDX0: |
3028 | case RTW89_CH_6G_BAND_IDX1: |
3029 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[0]; |
3030 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[0]; |
3031 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[0]; |
3032 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[0]; |
3033 | break; |
3034 | case RTW89_CH_6G_BAND_IDX2: |
3035 | case RTW89_CH_6G_BAND_IDX3: |
3036 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[1]; |
3037 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[1]; |
3038 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[1]; |
3039 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[1]; |
3040 | break; |
3041 | case RTW89_CH_6G_BAND_IDX4: |
3042 | case RTW89_CH_6G_BAND_IDX5: |
3043 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[2]; |
3044 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[2]; |
3045 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[2]; |
3046 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[2]; |
3047 | break; |
3048 | case RTW89_CH_6G_BAND_IDX6: |
3049 | case RTW89_CH_6G_BAND_IDX7: |
3050 | thm_up_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_p[3]; |
3051 | thm_down_a = rtw89_8852c_trk_cfg.delta_swingidx_6ga_n[3]; |
3052 | thm_up_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_p[3]; |
3053 | thm_down_b = rtw89_8852c_trk_cfg.delta_swingidx_6gb_n[3]; |
3054 | break; |
3055 | } |
3056 | |
3057 | if (path == RF_PATH_A) { |
3058 | thermal = tssi_info->thermal[RF_PATH_A]; |
3059 | |
3060 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3061 | fmt: "[TSSI] ch=%d thermal_pathA=0x%x\n" , ch, thermal); |
3062 | |
3063 | rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, data: 0x0); |
3064 | rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, data: 0x1); |
3065 | |
3066 | if (thermal == 0xff) { |
3067 | rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, data: 32); |
3068 | rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, data: 32); |
3069 | |
3070 | for (i = 0; i < 64; i += 4) { |
3071 | rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, data: 0x0); |
3072 | |
3073 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3074 | fmt: "[TSSI] write 0x%x val=0x%08x\n" , |
3075 | 0x5c00 + i, 0x0); |
3076 | } |
3077 | |
3078 | } else { |
3079 | rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, data: thermal); |
3080 | rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, |
3081 | data: thermal); |
3082 | |
3083 | i = 0; |
3084 | for (j = 0; j < 32; j++) |
3085 | thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? |
3086 | -thm_down_a[i++] : |
3087 | -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; |
3088 | |
3089 | i = 1; |
3090 | for (j = 63; j >= 32; j--) |
3091 | thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? |
3092 | thm_up_a[i++] : |
3093 | thm_up_a[DELTA_SWINGIDX_SIZE - 1]; |
3094 | |
3095 | for (i = 0; i < 64; i += 4) { |
3096 | tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); |
3097 | rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, data: tmp); |
3098 | |
3099 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3100 | fmt: "[TSSI] write 0x%x val=0x%08x\n" , |
3101 | 0x5c00 + i, tmp); |
3102 | } |
3103 | } |
3104 | rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, data: 0x1); |
3105 | rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, data: 0x0); |
3106 | |
3107 | } else { |
3108 | thermal = tssi_info->thermal[RF_PATH_B]; |
3109 | |
3110 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3111 | fmt: "[TSSI] ch=%d thermal_pathB=0x%x\n" , ch, thermal); |
3112 | |
3113 | rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, data: 0x0); |
3114 | rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, data: 0x1); |
3115 | |
3116 | if (thermal == 0xff) { |
3117 | rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, data: 32); |
3118 | rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, data: 32); |
3119 | |
3120 | for (i = 0; i < 64; i += 4) { |
3121 | rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, data: 0x0); |
3122 | |
3123 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3124 | fmt: "[TSSI] write 0x%x val=0x%08x\n" , |
3125 | 0x7c00 + i, 0x0); |
3126 | } |
3127 | |
3128 | } else { |
3129 | rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, data: thermal); |
3130 | rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, |
3131 | data: thermal); |
3132 | |
3133 | i = 0; |
3134 | for (j = 0; j < 32; j++) |
3135 | thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? |
3136 | -thm_down_b[i++] : |
3137 | -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; |
3138 | |
3139 | i = 1; |
3140 | for (j = 63; j >= 32; j--) |
3141 | thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? |
3142 | thm_up_b[i++] : |
3143 | thm_up_b[DELTA_SWINGIDX_SIZE - 1]; |
3144 | |
3145 | for (i = 0; i < 64; i += 4) { |
3146 | tmp = RTW8852C_TSSI_GET_VAL(thm_ofst, i); |
3147 | rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, data: tmp); |
3148 | |
3149 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3150 | fmt: "[TSSI] write 0x%x val=0x%08x\n" , |
3151 | 0x7c00 + i, tmp); |
3152 | } |
3153 | } |
3154 | rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, data: 0x1); |
3155 | rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, data: 0x0); |
3156 | } |
3157 | #undef RTW8852C_TSSI_GET_VAL |
3158 | } |
3159 | |
3160 | static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3161 | enum rtw89_rf_path path) |
3162 | { |
3163 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
3164 | enum rtw89_band band = chan->band_type; |
3165 | |
3166 | if (path == RF_PATH_A) { |
3167 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
3168 | &rtw8852c_tssi_slope_cal_org_defs_2g_a_tbl, |
3169 | &rtw8852c_tssi_slope_cal_org_defs_5g_a_tbl); |
3170 | } else { |
3171 | rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, |
3172 | &rtw8852c_tssi_slope_cal_org_defs_2g_b_tbl, |
3173 | &rtw8852c_tssi_slope_cal_org_defs_5g_b_tbl); |
3174 | } |
3175 | } |
3176 | |
3177 | static void _tssi_set_aligk_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3178 | enum rtw89_rf_path path) |
3179 | { |
3180 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
3181 | enum rtw89_band band = chan->band_type; |
3182 | const struct rtw89_rfk_tbl *tbl; |
3183 | |
3184 | if (path == RF_PATH_A) { |
3185 | if (band == RTW89_BAND_2G) |
3186 | tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_a_tbl; |
3187 | else if (band == RTW89_BAND_6G) |
3188 | tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_a_tbl; |
3189 | else |
3190 | tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_a_tbl; |
3191 | } else { |
3192 | if (band == RTW89_BAND_2G) |
3193 | tbl = &rtw8852c_tssi_set_aligk_default_defs_2g_b_tbl; |
3194 | else if (band == RTW89_BAND_6G) |
3195 | tbl = &rtw8852c_tssi_set_aligk_default_defs_6g_b_tbl; |
3196 | else |
3197 | tbl = &rtw8852c_tssi_set_aligk_default_defs_5g_b_tbl; |
3198 | } |
3199 | |
3200 | rtw89_rfk_parser(rtwdev, tbl); |
3201 | } |
3202 | |
3203 | static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3204 | enum rtw89_rf_path path) |
3205 | { |
3206 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
3207 | &rtw8852c_tssi_slope_defs_a_tbl, |
3208 | &rtw8852c_tssi_slope_defs_b_tbl); |
3209 | } |
3210 | |
3211 | static void _tssi_run_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3212 | enum rtw89_rf_path path) |
3213 | { |
3214 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
3215 | &rtw8852c_tssi_run_slope_defs_a_tbl, |
3216 | &rtw8852c_tssi_run_slope_defs_b_tbl); |
3217 | } |
3218 | |
3219 | static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3220 | enum rtw89_rf_path path) |
3221 | { |
3222 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
3223 | &rtw8852c_tssi_track_defs_a_tbl, |
3224 | &rtw8852c_tssi_track_defs_b_tbl); |
3225 | } |
3226 | |
3227 | static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, |
3228 | enum rtw89_phy_idx phy, |
3229 | enum rtw89_rf_path path) |
3230 | { |
3231 | rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, |
3232 | &rtw8852c_tssi_txagc_ofst_mv_avg_defs_a_tbl, |
3233 | &rtw8852c_tssi_txagc_ofst_mv_avg_defs_b_tbl); |
3234 | } |
3235 | |
3236 | static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
3237 | { |
3238 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
3239 | u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; |
3240 | |
3241 | if (rtwdev->dbcc_en) { |
3242 | if (phy == RTW89_PHY_0) { |
3243 | path = RF_PATH_A; |
3244 | path_max = RF_PATH_B; |
3245 | } else if (phy == RTW89_PHY_1) { |
3246 | path = RF_PATH_B; |
3247 | path_max = RF_PATH_NUM_8852C; |
3248 | } |
3249 | } |
3250 | |
3251 | for (i = path; i < path_max; i++) { |
3252 | _tssi_set_track(rtwdev, phy, path: i); |
3253 | _tssi_set_txagc_offset_mv_avg(rtwdev, phy, path: i); |
3254 | |
3255 | rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, |
3256 | &rtw8852c_tssi_enable_defs_a_tbl, |
3257 | &rtw8852c_tssi_enable_defs_b_tbl); |
3258 | |
3259 | tssi_info->base_thermal[i] = |
3260 | ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[i]); |
3261 | rtwdev->is_tssi_mode[i] = true; |
3262 | } |
3263 | } |
3264 | |
3265 | static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
3266 | { |
3267 | u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; |
3268 | |
3269 | if (rtwdev->dbcc_en) { |
3270 | if (phy == RTW89_PHY_0) { |
3271 | path = RF_PATH_A; |
3272 | path_max = RF_PATH_B; |
3273 | } else if (phy == RTW89_PHY_1) { |
3274 | path = RF_PATH_B; |
3275 | path_max = RF_PATH_NUM_8852C; |
3276 | } |
3277 | } |
3278 | |
3279 | for (i = path; i < path_max; i++) { |
3280 | if (i == RF_PATH_A) { |
3281 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_tssi_disable_defs_a_tbl); |
3282 | rtwdev->is_tssi_mode[RF_PATH_A] = false; |
3283 | } else if (i == RF_PATH_B) { |
3284 | rtw89_rfk_parser(rtwdev, tbl: &rtw8852c_tssi_disable_defs_b_tbl); |
3285 | rtwdev->is_tssi_mode[RF_PATH_B] = false; |
3286 | } |
3287 | } |
3288 | } |
3289 | |
3290 | static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) |
3291 | { |
3292 | switch (ch) { |
3293 | case 1 ... 2: |
3294 | return 0; |
3295 | case 3 ... 5: |
3296 | return 1; |
3297 | case 6 ... 8: |
3298 | return 2; |
3299 | case 9 ... 11: |
3300 | return 3; |
3301 | case 12 ... 13: |
3302 | return 4; |
3303 | case 14: |
3304 | return 5; |
3305 | } |
3306 | |
3307 | return 0; |
3308 | } |
3309 | |
3310 | #define (BIT(31)) |
3311 | #define (idx) (TSSI_EXTRA_GROUP_BIT | (idx)) |
3312 | #define (group) ((group) & TSSI_EXTRA_GROUP_BIT) |
3313 | #define (group) ((group) & ~TSSI_EXTRA_GROUP_BIT) |
3314 | #define (group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) |
3315 | |
3316 | static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) |
3317 | { |
3318 | switch (ch) { |
3319 | case 1 ... 2: |
3320 | return 0; |
3321 | case 3 ... 5: |
3322 | return 1; |
3323 | case 6 ... 8: |
3324 | return 2; |
3325 | case 9 ... 11: |
3326 | return 3; |
3327 | case 12 ... 14: |
3328 | return 4; |
3329 | case 36 ... 40: |
3330 | return 5; |
3331 | case 41 ... 43: |
3332 | return TSSI_EXTRA_GROUP(5); |
3333 | case 44 ... 48: |
3334 | return 6; |
3335 | case 49 ... 51: |
3336 | return TSSI_EXTRA_GROUP(6); |
3337 | case 52 ... 56: |
3338 | return 7; |
3339 | case 57 ... 59: |
3340 | return TSSI_EXTRA_GROUP(7); |
3341 | case 60 ... 64: |
3342 | return 8; |
3343 | case 100 ... 104: |
3344 | return 9; |
3345 | case 105 ... 107: |
3346 | return TSSI_EXTRA_GROUP(9); |
3347 | case 108 ... 112: |
3348 | return 10; |
3349 | case 113 ... 115: |
3350 | return TSSI_EXTRA_GROUP(10); |
3351 | case 116 ... 120: |
3352 | return 11; |
3353 | case 121 ... 123: |
3354 | return TSSI_EXTRA_GROUP(11); |
3355 | case 124 ... 128: |
3356 | return 12; |
3357 | case 129 ... 131: |
3358 | return TSSI_EXTRA_GROUP(12); |
3359 | case 132 ... 136: |
3360 | return 13; |
3361 | case 137 ... 139: |
3362 | return TSSI_EXTRA_GROUP(13); |
3363 | case 140 ... 144: |
3364 | return 14; |
3365 | case 149 ... 153: |
3366 | return 15; |
3367 | case 154 ... 156: |
3368 | return TSSI_EXTRA_GROUP(15); |
3369 | case 157 ... 161: |
3370 | return 16; |
3371 | case 162 ... 164: |
3372 | return TSSI_EXTRA_GROUP(16); |
3373 | case 165 ... 169: |
3374 | return 17; |
3375 | case 170 ... 172: |
3376 | return TSSI_EXTRA_GROUP(17); |
3377 | case 173 ... 177: |
3378 | return 18; |
3379 | } |
3380 | |
3381 | return 0; |
3382 | } |
3383 | |
3384 | static u32 _tssi_get_6g_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) |
3385 | { |
3386 | switch (ch) { |
3387 | case 1 ... 5: |
3388 | return 0; |
3389 | case 6 ... 8: |
3390 | return TSSI_EXTRA_GROUP(0); |
3391 | case 9 ... 13: |
3392 | return 1; |
3393 | case 14 ... 16: |
3394 | return TSSI_EXTRA_GROUP(1); |
3395 | case 17 ... 21: |
3396 | return 2; |
3397 | case 22 ... 24: |
3398 | return TSSI_EXTRA_GROUP(2); |
3399 | case 25 ... 29: |
3400 | return 3; |
3401 | case 33 ... 37: |
3402 | return 4; |
3403 | case 38 ... 40: |
3404 | return TSSI_EXTRA_GROUP(4); |
3405 | case 41 ... 45: |
3406 | return 5; |
3407 | case 46 ... 48: |
3408 | return TSSI_EXTRA_GROUP(5); |
3409 | case 49 ... 53: |
3410 | return 6; |
3411 | case 54 ... 56: |
3412 | return TSSI_EXTRA_GROUP(6); |
3413 | case 57 ... 61: |
3414 | return 7; |
3415 | case 65 ... 69: |
3416 | return 8; |
3417 | case 70 ... 72: |
3418 | return TSSI_EXTRA_GROUP(8); |
3419 | case 73 ... 77: |
3420 | return 9; |
3421 | case 78 ... 80: |
3422 | return TSSI_EXTRA_GROUP(9); |
3423 | case 81 ... 85: |
3424 | return 10; |
3425 | case 86 ... 88: |
3426 | return TSSI_EXTRA_GROUP(10); |
3427 | case 89 ... 93: |
3428 | return 11; |
3429 | case 97 ... 101: |
3430 | return 12; |
3431 | case 102 ... 104: |
3432 | return TSSI_EXTRA_GROUP(12); |
3433 | case 105 ... 109: |
3434 | return 13; |
3435 | case 110 ... 112: |
3436 | return TSSI_EXTRA_GROUP(13); |
3437 | case 113 ... 117: |
3438 | return 14; |
3439 | case 118 ... 120: |
3440 | return TSSI_EXTRA_GROUP(14); |
3441 | case 121 ... 125: |
3442 | return 15; |
3443 | case 129 ... 133: |
3444 | return 16; |
3445 | case 134 ... 136: |
3446 | return TSSI_EXTRA_GROUP(16); |
3447 | case 137 ... 141: |
3448 | return 17; |
3449 | case 142 ... 144: |
3450 | return TSSI_EXTRA_GROUP(17); |
3451 | case 145 ... 149: |
3452 | return 18; |
3453 | case 150 ... 152: |
3454 | return TSSI_EXTRA_GROUP(18); |
3455 | case 153 ... 157: |
3456 | return 19; |
3457 | case 161 ... 165: |
3458 | return 20; |
3459 | case 166 ... 168: |
3460 | return TSSI_EXTRA_GROUP(20); |
3461 | case 169 ... 173: |
3462 | return 21; |
3463 | case 174 ... 176: |
3464 | return TSSI_EXTRA_GROUP(21); |
3465 | case 177 ... 181: |
3466 | return 22; |
3467 | case 182 ... 184: |
3468 | return TSSI_EXTRA_GROUP(22); |
3469 | case 185 ... 189: |
3470 | return 23; |
3471 | case 193 ... 197: |
3472 | return 24; |
3473 | case 198 ... 200: |
3474 | return TSSI_EXTRA_GROUP(24); |
3475 | case 201 ... 205: |
3476 | return 25; |
3477 | case 206 ... 208: |
3478 | return TSSI_EXTRA_GROUP(25); |
3479 | case 209 ... 213: |
3480 | return 26; |
3481 | case 214 ... 216: |
3482 | return TSSI_EXTRA_GROUP(26); |
3483 | case 217 ... 221: |
3484 | return 27; |
3485 | case 225 ... 229: |
3486 | return 28; |
3487 | case 230 ... 232: |
3488 | return TSSI_EXTRA_GROUP(28); |
3489 | case 233 ... 237: |
3490 | return 29; |
3491 | case 238 ... 240: |
3492 | return TSSI_EXTRA_GROUP(29); |
3493 | case 241 ... 245: |
3494 | return 30; |
3495 | case 246 ... 248: |
3496 | return TSSI_EXTRA_GROUP(30); |
3497 | case 249 ... 253: |
3498 | return 31; |
3499 | } |
3500 | |
3501 | return 0; |
3502 | } |
3503 | |
3504 | static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) |
3505 | { |
3506 | switch (ch) { |
3507 | case 1 ... 8: |
3508 | return 0; |
3509 | case 9 ... 14: |
3510 | return 1; |
3511 | case 36 ... 48: |
3512 | return 2; |
3513 | case 49 ... 51: |
3514 | return TSSI_EXTRA_GROUP(2); |
3515 | case 52 ... 64: |
3516 | return 3; |
3517 | case 100 ... 112: |
3518 | return 4; |
3519 | case 113 ... 115: |
3520 | return TSSI_EXTRA_GROUP(4); |
3521 | case 116 ... 128: |
3522 | return 5; |
3523 | case 132 ... 144: |
3524 | return 6; |
3525 | case 149 ... 177: |
3526 | return 7; |
3527 | } |
3528 | |
3529 | return 0; |
3530 | } |
3531 | |
3532 | static u32 _tssi_get_6g_trim_group(struct rtw89_dev *rtwdev, u8 ch) |
3533 | { |
3534 | switch (ch) { |
3535 | case 1 ... 13: |
3536 | return 0; |
3537 | case 14 ... 16: |
3538 | return TSSI_EXTRA_GROUP(0); |
3539 | case 17 ... 29: |
3540 | return 1; |
3541 | case 33 ... 45: |
3542 | return 2; |
3543 | case 46 ... 48: |
3544 | return TSSI_EXTRA_GROUP(2); |
3545 | case 49 ... 61: |
3546 | return 3; |
3547 | case 65 ... 77: |
3548 | return 4; |
3549 | case 78 ... 80: |
3550 | return TSSI_EXTRA_GROUP(4); |
3551 | case 81 ... 93: |
3552 | return 5; |
3553 | case 97 ... 109: |
3554 | return 6; |
3555 | case 110 ... 112: |
3556 | return TSSI_EXTRA_GROUP(6); |
3557 | case 113 ... 125: |
3558 | return 7; |
3559 | case 129 ... 141: |
3560 | return 8; |
3561 | case 142 ... 144: |
3562 | return TSSI_EXTRA_GROUP(8); |
3563 | case 145 ... 157: |
3564 | return 9; |
3565 | case 161 ... 173: |
3566 | return 10; |
3567 | case 174 ... 176: |
3568 | return TSSI_EXTRA_GROUP(10); |
3569 | case 177 ... 189: |
3570 | return 11; |
3571 | case 193 ... 205: |
3572 | return 12; |
3573 | case 206 ... 208: |
3574 | return TSSI_EXTRA_GROUP(12); |
3575 | case 209 ... 221: |
3576 | return 13; |
3577 | case 225 ... 237: |
3578 | return 14; |
3579 | case 238 ... 240: |
3580 | return TSSI_EXTRA_GROUP(14); |
3581 | case 241 ... 253: |
3582 | return 15; |
3583 | } |
3584 | |
3585 | return 0; |
3586 | } |
3587 | |
3588 | static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3589 | enum rtw89_rf_path path) |
3590 | { |
3591 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
3592 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
3593 | enum rtw89_band band = chan->band_type; |
3594 | u8 ch = chan->channel; |
3595 | u32 gidx, gidx_1st, gidx_2nd; |
3596 | s8 de_1st; |
3597 | s8 de_2nd; |
3598 | s8 val; |
3599 | |
3600 | if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { |
3601 | gidx = _tssi_get_ofdm_group(rtwdev, ch); |
3602 | |
3603 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3604 | fmt: "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n" , |
3605 | path, gidx); |
3606 | |
3607 | if (IS_TSSI_EXTRA_GROUP(gidx)) { |
3608 | gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); |
3609 | gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); |
3610 | de_1st = tssi_info->tssi_mcs[path][gidx_1st]; |
3611 | de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; |
3612 | val = (de_1st + de_2nd) / 2; |
3613 | |
3614 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3615 | fmt: "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n" , |
3616 | path, val, de_1st, de_2nd); |
3617 | } else { |
3618 | val = tssi_info->tssi_mcs[path][gidx]; |
3619 | |
3620 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3621 | fmt: "[TSSI][TRIM]: path=%d mcs de=%d\n" , path, val); |
3622 | } |
3623 | } else { |
3624 | gidx = _tssi_get_6g_ofdm_group(rtwdev, ch); |
3625 | |
3626 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3627 | fmt: "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n" , |
3628 | path, gidx); |
3629 | |
3630 | if (IS_TSSI_EXTRA_GROUP(gidx)) { |
3631 | gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); |
3632 | gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); |
3633 | de_1st = tssi_info->tssi_6g_mcs[path][gidx_1st]; |
3634 | de_2nd = tssi_info->tssi_6g_mcs[path][gidx_2nd]; |
3635 | val = (de_1st + de_2nd) / 2; |
3636 | |
3637 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3638 | fmt: "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n" , |
3639 | path, val, de_1st, de_2nd); |
3640 | } else { |
3641 | val = tssi_info->tssi_6g_mcs[path][gidx]; |
3642 | |
3643 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3644 | fmt: "[TSSI][TRIM]: path=%d mcs de=%d\n" , path, val); |
3645 | } |
3646 | } |
3647 | |
3648 | return val; |
3649 | } |
3650 | |
3651 | static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, |
3652 | enum rtw89_phy_idx phy, |
3653 | enum rtw89_rf_path path) |
3654 | { |
3655 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
3656 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
3657 | enum rtw89_band band = chan->band_type; |
3658 | u8 ch = chan->channel; |
3659 | u32 tgidx, tgidx_1st, tgidx_2nd; |
3660 | s8 tde_1st = 0; |
3661 | s8 tde_2nd = 0; |
3662 | s8 val; |
3663 | |
3664 | if (band == RTW89_BAND_2G || band == RTW89_BAND_5G) { |
3665 | tgidx = _tssi_get_trim_group(rtwdev, ch); |
3666 | |
3667 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3668 | fmt: "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n" , |
3669 | path, tgidx); |
3670 | |
3671 | if (IS_TSSI_EXTRA_GROUP(tgidx)) { |
3672 | tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); |
3673 | tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); |
3674 | tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; |
3675 | tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; |
3676 | val = (tde_1st + tde_2nd) / 2; |
3677 | |
3678 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3679 | fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n" , |
3680 | path, val, tde_1st, tde_2nd); |
3681 | } else { |
3682 | val = tssi_info->tssi_trim[path][tgidx]; |
3683 | |
3684 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3685 | fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d\n" , |
3686 | path, val); |
3687 | } |
3688 | } else { |
3689 | tgidx = _tssi_get_6g_trim_group(rtwdev, ch); |
3690 | |
3691 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3692 | fmt: "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n" , |
3693 | path, tgidx); |
3694 | |
3695 | if (IS_TSSI_EXTRA_GROUP(tgidx)) { |
3696 | tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); |
3697 | tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); |
3698 | tde_1st = tssi_info->tssi_trim_6g[path][tgidx_1st]; |
3699 | tde_2nd = tssi_info->tssi_trim_6g[path][tgidx_2nd]; |
3700 | val = (tde_1st + tde_2nd) / 2; |
3701 | |
3702 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3703 | fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n" , |
3704 | path, val, tde_1st, tde_2nd); |
3705 | } else { |
3706 | val = tssi_info->tssi_trim_6g[path][tgidx]; |
3707 | |
3708 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3709 | fmt: "[TSSI][TRIM]: path=%d mcs trim_de=%d\n" , |
3710 | path, val); |
3711 | } |
3712 | } |
3713 | |
3714 | return val; |
3715 | } |
3716 | |
3717 | static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, |
3718 | enum rtw89_phy_idx phy) |
3719 | { |
3720 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
3721 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
3722 | u8 ch = chan->channel; |
3723 | u8 gidx; |
3724 | s8 ofdm_de; |
3725 | s8 trim_de; |
3726 | s32 val; |
3727 | u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; |
3728 | |
3729 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "[TSSI][TRIM]: phy=%d ch=%d\n" , |
3730 | phy, ch); |
3731 | |
3732 | if (rtwdev->dbcc_en) { |
3733 | if (phy == RTW89_PHY_0) { |
3734 | path = RF_PATH_A; |
3735 | path_max = RF_PATH_B; |
3736 | } else if (phy == RTW89_PHY_1) { |
3737 | path = RF_PATH_B; |
3738 | path_max = RF_PATH_NUM_8852C; |
3739 | } |
3740 | } |
3741 | |
3742 | for (i = path; i < path_max; i++) { |
3743 | gidx = _tssi_get_cck_group(rtwdev, ch); |
3744 | trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, path: i); |
3745 | val = tssi_info->tssi_cck[i][gidx] + trim_de; |
3746 | |
3747 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3748 | fmt: "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n" , |
3749 | i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); |
3750 | |
3751 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_cck_long[i], _TSSI_DE_MASK, data: val); |
3752 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_cck_short[i], _TSSI_DE_MASK, data: val); |
3753 | |
3754 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3755 | fmt: "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n" , |
3756 | _tssi_de_cck_long[i], |
3757 | rtw89_phy_read32_mask(rtwdev, addr: _tssi_de_cck_long[i], |
3758 | _TSSI_DE_MASK)); |
3759 | |
3760 | ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, path: i); |
3761 | trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, path: i); |
3762 | val = ofdm_de + trim_de; |
3763 | |
3764 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3765 | fmt: "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n" , |
3766 | i, ofdm_de, trim_de); |
3767 | |
3768 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_20m[i], _TSSI_DE_MASK, data: val); |
3769 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_40m[i], _TSSI_DE_MASK, data: val); |
3770 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_80m[i], _TSSI_DE_MASK, data: val); |
3771 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, data: val); |
3772 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_5m[i], _TSSI_DE_MASK, data: val); |
3773 | rtw89_phy_write32_mask(rtwdev, addr: _tssi_de_mcs_10m[i], _TSSI_DE_MASK, data: val); |
3774 | |
3775 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, |
3776 | fmt: "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n" , |
3777 | _tssi_de_mcs_20m[i], |
3778 | rtw89_phy_read32_mask(rtwdev, addr: _tssi_de_mcs_20m[i], |
3779 | _TSSI_DE_MASK)); |
3780 | } |
3781 | } |
3782 | |
3783 | static void rtw8852c_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, |
3784 | enum rtw89_rf_path path) |
3785 | { |
3786 | static const u32 tssi_trk[2] = {0x5818, 0x7818}; |
3787 | static const u32 tssi_en[2] = {0x5820, 0x7820}; |
3788 | |
3789 | if (en) { |
3790 | rtw89_phy_write32_mask(rtwdev, addr: tssi_trk[path], BIT(30), data: 0x0); |
3791 | rtw89_phy_write32_mask(rtwdev, addr: tssi_en[path], BIT(31), data: 0x0); |
3792 | if (rtwdev->dbcc_en && path == RF_PATH_B) |
3793 | _tssi_set_efuse_to_de(rtwdev, phy: RTW89_PHY_1); |
3794 | else |
3795 | _tssi_set_efuse_to_de(rtwdev, phy: RTW89_PHY_0); |
3796 | } else { |
3797 | rtw89_phy_write32_mask(rtwdev, addr: tssi_trk[path], BIT(30), data: 0x1); |
3798 | rtw89_phy_write32_mask(rtwdev, addr: tssi_en[path], BIT(31), data: 0x1); |
3799 | } |
3800 | } |
3801 | |
3802 | void rtw8852c_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) |
3803 | { |
3804 | if (!rtwdev->dbcc_en) { |
3805 | rtw8852c_tssi_cont_en(rtwdev, en, path: RF_PATH_A); |
3806 | rtw8852c_tssi_cont_en(rtwdev, en, path: RF_PATH_B); |
3807 | } else { |
3808 | if (phy_idx == RTW89_PHY_0) |
3809 | rtw8852c_tssi_cont_en(rtwdev, en, path: RF_PATH_A); |
3810 | else |
3811 | rtw8852c_tssi_cont_en(rtwdev, en, path: RF_PATH_B); |
3812 | } |
3813 | } |
3814 | |
3815 | static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, |
3816 | enum rtw89_bandwidth bw, bool is_dav) |
3817 | { |
3818 | u32 rf_reg18; |
3819 | u32 reg_reg18_addr; |
3820 | |
3821 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===>%s\n" , __func__); |
3822 | if (is_dav) |
3823 | reg_reg18_addr = RR_CFGCH; |
3824 | else |
3825 | reg_reg18_addr = RR_CFGCH_V1; |
3826 | |
3827 | rf_reg18 = rtw89_read_rf(rtwdev, rf_path: path, addr: reg_reg18_addr, RFREG_MASK); |
3828 | rf_reg18 &= ~RR_CFGCH_BW; |
3829 | |
3830 | switch (bw) { |
3831 | case RTW89_CHANNEL_WIDTH_5: |
3832 | case RTW89_CHANNEL_WIDTH_10: |
3833 | case RTW89_CHANNEL_WIDTH_20: |
3834 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); |
3835 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data: 0x3); |
3836 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data: 0xf); |
3837 | break; |
3838 | case RTW89_CHANNEL_WIDTH_40: |
3839 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); |
3840 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data: 0x3); |
3841 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data: 0xf); |
3842 | break; |
3843 | case RTW89_CHANNEL_WIDTH_80: |
3844 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); |
3845 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data: 0x2); |
3846 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data: 0xd); |
3847 | break; |
3848 | case RTW89_CHANNEL_WIDTH_160: |
3849 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_160M); |
3850 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW0 | (path << 8), B_P0_CFCH_BW0, data: 0x1); |
3851 | rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1 | (path << 8), B_P0_CFCH_BW1, data: 0xb); |
3852 | break; |
3853 | default: |
3854 | break; |
3855 | } |
3856 | |
3857 | rtw89_write_rf(rtwdev, rf_path: path, addr: reg_reg18_addr, RFREG_MASK, data: rf_reg18); |
3858 | } |
3859 | |
3860 | static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3861 | enum rtw89_bandwidth bw) |
3862 | { |
3863 | bool is_dav; |
3864 | u8 kpath, path; |
3865 | u32 tmp = 0; |
3866 | |
3867 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===>%s\n" , __func__); |
3868 | kpath = _kpath(rtwdev, phy_idx: phy); |
3869 | |
3870 | for (path = 0; path < 2; path++) { |
3871 | if (!(kpath & BIT(path))) |
3872 | continue; |
3873 | |
3874 | is_dav = true; |
3875 | _bw_setting(rtwdev, path, bw, is_dav); |
3876 | is_dav = false; |
3877 | _bw_setting(rtwdev, path, bw, is_dav); |
3878 | if (rtwdev->dbcc_en) |
3879 | continue; |
3880 | |
3881 | if (path == RF_PATH_B && rtwdev->hal.cv == CHIP_CAV) { |
3882 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x0); |
3883 | tmp = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_CFGCH, RFREG_MASK); |
3884 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_APK, RR_APK_MOD, data: 0x3); |
3885 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_CFGCH, RFREG_MASK, data: tmp); |
3886 | fsleep(usecs: 100); |
3887 | rtw89_write_rf(rtwdev, rf_path: RF_PATH_B, RR_RSV1, RR_RSV1_RST, data: 0x1); |
3888 | } |
3889 | } |
3890 | } |
3891 | |
3892 | static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, |
3893 | u8 central_ch, enum rtw89_band band, bool is_dav) |
3894 | { |
3895 | u32 rf_reg18; |
3896 | u32 reg_reg18_addr; |
3897 | |
3898 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===>%s\n" , __func__); |
3899 | if (is_dav) |
3900 | reg_reg18_addr = 0x18; |
3901 | else |
3902 | reg_reg18_addr = 0x10018; |
3903 | |
3904 | rf_reg18 = rtw89_read_rf(rtwdev, rf_path: path, addr: reg_reg18_addr, RFREG_MASK); |
3905 | rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BAND0 | RR_CFGCH_CH); |
3906 | rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); |
3907 | |
3908 | switch (band) { |
3909 | case RTW89_BAND_2G: |
3910 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_2G); |
3911 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_2G); |
3912 | break; |
3913 | case RTW89_BAND_5G: |
3914 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G); |
3915 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); |
3916 | break; |
3917 | case RTW89_BAND_6G: |
3918 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_6G); |
3919 | rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_6G); |
3920 | break; |
3921 | default: |
3922 | break; |
3923 | } |
3924 | rtw89_write_rf(rtwdev, rf_path: path, addr: reg_reg18_addr, RFREG_MASK, data: rf_reg18); |
3925 | fsleep(usecs: 100); |
3926 | } |
3927 | |
3928 | static void _ctrl_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3929 | u8 central_ch, enum rtw89_band band) |
3930 | { |
3931 | u8 kpath, path; |
3932 | |
3933 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RFK]===>%s\n" , __func__); |
3934 | if (band != RTW89_BAND_6G) { |
3935 | if ((central_ch > 14 && central_ch < 36) || |
3936 | (central_ch > 64 && central_ch < 100) || |
3937 | (central_ch > 144 && central_ch < 149) || central_ch > 177) |
3938 | return; |
3939 | } else { |
3940 | if (central_ch > 253 || central_ch == 2) |
3941 | return; |
3942 | } |
3943 | |
3944 | kpath = _kpath(rtwdev, phy_idx: phy); |
3945 | |
3946 | for (path = 0; path < 2; path++) { |
3947 | if (kpath & BIT(path)) { |
3948 | _ch_setting(rtwdev, path, central_ch, band, is_dav: true); |
3949 | _ch_setting(rtwdev, path, central_ch, band, is_dav: false); |
3950 | } |
3951 | } |
3952 | } |
3953 | |
3954 | static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
3955 | enum rtw89_bandwidth bw) |
3956 | { |
3957 | u8 kpath; |
3958 | u8 path; |
3959 | u32 val; |
3960 | |
3961 | kpath = _kpath(rtwdev, phy_idx: phy); |
3962 | for (path = 0; path < 2; path++) { |
3963 | if (!(kpath & BIT(path))) |
3964 | continue; |
3965 | |
3966 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE2, RR_LUTWE2_RTXBW, data: 0x1); |
3967 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWA, RR_LUTWA_M2, data: 0xa); |
3968 | switch (bw) { |
3969 | case RTW89_CHANNEL_WIDTH_20: |
3970 | val = 0x1b; |
3971 | break; |
3972 | case RTW89_CHANNEL_WIDTH_40: |
3973 | val = 0x13; |
3974 | break; |
3975 | case RTW89_CHANNEL_WIDTH_80: |
3976 | val = 0xb; |
3977 | break; |
3978 | case RTW89_CHANNEL_WIDTH_160: |
3979 | default: |
3980 | val = 0x3; |
3981 | break; |
3982 | } |
3983 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWD0, RR_LUTWD0_LB, data: val); |
3984 | rtw89_write_rf(rtwdev, rf_path: path, RR_LUTWE2, RR_LUTWE2_RTXBW, data: 0x0); |
3985 | } |
3986 | } |
3987 | |
3988 | static void _lck_keep_thermal(struct rtw89_dev *rtwdev) |
3989 | { |
3990 | struct rtw89_lck_info *lck = &rtwdev->lck; |
3991 | int path; |
3992 | |
3993 | for (path = 0; path < rtwdev->chip->rf_path_num; path++) { |
3994 | lck->thermal[path] = |
3995 | ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]); |
3996 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
3997 | fmt: "[LCK] path=%d thermal=0x%x" , path, lck->thermal[path]); |
3998 | } |
3999 | } |
4000 | |
4001 | static void _lck(struct rtw89_dev *rtwdev) |
4002 | { |
4003 | u32 tmp18[2]; |
4004 | int path = rtwdev->dbcc_en ? 2 : 1; |
4005 | int i; |
4006 | |
4007 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, fmt: "[LCK] DO LCK\n" ); |
4008 | |
4009 | tmp18[0] = rtw89_read_rf(rtwdev, rf_path: RF_PATH_A, RR_CFGCH, RFREG_MASK); |
4010 | tmp18[1] = rtw89_read_rf(rtwdev, rf_path: RF_PATH_B, RR_CFGCH, RFREG_MASK); |
4011 | |
4012 | for (i = 0; i < path; i++) { |
4013 | rtw89_write_rf(rtwdev, rf_path: i, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x1); |
4014 | rtw89_write_rf(rtwdev, rf_path: i, RR_CFGCH, RFREG_MASK, data: tmp18[i]); |
4015 | rtw89_write_rf(rtwdev, rf_path: i, RR_LCK_TRG, RR_LCK_TRGSEL, data: 0x0); |
4016 | } |
4017 | |
4018 | _lck_keep_thermal(rtwdev); |
4019 | } |
4020 | |
4021 | #define RTW8852C_LCK_TH 8 |
4022 | |
4023 | void rtw8852c_lck_track(struct rtw89_dev *rtwdev) |
4024 | { |
4025 | struct rtw89_lck_info *lck = &rtwdev->lck; |
4026 | u8 cur_thermal; |
4027 | int delta; |
4028 | int path; |
4029 | |
4030 | for (path = 0; path < rtwdev->chip->rf_path_num; path++) { |
4031 | cur_thermal = |
4032 | ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]); |
4033 | delta = abs((int)cur_thermal - lck->thermal[path]); |
4034 | |
4035 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
4036 | fmt: "[LCK] path=%d current thermal=0x%x delta=0x%x\n" , |
4037 | path, cur_thermal, delta); |
4038 | |
4039 | if (delta >= RTW8852C_LCK_TH) { |
4040 | _lck(rtwdev); |
4041 | return; |
4042 | } |
4043 | } |
4044 | } |
4045 | |
4046 | void rtw8852c_lck_init(struct rtw89_dev *rtwdev) |
4047 | { |
4048 | _lck_keep_thermal(rtwdev); |
4049 | } |
4050 | |
4051 | static |
4052 | void rtw8852c_ctrl_bw_ch(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
4053 | u8 central_ch, enum rtw89_band band, |
4054 | enum rtw89_bandwidth bw) |
4055 | { |
4056 | _ctrl_ch(rtwdev, phy, central_ch, band); |
4057 | _ctrl_bw(rtwdev, phy, bw); |
4058 | _rxbb_bw(rtwdev, phy, bw); |
4059 | } |
4060 | |
4061 | void rtw8852c_set_channel_rf(struct rtw89_dev *rtwdev, |
4062 | const struct rtw89_chan *chan, |
4063 | enum rtw89_phy_idx phy_idx) |
4064 | { |
4065 | rtw8852c_ctrl_bw_ch(rtwdev, phy: phy_idx, central_ch: chan->channel, |
4066 | band: chan->band_type, |
4067 | bw: chan->band_width); |
4068 | } |
4069 | |
4070 | void rtw8852c_mcc_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) |
4071 | { |
4072 | struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; |
4073 | DECLARE_BITMAP(map, RTW89_IQK_CHS_NR) = {}; |
4074 | const struct rtw89_chan *chan; |
4075 | enum rtw89_entity_mode mode; |
4076 | u8 chan_idx; |
4077 | u8 idx; |
4078 | u8 i; |
4079 | |
4080 | mode = rtw89_get_entity_mode(rtwdev); |
4081 | switch (mode) { |
4082 | case RTW89_ENTITY_MODE_MCC_PREPARE: |
4083 | chan_idx = RTW89_SUB_ENTITY_1; |
4084 | break; |
4085 | default: |
4086 | chan_idx = RTW89_SUB_ENTITY_0; |
4087 | break; |
4088 | } |
4089 | |
4090 | for (i = 0; i <= chan_idx; i++) { |
4091 | chan = rtw89_chan_get(rtwdev, idx: i); |
4092 | |
4093 | for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { |
4094 | if (rfk_mcc->ch[idx] == chan->channel && |
4095 | rfk_mcc->band[idx] == chan->band_type) { |
4096 | if (i != chan_idx) { |
4097 | set_bit(nr: idx, addr: map); |
4098 | break; |
4099 | } |
4100 | |
4101 | goto bottom; |
4102 | } |
4103 | } |
4104 | } |
4105 | |
4106 | idx = find_first_zero_bit(addr: map, RTW89_IQK_CHS_NR); |
4107 | if (idx == RTW89_IQK_CHS_NR) { |
4108 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
4109 | fmt: "%s: no empty rfk table; force replace the first\n" , |
4110 | __func__); |
4111 | idx = 0; |
4112 | } |
4113 | |
4114 | rfk_mcc->ch[idx] = chan->channel; |
4115 | rfk_mcc->band[idx] = chan->band_type; |
4116 | |
4117 | bottom: |
4118 | rfk_mcc->table_idx = idx; |
4119 | } |
4120 | |
4121 | void rtw8852c_rck(struct rtw89_dev *rtwdev) |
4122 | { |
4123 | u8 path; |
4124 | |
4125 | for (path = 0; path < 2; path++) |
4126 | _rck(rtwdev, path); |
4127 | } |
4128 | |
4129 | void rtw8852c_dack(struct rtw89_dev *rtwdev) |
4130 | { |
4131 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx: RTW89_PHY_0, paths: 0); |
4132 | |
4133 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_START); |
4134 | _dac_cal(rtwdev, force: false); |
4135 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DACK, state: BTC_WRFK_STOP); |
4136 | } |
4137 | |
4138 | void rtw8852c_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) |
4139 | { |
4140 | u32 tx_en; |
4141 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0); |
4142 | |
4143 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_START); |
4144 | rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL); |
4145 | _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx)); |
4146 | |
4147 | _iqk_init(rtwdev); |
4148 | _iqk(rtwdev, phy_idx, force: false); |
4149 | |
4150 | rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en); |
4151 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_IQK, state: BTC_WRFK_STOP); |
4152 | } |
4153 | |
4154 | #define RXDCK_VER_8852C 0xe |
4155 | |
4156 | static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, |
4157 | bool is_afe, u8 retry_limit) |
4158 | { |
4159 | struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; |
4160 | u8 path, kpath; |
4161 | u32 rf_reg5; |
4162 | bool is_fail; |
4163 | u8 rek_cnt; |
4164 | |
4165 | kpath = _kpath(rtwdev, phy_idx: phy); |
4166 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, |
4167 | fmt: "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n" , |
4168 | RXDCK_VER_8852C, rtwdev->hal.cv); |
4169 | |
4170 | for (path = 0; path < 2; path++) { |
4171 | rf_reg5 = rtw89_read_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK); |
4172 | if (!(kpath & BIT(path))) |
4173 | continue; |
4174 | |
4175 | if (rtwdev->is_tssi_mode[path]) |
4176 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), |
4177 | B_P0_TSSI_TRK_EN, data: 0x1); |
4178 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RR_RSV1_RST, data: 0x0); |
4179 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); |
4180 | rtw89_write_rf(rtwdev, rf_path: path, RR_MOD, RR_MOD_LO_SEL, data: rtwdev->dbcc_en); |
4181 | |
4182 | for (rek_cnt = 0; rek_cnt < retry_limit; rek_cnt++) { |
4183 | _set_rx_dck(rtwdev, phy, path, is_afe); |
4184 | |
4185 | /* To reduce IO of dck_rek_check(), the last try is seen |
4186 | * as failure always, and then do recovery procedure. |
4187 | */ |
4188 | if (rek_cnt == retry_limit - 1) { |
4189 | _rx_dck_recover(rtwdev, path); |
4190 | break; |
4191 | } |
4192 | |
4193 | is_fail = _rx_dck_rek_check(rtwdev, path); |
4194 | if (!is_fail) |
4195 | break; |
4196 | } |
4197 | |
4198 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK, fmt: "[RX_DCK] rek_cnt[%d]=%d" , |
4199 | path, rek_cnt); |
4200 | |
4201 | rx_dck->thermal[path] = ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]); |
4202 | rtw89_write_rf(rtwdev, rf_path: path, RR_RSV1, RFREG_MASK, data: rf_reg5); |
4203 | |
4204 | if (rtwdev->is_tssi_mode[path]) |
4205 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), |
4206 | B_P0_TSSI_TRK_EN, data: 0x0); |
4207 | } |
4208 | } |
4209 | |
4210 | void rtw8852c_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe) |
4211 | { |
4212 | _rx_dck(rtwdev, phy, is_afe, retry_limit: 1); |
4213 | } |
4214 | |
4215 | #define RTW8852C_RX_DCK_TH 12 |
4216 | |
4217 | void rtw8852c_rx_dck_track(struct rtw89_dev *rtwdev) |
4218 | { |
4219 | const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, idx: RTW89_SUB_ENTITY_0); |
4220 | struct rtw89_rx_dck_info *rx_dck = &rtwdev->rx_dck; |
4221 | enum rtw89_phy_idx phy_idx = RTW89_PHY_0; |
4222 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0); |
4223 | u8 dck_channel; |
4224 | u8 cur_thermal; |
4225 | u32 tx_en; |
4226 | int delta; |
4227 | int path; |
4228 | |
4229 | if (chan->band_type == RTW89_BAND_2G) |
4230 | return; |
4231 | |
4232 | if (rtwdev->scanning) |
4233 | return; |
4234 | |
4235 | for (path = 0; path < RF_PATH_NUM_8852C; path++) { |
4236 | cur_thermal = |
4237 | ewma_thermal_read(e: &rtwdev->phystat.avg_thermal[path]); |
4238 | delta = abs((int)cur_thermal - rx_dck->thermal[path]); |
4239 | |
4240 | rtw89_debug(rtwdev, mask: RTW89_DBG_RFK_TRACK, |
4241 | fmt: "[RX_DCK] path=%d current thermal=0x%x delta=0x%x\n" , |
4242 | path, cur_thermal, delta); |
4243 | |
4244 | if (delta >= RTW8852C_RX_DCK_TH) |
4245 | goto trigger_rx_dck; |
4246 | } |
4247 | |
4248 | return; |
4249 | |
4250 | trigger_rx_dck: |
4251 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_RXDCK, state: BTC_WRFK_START); |
4252 | rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL); |
4253 | |
4254 | for (path = 0; path < RF_PATH_NUM_8852C; path++) { |
4255 | dck_channel = _rx_dck_channel_calc(rtwdev, chan); |
4256 | _ctrl_ch(rtwdev, phy: RTW89_PHY_0, central_ch: dck_channel, band: chan->band_type); |
4257 | } |
4258 | |
4259 | _rx_dck(rtwdev, phy: RTW89_PHY_0, is_afe: false, retry_limit: 20); |
4260 | |
4261 | for (path = 0; path < RF_PATH_NUM_8852C; path++) |
4262 | _ctrl_ch(rtwdev, phy: RTW89_PHY_0, central_ch: chan->channel, band: chan->band_type); |
4263 | |
4264 | rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en); |
4265 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_RXDCK, state: BTC_WRFK_STOP); |
4266 | } |
4267 | |
4268 | void rtw8852c_dpk_init(struct rtw89_dev *rtwdev) |
4269 | { |
4270 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
4271 | |
4272 | dpk->is_dpk_enable = true; |
4273 | dpk->is_dpk_reload_en = false; |
4274 | } |
4275 | |
4276 | void rtw8852c_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) |
4277 | { |
4278 | u32 tx_en; |
4279 | u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, paths: 0); |
4280 | |
4281 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DPK, state: BTC_WRFK_START); |
4282 | rtw89_chip_stop_sch_tx(rtwdev, mac_idx: phy_idx, tx_en: &tx_en, sel: RTW89_SCH_TX_SEL_ALL); |
4283 | _wait_rx_mode(rtwdev, kpath: _kpath(rtwdev, phy_idx)); |
4284 | |
4285 | _dpk(rtwdev, phy: phy_idx, force: false); |
4286 | |
4287 | rtw89_chip_resume_sch_tx(rtwdev, mac_idx: phy_idx, tx_en); |
4288 | rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, type: BTC_WRFKT_DPK, state: BTC_WRFK_STOP); |
4289 | } |
4290 | |
4291 | void rtw8852c_dpk_track(struct rtw89_dev *rtwdev) |
4292 | { |
4293 | _dpk_track(rtwdev); |
4294 | } |
4295 | |
4296 | void rtw8852c_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
4297 | { |
4298 | u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; |
4299 | |
4300 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "[TSSI] %s: phy=%d\n" , __func__, phy); |
4301 | |
4302 | if (rtwdev->dbcc_en) { |
4303 | if (phy == RTW89_PHY_0) { |
4304 | path = RF_PATH_A; |
4305 | path_max = RF_PATH_B; |
4306 | } else if (phy == RTW89_PHY_1) { |
4307 | path = RF_PATH_B; |
4308 | path_max = RF_PATH_NUM_8852C; |
4309 | } |
4310 | } |
4311 | |
4312 | _tssi_disable(rtwdev, phy); |
4313 | |
4314 | for (i = path; i < path_max; i++) { |
4315 | _tssi_set_sys(rtwdev, phy, path: i); |
4316 | _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, path: i); |
4317 | _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, path: i); |
4318 | _tssi_set_dck(rtwdev, phy, path: i); |
4319 | _tssi_set_bbgain_split(rtwdev, phy, path: i); |
4320 | _tssi_set_tmeter_tbl(rtwdev, phy, path: i); |
4321 | _tssi_slope_cal_org(rtwdev, phy, path: i); |
4322 | _tssi_set_aligk_default(rtwdev, phy, path: i); |
4323 | _tssi_set_slope(rtwdev, phy, path: i); |
4324 | _tssi_run_slope(rtwdev, phy, path: i); |
4325 | } |
4326 | |
4327 | _tssi_enable(rtwdev, phy); |
4328 | _tssi_set_efuse_to_de(rtwdev, phy); |
4329 | } |
4330 | |
4331 | void rtw8852c_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) |
4332 | { |
4333 | u32 i, path = RF_PATH_A, path_max = RF_PATH_NUM_8852C; |
4334 | |
4335 | rtw89_debug(rtwdev, mask: RTW89_DBG_TSSI, fmt: "[TSSI] %s: phy=%d\n" , |
4336 | __func__, phy); |
4337 | |
4338 | if (!rtwdev->is_tssi_mode[RF_PATH_A]) |
4339 | return; |
4340 | if (!rtwdev->is_tssi_mode[RF_PATH_B]) |
4341 | return; |
4342 | |
4343 | if (rtwdev->dbcc_en) { |
4344 | if (phy == RTW89_PHY_0) { |
4345 | path = RF_PATH_A; |
4346 | path_max = RF_PATH_B; |
4347 | } else if (phy == RTW89_PHY_1) { |
4348 | path = RF_PATH_B; |
4349 | path_max = RF_PATH_NUM_8852C; |
4350 | } |
4351 | } |
4352 | |
4353 | _tssi_disable(rtwdev, phy); |
4354 | |
4355 | for (i = path; i < path_max; i++) { |
4356 | _tssi_set_sys(rtwdev, phy, path: i); |
4357 | _tssi_set_dck(rtwdev, phy, path: i); |
4358 | _tssi_set_tmeter_tbl(rtwdev, phy, path: i); |
4359 | _tssi_slope_cal_org(rtwdev, phy, path: i); |
4360 | _tssi_set_aligk_default(rtwdev, phy, path: i); |
4361 | } |
4362 | |
4363 | _tssi_enable(rtwdev, phy); |
4364 | _tssi_set_efuse_to_de(rtwdev, phy); |
4365 | } |
4366 | |
4367 | static void rtw8852c_tssi_default_txagc(struct rtw89_dev *rtwdev, |
4368 | enum rtw89_phy_idx phy, bool enable) |
4369 | { |
4370 | struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; |
4371 | u8 i; |
4372 | |
4373 | if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) |
4374 | return; |
4375 | |
4376 | if (enable) { |
4377 | /* SCAN_START */ |
4378 | if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && |
4379 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { |
4380 | for (i = 0; i < 6; i++) { |
4381 | tssi_info->default_txagc_offset[RF_PATH_A] = |
4382 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, |
4383 | B_TXAGC_BB); |
4384 | if (tssi_info->default_txagc_offset[RF_PATH_A]) |
4385 | break; |
4386 | } |
4387 | } |
4388 | |
4389 | if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && |
4390 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { |
4391 | for (i = 0; i < 6; i++) { |
4392 | tssi_info->default_txagc_offset[RF_PATH_B] = |
4393 | rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, |
4394 | B_TXAGC_BB_S1); |
4395 | if (tssi_info->default_txagc_offset[RF_PATH_B]) |
4396 | break; |
4397 | } |
4398 | } |
4399 | } else { |
4400 | /* SCAN_END */ |
4401 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, |
4402 | data: tssi_info->default_txagc_offset[RF_PATH_A]); |
4403 | rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, |
4404 | data: tssi_info->default_txagc_offset[RF_PATH_B]); |
4405 | |
4406 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, data: 0x0); |
4407 | rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, data: 0x1); |
4408 | |
4409 | rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, data: 0x0); |
4410 | rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, data: 0x1); |
4411 | } |
4412 | } |
4413 | |
4414 | void rtw8852c_wifi_scan_notify(struct rtw89_dev *rtwdev, |
4415 | bool scan_start, enum rtw89_phy_idx phy_idx) |
4416 | { |
4417 | if (scan_start) |
4418 | rtw8852c_tssi_default_txagc(rtwdev, phy: phy_idx, enable: true); |
4419 | else |
4420 | rtw8852c_tssi_default_txagc(rtwdev, phy: phy_idx, enable: false); |
4421 | } |
4422 | |
4423 | void rtw8852c_rfk_chanctx_cb(struct rtw89_dev *rtwdev, |
4424 | enum rtw89_chanctx_state state) |
4425 | { |
4426 | struct rtw89_dpk_info *dpk = &rtwdev->dpk; |
4427 | u8 path; |
4428 | |
4429 | switch (state) { |
4430 | case RTW89_CHANCTX_STATE_MCC_START: |
4431 | dpk->is_dpk_enable = false; |
4432 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) |
4433 | _dpk_onoff(rtwdev, path, off: false); |
4434 | break; |
4435 | case RTW89_CHANCTX_STATE_MCC_STOP: |
4436 | dpk->is_dpk_enable = true; |
4437 | for (path = 0; path < RTW8852C_DPK_RF_PATH; path++) |
4438 | _dpk_onoff(rtwdev, path, off: false); |
4439 | rtw8852c_dpk(rtwdev, phy_idx: RTW89_PHY_0); |
4440 | break; |
4441 | default: |
4442 | break; |
4443 | } |
4444 | } |
4445 | |