1e2340276SBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2e2340276SBjoern A. Zeeb /* Copyright(c) 2022-2023 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 "rtw8851b.h" 11e2340276SBjoern A. Zeeb #include "rtw8851b_rfk.h" 12e2340276SBjoern A. Zeeb #include "rtw8851b_rfk_table.h" 13e2340276SBjoern A. Zeeb #include "rtw8851b_table.h" 14e2340276SBjoern A. Zeeb 15e2340276SBjoern A. Zeeb #define DPK_VER_8851B 0x5 16e2340276SBjoern A. Zeeb #define DPK_KIP_REG_NUM_8851B 7 17e2340276SBjoern A. Zeeb #define DPK_RF_REG_NUM_8851B 4 18e2340276SBjoern A. Zeeb #define DPK_KSET_NUM 4 19e2340276SBjoern A. Zeeb #define RTW8851B_RXK_GROUP_NR 4 20e2340276SBjoern A. Zeeb #define RTW8851B_RXK_GROUP_IDX_NR 2 21e2340276SBjoern A. Zeeb #define RTW8851B_TXK_GROUP_NR 1 22e2340276SBjoern A. Zeeb #define RTW8851B_IQK_VER 0x2a 23e2340276SBjoern A. Zeeb #define RTW8851B_IQK_SS 1 24e2340276SBjoern A. Zeeb #define RTW8851B_LOK_GRAM 10 25e2340276SBjoern A. Zeeb #define RTW8851B_TSSI_PATH_NR 1 26e2340276SBjoern A. Zeeb 27e2340276SBjoern A. Zeeb #define _TSSI_DE_MASK GENMASK(21, 12) 28e2340276SBjoern A. Zeeb 29e2340276SBjoern A. Zeeb enum dpk_id { 30e2340276SBjoern A. Zeeb LBK_RXIQK = 0x06, 31e2340276SBjoern A. Zeeb SYNC = 0x10, 32e2340276SBjoern A. Zeeb MDPK_IDL = 0x11, 33e2340276SBjoern A. Zeeb MDPK_MPA = 0x12, 34e2340276SBjoern A. Zeeb GAIN_LOSS = 0x13, 35e2340276SBjoern A. Zeeb GAIN_CAL = 0x14, 36e2340276SBjoern A. Zeeb DPK_RXAGC = 0x15, 37e2340276SBjoern A. Zeeb KIP_PRESET = 0x16, 38e2340276SBjoern A. Zeeb KIP_RESTORE = 0x17, 39e2340276SBjoern A. Zeeb DPK_TXAGC = 0x19, 40e2340276SBjoern A. Zeeb D_KIP_PRESET = 0x28, 41e2340276SBjoern A. Zeeb D_TXAGC = 0x29, 42e2340276SBjoern A. Zeeb D_RXAGC = 0x2a, 43e2340276SBjoern A. Zeeb D_SYNC = 0x2b, 44e2340276SBjoern A. Zeeb D_GAIN_LOSS = 0x2c, 45e2340276SBjoern A. Zeeb D_MDPK_IDL = 0x2d, 46e2340276SBjoern A. Zeeb D_MDPK_LDL = 0x2e, 47e2340276SBjoern A. Zeeb D_GAIN_NORM = 0x2f, 48e2340276SBjoern A. Zeeb D_KIP_THERMAL = 0x30, 49e2340276SBjoern A. Zeeb D_KIP_RESTORE = 0x31 50e2340276SBjoern A. Zeeb }; 51e2340276SBjoern A. Zeeb 52e2340276SBjoern A. Zeeb enum dpk_agc_step { 53e2340276SBjoern A. Zeeb DPK_AGC_STEP_SYNC_DGAIN, 54e2340276SBjoern A. Zeeb DPK_AGC_STEP_GAIN_LOSS_IDX, 55e2340276SBjoern A. Zeeb DPK_AGC_STEP_GL_GT_CRITERION, 56e2340276SBjoern A. Zeeb DPK_AGC_STEP_GL_LT_CRITERION, 57e2340276SBjoern A. Zeeb DPK_AGC_STEP_SET_TX_GAIN, 58e2340276SBjoern A. Zeeb }; 59e2340276SBjoern A. Zeeb 60e2340276SBjoern A. Zeeb enum rtw8851b_iqk_type { 61e2340276SBjoern A. Zeeb ID_TXAGC = 0x0, 62e2340276SBjoern A. Zeeb ID_FLOK_COARSE = 0x1, 63e2340276SBjoern A. Zeeb ID_FLOK_FINE = 0x2, 64e2340276SBjoern A. Zeeb ID_TXK = 0x3, 65e2340276SBjoern A. Zeeb ID_RXAGC = 0x4, 66e2340276SBjoern A. Zeeb ID_RXK = 0x5, 67e2340276SBjoern A. Zeeb ID_NBTXK = 0x6, 68e2340276SBjoern A. Zeeb ID_NBRXK = 0x7, 69e2340276SBjoern A. Zeeb ID_FLOK_VBUFFER = 0x8, 70e2340276SBjoern A. Zeeb ID_A_FLOK_COARSE = 0x9, 71e2340276SBjoern A. Zeeb ID_G_FLOK_COARSE = 0xa, 72e2340276SBjoern A. Zeeb ID_A_FLOK_FINE = 0xb, 73e2340276SBjoern A. Zeeb ID_G_FLOK_FINE = 0xc, 74e2340276SBjoern A. Zeeb ID_IQK_RESTORE = 0x10, 75e2340276SBjoern A. Zeeb }; 76e2340276SBjoern A. Zeeb 77e2340276SBjoern A. Zeeb enum rf_mode { 78e2340276SBjoern A. Zeeb RF_SHUT_DOWN = 0x0, 79e2340276SBjoern A. Zeeb RF_STANDBY = 0x1, 80e2340276SBjoern A. Zeeb RF_TX = 0x2, 81e2340276SBjoern A. Zeeb RF_RX = 0x3, 82e2340276SBjoern A. Zeeb RF_TXIQK = 0x4, 83e2340276SBjoern A. Zeeb RF_DPK = 0x5, 84e2340276SBjoern A. Zeeb RF_RXK1 = 0x6, 85e2340276SBjoern A. Zeeb RF_RXK2 = 0x7, 86e2340276SBjoern A. Zeeb }; 87e2340276SBjoern A. Zeeb 88e2340276SBjoern A. Zeeb static const u32 _tssi_de_cck_long[RF_PATH_NUM_8851B] = {0x5858}; 89e2340276SBjoern A. Zeeb static const u32 _tssi_de_cck_short[RF_PATH_NUM_8851B] = {0x5860}; 90e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_20m[RF_PATH_NUM_8851B] = {0x5838}; 91e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_40m[RF_PATH_NUM_8851B] = {0x5840}; 92e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_80m[RF_PATH_NUM_8851B] = {0x5848}; 93e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_80m_80m[RF_PATH_NUM_8851B] = {0x5850}; 94e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_5m[RF_PATH_NUM_8851B] = {0x5828}; 95e2340276SBjoern A. Zeeb static const u32 _tssi_de_mcs_10m[RF_PATH_NUM_8851B] = {0x5830}; 96e2340276SBjoern A. Zeeb static const u32 g_idxrxgain[RTW8851B_RXK_GROUP_NR] = {0x10e, 0x116, 0x28e, 0x296}; 97e2340276SBjoern A. Zeeb static const u32 g_idxattc2[RTW8851B_RXK_GROUP_NR] = {0x0, 0xf, 0x0, 0xf}; 98e2340276SBjoern A. Zeeb static const u32 g_idxrxagc[RTW8851B_RXK_GROUP_NR] = {0x0, 0x1, 0x2, 0x3}; 99e2340276SBjoern A. Zeeb static const u32 a_idxrxgain[RTW8851B_RXK_GROUP_IDX_NR] = {0x10C, 0x28c}; 100e2340276SBjoern A. Zeeb static const u32 a_idxattc2[RTW8851B_RXK_GROUP_IDX_NR] = {0xf, 0xf}; 101e2340276SBjoern A. Zeeb static const u32 a_idxrxagc[RTW8851B_RXK_GROUP_IDX_NR] = {0x4, 0x6}; 102e2340276SBjoern A. Zeeb static const u32 a_power_range[RTW8851B_TXK_GROUP_NR] = {0x0}; 103e2340276SBjoern A. Zeeb static const u32 a_track_range[RTW8851B_TXK_GROUP_NR] = {0x6}; 104e2340276SBjoern A. Zeeb static const u32 a_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x0a}; 105e2340276SBjoern A. Zeeb static const u32 a_itqt[RTW8851B_TXK_GROUP_NR] = {0x12}; 106e2340276SBjoern A. Zeeb static const u32 g_power_range[RTW8851B_TXK_GROUP_NR] = {0x0}; 107e2340276SBjoern A. Zeeb static const u32 g_track_range[RTW8851B_TXK_GROUP_NR] = {0x6}; 108e2340276SBjoern A. Zeeb static const u32 g_gain_bb[RTW8851B_TXK_GROUP_NR] = {0x10}; 109e2340276SBjoern A. Zeeb static const u32 g_itqt[RTW8851B_TXK_GROUP_NR] = {0x12}; 110e2340276SBjoern A. Zeeb 111e2340276SBjoern A. Zeeb static const u32 rtw8851b_backup_bb_regs[] = {0xc0d4, 0xc0d8, 0xc0c4, 0xc0ec, 0xc0e8}; 112e2340276SBjoern A. Zeeb static const u32 rtw8851b_backup_rf_regs[] = { 113e2340276SBjoern A. Zeeb 0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; 114e2340276SBjoern A. Zeeb 115e2340276SBjoern A. Zeeb #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8851b_backup_bb_regs) 116e2340276SBjoern A. Zeeb #define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8851b_backup_rf_regs) 117e2340276SBjoern A. Zeeb 118e2340276SBjoern A. Zeeb static const u32 dpk_kip_reg[DPK_KIP_REG_NUM_8851B] = { 119e2340276SBjoern A. Zeeb 0x813c, 0x8124, 0xc0ec, 0xc0e8, 0xc0c4, 0xc0d4, 0xc0d8}; 120e2340276SBjoern A. Zeeb static const u32 dpk_rf_reg[DPK_RF_REG_NUM_8851B] = {0xde, 0x8f, 0x5, 0x10005}; 121e2340276SBjoern A. Zeeb 122e2340276SBjoern A. Zeeb static void _set_ch(struct rtw89_dev *rtwdev, u32 val); 123e2340276SBjoern A. Zeeb 124e2340276SBjoern A. Zeeb static u8 _rxk_5ghz_group_from_idx(u8 idx) 125e2340276SBjoern A. Zeeb { 126e2340276SBjoern A. Zeeb /* There are four RXK groups (RTW8851B_RXK_GROUP_NR), but only group 0 127e2340276SBjoern A. Zeeb * and 2 are used in 5 GHz band, so reduce elements to 2. 128e2340276SBjoern A. Zeeb */ 129e2340276SBjoern A. Zeeb if (idx < RTW8851B_RXK_GROUP_IDX_NR) 130e2340276SBjoern A. Zeeb return idx * 2; 131e2340276SBjoern A. Zeeb 132e2340276SBjoern A. Zeeb return 0; 133e2340276SBjoern A. Zeeb } 134e2340276SBjoern A. Zeeb 135e2340276SBjoern A. Zeeb static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 136e2340276SBjoern A. Zeeb { 137e2340276SBjoern A. Zeeb return RF_A; 138e2340276SBjoern A. Zeeb } 139e2340276SBjoern A. Zeeb 140e2340276SBjoern A. Zeeb static void _adc_fifo_rst(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 141e2340276SBjoern A. Zeeb u8 path) 142e2340276SBjoern A. Zeeb { 143e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x0101); 144e2340276SBjoern A. Zeeb fsleep(10); 145e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RXK, 0x1111); 146e2340276SBjoern A. Zeeb } 147e2340276SBjoern A. Zeeb 148e2340276SBjoern A. Zeeb static void _rfk_rf_direct_cntrl(struct rtw89_dev *rtwdev, 149e2340276SBjoern A. Zeeb enum rtw89_rf_path path, bool is_bybb) 150e2340276SBjoern A. Zeeb { 151e2340276SBjoern A. Zeeb if (is_bybb) 152e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); 153e2340276SBjoern A. Zeeb else 154e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 155e2340276SBjoern A. Zeeb } 156e2340276SBjoern A. Zeeb 157e2340276SBjoern A. Zeeb static void _rfk_drf_direct_cntrl(struct rtw89_dev *rtwdev, 158e2340276SBjoern A. Zeeb enum rtw89_rf_path path, bool is_bybb) 159e2340276SBjoern A. Zeeb { 160e2340276SBjoern A. Zeeb if (is_bybb) 161e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x1); 162e2340276SBjoern A. Zeeb else 163e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BBDC, RR_BBDC_SEL, 0x0); 164e2340276SBjoern A. Zeeb } 165e2340276SBjoern A. Zeeb 166e2340276SBjoern A. Zeeb static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) 167e2340276SBjoern A. Zeeb { 168e2340276SBjoern A. Zeeb u32 rf_mode; 169e2340276SBjoern A. Zeeb u8 path; 170e2340276SBjoern A. Zeeb int ret; 171e2340276SBjoern A. Zeeb 172e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_MAX; path++) { 173e2340276SBjoern A. Zeeb if (!(kpath & BIT(path))) 174e2340276SBjoern A. Zeeb continue; 175e2340276SBjoern A. Zeeb 176e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, 177e2340276SBjoern A. Zeeb rf_mode != 2, 2, 5000, false, 178e2340276SBjoern A. Zeeb rtwdev, path, 0x00, RR_MOD_MASK); 179e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 180e2340276SBjoern A. Zeeb "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", 181e2340276SBjoern A. Zeeb path, ret); 182e2340276SBjoern A. Zeeb } 183e2340276SBjoern A. Zeeb } 184e2340276SBjoern A. Zeeb 185e2340276SBjoern A. Zeeb static void _dack_reset(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 186e2340276SBjoern A. Zeeb { 187e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x0); 188e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_RST, 0x1); 189e2340276SBjoern A. Zeeb } 190e2340276SBjoern A. Zeeb 191e2340276SBjoern A. Zeeb static void _drck(struct rtw89_dev *rtwdev) 192e2340276SBjoern A. Zeeb { 193e2340276SBjoern A. Zeeb u32 rck_d; 194e2340276SBjoern A. Zeeb u32 val; 195e2340276SBjoern A. Zeeb int ret; 196e2340276SBjoern A. Zeeb 197e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]Ddie RCK start!!!\n"); 198e2340276SBjoern A. Zeeb 199e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x1); 200e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x1); 201e2340276SBjoern A. Zeeb 202e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 203e2340276SBjoern A. Zeeb 1, 10000, false, 204e2340276SBjoern A. Zeeb rtwdev, R_DRCK_RES, B_DRCK_POL); 205e2340276SBjoern A. Zeeb if (ret) 206e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DRCK timeout\n"); 207e2340276SBjoern A. Zeeb 208e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_EN, 0x0); 209e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x1); 210e2340276SBjoern A. Zeeb udelay(1); 211e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK_FH, B_DRCK_LAT, 0x0); 212e2340276SBjoern A. Zeeb 213e2340276SBjoern A. Zeeb rck_d = rtw89_phy_read32_mask(rtwdev, R_DRCK_RES, 0x7c00); 214e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_IDLE, 0x0); 215e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DRCK, B_DRCK_VAL, rck_d); 216e2340276SBjoern A. Zeeb 217e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0xc0c4 = 0x%x\n", 218e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DRCK, MASKDWORD)); 219e2340276SBjoern A. Zeeb } 220e2340276SBjoern A. Zeeb 221e2340276SBjoern A. Zeeb static void _addck_backup(struct rtw89_dev *rtwdev) 222e2340276SBjoern A. Zeeb { 223e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 224e2340276SBjoern A. Zeeb 225e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x0); 226e2340276SBjoern A. Zeeb 227e2340276SBjoern A. Zeeb dack->addck_d[0][0] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A0); 228e2340276SBjoern A. Zeeb dack->addck_d[0][1] = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_A1); 229e2340276SBjoern A. Zeeb } 230e2340276SBjoern A. Zeeb 231e2340276SBjoern A. Zeeb static void _addck_reload(struct rtw89_dev *rtwdev) 232e2340276SBjoern A. Zeeb { 233e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 234e2340276SBjoern A. Zeeb 235e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL1, dack->addck_d[0][0]); 236e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RL0, dack->addck_d[0][1]); 237e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0_RL, B_ADDCK0_RLS, 0x3); 238e2340276SBjoern A. Zeeb } 239e2340276SBjoern A. Zeeb 240e2340276SBjoern A. Zeeb static void _dack_backup_s0(struct rtw89_dev *rtwdev) 241e2340276SBjoern A. Zeeb { 242e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 243e2340276SBjoern A. Zeeb u8 i; 244e2340276SBjoern A. Zeeb 245e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x1); 246e2340276SBjoern A. Zeeb 247e2340276SBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 248e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF0, B_DCOF0_V, i); 249e2340276SBjoern A. Zeeb dack->msbk_d[0][0][i] = 250e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0M0); 251e2340276SBjoern A. Zeeb 252e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF8, B_DCOF8_V, i); 253e2340276SBjoern A. Zeeb dack->msbk_d[0][1][i] = 254e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0M1); 255e2340276SBjoern A. Zeeb } 256e2340276SBjoern A. Zeeb 257e2340276SBjoern A. Zeeb dack->biask_d[0][0] = 258e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS00, B_DACK_BIAS00); 259e2340276SBjoern A. Zeeb dack->biask_d[0][1] = 260e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_BIAS01, B_DACK_BIAS01); 261e2340276SBjoern A. Zeeb dack->dadck_d[0][0] = 262e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK00, B_DACK_DADCK00) + 24; 263e2340276SBjoern A. Zeeb dack->dadck_d[0][1] = 264e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_DADCK01, B_DACK_DADCK01) + 24; 265e2340276SBjoern A. Zeeb } 266e2340276SBjoern A. Zeeb 267e2340276SBjoern A. Zeeb static void _dack_reload_by_path(struct rtw89_dev *rtwdev, 268e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 index) 269e2340276SBjoern A. Zeeb { 270e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 271e2340276SBjoern A. Zeeb u32 idx_offset, path_offset; 272e2340276SBjoern A. Zeeb u32 offset, reg; 273e2340276SBjoern A. Zeeb u32 tmp; 274e2340276SBjoern A. Zeeb u8 i; 275e2340276SBjoern A. Zeeb 276e2340276SBjoern A. Zeeb if (index == 0) 277e2340276SBjoern A. Zeeb idx_offset = 0; 278e2340276SBjoern A. Zeeb else 279e2340276SBjoern A. Zeeb idx_offset = 0x14; 280e2340276SBjoern A. Zeeb 281e2340276SBjoern A. Zeeb if (path == RF_PATH_A) 282e2340276SBjoern A. Zeeb path_offset = 0; 283e2340276SBjoern A. Zeeb else 284e2340276SBjoern A. Zeeb path_offset = 0x28; 285e2340276SBjoern A. Zeeb 286e2340276SBjoern A. Zeeb offset = idx_offset + path_offset; 287e2340276SBjoern A. Zeeb 288e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_RST, 0x1); 289e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF9, B_DCOF9_RST, 0x1); 290e2340276SBjoern A. Zeeb 291e2340276SBjoern A. Zeeb /* msbk_d: 15/14/13/12 */ 292e2340276SBjoern A. Zeeb tmp = 0x0; 293e2340276SBjoern A. Zeeb for (i = 0; i < 4; i++) 294e2340276SBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); 295e2340276SBjoern A. Zeeb reg = 0xc200 + offset; 296e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, reg, tmp); 297e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, 298e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); 299e2340276SBjoern A. Zeeb 300e2340276SBjoern A. Zeeb /* msbk_d: 11/10/9/8 */ 301e2340276SBjoern A. Zeeb tmp = 0x0; 302e2340276SBjoern A. Zeeb for (i = 0; i < 4; i++) 303e2340276SBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); 304e2340276SBjoern A. Zeeb reg = 0xc204 + offset; 305e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, reg, tmp); 306e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, 307e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); 308e2340276SBjoern A. Zeeb 309e2340276SBjoern A. Zeeb /* msbk_d: 7/6/5/4 */ 310e2340276SBjoern A. Zeeb tmp = 0x0; 311e2340276SBjoern A. Zeeb for (i = 0; i < 4; i++) 312e2340276SBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); 313e2340276SBjoern A. Zeeb reg = 0xc208 + offset; 314e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, reg, tmp); 315e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, 316e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); 317e2340276SBjoern A. Zeeb 318e2340276SBjoern A. Zeeb /* msbk_d: 3/2/1/0 */ 319e2340276SBjoern A. Zeeb tmp = 0x0; 320e2340276SBjoern A. Zeeb for (i = 0; i < 4; i++) 321e2340276SBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i] << (i * 8); 322e2340276SBjoern A. Zeeb reg = 0xc20c + offset; 323e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, reg, tmp); 324e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, 325e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); 326e2340276SBjoern A. Zeeb 327e2340276SBjoern A. Zeeb /* dadak_d/biask_d */ 328e2340276SBjoern A. Zeeb tmp = 0x0; 329e2340276SBjoern A. Zeeb tmp = (dack->biask_d[path][index] << 22) | 330e2340276SBjoern A. Zeeb (dack->dadck_d[path][index] << 14); 331e2340276SBjoern A. Zeeb reg = 0xc210 + offset; 332e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, reg, tmp); 333e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", reg, 334e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg, MASKDWORD)); 335e2340276SBjoern A. Zeeb 336e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL + offset, B_DACKN0_EN, 0x1); 337e2340276SBjoern A. Zeeb } 338e2340276SBjoern A. Zeeb 339e2340276SBjoern A. Zeeb static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 340e2340276SBjoern A. Zeeb { 341e2340276SBjoern A. Zeeb u8 index; 342e2340276SBjoern A. Zeeb 343e2340276SBjoern A. Zeeb for (index = 0; index < 2; index++) 344e2340276SBjoern A. Zeeb _dack_reload_by_path(rtwdev, path, index); 345e2340276SBjoern A. Zeeb } 346e2340276SBjoern A. Zeeb 347e2340276SBjoern A. Zeeb static void _addck(struct rtw89_dev *rtwdev) 348e2340276SBjoern A. Zeeb { 349e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 350e2340276SBjoern A. Zeeb u32 val; 351e2340276SBjoern A. Zeeb int ret; 352e2340276SBjoern A. Zeeb 353e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x1); 354e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x1); 355e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_EN, 0x0); 356e2340276SBjoern A. Zeeb udelay(1); 357e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0, 0x1); 358e2340276SBjoern A. Zeeb 359e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 360e2340276SBjoern A. Zeeb 1, 10000, false, 361e2340276SBjoern A. Zeeb rtwdev, R_ADDCKR0, BIT(0)); 362e2340276SBjoern A. Zeeb if (ret) { 363e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); 364e2340276SBjoern A. Zeeb dack->addck_timeout[0] = true; 365e2340276SBjoern A. Zeeb } 366e2340276SBjoern A. Zeeb 367e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); 368e2340276SBjoern A. Zeeb 369e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_RST, 0x0); 370e2340276SBjoern A. Zeeb } 371e2340276SBjoern A. Zeeb 372e2340276SBjoern A. Zeeb static void _new_dadck(struct rtw89_dev *rtwdev) 373e2340276SBjoern A. Zeeb { 374e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 375e2340276SBjoern A. Zeeb u32 i_dc, q_dc, ic, qc; 376e2340276SBjoern A. Zeeb u32 val; 377e2340276SBjoern A. Zeeb int ret; 378e2340276SBjoern A. Zeeb 379e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_setup_defs_tbl); 380e2340276SBjoern A. Zeeb 381e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 382e2340276SBjoern A. Zeeb 1, 10000, false, 383e2340276SBjoern A. Zeeb rtwdev, R_ADDCKR0, BIT(0)); 384e2340276SBjoern A. Zeeb if (ret) { 385e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADCK timeout\n"); 386e2340276SBjoern A. Zeeb dack->addck_timeout[0] = true; 387e2340276SBjoern A. Zeeb } 388e2340276SBjoern A. Zeeb 389e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DADCK ret = %d\n", ret); 390e2340276SBjoern A. Zeeb 391e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x0); 392e2340276SBjoern A. Zeeb i_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); 393e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADDCK0, B_ADDCK0_IQ, 0x1); 394e2340276SBjoern A. Zeeb q_dc = rtw89_phy_read32_mask(rtwdev, R_ADDCKR0, B_ADDCKR0_DC); 395e2340276SBjoern A. Zeeb 396e2340276SBjoern A. Zeeb ic = 0x80 - sign_extend32(i_dc, 11) * 6; 397e2340276SBjoern A. Zeeb qc = 0x80 - sign_extend32(q_dc, 11) * 6; 398e2340276SBjoern A. Zeeb 399e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 400e2340276SBjoern A. Zeeb "[DACK]before DADCK, i_dc=0x%x, q_dc=0x%x\n", i_dc, q_dc); 401e2340276SBjoern A. Zeeb 402e2340276SBjoern A. Zeeb dack->dadck_d[0][0] = ic; 403e2340276SBjoern A. Zeeb dack->dadck_d[0][1] = qc; 404e2340276SBjoern A. Zeeb 405e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DACKN0_CTL, B_DACKN0_V, dack->dadck_d[0][0]); 406e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DACKN1_CTL, B_DACKN1_V, dack->dadck_d[0][1]); 407e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 408e2340276SBjoern A. Zeeb "[DACK]after DADCK, 0xc210=0x%x, 0xc224=0x%x\n", 409e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACKN0_CTL, MASKDWORD), 410e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACKN1_CTL, MASKDWORD)); 411e2340276SBjoern A. Zeeb 412e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_dadck_post_defs_tbl); 413e2340276SBjoern A. Zeeb } 414e2340276SBjoern A. Zeeb 415e2340276SBjoern A. Zeeb static bool _dack_s0_poll(struct rtw89_dev *rtwdev) 416e2340276SBjoern A. Zeeb { 417e2340276SBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_DACK_S0P0, B_DACK_S0P0_OK) == 0 || 418e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_S0P1, B_DACK_S0P1_OK) == 0 || 419e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_S0P2, B_DACK_S0P2_OK) == 0 || 420e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_DACK_S0P3, B_DACK_S0P3_OK) == 0) 421e2340276SBjoern A. Zeeb return false; 422e2340276SBjoern A. Zeeb 423e2340276SBjoern A. Zeeb return true; 424e2340276SBjoern A. Zeeb } 425e2340276SBjoern A. Zeeb 426e2340276SBjoern A. Zeeb static void _dack_s0(struct rtw89_dev *rtwdev) 427e2340276SBjoern A. Zeeb { 428e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 429e2340276SBjoern A. Zeeb bool done; 430e2340276SBjoern A. Zeeb int ret; 431e2340276SBjoern A. Zeeb 432e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_1_defs_tbl); 433e2340276SBjoern A. Zeeb _dack_reset(rtwdev, RF_PATH_A); 434e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DCOF1, B_DCOF1_S, 0x1); 435e2340276SBjoern A. Zeeb 436e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(_dack_s0_poll, done, done, 437e2340276SBjoern A. Zeeb 1, 10000, false, rtwdev); 438e2340276SBjoern A. Zeeb if (ret) { 439e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DACK timeout\n"); 440e2340276SBjoern A. Zeeb dack->msbk_timeout[0] = true; 441e2340276SBjoern A. Zeeb } 442e2340276SBjoern A. Zeeb 443e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); 444e2340276SBjoern A. Zeeb 445e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_dack_s0_2_defs_tbl); 446e2340276SBjoern A. Zeeb 447e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); 448e2340276SBjoern A. Zeeb 449e2340276SBjoern A. Zeeb _dack_backup_s0(rtwdev); 450e2340276SBjoern A. Zeeb _dack_reload(rtwdev, RF_PATH_A); 451e2340276SBjoern A. Zeeb 452e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG, 0x0); 453e2340276SBjoern A. Zeeb } 454e2340276SBjoern A. Zeeb 455e2340276SBjoern A. Zeeb static void _dack(struct rtw89_dev *rtwdev) 456e2340276SBjoern A. Zeeb { 457e2340276SBjoern A. Zeeb _dack_s0(rtwdev); 458e2340276SBjoern A. Zeeb } 459e2340276SBjoern A. Zeeb 460e2340276SBjoern A. Zeeb static void _dack_dump(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 u8 t; 465e2340276SBjoern A. Zeeb 466e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", 467e2340276SBjoern A. Zeeb dack->addck_d[0][0], dack->addck_d[0][1]); 468e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", 469e2340276SBjoern A. Zeeb dack->dadck_d[0][0], dack->dadck_d[0][1]); 470e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", 471e2340276SBjoern A. Zeeb dack->biask_d[0][0], dack->biask_d[0][1]); 472e2340276SBjoern A. Zeeb 473e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); 474e2340276SBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 475e2340276SBjoern A. Zeeb t = dack->msbk_d[0][0][i]; 476e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 477e2340276SBjoern A. Zeeb } 478e2340276SBjoern A. Zeeb 479e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); 480e2340276SBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 481e2340276SBjoern A. Zeeb t = dack->msbk_d[0][1][i]; 482e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 483e2340276SBjoern A. Zeeb } 484e2340276SBjoern A. Zeeb } 485e2340276SBjoern A. Zeeb 486e2340276SBjoern A. Zeeb static void _dack_manual_off(struct rtw89_dev *rtwdev) 487e2340276SBjoern A. Zeeb { 488e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_dack_manual_off_defs_tbl); 489e2340276SBjoern A. Zeeb } 490e2340276SBjoern A. Zeeb 491e2340276SBjoern A. Zeeb static void _dac_cal(struct rtw89_dev *rtwdev, bool force) 492e2340276SBjoern A. Zeeb { 493e2340276SBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 494e2340276SBjoern A. Zeeb u32 rf0_0; 495e2340276SBjoern A. Zeeb 496e2340276SBjoern A. Zeeb dack->dack_done = false; 497e2340276SBjoern A. Zeeb 498e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK 0x2\n"); 499e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); 500e2340276SBjoern A. Zeeb rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); 501e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]RF0=0x%x\n", rf0_0); 502e2340276SBjoern A. Zeeb 503e2340276SBjoern A. Zeeb _drck(rtwdev); 504e2340276SBjoern A. Zeeb _dack_manual_off(rtwdev); 505e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x337e1); 506e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); 507e2340276SBjoern A. Zeeb 508e2340276SBjoern A. Zeeb _addck(rtwdev); 509e2340276SBjoern A. Zeeb _addck_backup(rtwdev); 510e2340276SBjoern A. Zeeb _addck_reload(rtwdev); 511e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); 512e2340276SBjoern A. Zeeb 513e2340276SBjoern A. Zeeb _dack(rtwdev); 514e2340276SBjoern A. Zeeb _new_dadck(rtwdev); 515e2340276SBjoern A. Zeeb _dack_dump(rtwdev); 516e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); 517e2340276SBjoern A. Zeeb 518e2340276SBjoern A. Zeeb dack->dack_done = true; 519e2340276SBjoern A. Zeeb dack->dack_cnt++; 520e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); 521e2340276SBjoern A. Zeeb } 522e2340276SBjoern A. Zeeb 523e2340276SBjoern A. Zeeb static void _rx_dck_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 524*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, bool is_afe, 525*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 526e2340276SBjoern A. Zeeb { 527*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 528e2340276SBjoern A. Zeeb 529e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 530e2340276SBjoern A. Zeeb "[RX_DCK] ==== S%d RX DCK (%s / CH%d / %s / by %s)====\n", path, 531e2340276SBjoern A. Zeeb chan->band_type == RTW89_BAND_2G ? "2G" : 532e2340276SBjoern A. Zeeb chan->band_type == RTW89_BAND_5G ? "5G" : "6G", 533e2340276SBjoern A. Zeeb chan->channel, 534e2340276SBjoern A. Zeeb chan->band_width == RTW89_CHANNEL_WIDTH_20 ? "20M" : 535e2340276SBjoern A. Zeeb chan->band_width == RTW89_CHANNEL_WIDTH_40 ? "40M" : "80M", 536e2340276SBjoern A. Zeeb is_afe ? "AFE" : "RFC"); 537e2340276SBjoern A. Zeeb } 538e2340276SBjoern A. Zeeb 539e2340276SBjoern A. Zeeb static void _rxbb_ofst_swap(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) 540e2340276SBjoern A. Zeeb { 541e2340276SBjoern A. Zeeb u32 val, val_i, val_q; 542e2340276SBjoern A. Zeeb 543e2340276SBjoern A. Zeeb val_i = rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_S1); 544e2340276SBjoern A. Zeeb val_q = rtw89_read_rf(rtwdev, path, RR_DCK1, RR_DCK1_S1); 545e2340276SBjoern A. Zeeb 546e2340276SBjoern A. Zeeb val = val_q << 4 | val_i; 547e2340276SBjoern A. Zeeb 548e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x1); 549e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, rf_mode); 550e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val); 551e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_DIS, 0x0); 552e2340276SBjoern A. Zeeb 553e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 554e2340276SBjoern A. Zeeb "[RX_DCK] val_i = 0x%x, val_q = 0x%x, 0x3F = 0x%x\n", 555e2340276SBjoern A. Zeeb val_i, val_q, val); 556e2340276SBjoern A. Zeeb } 557e2340276SBjoern A. Zeeb 558e2340276SBjoern A. Zeeb static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 rf_mode) 559e2340276SBjoern A. Zeeb { 560e2340276SBjoern A. Zeeb u32 val; 561e2340276SBjoern A. Zeeb int ret; 562e2340276SBjoern A. Zeeb 563e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); 564e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); 565e2340276SBjoern A. Zeeb 566e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 567e2340276SBjoern A. Zeeb 2, 2000, false, 568e2340276SBjoern A. Zeeb rtwdev, path, RR_DCK, BIT(8)); 569e2340276SBjoern A. Zeeb 570e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); 571e2340276SBjoern A. Zeeb 572e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RX_DCK] S%d RXDCK finish (ret = %d)\n", 573e2340276SBjoern A. Zeeb path, ret); 574e2340276SBjoern A. Zeeb 575e2340276SBjoern A. Zeeb _rxbb_ofst_swap(rtwdev, path, rf_mode); 576e2340276SBjoern A. Zeeb } 577e2340276SBjoern A. Zeeb 578*df279a26SBjoern A. Zeeb static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool is_afe, 579*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 580e2340276SBjoern A. Zeeb { 581e2340276SBjoern A. Zeeb u32 rf_reg5; 582e2340276SBjoern A. Zeeb u8 path; 583e2340276SBjoern A. Zeeb 584e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 585e2340276SBjoern A. Zeeb "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", 586e2340276SBjoern A. Zeeb 0x2, rtwdev->hal.cv); 587e2340276SBjoern A. Zeeb 588e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 589*df279a26SBjoern A. Zeeb _rx_dck_info(rtwdev, phy, path, is_afe, chanctx_idx); 590e2340276SBjoern A. Zeeb 591e2340276SBjoern A. Zeeb rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); 592e2340276SBjoern A. Zeeb 593e2340276SBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 594e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, 595e2340276SBjoern A. Zeeb R_P0_TSSI_TRK + (path << 13), 596e2340276SBjoern A. Zeeb B_P0_TSSI_TRK_EN, 0x1); 597e2340276SBjoern A. Zeeb 598e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 599e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); 600e2340276SBjoern A. Zeeb _set_rx_dck(rtwdev, path, RF_RX); 601e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); 602e2340276SBjoern A. Zeeb 603e2340276SBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 604e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, 605e2340276SBjoern A. Zeeb R_P0_TSSI_TRK + (path << 13), 606e2340276SBjoern A. Zeeb B_P0_TSSI_TRK_EN, 0x0); 607e2340276SBjoern A. Zeeb } 608e2340276SBjoern A. Zeeb } 609e2340276SBjoern A. Zeeb 610e2340276SBjoern A. Zeeb static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) 611e2340276SBjoern A. Zeeb { 612e2340276SBjoern A. Zeeb u32 i; 613e2340276SBjoern A. Zeeb 614e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 615e2340276SBjoern A. Zeeb 616e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); 617e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); 618e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); 619e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); 620e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); 621e2340276SBjoern A. Zeeb 622e2340276SBjoern A. Zeeb for (i = 0; i <= 0x9f; i++) { 623e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 624e2340276SBjoern A. Zeeb 0x00010000 + i); 625e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", 626e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI)); 627e2340276SBjoern A. Zeeb } 628e2340276SBjoern A. Zeeb 629e2340276SBjoern A. Zeeb for (i = 0; i <= 0x9f; i++) { 630e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 631e2340276SBjoern A. Zeeb 0x00010000 + i); 632e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", 633e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ)); 634e2340276SBjoern A. Zeeb } 635e2340276SBjoern A. Zeeb 636e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000000); 637e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00000000); 638e2340276SBjoern A. Zeeb } 639e2340276SBjoern A. Zeeb 640e2340276SBjoern A. Zeeb static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) 641e2340276SBjoern A. Zeeb { 642e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); 643e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 644e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); 645e2340276SBjoern A. Zeeb } 646e2340276SBjoern A. Zeeb 647e2340276SBjoern A. Zeeb static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path) 648e2340276SBjoern A. Zeeb { 649e2340276SBjoern A. Zeeb bool fail1 = false, fail2 = false; 650e2340276SBjoern A. Zeeb u32 val; 651e2340276SBjoern A. Zeeb int ret; 652e2340276SBjoern A. Zeeb 653e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 654e2340276SBjoern A. Zeeb 10, 8200, false, 655e2340276SBjoern A. Zeeb rtwdev, 0xbff8, MASKBYTE0); 656e2340276SBjoern A. Zeeb if (ret) { 657e2340276SBjoern A. Zeeb fail1 = true; 658e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 659e2340276SBjoern A. Zeeb "[IQK]NCTL1 IQK timeout!!!\n"); 660e2340276SBjoern A. Zeeb } 661e2340276SBjoern A. Zeeb 662e2340276SBjoern A. Zeeb fsleep(10); 663e2340276SBjoern A. Zeeb 664e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, 665e2340276SBjoern A. Zeeb 10, 200, false, 666e2340276SBjoern A. Zeeb rtwdev, R_RPT_COM, B_RPT_COM_RDY); 667e2340276SBjoern A. Zeeb if (ret) { 668e2340276SBjoern A. Zeeb fail2 = true; 669e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 670e2340276SBjoern A. Zeeb "[IQK]NCTL2 IQK timeout!!!\n"); 671e2340276SBjoern A. Zeeb } 672e2340276SBjoern A. Zeeb 673e2340276SBjoern A. Zeeb fsleep(10); 674e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); 675e2340276SBjoern A. Zeeb 676e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 677e2340276SBjoern A. Zeeb "[IQK]S%x, ret = %d, notready = %x fail=%d,%d\n", 678e2340276SBjoern A. Zeeb path, ret, fail1 || fail2, fail1, fail2); 679e2340276SBjoern A. Zeeb 680e2340276SBjoern A. Zeeb return fail1 || fail2; 681e2340276SBjoern A. Zeeb } 682e2340276SBjoern A. Zeeb 683e2340276SBjoern A. Zeeb static bool _iqk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 684e2340276SBjoern A. Zeeb u8 path, u8 ktype) 685e2340276SBjoern A. Zeeb { 686e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 687e2340276SBjoern A. Zeeb bool notready; 688e2340276SBjoern A. Zeeb u32 iqk_cmd; 689e2340276SBjoern A. Zeeb 690e2340276SBjoern A. Zeeb switch (ktype) { 691e2340276SBjoern A. Zeeb case ID_A_FLOK_COARSE: 692e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 693e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_A_FLOK_COARSE ============\n", path); 694e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 695e2340276SBjoern A. Zeeb iqk_cmd = 0x108 | (1 << (4 + path)); 696e2340276SBjoern A. Zeeb break; 697e2340276SBjoern A. Zeeb case ID_G_FLOK_COARSE: 698e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 699e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_G_FLOK_COARSE ============\n", path); 700e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 701e2340276SBjoern A. Zeeb iqk_cmd = 0x108 | (1 << (4 + path)); 702e2340276SBjoern A. Zeeb break; 703e2340276SBjoern A. Zeeb case ID_A_FLOK_FINE: 704e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 705e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_A_FLOK_FINE ============\n", path); 706e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 707e2340276SBjoern A. Zeeb iqk_cmd = 0x308 | (1 << (4 + path)); 708e2340276SBjoern A. Zeeb break; 709e2340276SBjoern A. Zeeb case ID_G_FLOK_FINE: 710e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 711e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_G_FLOK_FINE ============\n", path); 712e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 713e2340276SBjoern A. Zeeb iqk_cmd = 0x308 | (1 << (4 + path)); 714e2340276SBjoern A. Zeeb break; 715e2340276SBjoern A. Zeeb case ID_TXK: 716e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 717e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_TXK ============\n", path); 718e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); 719e2340276SBjoern A. Zeeb iqk_cmd = 0x008 | (1 << (path + 4)) | 720e2340276SBjoern A. Zeeb (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); 721e2340276SBjoern A. Zeeb break; 722e2340276SBjoern A. Zeeb case ID_RXAGC: 723e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 724e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_RXAGC ============\n", path); 725e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 726e2340276SBjoern A. Zeeb iqk_cmd = 0x708 | (1 << (4 + path)) | (path << 1); 727e2340276SBjoern A. Zeeb break; 728e2340276SBjoern A. Zeeb case ID_RXK: 729e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 730e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_RXK ============\n", path); 731e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 732e2340276SBjoern A. Zeeb iqk_cmd = 0x008 | (1 << (path + 4)) | 733e2340276SBjoern A. Zeeb (((0xc + iqk_info->iqk_bw[path]) & 0xf) << 8); 734e2340276SBjoern A. Zeeb break; 735e2340276SBjoern A. Zeeb case ID_NBTXK: 736e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 737e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_NBTXK ============\n", path); 738e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); 739e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 740e2340276SBjoern A. Zeeb 0x00b); 741e2340276SBjoern A. Zeeb iqk_cmd = 0x408 | (1 << (4 + path)); 742e2340276SBjoern A. Zeeb break; 743e2340276SBjoern A. Zeeb case ID_NBRXK: 744e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 745e2340276SBjoern A. Zeeb "[IQK]============ S%d ID_NBRXK ============\n", path); 746e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 747e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 748e2340276SBjoern A. Zeeb 0x011); 749e2340276SBjoern A. Zeeb iqk_cmd = 0x608 | (1 << (4 + path)); 750e2340276SBjoern A. Zeeb break; 751e2340276SBjoern A. Zeeb default: 752e2340276SBjoern A. Zeeb return false; 753e2340276SBjoern A. Zeeb } 754e2340276SBjoern A. Zeeb 755e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); 756e2340276SBjoern A. Zeeb notready = _iqk_check_cal(rtwdev, path); 757e2340276SBjoern A. Zeeb if (iqk_info->iqk_sram_en && 758e2340276SBjoern A. Zeeb (ktype == ID_NBRXK || ktype == ID_RXK)) 759e2340276SBjoern A. Zeeb _iqk_sram(rtwdev, path); 760e2340276SBjoern A. Zeeb 761e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); 762e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 763e2340276SBjoern A. Zeeb "[IQK]S%x, ktype= %x, id = %x, notready = %x\n", 764e2340276SBjoern A. Zeeb path, ktype, iqk_cmd + 1, notready); 765e2340276SBjoern A. Zeeb 766e2340276SBjoern A. Zeeb return notready; 767e2340276SBjoern A. Zeeb } 768e2340276SBjoern A. Zeeb 769e2340276SBjoern A. Zeeb static bool _rxk_2g_group_sel(struct rtw89_dev *rtwdev, 770e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 771e2340276SBjoern A. Zeeb { 772e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 773e2340276SBjoern A. Zeeb bool kfail = false; 774e2340276SBjoern A. Zeeb bool notready; 775e2340276SBjoern A. Zeeb u32 rf_0; 776e2340276SBjoern A. Zeeb u8 gp; 777e2340276SBjoern A. Zeeb 778e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 779e2340276SBjoern A. Zeeb 780e2340276SBjoern A. Zeeb for (gp = 0; gp < RTW8851B_RXK_GROUP_NR; gp++) { 781e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); 782e2340276SBjoern A. Zeeb 783e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); 784e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); 785e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 786e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); 787e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); 788e2340276SBjoern A. Zeeb 789e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); 790e2340276SBjoern A. Zeeb fsleep(10); 791e2340276SBjoern A. Zeeb rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 792e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); 793e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); 794e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); 795e2340276SBjoern A. Zeeb 796e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); 797e2340276SBjoern A. Zeeb 798e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 799e2340276SBjoern A. Zeeb "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, 800e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), 801e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); 802e2340276SBjoern A. Zeeb 803e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 804e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 805e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); 806e2340276SBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 807e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; 808e2340276SBjoern A. Zeeb 809e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); 810e2340276SBjoern A. Zeeb 811e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 812e2340276SBjoern A. Zeeb "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, 813e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 814e2340276SBjoern A. Zeeb } 815e2340276SBjoern A. Zeeb 816e2340276SBjoern A. Zeeb if (!notready) 817e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 818e2340276SBjoern A. Zeeb 819e2340276SBjoern A. Zeeb if (kfail) 820e2340276SBjoern A. Zeeb _iqk_sram(rtwdev, path); 821e2340276SBjoern A. Zeeb 822e2340276SBjoern A. Zeeb if (kfail) { 823e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 824e2340276SBjoern A. Zeeb MASKDWORD, iqk_info->nb_rxcfir[path] | 0x2); 825e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = false; 826e2340276SBjoern A. Zeeb } else { 827e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 828e2340276SBjoern A. Zeeb MASKDWORD, 0x40000000); 829e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = true; 830e2340276SBjoern A. Zeeb } 831e2340276SBjoern A. Zeeb 832e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 833e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, 834e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_rxcfir[path]); 835e2340276SBjoern A. Zeeb return kfail; 836e2340276SBjoern A. Zeeb } 837e2340276SBjoern A. Zeeb 838e2340276SBjoern A. Zeeb static bool _rxk_5g_group_sel(struct rtw89_dev *rtwdev, 839e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 840e2340276SBjoern A. Zeeb { 841e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 842e2340276SBjoern A. Zeeb bool kfail = false; 843e2340276SBjoern A. Zeeb bool notready; 844e2340276SBjoern A. Zeeb u32 rf_0; 845e2340276SBjoern A. Zeeb u8 idx; 846e2340276SBjoern A. Zeeb u8 gp; 847e2340276SBjoern A. Zeeb 848e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 849e2340276SBjoern A. Zeeb 850e2340276SBjoern A. Zeeb for (idx = 0; idx < RTW8851B_RXK_GROUP_IDX_NR; idx++) { 851e2340276SBjoern A. Zeeb gp = _rxk_5ghz_group_from_idx(idx); 852e2340276SBjoern A. Zeeb 853e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); 854e2340276SBjoern A. Zeeb 855e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[idx]); 856e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[idx]); 857e2340276SBjoern A. Zeeb 858e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 859e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); 860e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); 861e2340276SBjoern A. Zeeb 862e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); 863e2340276SBjoern A. Zeeb fsleep(100); 864e2340276SBjoern A. Zeeb rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 865e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); 866e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[idx]); 867e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); 868e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); 869e2340276SBjoern A. Zeeb 870e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 871e2340276SBjoern A. Zeeb "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, 872e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), 873e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB)); 874e2340276SBjoern A. Zeeb 875e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 876e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 877e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); 878e2340276SBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 879e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; 880e2340276SBjoern A. Zeeb 881e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 882e2340276SBjoern A. Zeeb "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, 883e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 884e2340276SBjoern A. Zeeb 885e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK); 886e2340276SBjoern A. Zeeb 887e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 888e2340276SBjoern A. Zeeb "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", path, 889e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 890e2340276SBjoern A. Zeeb } 891e2340276SBjoern A. Zeeb 892e2340276SBjoern A. Zeeb if (!notready) 893e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 894e2340276SBjoern A. Zeeb 895e2340276SBjoern A. Zeeb if (kfail) 896e2340276SBjoern A. Zeeb _iqk_sram(rtwdev, path); 897e2340276SBjoern A. Zeeb 898e2340276SBjoern A. Zeeb if (kfail) { 899e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 900e2340276SBjoern A. Zeeb iqk_info->nb_rxcfir[path] | 0x2); 901e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = false; 902e2340276SBjoern A. Zeeb } else { 903e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 904e2340276SBjoern A. Zeeb 0x40000000); 905e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = true; 906e2340276SBjoern A. Zeeb } 907e2340276SBjoern A. Zeeb 908e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 909e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, 910e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_rxcfir[path]); 911e2340276SBjoern A. Zeeb return kfail; 912e2340276SBjoern A. Zeeb } 913e2340276SBjoern A. Zeeb 914e2340276SBjoern A. Zeeb static bool _iqk_5g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 915e2340276SBjoern A. Zeeb u8 path) 916e2340276SBjoern A. Zeeb { 917e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 918e2340276SBjoern A. Zeeb bool kfail = false; 919e2340276SBjoern A. Zeeb bool notready; 920e2340276SBjoern A. Zeeb u8 idx = 0x1; 921e2340276SBjoern A. Zeeb u32 rf_0; 922e2340276SBjoern A. Zeeb u8 gp; 923e2340276SBjoern A. Zeeb 924e2340276SBjoern A. Zeeb gp = _rxk_5ghz_group_from_idx(idx); 925e2340276SBjoern A. Zeeb 926e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 927e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); 928e2340276SBjoern A. Zeeb 929e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_RGM, a_idxrxgain[idx]); 930e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RXA2, RR_RXA2_ATT, a_idxattc2[idx]); 931e2340276SBjoern A. Zeeb 932e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 933e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); 934e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); 935e2340276SBjoern A. Zeeb 936e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); 937e2340276SBjoern A. Zeeb fsleep(100); 938e2340276SBjoern A. Zeeb rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 939e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); 940e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, a_idxrxagc[idx]); 941e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); 942e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); 943e2340276SBjoern A. Zeeb 944e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 945e2340276SBjoern A. Zeeb "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", path, 946e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), 947e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); 948e2340276SBjoern A. Zeeb 949e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 950e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 951e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); 952e2340276SBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 953e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; 954e2340276SBjoern A. Zeeb 955e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 956e2340276SBjoern A. Zeeb "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, 957e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 958e2340276SBjoern A. Zeeb 959e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", 960e2340276SBjoern A. Zeeb path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 961e2340276SBjoern A. Zeeb 962e2340276SBjoern A. Zeeb if (!notready) 963e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 964e2340276SBjoern A. Zeeb 965e2340276SBjoern A. Zeeb if (kfail) { 966e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 967e2340276SBjoern A. Zeeb MASKDWORD, 0x40000002); 968e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 969e2340276SBjoern A. Zeeb } else { 970e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 971e2340276SBjoern A. Zeeb } 972e2340276SBjoern A. Zeeb 973e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 974e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, 975e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_rxcfir[path]); 976e2340276SBjoern A. Zeeb 977e2340276SBjoern A. Zeeb return kfail; 978e2340276SBjoern A. Zeeb } 979e2340276SBjoern A. Zeeb 980e2340276SBjoern A. Zeeb static bool _iqk_2g_nbrxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 981e2340276SBjoern A. Zeeb u8 path) 982e2340276SBjoern A. Zeeb { 983e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 984e2340276SBjoern A. Zeeb bool kfail = false; 985e2340276SBjoern A. Zeeb bool notready; 986e2340276SBjoern A. Zeeb u8 gp = 0x3; 987e2340276SBjoern A. Zeeb u32 rf_0; 988e2340276SBjoern A. Zeeb 989e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 990e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, gp = %x\n", path, gp); 991e2340276SBjoern A. Zeeb 992e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RGM, g_idxrxgain[gp]); 993e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2, g_idxattc2[gp]); 994e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 995e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x0); 996e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP_V1, gp); 997e2340276SBjoern A. Zeeb 998e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RFREG_MASK, 0x80013); 999e2340276SBjoern A. Zeeb fsleep(10); 1000e2340276SBjoern A. Zeeb rf_0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 1001e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, rf_0); 1002e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RXA, B_IQK_RXAGC, g_idxrxagc[gp]); 1003e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); 1004e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXAGC); 1005e2340276SBjoern A. Zeeb 1006e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1007e2340276SBjoern A. Zeeb "[IQK]S%x, RXAGC 0x8008 = 0x%x, rxbb = %x\n", 1008e2340276SBjoern A. Zeeb path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD), 1009e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, 0x003e0)); 1010e2340276SBjoern A. Zeeb 1011e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 1012e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 1013e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK); 1014e2340276SBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 1015e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD) | 0x2; 1016e2340276SBjoern A. Zeeb 1017e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1018e2340276SBjoern A. Zeeb "[IQK]S%x, NBRXK 0x8008 = 0x%x\n", path, 1019e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 1020e2340276SBjoern A. Zeeb 1021e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, WBRXK 0x8008 = 0x%x\n", 1022e2340276SBjoern A. Zeeb path, rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD)); 1023e2340276SBjoern A. Zeeb 1024e2340276SBjoern A. Zeeb if (!notready) 1025e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 1026e2340276SBjoern A. Zeeb 1027e2340276SBjoern A. Zeeb if (kfail) { 1028e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 1029e2340276SBjoern A. Zeeb MASKDWORD, 0x40000002); 1030e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1031e2340276SBjoern A. Zeeb } else { 1032e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1033e2340276SBjoern A. Zeeb } 1034e2340276SBjoern A. Zeeb 1035e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1036e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x3c = 0x%x\n", path, kfail, 1037e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_rxcfir[path]); 1038e2340276SBjoern A. Zeeb return kfail; 1039e2340276SBjoern A. Zeeb } 1040e2340276SBjoern A. Zeeb 1041e2340276SBjoern A. Zeeb static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) 1042e2340276SBjoern A. Zeeb { 1043e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1044e2340276SBjoern A. Zeeb 1045e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_CKT, 0x1); 1046e2340276SBjoern A. Zeeb 1047e2340276SBjoern A. Zeeb if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) 1048e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_80_defs_tbl); 1049e2340276SBjoern A. Zeeb else 1050e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_rxclk_others_defs_tbl); 1051e2340276SBjoern A. Zeeb } 1052e2340276SBjoern A. Zeeb 1053e2340276SBjoern A. Zeeb static bool _txk_5g_group_sel(struct rtw89_dev *rtwdev, 1054e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 1055e2340276SBjoern A. Zeeb { 1056e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1057e2340276SBjoern A. Zeeb bool kfail = false; 1058e2340276SBjoern A. Zeeb bool notready; 1059e2340276SBjoern A. Zeeb u8 gp; 1060e2340276SBjoern A. Zeeb 1061e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1062e2340276SBjoern A. Zeeb 1063e2340276SBjoern A. Zeeb for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { 1064e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); 1065e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); 1066e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); 1067e2340276SBjoern A. Zeeb 1068e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 1069e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); 1070e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); 1071e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); 1072e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1073e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); 1074e2340276SBjoern A. Zeeb 1075e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); 1076e2340276SBjoern A. Zeeb iqk_info->nb_txcfir[path] = 1077e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; 1078e2340276SBjoern A. Zeeb 1079e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), 1080e2340276SBjoern A. Zeeb MASKDWORD, a_itqt[gp]); 1081e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); 1082e2340276SBjoern A. Zeeb } 1083e2340276SBjoern A. Zeeb 1084e2340276SBjoern A. Zeeb if (!notready) 1085e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 1086e2340276SBjoern A. Zeeb 1087e2340276SBjoern A. Zeeb if (kfail) { 1088e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1089e2340276SBjoern A. Zeeb MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); 1090e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = false; 1091e2340276SBjoern A. Zeeb } else { 1092e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1093e2340276SBjoern A. Zeeb MASKDWORD, 0x40000000); 1094e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = true; 1095e2340276SBjoern A. Zeeb } 1096e2340276SBjoern A. Zeeb 1097e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1098e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, 1099e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_txcfir[path]); 1100e2340276SBjoern A. Zeeb return kfail; 1101e2340276SBjoern A. Zeeb } 1102e2340276SBjoern A. Zeeb 1103e2340276SBjoern A. Zeeb static bool _txk_2g_group_sel(struct rtw89_dev *rtwdev, 1104e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 1105e2340276SBjoern A. Zeeb { 1106e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1107e2340276SBjoern A. Zeeb bool kfail = false; 1108e2340276SBjoern A. Zeeb bool notready; 1109e2340276SBjoern A. Zeeb u8 gp; 1110e2340276SBjoern A. Zeeb 1111e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1112e2340276SBjoern A. Zeeb 1113e2340276SBjoern A. Zeeb for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { 1114e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); 1115e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); 1116e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); 1117e2340276SBjoern A. Zeeb 1118e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); 1119e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 1120e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); 1121e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); 1122e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); 1123e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1124e2340276SBjoern A. Zeeb 1125e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); 1126e2340276SBjoern A. Zeeb iqk_info->nb_txcfir[path] = 1127e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; 1128e2340276SBjoern A. Zeeb 1129e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), 1130e2340276SBjoern A. Zeeb MASKDWORD, g_itqt[gp]); 1131e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK); 1132e2340276SBjoern A. Zeeb } 1133e2340276SBjoern A. Zeeb 1134e2340276SBjoern A. Zeeb if (!notready) 1135e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 1136e2340276SBjoern A. Zeeb 1137e2340276SBjoern A. Zeeb if (kfail) { 1138e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1139e2340276SBjoern A. Zeeb MASKDWORD, iqk_info->nb_txcfir[path] | 0x2); 1140e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = false; 1141e2340276SBjoern A. Zeeb } else { 1142e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1143e2340276SBjoern A. Zeeb MASKDWORD, 0x40000000); 1144e2340276SBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = true; 1145e2340276SBjoern A. Zeeb } 1146e2340276SBjoern A. Zeeb 1147e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1148e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, 1149e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_txcfir[path]); 1150e2340276SBjoern A. Zeeb return kfail; 1151e2340276SBjoern A. Zeeb } 1152e2340276SBjoern A. Zeeb 1153e2340276SBjoern A. Zeeb static bool _iqk_5g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1154e2340276SBjoern A. Zeeb u8 path) 1155e2340276SBjoern A. Zeeb { 1156e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1157e2340276SBjoern A. Zeeb bool kfail = false; 1158e2340276SBjoern A. Zeeb bool notready; 1159e2340276SBjoern A. Zeeb u8 gp; 1160e2340276SBjoern A. Zeeb 1161e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1162e2340276SBjoern A. Zeeb 1163e2340276SBjoern A. Zeeb for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { 1164e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, a_power_range[gp]); 1165e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, a_track_range[gp]); 1166e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, a_gain_bb[gp]); 1167e2340276SBjoern A. Zeeb 1168e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 1169e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); 1170e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); 1171e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); 1172e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1173e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, a_itqt[gp]); 1174e2340276SBjoern A. Zeeb 1175e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); 1176e2340276SBjoern A. Zeeb iqk_info->nb_txcfir[path] = 1177e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXIQC, MASKDWORD) | 0x2; 1178e2340276SBjoern A. Zeeb } 1179e2340276SBjoern A. Zeeb 1180e2340276SBjoern A. Zeeb if (!notready) 1181e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 1182e2340276SBjoern A. Zeeb 1183e2340276SBjoern A. Zeeb if (kfail) { 1184e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1185e2340276SBjoern A. Zeeb MASKDWORD, 0x40000002); 1186e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1187e2340276SBjoern A. Zeeb } else { 1188e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1189e2340276SBjoern A. Zeeb } 1190e2340276SBjoern A. Zeeb 1191e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1192e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, 1193e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_txcfir[path]); 1194e2340276SBjoern A. Zeeb return kfail; 1195e2340276SBjoern A. Zeeb } 1196e2340276SBjoern A. Zeeb 1197e2340276SBjoern A. Zeeb static bool _iqk_2g_nbtxk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1198e2340276SBjoern A. Zeeb u8 path) 1199e2340276SBjoern A. Zeeb { 1200e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1201e2340276SBjoern A. Zeeb bool kfail = false; 1202e2340276SBjoern A. Zeeb bool notready; 1203e2340276SBjoern A. Zeeb u8 gp; 1204e2340276SBjoern A. Zeeb 1205e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1206e2340276SBjoern A. Zeeb 1207e2340276SBjoern A. Zeeb for (gp = 0x0; gp < RTW8851B_TXK_GROUP_NR; gp++) { 1208e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, g_power_range[gp]); 1209e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, g_track_range[gp]); 1210e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, g_gain_bb[gp]); 1211e2340276SBjoern A. Zeeb 1212e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, MASKDWORD, g_itqt[gp]); 1213e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_SEL, 0x1); 1214e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, 0x1); 1215e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G2, 0x0); 1216e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_GP, gp); 1217e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1218e2340276SBjoern A. Zeeb 1219e2340276SBjoern A. Zeeb notready = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK); 1220e2340276SBjoern A. Zeeb iqk_info->nb_txcfir[path] = 1221e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), 1222e2340276SBjoern A. Zeeb MASKDWORD) | 0x2; 1223e2340276SBjoern A. Zeeb } 1224e2340276SBjoern A. Zeeb 1225e2340276SBjoern A. Zeeb if (!notready) 1226e2340276SBjoern A. Zeeb kfail = !!rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, B_NCTL_RPT_FLG); 1227e2340276SBjoern A. Zeeb 1228e2340276SBjoern A. Zeeb if (kfail) { 1229e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), 1230e2340276SBjoern A. Zeeb MASKDWORD, 0x40000002); 1231e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1232e2340276SBjoern A. Zeeb } else { 1233e2340276SBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = false; 1234e2340276SBjoern A. Zeeb } 1235e2340276SBjoern A. Zeeb 1236e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1237e2340276SBjoern A. Zeeb "[IQK]S%x, kfail = 0x%x, 0x8%x38 = 0x%x\n", path, kfail, 1238e2340276SBjoern A. Zeeb 1 << path, iqk_info->nb_txcfir[path]); 1239e2340276SBjoern A. Zeeb return kfail; 1240e2340276SBjoern A. Zeeb } 1241e2340276SBjoern A. Zeeb 1242e2340276SBjoern A. Zeeb static bool _iqk_2g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1243e2340276SBjoern A. Zeeb u8 path) 1244e2340276SBjoern A. Zeeb { 1245e2340276SBjoern A. Zeeb static const u32 g_txbb[RTW8851B_LOK_GRAM] = { 1246e2340276SBjoern A. Zeeb 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; 1247e2340276SBjoern A. Zeeb static const u32 g_itqt[RTW8851B_LOK_GRAM] = { 1248e2340276SBjoern A. Zeeb 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b}; 1249e2340276SBjoern A. Zeeb static const u32 g_wa[RTW8851B_LOK_GRAM] = { 1250e2340276SBjoern A. Zeeb 0x00, 0x04, 0x08, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; 1251e2340276SBjoern A. Zeeb bool fail = false; 1252e2340276SBjoern A. Zeeb u8 i; 1253e2340276SBjoern A. Zeeb 1254e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1255e2340276SBjoern A. Zeeb 1256e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); 1257e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); 1258e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x6); 1259e2340276SBjoern A. Zeeb 1260e2340276SBjoern A. Zeeb for (i = 0; i < RTW8851B_LOK_GRAM; i++) { 1261e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, g_txbb[i]); 1262e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, g_wa[i]); 1263e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 1264e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); 1265e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); 1266e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 1267e2340276SBjoern A. Zeeb 0x00000109 | (1 << (4 + path))); 1268e2340276SBjoern A. Zeeb fail |= _iqk_check_cal(rtwdev, path); 1269e2340276SBjoern A. Zeeb 1270e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1271e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, g_itqt[i]); 1272e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 1273e2340276SBjoern A. Zeeb 0x00000309 | (1 << (4 + path))); 1274e2340276SBjoern A. Zeeb fail |= _iqk_check_cal(rtwdev, path); 1275e2340276SBjoern A. Zeeb 1276e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1277e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); 1278e2340276SBjoern A. Zeeb 1279e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1280e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, 1281e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), 1282e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); 1283e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1284e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, 1285e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), 1286e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); 1287e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1288e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x58 = %x\n", i, 1289e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); 1290e2340276SBjoern A. Zeeb } 1291e2340276SBjoern A. Zeeb 1292e2340276SBjoern A. Zeeb return fail; 1293e2340276SBjoern A. Zeeb } 1294e2340276SBjoern A. Zeeb 1295e2340276SBjoern A. Zeeb static bool _iqk_5g_lok(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1296e2340276SBjoern A. Zeeb u8 path) 1297e2340276SBjoern A. Zeeb { 1298e2340276SBjoern A. Zeeb static const u32 a_txbb[RTW8851B_LOK_GRAM] = { 1299e2340276SBjoern A. Zeeb 0x02, 0x06, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x17}; 1300e2340276SBjoern A. Zeeb static const u32 a_itqt[RTW8851B_LOK_GRAM] = { 1301e2340276SBjoern A. Zeeb 0x09, 0x09, 0x09, 0x12, 0x12, 0x12, 0x1b, 0x1b, 0x1b, 0x1b}; 1302e2340276SBjoern A. Zeeb static const u32 a_wa[RTW8851B_LOK_GRAM] = { 1303e2340276SBjoern A. Zeeb 0x80, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97}; 1304e2340276SBjoern A. Zeeb bool fail = false; 1305e2340276SBjoern A. Zeeb u8 i; 1306e2340276SBjoern A. Zeeb 1307e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1308e2340276SBjoern A. Zeeb 1309e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); 1310e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR0, 0x0); 1311e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_GR1, 0x7); 1312e2340276SBjoern A. Zeeb 1313e2340276SBjoern A. Zeeb for (i = 0; i < RTW8851B_LOK_GRAM; i++) { 1314e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXIG, RR_TXIG_TG, a_txbb[i]); 1315e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RR_LUTWA_M1, a_wa[i]); 1316e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x1); 1317e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); 1318e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); 1319e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 1320e2340276SBjoern A. Zeeb 0x00000109 | (1 << (4 + path))); 1321e2340276SBjoern A. Zeeb fail |= _iqk_check_cal(rtwdev, path); 1322e2340276SBjoern A. Zeeb 1323e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1324e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP, B_KIP_IQP_IQSW, a_itqt[i]); 1325e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x021); 1326e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 1327e2340276SBjoern A. Zeeb 0x00000309 | (1 << (4 + path))); 1328e2340276SBjoern A. Zeeb fail |= _iqk_check_cal(rtwdev, path); 1329e2340276SBjoern A. Zeeb 1330e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1331e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK, B_IQK_RFC_ON, 0x0); 1332e2340276SBjoern A. Zeeb 1333e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1334e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x8[19:15] = 0x%x,0x8[09:05] = 0x%x\n", i, 1335e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0xf8000), 1336e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_DTXLOK, 0x003e0)); 1337e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1338e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x9[19:16] = 0x%x,0x9[09:06] = 0x%x\n", i, 1339e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0xf0000), 1340e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV2, 0x003c0)); 1341e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1342e2340276SBjoern A. Zeeb "[IQK]S0, i = %x, 0x58 = %x\n", i, 1343e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_TXMO, RFREG_MASK)); 1344e2340276SBjoern A. Zeeb } 1345e2340276SBjoern A. Zeeb 1346e2340276SBjoern A. Zeeb return fail; 1347e2340276SBjoern A. Zeeb } 1348e2340276SBjoern A. Zeeb 1349e2340276SBjoern A. Zeeb static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) 1350e2340276SBjoern A. Zeeb { 1351e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1352e2340276SBjoern A. Zeeb 1353e2340276SBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 1354e2340276SBjoern A. Zeeb case RTW89_BAND_2G: 1355e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_2G\n"); 1356e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_2ghz_defs_tbl); 1357e2340276SBjoern A. Zeeb break; 1358e2340276SBjoern A. Zeeb case RTW89_BAND_5G: 1359e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]RTW89_BAND_5G\n"); 1360e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_txk_5ghz_defs_tbl); 1361e2340276SBjoern A. Zeeb break; 1362e2340276SBjoern A. Zeeb default: 1363e2340276SBjoern A. Zeeb break; 1364e2340276SBjoern A. Zeeb } 1365e2340276SBjoern A. Zeeb } 1366e2340276SBjoern A. Zeeb 1367e2340276SBjoern A. Zeeb #define IQK_LOK_RETRY 1 1368e2340276SBjoern A. Zeeb 1369e2340276SBjoern A. Zeeb static void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1370e2340276SBjoern A. Zeeb u8 path) 1371e2340276SBjoern A. Zeeb { 1372e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1373e2340276SBjoern A. Zeeb bool lok_is_fail; 1374e2340276SBjoern A. Zeeb u8 i; 1375e2340276SBjoern A. Zeeb 1376e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1377e2340276SBjoern A. Zeeb 1378e2340276SBjoern A. Zeeb for (i = 0; i < IQK_LOK_RETRY; i++) { 1379e2340276SBjoern A. Zeeb _iqk_txk_setting(rtwdev, path); 1380e2340276SBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 1381e2340276SBjoern A. Zeeb lok_is_fail = _iqk_2g_lok(rtwdev, phy_idx, path); 1382e2340276SBjoern A. Zeeb else 1383e2340276SBjoern A. Zeeb lok_is_fail = _iqk_5g_lok(rtwdev, phy_idx, path); 1384e2340276SBjoern A. Zeeb 1385e2340276SBjoern A. Zeeb if (!lok_is_fail) 1386e2340276SBjoern A. Zeeb break; 1387e2340276SBjoern A. Zeeb } 1388e2340276SBjoern A. Zeeb 1389e2340276SBjoern A. Zeeb if (iqk_info->is_nbiqk) { 1390e2340276SBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 1391e2340276SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = 1392e2340276SBjoern A. Zeeb _iqk_2g_nbtxk(rtwdev, phy_idx, path); 1393e2340276SBjoern A. Zeeb else 1394e2340276SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = 1395e2340276SBjoern A. Zeeb _iqk_5g_nbtxk(rtwdev, phy_idx, path); 1396e2340276SBjoern A. Zeeb } else { 1397e2340276SBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 1398e2340276SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = 1399e2340276SBjoern A. Zeeb _txk_2g_group_sel(rtwdev, phy_idx, path); 1400e2340276SBjoern A. Zeeb else 1401e2340276SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = 1402e2340276SBjoern A. Zeeb _txk_5g_group_sel(rtwdev, phy_idx, path); 1403e2340276SBjoern A. Zeeb } 1404e2340276SBjoern A. Zeeb 1405e2340276SBjoern A. Zeeb _iqk_rxclk_setting(rtwdev, path); 1406e2340276SBjoern A. Zeeb _iqk_rxk_setting(rtwdev, path); 1407e2340276SBjoern A. Zeeb _adc_fifo_rst(rtwdev, phy_idx, path); 1408e2340276SBjoern A. Zeeb 1409e2340276SBjoern A. Zeeb if (iqk_info->is_nbiqk) { 1410e2340276SBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 1411e2340276SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = 1412e2340276SBjoern A. Zeeb _iqk_2g_nbrxk(rtwdev, phy_idx, path); 1413e2340276SBjoern A. Zeeb else 1414e2340276SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = 1415e2340276SBjoern A. Zeeb _iqk_5g_nbrxk(rtwdev, phy_idx, path); 1416e2340276SBjoern A. Zeeb } else { 1417e2340276SBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 1418e2340276SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = 1419e2340276SBjoern A. Zeeb _rxk_2g_group_sel(rtwdev, phy_idx, path); 1420e2340276SBjoern A. Zeeb else 1421e2340276SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = 1422e2340276SBjoern A. Zeeb _rxk_5g_group_sel(rtwdev, phy_idx, path); 1423e2340276SBjoern A. Zeeb } 1424e2340276SBjoern A. Zeeb } 1425e2340276SBjoern A. Zeeb 1426e2340276SBjoern A. Zeeb static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, 1427e2340276SBjoern A. Zeeb u32 backup_bb_reg_val[]) 1428e2340276SBjoern A. Zeeb { 1429e2340276SBjoern A. Zeeb u32 i; 1430e2340276SBjoern A. Zeeb 1431e2340276SBjoern A. Zeeb for (i = 0; i < BACKUP_BB_REGS_NR; i++) { 1432e2340276SBjoern A. Zeeb backup_bb_reg_val[i] = 1433e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, rtw8851b_backup_bb_regs[i], 1434e2340276SBjoern A. Zeeb MASKDWORD); 1435e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1436e2340276SBjoern A. Zeeb "[RFK]backup bb reg : %x, value =%x\n", 1437e2340276SBjoern A. Zeeb rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); 1438e2340276SBjoern A. Zeeb } 1439e2340276SBjoern A. Zeeb } 1440e2340276SBjoern A. Zeeb 1441e2340276SBjoern A. Zeeb static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, 1442e2340276SBjoern A. Zeeb u32 backup_rf_reg_val[], u8 rf_path) 1443e2340276SBjoern A. Zeeb { 1444e2340276SBjoern A. Zeeb u32 i; 1445e2340276SBjoern A. Zeeb 1446e2340276SBjoern A. Zeeb for (i = 0; i < BACKUP_RF_REGS_NR; i++) { 1447e2340276SBjoern A. Zeeb backup_rf_reg_val[i] = 1448e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, rf_path, 1449e2340276SBjoern A. Zeeb rtw8851b_backup_rf_regs[i], RFREG_MASK); 1450e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1451e2340276SBjoern A. Zeeb "[RFK]backup rf S%d reg : %x, value =%x\n", rf_path, 1452e2340276SBjoern A. Zeeb rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); 1453e2340276SBjoern A. Zeeb } 1454e2340276SBjoern A. Zeeb } 1455e2340276SBjoern A. Zeeb 1456e2340276SBjoern A. Zeeb static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, 1457e2340276SBjoern A. Zeeb const u32 backup_bb_reg_val[]) 1458e2340276SBjoern A. Zeeb { 1459e2340276SBjoern A. Zeeb u32 i; 1460e2340276SBjoern A. Zeeb 1461e2340276SBjoern A. Zeeb for (i = 0; i < BACKUP_BB_REGS_NR; i++) { 1462e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, rtw8851b_backup_bb_regs[i], 1463e2340276SBjoern A. Zeeb MASKDWORD, backup_bb_reg_val[i]); 1464e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1465e2340276SBjoern A. Zeeb "[RFK]restore bb reg : %x, value =%x\n", 1466e2340276SBjoern A. Zeeb rtw8851b_backup_bb_regs[i], backup_bb_reg_val[i]); 1467e2340276SBjoern A. Zeeb } 1468e2340276SBjoern A. Zeeb } 1469e2340276SBjoern A. Zeeb 1470e2340276SBjoern A. Zeeb static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, 1471e2340276SBjoern A. Zeeb const u32 backup_rf_reg_val[], u8 rf_path) 1472e2340276SBjoern A. Zeeb { 1473e2340276SBjoern A. Zeeb u32 i; 1474e2340276SBjoern A. Zeeb 1475e2340276SBjoern A. Zeeb for (i = 0; i < BACKUP_RF_REGS_NR; i++) { 1476e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, rf_path, rtw8851b_backup_rf_regs[i], 1477e2340276SBjoern A. Zeeb RFREG_MASK, backup_rf_reg_val[i]); 1478e2340276SBjoern A. Zeeb 1479e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1480e2340276SBjoern A. Zeeb "[RFK]restore rf S%d reg: %x, value =%x\n", rf_path, 1481e2340276SBjoern A. Zeeb rtw8851b_backup_rf_regs[i], backup_rf_reg_val[i]); 1482e2340276SBjoern A. Zeeb } 1483e2340276SBjoern A. Zeeb } 1484e2340276SBjoern A. Zeeb 1485e2340276SBjoern A. Zeeb static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1486*df279a26SBjoern A. Zeeb u8 path, enum rtw89_chanctx_idx chanctx_idx) 1487e2340276SBjoern A. Zeeb { 1488*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 1489e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1490e2340276SBjoern A. Zeeb u8 idx = 0; 1491e2340276SBjoern A. Zeeb 1492e2340276SBjoern A. Zeeb iqk_info->iqk_band[path] = chan->band_type; 1493e2340276SBjoern A. Zeeb iqk_info->iqk_bw[path] = chan->band_width; 1494e2340276SBjoern A. Zeeb iqk_info->iqk_ch[path] = chan->channel; 1495e2340276SBjoern A. Zeeb iqk_info->iqk_table_idx[path] = idx; 1496e2340276SBjoern A. Zeeb 1497e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", 1498e2340276SBjoern A. Zeeb path, phy, rtwdev->dbcc_en ? "on" : "off", 1499e2340276SBjoern A. Zeeb iqk_info->iqk_band[path] == 0 ? "2G" : 1500e2340276SBjoern A. Zeeb iqk_info->iqk_band[path] == 1 ? "5G" : "6G", 1501e2340276SBjoern A. Zeeb iqk_info->iqk_ch[path], 1502e2340276SBjoern A. Zeeb iqk_info->iqk_bw[path] == 0 ? "20M" : 1503e2340276SBjoern A. Zeeb iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); 1504e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]times = 0x%x, ch =%x\n", 1505e2340276SBjoern A. Zeeb iqk_info->iqk_times, idx); 1506e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, iqk_info->syn1to2= 0x%x\n", 1507e2340276SBjoern A. Zeeb path, iqk_info->syn1to2); 1508e2340276SBjoern A. Zeeb } 1509e2340276SBjoern A. Zeeb 1510e2340276SBjoern A. Zeeb static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1511e2340276SBjoern A. Zeeb u8 path) 1512e2340276SBjoern A. Zeeb { 1513e2340276SBjoern A. Zeeb _iqk_by_path(rtwdev, phy_idx, path); 1514e2340276SBjoern A. Zeeb } 1515e2340276SBjoern A. Zeeb 1516e2340276SBjoern A. Zeeb static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) 1517e2340276SBjoern A. Zeeb { 1518e2340276SBjoern A. Zeeb bool fail; 1519e2340276SBjoern A. Zeeb 1520e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1521e2340276SBjoern A. Zeeb 1522e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, 0x00001219); 1523e2340276SBjoern A. Zeeb fsleep(10); 1524e2340276SBjoern A. Zeeb fail = _iqk_check_cal(rtwdev, path); 1525e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] restore fail=%d\n", fail); 1526e2340276SBjoern A. Zeeb 1527e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RR_LUTWE_LOK, 0x0); 1528e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTDBG, RR_LUTDBG_TIA, 0x0); 1529e2340276SBjoern A. Zeeb 1530e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP, 0x00); 1531e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); 1532e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); 1533e2340276SBjoern A. Zeeb } 1534e2340276SBjoern A. Zeeb 1535e2340276SBjoern A. Zeeb static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, 1536e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 1537e2340276SBjoern A. Zeeb { 1538e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_afebb_restore_defs_tbl); 1539e2340276SBjoern A. Zeeb } 1540e2340276SBjoern A. Zeeb 1541e2340276SBjoern A. Zeeb static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) 1542e2340276SBjoern A. Zeeb { 1543e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1544e2340276SBjoern A. Zeeb 1545e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 1546e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); 1547e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); 1548e2340276SBjoern A. Zeeb } 1549e2340276SBjoern A. Zeeb 1550e2340276SBjoern A. Zeeb static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, 1551e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 1552e2340276SBjoern A. Zeeb { 1553e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1554e2340276SBjoern A. Zeeb 1555e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_macbb_defs_tbl); 1556e2340276SBjoern A. Zeeb } 1557e2340276SBjoern A. Zeeb 1558e2340276SBjoern A. Zeeb static void _iqk_init(struct rtw89_dev *rtwdev) 1559e2340276SBjoern A. Zeeb { 1560e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1561e2340276SBjoern A. Zeeb u8 idx, path; 1562e2340276SBjoern A. Zeeb 1563e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, MASKDWORD, 0x0); 1564e2340276SBjoern A. Zeeb 1565e2340276SBjoern A. Zeeb if (iqk_info->is_iqk_init) 1566e2340276SBjoern A. Zeeb return; 1567e2340276SBjoern A. Zeeb 1568e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 1569e2340276SBjoern A. Zeeb 1570e2340276SBjoern A. Zeeb iqk_info->is_iqk_init = true; 1571e2340276SBjoern A. Zeeb iqk_info->is_nbiqk = false; 1572e2340276SBjoern A. Zeeb iqk_info->iqk_fft_en = false; 1573e2340276SBjoern A. Zeeb iqk_info->iqk_sram_en = false; 1574e2340276SBjoern A. Zeeb iqk_info->iqk_cfir_en = false; 1575e2340276SBjoern A. Zeeb iqk_info->iqk_xym_en = false; 1576e2340276SBjoern A. Zeeb iqk_info->iqk_times = 0x0; 1577e2340276SBjoern A. Zeeb 1578e2340276SBjoern A. Zeeb for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { 1579e2340276SBjoern A. Zeeb iqk_info->iqk_channel[idx] = 0x0; 1580e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 1581e2340276SBjoern A. Zeeb iqk_info->lok_cor_fail[idx][path] = false; 1582e2340276SBjoern A. Zeeb iqk_info->lok_fin_fail[idx][path] = false; 1583e2340276SBjoern A. Zeeb iqk_info->iqk_tx_fail[idx][path] = false; 1584e2340276SBjoern A. Zeeb iqk_info->iqk_rx_fail[idx][path] = false; 1585e2340276SBjoern A. Zeeb iqk_info->iqk_table_idx[path] = 0x0; 1586e2340276SBjoern A. Zeeb } 1587e2340276SBjoern A. Zeeb } 1588e2340276SBjoern A. Zeeb } 1589e2340276SBjoern A. Zeeb 1590e2340276SBjoern A. Zeeb static void _doiqk(struct rtw89_dev *rtwdev, bool force, 1591*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 1592*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 1593e2340276SBjoern A. Zeeb { 1594e2340276SBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1595*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); 1596e2340276SBjoern A. Zeeb u32 backup_rf_val[RTW8851B_IQK_SS][BACKUP_RF_REGS_NR]; 1597e2340276SBjoern A. Zeeb u32 backup_bb_val[BACKUP_BB_REGS_NR]; 1598e2340276SBjoern A. Zeeb 1599e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, 1600e2340276SBjoern A. Zeeb BTC_WRFK_ONESHOT_START); 1601e2340276SBjoern A. Zeeb 1602e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1603e2340276SBjoern A. Zeeb "[IQK]==========IQK start!!!!!==========\n"); 1604e2340276SBjoern A. Zeeb iqk_info->iqk_times++; 1605e2340276SBjoern A. Zeeb iqk_info->version = RTW8851B_IQK_VER; 1606e2340276SBjoern A. Zeeb 1607e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); 1608*df279a26SBjoern A. Zeeb _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); 1609e2340276SBjoern A. Zeeb 1610e2340276SBjoern A. Zeeb _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); 1611e2340276SBjoern A. Zeeb _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); 1612e2340276SBjoern A. Zeeb _iqk_macbb_setting(rtwdev, phy_idx, path); 1613e2340276SBjoern A. Zeeb _iqk_preset(rtwdev, path); 1614e2340276SBjoern A. Zeeb _iqk_start_iqk(rtwdev, phy_idx, path); 1615e2340276SBjoern A. Zeeb _iqk_restore(rtwdev, path); 1616e2340276SBjoern A. Zeeb _iqk_afebb_restore(rtwdev, phy_idx, path); 1617e2340276SBjoern A. Zeeb _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); 1618e2340276SBjoern A. Zeeb _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); 1619e2340276SBjoern A. Zeeb 1620e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, 1621e2340276SBjoern A. Zeeb BTC_WRFK_ONESHOT_STOP); 1622e2340276SBjoern A. Zeeb } 1623e2340276SBjoern A. Zeeb 1624*df279a26SBjoern A. Zeeb static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1625*df279a26SBjoern A. Zeeb bool force, enum rtw89_chanctx_idx chanctx_idx) 1626e2340276SBjoern A. Zeeb { 1627*df279a26SBjoern A. Zeeb _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); 1628e2340276SBjoern A. Zeeb } 1629e2340276SBjoern A. Zeeb 1630e2340276SBjoern A. Zeeb static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, const u32 *reg, 1631e2340276SBjoern A. Zeeb u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) 1632e2340276SBjoern A. Zeeb { 1633e2340276SBjoern A. Zeeb u8 i; 1634e2340276SBjoern A. Zeeb 1635e2340276SBjoern A. Zeeb for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { 1636e2340276SBjoern A. Zeeb reg_bkup[path][i] = 1637e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD); 1638e2340276SBjoern A. Zeeb 1639e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", 1640e2340276SBjoern A. Zeeb reg[i] + (path << 8), reg_bkup[path][i]); 1641e2340276SBjoern A. Zeeb } 1642e2340276SBjoern A. Zeeb } 1643e2340276SBjoern A. Zeeb 1644e2340276SBjoern A. Zeeb static void _dpk_bkup_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, 1645e2340276SBjoern A. Zeeb u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) 1646e2340276SBjoern A. Zeeb { 1647e2340276SBjoern A. Zeeb u8 i; 1648e2340276SBjoern A. Zeeb 1649e2340276SBjoern A. Zeeb for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { 1650e2340276SBjoern A. Zeeb rf_bkup[path][i] = rtw89_read_rf(rtwdev, path, rf_reg[i], RFREG_MASK); 1651e2340276SBjoern A. Zeeb 1652e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup RF S%d 0x%x = %x\n", 1653e2340276SBjoern A. Zeeb path, rf_reg[i], rf_bkup[path][i]); 1654e2340276SBjoern A. Zeeb } 1655e2340276SBjoern A. Zeeb } 1656e2340276SBjoern A. Zeeb 1657e2340276SBjoern A. Zeeb static void _dpk_reload_kip(struct rtw89_dev *rtwdev, const u32 *reg, 1658e2340276SBjoern A. Zeeb u32 reg_bkup[][DPK_KIP_REG_NUM_8851B], u8 path) 1659e2340276SBjoern A. Zeeb { 1660e2340276SBjoern A. Zeeb u8 i; 1661e2340276SBjoern A. Zeeb 1662e2340276SBjoern A. Zeeb for (i = 0; i < DPK_KIP_REG_NUM_8851B; i++) { 1663e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), MASKDWORD, 1664e2340276SBjoern A. Zeeb reg_bkup[path][i]); 1665e2340276SBjoern A. Zeeb 1666e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1667e2340276SBjoern A. Zeeb "[DPK] Reload 0x%x = %x\n", 1668e2340276SBjoern A. Zeeb reg[i] + (path << 8), reg_bkup[path][i]); 1669e2340276SBjoern A. Zeeb } 1670e2340276SBjoern A. Zeeb } 1671e2340276SBjoern A. Zeeb 1672e2340276SBjoern A. Zeeb static void _dpk_reload_rf(struct rtw89_dev *rtwdev, const u32 *rf_reg, 1673e2340276SBjoern A. Zeeb u32 rf_bkup[][DPK_RF_REG_NUM_8851B], u8 path) 1674e2340276SBjoern A. Zeeb { 1675e2340276SBjoern A. Zeeb u8 i; 1676e2340276SBjoern A. Zeeb 1677e2340276SBjoern A. Zeeb for (i = 0; i < DPK_RF_REG_NUM_8851B; i++) { 1678e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, rf_reg[i], RFREG_MASK, rf_bkup[path][i]); 1679e2340276SBjoern A. Zeeb 1680e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1681e2340276SBjoern A. Zeeb "[DPK] Reload RF S%d 0x%x = %x\n", path, 1682e2340276SBjoern A. Zeeb rf_reg[i], rf_bkup[path][i]); 1683e2340276SBjoern A. Zeeb } 1684e2340276SBjoern A. Zeeb } 1685e2340276SBjoern A. Zeeb 1686e2340276SBjoern A. Zeeb static void _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1687e2340276SBjoern A. Zeeb enum rtw89_rf_path path, enum dpk_id id) 1688e2340276SBjoern A. Zeeb { 1689e2340276SBjoern A. Zeeb u16 dpk_cmd; 1690e2340276SBjoern A. Zeeb u32 val; 1691e2340276SBjoern A. Zeeb int ret; 1692e2340276SBjoern A. Zeeb 1693e2340276SBjoern A. Zeeb dpk_cmd = ((id << 8) | (0x19 + path * 0x12)); 1694e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); 1695e2340276SBjoern A. Zeeb 1696e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 1697e2340276SBjoern A. Zeeb 10, 20000, false, 1698e2340276SBjoern A. Zeeb rtwdev, 0xbff8, MASKBYTE0); 1699e2340276SBjoern A. Zeeb if (ret) 1700e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 1 timeout\n"); 1701e2340276SBjoern A. Zeeb 1702e2340276SBjoern A. Zeeb udelay(1); 1703e2340276SBjoern A. Zeeb 1704e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x8000, 1705e2340276SBjoern A. Zeeb 1, 2000, false, 1706e2340276SBjoern A. Zeeb rtwdev, R_RPT_COM, MASKLWORD); 1707e2340276SBjoern A. Zeeb if (ret) 1708e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] one-shot 2 timeout\n"); 1709e2340276SBjoern A. Zeeb 1710e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N1, MASKBYTE0, 0x0); 1711e2340276SBjoern A. Zeeb 1712e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1713e2340276SBjoern A. Zeeb "[DPK] one-shot for %s = 0x%04x\n", 1714e2340276SBjoern A. Zeeb id == 0x28 ? "KIP_PRESET" : 1715e2340276SBjoern A. Zeeb id == 0x29 ? "DPK_TXAGC" : 1716e2340276SBjoern A. Zeeb id == 0x2a ? "DPK_RXAGC" : 1717e2340276SBjoern A. Zeeb id == 0x2b ? "SYNC" : 1718e2340276SBjoern A. Zeeb id == 0x2c ? "GAIN_LOSS" : 1719e2340276SBjoern A. Zeeb id == 0x2d ? "MDPK_IDL" : 1720e2340276SBjoern A. Zeeb id == 0x2f ? "DPK_GAIN_NORM" : 1721e2340276SBjoern A. Zeeb id == 0x31 ? "KIP_RESTORE" : 1722e2340276SBjoern A. Zeeb id == 0x6 ? "LBK_RXIQK" : "Unknown id", 1723e2340276SBjoern A. Zeeb dpk_cmd); 1724e2340276SBjoern A. Zeeb } 1725e2340276SBjoern A. Zeeb 1726e2340276SBjoern A. Zeeb static void _dpk_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 1727e2340276SBjoern A. Zeeb bool off) 1728e2340276SBjoern A. Zeeb { 1729e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1730e2340276SBjoern A. Zeeb u8 kidx = dpk->cur_idx[path]; 1731e2340276SBjoern A. Zeeb u8 off_reverse = off ? 0 : 1; 1732e2340276SBjoern A. Zeeb u8 val; 1733e2340276SBjoern A. Zeeb 1734e2340276SBjoern A. Zeeb val = dpk->is_dpk_enable * off_reverse * dpk->bp[path][kidx].path_ok; 1735e2340276SBjoern A. Zeeb 1736e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 1737e2340276SBjoern A. Zeeb 0xf0000000, val); 1738e2340276SBjoern A. Zeeb 1739e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, 1740e2340276SBjoern A. Zeeb kidx, val == 0 ? "disable" : "enable"); 1741e2340276SBjoern A. Zeeb } 1742e2340276SBjoern A. Zeeb 1743e2340276SBjoern A. Zeeb static void _dpk_init(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 1744e2340276SBjoern A. Zeeb { 1745e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1746e2340276SBjoern A. Zeeb 1747e2340276SBjoern A. Zeeb u8 kidx = dpk->cur_idx[path]; 1748e2340276SBjoern A. Zeeb 1749e2340276SBjoern A. Zeeb dpk->bp[path][kidx].path_ok = 0; 1750e2340276SBjoern A. Zeeb } 1751e2340276SBjoern A. Zeeb 1752e2340276SBjoern A. Zeeb static void _dpk_information(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1753*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) 1754e2340276SBjoern A. Zeeb { 1755*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 1756e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1757e2340276SBjoern A. Zeeb 1758e2340276SBjoern A. Zeeb u8 kidx = dpk->cur_idx[path]; 1759e2340276SBjoern A. Zeeb 1760e2340276SBjoern A. Zeeb dpk->bp[path][kidx].band = chan->band_type; 1761e2340276SBjoern A. Zeeb dpk->bp[path][kidx].ch = chan->band_width; 1762e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw = chan->channel; 1763e2340276SBjoern A. Zeeb 1764e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1765e2340276SBjoern A. Zeeb "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 1766e2340276SBjoern A. Zeeb path, dpk->cur_idx[path], phy, 1767e2340276SBjoern A. Zeeb rtwdev->is_tssi_mode[path] ? "on" : "off", 1768e2340276SBjoern A. Zeeb rtwdev->dbcc_en ? "on" : "off", 1769e2340276SBjoern A. Zeeb dpk->bp[path][kidx].band == 0 ? "2G" : 1770e2340276SBjoern A. Zeeb dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 1771e2340276SBjoern A. Zeeb dpk->bp[path][kidx].ch, 1772e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw == 0 ? "20M" : 1773e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw == 1 ? "40M" : 1774e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw == 2 ? "80M" : "160M"); 1775e2340276SBjoern A. Zeeb } 1776e2340276SBjoern A. Zeeb 1777e2340276SBjoern A. Zeeb static void _dpk_rxagc_onoff(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 1778e2340276SBjoern A. Zeeb bool turn_on) 1779e2340276SBjoern A. Zeeb { 1780e2340276SBjoern A. Zeeb if (path == RF_PATH_A) 1781e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_AGC_CTL, B_P0_AGC_EN, turn_on); 1782e2340276SBjoern A. Zeeb else 1783e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_AGC_CTL, B_P1_AGC_EN, turn_on); 1784e2340276SBjoern A. Zeeb 1785e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d RXAGC is %s\n", path, 1786e2340276SBjoern A. Zeeb turn_on ? "turn_on" : "turn_off"); 1787e2340276SBjoern A. Zeeb } 1788e2340276SBjoern A. Zeeb 1789e2340276SBjoern A. Zeeb static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 1790e2340276SBjoern A. Zeeb { 1791e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); 1792e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); 1793e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); 1794e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); 1795e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0xd801dffd); 1796e2340276SBjoern A. Zeeb 1797e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_iqk_bb_afe_defs_tbl); 1798e2340276SBjoern A. Zeeb 1799e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x1); 1800e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x1); 1801e2340276SBjoern A. Zeeb 1802e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE setting\n", path); 1803e2340276SBjoern A. Zeeb } 1804e2340276SBjoern A. Zeeb 1805e2340276SBjoern A. Zeeb static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 1806e2340276SBjoern A. Zeeb { 1807e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG, 0x0); 1808e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x1); 1809e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(20 + path), 0x0); 1810e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x1); 1811e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(28 + path), 0x0); 1812e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), MASKDWORD, 0x00000000); 1813e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), B_P0_TXCK_ALL, 0x00); 1814e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(16 + path), 0x0); 1815e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, BIT(24 + path), 0x0); 1816e2340276SBjoern A. Zeeb 1817e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d BB/AFE restore\n", path); 1818e2340276SBjoern A. Zeeb } 1819e2340276SBjoern A. Zeeb 1820e2340276SBjoern A. Zeeb static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 1821e2340276SBjoern A. Zeeb bool is_pause) 1822e2340276SBjoern A. Zeeb { 1823e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), 1824e2340276SBjoern A. Zeeb B_P0_TSSI_TRK_EN, is_pause); 1825e2340276SBjoern A. Zeeb 1826e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, 1827e2340276SBjoern A. Zeeb is_pause ? "pause" : "resume"); 1828e2340276SBjoern A. Zeeb } 1829e2340276SBjoern A. Zeeb 1830e2340276SBjoern A. Zeeb static void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) 1831e2340276SBjoern A. Zeeb { 1832e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1833e2340276SBjoern A. Zeeb 1834e2340276SBjoern A. Zeeb if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) { 1835e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x0); 1836e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xffe0fa00); 1837e2340276SBjoern A. Zeeb } else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) { 1838e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); 1839e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xff4009e0); 1840e2340276SBjoern A. Zeeb } else { 1841e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); 1842e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_SEL, MASKDWORD, 0xf9f007d0); 1843e2340276SBjoern A. Zeeb } 1844e2340276SBjoern A. Zeeb 1845e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG Select for %s\n", 1846e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : 1847e2340276SBjoern A. Zeeb dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); 1848e2340276SBjoern A. Zeeb } 1849e2340276SBjoern A. Zeeb 1850e2340276SBjoern A. Zeeb static void _dpk_txpwr_bb_force(struct rtw89_dev *rtwdev, 1851e2340276SBjoern A. Zeeb enum rtw89_rf_path path, bool force) 1852e2340276SBjoern A. Zeeb { 1853e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), B_TXPWRB_ON, force); 1854e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXPWRB_H + (path << 13), B_TXPWRB_RDY, force); 1855e2340276SBjoern A. Zeeb 1856e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d txpwr_bb_force %s\n", 1857e2340276SBjoern A. Zeeb path, force ? "on" : "off"); 1858e2340276SBjoern A. Zeeb } 1859e2340276SBjoern A. Zeeb 1860e2340276SBjoern A. Zeeb static void _dpk_kip_pwr_clk_onoff(struct rtw89_dev *rtwdev, bool turn_on) 1861e2340276SBjoern A. Zeeb { 1862e2340276SBjoern A. Zeeb if (turn_on) { 1863e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); 1864e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); 1865e2340276SBjoern A. Zeeb } else { 1866e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000000); 1867e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); 1868e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_WR, BIT(18), 0x1); 1869e2340276SBjoern A. Zeeb } 1870e2340276SBjoern A. Zeeb } 1871e2340276SBjoern A. Zeeb 1872e2340276SBjoern A. Zeeb static void _dpk_kip_control_rfc(struct rtw89_dev *rtwdev, 1873e2340276SBjoern A. Zeeb enum rtw89_rf_path path, bool ctrl_by_kip) 1874e2340276SBjoern A. Zeeb { 1875e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK + (path << 13), 1876e2340276SBjoern A. Zeeb B_IQK_RFC_ON, ctrl_by_kip); 1877e2340276SBjoern A. Zeeb 1878e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] RFC is controlled by %s\n", 1879e2340276SBjoern A. Zeeb ctrl_by_kip ? "KIP" : "BB"); 1880e2340276SBjoern A. Zeeb } 1881e2340276SBjoern A. Zeeb 1882e2340276SBjoern A. Zeeb static void _dpk_kip_preset(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1883e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 1884e2340276SBjoern A. Zeeb { 1885e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, 1886e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); 1887e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 1888e2340276SBjoern A. Zeeb B_DPD_SEL, 0x01); 1889e2340276SBjoern A. Zeeb 1890e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, true); 1891e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_KIP_PRESET); 1892e2340276SBjoern A. Zeeb } 1893e2340276SBjoern A. Zeeb 1894e2340276SBjoern A. Zeeb static void _dpk_kip_restore(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1895e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 1896e2340276SBjoern A. Zeeb { 1897e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_KIP_RESTORE); 1898e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 1899e2340276SBjoern A. Zeeb _dpk_txpwr_bb_force(rtwdev, path, false); 1900e2340276SBjoern A. Zeeb 1901e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); 1902e2340276SBjoern A. Zeeb } 1903e2340276SBjoern A. Zeeb 1904e2340276SBjoern A. Zeeb static void _dpk_kset_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 1905e2340276SBjoern A. Zeeb { 1906e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1907e2340276SBjoern A. Zeeb 1908e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0x10); 1909e2340276SBjoern A. Zeeb 1910e2340276SBjoern A. Zeeb dpk->cur_k_set = 1911e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), B_RPT_PER_KSET) - 1; 1912e2340276SBjoern A. Zeeb } 1913e2340276SBjoern A. Zeeb 1914e2340276SBjoern A. Zeeb static void _dpk_para_query(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) 1915e2340276SBjoern A. Zeeb { 1916e2340276SBjoern A. Zeeb static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { 1917e2340276SBjoern A. Zeeb {0x8190, 0x8194, 0x8198, 0x81a4}, 1918e2340276SBjoern A. Zeeb {0x81a8, 0x81c4, 0x81c8, 0x81e8} 1919e2340276SBjoern A. Zeeb }; 1920e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1921e2340276SBjoern A. Zeeb u8 cur_k_set = dpk->cur_k_set; 1922e2340276SBjoern A. Zeeb u32 para; 1923e2340276SBjoern A. Zeeb 1924e2340276SBjoern A. Zeeb if (cur_k_set >= DPK_KSET_NUM) { 1925e2340276SBjoern A. Zeeb rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); 1926e2340276SBjoern A. Zeeb cur_k_set = 2; 1927e2340276SBjoern A. Zeeb } 1928e2340276SBjoern A. Zeeb 1929e2340276SBjoern A. Zeeb para = rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), 1930e2340276SBjoern A. Zeeb MASKDWORD); 1931e2340276SBjoern A. Zeeb 1932e2340276SBjoern A. Zeeb dpk->bp[path][kidx].txagc_dpk = (para >> 10) & 0x3f; 1933e2340276SBjoern A. Zeeb dpk->bp[path][kidx].ther_dpk = (para >> 26) & 0x3f; 1934e2340276SBjoern A. Zeeb 1935e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1936e2340276SBjoern A. Zeeb "[DPK] thermal/ txagc_RF (K%d) = 0x%x/ 0x%x\n", 1937e2340276SBjoern A. Zeeb dpk->cur_k_set, dpk->bp[path][kidx].ther_dpk, 1938e2340276SBjoern A. Zeeb dpk->bp[path][kidx].txagc_dpk); 1939e2340276SBjoern A. Zeeb } 1940e2340276SBjoern A. Zeeb 1941e2340276SBjoern A. Zeeb static bool _dpk_sync_check(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) 1942e2340276SBjoern A. Zeeb { 1943e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1944e2340276SBjoern A. Zeeb u8 corr_val, corr_idx, rxbb; 1945e2340276SBjoern A. Zeeb u16 dc_i, dc_q; 1946e2340276SBjoern A. Zeeb u8 rxbb_ov; 1947e2340276SBjoern A. Zeeb 1948e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); 1949e2340276SBjoern A. Zeeb 1950e2340276SBjoern A. Zeeb corr_idx = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); 1951e2340276SBjoern A. Zeeb corr_val = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); 1952e2340276SBjoern A. Zeeb dpk->corr_idx[path][kidx] = corr_idx; 1953e2340276SBjoern A. Zeeb dpk->corr_val[path][kidx] = corr_val; 1954e2340276SBjoern A. Zeeb 1955e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); 1956e2340276SBjoern A. Zeeb 1957e2340276SBjoern A. Zeeb dc_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); 1958e2340276SBjoern A. Zeeb dc_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); 1959e2340276SBjoern A. Zeeb 1960e2340276SBjoern A. Zeeb dc_i = abs(sign_extend32(dc_i, 11)); 1961e2340276SBjoern A. Zeeb dc_q = abs(sign_extend32(dc_q, 11)); 1962e2340276SBjoern A. Zeeb 1963e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1964e2340276SBjoern A. Zeeb "[DPK] S%d Corr_idx/ Corr_val /DC I/Q, = %d / %d / %d / %d\n", 1965e2340276SBjoern A. Zeeb path, corr_idx, corr_val, dc_i, dc_q); 1966e2340276SBjoern A. Zeeb 1967e2340276SBjoern A. Zeeb dpk->dc_i[path][kidx] = dc_i; 1968e2340276SBjoern A. Zeeb dpk->dc_q[path][kidx] = dc_q; 1969e2340276SBjoern A. Zeeb 1970e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x8); 1971e2340276SBjoern A. Zeeb rxbb = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXBB); 1972e2340276SBjoern A. Zeeb 1973e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x31); 1974e2340276SBjoern A. Zeeb rxbb_ov = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_RXOV); 1975e2340276SBjoern A. Zeeb 1976e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1977e2340276SBjoern A. Zeeb "[DPK] S%d RXBB/ RXAGC_done /RXBB_ovlmt = %d / %d / %d\n", 1978e2340276SBjoern A. Zeeb path, rxbb, 1979e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DONE), 1980e2340276SBjoern A. Zeeb rxbb_ov); 1981e2340276SBjoern A. Zeeb 1982e2340276SBjoern A. Zeeb if (dc_i > 200 || dc_q > 200 || corr_val < 170) 1983e2340276SBjoern A. Zeeb return true; 1984e2340276SBjoern A. Zeeb else 1985e2340276SBjoern A. Zeeb return false; 1986e2340276SBjoern A. Zeeb } 1987e2340276SBjoern A. Zeeb 1988e2340276SBjoern A. Zeeb static void _dpk_kip_set_txagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1989e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 dbm, 1990e2340276SBjoern A. Zeeb bool set_from_bb) 1991e2340276SBjoern A. Zeeb { 1992e2340276SBjoern A. Zeeb if (set_from_bb) { 1993e2340276SBjoern A. Zeeb dbm = clamp_t(u8, dbm, 7, 24); 1994e2340276SBjoern A. Zeeb 1995e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1996e2340276SBjoern A. Zeeb "[DPK] set S%d txagc to %ddBm\n", path, dbm); 1997e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXPWRB + (path << 13), 1998e2340276SBjoern A. Zeeb B_TXPWRB_VAL, dbm << 2); 1999e2340276SBjoern A. Zeeb } 2000e2340276SBjoern A. Zeeb 2001e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_TXAGC); 2002e2340276SBjoern A. Zeeb _dpk_kset_query(rtwdev, path); 2003e2340276SBjoern A. Zeeb } 2004e2340276SBjoern A. Zeeb 2005e2340276SBjoern A. Zeeb static bool _dpk_kip_set_rxagc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2006e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 2007e2340276SBjoern A. Zeeb { 2008e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2009e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_MOD, B_KIP_MOD, 2010e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); 2011e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, true); 2012e2340276SBjoern A. Zeeb 2013e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_RXAGC); 2014e2340276SBjoern A. Zeeb return _dpk_sync_check(rtwdev, path, kidx); 2015e2340276SBjoern A. Zeeb } 2016e2340276SBjoern A. Zeeb 2017e2340276SBjoern A. Zeeb static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2018e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2019e2340276SBjoern A. Zeeb { 2020e2340276SBjoern A. Zeeb u32 rf_11, reg_81cc; 2021e2340276SBjoern A. Zeeb u8 cur_rxbb; 2022e2340276SBjoern A. Zeeb 2023e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); 2024e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x1); 2025e2340276SBjoern A. Zeeb 2026e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2027e2340276SBjoern A. Zeeb 2028e2340276SBjoern A. Zeeb cur_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); 2029e2340276SBjoern A. Zeeb rf_11 = rtw89_read_rf(rtwdev, path, RR_TXIG, RFREG_MASK); 2030e2340276SBjoern A. Zeeb reg_81cc = rtw89_phy_read32_mask(rtwdev, R_KIP_IQP + (path << 8), 2031e2340276SBjoern A. Zeeb B_KIP_IQP_SW); 2032e2340276SBjoern A. Zeeb 2033e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR0, 0x0); 2034e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_GR1, 0x3); 2035e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RR_TXIG_TG, 0xd); 2036e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, 0x1f); 2037e2340276SBjoern A. Zeeb 2038e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW, 0x12); 2039e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, 0x3); 2040e2340276SBjoern A. Zeeb 2041e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, true); 2042e2340276SBjoern A. Zeeb 2043e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, MASKDWORD, 0x00250025); 2044e2340276SBjoern A. Zeeb 2045e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK); 2046e2340276SBjoern A. Zeeb 2047e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, 2048e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD)); 2049e2340276SBjoern A. Zeeb 2050e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2051e2340276SBjoern A. Zeeb 2052e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXIG, RFREG_MASK, rf_11); 2053e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, cur_rxbb); 2054e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_SW, reg_81cc); 2055e2340276SBjoern A. Zeeb 2056e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, B_MDPK_RX_DCK_EN, 0x0); 2057e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, B_KPATH_CFG_ED, 0x0); 2058e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_DI, 0x1); 2059e2340276SBjoern A. Zeeb 2060e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, true); 2061e2340276SBjoern A. Zeeb } 2062e2340276SBjoern A. Zeeb 2063e2340276SBjoern A. Zeeb static void _dpk_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) 2064e2340276SBjoern A. Zeeb { 2065e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2066e2340276SBjoern A. Zeeb 2067e2340276SBjoern A. Zeeb if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { 2068e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 0x50521); 2069e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); 2070e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); 2071e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x7); 2072e2340276SBjoern A. Zeeb } else { 2073e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 2074e2340276SBjoern A. Zeeb 0x50521 | BIT(rtwdev->dbcc_en)); 2075e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD_V1, RR_MOD_MASK, RF_DPK); 2076e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RAA2_SATT, 0x3); 2077e2340276SBjoern A. Zeeb } 2078e2340276SBjoern A. Zeeb 2079e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); 2080e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); 2081e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); 2082e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_RXBB2_EBW, 0x0); 2083e2340276SBjoern A. Zeeb } 2084e2340276SBjoern A. Zeeb 2085e2340276SBjoern A. Zeeb static void _dpk_bypass_rxiqc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 2086e2340276SBjoern A. Zeeb { 2087e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_V1 + (path << 8), B_DPD_LBK, 0x1); 2088e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 0x40000002); 2089e2340276SBjoern A. Zeeb 2090e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Bypass RXIQC\n"); 2091e2340276SBjoern A. Zeeb } 2092e2340276SBjoern A. Zeeb 2093e2340276SBjoern A. Zeeb static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) 2094e2340276SBjoern A. Zeeb { 2095e2340276SBjoern A. Zeeb u16 dgain; 2096e2340276SBjoern A. Zeeb 2097e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x0); 2098e2340276SBjoern A. Zeeb dgain = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); 2099e2340276SBjoern A. Zeeb 2100e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x\n", dgain); 2101e2340276SBjoern A. Zeeb 2102e2340276SBjoern A. Zeeb return dgain; 2103e2340276SBjoern A. Zeeb } 2104e2340276SBjoern A. Zeeb 2105e2340276SBjoern A. Zeeb static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) 2106e2340276SBjoern A. Zeeb { 2107e2340276SBjoern A. Zeeb u8 result; 2108e2340276SBjoern A. Zeeb 2109e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); 2110e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); 2111e2340276SBjoern A. Zeeb result = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); 2112e2340276SBjoern A. Zeeb 2113e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp GL = %d\n", result); 2114e2340276SBjoern A. Zeeb 2115e2340276SBjoern A. Zeeb return result; 2116e2340276SBjoern A. Zeeb } 2117e2340276SBjoern A. Zeeb 2118e2340276SBjoern A. Zeeb static u8 _dpk_gainloss(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2119e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 2120e2340276SBjoern A. Zeeb { 2121e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_GAIN_LOSS); 2122e2340276SBjoern A. Zeeb _dpk_kip_set_txagc(rtwdev, phy, path, 0xff, false); 2123e2340276SBjoern A. Zeeb 2124e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A1, 0xf078); 2125e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_GL + (path << 8), B_DPK_GL_A0, 0x0); 2126e2340276SBjoern A. Zeeb 2127e2340276SBjoern A. Zeeb return _dpk_gainloss_read(rtwdev); 2128e2340276SBjoern A. Zeeb } 2129e2340276SBjoern A. Zeeb 2130e2340276SBjoern A. Zeeb static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, u8 is_check) 2131e2340276SBjoern A. Zeeb { 2132e2340276SBjoern A. Zeeb u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; 2133e2340276SBjoern A. Zeeb u32 val1_sqrt_sum, val2_sqrt_sum; 2134e2340276SBjoern A. Zeeb u8 i; 2135e2340276SBjoern A. Zeeb 2136e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKBYTE2, 0x06); 2137e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x0); 2138e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE2, 0x08); 2139e2340276SBjoern A. Zeeb 2140e2340276SBjoern A. Zeeb if (is_check) { 2141e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); 2142e2340276SBjoern A. Zeeb val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); 2143e2340276SBjoern A. Zeeb val1_i = abs(sign_extend32(val1_i, 11)); 2144e2340276SBjoern A. Zeeb val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); 2145e2340276SBjoern A. Zeeb val1_q = abs(sign_extend32(val1_q, 11)); 2146e2340276SBjoern A. Zeeb 2147e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); 2148e2340276SBjoern A. Zeeb val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); 2149e2340276SBjoern A. Zeeb val2_i = abs(sign_extend32(val2_i, 11)); 2150e2340276SBjoern A. Zeeb val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); 2151e2340276SBjoern A. Zeeb val2_q = abs(sign_extend32(val2_q, 11)); 2152e2340276SBjoern A. Zeeb 2153e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", 2154e2340276SBjoern A. Zeeb phy_div(val1_i * val1_i + val1_q * val1_q, 2155e2340276SBjoern A. Zeeb val2_i * val2_i + val2_q * val2_q)); 2156e2340276SBjoern A. Zeeb } else { 2157e2340276SBjoern A. Zeeb for (i = 0; i < 32; i++) { 2158e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); 2159e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2160e2340276SBjoern A. Zeeb "[DPK] PAS_Read[%02d]= 0x%08x\n", i, 2161e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); 2162e2340276SBjoern A. Zeeb } 2163e2340276SBjoern A. Zeeb } 2164e2340276SBjoern A. Zeeb 2165e2340276SBjoern A. Zeeb val1_sqrt_sum = val1_i * val1_i + val1_q * val1_q; 2166e2340276SBjoern A. Zeeb val2_sqrt_sum = val2_i * val2_i + val2_q * val2_q; 2167e2340276SBjoern A. Zeeb 2168e2340276SBjoern A. Zeeb if (val1_sqrt_sum < val2_sqrt_sum) 2169e2340276SBjoern A. Zeeb return 2; 2170e2340276SBjoern A. Zeeb else if (val1_sqrt_sum >= val2_sqrt_sum * 8 / 5) 2171e2340276SBjoern A. Zeeb return 1; 2172e2340276SBjoern A. Zeeb else 2173e2340276SBjoern A. Zeeb return 0; 2174e2340276SBjoern A. Zeeb } 2175e2340276SBjoern A. Zeeb 2176e2340276SBjoern A. Zeeb static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2177e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, u8 init_xdbm, u8 loss_only) 2178e2340276SBjoern A. Zeeb { 2179e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2180e2340276SBjoern A. Zeeb u8 tmp_dbm = init_xdbm, tmp_gl_idx = 0; 2181e2340276SBjoern A. Zeeb u8 step = DPK_AGC_STEP_SYNC_DGAIN; 2182e2340276SBjoern A. Zeeb u8 goout = 0, agc_cnt = 0; 2183e2340276SBjoern A. Zeeb bool is_fail = false; 2184e2340276SBjoern A. Zeeb int limit = 200; 2185e2340276SBjoern A. Zeeb u8 tmp_rxbb; 2186e2340276SBjoern A. Zeeb u16 dgain; 2187e2340276SBjoern A. Zeeb 2188e2340276SBjoern A. Zeeb do { 2189e2340276SBjoern A. Zeeb switch (step) { 2190e2340276SBjoern A. Zeeb case DPK_AGC_STEP_SYNC_DGAIN: 2191e2340276SBjoern A. Zeeb is_fail = _dpk_kip_set_rxagc(rtwdev, phy, path, kidx); 2192e2340276SBjoern A. Zeeb 2193e2340276SBjoern A. Zeeb if (is_fail) { 2194e2340276SBjoern A. Zeeb goout = 1; 2195e2340276SBjoern A. Zeeb break; 2196e2340276SBjoern A. Zeeb } 2197e2340276SBjoern A. Zeeb 2198e2340276SBjoern A. Zeeb dgain = _dpk_dgain_read(rtwdev); 2199e2340276SBjoern A. Zeeb 2200e2340276SBjoern A. Zeeb if (dgain > 0x5fc || dgain < 0x556) { 2201e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_SYNC); 2202*df279a26SBjoern A. Zeeb _dpk_dgain_read(rtwdev); 2203e2340276SBjoern A. Zeeb } 2204e2340276SBjoern A. Zeeb 2205e2340276SBjoern A. Zeeb if (agc_cnt == 0) { 2206e2340276SBjoern A. Zeeb if (dpk->bp[path][kidx].band == RTW89_BAND_2G) 2207e2340276SBjoern A. Zeeb _dpk_bypass_rxiqc(rtwdev, path); 2208e2340276SBjoern A. Zeeb else 2209e2340276SBjoern A. Zeeb _dpk_lbk_rxiqk(rtwdev, phy, path); 2210e2340276SBjoern A. Zeeb } 2211e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_LOSS_IDX; 2212e2340276SBjoern A. Zeeb break; 2213e2340276SBjoern A. Zeeb 2214e2340276SBjoern A. Zeeb case DPK_AGC_STEP_GAIN_LOSS_IDX: 2215e2340276SBjoern A. Zeeb tmp_gl_idx = _dpk_gainloss(rtwdev, phy, path, kidx); 2216e2340276SBjoern A. Zeeb 2217e2340276SBjoern A. Zeeb if (_dpk_pas_read(rtwdev, true) == 2 && tmp_gl_idx > 0) 2218e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_GL_LT_CRITERION; 2219e2340276SBjoern A. Zeeb else if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true) == 1) || 2220e2340276SBjoern A. Zeeb tmp_gl_idx >= 7) 2221e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_GL_GT_CRITERION; 2222e2340276SBjoern A. Zeeb else if (tmp_gl_idx == 0) 2223e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_GL_LT_CRITERION; 2224e2340276SBjoern A. Zeeb else 2225e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_SET_TX_GAIN; 2226e2340276SBjoern A. Zeeb break; 2227e2340276SBjoern A. Zeeb 2228e2340276SBjoern A. Zeeb case DPK_AGC_STEP_GL_GT_CRITERION: 2229e2340276SBjoern A. Zeeb if (tmp_dbm <= 7) { 2230e2340276SBjoern A. Zeeb goout = 1; 2231e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2232e2340276SBjoern A. Zeeb "[DPK] Txagc@lower bound!!\n"); 2233e2340276SBjoern A. Zeeb } else { 2234e2340276SBjoern A. Zeeb tmp_dbm = max_t(u8, tmp_dbm - 3, 7); 2235e2340276SBjoern A. Zeeb _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); 2236e2340276SBjoern A. Zeeb } 2237e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_SYNC_DGAIN; 2238e2340276SBjoern A. Zeeb agc_cnt++; 2239e2340276SBjoern A. Zeeb break; 2240e2340276SBjoern A. Zeeb 2241e2340276SBjoern A. Zeeb case DPK_AGC_STEP_GL_LT_CRITERION: 2242e2340276SBjoern A. Zeeb if (tmp_dbm >= 24) { 2243e2340276SBjoern A. Zeeb goout = 1; 2244e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2245e2340276SBjoern A. Zeeb "[DPK] Txagc@upper bound!!\n"); 2246e2340276SBjoern A. Zeeb } else { 2247e2340276SBjoern A. Zeeb tmp_dbm = min_t(u8, tmp_dbm + 2, 24); 2248e2340276SBjoern A. Zeeb _dpk_kip_set_txagc(rtwdev, phy, path, tmp_dbm, true); 2249e2340276SBjoern A. Zeeb } 2250e2340276SBjoern A. Zeeb step = DPK_AGC_STEP_SYNC_DGAIN; 2251e2340276SBjoern A. Zeeb agc_cnt++; 2252e2340276SBjoern A. Zeeb break; 2253e2340276SBjoern A. Zeeb 2254e2340276SBjoern A. Zeeb case DPK_AGC_STEP_SET_TX_GAIN: 2255e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2256e2340276SBjoern A. Zeeb tmp_rxbb = rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_RXB); 2257e2340276SBjoern A. Zeeb tmp_rxbb = min_t(u8, tmp_rxbb + tmp_gl_idx, 0x1f); 2258e2340276SBjoern A. Zeeb 2259e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_RXB, tmp_rxbb); 2260e2340276SBjoern A. Zeeb 2261e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2262e2340276SBjoern A. Zeeb "[DPK] Adjust RXBB (%+d) = 0x%x\n", 2263e2340276SBjoern A. Zeeb tmp_gl_idx, tmp_rxbb); 2264e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, true); 2265e2340276SBjoern A. Zeeb goout = 1; 2266e2340276SBjoern A. Zeeb break; 2267e2340276SBjoern A. Zeeb default: 2268e2340276SBjoern A. Zeeb goout = 1; 2269e2340276SBjoern A. Zeeb break; 2270e2340276SBjoern A. Zeeb } 2271e2340276SBjoern A. Zeeb } while (!goout && agc_cnt < 6 && limit-- > 0); 2272e2340276SBjoern A. Zeeb 2273e2340276SBjoern A. Zeeb return is_fail; 2274e2340276SBjoern A. Zeeb } 2275e2340276SBjoern A. Zeeb 2276e2340276SBjoern A. Zeeb static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) 2277e2340276SBjoern A. Zeeb { 2278e2340276SBjoern A. Zeeb switch (order) { 2279e2340276SBjoern A. Zeeb case 0: /* (5,3,1) */ 2280e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x0); 2281e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x2); 2282e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4); 2283e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); 2284e2340276SBjoern A. Zeeb break; 2285e2340276SBjoern A. Zeeb case 1: /* (5,3,0) */ 2286e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x1); 2287e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x1); 2288e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); 2289e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); 2290e2340276SBjoern A. Zeeb break; 2291e2340276SBjoern A. Zeeb case 2: /* (5,0,0) */ 2292e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x2); 2293e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x0); 2294e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x0); 2295e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x0); 2296e2340276SBjoern A. Zeeb break; 2297e2340276SBjoern A. Zeeb case 3: /* (7,3,1) */ 2298e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, 0x3); 2299e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL_SEL, 0x3); 2300e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x4); 2301e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_DMAN, 0x1); 2302e2340276SBjoern A. Zeeb break; 2303e2340276SBjoern A. Zeeb default: 2304e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2305e2340276SBjoern A. Zeeb "[DPK] Wrong MDPD order!!(0x%x)\n", order); 2306e2340276SBjoern A. Zeeb break; 2307e2340276SBjoern A. Zeeb } 2308e2340276SBjoern A. Zeeb 2309e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Set %s for IDL\n", 2310e2340276SBjoern A. Zeeb order == 0x0 ? "(5,3,1)" : 2311e2340276SBjoern A. Zeeb order == 0x1 ? "(5,3,0)" : 2312e2340276SBjoern A. Zeeb order == 0x2 ? "(5,0,0)" : "(7,3,1)"); 2313e2340276SBjoern A. Zeeb } 2314e2340276SBjoern A. Zeeb 2315e2340276SBjoern A. Zeeb static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2316e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 2317e2340276SBjoern A. Zeeb { 2318e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_MA, 0x1); 2319e2340276SBjoern A. Zeeb 2320e2340276SBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD500) == 0x1) 2321e2340276SBjoern A. Zeeb _dpk_set_mdpd_para(rtwdev, 0x2); 2322e2340276SBjoern A. Zeeb else if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_MD530) == 0x1) 2323e2340276SBjoern A. Zeeb _dpk_set_mdpd_para(rtwdev, 0x1); 2324e2340276SBjoern A. Zeeb else 2325e2340276SBjoern A. Zeeb _dpk_set_mdpd_para(rtwdev, 0x0); 2326e2340276SBjoern A. Zeeb 2327e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_IDL, B_DPK_IDL, 0x0); 2328e2340276SBjoern A. Zeeb fsleep(1000); 2329e2340276SBjoern A. Zeeb 2330e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_MDPK_IDL); 2331e2340276SBjoern A. Zeeb } 2332e2340276SBjoern A. Zeeb 2333e2340276SBjoern A. Zeeb static u8 _dpk_order_convert(struct rtw89_dev *rtwdev) 2334e2340276SBjoern A. Zeeb { 2335e2340276SBjoern A. Zeeb u32 order; 2336e2340276SBjoern A. Zeeb u8 val; 2337e2340276SBjoern A. Zeeb 2338e2340276SBjoern A. Zeeb order = rtw89_phy_read32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP); 2339e2340276SBjoern A. Zeeb 2340e2340276SBjoern A. Zeeb switch (order) { 2341e2340276SBjoern A. Zeeb case 0: /* (5,3,1) */ 2342e2340276SBjoern A. Zeeb val = 0x6; 2343e2340276SBjoern A. Zeeb break; 2344e2340276SBjoern A. Zeeb case 1: /* (5,3,0) */ 2345e2340276SBjoern A. Zeeb val = 0x2; 2346e2340276SBjoern A. Zeeb break; 2347e2340276SBjoern A. Zeeb case 2: /* (5,0,0) */ 2348e2340276SBjoern A. Zeeb val = 0x0; 2349e2340276SBjoern A. Zeeb break; 2350e2340276SBjoern A. Zeeb default: 2351e2340276SBjoern A. Zeeb val = 0xff; 2352e2340276SBjoern A. Zeeb break; 2353e2340276SBjoern A. Zeeb } 2354e2340276SBjoern A. Zeeb 2355e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] convert MDPD order to 0x%x\n", val); 2356e2340276SBjoern A. Zeeb 2357e2340276SBjoern A. Zeeb return val; 2358e2340276SBjoern A. Zeeb } 2359e2340276SBjoern A. Zeeb 2360e2340276SBjoern A. Zeeb static void _dpk_gain_normalize(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2361e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, bool is_execute) 2362e2340276SBjoern A. Zeeb { 2363e2340276SBjoern A. Zeeb static const u32 reg[RTW89_DPK_BKUP_NUM][DPK_KSET_NUM] = { 2364e2340276SBjoern A. Zeeb {0x8190, 0x8194, 0x8198, 0x81a4}, 2365e2340276SBjoern A. Zeeb {0x81a8, 0x81c4, 0x81c8, 0x81e8} 2366e2340276SBjoern A. Zeeb }; 2367e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2368e2340276SBjoern A. Zeeb u8 cur_k_set = dpk->cur_k_set; 2369e2340276SBjoern A. Zeeb 2370e2340276SBjoern A. Zeeb if (cur_k_set >= DPK_KSET_NUM) { 2371e2340276SBjoern A. Zeeb rtw89_warn(rtwdev, "DPK cur_k_set = %d\n", cur_k_set); 2372e2340276SBjoern A. Zeeb cur_k_set = 2; 2373e2340276SBjoern A. Zeeb } 2374e2340276SBjoern A. Zeeb 2375e2340276SBjoern A. Zeeb if (is_execute) { 2376e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), 2377e2340276SBjoern A. Zeeb B_DPK_GN_AG, 0x200); 2378e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_GN + (path << 8), 2379e2340276SBjoern A. Zeeb B_DPK_GN_EN, 0x3); 2380e2340276SBjoern A. Zeeb 2381e2340276SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, D_GAIN_NORM); 2382e2340276SBjoern A. Zeeb } else { 2383e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), 2384e2340276SBjoern A. Zeeb 0x0000007F, 0x5b); 2385e2340276SBjoern A. Zeeb } 2386e2340276SBjoern A. Zeeb 2387e2340276SBjoern A. Zeeb dpk->bp[path][kidx].gs = 2388e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, reg[kidx][cur_k_set] + (path << 8), 2389e2340276SBjoern A. Zeeb 0x0000007F); 2390e2340276SBjoern A. Zeeb } 2391e2340276SBjoern A. Zeeb 2392e2340276SBjoern A. Zeeb static void _dpk_on(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2393e2340276SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 2394e2340276SBjoern A. Zeeb { 2395e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2396e2340276SBjoern A. Zeeb 2397e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); 2398e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x0); 2399e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 2400e2340276SBjoern A. Zeeb B_DPD_ORDER, _dpk_order_convert(rtwdev)); 2401e2340276SBjoern A. Zeeb 2402e2340276SBjoern A. Zeeb dpk->bp[path][kidx].path_ok = 2403e2340276SBjoern A. Zeeb dpk->bp[path][kidx].path_ok | BIT(dpk->cur_k_set); 2404e2340276SBjoern A. Zeeb 2405e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] path_ok = 0x%x\n", 2406e2340276SBjoern A. Zeeb path, kidx, dpk->bp[path][kidx].path_ok); 2407e2340276SBjoern A. Zeeb 2408e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 2409e2340276SBjoern A. Zeeb B_DPD_MEN, dpk->bp[path][kidx].path_ok); 2410e2340276SBjoern A. Zeeb 2411e2340276SBjoern A. Zeeb _dpk_gain_normalize(rtwdev, phy, path, kidx, false); 2412e2340276SBjoern A. Zeeb } 2413e2340276SBjoern A. Zeeb 2414e2340276SBjoern A. Zeeb static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2415e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2416e2340276SBjoern A. Zeeb { 2417e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2418e2340276SBjoern A. Zeeb u8 kidx = dpk->cur_idx[path]; 2419e2340276SBjoern A. Zeeb u8 init_xdbm = 17; 2420e2340276SBjoern A. Zeeb bool is_fail; 2421e2340276SBjoern A. Zeeb 2422e2340276SBjoern A. Zeeb if (dpk->bp[path][kidx].band != RTW89_BAND_2G) 2423e2340276SBjoern A. Zeeb init_xdbm = 15; 2424e2340276SBjoern A. Zeeb 2425e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2426e2340276SBjoern A. Zeeb _rfk_rf_direct_cntrl(rtwdev, path, false); 2427e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BBDC, RFREG_MASK, 0x03ffd); 2428e2340276SBjoern A. Zeeb 2429e2340276SBjoern A. Zeeb _dpk_rf_setting(rtwdev, path, kidx); 2430e2340276SBjoern A. Zeeb _set_rx_dck(rtwdev, path, RF_DPK); 2431e2340276SBjoern A. Zeeb 2432e2340276SBjoern A. Zeeb _dpk_kip_pwr_clk_onoff(rtwdev, true); 2433e2340276SBjoern A. Zeeb _dpk_kip_preset(rtwdev, phy, path, kidx); 2434e2340276SBjoern A. Zeeb _dpk_txpwr_bb_force(rtwdev, path, true); 2435e2340276SBjoern A. Zeeb _dpk_kip_set_txagc(rtwdev, phy, path, init_xdbm, true); 2436e2340276SBjoern A. Zeeb _dpk_tpg_sel(rtwdev, path, kidx); 2437e2340276SBjoern A. Zeeb is_fail = _dpk_agc(rtwdev, phy, path, kidx, init_xdbm, false); 2438e2340276SBjoern A. Zeeb if (is_fail) 2439e2340276SBjoern A. Zeeb goto _error; 2440e2340276SBjoern A. Zeeb 2441e2340276SBjoern A. Zeeb _dpk_idl_mpa(rtwdev, phy, path, kidx); 2442e2340276SBjoern A. Zeeb _dpk_para_query(rtwdev, path, kidx); 2443e2340276SBjoern A. Zeeb 2444e2340276SBjoern A. Zeeb _dpk_on(rtwdev, phy, path, kidx); 2445e2340276SBjoern A. Zeeb _error: 2446e2340276SBjoern A. Zeeb _dpk_kip_control_rfc(rtwdev, path, false); 2447e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RF_RX); 2448e2340276SBjoern A. Zeeb 2449e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d]_K%d %s\n", path, kidx, 2450e2340276SBjoern A. Zeeb dpk->cur_k_set, is_fail ? "need Check" : "is Success"); 2451e2340276SBjoern A. Zeeb 2452e2340276SBjoern A. Zeeb return is_fail; 2453e2340276SBjoern A. Zeeb } 2454e2340276SBjoern A. Zeeb 2455e2340276SBjoern A. Zeeb static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, 2456*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, u8 kpath, 2457*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 2458e2340276SBjoern A. Zeeb { 2459e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2460e2340276SBjoern A. Zeeb u32 kip_bkup[RF_PATH_NUM_8851B][DPK_KIP_REG_NUM_8851B] = {}; 2461e2340276SBjoern A. Zeeb u32 rf_bkup[RF_PATH_NUM_8851B][DPK_RF_REG_NUM_8851B] = {}; 2462e2340276SBjoern A. Zeeb bool is_fail; 2463e2340276SBjoern A. Zeeb u8 path; 2464e2340276SBjoern A. Zeeb 2465e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) 2466e2340276SBjoern A. Zeeb dpk->cur_idx[path] = 0; 2467e2340276SBjoern A. Zeeb 2468e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 2469e2340276SBjoern A. Zeeb if (!(kpath & BIT(path))) 2470e2340276SBjoern A. Zeeb continue; 2471e2340276SBjoern A. Zeeb _dpk_bkup_kip(rtwdev, dpk_kip_reg, kip_bkup, path); 2472e2340276SBjoern A. Zeeb _dpk_bkup_rf(rtwdev, dpk_rf_reg, rf_bkup, path); 2473*df279a26SBjoern A. Zeeb _dpk_information(rtwdev, phy, path, chanctx_idx); 2474e2340276SBjoern A. Zeeb _dpk_init(rtwdev, path); 2475e2340276SBjoern A. Zeeb 2476e2340276SBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 2477e2340276SBjoern A. Zeeb _dpk_tssi_pause(rtwdev, path, true); 2478e2340276SBjoern A. Zeeb } 2479e2340276SBjoern A. Zeeb 2480e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 2481e2340276SBjoern A. Zeeb if (!(kpath & BIT(path))) 2482e2340276SBjoern A. Zeeb continue; 2483e2340276SBjoern A. Zeeb 2484e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2485e2340276SBjoern A. Zeeb "[DPK] ========= S%d[%d] DPK Start =========\n", 2486e2340276SBjoern A. Zeeb path, dpk->cur_idx[path]); 2487e2340276SBjoern A. Zeeb 2488e2340276SBjoern A. Zeeb _dpk_rxagc_onoff(rtwdev, path, false); 2489e2340276SBjoern A. Zeeb _rfk_drf_direct_cntrl(rtwdev, path, false); 2490e2340276SBjoern A. Zeeb _dpk_bb_afe_setting(rtwdev, path); 2491e2340276SBjoern A. Zeeb 2492e2340276SBjoern A. Zeeb is_fail = _dpk_main(rtwdev, phy, path); 2493e2340276SBjoern A. Zeeb _dpk_onoff(rtwdev, path, is_fail); 2494e2340276SBjoern A. Zeeb } 2495e2340276SBjoern A. Zeeb 2496e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 2497e2340276SBjoern A. Zeeb if (!(kpath & BIT(path))) 2498e2340276SBjoern A. Zeeb continue; 2499e2340276SBjoern A. Zeeb 2500e2340276SBjoern A. Zeeb _dpk_kip_restore(rtwdev, phy, path); 2501e2340276SBjoern A. Zeeb _dpk_reload_kip(rtwdev, dpk_kip_reg, kip_bkup, path); 2502e2340276SBjoern A. Zeeb _dpk_reload_rf(rtwdev, dpk_rf_reg, rf_bkup, path); 2503e2340276SBjoern A. Zeeb _dpk_bb_afe_restore(rtwdev, path); 2504e2340276SBjoern A. Zeeb _dpk_rxagc_onoff(rtwdev, path, true); 2505e2340276SBjoern A. Zeeb 2506e2340276SBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 2507e2340276SBjoern A. Zeeb _dpk_tssi_pause(rtwdev, path, false); 2508e2340276SBjoern A. Zeeb } 2509e2340276SBjoern A. Zeeb 2510e2340276SBjoern A. Zeeb _dpk_kip_pwr_clk_onoff(rtwdev, false); 2511e2340276SBjoern A. Zeeb } 2512e2340276SBjoern A. Zeeb 2513*df279a26SBjoern A. Zeeb static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, bool force, 2514*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 2515e2340276SBjoern A. Zeeb { 2516e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 2517e2340276SBjoern A. Zeeb "[DPK] ****** 8851B DPK Start (Ver: 0x%x, Cv: %d) ******\n", 2518e2340276SBjoern A. Zeeb DPK_VER_8851B, rtwdev->hal.cv); 2519e2340276SBjoern A. Zeeb 2520*df279a26SBjoern A. Zeeb _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), chanctx_idx); 2521e2340276SBjoern A. Zeeb } 2522e2340276SBjoern A. Zeeb 2523e2340276SBjoern A. Zeeb static void _dpk_track(struct rtw89_dev *rtwdev) 2524e2340276SBjoern A. Zeeb { 2525e2340276SBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2526e2340276SBjoern A. Zeeb s8 txagc_bb, txagc_bb_tp, txagc_ofst; 2527e2340276SBjoern A. Zeeb s16 pwsf_tssi_ofst; 2528e2340276SBjoern A. Zeeb s8 delta_ther = 0; 2529e2340276SBjoern A. Zeeb u8 path, kidx; 2530e2340276SBjoern A. Zeeb u8 txagc_rf; 2531e2340276SBjoern A. Zeeb u8 cur_ther; 2532e2340276SBjoern A. Zeeb 2533e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 2534e2340276SBjoern A. Zeeb kidx = dpk->cur_idx[path]; 2535e2340276SBjoern A. Zeeb 2536e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2537e2340276SBjoern A. Zeeb "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", 2538e2340276SBjoern A. Zeeb path, kidx, dpk->bp[path][kidx].ch); 2539e2340276SBjoern A. Zeeb 2540e2340276SBjoern A. Zeeb txagc_rf = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), 2541e2340276SBjoern A. Zeeb B_TXAGC_RF); 2542e2340276SBjoern A. Zeeb txagc_bb = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), 2543e2340276SBjoern A. Zeeb MASKBYTE2); 2544e2340276SBjoern A. Zeeb txagc_bb_tp = rtw89_phy_read32_mask(rtwdev, R_TXAGC_BTP + (path << 13), 2545e2340276SBjoern A. Zeeb B_TXAGC_BTP); 2546e2340276SBjoern A. Zeeb 2547e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), 2548e2340276SBjoern A. Zeeb B_KIP_RPT_SEL, 0xf); 2549e2340276SBjoern A. Zeeb cur_ther = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), 2550e2340276SBjoern A. Zeeb B_RPT_PER_TH); 2551e2340276SBjoern A. Zeeb txagc_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), 2552e2340276SBjoern A. Zeeb B_RPT_PER_OF); 2553e2340276SBjoern A. Zeeb pwsf_tssi_ofst = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), 2554e2340276SBjoern A. Zeeb B_RPT_PER_TSSI); 2555e2340276SBjoern A. Zeeb pwsf_tssi_ofst = sign_extend32(pwsf_tssi_ofst, 12); 2556e2340276SBjoern A. Zeeb 2557e2340276SBjoern A. Zeeb delta_ther = cur_ther - dpk->bp[path][kidx].ther_dpk; 2558e2340276SBjoern A. Zeeb 2559e2340276SBjoern A. Zeeb delta_ther = delta_ther * 2 / 3; 2560e2340276SBjoern A. Zeeb 2561e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2562e2340276SBjoern A. Zeeb "[DPK_TRK] extra delta_ther = %d (0x%x / 0x%x@k)\n", 2563e2340276SBjoern A. Zeeb delta_ther, cur_ther, dpk->bp[path][kidx].ther_dpk); 2564e2340276SBjoern A. Zeeb 2565e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2566e2340276SBjoern A. Zeeb "[DPK_TRK] delta_txagc = %d (0x%x / 0x%x@k)\n", 2567e2340276SBjoern A. Zeeb txagc_rf - dpk->bp[path][kidx].txagc_dpk, 2568e2340276SBjoern A. Zeeb txagc_rf, dpk->bp[path][kidx].txagc_dpk); 2569e2340276SBjoern A. Zeeb 2570e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2571e2340276SBjoern A. Zeeb "[DPK_TRK] txagc_offset / pwsf_tssi_ofst = 0x%x / %+d\n", 2572e2340276SBjoern A. Zeeb txagc_ofst, pwsf_tssi_ofst); 2573e2340276SBjoern A. Zeeb 2574e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2575e2340276SBjoern A. Zeeb "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", 2576e2340276SBjoern A. Zeeb txagc_bb_tp, txagc_bb); 2577e2340276SBjoern A. Zeeb 2578e2340276SBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_IDL_MPA, B_IDL_DN) == 0x0 && 2579e2340276SBjoern A. Zeeb txagc_rf != 0) { 2580e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 2581e2340276SBjoern A. Zeeb "[DPK_TRK] New pwsf = 0x%x\n", 0x78 - delta_ther); 2582e2340276SBjoern A. Zeeb 2583e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, 2584e2340276SBjoern A. Zeeb R_DPD_BND + (path << 8) + (kidx << 2), 2585e2340276SBjoern A. Zeeb 0x07FC0000, 0x78 - delta_ther); 2586e2340276SBjoern A. Zeeb } 2587e2340276SBjoern A. Zeeb } 2588e2340276SBjoern A. Zeeb } 2589e2340276SBjoern A. Zeeb 2590e2340276SBjoern A. Zeeb static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 2591e2340276SBjoern A. Zeeb { 2592e2340276SBjoern A. Zeeb u32 rf_reg5; 2593e2340276SBjoern A. Zeeb u32 rck_val; 2594e2340276SBjoern A. Zeeb u32 val; 2595e2340276SBjoern A. Zeeb int ret; 2596e2340276SBjoern A. Zeeb 2597e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); 2598e2340276SBjoern A. Zeeb 2599e2340276SBjoern A. Zeeb rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); 2600e2340276SBjoern A. Zeeb 2601e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 2602e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); 2603e2340276SBjoern A. Zeeb 2604e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%05x\n", 2605e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); 2606e2340276SBjoern A. Zeeb 2607e2340276SBjoern A. Zeeb /* RCK trigger */ 2608e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); 2609e2340276SBjoern A. Zeeb 2610e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 30, 2611e2340276SBjoern A. Zeeb false, rtwdev, path, RR_RCKS, BIT(3)); 2612e2340276SBjoern A. Zeeb 2613e2340276SBjoern A. Zeeb rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); 2614e2340276SBjoern A. Zeeb 2615e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] rck_val = 0x%x, ret = %d\n", 2616e2340276SBjoern A. Zeeb rck_val, ret); 2617e2340276SBjoern A. Zeeb 2618e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); 2619e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); 2620e2340276SBjoern A. Zeeb 2621e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF 0x1b = 0x%x\n", 2622e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK)); 2623e2340276SBjoern A. Zeeb } 2624e2340276SBjoern A. Zeeb 2625e2340276SBjoern A. Zeeb static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2626*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 2627e2340276SBjoern A. Zeeb { 2628e2340276SBjoern A. Zeeb enum rtw89_band band = chan->band_type; 2629e2340276SBjoern A. Zeeb 2630e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_sys_defs_tbl); 2631e2340276SBjoern A. Zeeb 2632e2340276SBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, 2633e2340276SBjoern A. Zeeb &rtw8851b_tssi_sys_a_defs_2g_tbl, 2634e2340276SBjoern A. Zeeb &rtw8851b_tssi_sys_a_defs_5g_tbl); 2635e2340276SBjoern A. Zeeb } 2636e2340276SBjoern A. Zeeb 2637e2340276SBjoern A. Zeeb static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, 2638e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy, 2639e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2640e2340276SBjoern A. Zeeb { 2641e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_defs_a_tbl); 2642e2340276SBjoern A. Zeeb } 2643e2340276SBjoern A. Zeeb 2644e2340276SBjoern A. Zeeb static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, 2645e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy, 2646e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2647e2340276SBjoern A. Zeeb { 2648e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_init_txpwr_he_tb_defs_a_tbl); 2649e2340276SBjoern A. Zeeb } 2650e2340276SBjoern A. Zeeb 2651e2340276SBjoern A. Zeeb static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2652e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2653e2340276SBjoern A. Zeeb { 2654e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dck_defs_a_tbl); 2655e2340276SBjoern A. Zeeb } 2656e2340276SBjoern A. Zeeb 2657e2340276SBjoern A. Zeeb static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2658*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 2659e2340276SBjoern A. Zeeb { 2660e2340276SBjoern A. Zeeb #define RTW8851B_TSSI_GET_VAL(ptr, idx) \ 2661e2340276SBjoern A. Zeeb ({ \ 2662e2340276SBjoern A. Zeeb s8 *__ptr = (ptr); \ 2663e2340276SBjoern A. Zeeb u8 __idx = (idx), __i, __v; \ 2664e2340276SBjoern A. Zeeb u32 __val = 0; \ 2665e2340276SBjoern A. Zeeb for (__i = 0; __i < 4; __i++) { \ 2666e2340276SBjoern A. Zeeb __v = (__ptr[__idx + __i]); \ 2667e2340276SBjoern A. Zeeb __val |= (__v << (8 * __i)); \ 2668e2340276SBjoern A. Zeeb } \ 2669e2340276SBjoern A. Zeeb __val; \ 2670e2340276SBjoern A. Zeeb }) 2671e2340276SBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 2672e2340276SBjoern A. Zeeb u8 ch = chan->channel; 2673e2340276SBjoern A. Zeeb u8 subband = chan->subband_type; 2674e2340276SBjoern A. Zeeb const s8 *thm_up_a = NULL; 2675e2340276SBjoern A. Zeeb const s8 *thm_down_a = NULL; 2676e2340276SBjoern A. Zeeb u8 thermal = 0xff; 2677e2340276SBjoern A. Zeeb s8 thm_ofst[64] = {0}; 2678e2340276SBjoern A. Zeeb u32 tmp = 0; 2679e2340276SBjoern A. Zeeb u8 i, j; 2680e2340276SBjoern A. Zeeb 2681e2340276SBjoern A. Zeeb switch (subband) { 2682e2340276SBjoern A. Zeeb default: 2683e2340276SBjoern A. Zeeb case RTW89_CH_2G: 2684e2340276SBjoern A. Zeeb thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_2ga_p; 2685e2340276SBjoern A. Zeeb thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_2ga_n; 2686e2340276SBjoern A. Zeeb break; 2687e2340276SBjoern A. Zeeb case RTW89_CH_5G_BAND_1: 2688e2340276SBjoern A. Zeeb thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[0]; 2689e2340276SBjoern A. Zeeb thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[0]; 2690e2340276SBjoern A. Zeeb break; 2691e2340276SBjoern A. Zeeb case RTW89_CH_5G_BAND_3: 2692e2340276SBjoern A. Zeeb thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[1]; 2693e2340276SBjoern A. Zeeb thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[1]; 2694e2340276SBjoern A. Zeeb break; 2695e2340276SBjoern A. Zeeb case RTW89_CH_5G_BAND_4: 2696e2340276SBjoern A. Zeeb thm_up_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_p[2]; 2697e2340276SBjoern A. Zeeb thm_down_a = rtw89_8851b_trk_cfg.delta_swingidx_5ga_n[2]; 2698e2340276SBjoern A. Zeeb break; 2699e2340276SBjoern A. Zeeb } 2700e2340276SBjoern A. Zeeb 2701e2340276SBjoern A. Zeeb if (path == RF_PATH_A) { 2702e2340276SBjoern A. Zeeb thermal = tssi_info->thermal[RF_PATH_A]; 2703e2340276SBjoern A. Zeeb 2704e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2705e2340276SBjoern A. Zeeb "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); 2706e2340276SBjoern A. Zeeb 2707e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); 2708e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); 2709e2340276SBjoern A. Zeeb 2710e2340276SBjoern A. Zeeb if (thermal == 0xff) { 2711e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); 2712e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); 2713e2340276SBjoern A. Zeeb 2714e2340276SBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 2715e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); 2716e2340276SBjoern A. Zeeb 2717e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2718e2340276SBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 2719e2340276SBjoern A. Zeeb R_P0_TSSI_BASE + i, 0x0); 2720e2340276SBjoern A. Zeeb } 2721e2340276SBjoern A. Zeeb 2722e2340276SBjoern A. Zeeb } else { 2723e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 2724e2340276SBjoern A. Zeeb thermal); 2725e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 2726e2340276SBjoern A. Zeeb thermal); 2727e2340276SBjoern A. Zeeb 2728e2340276SBjoern A. Zeeb i = 0; 2729e2340276SBjoern A. Zeeb for (j = 0; j < 32; j++) 2730e2340276SBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 2731e2340276SBjoern A. Zeeb -thm_down_a[i++] : 2732e2340276SBjoern A. Zeeb -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; 2733e2340276SBjoern A. Zeeb 2734e2340276SBjoern A. Zeeb i = 1; 2735e2340276SBjoern A. Zeeb for (j = 63; j >= 32; j--) 2736e2340276SBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 2737e2340276SBjoern A. Zeeb thm_up_a[i++] : 2738e2340276SBjoern A. Zeeb thm_up_a[DELTA_SWINGIDX_SIZE - 1]; 2739e2340276SBjoern A. Zeeb 2740e2340276SBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 2741e2340276SBjoern A. Zeeb tmp = RTW8851B_TSSI_GET_VAL(thm_ofst, i); 2742e2340276SBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); 2743e2340276SBjoern A. Zeeb 2744e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2745e2340276SBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 2746e2340276SBjoern A. Zeeb 0x5c00 + i, tmp); 2747e2340276SBjoern A. Zeeb } 2748e2340276SBjoern A. Zeeb } 2749e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); 2750e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); 2751e2340276SBjoern A. Zeeb } 2752e2340276SBjoern A. Zeeb #undef RTW8851B_TSSI_GET_VAL 2753e2340276SBjoern A. Zeeb } 2754e2340276SBjoern A. Zeeb 2755e2340276SBjoern A. Zeeb static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2756e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2757e2340276SBjoern A. Zeeb { 2758e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_dac_gain_defs_a_tbl); 2759e2340276SBjoern A. Zeeb } 2760e2340276SBjoern A. Zeeb 2761e2340276SBjoern A. Zeeb static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2762*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 2763e2340276SBjoern A. Zeeb { 2764e2340276SBjoern A. Zeeb enum rtw89_band band = chan->band_type; 2765e2340276SBjoern A. Zeeb 2766e2340276SBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, 2767e2340276SBjoern A. Zeeb &rtw8851b_tssi_slope_a_defs_2g_tbl, 2768e2340276SBjoern A. Zeeb &rtw8851b_tssi_slope_a_defs_5g_tbl); 2769e2340276SBjoern A. Zeeb } 2770e2340276SBjoern A. Zeeb 2771e2340276SBjoern A. Zeeb static void _tssi_alignment_default(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2772*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, bool all, 2773*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 2774e2340276SBjoern A. Zeeb { 2775e2340276SBjoern A. Zeeb enum rtw89_band band = chan->band_type; 2776e2340276SBjoern A. Zeeb 2777e2340276SBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, 2778e2340276SBjoern A. Zeeb &rtw8851b_tssi_align_a_2g_defs_tbl, 2779e2340276SBjoern A. Zeeb &rtw8851b_tssi_align_a_5g_defs_tbl); 2780e2340276SBjoern A. Zeeb } 2781e2340276SBjoern A. Zeeb 2782e2340276SBjoern A. Zeeb static void _tssi_set_tssi_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2783e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2784e2340276SBjoern A. Zeeb { 2785e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_slope_defs_a_tbl); 2786e2340276SBjoern A. Zeeb } 2787e2340276SBjoern A. Zeeb 2788e2340276SBjoern A. Zeeb static void _tssi_set_tssi_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2789e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2790e2340276SBjoern A. Zeeb { 2791e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_track_defs_a_tbl); 2792e2340276SBjoern A. Zeeb } 2793e2340276SBjoern A. Zeeb 2794e2340276SBjoern A. Zeeb static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, 2795e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy, 2796e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 2797e2340276SBjoern A. Zeeb { 2798e2340276SBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8851b_tssi_mv_avg_defs_a_tbl); 2799e2340276SBjoern A. Zeeb } 2800e2340276SBjoern A. Zeeb 2801e2340276SBjoern A. Zeeb static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 2802e2340276SBjoern A. Zeeb { 2803e2340276SBjoern A. Zeeb _tssi_set_tssi_track(rtwdev, phy, RF_PATH_A); 2804e2340276SBjoern A. Zeeb _tssi_set_txagc_offset_mv_avg(rtwdev, phy, RF_PATH_A); 2805e2340276SBjoern A. Zeeb 2806e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x0); 2807e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); 2808e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x1); 2809e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_TXGA_V1, RR_TXGA_V1_TRK_EN, 0x1); 2810e2340276SBjoern A. Zeeb 2811e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 2812e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_RFC, 0x3); 2813e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); 2814e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 2815e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); 2816e2340276SBjoern A. Zeeb 2817e2340276SBjoern A. Zeeb rtwdev->is_tssi_mode[RF_PATH_A] = true; 2818e2340276SBjoern A. Zeeb } 2819e2340276SBjoern A. Zeeb 2820e2340276SBjoern A. Zeeb static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 2821e2340276SBjoern A. Zeeb { 2822e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_EN, 0x0); 2823e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 2824e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); 2825e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 2826e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_CLR, 0x1); 2827e2340276SBjoern A. Zeeb 2828e2340276SBjoern A. Zeeb rtwdev->is_tssi_mode[RF_PATH_A] = false; 2829e2340276SBjoern A. Zeeb } 2830e2340276SBjoern A. Zeeb 2831e2340276SBjoern A. Zeeb static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) 2832e2340276SBjoern A. Zeeb { 2833e2340276SBjoern A. Zeeb switch (ch) { 2834e2340276SBjoern A. Zeeb case 1 ... 2: 2835e2340276SBjoern A. Zeeb return 0; 2836e2340276SBjoern A. Zeeb case 3 ... 5: 2837e2340276SBjoern A. Zeeb return 1; 2838e2340276SBjoern A. Zeeb case 6 ... 8: 2839e2340276SBjoern A. Zeeb return 2; 2840e2340276SBjoern A. Zeeb case 9 ... 11: 2841e2340276SBjoern A. Zeeb return 3; 2842e2340276SBjoern A. Zeeb case 12 ... 13: 2843e2340276SBjoern A. Zeeb return 4; 2844e2340276SBjoern A. Zeeb case 14: 2845e2340276SBjoern A. Zeeb return 5; 2846e2340276SBjoern A. Zeeb } 2847e2340276SBjoern A. Zeeb 2848e2340276SBjoern A. Zeeb return 0; 2849e2340276SBjoern A. Zeeb } 2850e2340276SBjoern A. Zeeb 2851e2340276SBjoern A. Zeeb #define TSSI_EXTRA_GROUP_BIT (BIT(31)) 2852e2340276SBjoern A. Zeeb #define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) 2853e2340276SBjoern A. Zeeb #define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) 2854e2340276SBjoern A. Zeeb #define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) 2855e2340276SBjoern A. Zeeb #define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) 2856e2340276SBjoern A. Zeeb 2857e2340276SBjoern A. Zeeb static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) 2858e2340276SBjoern A. Zeeb { 2859e2340276SBjoern A. Zeeb switch (ch) { 2860e2340276SBjoern A. Zeeb case 1 ... 2: 2861e2340276SBjoern A. Zeeb return 0; 2862e2340276SBjoern A. Zeeb case 3 ... 5: 2863e2340276SBjoern A. Zeeb return 1; 2864e2340276SBjoern A. Zeeb case 6 ... 8: 2865e2340276SBjoern A. Zeeb return 2; 2866e2340276SBjoern A. Zeeb case 9 ... 11: 2867e2340276SBjoern A. Zeeb return 3; 2868e2340276SBjoern A. Zeeb case 12 ... 14: 2869e2340276SBjoern A. Zeeb return 4; 2870e2340276SBjoern A. Zeeb case 36 ... 40: 2871e2340276SBjoern A. Zeeb return 5; 2872e2340276SBjoern A. Zeeb case 41 ... 43: 2873e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(5); 2874e2340276SBjoern A. Zeeb case 44 ... 48: 2875e2340276SBjoern A. Zeeb return 6; 2876e2340276SBjoern A. Zeeb case 49 ... 51: 2877e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(6); 2878e2340276SBjoern A. Zeeb case 52 ... 56: 2879e2340276SBjoern A. Zeeb return 7; 2880e2340276SBjoern A. Zeeb case 57 ... 59: 2881e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(7); 2882e2340276SBjoern A. Zeeb case 60 ... 64: 2883e2340276SBjoern A. Zeeb return 8; 2884e2340276SBjoern A. Zeeb case 100 ... 104: 2885e2340276SBjoern A. Zeeb return 9; 2886e2340276SBjoern A. Zeeb case 105 ... 107: 2887e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(9); 2888e2340276SBjoern A. Zeeb case 108 ... 112: 2889e2340276SBjoern A. Zeeb return 10; 2890e2340276SBjoern A. Zeeb case 113 ... 115: 2891e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(10); 2892e2340276SBjoern A. Zeeb case 116 ... 120: 2893e2340276SBjoern A. Zeeb return 11; 2894e2340276SBjoern A. Zeeb case 121 ... 123: 2895e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(11); 2896e2340276SBjoern A. Zeeb case 124 ... 128: 2897e2340276SBjoern A. Zeeb return 12; 2898e2340276SBjoern A. Zeeb case 129 ... 131: 2899e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(12); 2900e2340276SBjoern A. Zeeb case 132 ... 136: 2901e2340276SBjoern A. Zeeb return 13; 2902e2340276SBjoern A. Zeeb case 137 ... 139: 2903e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(13); 2904e2340276SBjoern A. Zeeb case 140 ... 144: 2905e2340276SBjoern A. Zeeb return 14; 2906e2340276SBjoern A. Zeeb case 149 ... 153: 2907e2340276SBjoern A. Zeeb return 15; 2908e2340276SBjoern A. Zeeb case 154 ... 156: 2909e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(15); 2910e2340276SBjoern A. Zeeb case 157 ... 161: 2911e2340276SBjoern A. Zeeb return 16; 2912e2340276SBjoern A. Zeeb case 162 ... 164: 2913e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(16); 2914e2340276SBjoern A. Zeeb case 165 ... 169: 2915e2340276SBjoern A. Zeeb return 17; 2916e2340276SBjoern A. Zeeb case 170 ... 172: 2917e2340276SBjoern A. Zeeb return TSSI_EXTRA_GROUP(17); 2918e2340276SBjoern A. Zeeb case 173 ... 177: 2919e2340276SBjoern A. Zeeb return 18; 2920e2340276SBjoern A. Zeeb } 2921e2340276SBjoern A. Zeeb 2922e2340276SBjoern A. Zeeb return 0; 2923e2340276SBjoern A. Zeeb } 2924e2340276SBjoern A. Zeeb 2925e2340276SBjoern A. Zeeb static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) 2926e2340276SBjoern A. Zeeb { 2927e2340276SBjoern A. Zeeb switch (ch) { 2928e2340276SBjoern A. Zeeb case 1 ... 8: 2929e2340276SBjoern A. Zeeb return 0; 2930e2340276SBjoern A. Zeeb case 9 ... 14: 2931e2340276SBjoern A. Zeeb return 1; 2932e2340276SBjoern A. Zeeb case 36 ... 48: 2933e2340276SBjoern A. Zeeb return 2; 2934e2340276SBjoern A. Zeeb case 52 ... 64: 2935e2340276SBjoern A. Zeeb return 3; 2936e2340276SBjoern A. Zeeb case 100 ... 112: 2937e2340276SBjoern A. Zeeb return 4; 2938e2340276SBjoern A. Zeeb case 116 ... 128: 2939e2340276SBjoern A. Zeeb return 5; 2940e2340276SBjoern A. Zeeb case 132 ... 144: 2941e2340276SBjoern A. Zeeb return 6; 2942e2340276SBjoern A. Zeeb case 149 ... 177: 2943e2340276SBjoern A. Zeeb return 7; 2944e2340276SBjoern A. Zeeb } 2945e2340276SBjoern A. Zeeb 2946e2340276SBjoern A. Zeeb return 0; 2947e2340276SBjoern A. Zeeb } 2948e2340276SBjoern A. Zeeb 2949e2340276SBjoern A. Zeeb static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2950*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 2951e2340276SBjoern A. Zeeb { 2952e2340276SBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 2953e2340276SBjoern A. Zeeb u32 gidx, gidx_1st, gidx_2nd; 2954e2340276SBjoern A. Zeeb u8 ch = chan->channel; 2955e2340276SBjoern A. Zeeb s8 de_1st; 2956e2340276SBjoern A. Zeeb s8 de_2nd; 2957e2340276SBjoern A. Zeeb s8 val; 2958e2340276SBjoern A. Zeeb 2959e2340276SBjoern A. Zeeb gidx = _tssi_get_ofdm_group(rtwdev, ch); 2960e2340276SBjoern A. Zeeb 2961e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2962e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", path, gidx); 2963e2340276SBjoern A. Zeeb 2964e2340276SBjoern A. Zeeb if (IS_TSSI_EXTRA_GROUP(gidx)) { 2965e2340276SBjoern A. Zeeb gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); 2966e2340276SBjoern A. Zeeb gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); 2967e2340276SBjoern A. Zeeb de_1st = tssi_info->tssi_mcs[path][gidx_1st]; 2968e2340276SBjoern A. Zeeb de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; 2969e2340276SBjoern A. Zeeb val = (de_1st + de_2nd) / 2; 2970e2340276SBjoern A. Zeeb 2971e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2972e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", 2973e2340276SBjoern A. Zeeb path, val, de_1st, de_2nd); 2974e2340276SBjoern A. Zeeb } else { 2975e2340276SBjoern A. Zeeb val = tssi_info->tssi_mcs[path][gidx]; 2976e2340276SBjoern A. Zeeb 2977e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2978e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); 2979e2340276SBjoern A. Zeeb } 2980e2340276SBjoern A. Zeeb 2981e2340276SBjoern A. Zeeb return val; 2982e2340276SBjoern A. Zeeb } 2983e2340276SBjoern A. Zeeb 2984e2340276SBjoern A. Zeeb static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2985*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 2986e2340276SBjoern A. Zeeb { 2987e2340276SBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 2988e2340276SBjoern A. Zeeb u32 tgidx, tgidx_1st, tgidx_2nd; 2989e2340276SBjoern A. Zeeb u8 ch = chan->channel; 2990e2340276SBjoern A. Zeeb s8 tde_1st; 2991e2340276SBjoern A. Zeeb s8 tde_2nd; 2992e2340276SBjoern A. Zeeb s8 val; 2993e2340276SBjoern A. Zeeb 2994e2340276SBjoern A. Zeeb tgidx = _tssi_get_trim_group(rtwdev, ch); 2995e2340276SBjoern A. Zeeb 2996e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 2997e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", 2998e2340276SBjoern A. Zeeb path, tgidx); 2999e2340276SBjoern A. Zeeb 3000e2340276SBjoern A. Zeeb if (IS_TSSI_EXTRA_GROUP(tgidx)) { 3001e2340276SBjoern A. Zeeb tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); 3002e2340276SBjoern A. Zeeb tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); 3003e2340276SBjoern A. Zeeb tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; 3004e2340276SBjoern A. Zeeb tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; 3005e2340276SBjoern A. Zeeb val = (tde_1st + tde_2nd) / 2; 3006e2340276SBjoern A. Zeeb 3007e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3008e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", 3009e2340276SBjoern A. Zeeb path, val, tde_1st, tde_2nd); 3010e2340276SBjoern A. Zeeb } else { 3011e2340276SBjoern A. Zeeb val = tssi_info->tssi_trim[path][tgidx]; 3012e2340276SBjoern A. Zeeb 3013e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3014e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", 3015e2340276SBjoern A. Zeeb path, val); 3016e2340276SBjoern A. Zeeb } 3017e2340276SBjoern A. Zeeb 3018e2340276SBjoern A. Zeeb return val; 3019e2340276SBjoern A. Zeeb } 3020e2340276SBjoern A. Zeeb 3021*df279a26SBjoern A. Zeeb static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3022*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 3023e2340276SBjoern A. Zeeb { 3024e2340276SBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 3025e2340276SBjoern A. Zeeb u8 ch = chan->channel; 3026e2340276SBjoern A. Zeeb u8 gidx; 3027e2340276SBjoern A. Zeeb s8 ofdm_de; 3028e2340276SBjoern A. Zeeb s8 trim_de; 3029e2340276SBjoern A. Zeeb s32 val; 3030e2340276SBjoern A. Zeeb u32 i; 3031e2340276SBjoern A. Zeeb 3032e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", 3033e2340276SBjoern A. Zeeb phy, ch); 3034e2340276SBjoern A. Zeeb 3035e2340276SBjoern A. Zeeb for (i = RF_PATH_A; i < RTW8851B_TSSI_PATH_NR; i++) { 3036e2340276SBjoern A. Zeeb gidx = _tssi_get_cck_group(rtwdev, ch); 3037*df279a26SBjoern A. Zeeb trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); 3038e2340276SBjoern A. Zeeb val = tssi_info->tssi_cck[i][gidx] + trim_de; 3039e2340276SBjoern A. Zeeb 3040e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3041e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", 3042e2340276SBjoern A. Zeeb i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); 3043e2340276SBjoern A. Zeeb 3044e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_long[i], _TSSI_DE_MASK, val); 3045e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_cck_short[i], _TSSI_DE_MASK, val); 3046e2340276SBjoern A. Zeeb 3047e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3048e2340276SBjoern A. Zeeb "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", 3049e2340276SBjoern A. Zeeb _tssi_de_cck_long[i], 3050e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, _tssi_de_cck_long[i], 3051e2340276SBjoern A. Zeeb _TSSI_DE_MASK)); 3052e2340276SBjoern A. Zeeb 3053*df279a26SBjoern A. Zeeb ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); 3054*df279a26SBjoern A. Zeeb trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); 3055e2340276SBjoern A. Zeeb val = ofdm_de + trim_de; 3056e2340276SBjoern A. Zeeb 3057e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3058e2340276SBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", 3059e2340276SBjoern A. Zeeb i, ofdm_de, trim_de); 3060e2340276SBjoern A. Zeeb 3061e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_20m[i], _TSSI_DE_MASK, val); 3062e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_40m[i], _TSSI_DE_MASK, val); 3063e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m[i], _TSSI_DE_MASK, val); 3064e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_80m_80m[i], _TSSI_DE_MASK, val); 3065e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_5m[i], _TSSI_DE_MASK, val); 3066e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, _tssi_de_mcs_10m[i], _TSSI_DE_MASK, val); 3067e2340276SBjoern A. Zeeb 3068e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 3069e2340276SBjoern A. Zeeb "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", 3070e2340276SBjoern A. Zeeb _tssi_de_mcs_20m[i], 3071e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, _tssi_de_mcs_20m[i], 3072e2340276SBjoern A. Zeeb _TSSI_DE_MASK)); 3073e2340276SBjoern A. Zeeb } 3074e2340276SBjoern A. Zeeb } 3075e2340276SBjoern A. Zeeb 3076e2340276SBjoern A. Zeeb static void _tssi_alimentk_dump_result(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 3077e2340276SBjoern A. Zeeb { 3078e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3079e2340276SBjoern A. Zeeb "[TSSI PA K]\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n" 3080e2340276SBjoern A. Zeeb "0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n0x%x = 0x%08x\n", 3081e2340276SBjoern A. Zeeb R_TSSI_PA_K1 + (path << 13), 3082e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K1 + (path << 13), MASKDWORD), 3083e2340276SBjoern A. Zeeb R_TSSI_PA_K2 + (path << 13), 3084e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K2 + (path << 13), MASKDWORD), 3085e2340276SBjoern A. Zeeb R_P0_TSSI_ALIM1 + (path << 13), 3086e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD), 3087e2340276SBjoern A. Zeeb R_P0_TSSI_ALIM3 + (path << 13), 3088e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD), 3089e2340276SBjoern A. Zeeb R_TSSI_PA_K5 + (path << 13), 3090e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K5 + (path << 13), MASKDWORD), 3091e2340276SBjoern A. Zeeb R_P0_TSSI_ALIM2 + (path << 13), 3092e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD), 3093e2340276SBjoern A. Zeeb R_P0_TSSI_ALIM4 + (path << 13), 3094e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD), 3095e2340276SBjoern A. Zeeb R_TSSI_PA_K8 + (path << 13), 3096e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TSSI_PA_K8 + (path << 13), MASKDWORD)); 3097e2340276SBjoern A. Zeeb } 3098e2340276SBjoern A. Zeeb 3099e2340276SBjoern A. Zeeb static void _tssi_alimentk_done(struct rtw89_dev *rtwdev, 3100*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, enum rtw89_rf_path path, 3101*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 3102e2340276SBjoern A. Zeeb { 3103e2340276SBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 3104e2340276SBjoern A. Zeeb u8 channel = chan->channel; 3105e2340276SBjoern A. Zeeb u8 band; 3106e2340276SBjoern A. Zeeb 3107e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3108e2340276SBjoern A. Zeeb "======>%s phy=%d path=%d\n", __func__, phy, path); 3109e2340276SBjoern A. Zeeb 3110e2340276SBjoern A. Zeeb if (channel >= 1 && channel <= 14) 3111e2340276SBjoern A. Zeeb band = TSSI_ALIMK_2G; 3112e2340276SBjoern A. Zeeb else if (channel >= 36 && channel <= 64) 3113e2340276SBjoern A. Zeeb band = TSSI_ALIMK_5GL; 3114e2340276SBjoern A. Zeeb else if (channel >= 100 && channel <= 144) 3115e2340276SBjoern A. Zeeb band = TSSI_ALIMK_5GM; 3116e2340276SBjoern A. Zeeb else if (channel >= 149 && channel <= 177) 3117e2340276SBjoern A. Zeeb band = TSSI_ALIMK_5GH; 3118e2340276SBjoern A. Zeeb else 3119e2340276SBjoern A. Zeeb band = TSSI_ALIMK_2G; 3120e2340276SBjoern A. Zeeb 3121e2340276SBjoern A. Zeeb if (tssi_info->alignment_done[path][band]) { 3122e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM1 + (path << 13), MASKDWORD, 3123e2340276SBjoern A. Zeeb tssi_info->alignment_value[path][band][0]); 3124e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM3 + (path << 13), MASKDWORD, 3125e2340276SBjoern A. Zeeb tssi_info->alignment_value[path][band][1]); 3126e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM2 + (path << 13), MASKDWORD, 3127e2340276SBjoern A. Zeeb tssi_info->alignment_value[path][band][2]); 3128e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_ALIM4 + (path << 13), MASKDWORD, 3129e2340276SBjoern A. Zeeb tssi_info->alignment_value[path][band][3]); 3130e2340276SBjoern A. Zeeb } 3131e2340276SBjoern A. Zeeb 3132e2340276SBjoern A. Zeeb _tssi_alimentk_dump_result(rtwdev, path); 3133e2340276SBjoern A. Zeeb } 3134e2340276SBjoern A. Zeeb 3135e2340276SBjoern A. Zeeb static void rtw8851b_by_rate_dpd(struct rtw89_dev *rtwdev) 3136e2340276SBjoern A. Zeeb { 3137e2340276SBjoern A. Zeeb rtw89_write32_mask(rtwdev, R_AX_PWR_SWING_OTHER_CTRL0, 3138e2340276SBjoern A. Zeeb B_AX_CFIR_BY_RATE_OFF_MASK, 0x21861); 3139e2340276SBjoern A. Zeeb } 3140e2340276SBjoern A. Zeeb 3141e2340276SBjoern A. Zeeb void rtw8851b_dpk_init(struct rtw89_dev *rtwdev) 3142e2340276SBjoern A. Zeeb { 3143e2340276SBjoern A. Zeeb rtw8851b_by_rate_dpd(rtwdev); 3144e2340276SBjoern A. Zeeb } 3145e2340276SBjoern A. Zeeb 3146e2340276SBjoern A. Zeeb void rtw8851b_aack(struct rtw89_dev *rtwdev) 3147e2340276SBjoern A. Zeeb { 3148e2340276SBjoern A. Zeeb u32 tmp05, tmpd3, ib[4]; 3149e2340276SBjoern A. Zeeb u32 tmp; 3150e2340276SBjoern A. Zeeb int ret; 3151e2340276SBjoern A. Zeeb int rek; 3152e2340276SBjoern A. Zeeb int i; 3153e2340276SBjoern A. Zeeb 3154e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO AACK\n"); 3155e2340276SBjoern A. Zeeb 3156e2340276SBjoern A. Zeeb tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); 3157e2340276SBjoern A. Zeeb tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); 3158e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); 3159e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); 3160e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_ST, 0x0); 3161e2340276SBjoern A. Zeeb 3162e2340276SBjoern A. Zeeb for (rek = 0; rek < 4; rek++) { 3163e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201e); 3164e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_AACK, RFREG_MASK, 0x8201f); 3165e2340276SBjoern A. Zeeb fsleep(100); 3166e2340276SBjoern A. Zeeb 3167e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp, 3168e2340276SBjoern A. Zeeb 1, 1000, false, 3169e2340276SBjoern A. Zeeb rtwdev, RF_PATH_A, 0xd0, BIT(16)); 3170e2340276SBjoern A. Zeeb if (ret) 3171e2340276SBjoern A. Zeeb rtw89_warn(rtwdev, "[LCK]AACK timeout\n"); 3172e2340276SBjoern A. Zeeb 3173e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x1); 3174e2340276SBjoern A. Zeeb for (i = 0; i < 4; i++) { 3175e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCO, RR_VCO_SEL, i); 3176e2340276SBjoern A. Zeeb ib[i] = rtw89_read_rf(rtwdev, RF_PATH_A, RR_IBD, RR_IBD_VAL); 3177e2340276SBjoern A. Zeeb } 3178e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_VCI, RR_VCI_ON, 0x0); 3179e2340276SBjoern A. Zeeb 3180e2340276SBjoern A. Zeeb if (ib[0] != 0 && ib[1] != 0 && ib[2] != 0 && ib[3] != 0) 3181e2340276SBjoern A. Zeeb break; 3182e2340276SBjoern A. Zeeb } 3183e2340276SBjoern A. Zeeb 3184e2340276SBjoern A. Zeeb if (rek != 0) 3185e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]AACK rek = %d\n", rek); 3186e2340276SBjoern A. Zeeb 3187e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); 3188e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); 3189e2340276SBjoern A. Zeeb } 3190e2340276SBjoern A. Zeeb 3191e2340276SBjoern A. Zeeb static void _lck_keep_thermal(struct rtw89_dev *rtwdev) 3192e2340276SBjoern A. Zeeb { 3193e2340276SBjoern A. Zeeb struct rtw89_lck_info *lck = &rtwdev->lck; 3194e2340276SBjoern A. Zeeb 3195e2340276SBjoern A. Zeeb lck->thermal[RF_PATH_A] = 3196e2340276SBjoern A. Zeeb ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); 3197e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 3198e2340276SBjoern A. Zeeb "[LCK] path=%d thermal=0x%x", RF_PATH_A, lck->thermal[RF_PATH_A]); 3199e2340276SBjoern A. Zeeb } 3200e2340276SBjoern A. Zeeb 3201e2340276SBjoern A. Zeeb static void rtw8851b_lck(struct rtw89_dev *rtwdev) 3202e2340276SBjoern A. Zeeb { 3203e2340276SBjoern A. Zeeb u32 tmp05, tmp18, tmpd3; 3204e2340276SBjoern A. Zeeb 3205e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]DO LCK\n"); 3206e2340276SBjoern A. Zeeb 3207e2340276SBjoern A. Zeeb tmp05 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK); 3208e2340276SBjoern A. Zeeb tmp18 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); 3209e2340276SBjoern A. Zeeb tmpd3 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK); 3210e2340276SBjoern A. Zeeb 3211e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RR_MOD_MASK, 0x3); 3212e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, 0x0); 3213e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); 3214e2340276SBjoern A. Zeeb 3215e2340276SBjoern A. Zeeb _set_ch(rtwdev, tmp18); 3216e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RFREG_MASK, tmpd3); 3217e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RFREG_MASK, tmp05); 3218e2340276SBjoern A. Zeeb 3219e2340276SBjoern A. Zeeb _lck_keep_thermal(rtwdev); 3220e2340276SBjoern A. Zeeb } 3221e2340276SBjoern A. Zeeb 3222e2340276SBjoern A. Zeeb #define RTW8851B_LCK_TH 8 3223e2340276SBjoern A. Zeeb 3224e2340276SBjoern A. Zeeb void rtw8851b_lck_track(struct rtw89_dev *rtwdev) 3225e2340276SBjoern A. Zeeb { 3226e2340276SBjoern A. Zeeb struct rtw89_lck_info *lck = &rtwdev->lck; 3227e2340276SBjoern A. Zeeb u8 cur_thermal; 3228e2340276SBjoern A. Zeeb int delta; 3229e2340276SBjoern A. Zeeb 3230e2340276SBjoern A. Zeeb cur_thermal = 3231e2340276SBjoern A. Zeeb ewma_thermal_read(&rtwdev->phystat.avg_thermal[RF_PATH_A]); 3232e2340276SBjoern A. Zeeb delta = abs((int)cur_thermal - lck->thermal[RF_PATH_A]); 3233e2340276SBjoern A. Zeeb 3234e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 3235e2340276SBjoern A. Zeeb "[LCK] path=%d current thermal=0x%x delta=0x%x\n", 3236e2340276SBjoern A. Zeeb RF_PATH_A, cur_thermal, delta); 3237e2340276SBjoern A. Zeeb 3238e2340276SBjoern A. Zeeb if (delta >= RTW8851B_LCK_TH) { 3239e2340276SBjoern A. Zeeb rtw8851b_aack(rtwdev); 3240e2340276SBjoern A. Zeeb rtw8851b_lck(rtwdev); 3241e2340276SBjoern A. Zeeb } 3242e2340276SBjoern A. Zeeb } 3243e2340276SBjoern A. Zeeb 3244e2340276SBjoern A. Zeeb void rtw8851b_lck_init(struct rtw89_dev *rtwdev) 3245e2340276SBjoern A. Zeeb { 3246e2340276SBjoern A. Zeeb _lck_keep_thermal(rtwdev); 3247e2340276SBjoern A. Zeeb } 3248e2340276SBjoern A. Zeeb 3249e2340276SBjoern A. Zeeb void rtw8851b_rck(struct rtw89_dev *rtwdev) 3250e2340276SBjoern A. Zeeb { 3251e2340276SBjoern A. Zeeb _rck(rtwdev, RF_PATH_A); 3252e2340276SBjoern A. Zeeb } 3253e2340276SBjoern A. Zeeb 3254e2340276SBjoern A. Zeeb void rtw8851b_dack(struct rtw89_dev *rtwdev) 3255e2340276SBjoern A. Zeeb { 3256e2340276SBjoern A. Zeeb _dac_cal(rtwdev, false); 3257e2340276SBjoern A. Zeeb } 3258e2340276SBjoern A. Zeeb 3259*df279a26SBjoern A. Zeeb void rtw8851b_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3260*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 3261e2340276SBjoern A. Zeeb { 3262*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 3263e2340276SBjoern A. Zeeb u32 tx_en; 3264e2340276SBjoern A. Zeeb 3265e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); 3266e2340276SBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 3267e2340276SBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 3268e2340276SBjoern A. Zeeb 3269e2340276SBjoern A. Zeeb _iqk_init(rtwdev); 3270*df279a26SBjoern A. Zeeb _iqk(rtwdev, phy_idx, false, chanctx_idx); 3271e2340276SBjoern A. Zeeb 3272e2340276SBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 3273e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); 3274e2340276SBjoern A. Zeeb } 3275e2340276SBjoern A. Zeeb 3276*df279a26SBjoern A. Zeeb void rtw8851b_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3277*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 3278e2340276SBjoern A. Zeeb { 3279*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 3280e2340276SBjoern A. Zeeb u32 tx_en; 3281e2340276SBjoern A. Zeeb 3282e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); 3283e2340276SBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 3284e2340276SBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 3285e2340276SBjoern A. Zeeb 3286*df279a26SBjoern A. Zeeb _rx_dck(rtwdev, phy_idx, false, chanctx_idx); 3287e2340276SBjoern A. Zeeb 3288e2340276SBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 3289e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); 3290e2340276SBjoern A. Zeeb } 3291e2340276SBjoern A. Zeeb 3292*df279a26SBjoern A. Zeeb void rtw8851b_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3293*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 3294e2340276SBjoern A. Zeeb { 3295*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 3296e2340276SBjoern A. Zeeb u32 tx_en; 3297e2340276SBjoern A. Zeeb 3298e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); 3299e2340276SBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 3300e2340276SBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 3301e2340276SBjoern A. Zeeb 3302e2340276SBjoern A. Zeeb rtwdev->dpk.is_dpk_enable = true; 3303e2340276SBjoern A. Zeeb rtwdev->dpk.is_dpk_reload_en = false; 3304*df279a26SBjoern A. Zeeb _dpk(rtwdev, phy_idx, false, chanctx_idx); 3305e2340276SBjoern A. Zeeb 3306e2340276SBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 3307e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); 3308e2340276SBjoern A. Zeeb } 3309e2340276SBjoern A. Zeeb 3310e2340276SBjoern A. Zeeb void rtw8851b_dpk_track(struct rtw89_dev *rtwdev) 3311e2340276SBjoern A. Zeeb { 3312e2340276SBjoern A. Zeeb _dpk_track(rtwdev); 3313e2340276SBjoern A. Zeeb } 3314e2340276SBjoern A. Zeeb 3315*df279a26SBjoern A. Zeeb void rtw8851b_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3316*df279a26SBjoern A. Zeeb bool hwtx_en, enum rtw89_chanctx_idx chanctx_idx) 3317e2340276SBjoern A. Zeeb { 3318*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 3319*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy, RF_A, chanctx_idx); 3320e2340276SBjoern A. Zeeb u8 i; 3321e2340276SBjoern A. Zeeb 3322e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", __func__, phy); 3323e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); 3324e2340276SBjoern A. Zeeb 3325e2340276SBjoern A. Zeeb _tssi_disable(rtwdev, phy); 3326e2340276SBjoern A. Zeeb 3327e2340276SBjoern A. Zeeb for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { 3328*df279a26SBjoern A. Zeeb _tssi_set_sys(rtwdev, phy, i, chan); 3329e2340276SBjoern A. Zeeb _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i); 3330e2340276SBjoern A. Zeeb _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); 3331e2340276SBjoern A. Zeeb _tssi_set_dck(rtwdev, phy, i); 3332*df279a26SBjoern A. Zeeb _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); 3333e2340276SBjoern A. Zeeb _tssi_set_dac_gain_tbl(rtwdev, phy, i); 3334*df279a26SBjoern A. Zeeb _tssi_slope_cal_org(rtwdev, phy, i, chan); 3335*df279a26SBjoern A. Zeeb _tssi_alignment_default(rtwdev, phy, i, true, chan); 3336e2340276SBjoern A. Zeeb _tssi_set_tssi_slope(rtwdev, phy, i); 3337e2340276SBjoern A. Zeeb } 3338e2340276SBjoern A. Zeeb 3339e2340276SBjoern A. Zeeb _tssi_enable(rtwdev, phy); 3340*df279a26SBjoern A. Zeeb _tssi_set_efuse_to_de(rtwdev, phy, chan); 3341e2340276SBjoern A. Zeeb 3342e2340276SBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); 3343e2340276SBjoern A. Zeeb } 3344e2340276SBjoern A. Zeeb 3345*df279a26SBjoern A. Zeeb void rtw8851b_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3346*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 3347e2340276SBjoern A. Zeeb { 3348e2340276SBjoern A. Zeeb u8 channel = chan->channel; 3349e2340276SBjoern A. Zeeb u32 i; 3350e2340276SBjoern A. Zeeb 3351e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3352e2340276SBjoern A. Zeeb "======>%s phy=%d channel=%d\n", __func__, phy, channel); 3353e2340276SBjoern A. Zeeb 3354e2340276SBjoern A. Zeeb _tssi_disable(rtwdev, phy); 3355e2340276SBjoern A. Zeeb 3356e2340276SBjoern A. Zeeb for (i = RF_PATH_A; i < RF_PATH_NUM_8851B; i++) { 3357*df279a26SBjoern A. Zeeb _tssi_set_sys(rtwdev, phy, i, chan); 3358*df279a26SBjoern A. Zeeb _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); 3359*df279a26SBjoern A. Zeeb _tssi_slope_cal_org(rtwdev, phy, i, chan); 3360*df279a26SBjoern A. Zeeb _tssi_alignment_default(rtwdev, phy, i, true, chan); 3361e2340276SBjoern A. Zeeb } 3362e2340276SBjoern A. Zeeb 3363e2340276SBjoern A. Zeeb _tssi_enable(rtwdev, phy); 3364*df279a26SBjoern A. Zeeb _tssi_set_efuse_to_de(rtwdev, phy, chan); 3365e2340276SBjoern A. Zeeb } 3366e2340276SBjoern A. Zeeb 3367e2340276SBjoern A. Zeeb static void rtw8851b_tssi_default_txagc(struct rtw89_dev *rtwdev, 3368*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, bool enable, 3369*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 3370e2340276SBjoern A. Zeeb { 3371*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 3372e2340276SBjoern A. Zeeb u8 channel = chan->channel; 3373e2340276SBjoern A. Zeeb 3374e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "======> %s ch=%d\n", 3375e2340276SBjoern A. Zeeb __func__, channel); 3376e2340276SBjoern A. Zeeb 3377e2340276SBjoern A. Zeeb if (enable) 3378e2340276SBjoern A. Zeeb return; 3379e2340276SBjoern A. Zeeb 3380e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3381e2340276SBjoern A. Zeeb "======>%s 1 SCAN_END Set 0x5818[7:0]=0x%x\n", 3382e2340276SBjoern A. Zeeb __func__, 3383e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); 3384e2340276SBjoern A. Zeeb 3385e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 0xc0); 3386e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 3387e2340276SBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); 3388e2340276SBjoern A. Zeeb 3389*df279a26SBjoern A. Zeeb _tssi_alimentk_done(rtwdev, phy, RF_PATH_A, chan); 3390e2340276SBjoern A. Zeeb 3391e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3392e2340276SBjoern A. Zeeb "======>%s 2 SCAN_END Set 0x5818[7:0]=0x%x\n", 3393e2340276SBjoern A. Zeeb __func__, 3394e2340276SBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT)); 3395e2340276SBjoern A. Zeeb 3396e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3397e2340276SBjoern A. Zeeb "======> %s SCAN_END\n", __func__); 3398e2340276SBjoern A. Zeeb } 3399e2340276SBjoern A. Zeeb 3400e2340276SBjoern A. Zeeb void rtw8851b_wifi_scan_notify(struct rtw89_dev *rtwdev, bool scan_start, 3401*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, 3402*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 3403e2340276SBjoern A. Zeeb { 3404e2340276SBjoern A. Zeeb if (scan_start) 3405*df279a26SBjoern A. Zeeb rtw8851b_tssi_default_txagc(rtwdev, phy_idx, true, chanctx_idx); 3406e2340276SBjoern A. Zeeb else 3407*df279a26SBjoern A. Zeeb rtw8851b_tssi_default_txagc(rtwdev, phy_idx, false, chanctx_idx); 3408e2340276SBjoern A. Zeeb } 3409e2340276SBjoern A. Zeeb 3410e2340276SBjoern A. Zeeb static void _bw_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 3411e2340276SBjoern A. Zeeb enum rtw89_bandwidth bw, bool dav) 3412e2340276SBjoern A. Zeeb { 3413e2340276SBjoern A. Zeeb u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; 3414e2340276SBjoern A. Zeeb u32 rf_reg18; 3415e2340276SBjoern A. Zeeb 3416e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); 3417e2340276SBjoern A. Zeeb 3418e2340276SBjoern A. Zeeb rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); 3419e2340276SBjoern A. Zeeb if (rf_reg18 == INV_RF_DATA) { 3420e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3421e2340276SBjoern A. Zeeb "[RFK]Invalid RF_0x18 for Path-%d\n", path); 3422e2340276SBjoern A. Zeeb return; 3423e2340276SBjoern A. Zeeb } 3424e2340276SBjoern A. Zeeb rf_reg18 &= ~RR_CFGCH_BW; 3425e2340276SBjoern A. Zeeb 3426e2340276SBjoern A. Zeeb switch (bw) { 3427e2340276SBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_5: 3428e2340276SBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_10: 3429e2340276SBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_20: 3430e2340276SBjoern A. Zeeb rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_20M); 3431e2340276SBjoern A. Zeeb break; 3432e2340276SBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_40: 3433e2340276SBjoern A. Zeeb rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_40M); 3434e2340276SBjoern A. Zeeb break; 3435e2340276SBjoern A. Zeeb case RTW89_CHANNEL_WIDTH_80: 3436e2340276SBjoern A. Zeeb rf_reg18 |= FIELD_PREP(RR_CFGCH_BW, CFGCH_BW_80M); 3437e2340276SBjoern A. Zeeb break; 3438e2340276SBjoern A. Zeeb default: 3439e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]Fail to set CH\n"); 3440e2340276SBjoern A. Zeeb } 3441e2340276SBjoern A. Zeeb 3442e2340276SBjoern A. Zeeb rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | 3443e2340276SBjoern A. Zeeb RR_CFGCH_BW2) & RFREG_MASK; 3444e2340276SBjoern A. Zeeb rf_reg18 |= RR_CFGCH_BW2; 3445e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); 3446e2340276SBjoern A. Zeeb 3447e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set %x at path%d, %x =0x%x\n", 3448e2340276SBjoern A. Zeeb bw, path, reg18_addr, 3449e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); 3450e2340276SBjoern A. Zeeb } 3451e2340276SBjoern A. Zeeb 3452e2340276SBjoern A. Zeeb static void _ctrl_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3453e2340276SBjoern A. Zeeb enum rtw89_bandwidth bw) 3454e2340276SBjoern A. Zeeb { 3455e2340276SBjoern A. Zeeb _bw_setting(rtwdev, RF_PATH_A, bw, true); 3456e2340276SBjoern A. Zeeb _bw_setting(rtwdev, RF_PATH_A, bw, false); 3457e2340276SBjoern A. Zeeb } 3458e2340276SBjoern A. Zeeb 3459e2340276SBjoern A. Zeeb static bool _set_s0_arfc18(struct rtw89_dev *rtwdev, u32 val) 3460e2340276SBjoern A. Zeeb { 3461e2340276SBjoern A. Zeeb u32 bak; 3462e2340276SBjoern A. Zeeb u32 tmp; 3463e2340276SBjoern A. Zeeb int ret; 3464e2340276SBjoern A. Zeeb 3465e2340276SBjoern A. Zeeb bak = rtw89_read_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK); 3466e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RR_LDO_SEL, 0x1); 3467e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK, val); 3468e2340276SBjoern A. Zeeb 3469e2340276SBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, tmp, tmp == 0, 1, 1000, 3470e2340276SBjoern A. Zeeb false, rtwdev, RF_PATH_A, RR_LPF, RR_LPF_BUSY); 3471e2340276SBjoern A. Zeeb if (ret) 3472e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]LCK timeout\n"); 3473e2340276SBjoern A. Zeeb 3474e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LDO, RFREG_MASK, bak); 3475e2340276SBjoern A. Zeeb 3476e2340276SBjoern A. Zeeb return !!ret; 3477e2340276SBjoern A. Zeeb } 3478e2340276SBjoern A. Zeeb 3479e2340276SBjoern A. Zeeb static void _lck_check(struct rtw89_dev *rtwdev) 3480e2340276SBjoern A. Zeeb { 3481e2340276SBjoern A. Zeeb u32 tmp; 3482e2340276SBjoern A. Zeeb 3483e2340276SBjoern A. Zeeb if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { 3484e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN MMD reset\n"); 3485e2340276SBjoern A. Zeeb 3486e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x1); 3487e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x0); 3488e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_SYN, 0x1); 3489e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MMD, RR_MMD_RST_EN, 0x0); 3490e2340276SBjoern A. Zeeb } 3491e2340276SBjoern A. Zeeb 3492e2340276SBjoern A. Zeeb udelay(10); 3493e2340276SBjoern A. Zeeb 3494e2340276SBjoern A. Zeeb if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { 3495e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]re-set RF 0x18\n"); 3496e2340276SBjoern A. Zeeb 3497e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); 3498e2340276SBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); 3499e2340276SBjoern A. Zeeb _set_s0_arfc18(rtwdev, tmp); 3500e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); 3501e2340276SBjoern A. Zeeb } 3502e2340276SBjoern A. Zeeb 3503e2340276SBjoern A. Zeeb if (rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RR_SYNFB_LK) == 0) { 3504e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]SYN off/on\n"); 3505e2340276SBjoern A. Zeeb 3506e2340276SBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK); 3507e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RFREG_MASK, tmp); 3508e2340276SBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK); 3509e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_SX, RFREG_MASK, tmp); 3510e2340276SBjoern A. Zeeb 3511e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x1); 3512e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); 3513e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); 3514e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_SYNLUT, RR_SYNLUT_MOD, 0x0); 3515e2340276SBjoern A. Zeeb 3516e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x1); 3517e2340276SBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, RF_PATH_A, RR_CFGCH, RFREG_MASK); 3518e2340276SBjoern A. Zeeb _set_s0_arfc18(rtwdev, tmp); 3519e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_LCK_TRG, RR_LCK_TRGSEL, 0x0); 3520e2340276SBjoern A. Zeeb 3521e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[LCK]0xb2=%x, 0xc5=%x\n", 3522e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_VCO, RFREG_MASK), 3523e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, RF_PATH_A, RR_SYNFB, RFREG_MASK)); 3524e2340276SBjoern A. Zeeb } 3525e2340276SBjoern A. Zeeb } 3526e2340276SBjoern A. Zeeb 3527e2340276SBjoern A. Zeeb static void _set_ch(struct rtw89_dev *rtwdev, u32 val) 3528e2340276SBjoern A. Zeeb { 3529e2340276SBjoern A. Zeeb bool timeout; 3530e2340276SBjoern A. Zeeb 3531e2340276SBjoern A. Zeeb timeout = _set_s0_arfc18(rtwdev, val); 3532e2340276SBjoern A. Zeeb if (!timeout) 3533e2340276SBjoern A. Zeeb _lck_check(rtwdev); 3534e2340276SBjoern A. Zeeb } 3535e2340276SBjoern A. Zeeb 3536e2340276SBjoern A. Zeeb static void _ch_setting(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, 3537e2340276SBjoern A. Zeeb u8 central_ch, bool dav) 3538e2340276SBjoern A. Zeeb { 3539e2340276SBjoern A. Zeeb u32 reg18_addr = dav ? RR_CFGCH : RR_CFGCH_V1; 3540e2340276SBjoern A. Zeeb bool is_2g_ch = central_ch <= 14; 3541e2340276SBjoern A. Zeeb u32 rf_reg18; 3542e2340276SBjoern A. Zeeb 3543e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]===> %s\n", __func__); 3544e2340276SBjoern A. Zeeb 3545e2340276SBjoern A. Zeeb rf_reg18 = rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK); 3546e2340276SBjoern A. Zeeb rf_reg18 &= ~(RR_CFGCH_BAND1 | RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | 3547e2340276SBjoern A. Zeeb RR_CFGCH_BCN | RR_CFGCH_BAND0 | RR_CFGCH_CH); 3548e2340276SBjoern A. Zeeb rf_reg18 |= FIELD_PREP(RR_CFGCH_CH, central_ch); 3549e2340276SBjoern A. Zeeb 3550e2340276SBjoern A. Zeeb if (!is_2g_ch) 3551e2340276SBjoern A. Zeeb rf_reg18 |= FIELD_PREP(RR_CFGCH_BAND1, CFGCH_BAND1_5G) | 3552e2340276SBjoern A. Zeeb FIELD_PREP(RR_CFGCH_BAND0, CFGCH_BAND0_5G); 3553e2340276SBjoern A. Zeeb 3554e2340276SBjoern A. Zeeb rf_reg18 &= ~(RR_CFGCH_POW_LCK | RR_CFGCH_TRX_AH | RR_CFGCH_BCN | 3555e2340276SBjoern A. Zeeb RR_CFGCH_BW2) & RFREG_MASK; 3556e2340276SBjoern A. Zeeb rf_reg18 |= RR_CFGCH_BW2; 3557e2340276SBjoern A. Zeeb 3558e2340276SBjoern A. Zeeb if (path == RF_PATH_A && dav) 3559e2340276SBjoern A. Zeeb _set_ch(rtwdev, rf_reg18); 3560e2340276SBjoern A. Zeeb else 3561e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, reg18_addr, RFREG_MASK, rf_reg18); 3562e2340276SBjoern A. Zeeb 3563e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 0); 3564e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LCKST, RR_LCKST_BIN, 1); 3565e2340276SBjoern A. Zeeb 3566e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3567e2340276SBjoern A. Zeeb "[RFK]CH: %d for Path-%d, reg0x%x = 0x%x\n", 3568e2340276SBjoern A. Zeeb central_ch, path, reg18_addr, 3569e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, reg18_addr, RFREG_MASK)); 3570e2340276SBjoern A. Zeeb } 3571e2340276SBjoern A. Zeeb 3572e2340276SBjoern A. Zeeb static void _ctrl_ch(struct rtw89_dev *rtwdev, u8 central_ch) 3573e2340276SBjoern A. Zeeb { 3574e2340276SBjoern A. Zeeb _ch_setting(rtwdev, RF_PATH_A, central_ch, true); 3575e2340276SBjoern A. Zeeb _ch_setting(rtwdev, RF_PATH_A, central_ch, false); 3576e2340276SBjoern A. Zeeb } 3577e2340276SBjoern A. Zeeb 3578e2340276SBjoern A. Zeeb static void _set_rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_bandwidth bw, 3579e2340276SBjoern A. Zeeb enum rtw89_rf_path path) 3580e2340276SBjoern A. Zeeb { 3581e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x1); 3582e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_M2, 0x12); 3583e2340276SBjoern A. Zeeb 3584e2340276SBjoern A. Zeeb if (bw == RTW89_CHANNEL_WIDTH_20) 3585e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x1b); 3586e2340276SBjoern A. Zeeb else if (bw == RTW89_CHANNEL_WIDTH_40) 3587e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x13); 3588e2340276SBjoern A. Zeeb else if (bw == RTW89_CHANNEL_WIDTH_80) 3589e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0xb); 3590e2340276SBjoern A. Zeeb else 3591e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB, 0x3); 3592e2340276SBjoern A. Zeeb 3593e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK] set S%d RXBB BW 0x3F = 0x%x\n", path, 3594e2340276SBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_LUTWD0, RR_LUTWD0_LB)); 3595e2340276SBjoern A. Zeeb 3596e2340276SBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE2, RR_LUTWE2_RTXBW, 0x0); 3597e2340276SBjoern A. Zeeb } 3598e2340276SBjoern A. Zeeb 3599e2340276SBjoern A. Zeeb static void _rxbb_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3600e2340276SBjoern A. Zeeb enum rtw89_bandwidth bw) 3601e2340276SBjoern A. Zeeb { 3602e2340276SBjoern A. Zeeb u8 kpath, path; 3603e2340276SBjoern A. Zeeb 3604e2340276SBjoern A. Zeeb kpath = _kpath(rtwdev, phy); 3605e2340276SBjoern A. Zeeb 3606e2340276SBjoern A. Zeeb for (path = 0; path < RF_PATH_NUM_8851B; path++) { 3607e2340276SBjoern A. Zeeb if (!(kpath & BIT(path))) 3608e2340276SBjoern A. Zeeb continue; 3609e2340276SBjoern A. Zeeb 3610e2340276SBjoern A. Zeeb _set_rxbb_bw(rtwdev, bw, path); 3611e2340276SBjoern A. Zeeb } 3612e2340276SBjoern A. Zeeb } 3613e2340276SBjoern A. Zeeb 3614e2340276SBjoern A. Zeeb static void rtw8851b_ctrl_bw_ch(struct rtw89_dev *rtwdev, 3615e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy, u8 central_ch, 3616e2340276SBjoern A. Zeeb enum rtw89_band band, enum rtw89_bandwidth bw) 3617e2340276SBjoern A. Zeeb { 3618e2340276SBjoern A. Zeeb _ctrl_ch(rtwdev, central_ch); 3619e2340276SBjoern A. Zeeb _ctrl_bw(rtwdev, phy, bw); 3620e2340276SBjoern A. Zeeb _rxbb_bw(rtwdev, phy, bw); 3621e2340276SBjoern A. Zeeb } 3622e2340276SBjoern A. Zeeb 3623e2340276SBjoern A. Zeeb void rtw8851b_set_channel_rf(struct rtw89_dev *rtwdev, 3624e2340276SBjoern A. Zeeb const struct rtw89_chan *chan, 3625e2340276SBjoern A. Zeeb enum rtw89_phy_idx phy_idx) 3626e2340276SBjoern A. Zeeb { 3627e2340276SBjoern A. Zeeb rtw8851b_ctrl_bw_ch(rtwdev, phy_idx, chan->channel, chan->band_type, 3628e2340276SBjoern A. Zeeb chan->band_width); 3629e2340276SBjoern A. Zeeb } 3630