16b069898SPing-Ke Shih // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
26b069898SPing-Ke Shih /* Copyright(c) 2019-2022 Realtek Corporation
36b069898SPing-Ke Shih */
46b069898SPing-Ke Shih
56b069898SPing-Ke Shih #include "coex.h"
66b069898SPing-Ke Shih #include "debug.h"
76b069898SPing-Ke Shih #include "mac.h"
86b069898SPing-Ke Shih #include "phy.h"
96b069898SPing-Ke Shih #include "reg.h"
106b069898SPing-Ke Shih #include "rtw8852b.h"
116b069898SPing-Ke Shih #include "rtw8852b_rfk.h"
126b069898SPing-Ke Shih #include "rtw8852b_rfk_table.h"
136b069898SPing-Ke Shih #include "rtw8852b_table.h"
146b069898SPing-Ke Shih
1521267107SPing-Ke Shih #define RTW8852B_RXDCK_VER 0x1
16f2abe804SPing-Ke Shih #define RTW8852B_IQK_VER 0x2a
17f2abe804SPing-Ke Shih #define RTW8852B_IQK_SS 2
18f2abe804SPing-Ke Shih #define RTW8852B_RXK_GROUP_NR 4
197f18a70dSPing-Ke Shih #define RTW8852B_TSSI_PATH_NR 2
205b8471acSPing-Ke Shih #define RTW8852B_RF_REL_VERSION 34
215b8471acSPing-Ke Shih #define RTW8852B_DPK_VER 0x0d
225b8471acSPing-Ke Shih #define RTW8852B_DPK_RF_PATH 2
23*150b7f9aSKuan-Chung Chen #define RTW8852B_DPK_KIP_REG_NUM 3
247f18a70dSPing-Ke Shih
257f18a70dSPing-Ke Shih #define _TSSI_DE_MASK GENMASK(21, 12)
2616be5e3bSPing-Ke Shih #define ADDC_T_AVG 100
275b8471acSPing-Ke Shih #define DPK_TXAGC_LOWER 0x2e
285b8471acSPing-Ke Shih #define DPK_TXAGC_UPPER 0x3f
295b8471acSPing-Ke Shih #define DPK_TXAGC_INVAL 0xff
305b8471acSPing-Ke Shih #define RFREG_MASKRXBB 0x003e0
315b8471acSPing-Ke Shih #define RFREG_MASKMODE 0xf0000
325b8471acSPing-Ke Shih
335b8471acSPing-Ke Shih enum rtw8852b_dpk_id {
345b8471acSPing-Ke Shih LBK_RXIQK = 0x06,
355b8471acSPing-Ke Shih SYNC = 0x10,
365b8471acSPing-Ke Shih MDPK_IDL = 0x11,
375b8471acSPing-Ke Shih MDPK_MPA = 0x12,
385b8471acSPing-Ke Shih GAIN_LOSS = 0x13,
395b8471acSPing-Ke Shih GAIN_CAL = 0x14,
405b8471acSPing-Ke Shih DPK_RXAGC = 0x15,
415b8471acSPing-Ke Shih KIP_PRESET = 0x16,
425b8471acSPing-Ke Shih KIP_RESTORE = 0x17,
435b8471acSPing-Ke Shih DPK_TXAGC = 0x19,
445b8471acSPing-Ke Shih D_KIP_PRESET = 0x28,
455b8471acSPing-Ke Shih D_TXAGC = 0x29,
465b8471acSPing-Ke Shih D_RXAGC = 0x2a,
475b8471acSPing-Ke Shih D_SYNC = 0x2b,
485b8471acSPing-Ke Shih D_GAIN_LOSS = 0x2c,
495b8471acSPing-Ke Shih D_MDPK_IDL = 0x2d,
505b8471acSPing-Ke Shih D_GAIN_NORM = 0x2f,
515b8471acSPing-Ke Shih D_KIP_THERMAL = 0x30,
525b8471acSPing-Ke Shih D_KIP_RESTORE = 0x31
535b8471acSPing-Ke Shih };
545b8471acSPing-Ke Shih
555b8471acSPing-Ke Shih enum dpk_agc_step {
565b8471acSPing-Ke Shih DPK_AGC_STEP_SYNC_DGAIN,
575b8471acSPing-Ke Shih DPK_AGC_STEP_GAIN_ADJ,
585b8471acSPing-Ke Shih DPK_AGC_STEP_GAIN_LOSS_IDX,
595b8471acSPing-Ke Shih DPK_AGC_STEP_GL_GT_CRITERION,
605b8471acSPing-Ke Shih DPK_AGC_STEP_GL_LT_CRITERION,
615b8471acSPing-Ke Shih DPK_AGC_STEP_SET_TX_GAIN,
625b8471acSPing-Ke Shih };
6316be5e3bSPing-Ke Shih
64f2abe804SPing-Ke Shih enum rtw8852b_iqk_type {
65f2abe804SPing-Ke Shih ID_TXAGC = 0x0,
66f2abe804SPing-Ke Shih ID_FLOK_COARSE = 0x1,
67f2abe804SPing-Ke Shih ID_FLOK_FINE = 0x2,
68f2abe804SPing-Ke Shih ID_TXK = 0x3,
69f2abe804SPing-Ke Shih ID_RXAGC = 0x4,
70f2abe804SPing-Ke Shih ID_RXK = 0x5,
71f2abe804SPing-Ke Shih ID_NBTXK = 0x6,
72f2abe804SPing-Ke Shih ID_NBRXK = 0x7,
73f2abe804SPing-Ke Shih ID_FLOK_VBUFFER = 0x8,
74f2abe804SPing-Ke Shih ID_A_FLOK_COARSE = 0x9,
75f2abe804SPing-Ke Shih ID_G_FLOK_COARSE = 0xa,
76f2abe804SPing-Ke Shih ID_A_FLOK_FINE = 0xb,
77f2abe804SPing-Ke Shih ID_G_FLOK_FINE = 0xc,
78f2abe804SPing-Ke Shih ID_IQK_RESTORE = 0x10,
79f2abe804SPing-Ke Shih };
80f2abe804SPing-Ke Shih
817f18a70dSPing-Ke Shih static const u32 _tssi_trigger[RTW8852B_TSSI_PATH_NR] = {0x5820, 0x7820};
827f18a70dSPing-Ke Shih static const u32 _tssi_cw_rpt_addr[RTW8852B_TSSI_PATH_NR] = {0x1c18, 0x3c18};
837f18a70dSPing-Ke Shih static const u32 _tssi_cw_default_addr[RTW8852B_TSSI_PATH_NR][4] = {
847f18a70dSPing-Ke Shih {0x5634, 0x5630, 0x5630, 0x5630},
857f18a70dSPing-Ke Shih {0x7634, 0x7630, 0x7630, 0x7630} };
867f18a70dSPing-Ke Shih static const u32 _tssi_cw_default_mask[4] = {
877f18a70dSPing-Ke Shih 0x000003ff, 0x3ff00000, 0x000ffc00, 0x000003ff};
887f18a70dSPing-Ke Shih static const u32 _tssi_de_cck_long[RF_PATH_NUM_8852B] = {0x5858, 0x7858};
897f18a70dSPing-Ke Shih static const u32 _tssi_de_cck_short[RF_PATH_NUM_8852B] = {0x5860, 0x7860};
907f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8852B] = {0x5838, 0x7838};
917f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8852B] = {0x5840, 0x7840};
927f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8852B] = {0x5848, 0x7848};
937f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8852B] = {0x5850, 0x7850};
947f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8852B] = {0x5828, 0x7828};
957f18a70dSPing-Ke Shih static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8852B] = {0x5830, 0x7830};
96f2abe804SPing-Ke Shih static const u32 _a_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x190, 0x198, 0x350, 0x352};
97f2abe804SPing-Ke Shih static const u32 _a_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x0f, 0x0f, 0x3f, 0x7f};
98f2abe804SPing-Ke Shih static const u32 _a_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x1, 0x0, 0x0};
99f2abe804SPing-Ke Shih static const u32 _g_idxrxgain[RTW8852B_RXK_GROUP_NR] = {0x212, 0x21c, 0x350, 0x360};
100f2abe804SPing-Ke Shih static const u32 _g_idxattc2[RTW8852B_RXK_GROUP_NR] = {0x00, 0x00, 0x28, 0x5f};
101f2abe804SPing-Ke Shih static const u32 _g_idxattc1[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x2, 0x1};
102f2abe804SPing-Ke Shih static const u32 _a_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0};
103f2abe804SPing-Ke Shih static const u32 _a_track_range[RTW8852B_RXK_GROUP_NR] = {0x3, 0x3, 0x6, 0x6};
104f2abe804SPing-Ke Shih static const u32 _a_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e};
105f2abe804SPing-Ke Shih static const u32 _a_itqt[RTW8852B_RXK_GROUP_NR] = {0x12, 0x12, 0x12, 0x1b};
106f2abe804SPing-Ke Shih static const u32 _g_power_range[RTW8852B_RXK_GROUP_NR] = {0x0, 0x0, 0x0, 0x0};
107f2abe804SPing-Ke Shih static const u32 _g_track_range[RTW8852B_RXK_GROUP_NR] = {0x4, 0x4, 0x6, 0x6};
108f2abe804SPing-Ke Shih static const u32 _g_gain_bb[RTW8852B_RXK_GROUP_NR] = {0x08, 0x0e, 0x06, 0x0e};
109f2abe804SPing-Ke Shih static const u32 _g_itqt[RTW8852B_RXK_GROUP_NR] = {0x09, 0x12, 0x1b, 0x24};
110f2abe804SPing-Ke Shih
111f2abe804SPing-Ke Shih static const u32 rtw8852b_backup_bb_regs[] = {0x2344, 0x5800, 0x7800};
112f2abe804SPing-Ke Shih static const u32 rtw8852b_backup_rf_regs[] = {
113f2abe804SPing-Ke Shih 0xde, 0xdf, 0x8b, 0x90, 0x97, 0x85, 0x1e, 0x0, 0x2, 0x5, 0x10005
114f2abe804SPing-Ke Shih };
115f2abe804SPing-Ke Shih
116f2abe804SPing-Ke Shih #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852b_backup_bb_regs)
117f2abe804SPing-Ke Shih #define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852b_backup_rf_regs)
118f2abe804SPing-Ke Shih
119f2abe804SPing-Ke Shih static const struct rtw89_reg3_def rtw8852b_set_nondbcc_path01[] = {
120f2abe804SPing-Ke Shih {0x20fc, 0xffff0000, 0x0303},
121f2abe804SPing-Ke Shih {0x5864, 0x18000000, 0x3},
122f2abe804SPing-Ke Shih {0x7864, 0x18000000, 0x3},
123f2abe804SPing-Ke Shih {0x12b8, 0x40000000, 0x1},
124f2abe804SPing-Ke Shih {0x32b8, 0x40000000, 0x1},
125f2abe804SPing-Ke Shih {0x030c, 0xff000000, 0x13},
126f2abe804SPing-Ke Shih {0x032c, 0xffff0000, 0x0041},
127f2abe804SPing-Ke Shih {0x12b8, 0x10000000, 0x1},
128f2abe804SPing-Ke Shih {0x58c8, 0x01000000, 0x1},
129f2abe804SPing-Ke Shih {0x78c8, 0x01000000, 0x1},
130f2abe804SPing-Ke Shih {0x5864, 0xc0000000, 0x3},
131f2abe804SPing-Ke Shih {0x7864, 0xc0000000, 0x3},
132f2abe804SPing-Ke Shih {0x2008, 0x01ffffff, 0x1ffffff},
133f2abe804SPing-Ke Shih {0x0c1c, 0x00000004, 0x1},
134f2abe804SPing-Ke Shih {0x0700, 0x08000000, 0x1},
135f2abe804SPing-Ke Shih {0x0c70, 0x000003ff, 0x3ff},
136f2abe804SPing-Ke Shih {0x0c60, 0x00000003, 0x3},
137f2abe804SPing-Ke Shih {0x0c6c, 0x00000001, 0x1},
138f2abe804SPing-Ke Shih {0x58ac, 0x08000000, 0x1},
139f2abe804SPing-Ke Shih {0x78ac, 0x08000000, 0x1},
140f2abe804SPing-Ke Shih {0x0c3c, 0x00000200, 0x1},
141f2abe804SPing-Ke Shih {0x2344, 0x80000000, 0x1},
142f2abe804SPing-Ke Shih {0x4490, 0x80000000, 0x1},
143f2abe804SPing-Ke Shih {0x12a0, 0x00007000, 0x7},
144f2abe804SPing-Ke Shih {0x12a0, 0x00008000, 0x1},
145f2abe804SPing-Ke Shih {0x12a0, 0x00070000, 0x3},
146f2abe804SPing-Ke Shih {0x12a0, 0x00080000, 0x1},
147f2abe804SPing-Ke Shih {0x32a0, 0x00070000, 0x3},
148f2abe804SPing-Ke Shih {0x32a0, 0x00080000, 0x1},
149f2abe804SPing-Ke Shih {0x0700, 0x01000000, 0x1},
150f2abe804SPing-Ke Shih {0x0700, 0x06000000, 0x2},
151f2abe804SPing-Ke Shih {0x20fc, 0xffff0000, 0x3333},
152f2abe804SPing-Ke Shih };
153f2abe804SPing-Ke Shih
154f2abe804SPing-Ke Shih static const struct rtw89_reg3_def rtw8852b_restore_nondbcc_path01[] = {
155f2abe804SPing-Ke Shih {0x20fc, 0xffff0000, 0x0303},
156f2abe804SPing-Ke Shih {0x12b8, 0x40000000, 0x0},
157f2abe804SPing-Ke Shih {0x32b8, 0x40000000, 0x0},
158f2abe804SPing-Ke Shih {0x5864, 0xc0000000, 0x0},
159f2abe804SPing-Ke Shih {0x7864, 0xc0000000, 0x0},
160f2abe804SPing-Ke Shih {0x2008, 0x01ffffff, 0x0000000},
161f2abe804SPing-Ke Shih {0x0c1c, 0x00000004, 0x0},
162f2abe804SPing-Ke Shih {0x0700, 0x08000000, 0x0},
163f2abe804SPing-Ke Shih {0x0c70, 0x0000001f, 0x03},
164f2abe804SPing-Ke Shih {0x0c70, 0x000003e0, 0x03},
165f2abe804SPing-Ke Shih {0x12a0, 0x000ff000, 0x00},
166f2abe804SPing-Ke Shih {0x32a0, 0x000ff000, 0x00},
167f2abe804SPing-Ke Shih {0x0700, 0x07000000, 0x0},
168f2abe804SPing-Ke Shih {0x20fc, 0xffff0000, 0x0000},
169f2abe804SPing-Ke Shih {0x58c8, 0x01000000, 0x0},
170f2abe804SPing-Ke Shih {0x78c8, 0x01000000, 0x0},
171f2abe804SPing-Ke Shih {0x0c3c, 0x00000200, 0x0},
172f2abe804SPing-Ke Shih {0x2344, 0x80000000, 0x0},
173f2abe804SPing-Ke Shih };
174f2abe804SPing-Ke Shih
_rfk_backup_bb_reg(struct rtw89_dev * rtwdev,u32 backup_bb_reg_val[])175f2abe804SPing-Ke Shih static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[])
176f2abe804SPing-Ke Shih {
177f2abe804SPing-Ke Shih u32 i;
178f2abe804SPing-Ke Shih
179f2abe804SPing-Ke Shih for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
180f2abe804SPing-Ke Shih backup_bb_reg_val[i] =
181f2abe804SPing-Ke Shih rtw89_phy_read32_mask(rtwdev, rtw8852b_backup_bb_regs[i],
182f2abe804SPing-Ke Shih MASKDWORD);
183f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
184f2abe804SPing-Ke Shih "[RFK]backup bb reg : %x, value =%x\n",
185f2abe804SPing-Ke Shih rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]);
186f2abe804SPing-Ke Shih }
187f2abe804SPing-Ke Shih }
188f2abe804SPing-Ke Shih
_rfk_backup_rf_reg(struct rtw89_dev * rtwdev,u32 backup_rf_reg_val[],u8 rf_path)189f2abe804SPing-Ke Shih static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[],
190f2abe804SPing-Ke Shih u8 rf_path)
191f2abe804SPing-Ke Shih {
192f2abe804SPing-Ke Shih u32 i;
193f2abe804SPing-Ke Shih
194f2abe804SPing-Ke Shih for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
195f2abe804SPing-Ke Shih backup_rf_reg_val[i] =
196f2abe804SPing-Ke Shih rtw89_read_rf(rtwdev, rf_path,
197f2abe804SPing-Ke Shih rtw8852b_backup_rf_regs[i], RFREG_MASK);
198f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
199f2abe804SPing-Ke Shih "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path,
200f2abe804SPing-Ke Shih rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]);
201f2abe804SPing-Ke Shih }
202f2abe804SPing-Ke Shih }
203f2abe804SPing-Ke Shih
_rfk_restore_bb_reg(struct rtw89_dev * rtwdev,const u32 backup_bb_reg_val[])204f2abe804SPing-Ke Shih static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev,
205f2abe804SPing-Ke Shih const u32 backup_bb_reg_val[])
206f2abe804SPing-Ke Shih {
207f2abe804SPing-Ke Shih u32 i;
208f2abe804SPing-Ke Shih
209f2abe804SPing-Ke Shih for (i = 0; i < BACKUP_BB_REGS_NR; i++) {
210f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, rtw8852b_backup_bb_regs[i],
211f2abe804SPing-Ke Shih MASKDWORD, backup_bb_reg_val[i]);
212f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
213f2abe804SPing-Ke Shih "[RFK]restore bb reg : %x, value =%x\n",
214f2abe804SPing-Ke Shih rtw8852b_backup_bb_regs[i], backup_bb_reg_val[i]);
215f2abe804SPing-Ke Shih }
216f2abe804SPing-Ke Shih }
217f2abe804SPing-Ke Shih
_rfk_restore_rf_reg(struct rtw89_dev * rtwdev,const u32 backup_rf_reg_val[],u8 rf_path)218f2abe804SPing-Ke Shih static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev,
219f2abe804SPing-Ke Shih const u32 backup_rf_reg_val[], u8 rf_path)
220f2abe804SPing-Ke Shih {
221f2abe804SPing-Ke Shih u32 i;
222f2abe804SPing-Ke Shih
223f2abe804SPing-Ke Shih for (i = 0; i < BACKUP_RF_REGS_NR; i++) {
224f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, rf_path, rtw8852b_backup_rf_regs[i],
225f2abe804SPing-Ke Shih RFREG_MASK, backup_rf_reg_val[i]);
226f2abe804SPing-Ke Shih
227f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
228f2abe804SPing-Ke Shih "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path,
229f2abe804SPing-Ke Shih rtw8852b_backup_rf_regs[i], backup_rf_reg_val[i]);
230f2abe804SPing-Ke Shih }
231f2abe804SPing-Ke Shih }
232f2abe804SPing-Ke Shih
_rfk_rf_direct_cntrl(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,bool is_bybb)2335b8471acSPing-Ke Shih static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev,
2345b8471acSPing-Ke Shih enum rtw89_rf_path path, bool is_bybb)
2355b8471acSPing-Ke Shih {
2365b8471acSPing-Ke Shih if (is_bybb)
2375b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1);
2385b8471acSPing-Ke Shih else
2395b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
2405b8471acSPing-Ke Shih }
2415b8471acSPing-Ke Shih
_rfk_drf_direct_cntrl(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,bool is_bybb)2425b8471acSPing-Ke Shih static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev,
2435b8471acSPing-Ke Shih enum rtw89_rf_path path, bool is_bybb)
2445b8471acSPing-Ke Shih {
2455b8471acSPing-Ke Shih if (is_bybb)
2465b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1);
2475b8471acSPing-Ke Shih else
2485b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0);
2495b8471acSPing-Ke Shih }
2505b8471acSPing-Ke Shih
_iqk_check_cal(struct rtw89_dev * rtwdev,u8 path)251f2abe804SPing-Ke Shih static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path)
252f2abe804SPing-Ke Shih {
253f2abe804SPing-Ke Shih bool fail = true;
254f2abe804SPing-Ke Shih u32 val;
255f2abe804SPing-Ke Shih int ret;
256f2abe804SPing-Ke Shih
257f2abe804SPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
258f2abe804SPing-Ke Shih 1, 8200, false, rtwdev, 0xbff8, MASKBYTE0);
259f2abe804SPing-Ke Shih if (ret)
260f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]NCTL1 IQK timeout!!!\n");
261f2abe804SPing-Ke Shih
262f2abe804SPing-Ke Shih udelay(200);
263f2abe804SPing-Ke Shih
264f2abe804SPing-Ke Shih if (!ret)
265f2abe804SPing-Ke Shih fail = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG);
266f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0);
267f2abe804SPing-Ke Shih
268f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret);
269f2abe804SPing-Ke Shih val = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD);
270f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8008 = 0x%x\n", path, val);
271f2abe804SPing-Ke Shih
272f2abe804SPing-Ke Shih return fail;
273f2abe804SPing-Ke Shih }
274f2abe804SPing-Ke Shih
_kpath(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)2756b069898SPing-Ke Shih static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
2766b069898SPing-Ke Shih {
2776b069898SPing-Ke Shih u8 val;
2786b069898SPing-Ke Shih
2796b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x,PHY%d\n",
2806b069898SPing-Ke Shih rtwdev->dbcc_en, phy_idx);
2816b069898SPing-Ke Shih
2826b069898SPing-Ke Shih if (!rtwdev->dbcc_en) {
2836b069898SPing-Ke Shih val = RF_AB;
2846b069898SPing-Ke Shih } else {
2856b069898SPing-Ke Shih if (phy_idx == RTW89_PHY_0)
2866b069898SPing-Ke Shih val = RF_A;
2876b069898SPing-Ke Shih else
2886b069898SPing-Ke Shih val = RF_B;
2896b069898SPing-Ke Shih }
2906b069898SPing-Ke Shih return val;
2916b069898SPing-Ke Shih }
2926b069898SPing-Ke Shih
_set_rx_dck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)29321267107SPing-Ke Shih static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
29421267107SPing-Ke Shih enum rtw89_rf_path path)
29521267107SPing-Ke Shih {
29621267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_CLR, 0x0);
29721267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0);
29821267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1);
29921267107SPing-Ke Shih mdelay(1);
30021267107SPing-Ke Shih }
30121267107SPing-Ke Shih
_rx_dck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)30221267107SPing-Ke Shih static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
30321267107SPing-Ke Shih {
30421267107SPing-Ke Shih u8 path, dck_tune;
30521267107SPing-Ke Shih u32 rf_reg5;
30621267107SPing-Ke Shih
30721267107SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
30821267107SPing-Ke Shih "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, CV : 0x%x) ******\n",
30921267107SPing-Ke Shih RTW8852B_RXDCK_VER, rtwdev->hal.cv);
31021267107SPing-Ke Shih
31121267107SPing-Ke Shih for (path = 0; path < RF_PATH_NUM_8852B; path++) {
31221267107SPing-Ke Shih rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
31321267107SPing-Ke Shih dck_tune = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE);
31421267107SPing-Ke Shih
31521267107SPing-Ke Shih if (rtwdev->is_tssi_mode[path])
31621267107SPing-Ke Shih rtw89_phy_write32_mask(rtwdev,
31721267107SPing-Ke Shih R_P0_TSSI_TRK + (path << 13),
31821267107SPing-Ke Shih B_P0_TSSI_TRK_EN, 0x1);
31921267107SPing-Ke Shih
32021267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
32121267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0);
32221267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
32321267107SPing-Ke Shih _set_rx_dck(rtwdev, phy, path);
32421267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune);
32521267107SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
32621267107SPing-Ke Shih
32721267107SPing-Ke Shih if (rtwdev->is_tssi_mode[path])
32821267107SPing-Ke Shih rtw89_phy_write32_mask(rtwdev,
32921267107SPing-Ke Shih R_P0_TSSI_TRK + (path << 13),
33021267107SPing-Ke Shih B_P0_TSSI_TRK_EN, 0x0);
33121267107SPing-Ke Shih }
33221267107SPing-Ke Shih }
33321267107SPing-Ke Shih
_rck(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)33410298b53SPing-Ke Shih static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
33510298b53SPing-Ke Shih {
33610298b53SPing-Ke Shih u32 rf_reg5;
33710298b53SPing-Ke Shih u32 rck_val;
33810298b53SPing-Ke Shih u32 val;
33910298b53SPing-Ke Shih int ret;
34010298b53SPing-Ke Shih
34110298b53SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path);
34210298b53SPing-Ke Shih
34310298b53SPing-Ke Shih rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK);
34410298b53SPing-Ke Shih
34510298b53SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
34610298b53SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
34710298b53SPing-Ke Shih
34810298b53SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n",
34910298b53SPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK));
35010298b53SPing-Ke Shih
35110298b53SPing-Ke Shih /* RCK trigger */
35210298b53SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240);
35310298b53SPing-Ke Shih
35410298b53SPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30,
35510298b53SPing-Ke Shih false, rtwdev, path, RR_RCKS, BIT(3));
35610298b53SPing-Ke Shih
35710298b53SPing-Ke Shih rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA);
35810298b53SPing-Ke Shih
35910298b53SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n",
36010298b53SPing-Ke Shih rck_val, ret);
36110298b53SPing-Ke Shih
36210298b53SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val);
36310298b53SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5);
36410298b53SPing-Ke Shih
36510298b53SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n",
36610298b53SPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK));
36710298b53SPing-Ke Shih }
36810298b53SPing-Ke Shih
_afe_init(struct rtw89_dev * rtwdev)36916be5e3bSPing-Ke Shih static void _afe_init(struct rtw89_dev *rtwdev)
37016be5e3bSPing-Ke Shih {
37116be5e3bSPing-Ke Shih rtw89_write32(rtwdev, R_AX_PHYREG_SET, 0xf);
37216be5e3bSPing-Ke Shih
37316be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_afe_init_defs_tbl);
37416be5e3bSPing-Ke Shih }
37516be5e3bSPing-Ke Shih
_drck(struct rtw89_dev * rtwdev)37616be5e3bSPing-Ke Shih static void _drck(struct rtw89_dev *rtwdev)
37716be5e3bSPing-Ke Shih {
37816be5e3bSPing-Ke Shih u32 rck_d;
37916be5e3bSPing-Ke Shih u32 val;
38016be5e3bSPing-Ke Shih int ret;
38116be5e3bSPing-Ke Shih
38216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n");
38316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x1);
38416be5e3bSPing-Ke Shih
38516be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
38616be5e3bSPing-Ke Shih false, rtwdev, R_DRCK_RS, B_DRCK_RS_DONE);
38716be5e3bSPing-Ke Shih if (ret)
38816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n");
38916be5e3bSPing-Ke Shih
39016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_KICK, 0x0);
39116be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1);
39216be5e3bSPing-Ke Shih udelay(1);
39316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0);
39416be5e3bSPing-Ke Shih rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RS, B_DRCK_RS_LPS);
39516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_SEL, 0x0);
39616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DRCK_V1, B_DRCK_V1_CV, rck_d);
39716be5e3bSPing-Ke Shih
39816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0cc = 0x%x\n",
39916be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DRCK_V1, MASKDWORD));
40016be5e3bSPing-Ke Shih }
40116be5e3bSPing-Ke Shih
_addck_backup(struct rtw89_dev * rtwdev)40216be5e3bSPing-Ke Shih static void _addck_backup(struct rtw89_dev *rtwdev)
40316be5e3bSPing-Ke Shih {
40416be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
40516be5e3bSPing-Ke Shih
40616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0);
40716be5e3bSPing-Ke Shih dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0);
40816be5e3bSPing-Ke Shih dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1);
40916be5e3bSPing-Ke Shih
41016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x0);
41116be5e3bSPing-Ke Shih dack->addck_d[1][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A0);
41216be5e3bSPing-Ke Shih dack->addck_d[1][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR1, B_ADDCKR1_A1);
41316be5e3bSPing-Ke Shih }
41416be5e3bSPing-Ke Shih
_addck_reload(struct rtw89_dev * rtwdev)41516be5e3bSPing-Ke Shih static void _addck_reload(struct rtw89_dev *rtwdev)
41616be5e3bSPing-Ke Shih {
41716be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
41816be5e3bSPing-Ke Shih
41916be5e3bSPing-Ke Shih /* S0 */
42016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL, dack->addck_d[0][0]);
42116be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_VAL, dack->addck_d[0][1] >> 6);
42216be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0D, B_ADDCK0D_VAL2, dack->addck_d[0][1] & 0x3f);
42316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x3);
42416be5e3bSPing-Ke Shih
42516be5e3bSPing-Ke Shih /* S1 */
42616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL, dack->addck_d[1][0]);
42716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK0_VAL, dack->addck_d[1][1] >> 6);
42816be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1D, B_ADDCK1D_VAL2, dack->addck_d[1][1] & 0x3f);
42916be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_MAN, 0x3);
43016be5e3bSPing-Ke Shih }
43116be5e3bSPing-Ke Shih
_dack_backup_s0(struct rtw89_dev * rtwdev)43216be5e3bSPing-Ke Shih static void _dack_backup_s0(struct rtw89_dev *rtwdev)
43316be5e3bSPing-Ke Shih {
43416be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
43516be5e3bSPing-Ke Shih u8 i;
43616be5e3bSPing-Ke Shih
43716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
43816be5e3bSPing-Ke Shih
43916be5e3bSPing-Ke Shih for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
44016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i);
44116be5e3bSPing-Ke Shih dack->msbk_d[0][0][i] =
44216be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0);
44316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i);
44416be5e3bSPing-Ke Shih dack->msbk_d[0][1][i] =
44516be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1);
44616be5e3bSPing-Ke Shih }
44716be5e3bSPing-Ke Shih
44816be5e3bSPing-Ke Shih dack->biask_d[0][0] =
44916be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00);
45016be5e3bSPing-Ke Shih dack->biask_d[0][1] =
45116be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01);
45216be5e3bSPing-Ke Shih
45316be5e3bSPing-Ke Shih dack->dadck_d[0][0] =
45416be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00);
45516be5e3bSPing-Ke Shih dack->dadck_d[0][1] =
45616be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01);
45716be5e3bSPing-Ke Shih }
45816be5e3bSPing-Ke Shih
_dack_backup_s1(struct rtw89_dev * rtwdev)45916be5e3bSPing-Ke Shih static void _dack_backup_s1(struct rtw89_dev *rtwdev)
46016be5e3bSPing-Ke Shih {
46116be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
46216be5e3bSPing-Ke Shih u8 i;
46316be5e3bSPing-Ke Shih
46416be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
46516be5e3bSPing-Ke Shih
46616be5e3bSPing-Ke Shih for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
46716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DACK10, B_DACK10, i);
46816be5e3bSPing-Ke Shih dack->msbk_d[1][0][i] =
46916be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK10S);
47016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DACK11, B_DACK11, i);
47116be5e3bSPing-Ke Shih dack->msbk_d[1][1][i] =
47216be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK11S);
47316be5e3bSPing-Ke Shih }
47416be5e3bSPing-Ke Shih
47516be5e3bSPing-Ke Shih dack->biask_d[1][0] =
47616be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS10, B_DACK_BIAS10);
47716be5e3bSPing-Ke Shih dack->biask_d[1][1] =
47816be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS11, B_DACK_BIAS11);
47916be5e3bSPing-Ke Shih
48016be5e3bSPing-Ke Shih dack->dadck_d[1][0] =
48116be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK10, B_DACK_DADCK10);
48216be5e3bSPing-Ke Shih dack->dadck_d[1][1] =
48316be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK11, B_DACK_DADCK11);
48416be5e3bSPing-Ke Shih }
48516be5e3bSPing-Ke Shih
_check_addc(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)48616be5e3bSPing-Ke Shih static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
48716be5e3bSPing-Ke Shih {
48816be5e3bSPing-Ke Shih s32 dc_re = 0, dc_im = 0;
48916be5e3bSPing-Ke Shih u32 tmp;
49016be5e3bSPing-Ke Shih u32 i;
49116be5e3bSPing-Ke Shih
49216be5e3bSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
49316be5e3bSPing-Ke Shih &rtw8852b_check_addc_defs_a_tbl,
49416be5e3bSPing-Ke Shih &rtw8852b_check_addc_defs_b_tbl);
49516be5e3bSPing-Ke Shih
49616be5e3bSPing-Ke Shih for (i = 0; i < ADDC_T_AVG; i++) {
49716be5e3bSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD);
49816be5e3bSPing-Ke Shih dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), 11);
49916be5e3bSPing-Ke Shih dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11);
50016be5e3bSPing-Ke Shih }
50116be5e3bSPing-Ke Shih
50216be5e3bSPing-Ke Shih dc_re /= ADDC_T_AVG;
50316be5e3bSPing-Ke Shih dc_im /= ADDC_T_AVG;
50416be5e3bSPing-Ke Shih
50516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
50616be5e3bSPing-Ke Shih "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im);
50716be5e3bSPing-Ke Shih }
50816be5e3bSPing-Ke Shih
_addck(struct rtw89_dev * rtwdev)50916be5e3bSPing-Ke Shih static void _addck(struct rtw89_dev *rtwdev)
51016be5e3bSPing-Ke Shih {
51116be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
51216be5e3bSPing-Ke Shih u32 val;
51316be5e3bSPing-Ke Shih int ret;
51416be5e3bSPing-Ke Shih
51516be5e3bSPing-Ke Shih /* S0 */
51616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_MAN, 0x0);
51716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, 0x30, 0x0);
51816be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
51916be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0);
52016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0);
52116be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1);
52216be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf);
52316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0);
52416be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x1);
52516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3);
52616be5e3bSPing-Ke Shih
52716be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n");
52816be5e3bSPing-Ke Shih _check_addc(rtwdev, RF_PATH_A);
52916be5e3bSPing-Ke Shih
53016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x1);
53116be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_TRG, 0x0);
53216be5e3bSPing-Ke Shih udelay(1);
53316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1);
53416be5e3bSPing-Ke Shih
53516be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
53616be5e3bSPing-Ke Shih false, rtwdev, R_ADDCKR0, BIT(0));
53716be5e3bSPing-Ke Shih if (ret) {
53816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n");
53916be5e3bSPing-Ke Shih dack->addck_timeout[0] = true;
54016be5e3bSPing-Ke Shih }
54116be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret);
54216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n");
54316be5e3bSPing-Ke Shih _check_addc(rtwdev, RF_PATH_A);
54416be5e3bSPing-Ke Shih
54516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH0_SAMPL_DLY_T_V1, BIT(1), 0x0);
54616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1);
54716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc);
54816be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1);
54916be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
55016be5e3bSPing-Ke Shih
55116be5e3bSPing-Ke Shih /* S1 */
55216be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
55316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x0);
55416be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0);
55516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1);
55616be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xf);
55716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x0);
55816be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x1);
55916be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3);
56016be5e3bSPing-Ke Shih
56116be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n");
56216be5e3bSPing-Ke Shih _check_addc(rtwdev, RF_PATH_B);
56316be5e3bSPing-Ke Shih
56416be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x1);
56516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1_TRG, 0x0);
56616be5e3bSPing-Ke Shih udelay(1);
56716be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ADDCK1, B_ADDCK1, 0x1);
56816be5e3bSPing-Ke Shih
56916be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000,
57016be5e3bSPing-Ke Shih false, rtwdev, R_ADDCKR1, BIT(0));
57116be5e3bSPing-Ke Shih if (ret) {
57216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n");
57316be5e3bSPing-Ke Shih dack->addck_timeout[1] = true;
57416be5e3bSPing-Ke Shih }
57516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret);
57616be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n");
57716be5e3bSPing-Ke Shih _check_addc(rtwdev, RF_PATH_B);
57816be5e3bSPing-Ke Shih
57916be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH1_SAMPL_DLY_T_V1, BIT(1), 0x0);
58016be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_EN, 0x1);
58116be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0xc);
58216be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK, 0x1);
58316be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
58416be5e3bSPing-Ke Shih }
58516be5e3bSPing-Ke Shih
_check_dadc(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)58616be5e3bSPing-Ke Shih static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
58716be5e3bSPing-Ke Shih {
58816be5e3bSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
58916be5e3bSPing-Ke Shih &rtw8852b_check_dadc_en_defs_a_tbl,
59016be5e3bSPing-Ke Shih &rtw8852b_check_dadc_en_defs_b_tbl);
59116be5e3bSPing-Ke Shih
59216be5e3bSPing-Ke Shih _check_addc(rtwdev, path);
59316be5e3bSPing-Ke Shih
59416be5e3bSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
59516be5e3bSPing-Ke Shih &rtw8852b_check_dadc_dis_defs_a_tbl,
59616be5e3bSPing-Ke Shih &rtw8852b_check_dadc_dis_defs_b_tbl);
59716be5e3bSPing-Ke Shih }
59816be5e3bSPing-Ke Shih
_dack_s0_check_done(struct rtw89_dev * rtwdev,bool part1)59916be5e3bSPing-Ke Shih static bool _dack_s0_check_done(struct rtw89_dev *rtwdev, bool part1)
60016be5e3bSPing-Ke Shih {
60116be5e3bSPing-Ke Shih if (part1) {
60216be5e3bSPing-Ke Shih if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 ||
60316be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0)
60416be5e3bSPing-Ke Shih return false;
60516be5e3bSPing-Ke Shih } else {
60616be5e3bSPing-Ke Shih if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 ||
60716be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0)
60816be5e3bSPing-Ke Shih return false;
60916be5e3bSPing-Ke Shih }
61016be5e3bSPing-Ke Shih
61116be5e3bSPing-Ke Shih return true;
61216be5e3bSPing-Ke Shih }
61316be5e3bSPing-Ke Shih
_dack_s0(struct rtw89_dev * rtwdev)61416be5e3bSPing-Ke Shih static void _dack_s0(struct rtw89_dev *rtwdev)
61516be5e3bSPing-Ke Shih {
61616be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
61716be5e3bSPing-Ke Shih bool done;
61816be5e3bSPing-Ke Shih int ret;
61916be5e3bSPing-Ke Shih
62016be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_1_defs_tbl);
62116be5e3bSPing-Ke Shih
62216be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000,
62316be5e3bSPing-Ke Shih false, rtwdev, true);
62416be5e3bSPing-Ke Shih if (ret) {
62516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n");
62616be5e3bSPing-Ke Shih dack->msbk_timeout[0] = true;
62716be5e3bSPing-Ke Shih }
62816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret);
62916be5e3bSPing-Ke Shih
63016be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_2_defs_tbl);
63116be5e3bSPing-Ke Shih
63216be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(_dack_s0_check_done, done, done, 1, 10000,
63316be5e3bSPing-Ke Shih false, rtwdev, false);
63416be5e3bSPing-Ke Shih if (ret) {
63516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n");
63616be5e3bSPing-Ke Shih dack->dadck_timeout[0] = true;
63716be5e3bSPing-Ke Shih }
63816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret);
63916be5e3bSPing-Ke Shih
64016be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s0_3_defs_tbl);
64116be5e3bSPing-Ke Shih
64216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n");
64316be5e3bSPing-Ke Shih
64416be5e3bSPing-Ke Shih _dack_backup_s0(rtwdev);
64516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0);
64616be5e3bSPing-Ke Shih }
64716be5e3bSPing-Ke Shih
_dack_s1_check_done(struct rtw89_dev * rtwdev,bool part1)64816be5e3bSPing-Ke Shih static bool _dack_s1_check_done(struct rtw89_dev *rtwdev, bool part1)
64916be5e3bSPing-Ke Shih {
65016be5e3bSPing-Ke Shih if (part1) {
65116be5e3bSPing-Ke Shih if (rtw89_phy_read32_mask(rtwdev, R_DACK_S1P0, B_DACK_S1P0_OK) == 0 &&
65216be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK_S1P1, B_DACK_S1P1_OK) == 0)
65316be5e3bSPing-Ke Shih return false;
65416be5e3bSPing-Ke Shih } else {
65516be5e3bSPing-Ke Shih if (rtw89_phy_read32_mask(rtwdev, R_DACK10S, B_DACK_S1P2_OK) == 0 &&
65616be5e3bSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_DACK11S, B_DACK_S1P3_OK) == 0)
65716be5e3bSPing-Ke Shih return false;
65816be5e3bSPing-Ke Shih }
65916be5e3bSPing-Ke Shih
66016be5e3bSPing-Ke Shih return true;
66116be5e3bSPing-Ke Shih }
66216be5e3bSPing-Ke Shih
_dack_s1(struct rtw89_dev * rtwdev)66316be5e3bSPing-Ke Shih static void _dack_s1(struct rtw89_dev *rtwdev)
66416be5e3bSPing-Ke Shih {
66516be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
66616be5e3bSPing-Ke Shih bool done;
66716be5e3bSPing-Ke Shih int ret;
66816be5e3bSPing-Ke Shih
66916be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_1_defs_tbl);
67016be5e3bSPing-Ke Shih
67116be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000,
67216be5e3bSPing-Ke Shih false, rtwdev, true);
67316be5e3bSPing-Ke Shih if (ret) {
67416be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n");
67516be5e3bSPing-Ke Shih dack->msbk_timeout[1] = true;
67616be5e3bSPing-Ke Shih }
67716be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret);
67816be5e3bSPing-Ke Shih
67916be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_2_defs_tbl);
68016be5e3bSPing-Ke Shih
68116be5e3bSPing-Ke Shih ret = read_poll_timeout_atomic(_dack_s1_check_done, done, done, 1, 10000,
68216be5e3bSPing-Ke Shih false, rtwdev, false);
68316be5e3bSPing-Ke Shih if (ret) {
68416be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n");
68516be5e3bSPing-Ke Shih dack->dadck_timeout[1] = true;
68616be5e3bSPing-Ke Shih }
68716be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret);
68816be5e3bSPing-Ke Shih
68916be5e3bSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dack_s1_3_defs_tbl);
69016be5e3bSPing-Ke Shih
69116be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n");
69216be5e3bSPing-Ke Shih
69316be5e3bSPing-Ke Shih _check_dadc(rtwdev, RF_PATH_B);
69416be5e3bSPing-Ke Shih _dack_backup_s1(rtwdev);
69516be5e3bSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x0);
69616be5e3bSPing-Ke Shih }
69716be5e3bSPing-Ke Shih
_dack(struct rtw89_dev * rtwdev)69816be5e3bSPing-Ke Shih static void _dack(struct rtw89_dev *rtwdev)
69916be5e3bSPing-Ke Shih {
70016be5e3bSPing-Ke Shih _dack_s0(rtwdev);
70116be5e3bSPing-Ke Shih _dack_s1(rtwdev);
70216be5e3bSPing-Ke Shih }
70316be5e3bSPing-Ke Shih
_dack_dump(struct rtw89_dev * rtwdev)70416be5e3bSPing-Ke Shih static void _dack_dump(struct rtw89_dev *rtwdev)
70516be5e3bSPing-Ke Shih {
70616be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
70716be5e3bSPing-Ke Shih u8 i;
70816be5e3bSPing-Ke Shih u8 t;
70916be5e3bSPing-Ke Shih
71016be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
71116be5e3bSPing-Ke Shih "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n",
71216be5e3bSPing-Ke Shih dack->addck_d[0][0], dack->addck_d[0][1]);
71316be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
71416be5e3bSPing-Ke Shih "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n",
71516be5e3bSPing-Ke Shih dack->addck_d[1][0], dack->addck_d[1][1]);
71616be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
71716be5e3bSPing-Ke Shih "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n",
71816be5e3bSPing-Ke Shih dack->dadck_d[0][0], dack->dadck_d[0][1]);
71916be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
72016be5e3bSPing-Ke Shih "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n",
72116be5e3bSPing-Ke Shih dack->dadck_d[1][0], dack->dadck_d[1][1]);
72216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
72316be5e3bSPing-Ke Shih "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n",
72416be5e3bSPing-Ke Shih dack->biask_d[0][0], dack->biask_d[0][1]);
72516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
72616be5e3bSPing-Ke Shih "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n",
72716be5e3bSPing-Ke Shih dack->biask_d[1][0], dack->biask_d[1][1]);
72816be5e3bSPing-Ke Shih
72916be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n");
73016be5e3bSPing-Ke Shih for (i = 0; i < 0x10; i++) {
73116be5e3bSPing-Ke Shih t = dack->msbk_d[0][0][i];
73216be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
73316be5e3bSPing-Ke Shih }
73416be5e3bSPing-Ke Shih
73516be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n");
73616be5e3bSPing-Ke Shih for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
73716be5e3bSPing-Ke Shih t = dack->msbk_d[0][1][i];
73816be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
73916be5e3bSPing-Ke Shih }
74016be5e3bSPing-Ke Shih
74116be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n");
74216be5e3bSPing-Ke Shih for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
74316be5e3bSPing-Ke Shih t = dack->msbk_d[1][0][i];
74416be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
74516be5e3bSPing-Ke Shih }
74616be5e3bSPing-Ke Shih
74716be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n");
74816be5e3bSPing-Ke Shih for (i = 0; i < RTW89_DACK_MSBK_NR; i++) {
74916be5e3bSPing-Ke Shih t = dack->msbk_d[1][1][i];
75016be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t);
75116be5e3bSPing-Ke Shih }
75216be5e3bSPing-Ke Shih }
75316be5e3bSPing-Ke Shih
_dac_cal(struct rtw89_dev * rtwdev,bool force)75416be5e3bSPing-Ke Shih static void _dac_cal(struct rtw89_dev *rtwdev, bool force)
75516be5e3bSPing-Ke Shih {
75616be5e3bSPing-Ke Shih struct rtw89_dack_info *dack = &rtwdev->dack;
75716be5e3bSPing-Ke Shih u32 rf0_0, rf1_0;
75816be5e3bSPing-Ke Shih
75916be5e3bSPing-Ke Shih dack->dack_done = false;
76016be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x1\n");
76116be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n");
76216be5e3bSPing-Ke Shih
76316be5e3bSPing-Ke Shih rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK);
76416be5e3bSPing-Ke Shih rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK);
76516be5e3bSPing-Ke Shih _afe_init(rtwdev);
76616be5e3bSPing-Ke Shih _drck(rtwdev);
76716be5e3bSPing-Ke Shih
76816be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0);
76916be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0);
77016be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1);
77116be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x337e1);
77216be5e3bSPing-Ke Shih _addck(rtwdev);
77316be5e3bSPing-Ke Shih _addck_backup(rtwdev);
77416be5e3bSPing-Ke Shih _addck_reload(rtwdev);
77516be5e3bSPing-Ke Shih
77616be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0);
77716be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0);
77816be5e3bSPing-Ke Shih _dack(rtwdev);
77916be5e3bSPing-Ke Shih _dack_dump(rtwdev);
78016be5e3bSPing-Ke Shih dack->dack_done = true;
78116be5e3bSPing-Ke Shih
78216be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0);
78316be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0);
78416be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1);
78516be5e3bSPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1);
78616be5e3bSPing-Ke Shih dack->dack_cnt++;
78716be5e3bSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n");
78816be5e3bSPing-Ke Shih }
78916be5e3bSPing-Ke Shih
_iqk_rxk_setting(struct rtw89_dev * rtwdev,u8 path)790f2abe804SPing-Ke Shih static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path)
791f2abe804SPing-Ke Shih {
792f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
793f2abe804SPing-Ke Shih u32 tmp;
794f2abe804SPing-Ke Shih
795f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
796f2abe804SPing-Ke Shih case RTW89_BAND_2G:
797f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc);
798f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1);
799f2abe804SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
800f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp);
801f2abe804SPing-Ke Shih break;
802f2abe804SPing-Ke Shih case RTW89_BAND_5G:
803f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc);
804f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1);
805f2abe804SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
806f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp);
807f2abe804SPing-Ke Shih break;
808f2abe804SPing-Ke Shih default:
809f2abe804SPing-Ke Shih break;
810f2abe804SPing-Ke Shih }
811f2abe804SPing-Ke Shih }
812f2abe804SPing-Ke Shih
_iqk_one_shot(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path,u8 ktype)813f2abe804SPing-Ke Shih static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
814f2abe804SPing-Ke Shih u8 path, u8 ktype)
815f2abe804SPing-Ke Shih {
816f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
817f2abe804SPing-Ke Shih u32 iqk_cmd;
818f2abe804SPing-Ke Shih bool fail;
819f2abe804SPing-Ke Shih
820f2abe804SPing-Ke Shih switch (ktype) {
821f2abe804SPing-Ke Shih case ID_FLOK_COARSE:
822f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
823f2abe804SPing-Ke Shih iqk_cmd = 0x108 | (1 << (4 + path));
824f2abe804SPing-Ke Shih break;
825f2abe804SPing-Ke Shih case ID_FLOK_FINE:
826f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
827f2abe804SPing-Ke Shih iqk_cmd = 0x208 | (1 << (4 + path));
828f2abe804SPing-Ke Shih break;
829f2abe804SPing-Ke Shih case ID_FLOK_VBUFFER:
830f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
831f2abe804SPing-Ke Shih iqk_cmd = 0x308 | (1 << (4 + path));
832f2abe804SPing-Ke Shih break;
833f2abe804SPing-Ke Shih case ID_TXK:
834f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
835f2abe804SPing-Ke Shih iqk_cmd = 0x008 | (1 << (path + 4)) |
836f2abe804SPing-Ke Shih (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8);
837f2abe804SPing-Ke Shih break;
838f2abe804SPing-Ke Shih case ID_RXAGC:
839f2abe804SPing-Ke Shih iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1);
840f2abe804SPing-Ke Shih break;
841f2abe804SPing-Ke Shih case ID_RXK:
842f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
843f2abe804SPing-Ke Shih iqk_cmd = 0x008 | (1 << (path + 4)) |
844f2abe804SPing-Ke Shih (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8);
845f2abe804SPing-Ke Shih break;
846f2abe804SPing-Ke Shih case ID_NBTXK:
847f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
848f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011);
849b3bfc4fbSPing-Ke Shih iqk_cmd = 0x408 | (1 << (4 + path));
850f2abe804SPing-Ke Shih break;
851f2abe804SPing-Ke Shih case ID_NBRXK:
852f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
853f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011);
854f2abe804SPing-Ke Shih iqk_cmd = 0x608 | (1 << (4 + path));
855f2abe804SPing-Ke Shih break;
856f2abe804SPing-Ke Shih default:
857f2abe804SPing-Ke Shih return false;
858f2abe804SPing-Ke Shih }
859f2abe804SPing-Ke Shih
860f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1);
861f2abe804SPing-Ke Shih udelay(1);
862f2abe804SPing-Ke Shih fail = _iqk_check_cal(rtwdev, path);
863f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
864f2abe804SPing-Ke Shih
865f2abe804SPing-Ke Shih return fail;
866f2abe804SPing-Ke Shih }
867f2abe804SPing-Ke Shih
_rxk_group_sel(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)868f2abe804SPing-Ke Shih static bool _rxk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
869f2abe804SPing-Ke Shih u8 path)
870f2abe804SPing-Ke Shih {
871f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
872f2abe804SPing-Ke Shih bool kfail = false;
873f2abe804SPing-Ke Shih bool fail;
874f2abe804SPing-Ke Shih u8 gp;
875f2abe804SPing-Ke Shih
876f2abe804SPing-Ke Shih for (gp = 0; gp < RTW8852B_RXK_GROUP_NR; gp++) {
877f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
878f2abe804SPing-Ke Shih case RTW89_BAND_2G:
879f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM,
880f2abe804SPing-Ke Shih _g_idxrxgain[gp]);
881f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G,
882f2abe804SPing-Ke Shih _g_idxattc2[gp]);
883f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G,
884f2abe804SPing-Ke Shih _g_idxattc1[gp]);
885f2abe804SPing-Ke Shih break;
886f2abe804SPing-Ke Shih case RTW89_BAND_5G:
887f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM,
888f2abe804SPing-Ke Shih _a_idxrxgain[gp]);
889f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT,
890f2abe804SPing-Ke Shih _a_idxattc2[gp]);
891f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2,
892f2abe804SPing-Ke Shih _a_idxattc1[gp]);
893f2abe804SPing-Ke Shih break;
894f2abe804SPing-Ke Shih default:
895f2abe804SPing-Ke Shih break;
896f2abe804SPing-Ke Shih }
897f2abe804SPing-Ke Shih
898f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
899f2abe804SPing-Ke Shih B_CFIR_LUT_SEL, 0x1);
900f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
901f2abe804SPing-Ke Shih B_CFIR_LUT_SET, 0x0);
902f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
903f2abe804SPing-Ke Shih B_CFIR_LUT_GP_V1, gp);
904f2abe804SPing-Ke Shih fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK);
905f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF,
906f2abe804SPing-Ke Shih BIT(16 + gp + path * 4), fail);
907f2abe804SPing-Ke Shih kfail |= fail;
908f2abe804SPing-Ke Shih }
909f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0);
910f2abe804SPing-Ke Shih
911f2abe804SPing-Ke Shih if (kfail) {
912f2abe804SPing-Ke Shih iqk_info->nb_rxcfir[path] = 0x40000002;
913f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
914f2abe804SPing-Ke Shih B_IQK_RES_RXCFIR, 0x0);
915f2abe804SPing-Ke Shih iqk_info->is_wb_rxiqk[path] = false;
916f2abe804SPing-Ke Shih } else {
917f2abe804SPing-Ke Shih iqk_info->nb_rxcfir[path] = 0x40000000;
918f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
919f2abe804SPing-Ke Shih B_IQK_RES_RXCFIR, 0x5);
920f2abe804SPing-Ke Shih iqk_info->is_wb_rxiqk[path] = true;
921f2abe804SPing-Ke Shih }
922f2abe804SPing-Ke Shih
923f2abe804SPing-Ke Shih return kfail;
924f2abe804SPing-Ke Shih }
925f2abe804SPing-Ke Shih
_iqk_nbrxk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)926f2abe804SPing-Ke Shih static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx,
927f2abe804SPing-Ke Shih u8 path)
928f2abe804SPing-Ke Shih {
929f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
930f2abe804SPing-Ke Shih const u8 gp = 0x3;
931f2abe804SPing-Ke Shih bool kfail = false;
932f2abe804SPing-Ke Shih bool fail;
933f2abe804SPing-Ke Shih
934f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
935f2abe804SPing-Ke Shih case RTW89_BAND_2G:
936f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM,
937f2abe804SPing-Ke Shih _g_idxrxgain[gp]);
938f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G,
939f2abe804SPing-Ke Shih _g_idxattc2[gp]);
940f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G,
941f2abe804SPing-Ke Shih _g_idxattc1[gp]);
942f2abe804SPing-Ke Shih break;
943f2abe804SPing-Ke Shih case RTW89_BAND_5G:
944f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM,
945f2abe804SPing-Ke Shih _a_idxrxgain[gp]);
946f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_HATT,
947f2abe804SPing-Ke Shih _a_idxattc2[gp]);
948f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_CC2,
949f2abe804SPing-Ke Shih _a_idxattc1[gp]);
950f2abe804SPing-Ke Shih break;
951f2abe804SPing-Ke Shih default:
952f2abe804SPing-Ke Shih break;
953f2abe804SPing-Ke Shih }
954f2abe804SPing-Ke Shih
955f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1);
956f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x0);
957f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP_V1, gp);
958f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013);
959f2abe804SPing-Ke Shih udelay(1);
960f2abe804SPing-Ke Shih
961f2abe804SPing-Ke Shih fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK);
962f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail);
963f2abe804SPing-Ke Shih kfail |= fail;
964f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0);
965f2abe804SPing-Ke Shih
966f2abe804SPing-Ke Shih if (!kfail)
967f2abe804SPing-Ke Shih iqk_info->nb_rxcfir[path] =
968f2abe804SPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD) | 0x2;
969f2abe804SPing-Ke Shih else
970f2abe804SPing-Ke Shih iqk_info->nb_rxcfir[path] = 0x40000002;
971f2abe804SPing-Ke Shih
972f2abe804SPing-Ke Shih return kfail;
973f2abe804SPing-Ke Shih }
974f2abe804SPing-Ke Shih
_iqk_rxclk_setting(struct rtw89_dev * rtwdev,u8 path)975f2abe804SPing-Ke Shih static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path)
976f2abe804SPing-Ke Shih {
977f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
978f2abe804SPing-Ke Shih
979f2abe804SPing-Ke Shih if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) {
980f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
981f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
982f2abe804SPing-Ke Shih udelay(1);
983f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f);
984f2abe804SPing-Ke Shih udelay(1);
985f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03);
986f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001);
987f2abe804SPing-Ke Shih udelay(1);
988f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041);
989f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x2);
990f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1);
991f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x2);
992f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1);
993f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1);
994f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1);
995f2abe804SPing-Ke Shih } else {
996f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
997f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
998f2abe804SPing-Ke Shih udelay(1);
999f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x0f);
1000f2abe804SPing-Ke Shih udelay(1);
1001f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x03);
1002f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa001);
1003f2abe804SPing-Ke Shih udelay(1);
1004f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041);
1005f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_VAL, 0x1);
1006f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RXCK, B_P0_RXCK_ON, 0x1);
1007f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_VAL, 0x1);
1008f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RXCK, B_P1_RXCK_ON, 0x1);
1009f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON, 0x1);
1010f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x0);
1011f2abe804SPing-Ke Shih }
1012f2abe804SPing-Ke Shih }
1013f2abe804SPing-Ke Shih
_txk_group_sel(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1014f2abe804SPing-Ke Shih static bool _txk_group_sel(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1015f2abe804SPing-Ke Shih {
1016f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1017f2abe804SPing-Ke Shih bool kfail = false;
1018f2abe804SPing-Ke Shih bool fail;
1019f2abe804SPing-Ke Shih u8 gp;
1020f2abe804SPing-Ke Shih
1021f2abe804SPing-Ke Shih for (gp = 0x0; gp < RTW8852B_RXK_GROUP_NR; gp++) {
1022f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1023f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1024f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0,
1025f2abe804SPing-Ke Shih _g_power_range[gp]);
1026f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1,
1027f2abe804SPing-Ke Shih _g_track_range[gp]);
1028f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG,
1029f2abe804SPing-Ke Shih _g_gain_bb[gp]);
1030f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1031f2abe804SPing-Ke Shih MASKDWORD, _g_itqt[gp]);
1032f2abe804SPing-Ke Shih break;
1033f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1034f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0,
1035f2abe804SPing-Ke Shih _a_power_range[gp]);
1036f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1,
1037f2abe804SPing-Ke Shih _a_track_range[gp]);
1038f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG,
1039f2abe804SPing-Ke Shih _a_gain_bb[gp]);
1040f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1041f2abe804SPing-Ke Shih MASKDWORD, _a_itqt[gp]);
1042f2abe804SPing-Ke Shih break;
1043f2abe804SPing-Ke Shih default:
1044f2abe804SPing-Ke Shih break;
1045f2abe804SPing-Ke Shih }
1046f2abe804SPing-Ke Shih
1047f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1048f2abe804SPing-Ke Shih B_CFIR_LUT_SEL, 0x1);
1049f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1050f2abe804SPing-Ke Shih B_CFIR_LUT_SET, 0x1);
1051f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1052f2abe804SPing-Ke Shih B_CFIR_LUT_G2, 0x0);
1053f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8),
1054f2abe804SPing-Ke Shih B_CFIR_LUT_GP, gp);
1055f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
1056f2abe804SPing-Ke Shih fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK);
1057f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF,
1058f2abe804SPing-Ke Shih BIT(8 + gp + path * 4), fail);
1059f2abe804SPing-Ke Shih kfail |= fail;
1060f2abe804SPing-Ke Shih }
1061f2abe804SPing-Ke Shih
1062f2abe804SPing-Ke Shih if (kfail) {
1063f2abe804SPing-Ke Shih iqk_info->nb_txcfir[path] = 0x40000002;
1064f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
1065f2abe804SPing-Ke Shih B_IQK_RES_TXCFIR, 0x0);
1066f2abe804SPing-Ke Shih iqk_info->is_wb_txiqk[path] = false;
1067f2abe804SPing-Ke Shih } else {
1068f2abe804SPing-Ke Shih iqk_info->nb_txcfir[path] = 0x40000000;
1069f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8),
1070f2abe804SPing-Ke Shih B_IQK_RES_TXCFIR, 0x5);
1071f2abe804SPing-Ke Shih iqk_info->is_wb_txiqk[path] = true;
1072f2abe804SPing-Ke Shih }
1073f2abe804SPing-Ke Shih
1074f2abe804SPing-Ke Shih return kfail;
1075f2abe804SPing-Ke Shih }
1076f2abe804SPing-Ke Shih
_iqk_nbtxk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1077f2abe804SPing-Ke Shih static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1078f2abe804SPing-Ke Shih {
1079f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1080f2abe804SPing-Ke Shih bool kfail;
1081b3bfc4fbSPing-Ke Shih u8 gp = 0x2;
1082f2abe804SPing-Ke Shih
1083f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1084f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1085f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0,
1086f2abe804SPing-Ke Shih _g_power_range[gp]);
1087f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1,
1088f2abe804SPing-Ke Shih _g_track_range[gp]);
1089f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG,
1090f2abe804SPing-Ke Shih _g_gain_bb[gp]);
1091f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1092f2abe804SPing-Ke Shih MASKDWORD, _g_itqt[gp]);
1093f2abe804SPing-Ke Shih break;
1094f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1095f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0,
1096f2abe804SPing-Ke Shih _a_power_range[gp]);
1097f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1,
1098f2abe804SPing-Ke Shih _a_track_range[gp]);
1099f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG,
1100f2abe804SPing-Ke Shih _a_gain_bb[gp]);
1101f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8),
1102f2abe804SPing-Ke Shih MASKDWORD, _a_itqt[gp]);
1103f2abe804SPing-Ke Shih break;
1104f2abe804SPing-Ke Shih default:
1105f2abe804SPing-Ke Shih break;
1106f2abe804SPing-Ke Shih }
1107f2abe804SPing-Ke Shih
1108f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1);
1109f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SET, 0x1);
1110f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G2, 0x0);
1111f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp);
1112f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
1113f2abe804SPing-Ke Shih kfail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK);
1114f2abe804SPing-Ke Shih
1115f2abe804SPing-Ke Shih if (!kfail)
1116f2abe804SPing-Ke Shih iqk_info->nb_txcfir[path] =
1117f2abe804SPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8),
1118f2abe804SPing-Ke Shih MASKDWORD) | 0x2;
1119f2abe804SPing-Ke Shih else
1120f2abe804SPing-Ke Shih iqk_info->nb_txcfir[path] = 0x40000002;
1121f2abe804SPing-Ke Shih
1122f2abe804SPing-Ke Shih return kfail;
1123f2abe804SPing-Ke Shih }
1124f2abe804SPing-Ke Shih
_lok_res_table(struct rtw89_dev * rtwdev,u8 path,u8 ibias)1125f2abe804SPing-Ke Shih static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias)
1126f2abe804SPing-Ke Shih {
1127f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1128f2abe804SPing-Ke Shih
1129f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
1130f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias);
1131f2abe804SPing-Ke Shih
1132f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2);
1133f2abe804SPing-Ke Shih if (iqk_info->iqk_band[path] == RTW89_BAND_2G)
1134f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0);
1135f2abe804SPing-Ke Shih else
1136f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1);
1137f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias);
1138f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
1139f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXVBUF, RR_TXVBUF_DACEN, 0x1);
1140f2abe804SPing-Ke Shih
1141f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x7c = %x\n", path,
1142f2abe804SPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_TXVBUF, RFREG_MASK));
1143f2abe804SPing-Ke Shih }
1144f2abe804SPing-Ke Shih
_lok_finetune_check(struct rtw89_dev * rtwdev,u8 path)1145f2abe804SPing-Ke Shih static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path)
1146f2abe804SPing-Ke Shih {
1147f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1148f2abe804SPing-Ke Shih bool is_fail1, is_fail2;
1149f2abe804SPing-Ke Shih u32 vbuff_i;
1150f2abe804SPing-Ke Shih u32 vbuff_q;
1151f2abe804SPing-Ke Shih u32 core_i;
1152f2abe804SPing-Ke Shih u32 core_q;
1153f2abe804SPing-Ke Shih u32 tmp;
1154f2abe804SPing-Ke Shih u8 ch;
1155f2abe804SPing-Ke Shih
1156f2abe804SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK);
1157f2abe804SPing-Ke Shih core_i = FIELD_GET(RR_TXMO_COI, tmp);
1158f2abe804SPing-Ke Shih core_q = FIELD_GET(RR_TXMO_COQ, tmp);
1159f2abe804SPing-Ke Shih ch = (iqk_info->iqk_times / 2) % RTW89_IQK_CHS_NR;
1160f2abe804SPing-Ke Shih
1161f2abe804SPing-Ke Shih if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d)
1162f2abe804SPing-Ke Shih is_fail1 = true;
1163f2abe804SPing-Ke Shih else
1164f2abe804SPing-Ke Shih is_fail1 = false;
1165f2abe804SPing-Ke Shih
1166f2abe804SPing-Ke Shih iqk_info->lok_idac[ch][path] = tmp;
1167f2abe804SPing-Ke Shih
1168f2abe804SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_LOKVB, RFREG_MASK);
1169f2abe804SPing-Ke Shih vbuff_i = FIELD_GET(RR_LOKVB_COI, tmp);
1170f2abe804SPing-Ke Shih vbuff_q = FIELD_GET(RR_LOKVB_COQ, tmp);
1171f2abe804SPing-Ke Shih
1172f2abe804SPing-Ke Shih if (vbuff_i < 0x2 || vbuff_i > 0x3d || vbuff_q < 0x2 || vbuff_q > 0x3d)
1173f2abe804SPing-Ke Shih is_fail2 = true;
1174f2abe804SPing-Ke Shih else
1175f2abe804SPing-Ke Shih is_fail2 = false;
1176f2abe804SPing-Ke Shih
1177f2abe804SPing-Ke Shih iqk_info->lok_vbuf[ch][path] = tmp;
1178f2abe804SPing-Ke Shih
1179f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
1180f2abe804SPing-Ke Shih "[IQK]S%x, lok_idac[%x][%x] = 0x%x\n", path, ch, path,
1181f2abe804SPing-Ke Shih iqk_info->lok_idac[ch][path]);
1182f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
1183f2abe804SPing-Ke Shih "[IQK]S%x, lok_vbuf[%x][%x] = 0x%x\n", path, ch, path,
1184f2abe804SPing-Ke Shih iqk_info->lok_vbuf[ch][path]);
1185f2abe804SPing-Ke Shih
1186f2abe804SPing-Ke Shih return is_fail1 | is_fail2;
1187f2abe804SPing-Ke Shih }
1188f2abe804SPing-Ke Shih
_iqk_lok(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1189f2abe804SPing-Ke Shih static bool _iqk_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1190f2abe804SPing-Ke Shih {
1191f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1192f2abe804SPing-Ke Shih bool tmp;
1193f2abe804SPing-Ke Shih
1194f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021);
1195f2abe804SPing-Ke Shih
1196f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1197f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1198f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0);
1199f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x6);
1200f2abe804SPing-Ke Shih break;
1201f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1202f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0);
1203f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x4);
1204f2abe804SPing-Ke Shih break;
1205f2abe804SPing-Ke Shih default:
1206f2abe804SPing-Ke Shih break;
1207f2abe804SPing-Ke Shih }
1208f2abe804SPing-Ke Shih
1209f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1210f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1211f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
1212f2abe804SPing-Ke Shih break;
1213f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1214f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
1215f2abe804SPing-Ke Shih break;
1216f2abe804SPing-Ke Shih default:
1217f2abe804SPing-Ke Shih break;
1218f2abe804SPing-Ke Shih }
1219f2abe804SPing-Ke Shih
1220f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9);
1221f2abe804SPing-Ke Shih tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE);
1222f2abe804SPing-Ke Shih iqk_info->lok_cor_fail[0][path] = tmp;
1223f2abe804SPing-Ke Shih
1224f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1225f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1226f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
1227f2abe804SPing-Ke Shih break;
1228f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1229f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
1230f2abe804SPing-Ke Shih break;
1231f2abe804SPing-Ke Shih default:
1232f2abe804SPing-Ke Shih break;
1233f2abe804SPing-Ke Shih }
1234f2abe804SPing-Ke Shih
1235f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24);
1236f2abe804SPing-Ke Shih tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER);
1237f2abe804SPing-Ke Shih
1238f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1239f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1240f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
1241f2abe804SPing-Ke Shih break;
1242f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1243f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x0);
1244f2abe804SPing-Ke Shih break;
1245f2abe804SPing-Ke Shih default:
1246f2abe804SPing-Ke Shih break;
1247f2abe804SPing-Ke Shih }
1248f2abe804SPing-Ke Shih
1249f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x9);
1250f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021);
1251f2abe804SPing-Ke Shih tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE);
1252f2abe804SPing-Ke Shih iqk_info->lok_fin_fail[0][path] = tmp;
1253f2abe804SPing-Ke Shih
1254f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1255f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1256f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
1257f2abe804SPing-Ke Shih break;
1258f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1259f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0x12);
1260f2abe804SPing-Ke Shih break;
1261f2abe804SPing-Ke Shih default:
1262f2abe804SPing-Ke Shih break;
1263f2abe804SPing-Ke Shih }
1264f2abe804SPing-Ke Shih
1265f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, 0x24);
1266f2abe804SPing-Ke Shih _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_VBUFFER);
1267f2abe804SPing-Ke Shih
1268f2abe804SPing-Ke Shih return _lok_finetune_check(rtwdev, path);
1269f2abe804SPing-Ke Shih }
1270f2abe804SPing-Ke Shih
_iqk_txk_setting(struct rtw89_dev * rtwdev,u8 path)1271f2abe804SPing-Ke Shih static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path)
1272f2abe804SPing-Ke Shih {
1273f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1274f2abe804SPing-Ke Shih
1275f2abe804SPing-Ke Shih switch (iqk_info->iqk_band[path]) {
1276f2abe804SPing-Ke Shih case RTW89_BAND_2G:
1277f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW2, 0x00);
1278f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0);
1279f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x0);
1280f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1);
1281f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0);
1282f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1);
1283f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x00);
1284f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e);
1285f2abe804SPing-Ke Shih udelay(1);
1286f2abe804SPing-Ke Shih break;
1287f2abe804SPing-Ke Shih case RTW89_BAND_5G:
1288f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00);
1289f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x1);
1290f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EXT, 0x0);
1291f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1);
1292f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M1, 0x80);
1293f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_IQK, 0x403e);
1294f2abe804SPing-Ke Shih udelay(1);
1295f2abe804SPing-Ke Shih break;
1296f2abe804SPing-Ke Shih default:
1297f2abe804SPing-Ke Shih break;
1298f2abe804SPing-Ke Shih }
1299f2abe804SPing-Ke Shih }
1300f2abe804SPing-Ke Shih
_iqk_txclk_setting(struct rtw89_dev * rtwdev,u8 path)1301f2abe804SPing-Ke Shih static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path)
1302f2abe804SPing-Ke Shih {
1303f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1);
1304f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON, 0x1);
1305f2abe804SPing-Ke Shih udelay(1);
1306f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f);
1307f2abe804SPing-Ke Shih udelay(1);
1308f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13);
1309f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001);
1310f2abe804SPing-Ke Shih udelay(1);
1311f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041);
1312f2abe804SPing-Ke Shih }
1313f2abe804SPing-Ke Shih
_iqk_info_iqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1314f2abe804SPing-Ke Shih static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1315f2abe804SPing-Ke Shih {
1316f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1317f2abe804SPing-Ke Shih u32 tmp;
1318f2abe804SPing-Ke Shih bool flag;
1319f2abe804SPing-Ke Shih
1320f2abe804SPing-Ke Shih flag = iqk_info->lok_cor_fail[0][path];
1321f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FCOR << (path * 4), flag);
1322f2abe804SPing-Ke Shih flag = iqk_info->lok_fin_fail[0][path];
1323f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FFIN << (path * 4), flag);
1324f2abe804SPing-Ke Shih flag = iqk_info->iqk_tx_fail[0][path];
1325f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_FTX << (path * 4), flag);
1326f2abe804SPing-Ke Shih flag = iqk_info->iqk_rx_fail[0][path];
1327f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_F_RX << (path * 4), flag);
1328f2abe804SPing-Ke Shih
1329f2abe804SPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD);
1330f2abe804SPing-Ke Shih iqk_info->bp_iqkenable[path] = tmp;
1331f2abe804SPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD);
1332f2abe804SPing-Ke Shih iqk_info->bp_txkresult[path] = tmp;
1333f2abe804SPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD);
1334f2abe804SPing-Ke Shih iqk_info->bp_rxkresult[path] = tmp;
1335f2abe804SPing-Ke Shih
1336f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, iqk_info->iqk_times);
1337f2abe804SPing-Ke Shih
1338f2abe804SPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, B_IQKINF_FAIL << (path * 4));
1339f2abe804SPing-Ke Shih if (tmp)
1340f2abe804SPing-Ke Shih iqk_info->iqk_fail_cnt++;
1341f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_FCNT << (path * 4),
1342f2abe804SPing-Ke Shih iqk_info->iqk_fail_cnt);
1343f2abe804SPing-Ke Shih }
1344f2abe804SPing-Ke Shih
_iqk_by_path(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1345f2abe804SPing-Ke Shih static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1346f2abe804SPing-Ke Shih {
1347f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1348f2abe804SPing-Ke Shih bool lok_is_fail = false;
1349f2abe804SPing-Ke Shih const int try = 3;
1350f2abe804SPing-Ke Shih u8 ibias = 0x1;
1351f2abe804SPing-Ke Shih u8 i;
1352f2abe804SPing-Ke Shih
1353f2abe804SPing-Ke Shih _iqk_txclk_setting(rtwdev, path);
1354f2abe804SPing-Ke Shih
1355f2abe804SPing-Ke Shih /* LOK */
1356f2abe804SPing-Ke Shih for (i = 0; i < try; i++) {
1357f2abe804SPing-Ke Shih _lok_res_table(rtwdev, path, ibias++);
1358f2abe804SPing-Ke Shih _iqk_txk_setting(rtwdev, path);
1359f2abe804SPing-Ke Shih lok_is_fail = _iqk_lok(rtwdev, phy_idx, path);
1360f2abe804SPing-Ke Shih if (!lok_is_fail)
1361f2abe804SPing-Ke Shih break;
1362f2abe804SPing-Ke Shih }
1363f2abe804SPing-Ke Shih
1364f2abe804SPing-Ke Shih if (lok_is_fail)
1365f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] LOK (%d) fail\n", path);
1366f2abe804SPing-Ke Shih
1367f2abe804SPing-Ke Shih /* TXK */
1368f2abe804SPing-Ke Shih if (iqk_info->is_nbiqk)
1369f2abe804SPing-Ke Shih iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path);
1370f2abe804SPing-Ke Shih else
1371f2abe804SPing-Ke Shih iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path);
1372f2abe804SPing-Ke Shih
1373f2abe804SPing-Ke Shih /* RX */
1374f2abe804SPing-Ke Shih _iqk_rxclk_setting(rtwdev, path);
1375f2abe804SPing-Ke Shih _iqk_rxk_setting(rtwdev, path);
1376f2abe804SPing-Ke Shih if (iqk_info->is_nbiqk)
1377f2abe804SPing-Ke Shih iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path);
1378f2abe804SPing-Ke Shih else
1379f2abe804SPing-Ke Shih iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path);
1380f2abe804SPing-Ke Shih
1381f2abe804SPing-Ke Shih _iqk_info_iqk(rtwdev, phy_idx, path);
1382f2abe804SPing-Ke Shih }
1383f2abe804SPing-Ke Shih
_iqk_get_ch_info(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,u8 path)1384f2abe804SPing-Ke Shih static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, u8 path)
1385f2abe804SPing-Ke Shih {
1386f2abe804SPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
1387f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1388f2abe804SPing-Ke Shih u32 reg_rf18;
1389f2abe804SPing-Ke Shih u32 reg_35c;
1390f2abe804SPing-Ke Shih u8 idx;
1391f2abe804SPing-Ke Shih u8 get_empty_table = false;
1392f2abe804SPing-Ke Shih
1393f2abe804SPing-Ke Shih for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
1394f2abe804SPing-Ke Shih if (iqk_info->iqk_mcc_ch[idx][path] == 0) {
1395f2abe804SPing-Ke Shih get_empty_table = true;
1396f2abe804SPing-Ke Shih break;
1397f2abe804SPing-Ke Shih }
1398f2abe804SPing-Ke Shih }
1399f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (1)idx = %x\n", idx);
1400f2abe804SPing-Ke Shih
1401f2abe804SPing-Ke Shih if (!get_empty_table) {
1402f2abe804SPing-Ke Shih idx = iqk_info->iqk_table_idx[path] + 1;
1403f2abe804SPing-Ke Shih if (idx > 1)
1404f2abe804SPing-Ke Shih idx = 0;
1405f2abe804SPing-Ke Shih }
1406f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (2)idx = %x\n", idx);
1407f2abe804SPing-Ke Shih
1408f2abe804SPing-Ke Shih reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
1409f2abe804SPing-Ke Shih reg_35c = rtw89_phy_read32_mask(rtwdev, R_CIRST, B_CIRST_SYN);
1410f2abe804SPing-Ke Shih
1411f2abe804SPing-Ke Shih iqk_info->iqk_band[path] = chan->band_type;
1412f2abe804SPing-Ke Shih iqk_info->iqk_bw[path] = chan->band_width;
1413f2abe804SPing-Ke Shih iqk_info->iqk_ch[path] = chan->channel;
1414f2abe804SPing-Ke Shih iqk_info->iqk_mcc_ch[idx][path] = chan->channel;
1415f2abe804SPing-Ke Shih iqk_info->iqk_table_idx[path] = idx;
1416f2abe804SPing-Ke Shih
1417f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x, idx = %x\n",
1418f2abe804SPing-Ke Shih path, reg_rf18, idx);
1419f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x18= 0x%x\n",
1420f2abe804SPing-Ke Shih path, reg_rf18);
1421f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n",
1422f2abe804SPing-Ke Shih iqk_info->iqk_times, idx);
1423f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_mcc_ch[%x][%x] = 0x%x\n",
1424f2abe804SPing-Ke Shih idx, path, iqk_info->iqk_mcc_ch[idx][path]);
1425f2abe804SPing-Ke Shih
1426f2abe804SPing-Ke Shih if (reg_35c == 0x01)
1427f2abe804SPing-Ke Shih iqk_info->syn1to2 = 0x1;
1428f2abe804SPing-Ke Shih else
1429f2abe804SPing-Ke Shih iqk_info->syn1to2 = 0x0;
1430f2abe804SPing-Ke Shih
1431f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
1432f2abe804SPing-Ke Shih "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", path,
1433f2abe804SPing-Ke Shih iqk_info->syn1to2);
1434f2abe804SPing-Ke Shih
1435f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852B_IQK_VER);
1436f2abe804SPing-Ke Shih /* 2GHz/5GHz/6GHz = 0/1/2 */
1437f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BAND << (path * 16),
1438f2abe804SPing-Ke Shih iqk_info->iqk_band[path]);
1439f2abe804SPing-Ke Shih /* 20/40/80 = 0/1/2 */
1440f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_BW << (path * 16),
1441f2abe804SPing-Ke Shih iqk_info->iqk_bw[path]);
1442f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKCH, B_IQKCH_CH << (path * 16),
1443f2abe804SPing-Ke Shih iqk_info->iqk_ch[path]);
1444f2abe804SPing-Ke Shih }
1445f2abe804SPing-Ke Shih
_iqk_start_iqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1446f2abe804SPing-Ke Shih static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path)
1447f2abe804SPing-Ke Shih {
1448f2abe804SPing-Ke Shih _iqk_by_path(rtwdev, phy_idx, path);
1449f2abe804SPing-Ke Shih }
1450f2abe804SPing-Ke Shih
_iqk_restore(struct rtw89_dev * rtwdev,u8 path)1451f2abe804SPing-Ke Shih static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path)
1452f2abe804SPing-Ke Shih {
1453f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1454f2abe804SPing-Ke Shih bool fail;
1455f2abe804SPing-Ke Shih
1456f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD,
1457f2abe804SPing-Ke Shih iqk_info->nb_txcfir[path]);
1458f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD,
1459f2abe804SPing-Ke Shih iqk_info->nb_rxcfir[path]);
1460f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD,
1461f2abe804SPing-Ke Shih 0x00000e19 + (path << 4));
1462f2abe804SPing-Ke Shih fail = _iqk_check_cal(rtwdev, path);
1463f2abe804SPing-Ke Shih
1464f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "%s result =%x\n", __func__, fail);
1465f2abe804SPing-Ke Shih
1466f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00);
1467f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000);
1468f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000);
1469f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS, B_IQK_RES_K, 0x0);
1470f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K1, 0x0);
1471f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQRSN, B_IQRSN_K2, 0x0);
1472f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0);
1473f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0);
1474f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0x3);
1475f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1);
1476f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1);
1477f2abe804SPing-Ke Shih }
1478f2abe804SPing-Ke Shih
_iqk_afebb_restore(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1479f2abe804SPing-Ke Shih static void _iqk_afebb_restore(struct rtw89_dev *rtwdev,
1480f2abe804SPing-Ke Shih enum rtw89_phy_idx phy_idx, u8 path)
1481f2abe804SPing-Ke Shih {
1482f2abe804SPing-Ke Shih const struct rtw89_reg3_def *def;
1483f2abe804SPing-Ke Shih int size;
1484f2abe804SPing-Ke Shih u8 kpath;
1485f2abe804SPing-Ke Shih int i;
1486f2abe804SPing-Ke Shih
1487f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "===> %s\n", __func__);
1488f2abe804SPing-Ke Shih
1489f2abe804SPing-Ke Shih kpath = _kpath(rtwdev, phy_idx);
1490f2abe804SPing-Ke Shih
1491f2abe804SPing-Ke Shih switch (kpath) {
1492f2abe804SPing-Ke Shih case RF_A:
1493f2abe804SPing-Ke Shih case RF_B:
1494f2abe804SPing-Ke Shih return;
1495f2abe804SPing-Ke Shih default:
1496f2abe804SPing-Ke Shih size = ARRAY_SIZE(rtw8852b_restore_nondbcc_path01);
1497f2abe804SPing-Ke Shih def = rtw8852b_restore_nondbcc_path01;
1498f2abe804SPing-Ke Shih break;
1499f2abe804SPing-Ke Shih }
1500f2abe804SPing-Ke Shih
1501f2abe804SPing-Ke Shih for (i = 0; i < size; i++, def++)
1502f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data);
1503f2abe804SPing-Ke Shih }
1504f2abe804SPing-Ke Shih
_iqk_preset(struct rtw89_dev * rtwdev,u8 path)1505f2abe804SPing-Ke Shih static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path)
1506f2abe804SPing-Ke Shih {
1507f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1508f2abe804SPing-Ke Shih u8 idx;
1509f2abe804SPing-Ke Shih
1510f2abe804SPing-Ke Shih idx = iqk_info->iqk_table_idx[path];
1511f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] (3)idx = %x\n", idx);
1512f2abe804SPing-Ke Shih
1513f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_IQC, idx);
1514f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, idx);
1515f2abe804SPing-Ke Shih
1516f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0);
1517f2abe804SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0);
1518f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080);
1519f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a);
1520f2abe804SPing-Ke Shih
1521f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x54 = 0x%x\n", path, 1 << path,
1522f2abe804SPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_CFIR_LUT + (path << 8), MASKDWORD));
1523f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK](1)S%x, 0x8%x04 = 0x%x\n", path, 1 << path,
1524f2abe804SPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_COEF_SEL + (path << 8), MASKDWORD));
1525f2abe804SPing-Ke Shih }
1526f2abe804SPing-Ke Shih
_iqk_macbb_setting(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,u8 path)1527f2abe804SPing-Ke Shih static void _iqk_macbb_setting(struct rtw89_dev *rtwdev,
1528f2abe804SPing-Ke Shih enum rtw89_phy_idx phy_idx, u8 path)
1529f2abe804SPing-Ke Shih {
1530f2abe804SPing-Ke Shih const struct rtw89_reg3_def *def;
1531f2abe804SPing-Ke Shih int size;
1532f2abe804SPing-Ke Shih u8 kpath;
1533f2abe804SPing-Ke Shih int i;
1534f2abe804SPing-Ke Shih
1535f2abe804SPing-Ke Shih kpath = _kpath(rtwdev, phy_idx);
1536f2abe804SPing-Ke Shih
1537f2abe804SPing-Ke Shih switch (kpath) {
1538f2abe804SPing-Ke Shih case RF_A:
1539f2abe804SPing-Ke Shih case RF_B:
1540f2abe804SPing-Ke Shih return;
1541f2abe804SPing-Ke Shih default:
1542f2abe804SPing-Ke Shih size = ARRAY_SIZE(rtw8852b_set_nondbcc_path01);
1543f2abe804SPing-Ke Shih def = rtw8852b_set_nondbcc_path01;
1544f2abe804SPing-Ke Shih break;
1545f2abe804SPing-Ke Shih }
1546f2abe804SPing-Ke Shih
1547f2abe804SPing-Ke Shih for (i = 0; i < size; i++, def++)
1548f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, def->addr, def->mask, def->data);
1549f2abe804SPing-Ke Shih }
1550f2abe804SPing-Ke Shih
_iqk_init(struct rtw89_dev * rtwdev)1551f2abe804SPing-Ke Shih static void _iqk_init(struct rtw89_dev *rtwdev)
1552f2abe804SPing-Ke Shih {
1553f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1554f2abe804SPing-Ke Shih u8 idx, path;
1555f2abe804SPing-Ke Shih
1556f2abe804SPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0);
1557f2abe804SPing-Ke Shih if (iqk_info->is_iqk_init)
1558f2abe804SPing-Ke Shih return;
1559f2abe804SPing-Ke Shih
1560f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__);
1561f2abe804SPing-Ke Shih iqk_info->is_iqk_init = true;
1562f2abe804SPing-Ke Shih iqk_info->is_nbiqk = false;
1563f2abe804SPing-Ke Shih iqk_info->iqk_fft_en = false;
1564f2abe804SPing-Ke Shih iqk_info->iqk_sram_en = false;
1565f2abe804SPing-Ke Shih iqk_info->iqk_cfir_en = false;
1566f2abe804SPing-Ke Shih iqk_info->iqk_xym_en = false;
1567f2abe804SPing-Ke Shih iqk_info->iqk_times = 0x0;
1568f2abe804SPing-Ke Shih
1569f2abe804SPing-Ke Shih for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) {
1570f2abe804SPing-Ke Shih iqk_info->iqk_channel[idx] = 0x0;
1571f2abe804SPing-Ke Shih for (path = 0; path < RTW8852B_IQK_SS; path++) {
1572f2abe804SPing-Ke Shih iqk_info->lok_cor_fail[idx][path] = false;
1573f2abe804SPing-Ke Shih iqk_info->lok_fin_fail[idx][path] = false;
1574f2abe804SPing-Ke Shih iqk_info->iqk_tx_fail[idx][path] = false;
1575f2abe804SPing-Ke Shih iqk_info->iqk_rx_fail[idx][path] = false;
1576f2abe804SPing-Ke Shih iqk_info->iqk_mcc_ch[idx][path] = 0x0;
1577f2abe804SPing-Ke Shih iqk_info->iqk_table_idx[path] = 0x0;
1578f2abe804SPing-Ke Shih }
1579f2abe804SPing-Ke Shih }
1580f2abe804SPing-Ke Shih }
1581f2abe804SPing-Ke Shih
_wait_rx_mode(struct rtw89_dev * rtwdev,u8 kpath)158221267107SPing-Ke Shih static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath)
158321267107SPing-Ke Shih {
158421267107SPing-Ke Shih u32 rf_mode;
158521267107SPing-Ke Shih u8 path;
158621267107SPing-Ke Shih int ret;
158721267107SPing-Ke Shih
158821267107SPing-Ke Shih for (path = 0; path < RF_PATH_MAX; path++) {
158921267107SPing-Ke Shih if (!(kpath & BIT(path)))
159021267107SPing-Ke Shih continue;
159121267107SPing-Ke Shih
159221267107SPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode,
159321267107SPing-Ke Shih rf_mode != 2, 2, 5000, false,
159421267107SPing-Ke Shih rtwdev, path, RR_MOD, RR_MOD_MASK);
159521267107SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
159621267107SPing-Ke Shih "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", path, ret);
159721267107SPing-Ke Shih }
159821267107SPing-Ke Shih }
159921267107SPing-Ke Shih
_tmac_tx_pause(struct rtw89_dev * rtwdev,enum rtw89_phy_idx band_idx,bool is_pause)16007f18a70dSPing-Ke Shih static void _tmac_tx_pause(struct rtw89_dev *rtwdev, enum rtw89_phy_idx band_idx,
16017f18a70dSPing-Ke Shih bool is_pause)
16027f18a70dSPing-Ke Shih {
16037f18a70dSPing-Ke Shih if (!is_pause)
16047f18a70dSPing-Ke Shih return;
16057f18a70dSPing-Ke Shih
16067f18a70dSPing-Ke Shih _wait_rx_mode(rtwdev, _kpath(rtwdev, band_idx));
16077f18a70dSPing-Ke Shih }
16087f18a70dSPing-Ke Shih
_doiqk(struct rtw89_dev * rtwdev,bool force,enum rtw89_phy_idx phy_idx,u8 path)1609f2abe804SPing-Ke Shih static void _doiqk(struct rtw89_dev *rtwdev, bool force,
1610f2abe804SPing-Ke Shih enum rtw89_phy_idx phy_idx, u8 path)
1611f2abe804SPing-Ke Shih {
1612f2abe804SPing-Ke Shih struct rtw89_iqk_info *iqk_info = &rtwdev->iqk;
1613f2abe804SPing-Ke Shih u32 backup_bb_val[BACKUP_BB_REGS_NR];
1614f2abe804SPing-Ke Shih u32 backup_rf_val[RTW8852B_IQK_SS][BACKUP_RF_REGS_NR];
1615f2abe804SPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB);
1616f2abe804SPing-Ke Shih
1617f2abe804SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
1618f2abe804SPing-Ke Shih
1619f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
16205bc9a34cSDmitry Antipov "[IQK]==========IQK start!!!!!==========\n");
1621f2abe804SPing-Ke Shih iqk_info->iqk_times++;
1622f2abe804SPing-Ke Shih iqk_info->version = RTW8852B_IQK_VER;
1623f2abe804SPing-Ke Shih
1624f2abe804SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version);
1625f2abe804SPing-Ke Shih _iqk_get_ch_info(rtwdev, phy_idx, path);
1626f2abe804SPing-Ke Shih
1627f2abe804SPing-Ke Shih _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]);
1628f2abe804SPing-Ke Shih _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
1629f2abe804SPing-Ke Shih _iqk_macbb_setting(rtwdev, phy_idx, path);
1630f2abe804SPing-Ke Shih _iqk_preset(rtwdev, path);
1631f2abe804SPing-Ke Shih _iqk_start_iqk(rtwdev, phy_idx, path);
1632f2abe804SPing-Ke Shih _iqk_restore(rtwdev, path);
1633f2abe804SPing-Ke Shih _iqk_afebb_restore(rtwdev, phy_idx, path);
1634f2abe804SPing-Ke Shih _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]);
1635f2abe804SPing-Ke Shih _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path);
1636f2abe804SPing-Ke Shih
1637f2abe804SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
1638f2abe804SPing-Ke Shih }
1639f2abe804SPing-Ke Shih
_iqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx,bool force)1640f2abe804SPing-Ke Shih static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force)
1641f2abe804SPing-Ke Shih {
1642f2abe804SPing-Ke Shih u8 kpath = _kpath(rtwdev, phy_idx);
1643f2abe804SPing-Ke Shih
1644f2abe804SPing-Ke Shih switch (kpath) {
1645f2abe804SPing-Ke Shih case RF_A:
1646f2abe804SPing-Ke Shih _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
1647f2abe804SPing-Ke Shih break;
1648f2abe804SPing-Ke Shih case RF_B:
1649f2abe804SPing-Ke Shih _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
1650f2abe804SPing-Ke Shih break;
1651f2abe804SPing-Ke Shih case RF_AB:
1652f2abe804SPing-Ke Shih _doiqk(rtwdev, force, phy_idx, RF_PATH_A);
1653f2abe804SPing-Ke Shih _doiqk(rtwdev, force, phy_idx, RF_PATH_B);
1654f2abe804SPing-Ke Shih break;
1655f2abe804SPing-Ke Shih default:
1656f2abe804SPing-Ke Shih break;
1657f2abe804SPing-Ke Shih }
1658f2abe804SPing-Ke Shih }
1659f2abe804SPing-Ke Shih
_dpk_bkup_kip(struct rtw89_dev * rtwdev,const u32 reg[],u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM],u8 path)16605b8471acSPing-Ke Shih static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 reg[],
16615b8471acSPing-Ke Shih u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path)
16625b8471acSPing-Ke Shih {
16635b8471acSPing-Ke Shih u8 i;
16645b8471acSPing-Ke Shih
16655b8471acSPing-Ke Shih for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) {
16665b8471acSPing-Ke Shih reg_bkup[path][i] =
16675b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD);
16685b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n",
16695b8471acSPing-Ke Shih reg[i] + (path << 8), reg_bkup[path][i]);
16705b8471acSPing-Ke Shih }
16715b8471acSPing-Ke Shih }
16725b8471acSPing-Ke Shih
_dpk_reload_kip(struct rtw89_dev * rtwdev,const u32 reg[],const u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM],u8 path)16735b8471acSPing-Ke Shih static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 reg[],
16745b8471acSPing-Ke Shih const u32 reg_bkup[][RTW8852B_DPK_KIP_REG_NUM], u8 path)
16755b8471acSPing-Ke Shih {
16765b8471acSPing-Ke Shih u8 i;
16775b8471acSPing-Ke Shih
16785b8471acSPing-Ke Shih for (i = 0; i < RTW8852B_DPK_KIP_REG_NUM; i++) {
16795b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD,
16805b8471acSPing-Ke Shih reg_bkup[path][i]);
16815b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n",
16825b8471acSPing-Ke Shih reg[i] + (path << 8), reg_bkup[path][i]);
16835b8471acSPing-Ke Shih }
16845b8471acSPing-Ke Shih }
16855b8471acSPing-Ke Shih
_dpk_order_convert(struct rtw89_dev * rtwdev)16865b8471acSPing-Ke Shih static u8 _dpk_order_convert(struct rtw89_dev *rtwdev)
16875b8471acSPing-Ke Shih {
16885b8471acSPing-Ke Shih u8 order;
16895b8471acSPing-Ke Shih u8 val;
16905b8471acSPing-Ke Shih
16915b8471acSPing-Ke Shih order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP);
16925b8471acSPing-Ke Shih val = 0x3 >> order;
16935b8471acSPing-Ke Shih
16945b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val);
16955b8471acSPing-Ke Shih
16965b8471acSPing-Ke Shih return val;
16975b8471acSPing-Ke Shih }
16985b8471acSPing-Ke Shih
_dpk_onoff(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,bool off)16995b8471acSPing-Ke Shih static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, bool off)
17005b8471acSPing-Ke Shih {
17015b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
17025b8471acSPing-Ke Shih u8 val, kidx = dpk->cur_idx[path];
17035b8471acSPing-Ke Shih
17045b8471acSPing-Ke Shih val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok;
17055b8471acSPing-Ke Shih
17065b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
17075b8471acSPing-Ke Shih MASKBYTE3, _dpk_order_convert(rtwdev) << 1 | val);
17085b8471acSPing-Ke Shih
17095b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path,
17105b8471acSPing-Ke Shih kidx, dpk->is_dpk_enable && !off ? "enable" : "disable");
17115b8471acSPing-Ke Shih }
17125b8471acSPing-Ke Shih
_dpk_one_shot(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,enum rtw8852b_dpk_id id)17135b8471acSPing-Ke Shih static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
17145b8471acSPing-Ke Shih enum rtw89_rf_path path, enum rtw8852b_dpk_id id)
17155b8471acSPing-Ke Shih {
17165b8471acSPing-Ke Shih u16 dpk_cmd;
17175b8471acSPing-Ke Shih u32 val;
17185b8471acSPing-Ke Shih int ret;
17195b8471acSPing-Ke Shih
17205b8471acSPing-Ke Shih dpk_cmd = (id << 8) | (0x19 + (path << 4));
17215b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd);
17225b8471acSPing-Ke Shih
17235b8471acSPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55,
17245b8471acSPing-Ke Shih 1, 20000, false,
17255b8471acSPing-Ke Shih rtwdev, 0xbff8, MASKBYTE0);
17265b8471acSPing-Ke Shih if (ret)
17275b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n");
17285b8471acSPing-Ke Shih
17295b8471acSPing-Ke Shih udelay(1);
17305b8471acSPing-Ke Shih
17315b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00030000);
17325b8471acSPing-Ke Shih
17335b8471acSPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000,
17345b8471acSPing-Ke Shih 1, 2000, false,
17355b8471acSPing-Ke Shih rtwdev, 0x80fc, MASKLWORD);
17365b8471acSPing-Ke Shih if (ret)
17375b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot over 20ms!!!!\n");
17385b8471acSPing-Ke Shih
17395b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0);
17405b8471acSPing-Ke Shih
17415b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
17425b8471acSPing-Ke Shih "[DPK] one-shot for %s = 0x%x\n",
17435b8471acSPing-Ke Shih id == 0x06 ? "LBK_RXIQK" :
17445b8471acSPing-Ke Shih id == 0x10 ? "SYNC" :
17455b8471acSPing-Ke Shih id == 0x11 ? "MDPK_IDL" :
17465b8471acSPing-Ke Shih id == 0x12 ? "MDPK_MPA" :
17475b8471acSPing-Ke Shih id == 0x13 ? "GAIN_LOSS" :
17485b8471acSPing-Ke Shih id == 0x14 ? "PWR_CAL" :
17495b8471acSPing-Ke Shih id == 0x15 ? "DPK_RXAGC" :
17505b8471acSPing-Ke Shih id == 0x16 ? "KIP_PRESET" :
17518fa68170SColin Ian King id == 0x17 ? "KIP_RESTORE" : "DPK_TXAGC",
17525b8471acSPing-Ke Shih dpk_cmd);
17535b8471acSPing-Ke Shih }
17545b8471acSPing-Ke Shih
_dpk_rx_dck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)17555b8471acSPing-Ke Shih static void _dpk_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
17565b8471acSPing-Ke Shih enum rtw89_rf_path path)
17575b8471acSPing-Ke Shih {
17585b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3);
17595b8471acSPing-Ke Shih _set_rx_dck(rtwdev, phy, path);
17605b8471acSPing-Ke Shih }
17615b8471acSPing-Ke Shih
_dpk_information(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)17625b8471acSPing-Ke Shih static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
17635b8471acSPing-Ke Shih enum rtw89_rf_path path)
17645b8471acSPing-Ke Shih {
17655b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
17665b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
17675b8471acSPing-Ke Shih
17685b8471acSPing-Ke Shih u8 kidx = dpk->cur_idx[path];
17695b8471acSPing-Ke Shih
17705b8471acSPing-Ke Shih dpk->bp[path][kidx].band = chan->band_type;
17715b8471acSPing-Ke Shih dpk->bp[path][kidx].ch = chan->channel;
17725b8471acSPing-Ke Shih dpk->bp[path][kidx].bw = chan->band_width;
17735b8471acSPing-Ke Shih
17745b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
17755b8471acSPing-Ke Shih "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n",
17765b8471acSPing-Ke Shih path, dpk->cur_idx[path], phy,
17775b8471acSPing-Ke Shih rtwdev->is_tssi_mode[path] ? "on" : "off",
17785b8471acSPing-Ke Shih rtwdev->dbcc_en ? "on" : "off",
17795b8471acSPing-Ke Shih dpk->bp[path][kidx].band == 0 ? "2G" :
17805b8471acSPing-Ke Shih dpk->bp[path][kidx].band == 1 ? "5G" : "6G",
17815b8471acSPing-Ke Shih dpk->bp[path][kidx].ch,
17825b8471acSPing-Ke Shih dpk->bp[path][kidx].bw == 0 ? "20M" :
17835b8471acSPing-Ke Shih dpk->bp[path][kidx].bw == 1 ? "40M" : "80M");
17845b8471acSPing-Ke Shih }
17855b8471acSPing-Ke Shih
_dpk_bb_afe_setting(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kpath)17865b8471acSPing-Ke Shih static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev,
17875b8471acSPing-Ke Shih enum rtw89_phy_idx phy,
17885b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kpath)
17895b8471acSPing-Ke Shih {
17905b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
17915b8471acSPing-Ke Shih
17925b8471acSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_defs_tbl);
17935b8471acSPing-Ke Shih
17945b8471acSPing-Ke Shih if (chan->band_width == RTW89_CHANNEL_WIDTH_80) {
17955b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x1);
17965b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x1);
17975b8471acSPing-Ke Shih }
17985b8471acSPing-Ke Shih
17995b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
18005b8471acSPing-Ke Shih "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath);
18015b8471acSPing-Ke Shih }
18025b8471acSPing-Ke Shih
_dpk_bb_afe_restore(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kpath)18035b8471acSPing-Ke Shih static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev,
18045b8471acSPing-Ke Shih enum rtw89_phy_idx phy,
18055b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kpath)
18065b8471acSPing-Ke Shih {
18075b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
18085b8471acSPing-Ke Shih
18095b8471acSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_afe_restore_defs_tbl);
18105b8471acSPing-Ke Shih
18115b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
18125b8471acSPing-Ke Shih "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath);
18135b8471acSPing-Ke Shih
18145b8471acSPing-Ke Shih if (chan->band_width == RTW89_CHANNEL_WIDTH_80) {
18155b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_CFCH_BW1, B_P0_CFCH_EX, 0x0);
18165b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_PATH1_BW_SEL_V1, B_PATH1_BW_SEL_EX, 0x0);
18175b8471acSPing-Ke Shih }
18185b8471acSPing-Ke Shih }
18195b8471acSPing-Ke Shih
_dpk_tssi_pause(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,bool is_pause)18205b8471acSPing-Ke Shih static void _dpk_tssi_pause(struct rtw89_dev *rtwdev,
18215b8471acSPing-Ke Shih enum rtw89_rf_path path, bool is_pause)
18225b8471acSPing-Ke Shih {
18235b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13),
18245b8471acSPing-Ke Shih B_P0_TSSI_TRK_EN, is_pause);
18255b8471acSPing-Ke Shih
18265b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path,
18275b8471acSPing-Ke Shih is_pause ? "pause" : "resume");
18285b8471acSPing-Ke Shih }
18295b8471acSPing-Ke Shih
_dpk_kip_restore(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)18305b8471acSPing-Ke Shih static void _dpk_kip_restore(struct rtw89_dev *rtwdev,
18315b8471acSPing-Ke Shih enum rtw89_rf_path path)
18325b8471acSPing-Ke Shih {
18335b8471acSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_dpk_kip_defs_tbl);
18345b8471acSPing-Ke Shih
18355b8471acSPing-Ke Shih if (rtwdev->hal.cv > CHIP_CAV)
18365b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), B_DPD_COM_OF, 0x1);
18375b8471acSPing-Ke Shih
18385b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path);
18395b8471acSPing-Ke Shih }
18405b8471acSPing-Ke Shih
_dpk_lbk_rxiqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)18415b8471acSPing-Ke Shih static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
18425b8471acSPing-Ke Shih enum rtw89_rf_path path)
18435b8471acSPing-Ke Shih {
18445b8471acSPing-Ke Shih u8 cur_rxbb;
18455b8471acSPing-Ke Shih u32 tmp;
18465b8471acSPing-Ke Shih
18475b8471acSPing-Ke Shih cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB);
18485b8471acSPing-Ke Shih
18495b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1);
18505b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR, 0x0);
18515b8471acSPing-Ke Shih
18525b8471acSPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK);
18535b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp);
18545b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0xd);
18555b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1);
18565b8471acSPing-Ke Shih
18575b8471acSPing-Ke Shih if (cur_rxbb >= 0x11)
18585b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x13);
18595b8471acSPing-Ke Shih else if (cur_rxbb <= 0xa)
18605b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x00);
18615b8471acSPing-Ke Shih else
18625b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXIQK, RR_TXIQK_ATT1, 0x05);
18635b8471acSPing-Ke Shih
18645b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x0);
18655b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0);
18665b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80014);
18675b8471acSPing-Ke Shih udelay(70);
18685b8471acSPing-Ke Shih
18695b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
18705b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x025);
18715b8471acSPing-Ke Shih
18725b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK);
18735b8471acSPing-Ke Shih
18745b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path,
18755b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD));
18765b8471acSPing-Ke Shih
18775b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
18785b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0);
18795b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0);
18805b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0);
18815b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1);
18825b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKMODE, 0x5);
18835b8471acSPing-Ke Shih }
18845b8471acSPing-Ke Shih
_dpk_get_thermal(struct rtw89_dev * rtwdev,u8 kidx,enum rtw89_rf_path path)18855b8471acSPing-Ke Shih static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, enum rtw89_rf_path path)
18865b8471acSPing-Ke Shih {
18875b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
18885b8471acSPing-Ke Shih
18895b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1);
18905b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x0);
18915b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TM, RR_TM_TRI, 0x1);
18925b8471acSPing-Ke Shih
18935b8471acSPing-Ke Shih udelay(200);
18945b8471acSPing-Ke Shih
18955b8471acSPing-Ke Shih dpk->bp[path][kidx].ther_dpk = rtw89_read_rf(rtwdev, path, RR_TM, RR_TM_VAL);
18965b8471acSPing-Ke Shih
18975b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n",
18985b8471acSPing-Ke Shih dpk->bp[path][kidx].ther_dpk);
18995b8471acSPing-Ke Shih }
19005b8471acSPing-Ke Shih
_dpk_rf_setting(struct rtw89_dev * rtwdev,u8 gain,enum rtw89_rf_path path,u8 kidx)19015b8471acSPing-Ke Shih static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain,
19025b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx)
19035b8471acSPing-Ke Shih {
19045b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
19055b8471acSPing-Ke Shih
19065b8471acSPing-Ke Shih if (dpk->bp[path][kidx].band == RTW89_BAND_2G) {
19075b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220);
19085b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_FATT, 0xf2);
19095b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1);
19105b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1);
19115b8471acSPing-Ke Shih } else {
19125b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50220);
19135b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SWATT, 0x5);
19145b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_TIA, 0x1);
19155b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TIA, RR_TIA_N6, 0x1);
19165b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RXA_LNA, RFREG_MASK, 0x920FC);
19175b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_XALNA2, RFREG_MASK, 0x002C0);
19185b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_IQGEN, RFREG_MASK, 0x38800);
19195b8471acSPing-Ke Shih }
19205b8471acSPing-Ke Shih
19215b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1);
19225b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1);
19235b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0);
19245b8471acSPing-Ke Shih
19255b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
19265b8471acSPing-Ke Shih "[DPK] ARF 0x0/0x11/0x1a = 0x%x/ 0x%x/ 0x%x\n",
19275b8471acSPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK),
19285b8471acSPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK),
19295b8471acSPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK));
19305b8471acSPing-Ke Shih }
19315b8471acSPing-Ke Shih
_dpk_bypass_rxcfir(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,bool is_bypass)19325b8471acSPing-Ke Shih static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev,
19335b8471acSPing-Ke Shih enum rtw89_rf_path path, bool is_bypass)
19345b8471acSPing-Ke Shih {
19355b8471acSPing-Ke Shih if (is_bypass) {
19365b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
19375b8471acSPing-Ke Shih B_RXIQC_BYPASS2, 0x1);
19385b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8),
19395b8471acSPing-Ke Shih B_RXIQC_BYPASS, 0x1);
19405b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
19415b8471acSPing-Ke Shih "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path,
19425b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
19435b8471acSPing-Ke Shih MASKDWORD));
19445b8471acSPing-Ke Shih } else {
19455b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2);
19465b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS);
19475b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
19485b8471acSPing-Ke Shih "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path,
19495b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8),
19505b8471acSPing-Ke Shih MASKDWORD));
19515b8471acSPing-Ke Shih }
19525b8471acSPing-Ke Shih }
19535b8471acSPing-Ke Shih
19545b8471acSPing-Ke Shih static
_dpk_tpg_sel(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,u8 kidx)19555b8471acSPing-Ke Shih void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
19565b8471acSPing-Ke Shih {
19575b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
19585b8471acSPing-Ke Shih
19595b8471acSPing-Ke Shih if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80)
19605b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F);
19615b8471acSPing-Ke Shih else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40)
19625b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2);
19635b8471acSPing-Ke Shih else
19645b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1);
19655b8471acSPing-Ke Shih
19665b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n",
19675b8471acSPing-Ke Shih dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" :
19685b8471acSPing-Ke Shih dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M");
19695b8471acSPing-Ke Shih }
19705b8471acSPing-Ke Shih
_dpk_table_select(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,u8 kidx,u8 gain)19715b8471acSPing-Ke Shih static void _dpk_table_select(struct rtw89_dev *rtwdev,
19725b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx, u8 gain)
19735b8471acSPing-Ke Shih {
19745b8471acSPing-Ke Shih u8 val;
19755b8471acSPing-Ke Shih
19765b8471acSPing-Ke Shih val = 0x80 + kidx * 0x20 + gain * 0x10;
19775b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val);
19785b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
19795b8471acSPing-Ke Shih "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx,
19805b8471acSPing-Ke Shih gain, val);
19815b8471acSPing-Ke Shih }
19825b8471acSPing-Ke Shih
_dpk_sync_check(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,u8 kidx)19835b8471acSPing-Ke Shih static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx)
19845b8471acSPing-Ke Shih {
19855b8471acSPing-Ke Shih #define DPK_SYNC_TH_DC_I 200
19865b8471acSPing-Ke Shih #define DPK_SYNC_TH_DC_Q 200
19875b8471acSPing-Ke Shih #define DPK_SYNC_TH_CORR 170
19885b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
19895b8471acSPing-Ke Shih u16 dc_i, dc_q;
19905b8471acSPing-Ke Shih u8 corr_val, corr_idx;
19915b8471acSPing-Ke Shih
19925b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL);
19935b8471acSPing-Ke Shih
19945b8471acSPing-Ke Shih corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI);
19955b8471acSPing-Ke Shih corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV);
19965b8471acSPing-Ke Shih
19975b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
19985b8471acSPing-Ke Shih "[DPK] S%d Corr_idx / Corr_val = %d / %d\n",
19995b8471acSPing-Ke Shih path, corr_idx, corr_val);
20005b8471acSPing-Ke Shih
20015b8471acSPing-Ke Shih dpk->corr_idx[path][kidx] = corr_idx;
20025b8471acSPing-Ke Shih dpk->corr_val[path][kidx] = corr_val;
20035b8471acSPing-Ke Shih
20045b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9);
20055b8471acSPing-Ke Shih
20065b8471acSPing-Ke Shih dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI);
20075b8471acSPing-Ke Shih dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ);
20085b8471acSPing-Ke Shih
20095b8471acSPing-Ke Shih dc_i = abs(sign_extend32(dc_i, 11));
20105b8471acSPing-Ke Shih dc_q = abs(sign_extend32(dc_q, 11));
20115b8471acSPing-Ke Shih
20125b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n",
20135b8471acSPing-Ke Shih path, dc_i, dc_q);
20145b8471acSPing-Ke Shih
20155b8471acSPing-Ke Shih dpk->dc_i[path][kidx] = dc_i;
20165b8471acSPing-Ke Shih dpk->dc_q[path][kidx] = dc_q;
20175b8471acSPing-Ke Shih
20185b8471acSPing-Ke Shih if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q ||
20195b8471acSPing-Ke Shih corr_val < DPK_SYNC_TH_CORR)
20205b8471acSPing-Ke Shih return true;
20215b8471acSPing-Ke Shih else
20225b8471acSPing-Ke Shih return false;
20235b8471acSPing-Ke Shih }
20245b8471acSPing-Ke Shih
_dpk_sync(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx)20255b8471acSPing-Ke Shih static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
20265b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx)
20275b8471acSPing-Ke Shih {
20285b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, SYNC);
20295b8471acSPing-Ke Shih
20305b8471acSPing-Ke Shih return _dpk_sync_check(rtwdev, path, kidx);
20315b8471acSPing-Ke Shih }
20325b8471acSPing-Ke Shih
_dpk_dgain_read(struct rtw89_dev * rtwdev)20335b8471acSPing-Ke Shih static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev)
20345b8471acSPing-Ke Shih {
20355b8471acSPing-Ke Shih u16 dgain;
20365b8471acSPing-Ke Shih
20375b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0);
20385b8471acSPing-Ke Shih
20395b8471acSPing-Ke Shih dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI);
20405b8471acSPing-Ke Shih
20415b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain);
20425b8471acSPing-Ke Shih
20435b8471acSPing-Ke Shih return dgain;
20445b8471acSPing-Ke Shih }
20455b8471acSPing-Ke Shih
_dpk_dgain_mapping(struct rtw89_dev * rtwdev,u16 dgain)20465b8471acSPing-Ke Shih static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain)
20475b8471acSPing-Ke Shih {
20485b8471acSPing-Ke Shih static const u16 bnd[15] = {
20495b8471acSPing-Ke Shih 0xbf1, 0xaa5, 0x97d, 0x875, 0x789, 0x6b7, 0x5fc, 0x556,
20505b8471acSPing-Ke Shih 0x4c1, 0x43d, 0x3c7, 0x35e, 0x2ac, 0x262, 0x220
20515b8471acSPing-Ke Shih };
20525b8471acSPing-Ke Shih s8 offset;
20535b8471acSPing-Ke Shih
20545b8471acSPing-Ke Shih if (dgain >= bnd[0])
20555b8471acSPing-Ke Shih offset = 0x6;
20565b8471acSPing-Ke Shih else if (bnd[0] > dgain && dgain >= bnd[1])
20575b8471acSPing-Ke Shih offset = 0x6;
20585b8471acSPing-Ke Shih else if (bnd[1] > dgain && dgain >= bnd[2])
20595b8471acSPing-Ke Shih offset = 0x5;
20605b8471acSPing-Ke Shih else if (bnd[2] > dgain && dgain >= bnd[3])
20615b8471acSPing-Ke Shih offset = 0x4;
20625b8471acSPing-Ke Shih else if (bnd[3] > dgain && dgain >= bnd[4])
20635b8471acSPing-Ke Shih offset = 0x3;
20645b8471acSPing-Ke Shih else if (bnd[4] > dgain && dgain >= bnd[5])
20655b8471acSPing-Ke Shih offset = 0x2;
20665b8471acSPing-Ke Shih else if (bnd[5] > dgain && dgain >= bnd[6])
20675b8471acSPing-Ke Shih offset = 0x1;
20685b8471acSPing-Ke Shih else if (bnd[6] > dgain && dgain >= bnd[7])
20695b8471acSPing-Ke Shih offset = 0x0;
20705b8471acSPing-Ke Shih else if (bnd[7] > dgain && dgain >= bnd[8])
20715b8471acSPing-Ke Shih offset = 0xff;
20725b8471acSPing-Ke Shih else if (bnd[8] > dgain && dgain >= bnd[9])
20735b8471acSPing-Ke Shih offset = 0xfe;
20745b8471acSPing-Ke Shih else if (bnd[9] > dgain && dgain >= bnd[10])
20755b8471acSPing-Ke Shih offset = 0xfd;
20765b8471acSPing-Ke Shih else if (bnd[10] > dgain && dgain >= bnd[11])
20775b8471acSPing-Ke Shih offset = 0xfc;
20785b8471acSPing-Ke Shih else if (bnd[11] > dgain && dgain >= bnd[12])
20795b8471acSPing-Ke Shih offset = 0xfb;
20805b8471acSPing-Ke Shih else if (bnd[12] > dgain && dgain >= bnd[13])
20815b8471acSPing-Ke Shih offset = 0xfa;
20825b8471acSPing-Ke Shih else if (bnd[13] > dgain && dgain >= bnd[14])
20835b8471acSPing-Ke Shih offset = 0xf9;
20845b8471acSPing-Ke Shih else if (bnd[14] > dgain)
20855b8471acSPing-Ke Shih offset = 0xf8;
20865b8471acSPing-Ke Shih else
20875b8471acSPing-Ke Shih offset = 0x0;
20885b8471acSPing-Ke Shih
20895b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain offset = %d\n", offset);
20905b8471acSPing-Ke Shih
20915b8471acSPing-Ke Shih return offset;
20925b8471acSPing-Ke Shih }
20935b8471acSPing-Ke Shih
_dpk_gainloss_read(struct rtw89_dev * rtwdev)20945b8471acSPing-Ke Shih static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev)
20955b8471acSPing-Ke Shih {
20965b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6);
20975b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1);
20985b8471acSPing-Ke Shih
20995b8471acSPing-Ke Shih return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL);
21005b8471acSPing-Ke Shih }
21015b8471acSPing-Ke Shih
_dpk_gainloss(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx)21025b8471acSPing-Ke Shih static void _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
21035b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx)
21045b8471acSPing-Ke Shih {
21055b8471acSPing-Ke Shih _dpk_table_select(rtwdev, path, kidx, 1);
21065b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS);
21075b8471acSPing-Ke Shih }
21085b8471acSPing-Ke Shih
_dpk_kip_preset(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx)21095b8471acSPing-Ke Shih static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
21105b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx)
21115b8471acSPing-Ke Shih {
21125b8471acSPing-Ke Shih _dpk_tpg_sel(rtwdev, path, kidx);
21135b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, KIP_PRESET);
21145b8471acSPing-Ke Shih }
21155b8471acSPing-Ke Shih
_dpk_kip_pwr_clk_on(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)21165b8471acSPing-Ke Shih static void _dpk_kip_pwr_clk_on(struct rtw89_dev *rtwdev,
21175b8471acSPing-Ke Shih enum rtw89_rf_path path)
21185b8471acSPing-Ke Shih {
21195b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080);
21205b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a);
21215b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08);
21225b8471acSPing-Ke Shih
21235b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP Power/CLK on\n");
21245b8471acSPing-Ke Shih }
21255b8471acSPing-Ke Shih
_dpk_kip_set_txagc(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 txagc)21265b8471acSPing-Ke Shih static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
21275b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 txagc)
21285b8471acSPing-Ke Shih {
21295b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXAGC, RFREG_MASK, txagc);
21305b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
21315b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, DPK_TXAGC);
21325b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
21335b8471acSPing-Ke Shih
21345b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] set TXAGC = 0x%x\n", txagc);
21355b8471acSPing-Ke Shih }
21365b8471acSPing-Ke Shih
_dpk_kip_set_rxagc(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)21375b8471acSPing-Ke Shih static void _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
21385b8471acSPing-Ke Shih enum rtw89_rf_path path)
21395b8471acSPing-Ke Shih {
21405b8471acSPing-Ke Shih u32 tmp;
21415b8471acSPing-Ke Shih
21425b8471acSPing-Ke Shih tmp = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK);
21435b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, tmp);
21445b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1);
21455b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, DPK_RXAGC);
21465b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0);
21475b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL_V1, 0x8);
21485b8471acSPing-Ke Shih
21495b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
21505b8471acSPing-Ke Shih "[DPK] set RXBB = 0x%x (RF0x0[9:5] = 0x%x)\n",
21515b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB_V1),
21525b8471acSPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB));
21535b8471acSPing-Ke Shih }
21545b8471acSPing-Ke Shih
_dpk_set_offset(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,s8 gain_offset)21555b8471acSPing-Ke Shih static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
21565b8471acSPing-Ke Shih enum rtw89_rf_path path, s8 gain_offset)
21575b8471acSPing-Ke Shih {
21585b8471acSPing-Ke Shih u8 txagc;
21595b8471acSPing-Ke Shih
21605b8471acSPing-Ke Shih txagc = rtw89_read_rf(rtwdev, path, RR_TXAGC, RFREG_MASK);
21615b8471acSPing-Ke Shih
21625b8471acSPing-Ke Shih if (txagc - gain_offset < DPK_TXAGC_LOWER)
21635b8471acSPing-Ke Shih txagc = DPK_TXAGC_LOWER;
21645b8471acSPing-Ke Shih else if (txagc - gain_offset > DPK_TXAGC_UPPER)
21655b8471acSPing-Ke Shih txagc = DPK_TXAGC_UPPER;
21665b8471acSPing-Ke Shih else
21675b8471acSPing-Ke Shih txagc = txagc - gain_offset;
21685b8471acSPing-Ke Shih
21695b8471acSPing-Ke Shih _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
21705b8471acSPing-Ke Shih
21715b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n",
21725b8471acSPing-Ke Shih gain_offset, txagc);
21735b8471acSPing-Ke Shih return txagc;
21745b8471acSPing-Ke Shih }
21755b8471acSPing-Ke Shih
_dpk_pas_read(struct rtw89_dev * rtwdev,bool is_check)21765b8471acSPing-Ke Shih static bool _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check)
21775b8471acSPing-Ke Shih {
21785b8471acSPing-Ke Shih u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0;
21795b8471acSPing-Ke Shih u8 i;
21805b8471acSPing-Ke Shih
21815b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06);
21825b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0);
21835b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08);
21845b8471acSPing-Ke Shih
21855b8471acSPing-Ke Shih if (is_check) {
21865b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00);
21875b8471acSPing-Ke Shih val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
21885b8471acSPing-Ke Shih val1_i = abs(sign_extend32(val1_i, 11));
21895b8471acSPing-Ke Shih val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
21905b8471acSPing-Ke Shih val1_q = abs(sign_extend32(val1_q, 11));
21915b8471acSPing-Ke Shih
21925b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f);
21935b8471acSPing-Ke Shih val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD);
21945b8471acSPing-Ke Shih val2_i = abs(sign_extend32(val2_i, 11));
21955b8471acSPing-Ke Shih val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD);
21965b8471acSPing-Ke Shih val2_q = abs(sign_extend32(val2_q, 11));
21975b8471acSPing-Ke Shih
21985b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n",
21995b8471acSPing-Ke Shih phy_div(val1_i * val1_i + val1_q * val1_q,
22005b8471acSPing-Ke Shih val2_i * val2_i + val2_q * val2_q));
22015b8471acSPing-Ke Shih } else {
22025b8471acSPing-Ke Shih for (i = 0; i < 32; i++) {
22035b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i);
22045b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
22055b8471acSPing-Ke Shih "[DPK] PAS_Read[%02d]= 0x%08x\n", i,
22065b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD));
22075b8471acSPing-Ke Shih }
22085b8471acSPing-Ke Shih }
22095b8471acSPing-Ke Shih
22105b8471acSPing-Ke Shih if (val1_i * val1_i + val1_q * val1_q >=
22115b8471acSPing-Ke Shih (val2_i * val2_i + val2_q * val2_q) * 8 / 5)
22125b8471acSPing-Ke Shih return true;
22135b8471acSPing-Ke Shih
22145b8471acSPing-Ke Shih return false;
22155b8471acSPing-Ke Shih }
22165b8471acSPing-Ke Shih
_dpk_agc(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx,u8 init_txagc,bool loss_only)22175b8471acSPing-Ke Shih static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
22185b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx, u8 init_txagc,
22195b8471acSPing-Ke Shih bool loss_only)
22205b8471acSPing-Ke Shih {
22215b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
22225b8471acSPing-Ke Shih u8 step = DPK_AGC_STEP_SYNC_DGAIN;
22235b8471acSPing-Ke Shih u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0;
22245b8471acSPing-Ke Shih u8 goout = 0, agc_cnt = 0, limited_rxbb = 0;
22255b8471acSPing-Ke Shih u16 dgain = 0;
22265b8471acSPing-Ke Shih s8 offset;
22275b8471acSPing-Ke Shih int limit = 200;
22285b8471acSPing-Ke Shih
22295b8471acSPing-Ke Shih tmp_txagc = init_txagc;
22305b8471acSPing-Ke Shih
22315b8471acSPing-Ke Shih do {
22325b8471acSPing-Ke Shih switch (step) {
22335b8471acSPing-Ke Shih case DPK_AGC_STEP_SYNC_DGAIN:
22345b8471acSPing-Ke Shih if (_dpk_sync(rtwdev, phy, path, kidx)) {
22355b8471acSPing-Ke Shih tmp_txagc = 0xff;
22365b8471acSPing-Ke Shih goout = 1;
22375b8471acSPing-Ke Shih break;
22385b8471acSPing-Ke Shih }
22395b8471acSPing-Ke Shih
22405b8471acSPing-Ke Shih dgain = _dpk_dgain_read(rtwdev);
22415b8471acSPing-Ke Shih
22425b8471acSPing-Ke Shih if (loss_only == 1 || limited_rxbb == 1)
22435b8471acSPing-Ke Shih step = DPK_AGC_STEP_GAIN_LOSS_IDX;
22445b8471acSPing-Ke Shih else
22455b8471acSPing-Ke Shih step = DPK_AGC_STEP_GAIN_ADJ;
22465b8471acSPing-Ke Shih break;
22475b8471acSPing-Ke Shih
22485b8471acSPing-Ke Shih case DPK_AGC_STEP_GAIN_ADJ:
22495b8471acSPing-Ke Shih tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD,
22505b8471acSPing-Ke Shih RFREG_MASKRXBB);
22515b8471acSPing-Ke Shih offset = _dpk_dgain_mapping(rtwdev, dgain);
22525b8471acSPing-Ke Shih
22535b8471acSPing-Ke Shih if (tmp_rxbb + offset > 0x1f) {
22545b8471acSPing-Ke Shih tmp_rxbb = 0x1f;
22555b8471acSPing-Ke Shih limited_rxbb = 1;
22565b8471acSPing-Ke Shih } else if (tmp_rxbb + offset < 0) {
22575b8471acSPing-Ke Shih tmp_rxbb = 0;
22585b8471acSPing-Ke Shih limited_rxbb = 1;
22595b8471acSPing-Ke Shih } else {
22605b8471acSPing-Ke Shih tmp_rxbb = tmp_rxbb + offset;
22615b8471acSPing-Ke Shih }
22625b8471acSPing-Ke Shih
22635b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASKRXBB,
22645b8471acSPing-Ke Shih tmp_rxbb);
22655b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
22665b8471acSPing-Ke Shih "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, tmp_rxbb);
22675b8471acSPing-Ke Shih if (offset || agc_cnt == 0) {
22685b8471acSPing-Ke Shih if (chan->band_width < RTW89_CHANNEL_WIDTH_80)
22695b8471acSPing-Ke Shih _dpk_bypass_rxcfir(rtwdev, path, true);
22705b8471acSPing-Ke Shih else
22715b8471acSPing-Ke Shih _dpk_lbk_rxiqk(rtwdev, phy, path);
22725b8471acSPing-Ke Shih }
22735b8471acSPing-Ke Shih if (dgain > 1922 || dgain < 342)
22745b8471acSPing-Ke Shih step = DPK_AGC_STEP_SYNC_DGAIN;
22755b8471acSPing-Ke Shih else
22765b8471acSPing-Ke Shih step = DPK_AGC_STEP_GAIN_LOSS_IDX;
22775b8471acSPing-Ke Shih
22785b8471acSPing-Ke Shih agc_cnt++;
22795b8471acSPing-Ke Shih break;
22805b8471acSPing-Ke Shih
22815b8471acSPing-Ke Shih case DPK_AGC_STEP_GAIN_LOSS_IDX:
22825b8471acSPing-Ke Shih _dpk_gainloss(rtwdev, phy, path, kidx);
22835b8471acSPing-Ke Shih tmp_gl_idx = _dpk_gainloss_read(rtwdev);
22845b8471acSPing-Ke Shih
22855b8471acSPing-Ke Shih if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) ||
22865b8471acSPing-Ke Shih tmp_gl_idx >= 7)
22875b8471acSPing-Ke Shih step = DPK_AGC_STEP_GL_GT_CRITERION;
22885b8471acSPing-Ke Shih else if (tmp_gl_idx == 0)
22895b8471acSPing-Ke Shih step = DPK_AGC_STEP_GL_LT_CRITERION;
22905b8471acSPing-Ke Shih else
22915b8471acSPing-Ke Shih step = DPK_AGC_STEP_SET_TX_GAIN;
22925b8471acSPing-Ke Shih break;
22935b8471acSPing-Ke Shih
22945b8471acSPing-Ke Shih case DPK_AGC_STEP_GL_GT_CRITERION:
22955b8471acSPing-Ke Shih if (tmp_txagc == 0x2e) {
22965b8471acSPing-Ke Shih goout = 1;
22975b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
22985b8471acSPing-Ke Shih "[DPK] Txagc@lower bound!!\n");
22995b8471acSPing-Ke Shih } else {
23005b8471acSPing-Ke Shih tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0x3);
23015b8471acSPing-Ke Shih }
23025b8471acSPing-Ke Shih step = DPK_AGC_STEP_GAIN_LOSS_IDX;
23035b8471acSPing-Ke Shih agc_cnt++;
23045b8471acSPing-Ke Shih break;
23055b8471acSPing-Ke Shih
23065b8471acSPing-Ke Shih case DPK_AGC_STEP_GL_LT_CRITERION:
23075b8471acSPing-Ke Shih if (tmp_txagc == 0x3f) {
23085b8471acSPing-Ke Shih goout = 1;
23095b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
23105b8471acSPing-Ke Shih "[DPK] Txagc@upper bound!!\n");
23115b8471acSPing-Ke Shih } else {
23125b8471acSPing-Ke Shih tmp_txagc = _dpk_set_offset(rtwdev, phy, path, 0xfe);
23135b8471acSPing-Ke Shih }
23145b8471acSPing-Ke Shih step = DPK_AGC_STEP_GAIN_LOSS_IDX;
23155b8471acSPing-Ke Shih agc_cnt++;
23165b8471acSPing-Ke Shih break;
23175b8471acSPing-Ke Shih case DPK_AGC_STEP_SET_TX_GAIN:
23185b8471acSPing-Ke Shih tmp_txagc = _dpk_set_offset(rtwdev, phy, path, tmp_gl_idx);
23195b8471acSPing-Ke Shih goout = 1;
23205b8471acSPing-Ke Shih agc_cnt++;
23215b8471acSPing-Ke Shih break;
23225b8471acSPing-Ke Shih
23235b8471acSPing-Ke Shih default:
23245b8471acSPing-Ke Shih goout = 1;
23255b8471acSPing-Ke Shih break;
23265b8471acSPing-Ke Shih }
23275b8471acSPing-Ke Shih } while (!goout && agc_cnt < 6 && limit-- > 0);
23285b8471acSPing-Ke Shih
23295b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
23305b8471acSPing-Ke Shih "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc,
23315b8471acSPing-Ke Shih tmp_rxbb);
23325b8471acSPing-Ke Shih
23335b8471acSPing-Ke Shih return tmp_txagc;
23345b8471acSPing-Ke Shih }
23355b8471acSPing-Ke Shih
_dpk_set_mdpd_para(struct rtw89_dev * rtwdev,u8 order)23365b8471acSPing-Ke Shih static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order)
23375b8471acSPing-Ke Shih {
23385b8471acSPing-Ke Shih switch (order) {
23395b8471acSPing-Ke Shih case 0:
23405b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
23415b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3);
23425b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1);
23435b8471acSPing-Ke Shih break;
23445b8471acSPing-Ke Shih case 1:
23455b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
23465b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN);
23475b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN);
23485b8471acSPing-Ke Shih break;
23495b8471acSPing-Ke Shih case 2:
23505b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order);
23515b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN);
23525b8471acSPing-Ke Shih rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN);
23535b8471acSPing-Ke Shih break;
23545b8471acSPing-Ke Shih default:
23555b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
23565b8471acSPing-Ke Shih "[DPK] Wrong MDPD order!!(0x%x)\n", order);
23575b8471acSPing-Ke Shih break;
23585b8471acSPing-Ke Shih }
23595b8471acSPing-Ke Shih
23605b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
23615b8471acSPing-Ke Shih "[DPK] Set MDPD order to 0x%x for IDL\n", order);
23625b8471acSPing-Ke Shih }
23635b8471acSPing-Ke Shih
_dpk_idl_mpa(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx,u8 gain)23645b8471acSPing-Ke Shih static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
23655b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx, u8 gain)
23665b8471acSPing-Ke Shih {
23675b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
23685b8471acSPing-Ke Shih
23695b8471acSPing-Ke Shih if (dpk->bp[path][kidx].bw < RTW89_CHANNEL_WIDTH_80 &&
23705b8471acSPing-Ke Shih dpk->bp[path][kidx].band == RTW89_BAND_5G)
23715b8471acSPing-Ke Shih _dpk_set_mdpd_para(rtwdev, 0x2);
23725b8471acSPing-Ke Shih else
23735b8471acSPing-Ke Shih _dpk_set_mdpd_para(rtwdev, 0x0);
23745b8471acSPing-Ke Shih
23755b8471acSPing-Ke Shih _dpk_one_shot(rtwdev, phy, path, MDPK_IDL);
23765b8471acSPing-Ke Shih }
23775b8471acSPing-Ke Shih
_dpk_fill_result(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 kidx,u8 gain,u8 txagc)23785b8471acSPing-Ke Shih static void _dpk_fill_result(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
23795b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 kidx, u8 gain, u8 txagc)
23805b8471acSPing-Ke Shih {
23815b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
23825b8471acSPing-Ke Shih const u16 pwsf = 0x78;
23835b8471acSPing-Ke Shih u8 gs = dpk->dpk_gs[phy];
23845b8471acSPing-Ke Shih
23855b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8),
23865b8471acSPing-Ke Shih B_COEF_SEL_MDPD, kidx);
23875b8471acSPing-Ke Shih
23885b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
23895b8471acSPing-Ke Shih "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc,
23905b8471acSPing-Ke Shih pwsf, gs);
23915b8471acSPing-Ke Shih
23925b8471acSPing-Ke Shih dpk->bp[path][kidx].txagc_dpk = txagc;
23935b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8),
23945b8471acSPing-Ke Shih 0x3F << ((gain << 3) + (kidx << 4)), txagc);
23955b8471acSPing-Ke Shih
23965b8471acSPing-Ke Shih dpk->bp[path][kidx].pwsf = pwsf;
23975b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2),
23985b8471acSPing-Ke Shih 0x1FF << (gain << 4), pwsf);
23995b8471acSPing-Ke Shih
24005b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1);
24015b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0);
24025b8471acSPing-Ke Shih
24035b8471acSPing-Ke Shih dpk->bp[path][kidx].gs = gs;
24045b8471acSPing-Ke Shih if (dpk->dpk_gs[phy] == 0x7f)
24055b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
24065b8471acSPing-Ke Shih MASKDWORD, 0x007f7f7f);
24075b8471acSPing-Ke Shih else
24085b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
24095b8471acSPing-Ke Shih MASKDWORD, 0x005b5b5b);
24105b8471acSPing-Ke Shih
24115b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2),
24125b8471acSPing-Ke Shih B_DPD_ORDER_V1, _dpk_order_convert(rtwdev));
24135b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD, 0x0);
24145b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL, 0x0);
24155b8471acSPing-Ke Shih }
24165b8471acSPing-Ke Shih
_dpk_reload_check(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)24175b8471acSPing-Ke Shih static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
24185b8471acSPing-Ke Shih enum rtw89_rf_path path)
24195b8471acSPing-Ke Shih {
24205b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
24215b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
24225b8471acSPing-Ke Shih bool is_reload = false;
24235b8471acSPing-Ke Shih u8 idx, cur_band, cur_ch;
24245b8471acSPing-Ke Shih
24255b8471acSPing-Ke Shih cur_band = chan->band_type;
24265b8471acSPing-Ke Shih cur_ch = chan->channel;
24275b8471acSPing-Ke Shih
24285b8471acSPing-Ke Shih for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) {
24295b8471acSPing-Ke Shih if (cur_band != dpk->bp[path][idx].band ||
24305b8471acSPing-Ke Shih cur_ch != dpk->bp[path][idx].ch)
24315b8471acSPing-Ke Shih continue;
24325b8471acSPing-Ke Shih
24335b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8),
24345b8471acSPing-Ke Shih B_COEF_SEL_MDPD, idx);
24355b8471acSPing-Ke Shih dpk->cur_idx[path] = idx;
24365b8471acSPing-Ke Shih is_reload = true;
24375b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
24385b8471acSPing-Ke Shih "[DPK] reload S%d[%d] success\n", path, idx);
24395b8471acSPing-Ke Shih }
24405b8471acSPing-Ke Shih
24415b8471acSPing-Ke Shih return is_reload;
24425b8471acSPing-Ke Shih }
24435b8471acSPing-Ke Shih
_dpk_main(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u8 gain)24445b8471acSPing-Ke Shih static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
24455b8471acSPing-Ke Shih enum rtw89_rf_path path, u8 gain)
24465b8471acSPing-Ke Shih {
24475b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
24485b8471acSPing-Ke Shih u8 txagc = 0x38, kidx = dpk->cur_idx[path];
24495b8471acSPing-Ke Shih bool is_fail = false;
24505b8471acSPing-Ke Shih
24515b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
24525b8471acSPing-Ke Shih "[DPK] ========= S%d[%d] DPK Start =========\n", path, kidx);
24535b8471acSPing-Ke Shih
24545b8471acSPing-Ke Shih _rfk_rf_direct_cntrl(rtwdev, path, false);
24555b8471acSPing-Ke Shih _rfk_drf_direct_cntrl(rtwdev, path, false);
24565b8471acSPing-Ke Shih
24575b8471acSPing-Ke Shih _dpk_kip_pwr_clk_on(rtwdev, path);
24585b8471acSPing-Ke Shih _dpk_kip_set_txagc(rtwdev, phy, path, txagc);
24595b8471acSPing-Ke Shih _dpk_rf_setting(rtwdev, gain, path, kidx);
24605b8471acSPing-Ke Shih _dpk_rx_dck(rtwdev, phy, path);
24615b8471acSPing-Ke Shih
24625b8471acSPing-Ke Shih _dpk_kip_preset(rtwdev, phy, path, kidx);
24635b8471acSPing-Ke Shih _dpk_kip_set_rxagc(rtwdev, phy, path);
24645b8471acSPing-Ke Shih _dpk_table_select(rtwdev, path, kidx, gain);
24655b8471acSPing-Ke Shih
24665b8471acSPing-Ke Shih txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false);
24675b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Adjust txagc = 0x%x\n", txagc);
24685b8471acSPing-Ke Shih
24695b8471acSPing-Ke Shih if (txagc == 0xff) {
24705b8471acSPing-Ke Shih is_fail = true;
24715b8471acSPing-Ke Shih } else {
24725b8471acSPing-Ke Shih _dpk_get_thermal(rtwdev, kidx, path);
24735b8471acSPing-Ke Shih
24745b8471acSPing-Ke Shih _dpk_idl_mpa(rtwdev, phy, path, kidx, gain);
24755b8471acSPing-Ke Shih
24765b8471acSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX);
24775b8471acSPing-Ke Shih
24785b8471acSPing-Ke Shih _dpk_fill_result(rtwdev, phy, path, kidx, gain, txagc);
24795b8471acSPing-Ke Shih }
24805b8471acSPing-Ke Shih
24815b8471acSPing-Ke Shih if (!is_fail)
24825b8471acSPing-Ke Shih dpk->bp[path][kidx].path_ok = true;
24835b8471acSPing-Ke Shih else
24845b8471acSPing-Ke Shih dpk->bp[path][kidx].path_ok = false;
24855b8471acSPing-Ke Shih
24865b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx,
24875b8471acSPing-Ke Shih is_fail ? "Check" : "Success");
24885b8471acSPing-Ke Shih
24895b8471acSPing-Ke Shih return is_fail;
24905b8471acSPing-Ke Shih }
24915b8471acSPing-Ke Shih
_dpk_cal_select(struct rtw89_dev * rtwdev,bool force,enum rtw89_phy_idx phy,u8 kpath)24925b8471acSPing-Ke Shih static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force,
24935b8471acSPing-Ke Shih enum rtw89_phy_idx phy, u8 kpath)
24945b8471acSPing-Ke Shih {
24955b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
24965b8471acSPing-Ke Shih static const u32 kip_reg[] = {0x813c, 0x8124, 0x8120};
24975b8471acSPing-Ke Shih u32 kip_bkup[RTW8852B_DPK_RF_PATH][RTW8852B_DPK_KIP_REG_NUM] = {};
24985b8471acSPing-Ke Shih u32 backup_rf_val[RTW8852B_DPK_RF_PATH][BACKUP_RF_REGS_NR];
24995b8471acSPing-Ke Shih u32 backup_bb_val[BACKUP_BB_REGS_NR];
25005b8471acSPing-Ke Shih bool is_fail = true, reloaded[RTW8852B_DPK_RF_PATH] = {};
25015b8471acSPing-Ke Shih u8 path;
25025b8471acSPing-Ke Shih
25035b8471acSPing-Ke Shih if (dpk->is_dpk_reload_en) {
25045b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
25055b8471acSPing-Ke Shih reloaded[path] = _dpk_reload_check(rtwdev, phy, path);
25065b8471acSPing-Ke Shih if (!reloaded[path] && dpk->bp[path][0].ch)
25075b8471acSPing-Ke Shih dpk->cur_idx[path] = !dpk->cur_idx[path];
25085b8471acSPing-Ke Shih else
25095b8471acSPing-Ke Shih _dpk_onoff(rtwdev, path, false);
25105b8471acSPing-Ke Shih }
25115b8471acSPing-Ke Shih } else {
25125b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++)
25135b8471acSPing-Ke Shih dpk->cur_idx[path] = 0;
25145b8471acSPing-Ke Shih }
25155b8471acSPing-Ke Shih
25165b8471acSPing-Ke Shih _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]);
25175b8471acSPing-Ke Shih
25185b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
25195b8471acSPing-Ke Shih _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path);
25205b8471acSPing-Ke Shih _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path);
25215b8471acSPing-Ke Shih _dpk_information(rtwdev, phy, path);
25225b8471acSPing-Ke Shih if (rtwdev->is_tssi_mode[path])
25235b8471acSPing-Ke Shih _dpk_tssi_pause(rtwdev, path, true);
25245b8471acSPing-Ke Shih }
25255b8471acSPing-Ke Shih
25265b8471acSPing-Ke Shih _dpk_bb_afe_setting(rtwdev, phy, path, kpath);
25275b8471acSPing-Ke Shih
25285b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
25295b8471acSPing-Ke Shih is_fail = _dpk_main(rtwdev, phy, path, 1);
25305b8471acSPing-Ke Shih _dpk_onoff(rtwdev, path, is_fail);
25315b8471acSPing-Ke Shih }
25325b8471acSPing-Ke Shih
25335b8471acSPing-Ke Shih _dpk_bb_afe_restore(rtwdev, phy, path, kpath);
25345b8471acSPing-Ke Shih _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]);
25355b8471acSPing-Ke Shih
25365b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
25375b8471acSPing-Ke Shih _dpk_kip_restore(rtwdev, path);
25385b8471acSPing-Ke Shih _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path);
25395b8471acSPing-Ke Shih _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path);
25405b8471acSPing-Ke Shih if (rtwdev->is_tssi_mode[path])
25415b8471acSPing-Ke Shih _dpk_tssi_pause(rtwdev, path, false);
25425b8471acSPing-Ke Shih }
25435b8471acSPing-Ke Shih }
25445b8471acSPing-Ke Shih
_dpk_bypass_check(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)25455b8471acSPing-Ke Shih static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
25465b8471acSPing-Ke Shih {
25475b8471acSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
25485b8471acSPing-Ke Shih struct rtw89_fem_info *fem = &rtwdev->fem;
25495b8471acSPing-Ke Shih
25505b8471acSPing-Ke Shih if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) {
25515b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
25525b8471acSPing-Ke Shih "[DPK] Skip DPK due to 2G_ext_PA exist!!\n");
25535b8471acSPing-Ke Shih return true;
25545b8471acSPing-Ke Shih } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) {
25555b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
25565b8471acSPing-Ke Shih "[DPK] Skip DPK due to 5G_ext_PA exist!!\n");
25575b8471acSPing-Ke Shih return true;
25585b8471acSPing-Ke Shih } else if (fem->epa_6g && chan->band_type == RTW89_BAND_6G) {
25595b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
25605b8471acSPing-Ke Shih "[DPK] Skip DPK due to 6G_ext_PA exist!!\n");
25615b8471acSPing-Ke Shih return true;
25625b8471acSPing-Ke Shih }
25635b8471acSPing-Ke Shih
25645b8471acSPing-Ke Shih return false;
25655b8471acSPing-Ke Shih }
25665b8471acSPing-Ke Shih
_dpk_force_bypass(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)25675b8471acSPing-Ke Shih static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
25685b8471acSPing-Ke Shih {
25695b8471acSPing-Ke Shih u8 path, kpath;
25705b8471acSPing-Ke Shih
25715b8471acSPing-Ke Shih kpath = _kpath(rtwdev, phy);
25725b8471acSPing-Ke Shih
25735b8471acSPing-Ke Shih for (path = 0; path < RTW8852B_DPK_RF_PATH; path++) {
25745b8471acSPing-Ke Shih if (kpath & BIT(path))
25755b8471acSPing-Ke Shih _dpk_onoff(rtwdev, path, true);
25765b8471acSPing-Ke Shih }
25775b8471acSPing-Ke Shih }
25785b8471acSPing-Ke Shih
_dpk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,bool force)25795b8471acSPing-Ke Shih static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force)
25805b8471acSPing-Ke Shih {
25815b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
25825b8471acSPing-Ke Shih "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n",
25835b8471acSPing-Ke Shih RTW8852B_DPK_VER, rtwdev->hal.cv,
25845b8471acSPing-Ke Shih RTW8852B_RF_REL_VERSION);
25855b8471acSPing-Ke Shih
25865b8471acSPing-Ke Shih if (_dpk_bypass_check(rtwdev, phy))
25875b8471acSPing-Ke Shih _dpk_force_bypass(rtwdev, phy);
25885b8471acSPing-Ke Shih else
25895b8471acSPing-Ke Shih _dpk_cal_select(rtwdev, force, phy, RF_AB);
25905b8471acSPing-Ke Shih }
25915b8471acSPing-Ke Shih
_dpk_track(struct rtw89_dev * rtwdev)25925b8471acSPing-Ke Shih static void _dpk_track(struct rtw89_dev *rtwdev)
25935b8471acSPing-Ke Shih {
25945b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
25955b8471acSPing-Ke Shih s8 txagc_bb, txagc_bb_tp, ini_diff = 0, txagc_ofst;
25965b8471acSPing-Ke Shih s8 delta_ther[2] = {};
25975b8471acSPing-Ke Shih u8 trk_idx, txagc_rf;
25985b8471acSPing-Ke Shih u8 path, kidx;
25995b8471acSPing-Ke Shih u16 pwsf[2];
26005b8471acSPing-Ke Shih u8 cur_ther;
26015b8471acSPing-Ke Shih u32 tmp;
26025b8471acSPing-Ke Shih
26035b8471acSPing-Ke Shih for (path = 0; path < RF_PATH_NUM_8852B; path++) {
26045b8471acSPing-Ke Shih kidx = dpk->cur_idx[path];
26055b8471acSPing-Ke Shih
26065b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26075b8471acSPing-Ke Shih "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n",
26085b8471acSPing-Ke Shih path, kidx, dpk->bp[path][kidx].ch);
26095b8471acSPing-Ke Shih
26105b8471acSPing-Ke Shih cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]);
26115b8471acSPing-Ke Shih
26125b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26135b8471acSPing-Ke Shih "[DPK_TRK] thermal now = %d\n", cur_ther);
26145b8471acSPing-Ke Shih
26155b8471acSPing-Ke Shih if (dpk->bp[path][kidx].ch && cur_ther)
26165b8471acSPing-Ke Shih delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther;
26175b8471acSPing-Ke Shih
26185b8471acSPing-Ke Shih if (dpk->bp[path][kidx].band == RTW89_BAND_2G)
26195b8471acSPing-Ke Shih delta_ther[path] = delta_ther[path] * 3 / 2;
26205b8471acSPing-Ke Shih else
26215b8471acSPing-Ke Shih delta_ther[path] = delta_ther[path] * 5 / 2;
26225b8471acSPing-Ke Shih
26235b8471acSPing-Ke Shih txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
26245b8471acSPing-Ke Shih 0x0000003f);
26255b8471acSPing-Ke Shih
26265b8471acSPing-Ke Shih if (rtwdev->is_tssi_mode[path]) {
26275b8471acSPing-Ke Shih trk_idx = rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK);
26285b8471acSPing-Ke Shih
26295b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26305b8471acSPing-Ke Shih "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n",
26315b8471acSPing-Ke Shih txagc_rf, trk_idx);
26325b8471acSPing-Ke Shih
26335b8471acSPing-Ke Shih txagc_bb =
26345b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
26355b8471acSPing-Ke Shih MASKBYTE2);
26365b8471acSPing-Ke Shih txagc_bb_tp =
26375b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TXAGC_TP + (path << 13),
26385b8471acSPing-Ke Shih B_TXAGC_TP);
26395b8471acSPing-Ke Shih
26405b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26415b8471acSPing-Ke Shih "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n",
26425b8471acSPing-Ke Shih txagc_bb_tp, txagc_bb);
26435b8471acSPing-Ke Shih
26445b8471acSPing-Ke Shih txagc_ofst =
26455b8471acSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13),
26465b8471acSPing-Ke Shih MASKBYTE3);
26475b8471acSPing-Ke Shih
26485b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26495b8471acSPing-Ke Shih "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n",
26505b8471acSPing-Ke Shih txagc_ofst, delta_ther[path]);
26515b8471acSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8),
26525b8471acSPing-Ke Shih B_DPD_COM_OF);
26535b8471acSPing-Ke Shih if (tmp == 0x1) {
26545b8471acSPing-Ke Shih txagc_ofst = 0;
26555b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26565b8471acSPing-Ke Shih "[DPK_TRK] HW txagc offset mode\n");
26575b8471acSPing-Ke Shih }
26585b8471acSPing-Ke Shih
26595b8471acSPing-Ke Shih if (txagc_rf && cur_ther)
26605b8471acSPing-Ke Shih ini_diff = txagc_ofst + (delta_ther[path]);
26615b8471acSPing-Ke Shih
26625b8471acSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev,
26635b8471acSPing-Ke Shih R_P0_TXDPD + (path << 13),
26645b8471acSPing-Ke Shih B_P0_TXDPD);
26655b8471acSPing-Ke Shih if (tmp == 0x0) {
26665b8471acSPing-Ke Shih pwsf[0] = dpk->bp[path][kidx].pwsf +
26675b8471acSPing-Ke Shih txagc_bb_tp - txagc_bb + ini_diff;
26685b8471acSPing-Ke Shih pwsf[1] = dpk->bp[path][kidx].pwsf +
26695b8471acSPing-Ke Shih txagc_bb_tp - txagc_bb + ini_diff;
26705b8471acSPing-Ke Shih } else {
26715b8471acSPing-Ke Shih pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff;
26725b8471acSPing-Ke Shih pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff;
26735b8471acSPing-Ke Shih }
26745b8471acSPing-Ke Shih
26755b8471acSPing-Ke Shih } else {
26765b8471acSPing-Ke Shih pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
26775b8471acSPing-Ke Shih pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff;
26785b8471acSPing-Ke Shih }
26795b8471acSPing-Ke Shih
26805b8471acSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS);
26815b8471acSPing-Ke Shih if (!tmp && txagc_rf) {
26825b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK,
26835b8471acSPing-Ke Shih "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n",
26845b8471acSPing-Ke Shih pwsf[0], pwsf[1]);
26855b8471acSPing-Ke Shih
26865b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev,
26875b8471acSPing-Ke Shih R_DPD_BND + (path << 8) + (kidx << 2),
26885b8471acSPing-Ke Shih B_DPD_BND_0, pwsf[0]);
26895b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev,
26905b8471acSPing-Ke Shih R_DPD_BND + (path << 8) + (kidx << 2),
26915b8471acSPing-Ke Shih B_DPD_BND_1, pwsf[1]);
26925b8471acSPing-Ke Shih }
26935b8471acSPing-Ke Shih }
26945b8471acSPing-Ke Shih }
26955b8471acSPing-Ke Shih
_set_dpd_backoff(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)26965b8471acSPing-Ke Shih static void _set_dpd_backoff(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
26975b8471acSPing-Ke Shih {
26985b8471acSPing-Ke Shih struct rtw89_dpk_info *dpk = &rtwdev->dpk;
26995b8471acSPing-Ke Shih u8 tx_scale, ofdm_bkof, path, kpath;
27005b8471acSPing-Ke Shih
27015b8471acSPing-Ke Shih kpath = _kpath(rtwdev, phy);
27025b8471acSPing-Ke Shih
27035b8471acSPing-Ke Shih ofdm_bkof = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_OFDM);
27045b8471acSPing-Ke Shih tx_scale = rtw89_phy_read32_mask(rtwdev, R_DPD_BF + (phy << 13), B_DPD_BF_SCA);
27055b8471acSPing-Ke Shih
27065b8471acSPing-Ke Shih if (ofdm_bkof + tx_scale >= 44) {
27075b8471acSPing-Ke Shih /* move dpd backoff to bb, and set dpd backoff to 0 */
27085b8471acSPing-Ke Shih dpk->dpk_gs[phy] = 0x7f;
27095b8471acSPing-Ke Shih for (path = 0; path < RF_PATH_NUM_8852B; path++) {
27105b8471acSPing-Ke Shih if (!(kpath & BIT(path)))
27115b8471acSPing-Ke Shih continue;
27125b8471acSPing-Ke Shih
27135b8471acSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8),
27145b8471acSPing-Ke Shih B_DPD_CFG, 0x7f7f7f);
27155b8471acSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
27165b8471acSPing-Ke Shih "[RFK] Set S%d DPD backoff to 0dB\n", path);
27175b8471acSPing-Ke Shih }
27185b8471acSPing-Ke Shih } else {
27195b8471acSPing-Ke Shih dpk->dpk_gs[phy] = 0x5b;
27205b8471acSPing-Ke Shih }
27215b8471acSPing-Ke Shih }
27225b8471acSPing-Ke Shih
_tssi_rf_setting(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27237f18a70dSPing-Ke Shih static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
27247f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27257f18a70dSPing-Ke Shih {
27267f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
27277f18a70dSPing-Ke Shih enum rtw89_band band = chan->band_type;
27287f18a70dSPing-Ke Shih
27297f18a70dSPing-Ke Shih if (band == RTW89_BAND_2G)
27307f18a70dSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1);
27317f18a70dSPing-Ke Shih else
27327f18a70dSPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1);
27337f18a70dSPing-Ke Shih }
27347f18a70dSPing-Ke Shih
_tssi_set_sys(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27357f18a70dSPing-Ke Shih static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
27367f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27377f18a70dSPing-Ke Shih {
27387f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
27397f18a70dSPing-Ke Shih enum rtw89_band band = chan->band_type;
27407f18a70dSPing-Ke Shih
27417f18a70dSPing-Ke Shih rtw89_rfk_parser(rtwdev, &rtw8852b_tssi_sys_defs_tbl);
27427f18a70dSPing-Ke Shih
27437f18a70dSPing-Ke Shih if (path == RF_PATH_A)
27447f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
27457f18a70dSPing-Ke Shih &rtw8852b_tssi_sys_a_defs_2g_tbl,
27467f18a70dSPing-Ke Shih &rtw8852b_tssi_sys_a_defs_5g_tbl);
27477f18a70dSPing-Ke Shih else
27487f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
27497f18a70dSPing-Ke Shih &rtw8852b_tssi_sys_b_defs_2g_tbl,
27507f18a70dSPing-Ke Shih &rtw8852b_tssi_sys_b_defs_5g_tbl);
27517f18a70dSPing-Ke Shih }
27527f18a70dSPing-Ke Shih
_tssi_ini_txpwr_ctrl_bb(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27537f18a70dSPing-Ke Shih static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev,
27547f18a70dSPing-Ke Shih enum rtw89_phy_idx phy,
27557f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27567f18a70dSPing-Ke Shih {
27577f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
27587f18a70dSPing-Ke Shih &rtw8852b_tssi_init_txpwr_defs_a_tbl,
27597f18a70dSPing-Ke Shih &rtw8852b_tssi_init_txpwr_defs_b_tbl);
27607f18a70dSPing-Ke Shih }
27617f18a70dSPing-Ke Shih
_tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27627f18a70dSPing-Ke Shih static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev,
27637f18a70dSPing-Ke Shih enum rtw89_phy_idx phy,
27647f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27657f18a70dSPing-Ke Shih {
27667f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
27677f18a70dSPing-Ke Shih &rtw8852b_tssi_init_txpwr_he_tb_defs_a_tbl,
27687f18a70dSPing-Ke Shih &rtw8852b_tssi_init_txpwr_he_tb_defs_b_tbl);
27697f18a70dSPing-Ke Shih }
27707f18a70dSPing-Ke Shih
_tssi_set_dck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27717f18a70dSPing-Ke Shih static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
27727f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27737f18a70dSPing-Ke Shih {
27747f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
27757f18a70dSPing-Ke Shih &rtw8852b_tssi_dck_defs_a_tbl,
27767f18a70dSPing-Ke Shih &rtw8852b_tssi_dck_defs_b_tbl);
27777f18a70dSPing-Ke Shih }
27787f18a70dSPing-Ke Shih
_tssi_set_tmeter_tbl(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)27797f18a70dSPing-Ke Shih static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
27807f18a70dSPing-Ke Shih enum rtw89_rf_path path)
27817f18a70dSPing-Ke Shih {
27827f18a70dSPing-Ke Shih #define RTW8852B_TSSI_GET_VAL(ptr, idx) \
27837f18a70dSPing-Ke Shih ({ \
27847f18a70dSPing-Ke Shih s8 *__ptr = (ptr); \
27857f18a70dSPing-Ke Shih u8 __idx = (idx), __i, __v; \
27867f18a70dSPing-Ke Shih u32 __val = 0; \
27877f18a70dSPing-Ke Shih for (__i = 0; __i < 4; __i++) { \
27887f18a70dSPing-Ke Shih __v = (__ptr[__idx + __i]); \
27897f18a70dSPing-Ke Shih __val |= (__v << (8 * __i)); \
27907f18a70dSPing-Ke Shih } \
27917f18a70dSPing-Ke Shih __val; \
27927f18a70dSPing-Ke Shih })
27937f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
27947f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
27957f18a70dSPing-Ke Shih u8 ch = chan->channel;
27967f18a70dSPing-Ke Shih u8 subband = chan->subband_type;
27977f18a70dSPing-Ke Shih const s8 *thm_up_a = NULL;
27987f18a70dSPing-Ke Shih const s8 *thm_down_a = NULL;
27997f18a70dSPing-Ke Shih const s8 *thm_up_b = NULL;
28007f18a70dSPing-Ke Shih const s8 *thm_down_b = NULL;
28017f18a70dSPing-Ke Shih u8 thermal = 0xff;
28027f18a70dSPing-Ke Shih s8 thm_ofst[64] = {0};
28037f18a70dSPing-Ke Shih u32 tmp = 0;
28047f18a70dSPing-Ke Shih u8 i, j;
28057f18a70dSPing-Ke Shih
28067f18a70dSPing-Ke Shih switch (subband) {
28077f18a70dSPing-Ke Shih default:
28087f18a70dSPing-Ke Shih case RTW89_CH_2G:
28097f18a70dSPing-Ke Shih thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_p;
28107f18a70dSPing-Ke Shih thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_2ga_n;
28117f18a70dSPing-Ke Shih thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_p;
28127f18a70dSPing-Ke Shih thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_2gb_n;
28137f18a70dSPing-Ke Shih break;
28147f18a70dSPing-Ke Shih case RTW89_CH_5G_BAND_1:
28157f18a70dSPing-Ke Shih thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[0];
28167f18a70dSPing-Ke Shih thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[0];
28177f18a70dSPing-Ke Shih thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[0];
28187f18a70dSPing-Ke Shih thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[0];
28197f18a70dSPing-Ke Shih break;
28207f18a70dSPing-Ke Shih case RTW89_CH_5G_BAND_3:
28217f18a70dSPing-Ke Shih thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[1];
28227f18a70dSPing-Ke Shih thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[1];
28237f18a70dSPing-Ke Shih thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[1];
28247f18a70dSPing-Ke Shih thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[1];
28257f18a70dSPing-Ke Shih break;
28267f18a70dSPing-Ke Shih case RTW89_CH_5G_BAND_4:
28277f18a70dSPing-Ke Shih thm_up_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_p[2];
28287f18a70dSPing-Ke Shih thm_down_a = rtw89_8852b_trk_cfg.delta_swingidx_5ga_n[2];
28297f18a70dSPing-Ke Shih thm_up_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_p[2];
28307f18a70dSPing-Ke Shih thm_down_b = rtw89_8852b_trk_cfg.delta_swingidx_5gb_n[2];
28317f18a70dSPing-Ke Shih break;
28327f18a70dSPing-Ke Shih }
28337f18a70dSPing-Ke Shih
28347f18a70dSPing-Ke Shih if (path == RF_PATH_A) {
28357f18a70dSPing-Ke Shih thermal = tssi_info->thermal[RF_PATH_A];
28367f18a70dSPing-Ke Shih
28377f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
28387f18a70dSPing-Ke Shih "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal);
28397f18a70dSPing-Ke Shih
28407f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0);
28417f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1);
28427f18a70dSPing-Ke Shih
28437f18a70dSPing-Ke Shih if (thermal == 0xff) {
28447f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32);
28457f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32);
28467f18a70dSPing-Ke Shih
28477f18a70dSPing-Ke Shih for (i = 0; i < 64; i += 4) {
28487f18a70dSPing-Ke Shih rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0);
28497f18a70dSPing-Ke Shih
28507f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
28517f18a70dSPing-Ke Shih "[TSSI] write 0x%x val=0x%08x\n",
28527f18a70dSPing-Ke Shih R_P0_TSSI_BASE + i, 0x0);
28537f18a70dSPing-Ke Shih }
28547f18a70dSPing-Ke Shih
28557f18a70dSPing-Ke Shih } else {
28567f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal);
28577f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL,
28587f18a70dSPing-Ke Shih thermal);
28597f18a70dSPing-Ke Shih
28607f18a70dSPing-Ke Shih i = 0;
28617f18a70dSPing-Ke Shih for (j = 0; j < 32; j++)
28627f18a70dSPing-Ke Shih thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
28637f18a70dSPing-Ke Shih -thm_down_a[i++] :
28647f18a70dSPing-Ke Shih -thm_down_a[DELTA_SWINGIDX_SIZE - 1];
28657f18a70dSPing-Ke Shih
28667f18a70dSPing-Ke Shih i = 1;
28677f18a70dSPing-Ke Shih for (j = 63; j >= 32; j--)
28687f18a70dSPing-Ke Shih thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
28697f18a70dSPing-Ke Shih thm_up_a[i++] :
28707f18a70dSPing-Ke Shih thm_up_a[DELTA_SWINGIDX_SIZE - 1];
28717f18a70dSPing-Ke Shih
28727f18a70dSPing-Ke Shih for (i = 0; i < 64; i += 4) {
28737f18a70dSPing-Ke Shih tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i);
28747f18a70dSPing-Ke Shih rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp);
28757f18a70dSPing-Ke Shih
28767f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
28777f18a70dSPing-Ke Shih "[TSSI] write 0x%x val=0x%08x\n",
28787f18a70dSPing-Ke Shih 0x5c00 + i, tmp);
28797f18a70dSPing-Ke Shih }
28807f18a70dSPing-Ke Shih }
28817f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1);
28827f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0);
28837f18a70dSPing-Ke Shih
28847f18a70dSPing-Ke Shih } else {
28857f18a70dSPing-Ke Shih thermal = tssi_info->thermal[RF_PATH_B];
28867f18a70dSPing-Ke Shih
28877f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
28887f18a70dSPing-Ke Shih "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal);
28897f18a70dSPing-Ke Shih
28907f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0);
28917f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1);
28927f18a70dSPing-Ke Shih
28937f18a70dSPing-Ke Shih if (thermal == 0xff) {
28947f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32);
28957f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32);
28967f18a70dSPing-Ke Shih
28977f18a70dSPing-Ke Shih for (i = 0; i < 64; i += 4) {
28987f18a70dSPing-Ke Shih rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0);
28997f18a70dSPing-Ke Shih
29007f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
29017f18a70dSPing-Ke Shih "[TSSI] write 0x%x val=0x%08x\n",
29027f18a70dSPing-Ke Shih 0x7c00 + i, 0x0);
29037f18a70dSPing-Ke Shih }
29047f18a70dSPing-Ke Shih
29057f18a70dSPing-Ke Shih } else {
29067f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal);
29077f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL,
29087f18a70dSPing-Ke Shih thermal);
29097f18a70dSPing-Ke Shih
29107f18a70dSPing-Ke Shih i = 0;
29117f18a70dSPing-Ke Shih for (j = 0; j < 32; j++)
29127f18a70dSPing-Ke Shih thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
29137f18a70dSPing-Ke Shih -thm_down_b[i++] :
29147f18a70dSPing-Ke Shih -thm_down_b[DELTA_SWINGIDX_SIZE - 1];
29157f18a70dSPing-Ke Shih
29167f18a70dSPing-Ke Shih i = 1;
29177f18a70dSPing-Ke Shih for (j = 63; j >= 32; j--)
29187f18a70dSPing-Ke Shih thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ?
29197f18a70dSPing-Ke Shih thm_up_b[i++] :
29207f18a70dSPing-Ke Shih thm_up_b[DELTA_SWINGIDX_SIZE - 1];
29217f18a70dSPing-Ke Shih
29227f18a70dSPing-Ke Shih for (i = 0; i < 64; i += 4) {
29237f18a70dSPing-Ke Shih tmp = RTW8852B_TSSI_GET_VAL(thm_ofst, i);
29247f18a70dSPing-Ke Shih rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp);
29257f18a70dSPing-Ke Shih
29267f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
29277f18a70dSPing-Ke Shih "[TSSI] write 0x%x val=0x%08x\n",
29287f18a70dSPing-Ke Shih 0x7c00 + i, tmp);
29297f18a70dSPing-Ke Shih }
29307f18a70dSPing-Ke Shih }
29317f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1);
29327f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0);
29337f18a70dSPing-Ke Shih }
29347f18a70dSPing-Ke Shih #undef RTW8852B_TSSI_GET_VAL
29357f18a70dSPing-Ke Shih }
29367f18a70dSPing-Ke Shih
_tssi_set_dac_gain_tbl(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)29377f18a70dSPing-Ke Shih static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
29387f18a70dSPing-Ke Shih enum rtw89_rf_path path)
29397f18a70dSPing-Ke Shih {
29407f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
29417f18a70dSPing-Ke Shih &rtw8852b_tssi_dac_gain_defs_a_tbl,
29427f18a70dSPing-Ke Shih &rtw8852b_tssi_dac_gain_defs_b_tbl);
29437f18a70dSPing-Ke Shih }
29447f18a70dSPing-Ke Shih
_tssi_slope_cal_org(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)29457f18a70dSPing-Ke Shih static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
29467f18a70dSPing-Ke Shih enum rtw89_rf_path path)
29477f18a70dSPing-Ke Shih {
29487f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
29497f18a70dSPing-Ke Shih enum rtw89_band band = chan->band_type;
29507f18a70dSPing-Ke Shih
29517f18a70dSPing-Ke Shih if (path == RF_PATH_A)
29527f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
29537f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_a_defs_2g_tbl,
29547f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_a_defs_5g_tbl);
29557f18a70dSPing-Ke Shih else
29567f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G,
29577f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_b_defs_2g_tbl,
29587f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_b_defs_5g_tbl);
29597f18a70dSPing-Ke Shih }
29607f18a70dSPing-Ke Shih
_tssi_alignment_default(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,bool all)29617f18a70dSPing-Ke Shih static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
29627f18a70dSPing-Ke Shih enum rtw89_rf_path path, bool all)
29637f18a70dSPing-Ke Shih {
29647f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
29657f18a70dSPing-Ke Shih enum rtw89_band band = chan->band_type;
29667f18a70dSPing-Ke Shih const struct rtw89_rfk_tbl *tbl = NULL;
29677f18a70dSPing-Ke Shih u8 ch = chan->channel;
29687f18a70dSPing-Ke Shih
29697f18a70dSPing-Ke Shih if (path == RF_PATH_A) {
29707f18a70dSPing-Ke Shih if (band == RTW89_BAND_2G) {
29717f18a70dSPing-Ke Shih if (all)
29727f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_2g_all_defs_tbl;
29737f18a70dSPing-Ke Shih else
29747f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_2g_part_defs_tbl;
29757f18a70dSPing-Ke Shih } else if (ch >= 36 && ch <= 64) {
29767f18a70dSPing-Ke Shih if (all)
29777f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g1_all_defs_tbl;
29787f18a70dSPing-Ke Shih else
29797f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g1_part_defs_tbl;
29807f18a70dSPing-Ke Shih } else if (ch >= 100 && ch <= 144) {
29817f18a70dSPing-Ke Shih if (all)
29827f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g2_all_defs_tbl;
29837f18a70dSPing-Ke Shih else
29847f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g2_part_defs_tbl;
29857f18a70dSPing-Ke Shih } else if (ch >= 149 && ch <= 177) {
29867f18a70dSPing-Ke Shih if (all)
29877f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g3_all_defs_tbl;
29887f18a70dSPing-Ke Shih else
29897f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_a_5g3_part_defs_tbl;
29907f18a70dSPing-Ke Shih }
29917f18a70dSPing-Ke Shih } else {
29927f18a70dSPing-Ke Shih if (ch >= 1 && ch <= 14) {
29937f18a70dSPing-Ke Shih if (all)
29947f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_2g_all_defs_tbl;
29957f18a70dSPing-Ke Shih else
29967f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_2g_part_defs_tbl;
29977f18a70dSPing-Ke Shih } else if (ch >= 36 && ch <= 64) {
29987f18a70dSPing-Ke Shih if (all)
29997f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g1_all_defs_tbl;
30007f18a70dSPing-Ke Shih else
30017f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g1_part_defs_tbl;
30027f18a70dSPing-Ke Shih } else if (ch >= 100 && ch <= 144) {
30037f18a70dSPing-Ke Shih if (all)
30047f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g2_all_defs_tbl;
30057f18a70dSPing-Ke Shih else
30067f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g2_part_defs_tbl;
30077f18a70dSPing-Ke Shih } else if (ch >= 149 && ch <= 177) {
30087f18a70dSPing-Ke Shih if (all)
30097f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g3_all_defs_tbl;
30107f18a70dSPing-Ke Shih else
30117f18a70dSPing-Ke Shih tbl = &rtw8852b_tssi_align_b_5g3_part_defs_tbl;
30127f18a70dSPing-Ke Shih }
30137f18a70dSPing-Ke Shih }
30147f18a70dSPing-Ke Shih
30157f18a70dSPing-Ke Shih if (tbl)
30167f18a70dSPing-Ke Shih rtw89_rfk_parser(rtwdev, tbl);
30177f18a70dSPing-Ke Shih }
30187f18a70dSPing-Ke Shih
_tssi_set_tssi_slope(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)30197f18a70dSPing-Ke Shih static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
30207f18a70dSPing-Ke Shih enum rtw89_rf_path path)
30217f18a70dSPing-Ke Shih {
30227f18a70dSPing-Ke Shih rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A,
30237f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_defs_a_tbl,
30247f18a70dSPing-Ke Shih &rtw8852b_tssi_slope_defs_b_tbl);
30257f18a70dSPing-Ke Shih }
30267f18a70dSPing-Ke Shih
_tssi_set_tssi_track(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)30277f18a70dSPing-Ke Shih static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
30287f18a70dSPing-Ke Shih enum rtw89_rf_path path)
30297f18a70dSPing-Ke Shih {
30307f18a70dSPing-Ke Shih if (path == RF_PATH_A)
30317f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSIC, B_P0_TSSIC_BYPASS, 0x0);
30327f18a70dSPing-Ke Shih else
30337f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSIC, B_P1_TSSIC_BYPASS, 0x0);
30347f18a70dSPing-Ke Shih }
30357f18a70dSPing-Ke Shih
_tssi_set_txagc_offset_mv_avg(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)30367f18a70dSPing-Ke Shih static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev,
30377f18a70dSPing-Ke Shih enum rtw89_phy_idx phy,
30387f18a70dSPing-Ke Shih enum rtw89_rf_path path)
30397f18a70dSPing-Ke Shih {
30407f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI, "======>%s path=%d\n", __func__,
30417f18a70dSPing-Ke Shih path);
30427f18a70dSPing-Ke Shih
30437f18a70dSPing-Ke Shih if (path == RF_PATH_A)
30447f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_MIX, 0x010);
30457f18a70dSPing-Ke Shih else
30467f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_RFCTM_DEL, 0x010);
30477f18a70dSPing-Ke Shih }
30487f18a70dSPing-Ke Shih
_tssi_enable(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)30497f18a70dSPing-Ke Shih static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
30507f18a70dSPing-Ke Shih {
30517f18a70dSPing-Ke Shih u8 i;
30527f18a70dSPing-Ke Shih
30537f18a70dSPing-Ke Shih for (i = 0; i < RF_PATH_NUM_8852B; i++) {
30547f18a70dSPing-Ke Shih _tssi_set_tssi_track(rtwdev, phy, i);
30557f18a70dSPing-Ke Shih _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i);
30567f18a70dSPing-Ke Shih
30577f18a70dSPing-Ke Shih if (i == RF_PATH_A) {
30587f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG,
30597f18a70dSPing-Ke Shih B_P0_TSSI_MV_CLR, 0x0);
30607f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
30617f18a70dSPing-Ke Shih B_P0_TSSI_EN, 0x0);
30627f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG,
30637f18a70dSPing-Ke Shih B_P0_TSSI_EN, 0x1);
30647f18a70dSPing-Ke Shih rtw89_write_rf(rtwdev, i, RR_TXGA_V1,
30657f18a70dSPing-Ke Shih RR_TXGA_V1_TRK_EN, 0x1);
30667f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
30677f18a70dSPing-Ke Shih B_P0_TSSI_RFC, 0x3);
30687f18a70dSPing-Ke Shih
30697f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
30707f18a70dSPing-Ke Shih B_P0_TSSI_OFT, 0xc0);
30717f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
30727f18a70dSPing-Ke Shih B_P0_TSSI_OFT_EN, 0x0);
30737f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK,
30747f18a70dSPing-Ke Shih B_P0_TSSI_OFT_EN, 0x1);
30757f18a70dSPing-Ke Shih
30767f18a70dSPing-Ke Shih rtwdev->is_tssi_mode[RF_PATH_A] = true;
30777f18a70dSPing-Ke Shih } else {
30787f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG,
30797f18a70dSPing-Ke Shih B_P1_TSSI_MV_CLR, 0x0);
30807f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
30817f18a70dSPing-Ke Shih B_P1_TSSI_EN, 0x0);
30827f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG,
30837f18a70dSPing-Ke Shih B_P1_TSSI_EN, 0x1);
30847f18a70dSPing-Ke Shih rtw89_write_rf(rtwdev, i, RR_TXGA_V1,
30857f18a70dSPing-Ke Shih RR_TXGA_V1_TRK_EN, 0x1);
30867f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
30877f18a70dSPing-Ke Shih B_P1_TSSI_RFC, 0x3);
30887f18a70dSPing-Ke Shih
30897f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
30907f18a70dSPing-Ke Shih B_P1_TSSI_OFT, 0xc0);
30917f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
30927f18a70dSPing-Ke Shih B_P1_TSSI_OFT_EN, 0x0);
30937f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK,
30947f18a70dSPing-Ke Shih B_P1_TSSI_OFT_EN, 0x1);
30957f18a70dSPing-Ke Shih
30967f18a70dSPing-Ke Shih rtwdev->is_tssi_mode[RF_PATH_B] = true;
30977f18a70dSPing-Ke Shih }
30987f18a70dSPing-Ke Shih }
30997f18a70dSPing-Ke Shih }
31007f18a70dSPing-Ke Shih
_tssi_disable(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)31017f18a70dSPing-Ke Shih static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
31027f18a70dSPing-Ke Shih {
31037f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0);
31047f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x1);
31057f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1);
31067f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_EN, 0x0);
31077f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_RFC, 0x1);
31087f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_CLR, 0x1);
31097f18a70dSPing-Ke Shih
31107f18a70dSPing-Ke Shih rtwdev->is_tssi_mode[RF_PATH_A] = false;
31117f18a70dSPing-Ke Shih rtwdev->is_tssi_mode[RF_PATH_B] = false;
31127f18a70dSPing-Ke Shih }
31137f18a70dSPing-Ke Shih
_tssi_get_cck_group(struct rtw89_dev * rtwdev,u8 ch)31147f18a70dSPing-Ke Shih static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch)
31157f18a70dSPing-Ke Shih {
31167f18a70dSPing-Ke Shih switch (ch) {
31177f18a70dSPing-Ke Shih case 1 ... 2:
31187f18a70dSPing-Ke Shih return 0;
31197f18a70dSPing-Ke Shih case 3 ... 5:
31207f18a70dSPing-Ke Shih return 1;
31217f18a70dSPing-Ke Shih case 6 ... 8:
31227f18a70dSPing-Ke Shih return 2;
31237f18a70dSPing-Ke Shih case 9 ... 11:
31247f18a70dSPing-Ke Shih return 3;
31257f18a70dSPing-Ke Shih case 12 ... 13:
31267f18a70dSPing-Ke Shih return 4;
31277f18a70dSPing-Ke Shih case 14:
31287f18a70dSPing-Ke Shih return 5;
31297f18a70dSPing-Ke Shih }
31307f18a70dSPing-Ke Shih
31317f18a70dSPing-Ke Shih return 0;
31327f18a70dSPing-Ke Shih }
31337f18a70dSPing-Ke Shih
31347f18a70dSPing-Ke Shih #define TSSI_EXTRA_GROUP_BIT (BIT(31))
31357f18a70dSPing-Ke Shih #define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx))
31367f18a70dSPing-Ke Shih #define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT)
31377f18a70dSPing-Ke Shih #define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT)
31387f18a70dSPing-Ke Shih #define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1)
31397f18a70dSPing-Ke Shih
_tssi_get_ofdm_group(struct rtw89_dev * rtwdev,u8 ch)31407f18a70dSPing-Ke Shih static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch)
31417f18a70dSPing-Ke Shih {
31427f18a70dSPing-Ke Shih switch (ch) {
31437f18a70dSPing-Ke Shih case 1 ... 2:
31447f18a70dSPing-Ke Shih return 0;
31457f18a70dSPing-Ke Shih case 3 ... 5:
31467f18a70dSPing-Ke Shih return 1;
31477f18a70dSPing-Ke Shih case 6 ... 8:
31487f18a70dSPing-Ke Shih return 2;
31497f18a70dSPing-Ke Shih case 9 ... 11:
31507f18a70dSPing-Ke Shih return 3;
31517f18a70dSPing-Ke Shih case 12 ... 14:
31527f18a70dSPing-Ke Shih return 4;
31537f18a70dSPing-Ke Shih case 36 ... 40:
31547f18a70dSPing-Ke Shih return 5;
31557f18a70dSPing-Ke Shih case 41 ... 43:
31567f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(5);
31577f18a70dSPing-Ke Shih case 44 ... 48:
31587f18a70dSPing-Ke Shih return 6;
31597f18a70dSPing-Ke Shih case 49 ... 51:
31607f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(6);
31617f18a70dSPing-Ke Shih case 52 ... 56:
31627f18a70dSPing-Ke Shih return 7;
31637f18a70dSPing-Ke Shih case 57 ... 59:
31647f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(7);
31657f18a70dSPing-Ke Shih case 60 ... 64:
31667f18a70dSPing-Ke Shih return 8;
31677f18a70dSPing-Ke Shih case 100 ... 104:
31687f18a70dSPing-Ke Shih return 9;
31697f18a70dSPing-Ke Shih case 105 ... 107:
31707f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(9);
31717f18a70dSPing-Ke Shih case 108 ... 112:
31727f18a70dSPing-Ke Shih return 10;
31737f18a70dSPing-Ke Shih case 113 ... 115:
31747f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(10);
31757f18a70dSPing-Ke Shih case 116 ... 120:
31767f18a70dSPing-Ke Shih return 11;
31777f18a70dSPing-Ke Shih case 121 ... 123:
31787f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(11);
31797f18a70dSPing-Ke Shih case 124 ... 128:
31807f18a70dSPing-Ke Shih return 12;
31817f18a70dSPing-Ke Shih case 129 ... 131:
31827f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(12);
31837f18a70dSPing-Ke Shih case 132 ... 136:
31847f18a70dSPing-Ke Shih return 13;
31857f18a70dSPing-Ke Shih case 137 ... 139:
31867f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(13);
31877f18a70dSPing-Ke Shih case 140 ... 144:
31887f18a70dSPing-Ke Shih return 14;
31897f18a70dSPing-Ke Shih case 149 ... 153:
31907f18a70dSPing-Ke Shih return 15;
31917f18a70dSPing-Ke Shih case 154 ... 156:
31927f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(15);
31937f18a70dSPing-Ke Shih case 157 ... 161:
31947f18a70dSPing-Ke Shih return 16;
31957f18a70dSPing-Ke Shih case 162 ... 164:
31967f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(16);
31977f18a70dSPing-Ke Shih case 165 ... 169:
31987f18a70dSPing-Ke Shih return 17;
31997f18a70dSPing-Ke Shih case 170 ... 172:
32007f18a70dSPing-Ke Shih return TSSI_EXTRA_GROUP(17);
32017f18a70dSPing-Ke Shih case 173 ... 177:
32027f18a70dSPing-Ke Shih return 18;
32037f18a70dSPing-Ke Shih }
32047f18a70dSPing-Ke Shih
32057f18a70dSPing-Ke Shih return 0;
32067f18a70dSPing-Ke Shih }
32077f18a70dSPing-Ke Shih
_tssi_get_trim_group(struct rtw89_dev * rtwdev,u8 ch)32087f18a70dSPing-Ke Shih static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch)
32097f18a70dSPing-Ke Shih {
32107f18a70dSPing-Ke Shih switch (ch) {
32117f18a70dSPing-Ke Shih case 1 ... 8:
32127f18a70dSPing-Ke Shih return 0;
32137f18a70dSPing-Ke Shih case 9 ... 14:
32147f18a70dSPing-Ke Shih return 1;
32157f18a70dSPing-Ke Shih case 36 ... 48:
32167f18a70dSPing-Ke Shih return 2;
32177f18a70dSPing-Ke Shih case 52 ... 64:
32187f18a70dSPing-Ke Shih return 3;
32197f18a70dSPing-Ke Shih case 100 ... 112:
32207f18a70dSPing-Ke Shih return 4;
32217f18a70dSPing-Ke Shih case 116 ... 128:
32227f18a70dSPing-Ke Shih return 5;
32237f18a70dSPing-Ke Shih case 132 ... 144:
32247f18a70dSPing-Ke Shih return 6;
32257f18a70dSPing-Ke Shih case 149 ... 177:
32267f18a70dSPing-Ke Shih return 7;
32277f18a70dSPing-Ke Shih }
32287f18a70dSPing-Ke Shih
32297f18a70dSPing-Ke Shih return 0;
32307f18a70dSPing-Ke Shih }
32317f18a70dSPing-Ke Shih
_tssi_get_ofdm_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)32327f18a70dSPing-Ke Shih static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
32337f18a70dSPing-Ke Shih enum rtw89_rf_path path)
32347f18a70dSPing-Ke Shih {
32357f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
32367f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
32377f18a70dSPing-Ke Shih u8 ch = chan->channel;
32387f18a70dSPing-Ke Shih u32 gidx, gidx_1st, gidx_2nd;
32397f18a70dSPing-Ke Shih s8 de_1st;
32407f18a70dSPing-Ke Shih s8 de_2nd;
32417f18a70dSPing-Ke Shih s8 val;
32427f18a70dSPing-Ke Shih
32437f18a70dSPing-Ke Shih gidx = _tssi_get_ofdm_group(rtwdev, ch);
32447f18a70dSPing-Ke Shih
32457f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32467f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx);
32477f18a70dSPing-Ke Shih
32487f18a70dSPing-Ke Shih if (IS_TSSI_EXTRA_GROUP(gidx)) {
32497f18a70dSPing-Ke Shih gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx);
32507f18a70dSPing-Ke Shih gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx);
32517f18a70dSPing-Ke Shih de_1st = tssi_info->tssi_mcs[path][gidx_1st];
32527f18a70dSPing-Ke Shih de_2nd = tssi_info->tssi_mcs[path][gidx_2nd];
32537f18a70dSPing-Ke Shih val = (de_1st + de_2nd) / 2;
32547f18a70dSPing-Ke Shih
32557f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32567f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n",
32577f18a70dSPing-Ke Shih path, val, de_1st, de_2nd);
32587f18a70dSPing-Ke Shih } else {
32597f18a70dSPing-Ke Shih val = tssi_info->tssi_mcs[path][gidx];
32607f18a70dSPing-Ke Shih
32617f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32627f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val);
32637f18a70dSPing-Ke Shih }
32647f18a70dSPing-Ke Shih
32657f18a70dSPing-Ke Shih return val;
32667f18a70dSPing-Ke Shih }
32677f18a70dSPing-Ke Shih
_tssi_get_ofdm_trim_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)32687f18a70dSPing-Ke Shih static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
32697f18a70dSPing-Ke Shih enum rtw89_rf_path path)
32707f18a70dSPing-Ke Shih {
32717f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
32727f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
32737f18a70dSPing-Ke Shih u8 ch = chan->channel;
32747f18a70dSPing-Ke Shih u32 tgidx, tgidx_1st, tgidx_2nd;
32757f18a70dSPing-Ke Shih s8 tde_1st;
32767f18a70dSPing-Ke Shih s8 tde_2nd;
32777f18a70dSPing-Ke Shih s8 val;
32787f18a70dSPing-Ke Shih
32797f18a70dSPing-Ke Shih tgidx = _tssi_get_trim_group(rtwdev, ch);
32807f18a70dSPing-Ke Shih
32817f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32827f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n",
32837f18a70dSPing-Ke Shih path, tgidx);
32847f18a70dSPing-Ke Shih
32857f18a70dSPing-Ke Shih if (IS_TSSI_EXTRA_GROUP(tgidx)) {
32867f18a70dSPing-Ke Shih tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx);
32877f18a70dSPing-Ke Shih tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx);
32887f18a70dSPing-Ke Shih tde_1st = tssi_info->tssi_trim[path][tgidx_1st];
32897f18a70dSPing-Ke Shih tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd];
32907f18a70dSPing-Ke Shih val = (tde_1st + tde_2nd) / 2;
32917f18a70dSPing-Ke Shih
32927f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32937f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n",
32947f18a70dSPing-Ke Shih path, val, tde_1st, tde_2nd);
32957f18a70dSPing-Ke Shih } else {
32967f18a70dSPing-Ke Shih val = tssi_info->tssi_trim[path][tgidx];
32977f18a70dSPing-Ke Shih
32987f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
32997f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs trim_de=%d\n",
33007f18a70dSPing-Ke Shih path, val);
33017f18a70dSPing-Ke Shih }
33027f18a70dSPing-Ke Shih
33037f18a70dSPing-Ke Shih return val;
33047f18a70dSPing-Ke Shih }
33057f18a70dSPing-Ke Shih
_tssi_set_efuse_to_de(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)33067f18a70dSPing-Ke Shih static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
33077f18a70dSPing-Ke Shih {
33087f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
33097f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
33107f18a70dSPing-Ke Shih u8 ch = chan->channel;
33117f18a70dSPing-Ke Shih u8 gidx;
33127f18a70dSPing-Ke Shih s8 ofdm_de;
33137f18a70dSPing-Ke Shih s8 trim_de;
33147f18a70dSPing-Ke Shih s32 val;
33157f18a70dSPing-Ke Shih u32 i;
33167f18a70dSPing-Ke Shih
33177f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n",
33187f18a70dSPing-Ke Shih phy, ch);
33197f18a70dSPing-Ke Shih
33207f18a70dSPing-Ke Shih for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
33217f18a70dSPing-Ke Shih gidx = _tssi_get_cck_group(rtwdev, ch);
33227f18a70dSPing-Ke Shih trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
33237f18a70dSPing-Ke Shih val = tssi_info->tssi_cck[i][gidx] + trim_de;
33247f18a70dSPing-Ke Shih
33257f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
33267f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n",
33277f18a70dSPing-Ke Shih i, gidx, tssi_info->tssi_cck[i][gidx], trim_de);
33287f18a70dSPing-Ke Shih
33297f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val);
33307f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val);
33317f18a70dSPing-Ke Shih
33327f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
33337f18a70dSPing-Ke Shih "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n",
33347f18a70dSPing-Ke Shih _tssi_de_cck_long[i],
33357f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i],
33367f18a70dSPing-Ke Shih _TSSI_DE_MASK));
33377f18a70dSPing-Ke Shih
33387f18a70dSPing-Ke Shih ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i);
33397f18a70dSPing-Ke Shih trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i);
33407f18a70dSPing-Ke Shih val = ofdm_de + trim_de;
33417f18a70dSPing-Ke Shih
33427f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
33437f18a70dSPing-Ke Shih "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n",
33447f18a70dSPing-Ke Shih i, ofdm_de, trim_de);
33457f18a70dSPing-Ke Shih
33467f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val);
33477f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val);
33487f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val);
33497f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val);
33507f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val);
33517f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val);
33527f18a70dSPing-Ke Shih
33537f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI,
33547f18a70dSPing-Ke Shih "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n",
33557f18a70dSPing-Ke Shih _tssi_de_mcs_20m[i],
33567f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i],
33577f18a70dSPing-Ke Shih _TSSI_DE_MASK));
33587f18a70dSPing-Ke Shih }
33597f18a70dSPing-Ke Shih }
33607f18a70dSPing-Ke Shih
_tssi_alimentk_dump_result(struct rtw89_dev * rtwdev,enum rtw89_rf_path path)33617f18a70dSPing-Ke Shih static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path)
33627f18a70dSPing-Ke Shih {
33637f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
33647f18a70dSPing-Ke Shih "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n"
33657f18a70dSPing-Ke Shih "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n",
33667f18a70dSPing-Ke Shih R_TSSI_PA_K1 + (path << 13),
33677f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD),
33687f18a70dSPing-Ke Shih R_TSSI_PA_K2 + (path << 13),
33697f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD),
33707f18a70dSPing-Ke Shih R_P0_TSSI_ALIM1 + (path << 13),
33717f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD),
33727f18a70dSPing-Ke Shih R_P0_TSSI_ALIM3 + (path << 13),
33737f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD),
33747f18a70dSPing-Ke Shih R_TSSI_PA_K5 + (path << 13),
33757f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD),
33767f18a70dSPing-Ke Shih R_P0_TSSI_ALIM2 + (path << 13),
33777f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD),
33787f18a70dSPing-Ke Shih R_P0_TSSI_ALIM4 + (path << 13),
33797f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD),
33807f18a70dSPing-Ke Shih R_TSSI_PA_K8 + (path << 13),
33817f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD));
33827f18a70dSPing-Ke Shih }
33837f18a70dSPing-Ke Shih
_tssi_alimentk_done(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)33847f18a70dSPing-Ke Shih static void _tssi_alimentk_done(struct rtw89_dev *rtwdev,
33857f18a70dSPing-Ke Shih enum rtw89_phy_idx phy, enum rtw89_rf_path path)
33867f18a70dSPing-Ke Shih {
33877f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
33887f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
33897f18a70dSPing-Ke Shih u8 channel = chan->channel;
33907f18a70dSPing-Ke Shih u8 band;
33917f18a70dSPing-Ke Shih
33927f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
33937f18a70dSPing-Ke Shih "======>%s phy=%d path=%d\n", __func__, phy, path);
33947f18a70dSPing-Ke Shih
33957f18a70dSPing-Ke Shih if (channel >= 1 && channel <= 14)
33967f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
33977f18a70dSPing-Ke Shih else if (channel >= 36 && channel <= 64)
33987f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GL;
33997f18a70dSPing-Ke Shih else if (channel >= 100 && channel <= 144)
34007f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GM;
34017f18a70dSPing-Ke Shih else if (channel >= 149 && channel <= 177)
34027f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GH;
34037f18a70dSPing-Ke Shih else
34047f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
34057f18a70dSPing-Ke Shih
34067f18a70dSPing-Ke Shih if (tssi_info->alignment_done[path][band]) {
34077f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD,
34087f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][0]);
34097f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD,
34107f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][1]);
34117f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD,
34127f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][2]);
34137f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD,
34147f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][3]);
34157f18a70dSPing-Ke Shih }
34167f18a70dSPing-Ke Shih
34177f18a70dSPing-Ke Shih _tssi_alimentk_dump_result(rtwdev, path);
34187f18a70dSPing-Ke Shih }
34197f18a70dSPing-Ke Shih
_tssi_hw_tx(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,u16 cnt,u16 period,s16 pwr_dbm,u8 enable)34207f18a70dSPing-Ke Shih static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
34217f18a70dSPing-Ke Shih enum rtw89_rf_path path, u16 cnt, u16 period, s16 pwr_dbm,
34227f18a70dSPing-Ke Shih u8 enable)
34237f18a70dSPing-Ke Shih {
34247f18a70dSPing-Ke Shih enum rtw89_rf_path_bit rx_path;
34257f18a70dSPing-Ke Shih
34267f18a70dSPing-Ke Shih if (path == RF_PATH_A)
34277f18a70dSPing-Ke Shih rx_path = RF_A;
34287f18a70dSPing-Ke Shih else if (path == RF_PATH_B)
34297f18a70dSPing-Ke Shih rx_path = RF_B;
34307f18a70dSPing-Ke Shih else if (path == RF_PATH_AB)
34317f18a70dSPing-Ke Shih rx_path = RF_AB;
34327f18a70dSPing-Ke Shih else
34337f18a70dSPing-Ke Shih rx_path = RF_ABCD; /* don't change path, but still set others */
34347f18a70dSPing-Ke Shih
34357f18a70dSPing-Ke Shih if (enable) {
34367f18a70dSPing-Ke Shih rtw8852b_bb_set_plcp_tx(rtwdev);
34377f18a70dSPing-Ke Shih rtw8852b_bb_cfg_tx_path(rtwdev, path);
34387f18a70dSPing-Ke Shih rtw8852b_bb_ctrl_rx_path(rtwdev, rx_path);
34397f18a70dSPing-Ke Shih rtw8852b_bb_set_power(rtwdev, pwr_dbm, phy);
34407f18a70dSPing-Ke Shih }
34417f18a70dSPing-Ke Shih
34427f18a70dSPing-Ke Shih rtw8852b_bb_set_pmac_pkt_tx(rtwdev, enable, cnt, period, 20, phy);
34437f18a70dSPing-Ke Shih }
34447f18a70dSPing-Ke Shih
_tssi_backup_bb_registers(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const u32 reg[],u32 reg_backup[],u32 reg_num)34457f18a70dSPing-Ke Shih static void _tssi_backup_bb_registers(struct rtw89_dev *rtwdev,
34467f18a70dSPing-Ke Shih enum rtw89_phy_idx phy, const u32 reg[],
34477f18a70dSPing-Ke Shih u32 reg_backup[], u32 reg_num)
34487f18a70dSPing-Ke Shih {
34497f18a70dSPing-Ke Shih u32 i;
34507f18a70dSPing-Ke Shih
34517f18a70dSPing-Ke Shih for (i = 0; i < reg_num; i++) {
34527f18a70dSPing-Ke Shih reg_backup[i] = rtw89_phy_read32_mask(rtwdev, reg[i], MASKDWORD);
34537f18a70dSPing-Ke Shih
34547f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
34557f18a70dSPing-Ke Shih "[TSSI] Backup BB 0x%x = 0x%x\n", reg[i],
34567f18a70dSPing-Ke Shih reg_backup[i]);
34577f18a70dSPing-Ke Shih }
34587f18a70dSPing-Ke Shih }
34597f18a70dSPing-Ke Shih
_tssi_reload_bb_registers(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,const u32 reg[],u32 reg_backup[],u32 reg_num)34607f18a70dSPing-Ke Shih static void _tssi_reload_bb_registers(struct rtw89_dev *rtwdev,
34617f18a70dSPing-Ke Shih enum rtw89_phy_idx phy, const u32 reg[],
34627f18a70dSPing-Ke Shih u32 reg_backup[], u32 reg_num)
34637f18a70dSPing-Ke Shih
34647f18a70dSPing-Ke Shih {
34657f18a70dSPing-Ke Shih u32 i;
34667f18a70dSPing-Ke Shih
34677f18a70dSPing-Ke Shih for (i = 0; i < reg_num; i++) {
34687f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, reg[i], MASKDWORD, reg_backup[i]);
34697f18a70dSPing-Ke Shih
34707f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
34717f18a70dSPing-Ke Shih "[TSSI] Reload BB 0x%x = 0x%x\n", reg[i],
34727f18a70dSPing-Ke Shih reg_backup[i]);
34737f18a70dSPing-Ke Shih }
34747f18a70dSPing-Ke Shih }
34757f18a70dSPing-Ke Shih
_tssi_ch_to_idx(struct rtw89_dev * rtwdev,u8 channel)34767f18a70dSPing-Ke Shih static u8 _tssi_ch_to_idx(struct rtw89_dev *rtwdev, u8 channel)
34777f18a70dSPing-Ke Shih {
34787f18a70dSPing-Ke Shih u8 channel_index;
34797f18a70dSPing-Ke Shih
34807f18a70dSPing-Ke Shih if (channel >= 1 && channel <= 14)
34817f18a70dSPing-Ke Shih channel_index = channel - 1;
34827f18a70dSPing-Ke Shih else if (channel >= 36 && channel <= 64)
34837f18a70dSPing-Ke Shih channel_index = (channel - 36) / 2 + 14;
34847f18a70dSPing-Ke Shih else if (channel >= 100 && channel <= 144)
34857f18a70dSPing-Ke Shih channel_index = ((channel - 100) / 2) + 15 + 14;
34867f18a70dSPing-Ke Shih else if (channel >= 149 && channel <= 177)
34877f18a70dSPing-Ke Shih channel_index = ((channel - 149) / 2) + 38 + 14;
34887f18a70dSPing-Ke Shih else
34897f18a70dSPing-Ke Shih channel_index = 0;
34907f18a70dSPing-Ke Shih
34917f18a70dSPing-Ke Shih return channel_index;
34927f18a70dSPing-Ke Shih }
34937f18a70dSPing-Ke Shih
_tssi_get_cw_report(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path,const s16 * power,u32 * tssi_cw_rpt)34947f18a70dSPing-Ke Shih static bool _tssi_get_cw_report(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
34957f18a70dSPing-Ke Shih enum rtw89_rf_path path, const s16 *power,
34967f18a70dSPing-Ke Shih u32 *tssi_cw_rpt)
34977f18a70dSPing-Ke Shih {
34987f18a70dSPing-Ke Shih u32 tx_counter, tx_counter_tmp;
34997f18a70dSPing-Ke Shih const int retry = 100;
35007f18a70dSPing-Ke Shih u32 tmp;
35017f18a70dSPing-Ke Shih int j, k;
35027f18a70dSPing-Ke Shih
35037f18a70dSPing-Ke Shih for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) {
35047f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x0);
35057f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, _tssi_trigger[path], B_P0_TSSI_EN, 0x1);
35067f18a70dSPing-Ke Shih
35077f18a70dSPing-Ke Shih tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
35087f18a70dSPing-Ke Shih
35097f18a70dSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, _tssi_trigger[path], MASKDWORD);
35107f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35117f18a70dSPing-Ke Shih "[TSSI PA K] 0x%x = 0x%08x path=%d\n",
35127f18a70dSPing-Ke Shih _tssi_trigger[path], tmp, path);
35137f18a70dSPing-Ke Shih
35147f18a70dSPing-Ke Shih if (j == 0)
35157f18a70dSPing-Ke Shih _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], true);
35167f18a70dSPing-Ke Shih else
35177f18a70dSPing-Ke Shih _tssi_hw_tx(rtwdev, phy, RF_PATH_ABCD, 100, 5000, power[j], true);
35187f18a70dSPing-Ke Shih
35197f18a70dSPing-Ke Shih tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
35207f18a70dSPing-Ke Shih tx_counter_tmp -= tx_counter;
35217f18a70dSPing-Ke Shih
35227f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35237f18a70dSPing-Ke Shih "[TSSI PA K] First HWTXcounter=%d path=%d\n",
35247f18a70dSPing-Ke Shih tx_counter_tmp, path);
35257f18a70dSPing-Ke Shih
35267f18a70dSPing-Ke Shih for (k = 0; k < retry; k++) {
35277f18a70dSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path],
35287f18a70dSPing-Ke Shih B_TSSI_CWRPT_RDY);
35297f18a70dSPing-Ke Shih if (tmp)
35307f18a70dSPing-Ke Shih break;
35317f18a70dSPing-Ke Shih
35327f18a70dSPing-Ke Shih udelay(30);
35337f18a70dSPing-Ke Shih
35347f18a70dSPing-Ke Shih tx_counter_tmp =
35357f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
35367f18a70dSPing-Ke Shih tx_counter_tmp -= tx_counter;
35377f18a70dSPing-Ke Shih
35387f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35397f18a70dSPing-Ke Shih "[TSSI PA K] Flow k = %d HWTXcounter=%d path=%d\n",
35407f18a70dSPing-Ke Shih k, tx_counter_tmp, path);
35417f18a70dSPing-Ke Shih }
35427f18a70dSPing-Ke Shih
35437f18a70dSPing-Ke Shih if (k >= retry) {
35447f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35457f18a70dSPing-Ke Shih "[TSSI PA K] TSSI finish bit k > %d mp:100ms normal:30us path=%d\n",
35467f18a70dSPing-Ke Shih k, path);
35477f18a70dSPing-Ke Shih
35487f18a70dSPing-Ke Shih _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false);
35497f18a70dSPing-Ke Shih return false;
35507f18a70dSPing-Ke Shih }
35517f18a70dSPing-Ke Shih
35527f18a70dSPing-Ke Shih tssi_cw_rpt[j] =
35537f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, _tssi_cw_rpt_addr[path], B_TSSI_CWRPT);
35547f18a70dSPing-Ke Shih
35557f18a70dSPing-Ke Shih _tssi_hw_tx(rtwdev, phy, path, 100, 5000, power[j], false);
35567f18a70dSPing-Ke Shih
35577f18a70dSPing-Ke Shih tx_counter_tmp = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD);
35587f18a70dSPing-Ke Shih tx_counter_tmp -= tx_counter;
35597f18a70dSPing-Ke Shih
35607f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35617f18a70dSPing-Ke Shih "[TSSI PA K] Final HWTXcounter=%d path=%d\n",
35627f18a70dSPing-Ke Shih tx_counter_tmp, path);
35637f18a70dSPing-Ke Shih }
35647f18a70dSPing-Ke Shih
35657f18a70dSPing-Ke Shih return true;
35667f18a70dSPing-Ke Shih }
35677f18a70dSPing-Ke Shih
_tssi_alimentk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_rf_path path)35687f18a70dSPing-Ke Shih static void _tssi_alimentk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
35697f18a70dSPing-Ke Shih enum rtw89_rf_path path)
35707f18a70dSPing-Ke Shih {
35717f18a70dSPing-Ke Shih static const u32 bb_reg[8] = {0x5820, 0x7820, 0x4978, 0x58e4,
35727f18a70dSPing-Ke Shih 0x78e4, 0x49c0, 0x0d18, 0x0d80};
35737f18a70dSPing-Ke Shih static const s16 power_2g[4] = {48, 20, 4, 4};
35747f18a70dSPing-Ke Shih static const s16 power_5g[4] = {48, 20, 4, 4};
35757f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
35767f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
35777f18a70dSPing-Ke Shih s32 tssi_alim_offset_1, tssi_alim_offset_2, tssi_alim_offset_3;
35787f18a70dSPing-Ke Shih u32 tssi_cw_rpt[RTW8852B_TSSI_PATH_NR] = {0};
35797f18a70dSPing-Ke Shih u8 channel = chan->channel;
35807f18a70dSPing-Ke Shih u8 ch_idx = _tssi_ch_to_idx(rtwdev, channel);
35817f18a70dSPing-Ke Shih struct rtw8852b_bb_tssi_bak tssi_bak;
35827f18a70dSPing-Ke Shih s32 aliment_diff, tssi_cw_default;
35837f18a70dSPing-Ke Shih u32 start_time, finish_time;
35847f18a70dSPing-Ke Shih u32 bb_reg_backup[8] = {0};
35857f18a70dSPing-Ke Shih const s16 *power;
35867f18a70dSPing-Ke Shih u8 band;
35877f18a70dSPing-Ke Shih bool ok;
35887f18a70dSPing-Ke Shih u32 tmp;
35897f18a70dSPing-Ke Shih u8 j;
35907f18a70dSPing-Ke Shih
35917f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
35927f18a70dSPing-Ke Shih "======> %s channel=%d path=%d\n", __func__, channel,
35937f18a70dSPing-Ke Shih path);
35947f18a70dSPing-Ke Shih
35957f18a70dSPing-Ke Shih if (tssi_info->check_backup_aligmk[path][ch_idx]) {
35967f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD,
35977f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][0]);
35987f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD,
35997f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][1]);
36007f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD,
36017f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][2]);
36027f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD,
36037f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][3]);
36047f18a70dSPing-Ke Shih
36057f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
36067f18a70dSPing-Ke Shih "======> %s Reload TSSI Alignment !!!\n", __func__);
36077f18a70dSPing-Ke Shih _tssi_alimentk_dump_result(rtwdev, path);
36087f18a70dSPing-Ke Shih return;
36097f18a70dSPing-Ke Shih }
36107f18a70dSPing-Ke Shih
36117f18a70dSPing-Ke Shih start_time = ktime_get_ns();
36127f18a70dSPing-Ke Shih
36137f18a70dSPing-Ke Shih if (chan->band_type == RTW89_BAND_2G)
36147f18a70dSPing-Ke Shih power = power_2g;
36157f18a70dSPing-Ke Shih else
36167f18a70dSPing-Ke Shih power = power_5g;
36177f18a70dSPing-Ke Shih
36187f18a70dSPing-Ke Shih if (channel >= 1 && channel <= 14)
36197f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
36207f18a70dSPing-Ke Shih else if (channel >= 36 && channel <= 64)
36217f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GL;
36227f18a70dSPing-Ke Shih else if (channel >= 100 && channel <= 144)
36237f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GM;
36247f18a70dSPing-Ke Shih else if (channel >= 149 && channel <= 177)
36257f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GH;
36267f18a70dSPing-Ke Shih else
36277f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
36287f18a70dSPing-Ke Shih
36297f18a70dSPing-Ke Shih rtw8852b_bb_backup_tssi(rtwdev, phy, &tssi_bak);
36307f18a70dSPing-Ke Shih _tssi_backup_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
36317f18a70dSPing-Ke Shih
36327f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x8);
36337f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x8);
36347f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2);
36357f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2);
36367f18a70dSPing-Ke Shih
36377f18a70dSPing-Ke Shih ok = _tssi_get_cw_report(rtwdev, phy, path, power, tssi_cw_rpt);
36387f18a70dSPing-Ke Shih if (!ok)
36397f18a70dSPing-Ke Shih goto out;
36407f18a70dSPing-Ke Shih
36417f18a70dSPing-Ke Shih for (j = 0; j < RTW8852B_TSSI_PATH_NR; j++) {
36427f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
36437f18a70dSPing-Ke Shih "[TSSI PA K] power[%d]=%d tssi_cw_rpt[%d]=%d\n", j,
36447f18a70dSPing-Ke Shih power[j], j, tssi_cw_rpt[j]);
36457f18a70dSPing-Ke Shih }
36467f18a70dSPing-Ke Shih
36477f18a70dSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][1],
36487f18a70dSPing-Ke Shih _tssi_cw_default_mask[1]);
36497f18a70dSPing-Ke Shih tssi_cw_default = sign_extend32(tmp, 8);
36507f18a70dSPing-Ke Shih tssi_alim_offset_1 = tssi_cw_rpt[0] - ((power[0] - power[1]) * 2) -
36517f18a70dSPing-Ke Shih tssi_cw_rpt[1] + tssi_cw_default;
36527f18a70dSPing-Ke Shih aliment_diff = tssi_alim_offset_1 - tssi_cw_default;
36537f18a70dSPing-Ke Shih
36547f18a70dSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][2],
36557f18a70dSPing-Ke Shih _tssi_cw_default_mask[2]);
36567f18a70dSPing-Ke Shih tssi_cw_default = sign_extend32(tmp, 8);
36577f18a70dSPing-Ke Shih tssi_alim_offset_2 = tssi_cw_default + aliment_diff;
36587f18a70dSPing-Ke Shih
36597f18a70dSPing-Ke Shih tmp = rtw89_phy_read32_mask(rtwdev, _tssi_cw_default_addr[path][3],
36607f18a70dSPing-Ke Shih _tssi_cw_default_mask[3]);
36617f18a70dSPing-Ke Shih tssi_cw_default = sign_extend32(tmp, 8);
36627f18a70dSPing-Ke Shih tssi_alim_offset_3 = tssi_cw_default + aliment_diff;
36637f18a70dSPing-Ke Shih
36647f18a70dSPing-Ke Shih if (path == RF_PATH_A) {
36657f18a70dSPing-Ke Shih tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
36667f18a70dSPing-Ke Shih FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
36677f18a70dSPing-Ke Shih FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
36687f18a70dSPing-Ke Shih
36697f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM1, tmp);
36707f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2, B_P0_TSSI_ALIM2, tmp);
36717f18a70dSPing-Ke Shih
36727f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
36737f18a70dSPing-Ke Shih "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
36747f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3, B_P0_TSSI_ALIM31),
36757f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM11),
36767f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM12),
36777f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1, B_P0_TSSI_ALIM13));
36787f18a70dSPing-Ke Shih } else {
36797f18a70dSPing-Ke Shih tmp = FIELD_PREP(B_P1_TSSI_ALIM11, tssi_alim_offset_1) |
36807f18a70dSPing-Ke Shih FIELD_PREP(B_P1_TSSI_ALIM12, tssi_alim_offset_2) |
36817f18a70dSPing-Ke Shih FIELD_PREP(B_P1_TSSI_ALIM13, tssi_alim_offset_3);
36827f18a70dSPing-Ke Shih
36837f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM1, tmp);
36847f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_ALIM2, B_P1_TSSI_ALIM2, tmp);
36857f18a70dSPing-Ke Shih
36867f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
36877f18a70dSPing-Ke Shih "[TSSI PA K] tssi_alim_offset = 0x%x 0x%x 0x%x 0x%x\n",
36887f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM3, B_P1_TSSI_ALIM31),
36897f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM11),
36907f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM12),
36917f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_ALIM1, B_P1_TSSI_ALIM13));
36927f18a70dSPing-Ke Shih }
36937f18a70dSPing-Ke Shih
36947f18a70dSPing-Ke Shih tssi_info->alignment_done[path][band] = true;
36957f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][0] =
36967f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
36977f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][1] =
36987f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
36997f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][2] =
37007f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
37017f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][3] =
37027f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
37037f18a70dSPing-Ke Shih
37047f18a70dSPing-Ke Shih tssi_info->check_backup_aligmk[path][ch_idx] = true;
37057f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][0] =
37067f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD);
37077f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][1] =
37087f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD);
37097f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][2] =
37107f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD);
37117f18a70dSPing-Ke Shih tssi_info->alignment_backup_by_ch[path][ch_idx][3] =
37127f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD);
37137f18a70dSPing-Ke Shih
37147f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
37157f18a70dSPing-Ke Shih "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][0], 0x%x = 0x%08x\n",
37167f18a70dSPing-Ke Shih path, band, R_P0_TSSI_ALIM1 + (path << 13),
37177f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][0]);
37187f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
37197f18a70dSPing-Ke Shih "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][1], 0x%x = 0x%08x\n",
37207f18a70dSPing-Ke Shih path, band, R_P0_TSSI_ALIM3 + (path << 13),
37217f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][1]);
37227f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
37237f18a70dSPing-Ke Shih "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][2], 0x%x = 0x%08x\n",
37247f18a70dSPing-Ke Shih path, band, R_P0_TSSI_ALIM2 + (path << 13),
37257f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][2]);
37267f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
37277f18a70dSPing-Ke Shih "[TSSI PA K] tssi_info->alignment_value[path=%d][band=%d][3], 0x%x = 0x%08x\n",
37287f18a70dSPing-Ke Shih path, band, R_P0_TSSI_ALIM4 + (path << 13),
37297f18a70dSPing-Ke Shih tssi_info->alignment_value[path][band][3]);
37307f18a70dSPing-Ke Shih
37317f18a70dSPing-Ke Shih out:
37327f18a70dSPing-Ke Shih _tssi_reload_bb_registers(rtwdev, phy, bb_reg, bb_reg_backup, ARRAY_SIZE(bb_reg_backup));
37337f18a70dSPing-Ke Shih rtw8852b_bb_restore_tssi(rtwdev, phy, &tssi_bak);
37347f18a70dSPing-Ke Shih rtw8852b_bb_tx_mode_switch(rtwdev, phy, 0);
37357f18a70dSPing-Ke Shih
37367f18a70dSPing-Ke Shih finish_time = ktime_get_ns();
37377f18a70dSPing-Ke Shih tssi_info->tssi_alimk_time += finish_time - start_time;
37387f18a70dSPing-Ke Shih
37397f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
37407f18a70dSPing-Ke Shih "[TSSI PA K] %s processing time = %d ms\n", __func__,
37417f18a70dSPing-Ke Shih tssi_info->tssi_alimk_time);
37427f18a70dSPing-Ke Shih }
37437f18a70dSPing-Ke Shih
rtw8852b_dpk_init(struct rtw89_dev * rtwdev)37445b8471acSPing-Ke Shih void rtw8852b_dpk_init(struct rtw89_dev *rtwdev)
37455b8471acSPing-Ke Shih {
37465b8471acSPing-Ke Shih _set_dpd_backoff(rtwdev, RTW89_PHY_0);
37475b8471acSPing-Ke Shih }
37485b8471acSPing-Ke Shih
rtw8852b_rck(struct rtw89_dev * rtwdev)374910298b53SPing-Ke Shih void rtw8852b_rck(struct rtw89_dev *rtwdev)
375010298b53SPing-Ke Shih {
375110298b53SPing-Ke Shih u8 path;
375210298b53SPing-Ke Shih
375310298b53SPing-Ke Shih for (path = 0; path < RF_PATH_NUM_8852B; path++)
375410298b53SPing-Ke Shih _rck(rtwdev, path);
375510298b53SPing-Ke Shih }
375610298b53SPing-Ke Shih
rtw8852b_dack(struct rtw89_dev * rtwdev)375716be5e3bSPing-Ke Shih void rtw8852b_dack(struct rtw89_dev *rtwdev)
375816be5e3bSPing-Ke Shih {
375916be5e3bSPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0);
376016be5e3bSPing-Ke Shih
376116be5e3bSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START);
376216be5e3bSPing-Ke Shih _dac_cal(rtwdev, false);
376316be5e3bSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP);
376416be5e3bSPing-Ke Shih }
376516be5e3bSPing-Ke Shih
rtw8852b_iqk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)3766f2abe804SPing-Ke Shih void rtw8852b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
3767f2abe804SPing-Ke Shih {
3768f2abe804SPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
3769f2abe804SPing-Ke Shih u32 tx_en;
3770f2abe804SPing-Ke Shih
3771f2abe804SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START);
3772f2abe804SPing-Ke Shih rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
3773f2abe804SPing-Ke Shih _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
3774f2abe804SPing-Ke Shih
3775f2abe804SPing-Ke Shih _iqk_init(rtwdev);
3776f2abe804SPing-Ke Shih _iqk(rtwdev, phy_idx, false);
3777f2abe804SPing-Ke Shih
3778f2abe804SPing-Ke Shih rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
3779f2abe804SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP);
3780f2abe804SPing-Ke Shih }
3781f2abe804SPing-Ke Shih
rtw8852b_rx_dck(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)378221267107SPing-Ke Shih void rtw8852b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
378321267107SPing-Ke Shih {
378421267107SPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
378521267107SPing-Ke Shih u32 tx_en;
378621267107SPing-Ke Shih
378721267107SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START);
378821267107SPing-Ke Shih rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
378921267107SPing-Ke Shih _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
379021267107SPing-Ke Shih
379121267107SPing-Ke Shih _rx_dck(rtwdev, phy_idx);
379221267107SPing-Ke Shih
379321267107SPing-Ke Shih rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
379421267107SPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP);
379521267107SPing-Ke Shih }
379621267107SPing-Ke Shih
rtw8852b_dpk(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy_idx)37975b8471acSPing-Ke Shih void rtw8852b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
37985b8471acSPing-Ke Shih {
37995b8471acSPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0);
38005b8471acSPing-Ke Shih u32 tx_en;
38015b8471acSPing-Ke Shih
38025b8471acSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START);
38035b8471acSPing-Ke Shih rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL);
38045b8471acSPing-Ke Shih _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx));
38055b8471acSPing-Ke Shih
38065b8471acSPing-Ke Shih rtwdev->dpk.is_dpk_enable = true;
38075b8471acSPing-Ke Shih rtwdev->dpk.is_dpk_reload_en = false;
38085b8471acSPing-Ke Shih _dpk(rtwdev, phy_idx, false);
38095b8471acSPing-Ke Shih
38105b8471acSPing-Ke Shih rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en);
38115b8471acSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP);
38125b8471acSPing-Ke Shih }
38135b8471acSPing-Ke Shih
rtw8852b_dpk_track(struct rtw89_dev * rtwdev)38145b8471acSPing-Ke Shih void rtw8852b_dpk_track(struct rtw89_dev *rtwdev)
38155b8471acSPing-Ke Shih {
38165b8471acSPing-Ke Shih _dpk_track(rtwdev);
38175b8471acSPing-Ke Shih }
38185b8471acSPing-Ke Shih
rtw8852b_tssi(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,bool hwtx_en)38197f18a70dSPing-Ke Shih void rtw8852b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool hwtx_en)
38207f18a70dSPing-Ke Shih {
38217f18a70dSPing-Ke Shih u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_AB);
38227f18a70dSPing-Ke Shih u32 tx_en;
38237f18a70dSPing-Ke Shih u8 i;
38247f18a70dSPing-Ke Shih
38257f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy);
38267f18a70dSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START);
38277f18a70dSPing-Ke Shih
38287f18a70dSPing-Ke Shih _tssi_disable(rtwdev, phy);
38297f18a70dSPing-Ke Shih
38307f18a70dSPing-Ke Shih for (i = RF_PATH_A; i < RF_PATH_NUM_8852B; i++) {
38317f18a70dSPing-Ke Shih _tssi_rf_setting(rtwdev, phy, i);
38327f18a70dSPing-Ke Shih _tssi_set_sys(rtwdev, phy, i);
38337f18a70dSPing-Ke Shih _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i);
38347f18a70dSPing-Ke Shih _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i);
38357f18a70dSPing-Ke Shih _tssi_set_dck(rtwdev, phy, i);
38367f18a70dSPing-Ke Shih _tssi_set_tmeter_tbl(rtwdev, phy, i);
38377f18a70dSPing-Ke Shih _tssi_set_dac_gain_tbl(rtwdev, phy, i);
38387f18a70dSPing-Ke Shih _tssi_slope_cal_org(rtwdev, phy, i);
38397f18a70dSPing-Ke Shih _tssi_alignment_default(rtwdev, phy, i, true);
38407f18a70dSPing-Ke Shih _tssi_set_tssi_slope(rtwdev, phy, i);
38417f18a70dSPing-Ke Shih
38427f18a70dSPing-Ke Shih rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL);
38437f18a70dSPing-Ke Shih _tmac_tx_pause(rtwdev, phy, true);
38447f18a70dSPing-Ke Shih if (hwtx_en)
38457f18a70dSPing-Ke Shih _tssi_alimentk(rtwdev, phy, i);
38467f18a70dSPing-Ke Shih _tmac_tx_pause(rtwdev, phy, false);
38477f18a70dSPing-Ke Shih rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en);
38487f18a70dSPing-Ke Shih }
38497f18a70dSPing-Ke Shih
38507f18a70dSPing-Ke Shih _tssi_enable(rtwdev, phy);
38517f18a70dSPing-Ke Shih _tssi_set_efuse_to_de(rtwdev, phy);
38527f18a70dSPing-Ke Shih
38537f18a70dSPing-Ke Shih rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP);
38547f18a70dSPing-Ke Shih }
38557f18a70dSPing-Ke Shih
rtw8852b_tssi_scan(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy)38567f18a70dSPing-Ke Shih void rtw8852b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy)
38577f18a70dSPing-Ke Shih {
38587f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
38597f18a70dSPing-Ke Shih struct rtw89_tssi_info *tssi_info = &rtwdev->tssi;
38607f18a70dSPing-Ke Shih u8 channel = chan->channel;
38617f18a70dSPing-Ke Shih u8 band;
38627f18a70dSPing-Ke Shih u32 i;
38637f18a70dSPing-Ke Shih
38647f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
38657f18a70dSPing-Ke Shih "======>%s phy=%d channel=%d\n", __func__, phy, channel);
38667f18a70dSPing-Ke Shih
38677f18a70dSPing-Ke Shih if (channel >= 1 && channel <= 14)
38687f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
38697f18a70dSPing-Ke Shih else if (channel >= 36 && channel <= 64)
38707f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GL;
38717f18a70dSPing-Ke Shih else if (channel >= 100 && channel <= 144)
38727f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GM;
38737f18a70dSPing-Ke Shih else if (channel >= 149 && channel <= 177)
38747f18a70dSPing-Ke Shih band = TSSI_ALIMK_5GH;
38757f18a70dSPing-Ke Shih else
38767f18a70dSPing-Ke Shih band = TSSI_ALIMK_2G;
38777f18a70dSPing-Ke Shih
38787f18a70dSPing-Ke Shih _tssi_disable(rtwdev, phy);
38797f18a70dSPing-Ke Shih
38807f18a70dSPing-Ke Shih for (i = RF_PATH_A; i < RTW8852B_TSSI_PATH_NR; i++) {
38817f18a70dSPing-Ke Shih _tssi_rf_setting(rtwdev, phy, i);
38827f18a70dSPing-Ke Shih _tssi_set_sys(rtwdev, phy, i);
38837f18a70dSPing-Ke Shih _tssi_set_tmeter_tbl(rtwdev, phy, i);
38847f18a70dSPing-Ke Shih
38857f18a70dSPing-Ke Shih if (tssi_info->alignment_done[i][band])
38867f18a70dSPing-Ke Shih _tssi_alimentk_done(rtwdev, phy, i);
38877f18a70dSPing-Ke Shih else
38887f18a70dSPing-Ke Shih _tssi_alignment_default(rtwdev, phy, i, true);
38897f18a70dSPing-Ke Shih }
38907f18a70dSPing-Ke Shih
38917f18a70dSPing-Ke Shih _tssi_enable(rtwdev, phy);
38927f18a70dSPing-Ke Shih _tssi_set_efuse_to_de(rtwdev, phy);
38937f18a70dSPing-Ke Shih }
38947f18a70dSPing-Ke Shih
rtw8852b_tssi_default_txagc(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,bool enable)38957f18a70dSPing-Ke Shih static void rtw8852b_tssi_default_txagc(struct rtw89_dev *rtwdev,
38967f18a70dSPing-Ke Shih enum rtw89_phy_idx phy, bool enable)
38977f18a70dSPing-Ke Shih {
38987f18a70dSPing-Ke Shih const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, RTW89_SUB_ENTITY_0);
38997f18a70dSPing-Ke Shih u8 channel = chan->channel;
39007f18a70dSPing-Ke Shih
39017f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n",
39027f18a70dSPing-Ke Shih __func__, channel);
39037f18a70dSPing-Ke Shih
39047f18a70dSPing-Ke Shih if (enable) {
39057f18a70dSPing-Ke Shih if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B])
39067f18a70dSPing-Ke Shih rtw8852b_tssi(rtwdev, phy, true);
39077f18a70dSPing-Ke Shih return;
39087f18a70dSPing-Ke Shih }
39097f18a70dSPing-Ke Shih
39107f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
39117f18a70dSPing-Ke Shih "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
39127f18a70dSPing-Ke Shih __func__,
39137f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
39147f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
39157f18a70dSPing-Ke Shih
39167f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0);
39177f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 0xc0);
39187f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0);
39197f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1);
39207f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0);
39217f18a70dSPing-Ke Shih rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1);
39227f18a70dSPing-Ke Shih
39237f18a70dSPing-Ke Shih _tssi_alimentk_done(rtwdev, phy, RF_PATH_A);
39247f18a70dSPing-Ke Shih _tssi_alimentk_done(rtwdev, phy, RF_PATH_B);
39257f18a70dSPing-Ke Shih
39267f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
39277f18a70dSPing-Ke Shih "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x 0x7818[7:0]=0x%x\n",
39287f18a70dSPing-Ke Shih __func__,
39297f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT),
39307f18a70dSPing-Ke Shih rtw89_phy_read32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT));
39317f18a70dSPing-Ke Shih
39327f18a70dSPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
39337f18a70dSPing-Ke Shih "======> %s SCAN_END\n", __func__);
39347f18a70dSPing-Ke Shih }
39357f18a70dSPing-Ke Shih
rtw8852b_wifi_scan_notify(struct rtw89_dev * rtwdev,bool scan_start,enum rtw89_phy_idx phy_idx)39367f18a70dSPing-Ke Shih void rtw8852b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start,
39377f18a70dSPing-Ke Shih enum rtw89_phy_idx phy_idx)
39387f18a70dSPing-Ke Shih {
39397f18a70dSPing-Ke Shih if (scan_start)
39407f18a70dSPing-Ke Shih rtw8852b_tssi_default_txagc(rtwdev, phy_idx, true);
39417f18a70dSPing-Ke Shih else
39427f18a70dSPing-Ke Shih rtw8852b_tssi_default_txagc(rtwdev, phy_idx, false);
39437f18a70dSPing-Ke Shih }
39447f18a70dSPing-Ke Shih
_bw_setting(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,enum rtw89_bandwidth bw,bool dav)39456b069898SPing-Ke Shih static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
39466b069898SPing-Ke Shih enum rtw89_bandwidth bw, bool dav)
39476b069898SPing-Ke Shih {
39486b069898SPing-Ke Shih u32 rf_reg18;
39496b069898SPing-Ke Shih u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
39506b069898SPing-Ke Shih
39516b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
39526b069898SPing-Ke Shih
39536b069898SPing-Ke Shih rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
39546b069898SPing-Ke Shih if (rf_reg18 == INV_RF_DATA) {
39556b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
39566b069898SPing-Ke Shih "[RFK]Invalid RF_0x18 for Path-%d\n", path);
39576b069898SPing-Ke Shih return;
39586b069898SPing-Ke Shih }
39596b069898SPing-Ke Shih rf_reg18 &= ~RR_CFGCH_BW;
39606b069898SPing-Ke Shih
39616b069898SPing-Ke Shih switch (bw) {
39626b069898SPing-Ke Shih case RTW89_CHANNEL_WIDTH_5:
39636b069898SPing-Ke Shih case RTW89_CHANNEL_WIDTH_10:
39646b069898SPing-Ke Shih case RTW89_CHANNEL_WIDTH_20:
39656b069898SPing-Ke Shih rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M);
39666b069898SPing-Ke Shih break;
39676b069898SPing-Ke Shih case RTW89_CHANNEL_WIDTH_40:
39686b069898SPing-Ke Shih rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M);
39696b069898SPing-Ke Shih break;
39706b069898SPing-Ke Shih case RTW89_CHANNEL_WIDTH_80:
39716b069898SPing-Ke Shih rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M);
39726b069898SPing-Ke Shih break;
39736b069898SPing-Ke Shih default:
39746b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n");
39756b069898SPing-Ke Shih }
39766b069898SPing-Ke Shih
39776b069898SPing-Ke Shih rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
39786b069898SPing-Ke Shih RR_CFGCH_BW2) & RFREG_MASK;
39796b069898SPing-Ke Shih rf_reg18 |= RR_CFGCH_BW2;
39806b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
39816b069898SPing-Ke Shih
39826b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n",
39836b069898SPing-Ke Shih bw, path, reg18_addr,
39846b069898SPing-Ke Shih rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
39856b069898SPing-Ke Shih }
39866b069898SPing-Ke Shih
_ctrl_bw(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_bandwidth bw)39876b069898SPing-Ke Shih static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
39886b069898SPing-Ke Shih enum rtw89_bandwidth bw)
39896b069898SPing-Ke Shih {
39906b069898SPing-Ke Shih _bw_setting(rtwdev, RF_PATH_A, bw, true);
39916b069898SPing-Ke Shih _bw_setting(rtwdev, RF_PATH_B, bw, true);
39926b069898SPing-Ke Shih _bw_setting(rtwdev, RF_PATH_A, bw, false);
39936b069898SPing-Ke Shih _bw_setting(rtwdev, RF_PATH_B, bw, false);
39946b069898SPing-Ke Shih }
39956b069898SPing-Ke Shih
_set_s0_arfc18(struct rtw89_dev * rtwdev,u32 val)39966b069898SPing-Ke Shih static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val)
39976b069898SPing-Ke Shih {
39986b069898SPing-Ke Shih u32 bak;
39996b069898SPing-Ke Shih u32 tmp;
40006b069898SPing-Ke Shih int ret;
40016b069898SPing-Ke Shih
40026b069898SPing-Ke Shih bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK);
40036b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1);
40046b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val);
40056b069898SPing-Ke Shih
40066b069898SPing-Ke Shih ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000,
40076b069898SPing-Ke Shih false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY);
40086b069898SPing-Ke Shih if (ret)
40096b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n");
40106b069898SPing-Ke Shih
40116b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak);
40126b069898SPing-Ke Shih
40136b069898SPing-Ke Shih return !!ret;
40146b069898SPing-Ke Shih }
40156b069898SPing-Ke Shih
_lck_check(struct rtw89_dev * rtwdev)40166b069898SPing-Ke Shih static void _lck_check(struct rtw89_dev *rtwdev)
40176b069898SPing-Ke Shih {
40186b069898SPing-Ke Shih u32 tmp;
40196b069898SPing-Ke Shih
40206b069898SPing-Ke Shih if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
40216b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n");
40226b069898SPing-Ke Shih
40236b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1);
40246b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0);
40256b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1);
40266b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0);
40276b069898SPing-Ke Shih }
40286b069898SPing-Ke Shih
40296b069898SPing-Ke Shih udelay(10);
40306b069898SPing-Ke Shih
40316b069898SPing-Ke Shih if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
40326b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n");
40336b069898SPing-Ke Shih
40346b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
40356b069898SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
40366b069898SPing-Ke Shih _set_s0_arfc18(rtwdev, tmp);
40376b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
40386b069898SPing-Ke Shih }
40396b069898SPing-Ke Shih
40406b069898SPing-Ke Shih if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) {
40416b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n");
40426b069898SPing-Ke Shih
40436b069898SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK);
40446b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp);
40456b069898SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK);
40466b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp);
40476b069898SPing-Ke Shih
40486b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1);
40496b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0);
40506b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3);
40516b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0);
40526b069898SPing-Ke Shih
40536b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1);
40546b069898SPing-Ke Shih tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK);
40556b069898SPing-Ke Shih _set_s0_arfc18(rtwdev, tmp);
40566b069898SPing-Ke Shih rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0);
40576b069898SPing-Ke Shih
40586b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n",
40596b069898SPing-Ke Shih rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK),
40606b069898SPing-Ke Shih rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK));
40616b069898SPing-Ke Shih }
40626b069898SPing-Ke Shih }
40636b069898SPing-Ke Shih
_set_ch(struct rtw89_dev * rtwdev,u32 val)40646b069898SPing-Ke Shih static void _set_ch(struct rtw89_dev *rtwdev, u32 val)
40656b069898SPing-Ke Shih {
40666b069898SPing-Ke Shih bool timeout;
40676b069898SPing-Ke Shih
40686b069898SPing-Ke Shih timeout = _set_s0_arfc18(rtwdev, val);
40696b069898SPing-Ke Shih if (!timeout)
40706b069898SPing-Ke Shih _lck_check(rtwdev);
40716b069898SPing-Ke Shih }
40726b069898SPing-Ke Shih
_ch_setting(struct rtw89_dev * rtwdev,enum rtw89_rf_path path,u8 central_ch,bool dav)40736b069898SPing-Ke Shih static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path,
40746b069898SPing-Ke Shih u8 central_ch, bool dav)
40756b069898SPing-Ke Shih {
40766b069898SPing-Ke Shih u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1;
40776b069898SPing-Ke Shih bool is_2g_ch = central_ch <= 14;
40786b069898SPing-Ke Shih u32 rf_reg18;
40796b069898SPing-Ke Shih
40806b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__);
40816b069898SPing-Ke Shih
40826b069898SPing-Ke Shih rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK);
40836b069898SPing-Ke Shih rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH |
40846b069898SPing-Ke Shih RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH);
40856b069898SPing-Ke Shih rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch);
40866b069898SPing-Ke Shih
40876b069898SPing-Ke Shih if (!is_2g_ch)
40886b069898SPing-Ke Shih rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) |
40896b069898SPing-Ke Shih FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G);
40906b069898SPing-Ke Shih
40916b069898SPing-Ke Shih rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN |
40926b069898SPing-Ke Shih RR_CFGCH_BW2) & RFREG_MASK;
40936b069898SPing-Ke Shih rf_reg18 |= RR_CFGCH_BW2;
40946b069898SPing-Ke Shih
40956b069898SPing-Ke Shih if (path == RF_PATH_A && dav)
40966b069898SPing-Ke Shih _set_ch(rtwdev, rf_reg18);
40976b069898SPing-Ke Shih else
40986b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18);
40996b069898SPing-Ke Shih
41006b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0);
41016b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1);
41026b069898SPing-Ke Shih
41036b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK,
41046b069898SPing-Ke Shih "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n",
41056b069898SPing-Ke Shih central_ch, path, reg18_addr,
41066b069898SPing-Ke Shih rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK));
41076b069898SPing-Ke Shih }
41086b069898SPing-Ke Shih
_ctrl_ch(struct rtw89_dev * rtwdev,u8 central_ch)41096b069898SPing-Ke Shih static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch)
41106b069898SPing-Ke Shih {
41116b069898SPing-Ke Shih _ch_setting(rtwdev, RF_PATH_A, central_ch, true);
41126b069898SPing-Ke Shih _ch_setting(rtwdev, RF_PATH_B, central_ch, true);
41136b069898SPing-Ke Shih _ch_setting(rtwdev, RF_PATH_A, central_ch, false);
41146b069898SPing-Ke Shih _ch_setting(rtwdev, RF_PATH_B, central_ch, false);
41156b069898SPing-Ke Shih }
41166b069898SPing-Ke Shih
_set_rxbb_bw(struct rtw89_dev * rtwdev,enum rtw89_bandwidth bw,enum rtw89_rf_path path)41176b069898SPing-Ke Shih static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw,
41186b069898SPing-Ke Shih enum rtw89_rf_path path)
41196b069898SPing-Ke Shih {
41206b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1);
41216b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12);
41226b069898SPing-Ke Shih
41236b069898SPing-Ke Shih if (bw == RTW89_CHANNEL_WIDTH_20)
41246b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b);
41256b069898SPing-Ke Shih else if (bw == RTW89_CHANNEL_WIDTH_40)
41266b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13);
41276b069898SPing-Ke Shih else if (bw == RTW89_CHANNEL_WIDTH_80)
41286b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb);
41296b069898SPing-Ke Shih else
41306b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3);
41316b069898SPing-Ke Shih
41326b069898SPing-Ke Shih rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path,
41336b069898SPing-Ke Shih rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB));
41346b069898SPing-Ke Shih
41356b069898SPing-Ke Shih rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0);
41366b069898SPing-Ke Shih }
41376b069898SPing-Ke Shih
_rxbb_bw(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,enum rtw89_bandwidth bw)41386b069898SPing-Ke Shih static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy,
41396b069898SPing-Ke Shih enum rtw89_bandwidth bw)
41406b069898SPing-Ke Shih {
41416b069898SPing-Ke Shih u8 kpath, path;
41426b069898SPing-Ke Shih
41436b069898SPing-Ke Shih kpath = _kpath(rtwdev, phy);
41446b069898SPing-Ke Shih
41456b069898SPing-Ke Shih for (path = 0; path < RF_PATH_NUM_8852B; path++) {
41466b069898SPing-Ke Shih if (!(kpath & BIT(path)))
41476b069898SPing-Ke Shih continue;
41486b069898SPing-Ke Shih
41496b069898SPing-Ke Shih _set_rxbb_bw(rtwdev, bw, path);
41506b069898SPing-Ke Shih }
41516b069898SPing-Ke Shih }
41526b069898SPing-Ke Shih
rtw8852b_ctrl_bw_ch(struct rtw89_dev * rtwdev,enum rtw89_phy_idx phy,u8 central_ch,enum rtw89_band band,enum rtw89_bandwidth bw)41536b069898SPing-Ke Shih static void rtw8852b_ctrl_bw_ch(struct rtw89_dev *rtwdev,
41546b069898SPing-Ke Shih enum rtw89_phy_idx phy, u8 central_ch,
41556b069898SPing-Ke Shih enum rtw89_band band, enum rtw89_bandwidth bw)
41566b069898SPing-Ke Shih {
41576b069898SPing-Ke Shih _ctrl_ch(rtwdev, central_ch);
41586b069898SPing-Ke Shih _ctrl_bw(rtwdev, phy, bw);
41596b069898SPing-Ke Shih _rxbb_bw(rtwdev, phy, bw);
41606b069898SPing-Ke Shih }
41616b069898SPing-Ke Shih
rtw8852b_set_channel_rf(struct rtw89_dev * rtwdev,const struct rtw89_chan * chan,enum rtw89_phy_idx phy_idx)41626b069898SPing-Ke Shih void rtw8852b_set_channel_rf(struct rtw89_dev *rtwdev,
41636b069898SPing-Ke Shih const struct rtw89_chan *chan,
41646b069898SPing-Ke Shih enum rtw89_phy_idx phy_idx)
41656b069898SPing-Ke Shih {
41666b069898SPing-Ke Shih rtw8852b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type,
41676b069898SPing-Ke Shih chan->band_width);
41686b069898SPing-Ke Shih }
4169