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