18e93258fSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 28e93258fSBjoern A. Zeeb /* Copyright(c) 2019-2020 Realtek Corporation 38e93258fSBjoern A. Zeeb */ 48e93258fSBjoern A. Zeeb 58e93258fSBjoern A. Zeeb #include "coex.h" 68e93258fSBjoern A. Zeeb #include "debug.h" 78e93258fSBjoern A. Zeeb #include "mac.h" 88e93258fSBjoern A. Zeeb #include "phy.h" 98e93258fSBjoern A. Zeeb #include "reg.h" 108e93258fSBjoern A. Zeeb #include "rtw8852a.h" 118e93258fSBjoern A. Zeeb #include "rtw8852a_rfk.h" 128e93258fSBjoern A. Zeeb #include "rtw8852a_rfk_table.h" 138e93258fSBjoern A. Zeeb #include "rtw8852a_table.h" 148e93258fSBjoern A. Zeeb 158e93258fSBjoern A. Zeeb static u8 _kpath(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 168e93258fSBjoern A. Zeeb { 178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RFK]dbcc_en: %x, PHY%d\n", 188e93258fSBjoern A. Zeeb rtwdev->dbcc_en, phy_idx); 198e93258fSBjoern A. Zeeb 208e93258fSBjoern A. Zeeb if (!rtwdev->dbcc_en) 218e93258fSBjoern A. Zeeb return RF_AB; 228e93258fSBjoern A. Zeeb 238e93258fSBjoern A. Zeeb if (phy_idx == RTW89_PHY_0) 248e93258fSBjoern A. Zeeb return RF_A; 258e93258fSBjoern A. Zeeb else 268e93258fSBjoern A. Zeeb return RF_B; 278e93258fSBjoern A. Zeeb } 288e93258fSBjoern A. Zeeb 298e93258fSBjoern A. Zeeb static const u32 rtw8852a_backup_bb_regs[] = {0x2344, 0x58f0, 0x78f0}; 308e93258fSBjoern A. Zeeb static const u32 rtw8852a_backup_rf_regs[] = {0xef, 0xde, 0x0, 0x1e, 0x2, 0x85, 0x90, 0x5}; 318e93258fSBjoern A. Zeeb #define BACKUP_BB_REGS_NR ARRAY_SIZE(rtw8852a_backup_bb_regs) 328e93258fSBjoern A. Zeeb #define BACKUP_RF_REGS_NR ARRAY_SIZE(rtw8852a_backup_rf_regs) 338e93258fSBjoern A. Zeeb 348e93258fSBjoern A. Zeeb static void _rfk_backup_bb_reg(struct rtw89_dev *rtwdev, u32 backup_bb_reg_val[]) 358e93258fSBjoern A. Zeeb { 368e93258fSBjoern A. Zeeb u32 i; 378e93258fSBjoern A. Zeeb 388e93258fSBjoern A. Zeeb for (i = 0; i < BACKUP_BB_REGS_NR; i++) { 398e93258fSBjoern A. Zeeb backup_bb_reg_val[i] = 408e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, rtw8852a_backup_bb_regs[i], 418e93258fSBjoern A. Zeeb MASKDWORD); 428e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 438e93258fSBjoern A. Zeeb "[IQK]backup bb reg : %x, value =%x\n", 448e93258fSBjoern A. Zeeb rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); 458e93258fSBjoern A. Zeeb } 468e93258fSBjoern A. Zeeb } 478e93258fSBjoern A. Zeeb 488e93258fSBjoern A. Zeeb static void _rfk_backup_rf_reg(struct rtw89_dev *rtwdev, u32 backup_rf_reg_val[], 498e93258fSBjoern A. Zeeb u8 rf_path) 508e93258fSBjoern A. Zeeb { 518e93258fSBjoern A. Zeeb u32 i; 528e93258fSBjoern A. Zeeb 538e93258fSBjoern A. Zeeb for (i = 0; i < BACKUP_RF_REGS_NR; i++) { 548e93258fSBjoern A. Zeeb backup_rf_reg_val[i] = 558e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, rf_path, 568e93258fSBjoern A. Zeeb rtw8852a_backup_rf_regs[i], RFREG_MASK); 578e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 588e93258fSBjoern A. Zeeb "[IQK]backup rf S%d reg : %x, value =%x\n", rf_path, 598e93258fSBjoern A. Zeeb rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); 608e93258fSBjoern A. Zeeb } 618e93258fSBjoern A. Zeeb } 628e93258fSBjoern A. Zeeb 638e93258fSBjoern A. Zeeb static void _rfk_restore_bb_reg(struct rtw89_dev *rtwdev, 648e93258fSBjoern A. Zeeb u32 backup_bb_reg_val[]) 658e93258fSBjoern A. Zeeb { 668e93258fSBjoern A. Zeeb u32 i; 678e93258fSBjoern A. Zeeb 688e93258fSBjoern A. Zeeb for (i = 0; i < BACKUP_BB_REGS_NR; i++) { 698e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, rtw8852a_backup_bb_regs[i], 708e93258fSBjoern A. Zeeb MASKDWORD, backup_bb_reg_val[i]); 718e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 728e93258fSBjoern A. Zeeb "[IQK]restore bb reg : %x, value =%x\n", 738e93258fSBjoern A. Zeeb rtw8852a_backup_bb_regs[i], backup_bb_reg_val[i]); 748e93258fSBjoern A. Zeeb } 758e93258fSBjoern A. Zeeb } 768e93258fSBjoern A. Zeeb 778e93258fSBjoern A. Zeeb static void _rfk_restore_rf_reg(struct rtw89_dev *rtwdev, 788e93258fSBjoern A. Zeeb u32 backup_rf_reg_val[], u8 rf_path) 798e93258fSBjoern A. Zeeb { 808e93258fSBjoern A. Zeeb u32 i; 818e93258fSBjoern A. Zeeb 828e93258fSBjoern A. Zeeb for (i = 0; i < BACKUP_RF_REGS_NR; i++) { 838e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, rf_path, rtw8852a_backup_rf_regs[i], 848e93258fSBjoern A. Zeeb RFREG_MASK, backup_rf_reg_val[i]); 858e93258fSBjoern A. Zeeb 868e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 878e93258fSBjoern A. Zeeb "[IQK]restore rf S%d reg: %x, value =%x\n", rf_path, 888e93258fSBjoern A. Zeeb rtw8852a_backup_rf_regs[i], backup_rf_reg_val[i]); 898e93258fSBjoern A. Zeeb } 908e93258fSBjoern A. Zeeb } 918e93258fSBjoern A. Zeeb 928e93258fSBjoern A. Zeeb static void _wait_rx_mode(struct rtw89_dev *rtwdev, u8 kpath) 938e93258fSBjoern A. Zeeb { 948e93258fSBjoern A. Zeeb u8 path; 958e93258fSBjoern A. Zeeb u32 rf_mode; 968e93258fSBjoern A. Zeeb int ret; 978e93258fSBjoern A. Zeeb 988e93258fSBjoern A. Zeeb for (path = 0; path < RF_PATH_MAX; path++) { 998e93258fSBjoern A. Zeeb if (!(kpath & BIT(path))) 1008e93258fSBjoern A. Zeeb continue; 1018e93258fSBjoern A. Zeeb 1028e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, rf_mode, rf_mode != 2, 1038e93258fSBjoern A. Zeeb 2, 5000, false, rtwdev, path, 0x00, 1048e93258fSBjoern A. Zeeb RR_MOD_MASK); 1058e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1068e93258fSBjoern A. Zeeb "[RFK] Wait S%d to Rx mode!! (ret = %d)\n", 1078e93258fSBjoern A. Zeeb path, ret); 1088e93258fSBjoern A. Zeeb } 1098e93258fSBjoern A. Zeeb } 1108e93258fSBjoern A. Zeeb 1118e93258fSBjoern A. Zeeb static void _dack_dump(struct rtw89_dev *rtwdev) 1128e93258fSBjoern A. Zeeb { 1138e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 1148e93258fSBjoern A. Zeeb u8 i; 1158e93258fSBjoern A. Zeeb u8 t; 1168e93258fSBjoern A. Zeeb 1178e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1188e93258fSBjoern A. Zeeb "[DACK]S0 ADC_DCK ic = 0x%x, qc = 0x%x\n", 1198e93258fSBjoern A. Zeeb dack->addck_d[0][0], dack->addck_d[0][1]); 1208e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1218e93258fSBjoern A. Zeeb "[DACK]S1 ADC_DCK ic = 0x%x, qc = 0x%x\n", 1228e93258fSBjoern A. Zeeb dack->addck_d[1][0], dack->addck_d[1][1]); 1238e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1248e93258fSBjoern A. Zeeb "[DACK]S0 DAC_DCK ic = 0x%x, qc = 0x%x\n", 1258e93258fSBjoern A. Zeeb dack->dadck_d[0][0], dack->dadck_d[0][1]); 1268e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1278e93258fSBjoern A. Zeeb "[DACK]S1 DAC_DCK ic = 0x%x, qc = 0x%x\n", 1288e93258fSBjoern A. Zeeb dack->dadck_d[1][0], dack->dadck_d[1][1]); 1298e93258fSBjoern A. Zeeb 1308e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1318e93258fSBjoern A. Zeeb "[DACK]S0 biask ic = 0x%x, qc = 0x%x\n", 1328e93258fSBjoern A. Zeeb dack->biask_d[0][0], dack->biask_d[0][1]); 1338e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1348e93258fSBjoern A. Zeeb "[DACK]S1 biask ic = 0x%x, qc = 0x%x\n", 1358e93258fSBjoern A. Zeeb dack->biask_d[1][0], dack->biask_d[1][1]); 1368e93258fSBjoern A. Zeeb 1378e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK ic:\n"); 1388e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 1398e93258fSBjoern A. Zeeb t = dack->msbk_d[0][0][i]; 1408e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 1418e93258fSBjoern A. Zeeb } 1428e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK qc:\n"); 1438e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 1448e93258fSBjoern A. Zeeb t = dack->msbk_d[0][1][i]; 1458e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 1468e93258fSBjoern A. Zeeb } 1478e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK ic:\n"); 1488e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 1498e93258fSBjoern A. Zeeb t = dack->msbk_d[1][0][i]; 1508e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 1518e93258fSBjoern A. Zeeb } 1528e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK qc:\n"); 1538e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 1548e93258fSBjoern A. Zeeb t = dack->msbk_d[1][1][i]; 1558e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x\n", t); 1568e93258fSBjoern A. Zeeb } 1578e93258fSBjoern A. Zeeb } 1588e93258fSBjoern A. Zeeb 1598e93258fSBjoern A. Zeeb static void _afe_init(struct rtw89_dev *rtwdev) 1608e93258fSBjoern A. Zeeb { 1618e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_afe_init_defs_tbl); 1628e93258fSBjoern A. Zeeb } 1638e93258fSBjoern A. Zeeb 1648e93258fSBjoern A. Zeeb static void _addck_backup(struct rtw89_dev *rtwdev) 1658e93258fSBjoern A. Zeeb { 1668e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 1678e93258fSBjoern A. Zeeb 1688e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_S0_RXDC2, B_S0_RXDC2_SEL); 1698e93258fSBjoern A. Zeeb dack->addck_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, 1708e93258fSBjoern A. Zeeb B_S0_ADDCK_Q); 1718e93258fSBjoern A. Zeeb dack->addck_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_ADDCK, 1728e93258fSBjoern A. Zeeb B_S0_ADDCK_I); 1738e93258fSBjoern A. Zeeb 1748e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_S1_RXDC2, B_S1_RXDC2_SEL); 1758e93258fSBjoern A. Zeeb dack->addck_d[1][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, 1768e93258fSBjoern A. Zeeb B_S1_ADDCK_Q); 1778e93258fSBjoern A. Zeeb dack->addck_d[1][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S1_ADDCK, 1788e93258fSBjoern A. Zeeb B_S1_ADDCK_I); 1798e93258fSBjoern A. Zeeb } 1808e93258fSBjoern A. Zeeb 1818e93258fSBjoern A. Zeeb static void _addck_reload(struct rtw89_dev *rtwdev) 1828e93258fSBjoern A. Zeeb { 1838e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 1848e93258fSBjoern A. Zeeb 1858e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_I, dack->addck_d[0][0]); 1868e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2, B_S0_RXDC2_Q2, 1878e93258fSBjoern A. Zeeb (dack->addck_d[0][1] >> 6)); 1888e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_RXDC, B_S0_RXDC_Q, 1898e93258fSBjoern A. Zeeb (dack->addck_d[0][1] & 0x3f)); 1908e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S0_RXDC2, B_S0_RXDC2_MEN); 1918e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_I, dack->addck_d[1][0]); 1928e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S1_RXDC2, B_S1_RXDC2_Q2, 1938e93258fSBjoern A. Zeeb (dack->addck_d[1][1] >> 6)); 1948e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S1_RXDC, B_S1_RXDC_Q, 1958e93258fSBjoern A. Zeeb (dack->addck_d[1][1] & 0x3f)); 1968e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S1_RXDC2, B_S1_RXDC2_EN); 1978e93258fSBjoern A. Zeeb } 1988e93258fSBjoern A. Zeeb 1998e93258fSBjoern A. Zeeb static void _dack_backup_s0(struct rtw89_dev *rtwdev) 2008e93258fSBjoern A. Zeeb { 2018e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 2028e93258fSBjoern A. Zeeb u8 i; 2038e93258fSBjoern A. Zeeb 2048e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S0_DACKI, B_S0_DACKI_EN); 2058e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S0_DACKQ, B_S0_DACKQ_EN); 2068e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); 2078e93258fSBjoern A. Zeeb 2088e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 2098e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_DACKI, B_S0_DACKI_AR, i); 2108e93258fSBjoern A. Zeeb dack->msbk_d[0][0][i] = 2118e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI7, B_S0_DACKI7_K); 2128e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_DACKQ, B_S0_DACKQ_AR, i); 2138e93258fSBjoern A. Zeeb dack->msbk_d[0][1][i] = 2148e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ7, B_S0_DACKQ7_K); 2158e93258fSBjoern A. Zeeb } 2168e93258fSBjoern A. Zeeb dack->biask_d[0][0] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI2, 2178e93258fSBjoern A. Zeeb B_S0_DACKI2_K); 2188e93258fSBjoern A. Zeeb dack->biask_d[0][1] = (u16)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ2, 2198e93258fSBjoern A. Zeeb B_S0_DACKQ2_K); 2208e93258fSBjoern A. Zeeb dack->dadck_d[0][0] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKI8, 2218e93258fSBjoern A. Zeeb B_S0_DACKI8_K) - 8; 2228e93258fSBjoern A. Zeeb dack->dadck_d[0][1] = (u8)rtw89_phy_read32_mask(rtwdev, R_S0_DACKQ8, 2238e93258fSBjoern A. Zeeb B_S0_DACKQ8_K) - 8; 2248e93258fSBjoern A. Zeeb } 2258e93258fSBjoern A. Zeeb 2268e93258fSBjoern A. Zeeb static void _dack_backup_s1(struct rtw89_dev *rtwdev) 2278e93258fSBjoern A. Zeeb { 2288e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 2298e93258fSBjoern A. Zeeb u8 i; 2308e93258fSBjoern A. Zeeb 2318e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S1_DACKI, B_S1_DACKI_EN); 2328e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S1_DACKQ, B_S1_DACKQ_EN); 2338e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); 2348e93258fSBjoern A. Zeeb 2358e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR; i++) { 2368e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S1_DACKI, B_S1_DACKI_AR, i); 2378e93258fSBjoern A. Zeeb dack->msbk_d[1][0][i] = 2388e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI7, B_S1_DACKI_K); 2398e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S1_DACKQ, B_S1_DACKQ_AR, i); 2408e93258fSBjoern A. Zeeb dack->msbk_d[1][1][i] = 2418e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ7, B_S1_DACKQ7_K); 2428e93258fSBjoern A. Zeeb } 2438e93258fSBjoern A. Zeeb dack->biask_d[1][0] = 2448e93258fSBjoern A. Zeeb (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI2, B_S1_DACKI2_K); 2458e93258fSBjoern A. Zeeb dack->biask_d[1][1] = 2468e93258fSBjoern A. Zeeb (u16)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ2, B_S1_DACKQ2_K); 2478e93258fSBjoern A. Zeeb dack->dadck_d[1][0] = 2488e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKI8, B_S1_DACKI8_K) - 8; 2498e93258fSBjoern A. Zeeb dack->dadck_d[1][1] = 2508e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, R_S1_DACKQ8, B_S1_DACKQ8_K) - 8; 2518e93258fSBjoern A. Zeeb } 2528e93258fSBjoern A. Zeeb 2538e93258fSBjoern A. Zeeb static void _dack_reload_by_path(struct rtw89_dev *rtwdev, 2548e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 index) 2558e93258fSBjoern A. Zeeb { 2568e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 2578e93258fSBjoern A. Zeeb u32 tmp = 0, tmp_offset, tmp_reg; 2588e93258fSBjoern A. Zeeb u8 i; 2598e93258fSBjoern A. Zeeb u32 idx_offset, path_offset; 2608e93258fSBjoern A. Zeeb 2618e93258fSBjoern A. Zeeb if (index == 0) 2628e93258fSBjoern A. Zeeb idx_offset = 0; 2638e93258fSBjoern A. Zeeb else 2648e93258fSBjoern A. Zeeb idx_offset = 0x50; 2658e93258fSBjoern A. Zeeb 2668e93258fSBjoern A. Zeeb if (path == RF_PATH_A) 2678e93258fSBjoern A. Zeeb path_offset = 0; 2688e93258fSBjoern A. Zeeb else 2698e93258fSBjoern A. Zeeb path_offset = 0x2000; 2708e93258fSBjoern A. Zeeb 2718e93258fSBjoern A. Zeeb tmp_offset = idx_offset + path_offset; 2728e93258fSBjoern A. Zeeb /* msbk_d: 15/14/13/12 */ 2738e93258fSBjoern A. Zeeb tmp = 0x0; 2748e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) 2758e93258fSBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 12] << (i * 8); 2768e93258fSBjoern A. Zeeb tmp_reg = 0x5e14 + tmp_offset; 2778e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, tmp_reg, tmp); 2788e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, 2798e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); 2808e93258fSBjoern A. Zeeb /* msbk_d: 11/10/9/8 */ 2818e93258fSBjoern A. Zeeb tmp = 0x0; 2828e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) 2838e93258fSBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 8] << (i * 8); 2848e93258fSBjoern A. Zeeb tmp_reg = 0x5e18 + tmp_offset; 2858e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, tmp_reg, tmp); 2868e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, 2878e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); 2888e93258fSBjoern A. Zeeb /* msbk_d: 7/6/5/4 */ 2898e93258fSBjoern A. Zeeb tmp = 0x0; 2908e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) 2918e93258fSBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i + 4] << (i * 8); 2928e93258fSBjoern A. Zeeb tmp_reg = 0x5e1c + tmp_offset; 2938e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, tmp_reg, tmp); 2948e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, 2958e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); 2968e93258fSBjoern A. Zeeb /* msbk_d: 3/2/1/0 */ 2978e93258fSBjoern A. Zeeb tmp = 0x0; 2988e93258fSBjoern A. Zeeb for (i = 0; i < RTW89_DACK_MSBK_NR / 4; i++) 2998e93258fSBjoern A. Zeeb tmp |= dack->msbk_d[path][index][i] << (i * 8); 3008e93258fSBjoern A. Zeeb tmp_reg = 0x5e20 + tmp_offset; 3018e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, tmp_reg, tmp); 3028e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]0x%x=0x%x\n", tmp_reg, 3038e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, tmp_reg, MASKDWORD)); 3048e93258fSBjoern A. Zeeb /* dadak_d/biask_d */ 3058e93258fSBjoern A. Zeeb tmp = 0x0; 3068e93258fSBjoern A. Zeeb tmp = (dack->biask_d[path][index] << 22) | 3078e93258fSBjoern A. Zeeb (dack->dadck_d[path][index] << 14); 3088e93258fSBjoern A. Zeeb tmp_reg = 0x5e24 + tmp_offset; 3098e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, tmp_reg, tmp); 3108e93258fSBjoern A. Zeeb } 3118e93258fSBjoern A. Zeeb 3128e93258fSBjoern A. Zeeb static void _dack_reload(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 3138e93258fSBjoern A. Zeeb { 3148e93258fSBjoern A. Zeeb u8 i; 3158e93258fSBjoern A. Zeeb 3168e93258fSBjoern A. Zeeb for (i = 0; i < 2; i++) 3178e93258fSBjoern A. Zeeb _dack_reload_by_path(rtwdev, path, i); 3188e93258fSBjoern A. Zeeb 3198e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 3208e93258fSBjoern A. Zeeb &rtw8852a_rfk_dack_reload_defs_a_tbl, 3218e93258fSBjoern A. Zeeb &rtw8852a_rfk_dack_reload_defs_b_tbl); 3228e93258fSBjoern A. Zeeb } 3238e93258fSBjoern A. Zeeb 3248e93258fSBjoern A. Zeeb #define ADDC_T_AVG 100 3258e93258fSBjoern A. Zeeb static void _check_addc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 3268e93258fSBjoern A. Zeeb { 3278e93258fSBjoern A. Zeeb s32 dc_re = 0, dc_im = 0; 3288e93258fSBjoern A. Zeeb u32 tmp; 3298e93258fSBjoern A. Zeeb u32 i; 3308e93258fSBjoern A. Zeeb 3318e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 3328e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_addc_defs_a_tbl, 3338e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_addc_defs_b_tbl); 3348e93258fSBjoern A. Zeeb 3358e93258fSBjoern A. Zeeb for (i = 0; i < ADDC_T_AVG; i++) { 3368e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_DBG32_D, MASKDWORD); 3378e93258fSBjoern A. Zeeb dc_re += sign_extend32(FIELD_GET(0xfff000, tmp), 11); 3388e93258fSBjoern A. Zeeb dc_im += sign_extend32(FIELD_GET(0xfff, tmp), 11); 3398e93258fSBjoern A. Zeeb } 3408e93258fSBjoern A. Zeeb 3418e93258fSBjoern A. Zeeb dc_re /= ADDC_T_AVG; 3428e93258fSBjoern A. Zeeb dc_im /= ADDC_T_AVG; 3438e93258fSBjoern A. Zeeb 3448e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 3458e93258fSBjoern A. Zeeb "[DACK]S%d,dc_re = 0x%x,dc_im =0x%x\n", path, dc_re, dc_im); 3468e93258fSBjoern A. Zeeb } 3478e93258fSBjoern A. Zeeb 3488e93258fSBjoern A. Zeeb static void _addck(struct rtw89_dev *rtwdev) 3498e93258fSBjoern A. Zeeb { 3508e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 3518e93258fSBjoern A. Zeeb u32 val; 3528e93258fSBjoern A. Zeeb int ret; 3538e93258fSBjoern A. Zeeb 3548e93258fSBjoern A. Zeeb /* S0 */ 3558e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_a_tbl); 3568e93258fSBjoern A. Zeeb 3578e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S0 ADDCK\n"); 3588e93258fSBjoern A. Zeeb _check_addc(rtwdev, RF_PATH_A); 3598e93258fSBjoern A. Zeeb 3608e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_a_tbl); 3618e93258fSBjoern A. Zeeb 3628e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 3638e93258fSBjoern A. Zeeb false, rtwdev, 0x1e00, BIT(0)); 3648e93258fSBjoern A. Zeeb if (ret) { 3658e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 ADDCK timeout\n"); 3668e93258fSBjoern A. Zeeb dack->addck_timeout[0] = true; 3678e93258fSBjoern A. Zeeb } 3688e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); 3698e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 ADDCK\n"); 3708e93258fSBjoern A. Zeeb _check_addc(rtwdev, RF_PATH_A); 3718e93258fSBjoern A. Zeeb 3728e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_a_tbl); 3738e93258fSBjoern A. Zeeb 3748e93258fSBjoern A. Zeeb /* S1 */ 3758e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_reset_defs_b_tbl); 3768e93258fSBjoern A. Zeeb 3778e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]before S1 ADDCK\n"); 3788e93258fSBjoern A. Zeeb _check_addc(rtwdev, RF_PATH_B); 3798e93258fSBjoern A. Zeeb 3808e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_trigger_defs_b_tbl); 3818e93258fSBjoern A. Zeeb 3828e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 3838e93258fSBjoern A. Zeeb false, rtwdev, 0x3e00, BIT(0)); 3848e93258fSBjoern A. Zeeb if (ret) { 3858e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 ADDCK timeout\n"); 3868e93258fSBjoern A. Zeeb dack->addck_timeout[1] = true; 3878e93258fSBjoern A. Zeeb } 3888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]ADDCK ret = %d\n", ret); 3898e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 ADDCK\n"); 3908e93258fSBjoern A. Zeeb _check_addc(rtwdev, RF_PATH_B); 3918e93258fSBjoern A. Zeeb 3928e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_addck_restore_defs_b_tbl); 3938e93258fSBjoern A. Zeeb } 3948e93258fSBjoern A. Zeeb 3958e93258fSBjoern A. Zeeb static void _check_dadc(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 3968e93258fSBjoern A. Zeeb { 3978e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 3988e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_dadc_defs_f_a_tbl, 3998e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_dadc_defs_f_b_tbl); 4008e93258fSBjoern A. Zeeb 4018e93258fSBjoern A. Zeeb _check_addc(rtwdev, path); 4028e93258fSBjoern A. Zeeb 4038e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 4048e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_dadc_defs_r_a_tbl, 4058e93258fSBjoern A. Zeeb &rtw8852a_rfk_check_dadc_defs_r_b_tbl); 4068e93258fSBjoern A. Zeeb } 4078e93258fSBjoern A. Zeeb 4088e93258fSBjoern A. Zeeb static void _dack_s0(struct rtw89_dev *rtwdev) 4098e93258fSBjoern A. Zeeb { 4108e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 4118e93258fSBjoern A. Zeeb u32 val; 4128e93258fSBjoern A. Zeeb int ret; 4138e93258fSBjoern A. Zeeb 4148e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_a_tbl); 4158e93258fSBjoern A. Zeeb 4168e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4178e93258fSBjoern A. Zeeb false, rtwdev, 0x5e28, BIT(15)); 4188e93258fSBjoern A. Zeeb ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4198e93258fSBjoern A. Zeeb false, rtwdev, 0x5e78, BIT(15)); 4208e93258fSBjoern A. Zeeb if (ret) { 4218e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 MSBK timeout\n"); 4228e93258fSBjoern A. Zeeb dack->msbk_timeout[0] = true; 4238e93258fSBjoern A. Zeeb } 4248e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); 4258e93258fSBjoern A. Zeeb 4268e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_a_tbl); 4278e93258fSBjoern A. Zeeb 4288e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4298e93258fSBjoern A. Zeeb false, rtwdev, 0x5e48, BIT(17)); 4308e93258fSBjoern A. Zeeb ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4318e93258fSBjoern A. Zeeb false, rtwdev, 0x5e98, BIT(17)); 4328e93258fSBjoern A. Zeeb if (ret) { 4338e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S0 DADACK timeout\n"); 4348e93258fSBjoern A. Zeeb dack->dadck_timeout[0] = true; 4358e93258fSBjoern A. Zeeb } 4368e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); 4378e93258fSBjoern A. Zeeb 4388e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_a_tbl); 4398e93258fSBjoern A. Zeeb 4408e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S0 DADCK\n"); 4418e93258fSBjoern A. Zeeb _check_dadc(rtwdev, RF_PATH_A); 4428e93258fSBjoern A. Zeeb 4438e93258fSBjoern A. Zeeb _dack_backup_s0(rtwdev); 4448e93258fSBjoern A. Zeeb _dack_reload(rtwdev, RF_PATH_A); 4458e93258fSBjoern A. Zeeb 4468e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_P0_NRBW, B_P0_NRBW_DBG); 4478e93258fSBjoern A. Zeeb } 4488e93258fSBjoern A. Zeeb 4498e93258fSBjoern A. Zeeb static void _dack_s1(struct rtw89_dev *rtwdev) 4508e93258fSBjoern A. Zeeb { 4518e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 4528e93258fSBjoern A. Zeeb u32 val; 4538e93258fSBjoern A. Zeeb int ret; 4548e93258fSBjoern A. Zeeb 4558e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_f_b_tbl); 4568e93258fSBjoern A. Zeeb 4578e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4588e93258fSBjoern A. Zeeb false, rtwdev, 0x7e28, BIT(15)); 4598e93258fSBjoern A. Zeeb ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4608e93258fSBjoern A. Zeeb false, rtwdev, 0x7e78, BIT(15)); 4618e93258fSBjoern A. Zeeb if (ret) { 4628e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 MSBK timeout\n"); 4638e93258fSBjoern A. Zeeb dack->msbk_timeout[1] = true; 4648e93258fSBjoern A. Zeeb } 4658e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); 4668e93258fSBjoern A. Zeeb 4678e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_m_b_tbl); 4688e93258fSBjoern A. Zeeb 4698e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4708e93258fSBjoern A. Zeeb false, rtwdev, 0x7e48, BIT(17)); 4718e93258fSBjoern A. Zeeb ret |= read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val, 1, 10000, 4728e93258fSBjoern A. Zeeb false, rtwdev, 0x7e98, BIT(17)); 4738e93258fSBjoern A. Zeeb if (ret) { 4748e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]S1 DADCK timeout\n"); 4758e93258fSBjoern A. Zeeb dack->dadck_timeout[1] = true; 4768e93258fSBjoern A. Zeeb } 4778e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK ret = %d\n", ret); 4788e93258fSBjoern A. Zeeb 4798e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dack_defs_r_b_tbl); 4808e93258fSBjoern A. Zeeb 4818e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]after S1 DADCK\n"); 4828e93258fSBjoern A. Zeeb _check_dadc(rtwdev, RF_PATH_B); 4838e93258fSBjoern A. Zeeb 4848e93258fSBjoern A. Zeeb _dack_backup_s1(rtwdev); 4858e93258fSBjoern A. Zeeb _dack_reload(rtwdev, RF_PATH_B); 4868e93258fSBjoern A. Zeeb 4878e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_P1_DBGMOD, B_P1_DBGMOD_ON); 4888e93258fSBjoern A. Zeeb } 4898e93258fSBjoern A. Zeeb 4908e93258fSBjoern A. Zeeb static void _dack(struct rtw89_dev *rtwdev) 4918e93258fSBjoern A. Zeeb { 4928e93258fSBjoern A. Zeeb _dack_s0(rtwdev); 4938e93258fSBjoern A. Zeeb _dack_s1(rtwdev); 4948e93258fSBjoern A. Zeeb } 4958e93258fSBjoern A. Zeeb 496*df279a26SBjoern A. Zeeb static void _dac_cal(struct rtw89_dev *rtwdev, bool force, 497*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 4988e93258fSBjoern A. Zeeb { 4998e93258fSBjoern A. Zeeb struct rtw89_dack_info *dack = &rtwdev->dack; 5008e93258fSBjoern A. Zeeb u32 rf0_0, rf1_0; 501*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, RF_AB, chanctx_idx); 5028e93258fSBjoern A. Zeeb 5038e93258fSBjoern A. Zeeb dack->dack_done = false; 5048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK b\n"); 5058e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK start!!!\n"); 5068e93258fSBjoern A. Zeeb rf0_0 = rtw89_read_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK); 5078e93258fSBjoern A. Zeeb rf1_0 = rtw89_read_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK); 5088e93258fSBjoern A. Zeeb _afe_init(rtwdev); 5098e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x0); 5108e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x0); 5118e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x30001); 5128e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x30001); 5138e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); 5148e93258fSBjoern A. Zeeb _addck(rtwdev); 5158e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); 5168e93258fSBjoern A. Zeeb _addck_backup(rtwdev); 5178e93258fSBjoern A. Zeeb _addck_reload(rtwdev); 5188e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, 0x40001); 5198e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, 0x40001); 5208e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RFREG_MASK, 0x0); 5218e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RFREG_MASK, 0x0); 5228e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_START); 5238e93258fSBjoern A. Zeeb _dack(rtwdev); 5248e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_ONESHOT_STOP); 5258e93258fSBjoern A. Zeeb _dack_dump(rtwdev); 5268e93258fSBjoern A. Zeeb dack->dack_done = true; 5278e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_MOD, RFREG_MASK, rf0_0); 5288e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_MOD, RFREG_MASK, rf1_0); 5298e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_A, RR_RSV1, RR_RSV1_RST, 0x1); 5308e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, RF_PATH_B, RR_RSV1, RR_RSV1_RST, 0x1); 5318e93258fSBjoern A. Zeeb dack->dack_cnt++; 5328e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DACK]DACK finish!!!\n"); 5338e93258fSBjoern A. Zeeb } 5348e93258fSBjoern A. Zeeb 5358e93258fSBjoern A. Zeeb #define RTW8852A_NCTL_VER 0xd 5368e93258fSBjoern A. Zeeb #define RTW8852A_IQK_VER 0x2a 5378e93258fSBjoern A. Zeeb #define RTW8852A_IQK_SS 2 5388e93258fSBjoern A. Zeeb #define RTW8852A_IQK_THR_REK 8 5398e93258fSBjoern A. Zeeb #define RTW8852A_IQK_CFIR_GROUP_NR 4 5408e93258fSBjoern A. Zeeb 5418e93258fSBjoern A. Zeeb enum rtw8852a_iqk_type { 5428e93258fSBjoern A. Zeeb ID_TXAGC, 5438e93258fSBjoern A. Zeeb ID_FLOK_COARSE, 5448e93258fSBjoern A. Zeeb ID_FLOK_FINE, 5458e93258fSBjoern A. Zeeb ID_TXK, 5468e93258fSBjoern A. Zeeb ID_RXAGC, 5478e93258fSBjoern A. Zeeb ID_RXK, 5488e93258fSBjoern A. Zeeb ID_NBTXK, 5498e93258fSBjoern A. Zeeb ID_NBRXK, 5508e93258fSBjoern A. Zeeb }; 5518e93258fSBjoern A. Zeeb 5528e93258fSBjoern A. Zeeb static void _iqk_read_fft_dbcc0(struct rtw89_dev *rtwdev, u8 path) 5538e93258fSBjoern A. Zeeb { 5548e93258fSBjoern A. Zeeb u8 i = 0x0; 5558e93258fSBjoern A. Zeeb u32 fft[6] = {0x0}; 5568e93258fSBjoern A. Zeeb 5578e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 5588e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00160000); 5598e93258fSBjoern A. Zeeb fft[0] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5608e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00170000); 5618e93258fSBjoern A. Zeeb fft[1] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5628e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00180000); 5638e93258fSBjoern A. Zeeb fft[2] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5648e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00190000); 5658e93258fSBjoern A. Zeeb fft[3] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5668e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001a0000); 5678e93258fSBjoern A. Zeeb fft[4] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5688e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x001b0000); 5698e93258fSBjoern A. Zeeb fft[5] = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD); 5708e93258fSBjoern A. Zeeb for (i = 0; i < 6; i++) 5718e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x,fft[%x]= %x\n", 5728e93258fSBjoern A. Zeeb path, i, fft[i]); 5738e93258fSBjoern A. Zeeb } 5748e93258fSBjoern A. Zeeb 5758e93258fSBjoern A. Zeeb static void _iqk_read_xym_dbcc0(struct rtw89_dev *rtwdev, u8 path) 5768e93258fSBjoern A. Zeeb { 5778e93258fSBjoern A. Zeeb u8 i = 0x0; 5788e93258fSBjoern A. Zeeb u32 tmp = 0x0; 5798e93258fSBjoern A. Zeeb 5808e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 5818e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); 5828e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX, 0x1); 5838e93258fSBjoern A. Zeeb 5848e93258fSBjoern A. Zeeb for (i = 0x0; i < 0x18; i++) { 5858e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x000000c0 + i); 5868e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N2, MASKDWORD); 5878e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); 5888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = %x\n", 5898e93258fSBjoern A. Zeeb path, BIT(path), tmp); 5908e93258fSBjoern A. Zeeb udelay(1); 5918e93258fSBjoern A. Zeeb } 5928e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_DIF, B_IQK_DIF_TRX); 5938e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 0x40000000); 5948e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_N2, MASKDWORD, 0x80010100); 5958e93258fSBjoern A. Zeeb udelay(1); 5968e93258fSBjoern A. Zeeb } 5978e93258fSBjoern A. Zeeb 5988e93258fSBjoern A. Zeeb static void _iqk_read_txcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, 5998e93258fSBjoern A. Zeeb u8 group) 6008e93258fSBjoern A. Zeeb { 6018e93258fSBjoern A. Zeeb static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { 6028e93258fSBjoern A. Zeeb {0x8f20, 0x8f54, 0x8f88, 0x8fbc}, 6038e93258fSBjoern A. Zeeb {0x9320, 0x9354, 0x9388, 0x93bc}, 6048e93258fSBjoern A. Zeeb }; 6058e93258fSBjoern A. Zeeb u8 idx = 0x0; 6068e93258fSBjoern A. Zeeb u32 tmp = 0x0; 6078e93258fSBjoern A. Zeeb u32 base_addr; 6088e93258fSBjoern A. Zeeb 6098e93258fSBjoern A. Zeeb if (path >= RTW8852A_IQK_SS) { 6108e93258fSBjoern A. Zeeb rtw89_warn(rtwdev, "cfir path %d out of range\n", path); 6118e93258fSBjoern A. Zeeb return; 6128e93258fSBjoern A. Zeeb } 6138e93258fSBjoern A. Zeeb if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { 6148e93258fSBjoern A. Zeeb rtw89_warn(rtwdev, "cfir group %d out of range\n", group); 6158e93258fSBjoern A. Zeeb return; 6168e93258fSBjoern A. Zeeb } 6178e93258fSBjoern A. Zeeb 6188e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 6198e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); 6208e93258fSBjoern A. Zeeb 6218e93258fSBjoern A. Zeeb base_addr = base_addrs[path][group]; 6228e93258fSBjoern A. Zeeb 6238e93258fSBjoern A. Zeeb for (idx = 0; idx < 0x0d; idx++) { 6248e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); 6258e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 6268e93258fSBjoern A. Zeeb "[IQK] %x = %x\n", 6278e93258fSBjoern A. Zeeb base_addr + (idx << 2), tmp); 6288e93258fSBjoern A. Zeeb } 6298e93258fSBjoern A. Zeeb 6308e93258fSBjoern A. Zeeb if (path == 0x0) { 6318e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); 6328e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C0, MASKDWORD); 6338e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f50 = %x\n", tmp); 6348e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C1, MASKDWORD); 6358e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8f84 = %x\n", tmp); 6368e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C2, MASKDWORD); 6378e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fb8 = %x\n", tmp); 6388e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P0C3, MASKDWORD); 6398e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8fec = %x\n", tmp); 6408e93258fSBjoern A. Zeeb } else { 6418e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); 6428e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C0, MASKDWORD); 6438e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9350 = %x\n", tmp); 6448e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C1, MASKDWORD); 6458e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9384 = %x\n", tmp); 6468e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C2, MASKDWORD); 6478e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93b8 = %x\n", tmp); 6488e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXCFIR_P1C3, MASKDWORD); 6498e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x93ec = %x\n", tmp); 6508e93258fSBjoern A. Zeeb } 6518e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); 6528e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xc); 6538e93258fSBjoern A. Zeeb udelay(1); 6548e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); 6558e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, 6568e93258fSBjoern A. Zeeb BIT(path), tmp); 6578e93258fSBjoern A. Zeeb } 6588e93258fSBjoern A. Zeeb 6598e93258fSBjoern A. Zeeb static void _iqk_read_rxcfir_dbcc0(struct rtw89_dev *rtwdev, u8 path, 6608e93258fSBjoern A. Zeeb u8 group) 6618e93258fSBjoern A. Zeeb { 6628e93258fSBjoern A. Zeeb static const u32 base_addrs[RTW8852A_IQK_SS][RTW8852A_IQK_CFIR_GROUP_NR] = { 6638e93258fSBjoern A. Zeeb {0x8d00, 0x8d44, 0x8d88, 0x8dcc}, 6648e93258fSBjoern A. Zeeb {0x9100, 0x9144, 0x9188, 0x91cc}, 6658e93258fSBjoern A. Zeeb }; 6668e93258fSBjoern A. Zeeb u8 idx = 0x0; 6678e93258fSBjoern A. Zeeb u32 tmp = 0x0; 6688e93258fSBjoern A. Zeeb u32 base_addr; 6698e93258fSBjoern A. Zeeb 6708e93258fSBjoern A. Zeeb if (path >= RTW8852A_IQK_SS) { 6718e93258fSBjoern A. Zeeb rtw89_warn(rtwdev, "cfir path %d out of range\n", path); 6728e93258fSBjoern A. Zeeb return; 6738e93258fSBjoern A. Zeeb } 6748e93258fSBjoern A. Zeeb if (group >= RTW8852A_IQK_CFIR_GROUP_NR) { 6758e93258fSBjoern A. Zeeb rtw89_warn(rtwdev, "cfir group %d out of range\n", group); 6768e93258fSBjoern A. Zeeb return; 6778e93258fSBjoern A. Zeeb } 6788e93258fSBjoern A. Zeeb 6798e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 6808e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_W_COEF + (path << 8), MASKDWORD, 0x00000001); 6818e93258fSBjoern A. Zeeb 6828e93258fSBjoern A. Zeeb base_addr = base_addrs[path][group]; 6838e93258fSBjoern A. Zeeb for (idx = 0; idx < 0x10; idx++) { 6848e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, base_addr + (idx << 2), MASKDWORD); 6858e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 6868e93258fSBjoern A. Zeeb "[IQK]%x = %x\n", 6878e93258fSBjoern A. Zeeb base_addr + (idx << 2), tmp); 6888e93258fSBjoern A. Zeeb } 6898e93258fSBjoern A. Zeeb 6908e93258fSBjoern A. Zeeb if (path == 0x0) { 6918e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); 6928e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C0, MASKDWORD); 6938e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d40 = %x\n", tmp); 6948e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C1, MASKDWORD); 6958e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8d84 = %x\n", tmp); 6968e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C2, MASKDWORD); 6978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8dc8 = %x\n", tmp); 6988e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P0C3, MASKDWORD); 6998e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x8e0c = %x\n", tmp); 7008e93258fSBjoern A. Zeeb } else { 7018e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]\n"); 7028e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C0, MASKDWORD); 7038e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9140 = %x\n", tmp); 7048e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C1, MASKDWORD); 7058e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x9184 = %x\n", tmp); 7068e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C2, MASKDWORD); 7078e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x91c8 = %x\n", tmp); 7088e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXCFIR_P1C3, MASKDWORD); 7098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK] 0x920c = %x\n", tmp); 7108e93258fSBjoern A. Zeeb } 7118e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_W_COEF + (path << 8), MASKDWORD); 7128e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT + (path << 8), B_KIP_RPT_SEL, 0xd); 7138e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_PER + (path << 8), MASKDWORD); 7148e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lxfc = %x\n", path, 7158e93258fSBjoern A. Zeeb BIT(path), tmp); 7168e93258fSBjoern A. Zeeb } 7178e93258fSBjoern A. Zeeb 7188e93258fSBjoern A. Zeeb static void _iqk_sram(struct rtw89_dev *rtwdev, u8 path) 7198e93258fSBjoern A. Zeeb { 7208e93258fSBjoern A. Zeeb u32 tmp = 0x0; 7218e93258fSBjoern A. Zeeb u32 i = 0x0; 7228e93258fSBjoern A. Zeeb 7238e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 7248e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, MASKDWORD, 0x00020000); 7258e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX2, MASKDWORD, 0x00000080); 7268e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000); 7278e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); 7288e93258fSBjoern A. Zeeb 7298e93258fSBjoern A. Zeeb for (i = 0; i <= 0x9f; i++) { 7308e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); 7318e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); 7328e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); 7338e93258fSBjoern A. Zeeb } 7348e93258fSBjoern A. Zeeb 7358e93258fSBjoern A. Zeeb for (i = 0; i <= 0x9f; i++) { 7368e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_SRAM_IQRX, MASKDWORD, 0x00010000 + i); 7378e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); 7388e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]0x%x\n", tmp); 7398e93258fSBjoern A. Zeeb } 7408e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX2, MASKDWORD); 7418e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_SRAM_IQRX, MASKDWORD); 7428e93258fSBjoern A. Zeeb } 7438e93258fSBjoern A. Zeeb 7448e93258fSBjoern A. Zeeb static void _iqk_rxk_setting(struct rtw89_dev *rtwdev, u8 path) 7458e93258fSBjoern A. Zeeb { 7468e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 7478e93258fSBjoern A. Zeeb u32 tmp = 0x0; 7488e93258fSBjoern A. Zeeb 7498e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); 7508e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x3); 7518e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0xa041); 7528e93258fSBjoern A. Zeeb udelay(1); 7538e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x3); 7548e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x0); 7558e93258fSBjoern A. Zeeb udelay(1); 7568e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST, 0x1); 7578e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H2, 0x0); 7588e93258fSBjoern A. Zeeb udelay(1); 7598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); 7608e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); 7618e93258fSBjoern A. Zeeb 7628e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 7638e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 7648e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); 7658e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x1); 7668e93258fSBjoern A. Zeeb break; 7678e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 7688e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RXK2); 7698e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x5); 7708e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x1); 7718e93258fSBjoern A. Zeeb break; 7728e93258fSBjoern A. Zeeb default: 7738e93258fSBjoern A. Zeeb break; 7748e93258fSBjoern A. Zeeb } 7758e93258fSBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); 7768e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, tmp); 7778e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 7788e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 7798e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); 7808e93258fSBjoern A. Zeeb fsleep(128); 7818e93258fSBjoern A. Zeeb } 7828e93258fSBjoern A. Zeeb 7838e93258fSBjoern A. Zeeb static bool _iqk_check_cal(struct rtw89_dev *rtwdev, u8 path, u8 ktype) 7848e93258fSBjoern A. Zeeb { 7858e93258fSBjoern A. Zeeb u32 tmp; 7868e93258fSBjoern A. Zeeb u32 val; 7878e93258fSBjoern A. Zeeb int ret; 7888e93258fSBjoern A. Zeeb 7898e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 1, 8200, 7908e93258fSBjoern A. Zeeb false, rtwdev, 0xbff8, MASKBYTE0); 7918e93258fSBjoern A. Zeeb if (ret) 7928e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]IQK timeout!!!\n"); 7938e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); 7948e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ret=%d\n", path, ret); 7958e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_NCTL_RPT, MASKDWORD); 7968e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 7978e93258fSBjoern A. Zeeb "[IQK]S%x, type= %x, 0x8008 = 0x%x\n", path, ktype, tmp); 7988e93258fSBjoern A. Zeeb 7998e93258fSBjoern A. Zeeb return false; 8008e93258fSBjoern A. Zeeb } 8018e93258fSBjoern A. Zeeb 8028e93258fSBjoern A. Zeeb static bool _iqk_one_shot(struct rtw89_dev *rtwdev, 803*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, u8 ktype, 804*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 8058e93258fSBjoern A. Zeeb { 8068e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 8078e93258fSBjoern A. Zeeb bool fail = false; 8088e93258fSBjoern A. Zeeb u32 iqk_cmd = 0x0; 809*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy_idx, path, chanctx_idx); 8108e93258fSBjoern A. Zeeb u32 addr_rfc_ctl = 0x0; 8118e93258fSBjoern A. Zeeb 8128e93258fSBjoern A. Zeeb if (path == RF_PATH_A) 8138e93258fSBjoern A. Zeeb addr_rfc_ctl = 0x5864; 8148e93258fSBjoern A. Zeeb else 8158e93258fSBjoern A. Zeeb addr_rfc_ctl = 0x7864; 8168e93258fSBjoern A. Zeeb 8178e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); 8188e93258fSBjoern A. Zeeb switch (ktype) { 8198e93258fSBjoern A. Zeeb case ID_TXAGC: 8208e93258fSBjoern A. Zeeb iqk_cmd = 0x008 | (1 << (4 + path)) | (path << 1); 8218e93258fSBjoern A. Zeeb break; 8228e93258fSBjoern A. Zeeb case ID_FLOK_COARSE: 8238e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); 8248e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); 8258e93258fSBjoern A. Zeeb iqk_cmd = 0x108 | (1 << (4 + path)); 8268e93258fSBjoern A. Zeeb break; 8278e93258fSBjoern A. Zeeb case ID_FLOK_FINE: 8288e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); 8298e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x009); 8308e93258fSBjoern A. Zeeb iqk_cmd = 0x208 | (1 << (4 + path)); 8318e93258fSBjoern A. Zeeb break; 8328e93258fSBjoern A. Zeeb case ID_TXK: 8338e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); 8348e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); 8358e93258fSBjoern A. Zeeb iqk_cmd = 0x008 | (1 << (path + 4)) | 8368e93258fSBjoern A. Zeeb (((0x8 + iqk_info->iqk_bw[path]) & 0xf) << 8); 8378e93258fSBjoern A. Zeeb break; 8388e93258fSBjoern A. Zeeb case ID_RXAGC: 8398e93258fSBjoern A. Zeeb iqk_cmd = 0x508 | (1 << (4 + path)) | (path << 1); 8408e93258fSBjoern A. Zeeb break; 8418e93258fSBjoern A. Zeeb case ID_RXK: 8428e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); 8438e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 8448e93258fSBjoern A. Zeeb iqk_cmd = 0x008 | (1 << (path + 4)) | 8458e93258fSBjoern A. Zeeb (((0xb + iqk_info->iqk_bw[path]) & 0xf) << 8); 8468e93258fSBjoern A. Zeeb break; 8478e93258fSBjoern A. Zeeb case ID_NBTXK: 8488e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); 8498e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x025); 8508e93258fSBjoern A. Zeeb iqk_cmd = 0x308 | (1 << (4 + path)); 8518e93258fSBjoern A. Zeeb break; 8528e93258fSBjoern A. Zeeb case ID_NBRXK: 8538e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, addr_rfc_ctl, 0x20000000); 8548e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x011); 8558e93258fSBjoern A. Zeeb iqk_cmd = 0x608 | (1 << (4 + path)); 8568e93258fSBjoern A. Zeeb break; 8578e93258fSBjoern A. Zeeb default: 8588e93258fSBjoern A. Zeeb return false; 8598e93258fSBjoern A. Zeeb } 8608e93258fSBjoern A. Zeeb 8618e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, iqk_cmd + 1); 8628e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); 8638e93258fSBjoern A. Zeeb udelay(1); 8648e93258fSBjoern A. Zeeb fail = _iqk_check_cal(rtwdev, path, ktype); 8658e93258fSBjoern A. Zeeb if (iqk_info->iqk_xym_en) 8668e93258fSBjoern A. Zeeb _iqk_read_xym_dbcc0(rtwdev, path); 8678e93258fSBjoern A. Zeeb if (iqk_info->iqk_fft_en) 8688e93258fSBjoern A. Zeeb _iqk_read_fft_dbcc0(rtwdev, path); 8698e93258fSBjoern A. Zeeb if (iqk_info->iqk_sram_en) 8708e93258fSBjoern A. Zeeb _iqk_sram(rtwdev, path); 8718e93258fSBjoern A. Zeeb if (iqk_info->iqk_cfir_en) { 8728e93258fSBjoern A. Zeeb if (ktype == ID_TXK) { 8738e93258fSBjoern A. Zeeb _iqk_read_txcfir_dbcc0(rtwdev, path, 0x0); 8748e93258fSBjoern A. Zeeb _iqk_read_txcfir_dbcc0(rtwdev, path, 0x1); 8758e93258fSBjoern A. Zeeb _iqk_read_txcfir_dbcc0(rtwdev, path, 0x2); 8768e93258fSBjoern A. Zeeb _iqk_read_txcfir_dbcc0(rtwdev, path, 0x3); 8778e93258fSBjoern A. Zeeb } else { 8788e93258fSBjoern A. Zeeb _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x0); 8798e93258fSBjoern A. Zeeb _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x1); 8808e93258fSBjoern A. Zeeb _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x2); 8818e93258fSBjoern A. Zeeb _iqk_read_rxcfir_dbcc0(rtwdev, path, 0x3); 8828e93258fSBjoern A. Zeeb } 8838e93258fSBjoern A. Zeeb } 8848e93258fSBjoern A. Zeeb 8858e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, addr_rfc_ctl, 0x20000000); 8868e93258fSBjoern A. Zeeb 8878e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); 8888e93258fSBjoern A. Zeeb 8898e93258fSBjoern A. Zeeb return fail; 8908e93258fSBjoern A. Zeeb } 8918e93258fSBjoern A. Zeeb 8928e93258fSBjoern A. Zeeb static bool _rxk_group_sel(struct rtw89_dev *rtwdev, 893*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 894*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 8958e93258fSBjoern A. Zeeb { 8968e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 8978e93258fSBjoern A. Zeeb static const u32 rxgn_a[4] = {0x18C, 0x1A0, 0x28C, 0x2A0}; 8988e93258fSBjoern A. Zeeb static const u32 attc2_a[4] = {0x0, 0x0, 0x07, 0x30}; 8998e93258fSBjoern A. Zeeb static const u32 attc1_a[4] = {0x7, 0x5, 0x1, 0x1}; 9008e93258fSBjoern A. Zeeb static const u32 rxgn_g[4] = {0x1CC, 0x1E0, 0x2CC, 0x2E0}; 9018e93258fSBjoern A. Zeeb static const u32 attc2_g[4] = {0x0, 0x15, 0x3, 0x1a}; 9028e93258fSBjoern A. Zeeb static const u32 attc1_g[4] = {0x1, 0x0, 0x1, 0x0}; 9038e93258fSBjoern A. Zeeb u8 gp = 0x0; 9048e93258fSBjoern A. Zeeb bool fail = false; 9058e93258fSBjoern A. Zeeb u32 rf0 = 0x0; 9068e93258fSBjoern A. Zeeb 9078e93258fSBjoern A. Zeeb for (gp = 0; gp < 0x4; gp++) { 9088e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 9098e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 9108e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_g[gp]); 9118e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, attc2_g[gp]); 9128e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, attc1_g[gp]); 9138e93258fSBjoern A. Zeeb break; 9148e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 9158e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, rxgn_a[gp]); 9168e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, attc2_a[gp]); 9178e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, attc1_a[gp]); 9188e93258fSBjoern A. Zeeb break; 9198e93258fSBjoern A. Zeeb default: 9208e93258fSBjoern A. Zeeb break; 9218e93258fSBjoern A. Zeeb } 9228e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); 9238e93258fSBjoern A. Zeeb rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 9248e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, 9258e93258fSBjoern A. Zeeb rf0 | iqk_info->syn1to2); 9268e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); 9278e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); 9288e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); 9298e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); 9308e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, gp); 9318e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN, 0x1); 9328e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); 933*df279a26SBjoern A. Zeeb fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_RXK, chanctx_idx); 9348e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(16 + gp + path * 4), fail); 9358e93258fSBjoern A. Zeeb } 9368e93258fSBjoern A. Zeeb 9378e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 9388e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 9398e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); 9408e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 9418e93258fSBjoern A. Zeeb break; 9428e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 9438e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); 9448e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 9458e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); 9468e93258fSBjoern A. Zeeb break; 9478e93258fSBjoern A. Zeeb default: 9488e93258fSBjoern A. Zeeb break; 9498e93258fSBjoern A. Zeeb } 9508e93258fSBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 0x40000000; 9518e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), 9528e93258fSBjoern A. Zeeb B_IQK_RES_RXCFIR, 0x5); 9538e93258fSBjoern A. Zeeb iqk_info->is_wb_rxiqk[path] = true; 9548e93258fSBjoern A. Zeeb return false; 9558e93258fSBjoern A. Zeeb } 9568e93258fSBjoern A. Zeeb 9578e93258fSBjoern A. Zeeb static bool _iqk_nbrxk(struct rtw89_dev *rtwdev, 958*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 959*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 9608e93258fSBjoern A. Zeeb { 9618e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 9628e93258fSBjoern A. Zeeb u8 group = 0x0; 9638e93258fSBjoern A. Zeeb u32 rf0 = 0x0, tmp = 0x0; 9648e93258fSBjoern A. Zeeb u32 idxrxgain_a = 0x1a0; 9658e93258fSBjoern A. Zeeb u32 idxattc2_a = 0x00; 9668e93258fSBjoern A. Zeeb u32 idxattc1_a = 0x5; 9678e93258fSBjoern A. Zeeb u32 idxrxgain_g = 0x1E0; 9688e93258fSBjoern A. Zeeb u32 idxattc2_g = 0x15; 9698e93258fSBjoern A. Zeeb u32 idxattc1_g = 0x0; 9708e93258fSBjoern A. Zeeb bool fail = false; 9718e93258fSBjoern A. Zeeb 9728e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 9738e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 9748e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_g); 9758e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C2G, idxattc2_g); 9768e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_C1G, idxattc1_g); 9778e93258fSBjoern A. Zeeb break; 9788e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 9798e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXG, idxrxgain_a); 9808e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C2, idxattc2_a); 9818e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA2, RR_RXA2_C1, idxattc1_a); 9828e93258fSBjoern A. Zeeb break; 9838e93258fSBjoern A. Zeeb default: 9848e93258fSBjoern A. Zeeb break; 9858e93258fSBjoern A. Zeeb } 9868e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); 9878e93258fSBjoern A. Zeeb rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 9888e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF2, B_IQK_DIF2_RXPI, 9898e93258fSBjoern A. Zeeb rf0 | iqk_info->syn1to2); 9908e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_COM, MASKDWORD, 0x40010100); 9918e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_RXCFIR); 9928e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); 9938e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); 9948e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 9958e93258fSBjoern A. Zeeb B_CFIR_LUT_GP, group); 9968e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); 9978e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); 998*df279a26SBjoern A. Zeeb fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBRXK, chanctx_idx); 9998e93258fSBjoern A. Zeeb 10008e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 10018e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 10028e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL2G, 0x0); 10038e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 10048e93258fSBjoern A. Zeeb break; 10058e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 10068e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_SEL5G, 0x0); 10078e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 10088e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_WLSEL, RR_WLSEL_AG, 0x0); 10098e93258fSBjoern A. Zeeb break; 10108e93258fSBjoern A. Zeeb default: 10118e93258fSBjoern A. Zeeb break; 10128e93258fSBjoern A. Zeeb } 10138e93258fSBjoern A. Zeeb if (!fail) { 10148e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); 10158e93258fSBjoern A. Zeeb iqk_info->nb_rxcfir[path] = tmp | 0x2; 10168e93258fSBjoern A. Zeeb } else { 10178e93258fSBjoern A. Zeeb iqk_info->nb_rxcfir[path] = 0x40000002; 10188e93258fSBjoern A. Zeeb } 10198e93258fSBjoern A. Zeeb return fail; 10208e93258fSBjoern A. Zeeb } 10218e93258fSBjoern A. Zeeb 10228e93258fSBjoern A. Zeeb static void _iqk_rxclk_setting(struct rtw89_dev *rtwdev, u8 path) 10238e93258fSBjoern A. Zeeb { 10248e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 10258e93258fSBjoern A. Zeeb 10268e93258fSBjoern A. Zeeb if (iqk_info->iqk_bw[path] == RTW89_CHANNEL_WIDTH_80) { 10278e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 10288e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), 10298e93258fSBjoern A. Zeeb MASKDWORD, 0x4d000a08); 10308e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), 10318e93258fSBjoern A. Zeeb B_P0_RXCK_VAL, 0x2); 10328e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); 10338e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); 10348e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL, 0x1); 10358e93258fSBjoern A. Zeeb } else { 10368e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), 10378e93258fSBjoern A. Zeeb MASKDWORD, 0x44000a08); 10388e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), 10398e93258fSBjoern A. Zeeb B_P0_RXCK_VAL, 0x1); 10408e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); 10418e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_ON); 10428e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_UPD_CLK_ADC, B_UPD_CLK_ADC_VAL); 10438e93258fSBjoern A. Zeeb } 10448e93258fSBjoern A. Zeeb } 10458e93258fSBjoern A. Zeeb 10468e93258fSBjoern A. Zeeb static bool _txk_group_sel(struct rtw89_dev *rtwdev, 1047*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 1048*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 10498e93258fSBjoern A. Zeeb { 10508e93258fSBjoern A. Zeeb static const u32 a_txgain[4] = {0xE466, 0x646D, 0xE4E2, 0x64ED}; 10518e93258fSBjoern A. Zeeb static const u32 g_txgain[4] = {0x60e8, 0x60f0, 0x61e8, 0x61ED}; 10528e93258fSBjoern A. Zeeb static const u32 a_itqt[4] = {0x12, 0x12, 0x12, 0x1b}; 10538e93258fSBjoern A. Zeeb static const u32 g_itqt[4] = {0x09, 0x12, 0x12, 0x12}; 10548e93258fSBjoern A. Zeeb static const u32 g_attsmxr[4] = {0x0, 0x1, 0x1, 0x1}; 10558e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 10568e93258fSBjoern A. Zeeb bool fail = false; 10578e93258fSBjoern A. Zeeb u8 gp = 0x0; 10588e93258fSBjoern A. Zeeb u32 tmp = 0x0; 10598e93258fSBjoern A. Zeeb 10608e93258fSBjoern A. Zeeb for (gp = 0x0; gp < 0x4; gp++) { 10618e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 10628e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 10638e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), 10648e93258fSBjoern A. Zeeb B_RFGAIN_BND, 0x08); 10658e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 10668e93258fSBjoern A. Zeeb g_txgain[gp]); 10678e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 10688e93258fSBjoern A. Zeeb g_attsmxr[gp]); 10698e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 10708e93258fSBjoern A. Zeeb g_attsmxr[gp]); 10718e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), 10728e93258fSBjoern A. Zeeb MASKDWORD, g_itqt[gp]); 10738e93258fSBjoern A. Zeeb break; 10748e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 10758e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), 10768e93258fSBjoern A. Zeeb B_RFGAIN_BND, 0x04); 10778e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 10788e93258fSBjoern A. Zeeb a_txgain[gp]); 10798e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), 10808e93258fSBjoern A. Zeeb MASKDWORD, a_itqt[gp]); 10818e93258fSBjoern A. Zeeb break; 10828e93258fSBjoern A. Zeeb default: 10838e93258fSBjoern A. Zeeb break; 10848e93258fSBjoern A. Zeeb } 10858e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); 10868e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); 10878e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); 10888e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 10898e93258fSBjoern A. Zeeb B_CFIR_LUT_GP, gp); 10908e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); 1091*df279a26SBjoern A. Zeeb fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_TXK, chanctx_idx); 10928e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(8 + gp + path * 4), fail); 10938e93258fSBjoern A. Zeeb } 10948e93258fSBjoern A. Zeeb 10958e93258fSBjoern A. Zeeb iqk_info->nb_txcfir[path] = 0x40000000; 10968e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_RES + (path << 8), 10978e93258fSBjoern A. Zeeb B_IQK_RES_TXCFIR, 0x5); 10988e93258fSBjoern A. Zeeb iqk_info->is_wb_txiqk[path] = true; 10998e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); 11008e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, 11018e93258fSBjoern A. Zeeb BIT(path), tmp); 11028e93258fSBjoern A. Zeeb return false; 11038e93258fSBjoern A. Zeeb } 11048e93258fSBjoern A. Zeeb 11058e93258fSBjoern A. Zeeb static bool _iqk_nbtxk(struct rtw89_dev *rtwdev, 1106*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 1107*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 11088e93258fSBjoern A. Zeeb { 11098e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 11108e93258fSBjoern A. Zeeb u8 group = 0x2; 11118e93258fSBjoern A. Zeeb u32 a_mode_txgain = 0x64e2; 11128e93258fSBjoern A. Zeeb u32 g_mode_txgain = 0x61e8; 11138e93258fSBjoern A. Zeeb u32 attsmxr = 0x1; 11148e93258fSBjoern A. Zeeb u32 itqt = 0x12; 11158e93258fSBjoern A. Zeeb u32 tmp = 0x0; 11168e93258fSBjoern A. Zeeb bool fail = false; 11178e93258fSBjoern A. Zeeb 11188e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 11198e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 11208e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), 11218e93258fSBjoern A. Zeeb B_RFGAIN_BND, 0x08); 11228e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, g_mode_txgain); 11238e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, attsmxr); 11248e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, attsmxr); 11258e93258fSBjoern A. Zeeb break; 11268e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 11278e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN_BND + (path << 8), 11288e93258fSBjoern A. Zeeb B_RFGAIN_BND, 0x04); 11298e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, a_mode_txgain); 11308e93258fSBjoern A. Zeeb break; 11318e93258fSBjoern A. Zeeb default: 11328e93258fSBjoern A. Zeeb break; 11338e93258fSBjoern A. Zeeb } 11348e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); 11358e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); 11368e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3); 11378e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, group); 11388e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); 11398e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); 1140*df279a26SBjoern A. Zeeb fail = _iqk_one_shot(rtwdev, phy_idx, path, ID_NBTXK, chanctx_idx); 11418e93258fSBjoern A. Zeeb if (!fail) { 11428e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); 11438e93258fSBjoern A. Zeeb iqk_info->nb_txcfir[path] = tmp | 0x2; 11448e93258fSBjoern A. Zeeb } else { 11458e93258fSBjoern A. Zeeb iqk_info->nb_txcfir[path] = 0x40000002; 11468e93258fSBjoern A. Zeeb } 11478e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); 11488e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, 0x8%lx38 = 0x%x\n", path, 11498e93258fSBjoern A. Zeeb BIT(path), tmp); 11508e93258fSBjoern A. Zeeb return fail; 11518e93258fSBjoern A. Zeeb } 11528e93258fSBjoern A. Zeeb 11538e93258fSBjoern A. Zeeb static void _lok_res_table(struct rtw89_dev *rtwdev, u8 path, u8 ibias) 11548e93258fSBjoern A. Zeeb { 11558e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 11568e93258fSBjoern A. Zeeb 11578e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, ibias = %x\n", path, ibias); 11588e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x2); 11598e93258fSBjoern A. Zeeb if (iqk_info->iqk_band[path] == RTW89_BAND_2G) 11608e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x0); 11618e93258fSBjoern A. Zeeb else 11628e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, 0x1); 11638e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, ibias); 11648e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0); 11658e93258fSBjoern A. Zeeb } 11668e93258fSBjoern A. Zeeb 11678e93258fSBjoern A. Zeeb static bool _lok_finetune_check(struct rtw89_dev *rtwdev, u8 path) 11688e93258fSBjoern A. Zeeb { 11698e93258fSBjoern A. Zeeb bool is_fail = false; 11708e93258fSBjoern A. Zeeb u32 tmp = 0x0; 11718e93258fSBjoern A. Zeeb u32 core_i = 0x0; 11728e93258fSBjoern A. Zeeb u32 core_q = 0x0; 11738e93258fSBjoern A. Zeeb 11748e93258fSBjoern A. Zeeb tmp = rtw89_read_rf(rtwdev, path, RR_TXMO, RFREG_MASK); 11758e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK][FineLOK] S%x, 0x58 = 0x%x\n", 11768e93258fSBjoern A. Zeeb path, tmp); 11778e93258fSBjoern A. Zeeb core_i = FIELD_GET(RR_TXMO_COI, tmp); 11788e93258fSBjoern A. Zeeb core_q = FIELD_GET(RR_TXMO_COQ, tmp); 11798e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, i = 0x%x\n", path, core_i); 11808e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%x, q = 0x%x\n", path, core_q); 11818e93258fSBjoern A. Zeeb 11828e93258fSBjoern A. Zeeb if (core_i < 0x2 || core_i > 0x1d || core_q < 0x2 || core_q > 0x1d) 11838e93258fSBjoern A. Zeeb is_fail = true; 11848e93258fSBjoern A. Zeeb return is_fail; 11858e93258fSBjoern A. Zeeb } 11868e93258fSBjoern A. Zeeb 11878e93258fSBjoern A. Zeeb static bool _iqk_lok(struct rtw89_dev *rtwdev, 1188*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 1189*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 11908e93258fSBjoern A. Zeeb { 11918e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 11928e93258fSBjoern A. Zeeb u32 rf0 = 0x0; 11938e93258fSBjoern A. Zeeb u8 itqt = 0x12; 11948e93258fSBjoern A. Zeeb bool fail = false; 11958e93258fSBjoern A. Zeeb bool tmp = false; 11968e93258fSBjoern A. Zeeb 11978e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 11988e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 11998e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe5e0); 12008e93258fSBjoern A. Zeeb itqt = 0x09; 12018e93258fSBjoern A. Zeeb break; 12028e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 12038e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_ALL, 0xe4e0); 12048e93258fSBjoern A. Zeeb itqt = 0x12; 12058e93258fSBjoern A. Zeeb break; 12068e93258fSBjoern A. Zeeb default: 12078e93258fSBjoern A. Zeeb break; 12088e93258fSBjoern A. Zeeb } 12098e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_IQK_CFG, B_IQK_CFG_SET); 12108e93258fSBjoern A. Zeeb rf0 = rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK); 12118e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF1, B_IQK_DIF1_TXPI, 12128e93258fSBjoern A. Zeeb rf0 | iqk_info->syn1to2); 12138e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQK_RES + (path << 8), B_IQK_RES_TXCFIR); 12148e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL, 0x1); 12158e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_G3, 0x1); 12168e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_GP, 0x0); 12178e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_IOQ_IQK_DPK, B_IOQ_IQK_DPK_EN); 12188e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, B_NCTL_N1_CIP); 12198e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); 1220*df279a26SBjoern A. Zeeb tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_COARSE, chanctx_idx); 12218e93258fSBjoern A. Zeeb iqk_info->lok_cor_fail[0][path] = tmp; 12228e93258fSBjoern A. Zeeb fsleep(10); 12238e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_IQP + (path << 8), MASKDWORD, itqt); 1224*df279a26SBjoern A. Zeeb tmp = _iqk_one_shot(rtwdev, phy_idx, path, ID_FLOK_FINE, chanctx_idx); 12258e93258fSBjoern A. Zeeb iqk_info->lok_fin_fail[0][path] = tmp; 12268e93258fSBjoern A. Zeeb fail = _lok_finetune_check(rtwdev, path); 12278e93258fSBjoern A. Zeeb return fail; 12288e93258fSBjoern A. Zeeb } 12298e93258fSBjoern A. Zeeb 12308e93258fSBjoern A. Zeeb static void _iqk_txk_setting(struct rtw89_dev *rtwdev, u8 path) 12318e93258fSBjoern A. Zeeb { 12328e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 12338e93258fSBjoern A. Zeeb 12348e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); 12358e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x1f); 12368e93258fSBjoern A. Zeeb udelay(1); 12378e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15, 0x13); 12388e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0001); 12398e93258fSBjoern A. Zeeb udelay(1); 12408e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_15, 0x0041); 12418e93258fSBjoern A. Zeeb udelay(1); 12428e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0303); 12438e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ADC_FIFO, B_ADC_FIFO_RST, 0x0000); 12448e93258fSBjoern A. Zeeb switch (iqk_info->iqk_band[path]) { 12458e93258fSBjoern A. Zeeb case RTW89_BAND_2G: 12468e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_XALNA2, RR_XALNA2_SW, 0x00); 12478e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); 12488e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT2, 0x0); 12498e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG1, RR_TXG1_ATT1, 0x1); 12508e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXG2, RR_TXG2_ATT0, 0x1); 12518e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); 12528e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); 12538e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); 12548e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x000); 12558e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); 12568e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); 12578e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 12588e93258fSBjoern A. Zeeb 0x403e0 | iqk_info->syn1to2); 12598e93258fSBjoern A. Zeeb udelay(1); 12608e93258fSBjoern A. Zeeb break; 12618e93258fSBjoern A. Zeeb case RTW89_BAND_5G: 12628e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_XGLNA2, RR_XGLNA2_SW, 0x00); 12638e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x3f); 12648e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BIASA, RR_BIASA_A, 0x7); 12658e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXGA, RR_TXGA_LOK_EN, 0x0); 12668e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x1); 12678e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTDBG, RR_LUTDBG_LOK, 0x0); 12688e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWA, RR_LUTWA_MASK, 0x100); 12698e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV2, RFREG_MASK, 0x80200); 12708e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DTXLOK, RFREG_MASK, 0x80200); 12718e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x1); 12728e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, 0x0); 12738e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RFREG_MASK, 12748e93258fSBjoern A. Zeeb 0x403e0 | iqk_info->syn1to2); 12758e93258fSBjoern A. Zeeb udelay(1); 12768e93258fSBjoern A. Zeeb break; 12778e93258fSBjoern A. Zeeb default: 12788e93258fSBjoern A. Zeeb break; 12798e93258fSBjoern A. Zeeb } 12808e93258fSBjoern A. Zeeb } 12818e93258fSBjoern A. Zeeb 12828e93258fSBjoern A. Zeeb static void _iqk_txclk_setting(struct rtw89_dev *rtwdev, u8 path) 12838e93258fSBjoern A. Zeeb { 12848e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); 12858e93258fSBjoern A. Zeeb } 12868e93258fSBjoern A. Zeeb 12878e93258fSBjoern A. Zeeb static void _iqk_info_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 12888e93258fSBjoern A. Zeeb u8 path) 12898e93258fSBjoern A. Zeeb { 12908e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 12918e93258fSBjoern A. Zeeb u32 tmp = 0x0; 12928e93258fSBjoern A. Zeeb bool flag = 0x0; 12938e93258fSBjoern A. Zeeb 1294e2340276SBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_thermal = %lu\n", path, 1295e2340276SBjoern A. Zeeb ewma_thermal_read(&rtwdev->phystat.avg_thermal[path])); 12968e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_COR_fail= %d\n", path, 12978e93258fSBjoern A. Zeeb iqk_info->lok_cor_fail[0][path]); 12988e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_LOK_FIN_fail= %d\n", path, 12998e93258fSBjoern A. Zeeb iqk_info->lok_fin_fail[0][path]); 13008e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_TXIQK_fail = %d\n", path, 13018e93258fSBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path]); 13028e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]S%d_RXIQK_fail= %d,\n", path, 13038e93258fSBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path]); 13048e93258fSBjoern A. Zeeb flag = iqk_info->lok_cor_fail[0][path]; 13058e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(0) << (path * 4), flag); 13068e93258fSBjoern A. Zeeb flag = iqk_info->lok_fin_fail[0][path]; 13078e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(1) << (path * 4), flag); 13088e93258fSBjoern A. Zeeb flag = iqk_info->iqk_tx_fail[0][path]; 13098e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(2) << (path * 4), flag); 13108e93258fSBjoern A. Zeeb flag = iqk_info->iqk_rx_fail[0][path]; 13118e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, BIT(3) << (path * 4), flag); 13128e93258fSBjoern A. Zeeb 13138e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_IQK_RES + (path << 8), MASKDWORD); 13148e93258fSBjoern A. Zeeb iqk_info->bp_iqkenable[path] = tmp; 13158e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD); 13168e93258fSBjoern A. Zeeb iqk_info->bp_txkresult[path] = tmp; 13178e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD); 13188e93258fSBjoern A. Zeeb iqk_info->bp_rxkresult[path] = tmp; 13198e93258fSBjoern A. Zeeb 13208e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF2, B_IQKINF2_KCNT, 13218e93258fSBjoern A. Zeeb (u8)iqk_info->iqk_times); 13228e93258fSBjoern A. Zeeb 13238e93258fSBjoern A. Zeeb tmp = rtw89_phy_read32_mask(rtwdev, R_IQKINF, 0x0000000f << (path * 4)); 13248e93258fSBjoern A. Zeeb if (tmp != 0x0) 13258e93258fSBjoern A. Zeeb iqk_info->iqk_fail_cnt++; 13268e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x00ff0000 << (path * 4), 13278e93258fSBjoern A. Zeeb iqk_info->iqk_fail_cnt); 13288e93258fSBjoern A. Zeeb } 13298e93258fSBjoern A. Zeeb 13308e93258fSBjoern A. Zeeb static 1331*df279a26SBjoern A. Zeeb void _iqk_by_path(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, u8 path, 1332*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 13338e93258fSBjoern A. Zeeb { 13348e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 13358e93258fSBjoern A. Zeeb bool lok_is_fail = false; 13368e93258fSBjoern A. Zeeb u8 ibias = 0x1; 13378e93258fSBjoern A. Zeeb u8 i = 0; 13388e93258fSBjoern A. Zeeb 13398e93258fSBjoern A. Zeeb _iqk_txclk_setting(rtwdev, path); 13408e93258fSBjoern A. Zeeb 13418e93258fSBjoern A. Zeeb for (i = 0; i < 3; i++) { 13428e93258fSBjoern A. Zeeb _lok_res_table(rtwdev, path, ibias++); 13438e93258fSBjoern A. Zeeb _iqk_txk_setting(rtwdev, path); 1344*df279a26SBjoern A. Zeeb lok_is_fail = _iqk_lok(rtwdev, phy_idx, path, chanctx_idx); 13458e93258fSBjoern A. Zeeb if (!lok_is_fail) 13468e93258fSBjoern A. Zeeb break; 13478e93258fSBjoern A. Zeeb } 13488e93258fSBjoern A. Zeeb if (iqk_info->is_nbiqk) 1349*df279a26SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = _iqk_nbtxk(rtwdev, phy_idx, path, 1350*df279a26SBjoern A. Zeeb chanctx_idx); 13518e93258fSBjoern A. Zeeb else 1352*df279a26SBjoern A. Zeeb iqk_info->iqk_tx_fail[0][path] = _txk_group_sel(rtwdev, phy_idx, path, 1353*df279a26SBjoern A. Zeeb chanctx_idx); 13548e93258fSBjoern A. Zeeb 13558e93258fSBjoern A. Zeeb _iqk_rxclk_setting(rtwdev, path); 13568e93258fSBjoern A. Zeeb _iqk_rxk_setting(rtwdev, path); 13578e93258fSBjoern A. Zeeb if (iqk_info->is_nbiqk || rtwdev->dbcc_en || iqk_info->iqk_band[path] == RTW89_BAND_2G) 1358*df279a26SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = _iqk_nbrxk(rtwdev, phy_idx, path, 1359*df279a26SBjoern A. Zeeb chanctx_idx); 13608e93258fSBjoern A. Zeeb else 1361*df279a26SBjoern A. Zeeb iqk_info->iqk_rx_fail[0][path] = _rxk_group_sel(rtwdev, phy_idx, path, 1362*df279a26SBjoern A. Zeeb chanctx_idx); 13638e93258fSBjoern A. Zeeb 13648e93258fSBjoern A. Zeeb _iqk_info_iqk(rtwdev, phy_idx, path); 13658e93258fSBjoern A. Zeeb } 13668e93258fSBjoern A. Zeeb 13678e93258fSBjoern A. Zeeb static void _iqk_get_ch_info(struct rtw89_dev *rtwdev, 1368*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, u8 path, 1369*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 13708e93258fSBjoern A. Zeeb { 13718e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 1372*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 13738e93258fSBjoern A. Zeeb u32 reg_rf18 = 0x0, reg_35c = 0x0; 13748e93258fSBjoern A. Zeeb u8 idx = 0; 13758e93258fSBjoern A. Zeeb u8 get_empty_table = false; 13768e93258fSBjoern A. Zeeb 13778e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 13788e93258fSBjoern A. Zeeb for (idx = 0; idx < RTW89_IQK_CHS_NR; idx++) { 13798e93258fSBjoern A. Zeeb if (iqk_info->iqk_mcc_ch[idx][path] == 0) { 13808e93258fSBjoern A. Zeeb get_empty_table = true; 13818e93258fSBjoern A. Zeeb break; 13828e93258fSBjoern A. Zeeb } 13838e93258fSBjoern A. Zeeb } 13848e93258fSBjoern A. Zeeb if (!get_empty_table) { 13858e93258fSBjoern A. Zeeb idx = iqk_info->iqk_table_idx[path] + 1; 13868e93258fSBjoern A. Zeeb if (idx > RTW89_IQK_CHS_NR - 1) 13878e93258fSBjoern A. Zeeb idx = 0; 13888e93258fSBjoern A. Zeeb } 13898e93258fSBjoern A. Zeeb reg_rf18 = rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK); 13908e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]cfg ch = %d\n", reg_rf18); 13918e93258fSBjoern A. Zeeb reg_35c = rtw89_phy_read32_mask(rtwdev, 0x35c, 0x00000c00); 13928e93258fSBjoern A. Zeeb 13938e93258fSBjoern A. Zeeb iqk_info->iqk_band[path] = chan->band_type; 13948e93258fSBjoern A. Zeeb iqk_info->iqk_bw[path] = chan->band_width; 13958e93258fSBjoern A. Zeeb iqk_info->iqk_ch[path] = chan->channel; 13968e93258fSBjoern A. Zeeb 13978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 13988e93258fSBjoern A. Zeeb "[IQK]iqk_info->iqk_band[%x] = 0x%x\n", path, 13998e93258fSBjoern A. Zeeb iqk_info->iqk_band[path]); 14008e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_bw[%x] = 0x%x\n", 14018e93258fSBjoern A. Zeeb path, iqk_info->iqk_bw[path]); 14028e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]iqk_info->iqk_ch[%x] = 0x%x\n", 14038e93258fSBjoern A. Zeeb path, iqk_info->iqk_ch[path]); 14048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 14058e93258fSBjoern A. Zeeb "[IQK]S%d (PHY%d): / DBCC %s/ %s/ CH%d/ %s\n", path, phy, 14068e93258fSBjoern A. Zeeb rtwdev->dbcc_en ? "on" : "off", 14078e93258fSBjoern A. Zeeb iqk_info->iqk_band[path] == 0 ? "2G" : 14088e93258fSBjoern A. Zeeb iqk_info->iqk_band[path] == 1 ? "5G" : "6G", 14098e93258fSBjoern A. Zeeb iqk_info->iqk_ch[path], 14108e93258fSBjoern A. Zeeb iqk_info->iqk_bw[path] == 0 ? "20M" : 14118e93258fSBjoern A. Zeeb iqk_info->iqk_bw[path] == 1 ? "40M" : "80M"); 14128e93258fSBjoern A. Zeeb if (reg_35c == 0x01) 14138e93258fSBjoern A. Zeeb iqk_info->syn1to2 = 0x1; 14148e93258fSBjoern A. Zeeb else 14158e93258fSBjoern A. Zeeb iqk_info->syn1to2 = 0x0; 14168e93258fSBjoern A. Zeeb 14178e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF, B_IQKINF_VER, RTW8852A_IQK_VER); 14188e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x000f << (path * 16), 14198e93258fSBjoern A. Zeeb (u8)iqk_info->iqk_band[path]); 14208e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0x00f0 << (path * 16), 14218e93258fSBjoern A. Zeeb (u8)iqk_info->iqk_bw[path]); 14228e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKCH, 0xff00 << (path * 16), 14238e93258fSBjoern A. Zeeb (u8)iqk_info->iqk_ch[path]); 14248e93258fSBjoern A. Zeeb 14258e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQKINF2, 0x000000ff, RTW8852A_NCTL_VER); 14268e93258fSBjoern A. Zeeb } 14278e93258fSBjoern A. Zeeb 14288e93258fSBjoern A. Zeeb static void _iqk_start_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 1429*df279a26SBjoern A. Zeeb u8 path, enum rtw89_chanctx_idx chanctx_idx) 14308e93258fSBjoern A. Zeeb { 1431*df279a26SBjoern A. Zeeb _iqk_by_path(rtwdev, phy_idx, path, chanctx_idx); 14328e93258fSBjoern A. Zeeb } 14338e93258fSBjoern A. Zeeb 14348e93258fSBjoern A. Zeeb static void _iqk_restore(struct rtw89_dev *rtwdev, u8 path) 14358e93258fSBjoern A. Zeeb { 14368e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 14378e93258fSBjoern A. Zeeb 14388e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXIQC + (path << 8), MASKDWORD, 14398e93258fSBjoern A. Zeeb iqk_info->nb_txcfir[path]); 14408e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), MASKDWORD, 14418e93258fSBjoern A. Zeeb iqk_info->nb_rxcfir[path]); 14428e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); 14438e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_MDPK_RX_DCK, MASKDWORD); 14448e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); 14458e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KPATH_CFG, MASKDWORD); 14468e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_GAPK, B_GAPK_ADR); 14478e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); 14488e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); 14498e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_MAP + (path << 8), MASKDWORD, 0xe4e4e4e4); 14508e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_CFIR_LUT + (path << 8), B_CFIR_LUT_SEL); 14518e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP_IQP + (path << 8), B_KIP_IQP_IQSW); 14528e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD, 0x00000002); 14538e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); 14548e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_POW, 0x0); 14558e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_LUTWE, RR_LUTWE_LOK, 0x0); 14568e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); 14578e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXRSV, RR_TXRSV_GAPK, 0x0); 14588e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BIAS, RR_BIAS_GAPK, 0x0); 14598e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); 14608e93258fSBjoern A. Zeeb } 14618e93258fSBjoern A. Zeeb 14628e93258fSBjoern A. Zeeb static void _iqk_afebb_restore(struct rtw89_dev *rtwdev, 14638e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 14648e93258fSBjoern A. Zeeb { 14658e93258fSBjoern A. Zeeb const struct rtw89_rfk_tbl *tbl; 14668e93258fSBjoern A. Zeeb 14678e93258fSBjoern A. Zeeb switch (_kpath(rtwdev, phy_idx)) { 14688e93258fSBjoern A. Zeeb case RF_A: 14698e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path0_tbl; 14708e93258fSBjoern A. Zeeb break; 14718e93258fSBjoern A. Zeeb case RF_B: 14728e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_restore_defs_dbcc_path1_tbl; 14738e93258fSBjoern A. Zeeb break; 14748e93258fSBjoern A. Zeeb default: 14758e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_restore_defs_nondbcc_path01_tbl; 14768e93258fSBjoern A. Zeeb break; 14778e93258fSBjoern A. Zeeb } 14788e93258fSBjoern A. Zeeb 14798e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, tbl); 14808e93258fSBjoern A. Zeeb } 14818e93258fSBjoern A. Zeeb 14828e93258fSBjoern A. Zeeb static void _iqk_preset(struct rtw89_dev *rtwdev, u8 path) 14838e93258fSBjoern A. Zeeb { 14848e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 14858e93258fSBjoern A. Zeeb u8 idx = iqk_info->iqk_table_idx[path]; 14868e93258fSBjoern A. Zeeb 14878e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) { 14888e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 14898e93258fSBjoern A. Zeeb B_COEF_SEL_IQC, path & 0x1); 14908e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 14918e93258fSBjoern A. Zeeb B_CFIR_LUT_G2, path & 0x1); 14928e93258fSBjoern A. Zeeb } else { 14938e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 14948e93258fSBjoern A. Zeeb B_COEF_SEL_IQC, idx); 14958e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT + (path << 8), 14968e93258fSBjoern A. Zeeb B_CFIR_LUT_G2, idx); 14978e93258fSBjoern A. Zeeb } 14988e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 14998e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); 15008e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_RW, MASKDWORD); 15018e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x81ff010a); 15028e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KPATH_CFG, MASKDWORD, 0x00200000); 15038e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_RX_DCK, MASKDWORD, 0x80000000); 15048e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), MASKDWORD); 15058e93258fSBjoern A. Zeeb } 15068e93258fSBjoern A. Zeeb 15078e93258fSBjoern A. Zeeb static void _iqk_macbb_setting(struct rtw89_dev *rtwdev, 15088e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path) 15098e93258fSBjoern A. Zeeb { 15108e93258fSBjoern A. Zeeb const struct rtw89_rfk_tbl *tbl; 15118e93258fSBjoern A. Zeeb 15128e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===> %s\n", __func__); 15138e93258fSBjoern A. Zeeb 15148e93258fSBjoern A. Zeeb switch (_kpath(rtwdev, phy_idx)) { 15158e93258fSBjoern A. Zeeb case RF_A: 15168e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path0_tbl; 15178e93258fSBjoern A. Zeeb break; 15188e93258fSBjoern A. Zeeb case RF_B: 15198e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_set_defs_dbcc_path1_tbl; 15208e93258fSBjoern A. Zeeb break; 15218e93258fSBjoern A. Zeeb default: 15228e93258fSBjoern A. Zeeb tbl = &rtw8852a_rfk_iqk_set_defs_nondbcc_path01_tbl; 15238e93258fSBjoern A. Zeeb break; 15248e93258fSBjoern A. Zeeb } 15258e93258fSBjoern A. Zeeb 15268e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, tbl); 15278e93258fSBjoern A. Zeeb } 15288e93258fSBjoern A. Zeeb 1529*df279a26SBjoern A. Zeeb static void _iqk_dbcc(struct rtw89_dev *rtwdev, u8 path, 1530*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 15318e93258fSBjoern A. Zeeb { 15328e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 15338e93258fSBjoern A. Zeeb u8 phy_idx = 0x0; 15348e93258fSBjoern A. Zeeb 15358e93258fSBjoern A. Zeeb iqk_info->iqk_times++; 15368e93258fSBjoern A. Zeeb 15378e93258fSBjoern A. Zeeb if (path == 0x0) 15388e93258fSBjoern A. Zeeb phy_idx = RTW89_PHY_0; 15398e93258fSBjoern A. Zeeb else 15408e93258fSBjoern A. Zeeb phy_idx = RTW89_PHY_1; 15418e93258fSBjoern A. Zeeb 1542*df279a26SBjoern A. Zeeb _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); 15438e93258fSBjoern A. Zeeb _iqk_macbb_setting(rtwdev, phy_idx, path); 15448e93258fSBjoern A. Zeeb _iqk_preset(rtwdev, path); 1545*df279a26SBjoern A. Zeeb _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx); 15468e93258fSBjoern A. Zeeb _iqk_restore(rtwdev, path); 15478e93258fSBjoern A. Zeeb _iqk_afebb_restore(rtwdev, phy_idx, path); 15488e93258fSBjoern A. Zeeb } 15498e93258fSBjoern A. Zeeb 15508e93258fSBjoern A. Zeeb static void _rck(struct rtw89_dev *rtwdev, enum rtw89_rf_path path) 15518e93258fSBjoern A. Zeeb { 15528e93258fSBjoern A. Zeeb u32 rf_reg5, rck_val = 0; 15538e93258fSBjoern A. Zeeb u32 val; 15548e93258fSBjoern A. Zeeb int ret; 15558e93258fSBjoern A. Zeeb 15568e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] ====== S%d RCK ======\n", path); 15578e93258fSBjoern A. Zeeb 15588e93258fSBjoern A. Zeeb rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); 15598e93258fSBjoern A. Zeeb 15608e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 15618e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); 15628e93258fSBjoern A. Zeeb 15638e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RF0x00 = 0x%x\n", 15648e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK)); 15658e93258fSBjoern A. Zeeb 15668e93258fSBjoern A. Zeeb /* RCK trigger */ 15678e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, 0x00240); 15688e93258fSBjoern A. Zeeb 15698e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_read_rf, val, val, 2, 20, 15708e93258fSBjoern A. Zeeb false, rtwdev, path, 0x1c, BIT(3)); 15718e93258fSBjoern A. Zeeb if (ret) 15728e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[RCK] RCK timeout\n"); 15738e93258fSBjoern A. Zeeb 15748e93258fSBjoern A. Zeeb rck_val = rtw89_read_rf(rtwdev, path, RR_RCKC, RR_RCKC_CA); 15758e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKC, RFREG_MASK, rck_val); 15768e93258fSBjoern A. Zeeb 15778e93258fSBjoern A. Zeeb /* RCK_ADC_OFFSET */ 15788e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKO, RR_RCKO_OFF, 0x4); 15798e93258fSBjoern A. Zeeb 15808e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x1); 15818e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RFC, RR_RFC_CKEN, 0x0); 15828e93258fSBjoern A. Zeeb 15838e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); 15848e93258fSBjoern A. Zeeb 15858e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 15868e93258fSBjoern A. Zeeb "[RCK] RF 0x1b / 0x1c / 0x1d = 0x%x / 0x%x / 0x%x\n", 15878e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_RCKC, RFREG_MASK), 15888e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_RCKS, RFREG_MASK), 15898e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_RCKO, RFREG_MASK)); 15908e93258fSBjoern A. Zeeb } 15918e93258fSBjoern A. Zeeb 15928e93258fSBjoern A. Zeeb static void _iqk_init(struct rtw89_dev *rtwdev) 15938e93258fSBjoern A. Zeeb { 15948e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 15958e93258fSBjoern A. Zeeb u8 ch, path; 15968e93258fSBjoern A. Zeeb 15978e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_IQKINF, MASKDWORD); 15988e93258fSBjoern A. Zeeb if (iqk_info->is_iqk_init) 15998e93258fSBjoern A. Zeeb return; 16008e93258fSBjoern A. Zeeb 16018e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]===>%s\n", __func__); 16028e93258fSBjoern A. Zeeb iqk_info->is_iqk_init = true; 16038e93258fSBjoern A. Zeeb iqk_info->is_nbiqk = false; 16048e93258fSBjoern A. Zeeb iqk_info->iqk_fft_en = false; 16058e93258fSBjoern A. Zeeb iqk_info->iqk_sram_en = false; 16068e93258fSBjoern A. Zeeb iqk_info->iqk_cfir_en = false; 16078e93258fSBjoern A. Zeeb iqk_info->iqk_xym_en = false; 16088e93258fSBjoern A. Zeeb iqk_info->iqk_times = 0x0; 16098e93258fSBjoern A. Zeeb 16108e93258fSBjoern A. Zeeb for (ch = 0; ch < RTW89_IQK_CHS_NR; ch++) { 16118e93258fSBjoern A. Zeeb iqk_info->iqk_channel[ch] = 0x0; 16128e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_IQK_SS; path++) { 16138e93258fSBjoern A. Zeeb iqk_info->lok_cor_fail[ch][path] = false; 16148e93258fSBjoern A. Zeeb iqk_info->lok_fin_fail[ch][path] = false; 16158e93258fSBjoern A. Zeeb iqk_info->iqk_tx_fail[ch][path] = false; 16168e93258fSBjoern A. Zeeb iqk_info->iqk_rx_fail[ch][path] = false; 16178e93258fSBjoern A. Zeeb iqk_info->iqk_mcc_ch[ch][path] = 0x0; 16188e93258fSBjoern A. Zeeb iqk_info->iqk_table_idx[path] = 0x0; 16198e93258fSBjoern A. Zeeb } 16208e93258fSBjoern A. Zeeb } 16218e93258fSBjoern A. Zeeb } 16228e93258fSBjoern A. Zeeb 16238e93258fSBjoern A. Zeeb static void _doiqk(struct rtw89_dev *rtwdev, bool force, 1624*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy_idx, u8 path, 1625*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 16268e93258fSBjoern A. Zeeb { 16278e93258fSBjoern A. Zeeb struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; 16288e93258fSBjoern A. Zeeb u32 backup_bb_val[BACKUP_BB_REGS_NR]; 16298e93258fSBjoern A. Zeeb u32 backup_rf_val[RTW8852A_IQK_SS][BACKUP_RF_REGS_NR]; 1630*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, RF_AB, chanctx_idx); 16318e93258fSBjoern A. Zeeb 16328e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_START); 16338e93258fSBjoern A. Zeeb 16348e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 1635e2340276SBjoern A. Zeeb "[IQK]==========IQK start!!!!!==========\n"); 16368e93258fSBjoern A. Zeeb iqk_info->iqk_times++; 16378e93258fSBjoern A. Zeeb iqk_info->version = RTW8852A_IQK_VER; 16388e93258fSBjoern A. Zeeb 16398e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[IQK]Test Ver 0x%x\n", iqk_info->version); 1640*df279a26SBjoern A. Zeeb _iqk_get_ch_info(rtwdev, phy_idx, path, chanctx_idx); 16418e93258fSBjoern A. Zeeb _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); 16428e93258fSBjoern A. Zeeb _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); 16438e93258fSBjoern A. Zeeb _iqk_macbb_setting(rtwdev, phy_idx, path); 16448e93258fSBjoern A. Zeeb _iqk_preset(rtwdev, path); 1645*df279a26SBjoern A. Zeeb _iqk_start_iqk(rtwdev, phy_idx, path, chanctx_idx); 16468e93258fSBjoern A. Zeeb _iqk_restore(rtwdev, path); 16478e93258fSBjoern A. Zeeb _iqk_afebb_restore(rtwdev, phy_idx, path); 16488e93258fSBjoern A. Zeeb _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); 16498e93258fSBjoern A. Zeeb _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); 16508e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_ONESHOT_STOP); 16518e93258fSBjoern A. Zeeb } 16528e93258fSBjoern A. Zeeb 1653*df279a26SBjoern A. Zeeb static void _iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, bool force, 1654*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 16558e93258fSBjoern A. Zeeb { 16568e93258fSBjoern A. Zeeb switch (_kpath(rtwdev, phy_idx)) { 16578e93258fSBjoern A. Zeeb case RF_A: 1658*df279a26SBjoern A. Zeeb _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); 16598e93258fSBjoern A. Zeeb break; 16608e93258fSBjoern A. Zeeb case RF_B: 1661*df279a26SBjoern A. Zeeb _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); 16628e93258fSBjoern A. Zeeb break; 16638e93258fSBjoern A. Zeeb case RF_AB: 1664*df279a26SBjoern A. Zeeb _doiqk(rtwdev, force, phy_idx, RF_PATH_A, chanctx_idx); 1665*df279a26SBjoern A. Zeeb _doiqk(rtwdev, force, phy_idx, RF_PATH_B, chanctx_idx); 16668e93258fSBjoern A. Zeeb break; 16678e93258fSBjoern A. Zeeb default: 16688e93258fSBjoern A. Zeeb break; 16698e93258fSBjoern A. Zeeb } 16708e93258fSBjoern A. Zeeb } 16718e93258fSBjoern A. Zeeb 16728e93258fSBjoern A. Zeeb #define RXDCK_VER_8852A 0xe 16738e93258fSBjoern A. Zeeb 16748e93258fSBjoern A. Zeeb static void _set_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1675*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, bool is_afe, 1676*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 16778e93258fSBjoern A. Zeeb { 1678*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx); 16798e93258fSBjoern A. Zeeb u32 ori_val; 16808e93258fSBjoern A. Zeeb 16818e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 16828e93258fSBjoern A. Zeeb "[RX_DCK] ==== S%d RX DCK (by %s)====\n", 16838e93258fSBjoern A. Zeeb path, is_afe ? "AFE" : "RFC"); 16848e93258fSBjoern A. Zeeb 16858e93258fSBjoern A. Zeeb ori_val = rtw89_phy_read32_mask(rtwdev, R_P0_RXCK + (path << 13), MASKDWORD); 16868e93258fSBjoern A. Zeeb 16878e93258fSBjoern A. Zeeb if (is_afe) { 16888e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); 16898e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_P0_RXCK + (path << 13), B_P0_RXCK_ON); 16908e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), 16918e93258fSBjoern A. Zeeb B_P0_RXCK_VAL, 0x3); 16928e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_S0_RXDC2 + (path << 13), B_S0_RXDC2_MEN); 16938e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_S0_RXDC2 + (path << 13), 16948e93258fSBjoern A. Zeeb B_S0_RXDC2_AVG, 0x3); 16958e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR_PW15, B_ANAPAR_PW15_H, 0x3); 16968e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_ADCCLK); 16978e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); 16988e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_ANAPAR, B_ANAPAR_FLTRST); 16998e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_ANAPAR, B_ANAPAR_CRXBB, 0x1); 17008e93258fSBjoern A. Zeeb } 17018e93258fSBjoern A. Zeeb 17028e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK2, RR_DCK2_CYCLE, 0x3f); 17038e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK1, RR_DCK1_SEL, is_afe); 17048e93258fSBjoern A. Zeeb 17058e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_START); 17068e93258fSBjoern A. Zeeb 17078e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); 17088e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x1); 17098e93258fSBjoern A. Zeeb 17108e93258fSBjoern A. Zeeb fsleep(600); 17118e93258fSBjoern A. Zeeb 17128e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_ONESHOT_STOP); 17138e93258fSBjoern A. Zeeb 17148e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_LV, 0x0); 17158e93258fSBjoern A. Zeeb 17168e93258fSBjoern A. Zeeb if (is_afe) { 17178e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_P0_NRBW + (path << 13), B_P0_NRBW_DBG); 17188e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RXCK + (path << 13), 17198e93258fSBjoern A. Zeeb MASKDWORD, ori_val); 17208e93258fSBjoern A. Zeeb } 17218e93258fSBjoern A. Zeeb } 17228e93258fSBjoern A. Zeeb 17238e93258fSBjoern A. Zeeb static void _rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1724*df279a26SBjoern A. Zeeb bool is_afe, enum rtw89_chanctx_idx chanctx_idx) 17258e93258fSBjoern A. Zeeb { 17268e93258fSBjoern A. Zeeb u8 path, kpath, dck_tune; 17278e93258fSBjoern A. Zeeb u32 rf_reg5; 17288e93258fSBjoern A. Zeeb u32 addr; 17298e93258fSBjoern A. Zeeb 17308e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 17318e93258fSBjoern A. Zeeb "[RX_DCK] ****** RXDCK Start (Ver: 0x%x, Cv: %d) ******\n", 17328e93258fSBjoern A. Zeeb RXDCK_VER_8852A, rtwdev->hal.cv); 17338e93258fSBjoern A. Zeeb 17348e93258fSBjoern A. Zeeb kpath = _kpath(rtwdev, phy); 17358e93258fSBjoern A. Zeeb 17368e93258fSBjoern A. Zeeb for (path = 0; path < 2; path++) { 17378e93258fSBjoern A. Zeeb if (!(kpath & BIT(path))) 17388e93258fSBjoern A. Zeeb continue; 17398e93258fSBjoern A. Zeeb 17408e93258fSBjoern A. Zeeb rf_reg5 = rtw89_read_rf(rtwdev, path, RR_RSV1, RFREG_MASK); 17418e93258fSBjoern A. Zeeb dck_tune = (u8)rtw89_read_rf(rtwdev, path, RR_DCK, RR_DCK_FINE); 17428e93258fSBjoern A. Zeeb 17438e93258fSBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) { 17448e93258fSBjoern A. Zeeb addr = 0x5818 + (path << 13); 17458e93258fSBjoern A. Zeeb /* TSSI pause */ 17468e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, addr, BIT(30)); 17478e93258fSBjoern A. Zeeb } 17488e93258fSBjoern A. Zeeb 17498e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 17508e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, 0x0); 17518e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); 1752*df279a26SBjoern A. Zeeb _set_rx_dck(rtwdev, phy, path, is_afe, chanctx_idx); 17538e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_DCK, RR_DCK_FINE, dck_tune); 17548e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RFREG_MASK, rf_reg5); 17558e93258fSBjoern A. Zeeb 17568e93258fSBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) { 17578e93258fSBjoern A. Zeeb addr = 0x5818 + (path << 13); 17588e93258fSBjoern A. Zeeb /* TSSI resume */ 17598e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, addr, BIT(30)); 17608e93258fSBjoern A. Zeeb } 17618e93258fSBjoern A. Zeeb } 17628e93258fSBjoern A. Zeeb } 17638e93258fSBjoern A. Zeeb 17648e93258fSBjoern A. Zeeb #define RTW8852A_RF_REL_VERSION 34 17658e93258fSBjoern A. Zeeb #define RTW8852A_DPK_VER 0x10 17668e93258fSBjoern A. Zeeb #define RTW8852A_DPK_TH_AVG_NUM 4 17678e93258fSBjoern A. Zeeb #define RTW8852A_DPK_RF_PATH 2 17688e93258fSBjoern A. Zeeb #define RTW8852A_DPK_KIP_REG_NUM 2 17698e93258fSBjoern A. Zeeb 17708e93258fSBjoern A. Zeeb enum rtw8852a_dpk_id { 17718e93258fSBjoern A. Zeeb LBK_RXIQK = 0x06, 17728e93258fSBjoern A. Zeeb SYNC = 0x10, 17738e93258fSBjoern A. Zeeb MDPK_IDL = 0x11, 17748e93258fSBjoern A. Zeeb MDPK_MPA = 0x12, 17758e93258fSBjoern A. Zeeb GAIN_LOSS = 0x13, 17768e93258fSBjoern A. Zeeb GAIN_CAL = 0x14, 17778e93258fSBjoern A. Zeeb }; 17788e93258fSBjoern A. Zeeb 17798e93258fSBjoern A. Zeeb static void _rf_direct_cntrl(struct rtw89_dev *rtwdev, 17808e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool is_bybb) 17818e93258fSBjoern A. Zeeb { 17828e93258fSBjoern A. Zeeb if (is_bybb) 17838e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x1); 17848e93258fSBjoern A. Zeeb else 17858e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV1, RR_RSV1_RST, 0x0); 17868e93258fSBjoern A. Zeeb } 17878e93258fSBjoern A. Zeeb 17888e93258fSBjoern A. Zeeb static void _dpk_onoff(struct rtw89_dev *rtwdev, 17898e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool off); 17908e93258fSBjoern A. Zeeb 17918e93258fSBjoern A. Zeeb static void _dpk_bkup_kip(struct rtw89_dev *rtwdev, u32 *reg, 17928e93258fSBjoern A. Zeeb u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], 17938e93258fSBjoern A. Zeeb u8 path) 17948e93258fSBjoern A. Zeeb { 17958e93258fSBjoern A. Zeeb u8 i; 17968e93258fSBjoern A. Zeeb 17978e93258fSBjoern A. Zeeb for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { 17988e93258fSBjoern A. Zeeb reg_bkup[path][i] = rtw89_phy_read32_mask(rtwdev, 17998e93258fSBjoern A. Zeeb reg[i] + (path << 8), 18008e93258fSBjoern A. Zeeb MASKDWORD); 18018e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Backup 0x%x = %x\n", 18028e93258fSBjoern A. Zeeb reg[i] + (path << 8), reg_bkup[path][i]); 18038e93258fSBjoern A. Zeeb } 18048e93258fSBjoern A. Zeeb } 18058e93258fSBjoern A. Zeeb 18068e93258fSBjoern A. Zeeb static void _dpk_reload_kip(struct rtw89_dev *rtwdev, u32 *reg, 18078e93258fSBjoern A. Zeeb u32 reg_bkup[][RTW8852A_DPK_KIP_REG_NUM], u8 path) 18088e93258fSBjoern A. Zeeb { 18098e93258fSBjoern A. Zeeb u8 i; 18108e93258fSBjoern A. Zeeb 18118e93258fSBjoern A. Zeeb for (i = 0; i < RTW8852A_DPK_KIP_REG_NUM; i++) { 18128e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, reg[i] + (path << 8), 18138e93258fSBjoern A. Zeeb MASKDWORD, reg_bkup[path][i]); 18148e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] Reload 0x%x = %x\n", 18158e93258fSBjoern A. Zeeb reg[i] + (path << 8), reg_bkup[path][i]); 18168e93258fSBjoern A. Zeeb } 18178e93258fSBjoern A. Zeeb } 18188e93258fSBjoern A. Zeeb 18198e93258fSBjoern A. Zeeb static u8 _dpk_one_shot(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 1820*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, enum rtw8852a_dpk_id id, 1821*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 18228e93258fSBjoern A. Zeeb { 1823*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_path_phymap(rtwdev, phy, path, chanctx_idx); 18248e93258fSBjoern A. Zeeb u16 dpk_cmd = 0x0; 18258e93258fSBjoern A. Zeeb u32 val; 18268e93258fSBjoern A. Zeeb int ret; 18278e93258fSBjoern A. Zeeb 18288e93258fSBjoern A. Zeeb dpk_cmd = (u16)((id << 8) | (0x19 + (path << 4))); 18298e93258fSBjoern A. Zeeb 18308e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_START); 18318e93258fSBjoern A. Zeeb 18328e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, MASKDWORD, dpk_cmd); 18338e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_DPK_CTL, B_DPK_CTL_EN); 18348e93258fSBjoern A. Zeeb 18358e93258fSBjoern A. Zeeb ret = read_poll_timeout_atomic(rtw89_phy_read32_mask, val, val == 0x55, 18368e93258fSBjoern A. Zeeb 10, 20000, false, rtwdev, 0xbff8, MASKBYTE0); 18378e93258fSBjoern A. Zeeb 18388e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_N1, MASKBYTE0); 18398e93258fSBjoern A. Zeeb 18408e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_ONESHOT_STOP); 18418e93258fSBjoern A. Zeeb 18428e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 18438e93258fSBjoern A. Zeeb "[DPK] one-shot for %s = 0x%x (ret=%d)\n", 18448e93258fSBjoern A. Zeeb id == 0x06 ? "LBK_RXIQK" : 18458e93258fSBjoern A. Zeeb id == 0x10 ? "SYNC" : 18468e93258fSBjoern A. Zeeb id == 0x11 ? "MDPK_IDL" : 18478e93258fSBjoern A. Zeeb id == 0x12 ? "MDPK_MPA" : 18488e93258fSBjoern A. Zeeb id == 0x13 ? "GAIN_LOSS" : "PWR_CAL", 18498e93258fSBjoern A. Zeeb dpk_cmd, ret); 18508e93258fSBjoern A. Zeeb 18518e93258fSBjoern A. Zeeb if (ret) { 18528e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 18538e93258fSBjoern A. Zeeb "[DPK] one-shot over 20ms!!!!\n"); 18548e93258fSBjoern A. Zeeb return 1; 18558e93258fSBjoern A. Zeeb } 18568e93258fSBjoern A. Zeeb 18578e93258fSBjoern A. Zeeb return 0; 18588e93258fSBjoern A. Zeeb } 18598e93258fSBjoern A. Zeeb 18608e93258fSBjoern A. Zeeb static void _dpk_rx_dck(struct rtw89_dev *rtwdev, 18618e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 1862*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, 1863*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 18648e93258fSBjoern A. Zeeb { 18658e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB2, RR_EN_TIA_IDA, 0x3); 1866*df279a26SBjoern A. Zeeb _set_rx_dck(rtwdev, phy, path, false, chanctx_idx); 18678e93258fSBjoern A. Zeeb } 18688e93258fSBjoern A. Zeeb 18698e93258fSBjoern A. Zeeb static void _dpk_information(struct rtw89_dev *rtwdev, 18708e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 1871*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) 18728e93258fSBjoern A. Zeeb { 18738e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 1874*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 18758e93258fSBjoern A. Zeeb u8 kidx = dpk->cur_idx[path]; 18768e93258fSBjoern A. Zeeb 18778e93258fSBjoern A. Zeeb dpk->bp[path][kidx].band = chan->band_type; 18788e93258fSBjoern A. Zeeb dpk->bp[path][kidx].ch = chan->channel; 18798e93258fSBjoern A. Zeeb dpk->bp[path][kidx].bw = chan->band_width; 18808e93258fSBjoern A. Zeeb 18818e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 18828e93258fSBjoern A. Zeeb "[DPK] S%d[%d] (PHY%d): TSSI %s/ DBCC %s/ %s/ CH%d/ %s\n", 18838e93258fSBjoern A. Zeeb path, dpk->cur_idx[path], phy, 18848e93258fSBjoern A. Zeeb rtwdev->is_tssi_mode[path] ? "on" : "off", 18858e93258fSBjoern A. Zeeb rtwdev->dbcc_en ? "on" : "off", 18868e93258fSBjoern A. Zeeb dpk->bp[path][kidx].band == 0 ? "2G" : 18878e93258fSBjoern A. Zeeb dpk->bp[path][kidx].band == 1 ? "5G" : "6G", 18888e93258fSBjoern A. Zeeb dpk->bp[path][kidx].ch, 18898e93258fSBjoern A. Zeeb dpk->bp[path][kidx].bw == 0 ? "20M" : 18908e93258fSBjoern A. Zeeb dpk->bp[path][kidx].bw == 1 ? "40M" : "80M"); 18918e93258fSBjoern A. Zeeb } 18928e93258fSBjoern A. Zeeb 18938e93258fSBjoern A. Zeeb static void _dpk_bb_afe_setting(struct rtw89_dev *rtwdev, 18948e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 18958e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kpath) 18968e93258fSBjoern A. Zeeb { 18978e93258fSBjoern A. Zeeb switch (kpath) { 18988e93258fSBjoern A. Zeeb case RF_A: 18998e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_a_tbl); 19008e93258fSBjoern A. Zeeb 19018e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x0) 19028e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); 19038e93258fSBjoern A. Zeeb 19048e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_a_tbl); 19058e93258fSBjoern A. Zeeb break; 19068e93258fSBjoern A. Zeeb case RF_B: 19078e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sf_defs_b_tbl); 19088e93258fSBjoern A. Zeeb 19098e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_2P4G_BAND, B_2P4G_BAND_SEL) == 0x1) 19108e93258fSBjoern A. Zeeb rtw89_phy_write32_set(rtwdev, R_RXCCA, B_RXCCA_DIS); 19118e93258fSBjoern A. Zeeb 19128e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_sr_defs_b_tbl); 19138e93258fSBjoern A. Zeeb break; 19148e93258fSBjoern A. Zeeb case RF_AB: 19158e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_s_defs_ab_tbl); 19168e93258fSBjoern A. Zeeb break; 19178e93258fSBjoern A. Zeeb default: 19188e93258fSBjoern A. Zeeb break; 19198e93258fSBjoern A. Zeeb } 19208e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 19218e93258fSBjoern A. Zeeb "[DPK] Set BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); 19228e93258fSBjoern A. Zeeb } 19238e93258fSBjoern A. Zeeb 19248e93258fSBjoern A. Zeeb static void _dpk_bb_afe_restore(struct rtw89_dev *rtwdev, 19258e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 19268e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kpath) 19278e93258fSBjoern A. Zeeb { 19288e93258fSBjoern A. Zeeb switch (kpath) { 19298e93258fSBjoern A. Zeeb case RF_A: 19308e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_a_tbl); 19318e93258fSBjoern A. Zeeb break; 19328e93258fSBjoern A. Zeeb case RF_B: 19338e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_b_tbl); 19348e93258fSBjoern A. Zeeb break; 19358e93258fSBjoern A. Zeeb case RF_AB: 19368e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_bb_afe_r_defs_ab_tbl); 19378e93258fSBjoern A. Zeeb break; 19388e93258fSBjoern A. Zeeb default: 19398e93258fSBjoern A. Zeeb break; 19408e93258fSBjoern A. Zeeb } 19418e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 19428e93258fSBjoern A. Zeeb "[DPK] Restore BB/AFE for PHY%d (kpath=%d)\n", phy, kpath); 19438e93258fSBjoern A. Zeeb } 19448e93258fSBjoern A. Zeeb 19458e93258fSBjoern A. Zeeb static void _dpk_tssi_pause(struct rtw89_dev *rtwdev, 19468e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool is_pause) 19478e93258fSBjoern A. Zeeb { 19488e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK + (path << 13), 19498e93258fSBjoern A. Zeeb B_P0_TSSI_TRK_EN, is_pause); 19508e93258fSBjoern A. Zeeb 19518e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d TSSI %s\n", path, 19528e93258fSBjoern A. Zeeb is_pause ? "pause" : "resume"); 19538e93258fSBjoern A. Zeeb } 19548e93258fSBjoern A. Zeeb 19558e93258fSBjoern A. Zeeb static void _dpk_kip_setting(struct rtw89_dev *rtwdev, 19568e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 19578e93258fSBjoern A. Zeeb { 19588e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_RPT, MASKDWORD, 0x00000080); 19598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_CLK, MASKDWORD, 0x00093f3f); 19608e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x807f030a); 19618e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0xce000a08); 19628e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG, B_DPK_CFG_IDX, 0x2); 19638e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_NCTL_CFG, B_NCTL_CFG_SPAGE, path); /*subpage_id*/ 19648e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8) + (kidx << 2), 19658e93258fSBjoern A. Zeeb MASKDWORD, 0x003f2e2e); 19668e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 19678e93258fSBjoern A. Zeeb MASKDWORD, 0x005b5b5b); 19688e93258fSBjoern A. Zeeb 19698e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] KIP setting for S%d[%d]!!\n", 19708e93258fSBjoern A. Zeeb path, kidx); 19718e93258fSBjoern A. Zeeb } 19728e93258fSBjoern A. Zeeb 19738e93258fSBjoern A. Zeeb static void _dpk_kip_restore(struct rtw89_dev *rtwdev, 19748e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 19758e93258fSBjoern A. Zeeb { 19768e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_NCTL_RPT, MASKDWORD); 19778e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_SYSCFG, MASKDWORD, 0x80000000); 19788e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_CFIR_SYS + (path << 8), MASKDWORD, 0x10010000); 19798e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP_CLK, MASKDWORD); 19808e93258fSBjoern A. Zeeb 19818e93258fSBjoern A. Zeeb if (rtwdev->hal.cv > CHIP_CBV) 19828e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_COM + (path << 8), BIT(15), 0x1); 19838e93258fSBjoern A. Zeeb 19848e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d restore KIP\n", path); 19858e93258fSBjoern A. Zeeb } 19868e93258fSBjoern A. Zeeb 19878e93258fSBjoern A. Zeeb static void _dpk_lbk_rxiqk(struct rtw89_dev *rtwdev, 19888e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 1989*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, 1990*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 19918e93258fSBjoern A. Zeeb { 19928e93258fSBjoern A. Zeeb u8 cur_rxbb; 19938e93258fSBjoern A. Zeeb 19948e93258fSBjoern A. Zeeb cur_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); 19958e93258fSBjoern A. Zeeb 19968e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_f_tbl); 19978e93258fSBjoern A. Zeeb 19988e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, 0xc); 19998e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x1); 20008e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x2); 20018e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RSV4, RFREG_MASK, 20028e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_CFGCH, RFREG_MASK)); 20038e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_OFF, 0x13); 20048e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); 20058e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x1); 20068e93258fSBjoern A. Zeeb 20078e93258fSBjoern A. Zeeb fsleep(70); 20088e93258fSBjoern A. Zeeb 20098e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTL, 0x1f); 20108e93258fSBjoern A. Zeeb 20118e93258fSBjoern A. Zeeb if (cur_rxbb <= 0xa) 20128e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x3); 20138e93258fSBjoern A. Zeeb else if (cur_rxbb <= 0x10 && cur_rxbb >= 0xb) 20148e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x1); 20158e93258fSBjoern A. Zeeb else 20168e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXIQGEN, RR_RXIQGEN_ATTH, 0x0); 20178e93258fSBjoern A. Zeeb 20188e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_RXT, 0x11); 20198e93258fSBjoern A. Zeeb 2020*df279a26SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, LBK_RXIQK, chanctx_idx); 20218e93258fSBjoern A. Zeeb 20228e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d LBK RXIQC = 0x%x\n", path, 20238e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC, MASKDWORD)); 20248e93258fSBjoern A. Zeeb 20258e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXK, RR_RXK_PLLEN, 0x0); 20268e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXPOW, RR_RXPOW_IQK, 0x0); 20278e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXKPLL, RR_RXKPLL_POW, 0x0); /*POW IQKPLL*/ 20288e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_DPK); 20298e93258fSBjoern A. Zeeb 20308e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_lbk_rxiqk_defs_r_tbl); 20318e93258fSBjoern A. Zeeb } 20328e93258fSBjoern A. Zeeb 20338e93258fSBjoern A. Zeeb static void _dpk_get_thermal(struct rtw89_dev *rtwdev, u8 kidx, 20348e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 20358e93258fSBjoern A. Zeeb { 20368e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 20378e93258fSBjoern A. Zeeb 20388e93258fSBjoern A. Zeeb dpk->bp[path][kidx].ther_dpk = 20398e93258fSBjoern A. Zeeb ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); 20408e93258fSBjoern A. Zeeb 20418e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] thermal@DPK = 0x%x\n", 20428e93258fSBjoern A. Zeeb dpk->bp[path][kidx].ther_dpk); 20438e93258fSBjoern A. Zeeb } 20448e93258fSBjoern A. Zeeb 20458e93258fSBjoern A. Zeeb static u8 _dpk_set_tx_pwr(struct rtw89_dev *rtwdev, u8 gain, 20468e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 20478e93258fSBjoern A. Zeeb { 20488e93258fSBjoern A. Zeeb u8 txagc_ori = 0x38; 20498e93258fSBjoern A. Zeeb 20508e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc_ori); 20518e93258fSBjoern A. Zeeb 20528e93258fSBjoern A. Zeeb return txagc_ori; 20538e93258fSBjoern A. Zeeb } 20548e93258fSBjoern A. Zeeb 20558e93258fSBjoern A. Zeeb static void _dpk_rf_setting(struct rtw89_dev *rtwdev, u8 gain, 20568e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx) 20578e93258fSBjoern A. Zeeb { 20588e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 20598e93258fSBjoern A. Zeeb 20608e93258fSBjoern A. Zeeb if (dpk->bp[path][kidx].band == RTW89_BAND_2G) { 20618e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x280b); 20628e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTC, 0x0); 20638e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXBB, RR_RXBB_ATTR, 0x4); 20648e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MIXER, RR_MIXER_GN, 0x0); 20658e93258fSBjoern A. Zeeb } else { 20668e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_DPK, 0x282e); 20678e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BIASA2, RR_BIASA2_LB, 0x7); 20688e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXATANK, RR_TXATANK_LBSW, 0x3); 20698e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RXA, RR_RXA_DPK, 0x3); 20708e93258fSBjoern A. Zeeb } 20718e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_RCKD, RR_RCKD_BW, 0x1); 20728e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_TXBB, dpk->bp[path][kidx].bw + 1); 20738e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_BTC, RR_BTC_RXBB, 0x0); 20748e93258fSBjoern A. Zeeb 20758e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 20768e93258fSBjoern A. Zeeb "[DPK] RF 0x0/0x1/0x1a = 0x%x/ 0x%x/ 0x%x\n", 20778e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MOD, RFREG_MASK), 20788e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK), 20798e93258fSBjoern A. Zeeb rtw89_read_rf(rtwdev, path, RR_BTC, RFREG_MASK)); 20808e93258fSBjoern A. Zeeb } 20818e93258fSBjoern A. Zeeb 20828e93258fSBjoern A. Zeeb static void _dpk_manual_txcfir(struct rtw89_dev *rtwdev, 20838e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool is_manual) 20848e93258fSBjoern A. Zeeb { 20858e93258fSBjoern A. Zeeb u8 tmp_pad, tmp_txbb; 20868e93258fSBjoern A. Zeeb 20878e93258fSBjoern A. Zeeb if (is_manual) { 20888e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN, 0x1); 20898e93258fSBjoern A. Zeeb tmp_pad = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_PAD); 20908e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), 20918e93258fSBjoern A. Zeeb B_RFGAIN_PAD, tmp_pad); 20928e93258fSBjoern A. Zeeb 20938e93258fSBjoern A. Zeeb tmp_txbb = (u8)rtw89_read_rf(rtwdev, path, RR_GAINTX, RR_GAINTX_BB); 20948e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RFGAIN + (path << 8), 20958e93258fSBjoern A. Zeeb B_RFGAIN_TXBB, tmp_txbb); 20968e93258fSBjoern A. Zeeb 20978e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), 20988e93258fSBjoern A. Zeeb B_LOAD_COEF_CFIR, 0x1); 20998e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), 21008e93258fSBjoern A. Zeeb B_LOAD_COEF_CFIR); 21018e93258fSBjoern A. Zeeb 21028e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), BIT(1), 0x1); 21038e93258fSBjoern A. Zeeb 21048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21058e93258fSBjoern A. Zeeb "[DPK] PAD_man / TXBB_man = 0x%x / 0x%x\n", tmp_pad, 21068e93258fSBjoern A. Zeeb tmp_txbb); 21078e93258fSBjoern A. Zeeb } else { 21088e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP + (path << 8), B_KIP_RFGAIN); 21098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21108e93258fSBjoern A. Zeeb "[DPK] disable manual switch TXCFIR\n"); 21118e93258fSBjoern A. Zeeb } 21128e93258fSBjoern A. Zeeb } 21138e93258fSBjoern A. Zeeb 21148e93258fSBjoern A. Zeeb static void _dpk_bypass_rxcfir(struct rtw89_dev *rtwdev, 21158e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool is_bypass) 21168e93258fSBjoern A. Zeeb { 21178e93258fSBjoern A. Zeeb if (is_bypass) { 21188e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 21198e93258fSBjoern A. Zeeb B_RXIQC_BYPASS2, 0x1); 21208e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_RXIQC + (path << 8), 21218e93258fSBjoern A. Zeeb B_RXIQC_BYPASS, 0x1); 21228e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21238e93258fSBjoern A. Zeeb "[DPK] Bypass RXIQC (0x8%d3c = 0x%x)\n", 1 + path, 21248e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), 21258e93258fSBjoern A. Zeeb MASKDWORD)); 21268e93258fSBjoern A. Zeeb } else { 21278e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS2); 21288e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_RXIQC + (path << 8), B_RXIQC_BYPASS); 21298e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21308e93258fSBjoern A. Zeeb "[DPK] restore 0x8%d3c = 0x%x\n", 1 + path, 21318e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RXIQC + (path << 8), 21328e93258fSBjoern A. Zeeb MASKDWORD)); 21338e93258fSBjoern A. Zeeb } 21348e93258fSBjoern A. Zeeb } 21358e93258fSBjoern A. Zeeb 21368e93258fSBjoern A. Zeeb static 21378e93258fSBjoern A. Zeeb void _dpk_tpg_sel(struct rtw89_dev *rtwdev, enum rtw89_rf_path path, u8 kidx) 21388e93258fSBjoern A. Zeeb { 21398e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 21408e93258fSBjoern A. Zeeb 21418e93258fSBjoern A. Zeeb if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80) 21428e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_TPG_MOD, B_TPG_MOD_F); 21438e93258fSBjoern A. Zeeb else if (dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40) 21448e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x2); 21458e93258fSBjoern A. Zeeb else 21468e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TPG_MOD, B_TPG_MOD_F, 0x1); 21478e93258fSBjoern A. Zeeb 21488e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] TPG_Select for %s\n", 21498e93258fSBjoern A. Zeeb dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_80 ? "80M" : 21508e93258fSBjoern A. Zeeb dpk->bp[path][kidx].bw == RTW89_CHANNEL_WIDTH_40 ? "40M" : "20M"); 21518e93258fSBjoern A. Zeeb } 21528e93258fSBjoern A. Zeeb 21538e93258fSBjoern A. Zeeb static void _dpk_table_select(struct rtw89_dev *rtwdev, 21548e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, u8 gain) 21558e93258fSBjoern A. Zeeb { 21568e93258fSBjoern A. Zeeb u8 val; 21578e93258fSBjoern A. Zeeb 21588e93258fSBjoern A. Zeeb val = 0x80 + kidx * 0x20 + gain * 0x10; 21598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0 + (path << 8), MASKBYTE3, val); 21608e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21618e93258fSBjoern A. Zeeb "[DPK] table select for Kidx[%d], Gain[%d] (0x%x)\n", kidx, 21628e93258fSBjoern A. Zeeb gain, val); 21638e93258fSBjoern A. Zeeb } 21648e93258fSBjoern A. Zeeb 21658e93258fSBjoern A. Zeeb static bool _dpk_sync_check(struct rtw89_dev *rtwdev, 21668e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 21678e93258fSBjoern A. Zeeb { 21688e93258fSBjoern A. Zeeb #define DPK_SYNC_TH_DC_I 200 21698e93258fSBjoern A. Zeeb #define DPK_SYNC_TH_DC_Q 200 21708e93258fSBjoern A. Zeeb #define DPK_SYNC_TH_CORR 170 21718e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 21728e93258fSBjoern A. Zeeb u16 dc_i, dc_q; 21738e93258fSBjoern A. Zeeb u8 corr_val, corr_idx; 21748e93258fSBjoern A. Zeeb 21758e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); 21768e93258fSBjoern A. Zeeb 21778e93258fSBjoern A. Zeeb corr_idx = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORI); 21788e93258fSBjoern A. Zeeb corr_val = (u8)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_CORV); 21798e93258fSBjoern A. Zeeb 21808e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 21818e93258fSBjoern A. Zeeb "[DPK] S%d Corr_idx / Corr_val = %d / %d\n", path, corr_idx, 21828e93258fSBjoern A. Zeeb corr_val); 21838e93258fSBjoern A. Zeeb 21848e93258fSBjoern A. Zeeb dpk->corr_idx[path][0] = corr_idx; 21858e93258fSBjoern A. Zeeb dpk->corr_val[path][0] = corr_val; 21868e93258fSBjoern A. Zeeb 21878e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x9); 21888e93258fSBjoern A. Zeeb 21898e93258fSBjoern A. Zeeb dc_i = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); 21908e93258fSBjoern A. Zeeb dc_q = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCQ); 21918e93258fSBjoern A. Zeeb 21928e93258fSBjoern A. Zeeb dc_i = abs(sign_extend32(dc_i, 11)); 21938e93258fSBjoern A. Zeeb dc_q = abs(sign_extend32(dc_q, 11)); 21948e93258fSBjoern A. Zeeb 21958e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d DC I/Q, = %d / %d\n", 21968e93258fSBjoern A. Zeeb path, dc_i, dc_q); 21978e93258fSBjoern A. Zeeb 21988e93258fSBjoern A. Zeeb dpk->dc_i[path][0] = dc_i; 21998e93258fSBjoern A. Zeeb dpk->dc_q[path][0] = dc_q; 22008e93258fSBjoern A. Zeeb 22018e93258fSBjoern A. Zeeb if (dc_i > DPK_SYNC_TH_DC_I || dc_q > DPK_SYNC_TH_DC_Q || 22028e93258fSBjoern A. Zeeb corr_val < DPK_SYNC_TH_CORR) 22038e93258fSBjoern A. Zeeb return true; 22048e93258fSBjoern A. Zeeb else 22058e93258fSBjoern A. Zeeb return false; 22068e93258fSBjoern A. Zeeb } 22078e93258fSBjoern A. Zeeb 22088e93258fSBjoern A. Zeeb static bool _dpk_sync(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2209*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, 2210*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 22118e93258fSBjoern A. Zeeb { 22128e93258fSBjoern A. Zeeb _dpk_tpg_sel(rtwdev, path, kidx); 2213*df279a26SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, SYNC, chanctx_idx); 22148e93258fSBjoern A. Zeeb return _dpk_sync_check(rtwdev, path); /*1= fail*/ 22158e93258fSBjoern A. Zeeb } 22168e93258fSBjoern A. Zeeb 22178e93258fSBjoern A. Zeeb static u16 _dpk_dgain_read(struct rtw89_dev *rtwdev) 22188e93258fSBjoern A. Zeeb { 22198e93258fSBjoern A. Zeeb u16 dgain = 0x0; 22208e93258fSBjoern A. Zeeb 22218e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL); 22228e93258fSBjoern A. Zeeb 22238e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_SYNERR); 22248e93258fSBjoern A. Zeeb 22258e93258fSBjoern A. Zeeb dgain = (u16)rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_DCI); 22268e93258fSBjoern A. Zeeb 22278e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] DGain = 0x%x (%d)\n", dgain, 22288e93258fSBjoern A. Zeeb dgain); 22298e93258fSBjoern A. Zeeb 22308e93258fSBjoern A. Zeeb return dgain; 22318e93258fSBjoern A. Zeeb } 22328e93258fSBjoern A. Zeeb 22338e93258fSBjoern A. Zeeb static s8 _dpk_dgain_mapping(struct rtw89_dev *rtwdev, u16 dgain) 22348e93258fSBjoern A. Zeeb { 22358e93258fSBjoern A. Zeeb s8 offset; 22368e93258fSBjoern A. Zeeb 22378e93258fSBjoern A. Zeeb if (dgain >= 0x783) 22388e93258fSBjoern A. Zeeb offset = 0x6; 22398e93258fSBjoern A. Zeeb else if (dgain <= 0x782 && dgain >= 0x551) 22408e93258fSBjoern A. Zeeb offset = 0x3; 22418e93258fSBjoern A. Zeeb else if (dgain <= 0x550 && dgain >= 0x3c4) 22428e93258fSBjoern A. Zeeb offset = 0x0; 22438e93258fSBjoern A. Zeeb else if (dgain <= 0x3c3 && dgain >= 0x2aa) 22448e93258fSBjoern A. Zeeb offset = -3; 22458e93258fSBjoern A. Zeeb else if (dgain <= 0x2a9 && dgain >= 0x1e3) 22468e93258fSBjoern A. Zeeb offset = -6; 22478e93258fSBjoern A. Zeeb else if (dgain <= 0x1e2 && dgain >= 0x156) 22488e93258fSBjoern A. Zeeb offset = -9; 22498e93258fSBjoern A. Zeeb else if (dgain <= 0x155) 22508e93258fSBjoern A. Zeeb offset = -12; 22518e93258fSBjoern A. Zeeb else 22528e93258fSBjoern A. Zeeb offset = 0x0; 22538e93258fSBjoern A. Zeeb 22548e93258fSBjoern A. Zeeb return offset; 22558e93258fSBjoern A. Zeeb } 22568e93258fSBjoern A. Zeeb 22578e93258fSBjoern A. Zeeb static u8 _dpk_gainloss_read(struct rtw89_dev *rtwdev) 22588e93258fSBjoern A. Zeeb { 22598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_KIP_RPT1, B_KIP_RPT1_SEL, 0x6); 22608e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG2, B_DPK_CFG2_ST, 0x1); 22618e93258fSBjoern A. Zeeb return rtw89_phy_read32_mask(rtwdev, R_RPT_COM, B_PRT_COM_GL); 22628e93258fSBjoern A. Zeeb } 22638e93258fSBjoern A. Zeeb 22648e93258fSBjoern A. Zeeb static void _dpk_gainloss(struct rtw89_dev *rtwdev, 22658e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, enum rtw89_rf_path path, 2266*df279a26SBjoern A. Zeeb u8 kidx, enum rtw89_chanctx_idx chanctx_idx) 22678e93258fSBjoern A. Zeeb { 22688e93258fSBjoern A. Zeeb _dpk_table_select(rtwdev, path, kidx, 1); 2269*df279a26SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, GAIN_LOSS, chanctx_idx); 22708e93258fSBjoern A. Zeeb } 22718e93258fSBjoern A. Zeeb 22728e93258fSBjoern A. Zeeb #define DPK_TXAGC_LOWER 0x2e 22738e93258fSBjoern A. Zeeb #define DPK_TXAGC_UPPER 0x3f 22748e93258fSBjoern A. Zeeb #define DPK_TXAGC_INVAL 0xff 22758e93258fSBjoern A. Zeeb 22768e93258fSBjoern A. Zeeb static u8 _dpk_set_offset(struct rtw89_dev *rtwdev, 22778e93258fSBjoern A. Zeeb enum rtw89_rf_path path, s8 gain_offset) 22788e93258fSBjoern A. Zeeb { 22798e93258fSBjoern A. Zeeb u8 txagc; 22808e93258fSBjoern A. Zeeb 22818e93258fSBjoern A. Zeeb txagc = (u8)rtw89_read_rf(rtwdev, path, RR_MODOPT, RFREG_MASK); 22828e93258fSBjoern A. Zeeb 22838e93258fSBjoern A. Zeeb if (txagc - gain_offset < DPK_TXAGC_LOWER) 22848e93258fSBjoern A. Zeeb txagc = DPK_TXAGC_LOWER; 22858e93258fSBjoern A. Zeeb else if (txagc - gain_offset > DPK_TXAGC_UPPER) 22868e93258fSBjoern A. Zeeb txagc = DPK_TXAGC_UPPER; 22878e93258fSBjoern A. Zeeb else 22888e93258fSBjoern A. Zeeb txagc = txagc - gain_offset; 22898e93258fSBjoern A. Zeeb 22908e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MODOPT, RFREG_MASK, txagc); 22918e93258fSBjoern A. Zeeb 22928e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] tmp_txagc (GL=%d) = 0x%x\n", 22938e93258fSBjoern A. Zeeb gain_offset, txagc); 22948e93258fSBjoern A. Zeeb return txagc; 22958e93258fSBjoern A. Zeeb } 22968e93258fSBjoern A. Zeeb 22978e93258fSBjoern A. Zeeb enum dpk_agc_step { 22988e93258fSBjoern A. Zeeb DPK_AGC_STEP_SYNC_DGAIN, 22998e93258fSBjoern A. Zeeb DPK_AGC_STEP_GAIN_ADJ, 23008e93258fSBjoern A. Zeeb DPK_AGC_STEP_GAIN_LOSS_IDX, 23018e93258fSBjoern A. Zeeb DPK_AGC_STEP_GL_GT_CRITERION, 23028e93258fSBjoern A. Zeeb DPK_AGC_STEP_GL_LT_CRITERION, 23038e93258fSBjoern A. Zeeb DPK_AGC_STEP_SET_TX_GAIN, 23048e93258fSBjoern A. Zeeb }; 23058e93258fSBjoern A. Zeeb 23068e93258fSBjoern A. Zeeb static u8 _dpk_pas_read(struct rtw89_dev *rtwdev, bool is_check) 23078e93258fSBjoern A. Zeeb { 23088e93258fSBjoern A. Zeeb u32 val1_i = 0, val1_q = 0, val2_i = 0, val2_q = 0; 23098e93258fSBjoern A. Zeeb u8 i; 23108e93258fSBjoern A. Zeeb 23118e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_rfk_dpk_pas_read_defs_tbl); 23128e93258fSBjoern A. Zeeb 23138e93258fSBjoern A. Zeeb if (is_check) { 23148e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x00); 23158e93258fSBjoern A. Zeeb val1_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); 23168e93258fSBjoern A. Zeeb val1_i = abs(sign_extend32(val1_i, 11)); 23178e93258fSBjoern A. Zeeb val1_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); 23188e93258fSBjoern A. Zeeb val1_q = abs(sign_extend32(val1_q, 11)); 23198e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, 0x1f); 23208e93258fSBjoern A. Zeeb val2_i = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKHWORD); 23218e93258fSBjoern A. Zeeb val2_i = abs(sign_extend32(val2_i, 11)); 23228e93258fSBjoern A. Zeeb val2_q = rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKLWORD); 23238e93258fSBjoern A. Zeeb val2_q = abs(sign_extend32(val2_q, 11)); 23248e93258fSBjoern A. Zeeb 23258e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] PAS_delta = 0x%x\n", 23268e93258fSBjoern A. Zeeb phy_div(val1_i * val1_i + val1_q * val1_q, 23278e93258fSBjoern A. Zeeb val2_i * val2_i + val2_q * val2_q)); 23288e93258fSBjoern A. Zeeb 23298e93258fSBjoern A. Zeeb } else { 23308e93258fSBjoern A. Zeeb for (i = 0; i < 32; i++) { 23318e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPK_CFG3, MASKBYTE3, i); 23328e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 23338e93258fSBjoern A. Zeeb "[DPK] PAS_Read[%02d]= 0x%08x\n", i, 23348e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_RPT_COM, MASKDWORD)); 23358e93258fSBjoern A. Zeeb } 23368e93258fSBjoern A. Zeeb } 23378e93258fSBjoern A. Zeeb if ((val1_i * val1_i + val1_q * val1_q) >= 23388e93258fSBjoern A. Zeeb ((val2_i * val2_i + val2_q * val2_q) * 8 / 5)) 23398e93258fSBjoern A. Zeeb return 1; 23408e93258fSBjoern A. Zeeb else 23418e93258fSBjoern A. Zeeb return 0; 23428e93258fSBjoern A. Zeeb } 23438e93258fSBjoern A. Zeeb 23448e93258fSBjoern A. Zeeb static u8 _dpk_agc(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 23458e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, u8 init_txagc, 2346*df279a26SBjoern A. Zeeb bool loss_only, enum rtw89_chanctx_idx chanctx_idx) 23478e93258fSBjoern A. Zeeb { 23488e93258fSBjoern A. Zeeb #define DPK_AGC_ADJ_LMT 6 23498e93258fSBjoern A. Zeeb #define DPK_DGAIN_UPPER 1922 23508e93258fSBjoern A. Zeeb #define DPK_DGAIN_LOWER 342 23518e93258fSBjoern A. Zeeb #define DPK_RXBB_UPPER 0x1f 23528e93258fSBjoern A. Zeeb #define DPK_RXBB_LOWER 0 23538e93258fSBjoern A. Zeeb #define DPK_GL_CRIT 7 2354*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 23558e93258fSBjoern A. Zeeb u8 tmp_txagc, tmp_rxbb = 0, tmp_gl_idx = 0; 23568e93258fSBjoern A. Zeeb u8 agc_cnt = 0; 23578e93258fSBjoern A. Zeeb bool limited_rxbb = false; 23588e93258fSBjoern A. Zeeb s8 offset = 0; 23598e93258fSBjoern A. Zeeb u16 dgain = 0; 23608e93258fSBjoern A. Zeeb u8 step = DPK_AGC_STEP_SYNC_DGAIN; 23618e93258fSBjoern A. Zeeb bool goout = false; 23628e93258fSBjoern A. Zeeb 23638e93258fSBjoern A. Zeeb tmp_txagc = init_txagc; 23648e93258fSBjoern A. Zeeb 23658e93258fSBjoern A. Zeeb do { 23668e93258fSBjoern A. Zeeb switch (step) { 23678e93258fSBjoern A. Zeeb case DPK_AGC_STEP_SYNC_DGAIN: 2368*df279a26SBjoern A. Zeeb if (_dpk_sync(rtwdev, phy, path, kidx, chanctx_idx)) { 23698e93258fSBjoern A. Zeeb tmp_txagc = DPK_TXAGC_INVAL; 23708e93258fSBjoern A. Zeeb goout = true; 23718e93258fSBjoern A. Zeeb break; 23728e93258fSBjoern A. Zeeb } 23738e93258fSBjoern A. Zeeb 23748e93258fSBjoern A. Zeeb dgain = _dpk_dgain_read(rtwdev); 23758e93258fSBjoern A. Zeeb 23768e93258fSBjoern A. Zeeb if (loss_only || limited_rxbb) 23778e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_LOSS_IDX; 23788e93258fSBjoern A. Zeeb else 23798e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_ADJ; 23808e93258fSBjoern A. Zeeb break; 23818e93258fSBjoern A. Zeeb 23828e93258fSBjoern A. Zeeb case DPK_AGC_STEP_GAIN_ADJ: 23838e93258fSBjoern A. Zeeb tmp_rxbb = (u8)rtw89_read_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB); 23848e93258fSBjoern A. Zeeb offset = _dpk_dgain_mapping(rtwdev, dgain); 23858e93258fSBjoern A. Zeeb 23868e93258fSBjoern A. Zeeb if (tmp_rxbb + offset > DPK_RXBB_UPPER) { 23878e93258fSBjoern A. Zeeb tmp_rxbb = DPK_RXBB_UPPER; 23888e93258fSBjoern A. Zeeb limited_rxbb = true; 23898e93258fSBjoern A. Zeeb } else if (tmp_rxbb + offset < DPK_RXBB_LOWER) { 23908e93258fSBjoern A. Zeeb tmp_rxbb = DPK_RXBB_LOWER; 23918e93258fSBjoern A. Zeeb limited_rxbb = true; 23928e93258fSBjoern A. Zeeb } else { 23938e93258fSBjoern A. Zeeb tmp_rxbb = tmp_rxbb + offset; 23948e93258fSBjoern A. Zeeb } 23958e93258fSBjoern A. Zeeb 23968e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_M_RXBB, tmp_rxbb); 23978e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 23988e93258fSBjoern A. Zeeb "[DPK] Adjust RXBB (%d) = 0x%x\n", offset, 23998e93258fSBjoern A. Zeeb tmp_rxbb); 24008e93258fSBjoern A. Zeeb if (offset != 0 || agc_cnt == 0) { 24018e93258fSBjoern A. Zeeb if (chan->band_width < RTW89_CHANNEL_WIDTH_80) 24028e93258fSBjoern A. Zeeb _dpk_bypass_rxcfir(rtwdev, path, true); 24038e93258fSBjoern A. Zeeb else 2404*df279a26SBjoern A. Zeeb _dpk_lbk_rxiqk(rtwdev, phy, path, 2405*df279a26SBjoern A. Zeeb chanctx_idx); 24068e93258fSBjoern A. Zeeb } 24078e93258fSBjoern A. Zeeb if (dgain > DPK_DGAIN_UPPER || dgain < DPK_DGAIN_LOWER) 24088e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_SYNC_DGAIN; 24098e93258fSBjoern A. Zeeb else 24108e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_LOSS_IDX; 24118e93258fSBjoern A. Zeeb 24128e93258fSBjoern A. Zeeb agc_cnt++; 24138e93258fSBjoern A. Zeeb break; 24148e93258fSBjoern A. Zeeb 24158e93258fSBjoern A. Zeeb case DPK_AGC_STEP_GAIN_LOSS_IDX: 2416*df279a26SBjoern A. Zeeb _dpk_gainloss(rtwdev, phy, path, kidx, chanctx_idx); 24178e93258fSBjoern A. Zeeb tmp_gl_idx = _dpk_gainloss_read(rtwdev); 24188e93258fSBjoern A. Zeeb 24198e93258fSBjoern A. Zeeb if ((tmp_gl_idx == 0 && _dpk_pas_read(rtwdev, true)) || 24208e93258fSBjoern A. Zeeb tmp_gl_idx > DPK_GL_CRIT) 24218e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GL_GT_CRITERION; 24228e93258fSBjoern A. Zeeb else if (tmp_gl_idx == 0) 24238e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GL_LT_CRITERION; 24248e93258fSBjoern A. Zeeb else 24258e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_SET_TX_GAIN; 24268e93258fSBjoern A. Zeeb break; 24278e93258fSBjoern A. Zeeb 24288e93258fSBjoern A. Zeeb case DPK_AGC_STEP_GL_GT_CRITERION: 24298e93258fSBjoern A. Zeeb if (tmp_txagc == DPK_TXAGC_LOWER) { 24308e93258fSBjoern A. Zeeb goout = true; 24318e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 24328e93258fSBjoern A. Zeeb "[DPK] Txagc@lower bound!!\n"); 24338e93258fSBjoern A. Zeeb } else { 24348e93258fSBjoern A. Zeeb tmp_txagc = _dpk_set_offset(rtwdev, path, 3); 24358e93258fSBjoern A. Zeeb } 24368e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_LOSS_IDX; 24378e93258fSBjoern A. Zeeb agc_cnt++; 24388e93258fSBjoern A. Zeeb break; 24398e93258fSBjoern A. Zeeb 24408e93258fSBjoern A. Zeeb case DPK_AGC_STEP_GL_LT_CRITERION: 24418e93258fSBjoern A. Zeeb if (tmp_txagc == DPK_TXAGC_UPPER) { 24428e93258fSBjoern A. Zeeb goout = true; 24438e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 24448e93258fSBjoern A. Zeeb "[DPK] Txagc@upper bound!!\n"); 24458e93258fSBjoern A. Zeeb } else { 24468e93258fSBjoern A. Zeeb tmp_txagc = _dpk_set_offset(rtwdev, path, -2); 24478e93258fSBjoern A. Zeeb } 24488e93258fSBjoern A. Zeeb step = DPK_AGC_STEP_GAIN_LOSS_IDX; 24498e93258fSBjoern A. Zeeb agc_cnt++; 24508e93258fSBjoern A. Zeeb break; 24518e93258fSBjoern A. Zeeb 24528e93258fSBjoern A. Zeeb case DPK_AGC_STEP_SET_TX_GAIN: 24538e93258fSBjoern A. Zeeb tmp_txagc = _dpk_set_offset(rtwdev, path, tmp_gl_idx); 24548e93258fSBjoern A. Zeeb goout = true; 24558e93258fSBjoern A. Zeeb agc_cnt++; 24568e93258fSBjoern A. Zeeb break; 24578e93258fSBjoern A. Zeeb 24588e93258fSBjoern A. Zeeb default: 24598e93258fSBjoern A. Zeeb goout = true; 24608e93258fSBjoern A. Zeeb break; 24618e93258fSBjoern A. Zeeb } 24628e93258fSBjoern A. Zeeb } while (!goout && (agc_cnt < DPK_AGC_ADJ_LMT)); 24638e93258fSBjoern A. Zeeb 24648e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 24658e93258fSBjoern A. Zeeb "[DPK] Txagc / RXBB for DPK = 0x%x / 0x%x\n", tmp_txagc, 24668e93258fSBjoern A. Zeeb tmp_rxbb); 24678e93258fSBjoern A. Zeeb 24688e93258fSBjoern A. Zeeb return tmp_txagc; 24698e93258fSBjoern A. Zeeb } 24708e93258fSBjoern A. Zeeb 24718e93258fSBjoern A. Zeeb static void _dpk_set_mdpd_para(struct rtw89_dev *rtwdev, u8 order) 24728e93258fSBjoern A. Zeeb { 24738e93258fSBjoern A. Zeeb switch (order) { 24748e93258fSBjoern A. Zeeb case 0: 24758e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); 24768e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_PN, 0x3); 24778e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN, 0x1); 24788e93258fSBjoern A. Zeeb break; 24798e93258fSBjoern A. Zeeb case 1: 24808e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); 24818e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); 24828e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); 24838e93258fSBjoern A. Zeeb break; 24848e93258fSBjoern A. Zeeb case 2: 24858e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LDL_NORM, B_LDL_NORM_OP, order); 24868e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_LDL_NORM, B_LDL_NORM_PN); 24878e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_MAN); 24888e93258fSBjoern A. Zeeb break; 24898e93258fSBjoern A. Zeeb default: 24908e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 24918e93258fSBjoern A. Zeeb "[DPK] Wrong MDPD order!!(0x%x)\n", order); 24928e93258fSBjoern A. Zeeb break; 24938e93258fSBjoern A. Zeeb } 24948e93258fSBjoern A. Zeeb 24958e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 24968e93258fSBjoern A. Zeeb "[DPK] Set MDPD order to 0x%x for IDL\n", order); 24978e93258fSBjoern A. Zeeb } 24988e93258fSBjoern A. Zeeb 24998e93258fSBjoern A. Zeeb static void _dpk_idl_mpa(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2500*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, u8 gain, 2501*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 25028e93258fSBjoern A. Zeeb { 25038e93258fSBjoern A. Zeeb _dpk_set_mdpd_para(rtwdev, 0x0); 25048e93258fSBjoern A. Zeeb _dpk_table_select(rtwdev, path, kidx, 1); 2505*df279a26SBjoern A. Zeeb _dpk_one_shot(rtwdev, phy, path, MDPK_IDL, chanctx_idx); 25068e93258fSBjoern A. Zeeb } 25078e93258fSBjoern A. Zeeb 25088e93258fSBjoern A. Zeeb static void _dpk_fill_result(struct rtw89_dev *rtwdev, 25098e93258fSBjoern A. Zeeb enum rtw89_rf_path path, u8 kidx, u8 gain, 25108e93258fSBjoern A. Zeeb u8 txagc) 25118e93258fSBjoern A. Zeeb { 25128e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 25138e93258fSBjoern A. Zeeb 25148e93258fSBjoern A. Zeeb u16 pwsf = 0x78; 25158e93258fSBjoern A. Zeeb u8 gs = 0x5b; 25168e93258fSBjoern A. Zeeb 25178e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), B_COEF_SEL_MDPD, kidx); 25188e93258fSBjoern A. Zeeb 25198e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 25208e93258fSBjoern A. Zeeb "[DPK] Fill txagc/ pwsf/ gs = 0x%x/ 0x%x/ 0x%x\n", txagc, 25218e93258fSBjoern A. Zeeb pwsf, gs); 25228e93258fSBjoern A. Zeeb 25238e93258fSBjoern A. Zeeb dpk->bp[path][kidx].txagc_dpk = txagc; 25248e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXAGC_RFK + (path << 8), 25258e93258fSBjoern A. Zeeb 0x3F << ((gain << 3) + (kidx << 4)), txagc); 25268e93258fSBjoern A. Zeeb 25278e93258fSBjoern A. Zeeb dpk->bp[path][kidx].pwsf = pwsf; 25288e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), 25298e93258fSBjoern A. Zeeb 0x1FF << (gain << 4), pwsf); 25308e93258fSBjoern A. Zeeb 25318e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD, 0x1); 25328e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_LOAD_COEF + (path << 8), B_LOAD_COEF_MDPD); 25338e93258fSBjoern A. Zeeb 25348e93258fSBjoern A. Zeeb dpk->bp[path][kidx].gs = gs; 25358e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 25368e93258fSBjoern A. Zeeb MASKDWORD, 0x065b5b5b); 25378e93258fSBjoern A. Zeeb 25388e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_DPD_V1 + (path << 8), MASKDWORD); 25398e93258fSBjoern A. Zeeb 25408e93258fSBjoern A. Zeeb rtw89_phy_write32_clr(rtwdev, R_MDPK_SYNC, B_MDPK_SYNC_SEL); 25418e93258fSBjoern A. Zeeb } 25428e93258fSBjoern A. Zeeb 25438e93258fSBjoern A. Zeeb static bool _dpk_reload_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2544*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, enum rtw89_chanctx_idx chanctx_idx) 25458e93258fSBjoern A. Zeeb { 25468e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 2547*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 25488e93258fSBjoern A. Zeeb bool is_reload = false; 25498e93258fSBjoern A. Zeeb u8 idx, cur_band, cur_ch; 25508e93258fSBjoern A. Zeeb 25518e93258fSBjoern A. Zeeb cur_band = chan->band_type; 25528e93258fSBjoern A. Zeeb cur_ch = chan->channel; 25538e93258fSBjoern A. Zeeb 25548e93258fSBjoern A. Zeeb for (idx = 0; idx < RTW89_DPK_BKUP_NUM; idx++) { 25558e93258fSBjoern A. Zeeb if (cur_band != dpk->bp[path][idx].band || 25568e93258fSBjoern A. Zeeb cur_ch != dpk->bp[path][idx].ch) 25578e93258fSBjoern A. Zeeb continue; 25588e93258fSBjoern A. Zeeb 25598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_COEF_SEL + (path << 8), 25608e93258fSBjoern A. Zeeb B_COEF_SEL_MDPD, idx); 25618e93258fSBjoern A. Zeeb dpk->cur_idx[path] = idx; 25628e93258fSBjoern A. Zeeb is_reload = true; 25638e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 25648e93258fSBjoern A. Zeeb "[DPK] reload S%d[%d] success\n", path, idx); 25658e93258fSBjoern A. Zeeb } 25668e93258fSBjoern A. Zeeb 25678e93258fSBjoern A. Zeeb return is_reload; 25688e93258fSBjoern A. Zeeb } 25698e93258fSBjoern A. Zeeb 25708e93258fSBjoern A. Zeeb static bool _dpk_main(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2571*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, u8 gain, 2572*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 25738e93258fSBjoern A. Zeeb { 25748e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 25758e93258fSBjoern A. Zeeb u8 txagc = 0, kidx = dpk->cur_idx[path]; 25768e93258fSBjoern A. Zeeb bool is_fail = false; 25778e93258fSBjoern A. Zeeb 25788e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 25798e93258fSBjoern A. Zeeb "[DPK] ========= S%d[%d] DPK Start =========\n", path, 25808e93258fSBjoern A. Zeeb kidx); 25818e93258fSBjoern A. Zeeb 25828e93258fSBjoern A. Zeeb _rf_direct_cntrl(rtwdev, path, false); 25838e93258fSBjoern A. Zeeb txagc = _dpk_set_tx_pwr(rtwdev, gain, path); 25848e93258fSBjoern A. Zeeb _dpk_rf_setting(rtwdev, gain, path, kidx); 2585*df279a26SBjoern A. Zeeb _dpk_rx_dck(rtwdev, phy, path, chanctx_idx); 25868e93258fSBjoern A. Zeeb 25878e93258fSBjoern A. Zeeb _dpk_kip_setting(rtwdev, path, kidx); 25888e93258fSBjoern A. Zeeb _dpk_manual_txcfir(rtwdev, path, true); 2589*df279a26SBjoern A. Zeeb txagc = _dpk_agc(rtwdev, phy, path, kidx, txagc, false, chanctx_idx); 25908e93258fSBjoern A. Zeeb if (txagc == DPK_TXAGC_INVAL) 25918e93258fSBjoern A. Zeeb is_fail = true; 25928e93258fSBjoern A. Zeeb _dpk_get_thermal(rtwdev, kidx, path); 25938e93258fSBjoern A. Zeeb 2594*df279a26SBjoern A. Zeeb _dpk_idl_mpa(rtwdev, phy, path, kidx, gain, chanctx_idx); 25958e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_MOD, RR_MOD_MASK, RR_MOD_V_RX); 25968e93258fSBjoern A. Zeeb _dpk_fill_result(rtwdev, path, kidx, gain, txagc); 25978e93258fSBjoern A. Zeeb _dpk_manual_txcfir(rtwdev, path, false); 25988e93258fSBjoern A. Zeeb 25998e93258fSBjoern A. Zeeb if (!is_fail) 26008e93258fSBjoern A. Zeeb dpk->bp[path][kidx].path_ok = true; 26018e93258fSBjoern A. Zeeb else 26028e93258fSBjoern A. Zeeb dpk->bp[path][kidx].path_ok = false; 26038e93258fSBjoern A. Zeeb 26048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s\n", path, kidx, 26058e93258fSBjoern A. Zeeb is_fail ? "Check" : "Success"); 26068e93258fSBjoern A. Zeeb 26078e93258fSBjoern A. Zeeb return is_fail; 26088e93258fSBjoern A. Zeeb } 26098e93258fSBjoern A. Zeeb 26108e93258fSBjoern A. Zeeb static void _dpk_cal_select(struct rtw89_dev *rtwdev, bool force, 2611*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, u8 kpath, 2612*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 26138e93258fSBjoern A. Zeeb { 26148e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 26158e93258fSBjoern A. Zeeb u32 backup_bb_val[BACKUP_BB_REGS_NR]; 26168e93258fSBjoern A. Zeeb u32 backup_rf_val[RTW8852A_DPK_RF_PATH][BACKUP_RF_REGS_NR]; 26178e93258fSBjoern A. Zeeb u32 kip_bkup[RTW8852A_DPK_RF_PATH][RTW8852A_DPK_KIP_REG_NUM] = {{0}}; 26188e93258fSBjoern A. Zeeb u32 kip_reg[] = {R_RXIQC, R_IQK_RES}; 26198e93258fSBjoern A. Zeeb u8 path; 26208e93258fSBjoern A. Zeeb bool is_fail = true, reloaded[RTW8852A_DPK_RF_PATH] = {false}; 26218e93258fSBjoern A. Zeeb 26228e93258fSBjoern A. Zeeb if (dpk->is_dpk_reload_en) { 26238e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 26248e93258fSBjoern A. Zeeb if (!(kpath & BIT(path))) 26258e93258fSBjoern A. Zeeb continue; 26268e93258fSBjoern A. Zeeb 2627*df279a26SBjoern A. Zeeb reloaded[path] = _dpk_reload_check(rtwdev, phy, path, 2628*df279a26SBjoern A. Zeeb chanctx_idx); 26298e93258fSBjoern A. Zeeb if (!reloaded[path] && dpk->bp[path][0].ch != 0) 26308e93258fSBjoern A. Zeeb dpk->cur_idx[path] = !dpk->cur_idx[path]; 26318e93258fSBjoern A. Zeeb else 26328e93258fSBjoern A. Zeeb _dpk_onoff(rtwdev, path, false); 26338e93258fSBjoern A. Zeeb } 26348e93258fSBjoern A. Zeeb } else { 26358e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) 26368e93258fSBjoern A. Zeeb dpk->cur_idx[path] = 0; 26378e93258fSBjoern A. Zeeb } 26388e93258fSBjoern A. Zeeb 26398e93258fSBjoern A. Zeeb if ((kpath == RF_A && reloaded[RF_PATH_A]) || 26408e93258fSBjoern A. Zeeb (kpath == RF_B && reloaded[RF_PATH_B]) || 26418e93258fSBjoern A. Zeeb (kpath == RF_AB && reloaded[RF_PATH_A] && reloaded[RF_PATH_B])) 26428e93258fSBjoern A. Zeeb return; 26438e93258fSBjoern A. Zeeb 26448e93258fSBjoern A. Zeeb _rfk_backup_bb_reg(rtwdev, &backup_bb_val[0]); 26458e93258fSBjoern A. Zeeb 26468e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 26478e93258fSBjoern A. Zeeb if (!(kpath & BIT(path)) || reloaded[path]) 26488e93258fSBjoern A. Zeeb continue; 26498e93258fSBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 26508e93258fSBjoern A. Zeeb _dpk_tssi_pause(rtwdev, path, true); 26518e93258fSBjoern A. Zeeb _dpk_bkup_kip(rtwdev, kip_reg, kip_bkup, path); 26528e93258fSBjoern A. Zeeb _rfk_backup_rf_reg(rtwdev, &backup_rf_val[path][0], path); 2653*df279a26SBjoern A. Zeeb _dpk_information(rtwdev, phy, path, chanctx_idx); 26548e93258fSBjoern A. Zeeb } 26558e93258fSBjoern A. Zeeb 26568e93258fSBjoern A. Zeeb _dpk_bb_afe_setting(rtwdev, phy, path, kpath); 26578e93258fSBjoern A. Zeeb 26588e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 26598e93258fSBjoern A. Zeeb if (!(kpath & BIT(path)) || reloaded[path]) 26608e93258fSBjoern A. Zeeb continue; 26618e93258fSBjoern A. Zeeb 2662*df279a26SBjoern A. Zeeb is_fail = _dpk_main(rtwdev, phy, path, 1, chanctx_idx); 26638e93258fSBjoern A. Zeeb _dpk_onoff(rtwdev, path, is_fail); 26648e93258fSBjoern A. Zeeb } 26658e93258fSBjoern A. Zeeb 26668e93258fSBjoern A. Zeeb _dpk_bb_afe_restore(rtwdev, phy, path, kpath); 26678e93258fSBjoern A. Zeeb _rfk_restore_bb_reg(rtwdev, &backup_bb_val[0]); 26688e93258fSBjoern A. Zeeb 26698e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 26708e93258fSBjoern A. Zeeb if (!(kpath & BIT(path)) || reloaded[path]) 26718e93258fSBjoern A. Zeeb continue; 26728e93258fSBjoern A. Zeeb 26738e93258fSBjoern A. Zeeb _dpk_kip_restore(rtwdev, path); 26748e93258fSBjoern A. Zeeb _dpk_reload_kip(rtwdev, kip_reg, kip_bkup, path); 26758e93258fSBjoern A. Zeeb _rfk_restore_rf_reg(rtwdev, &backup_rf_val[path][0], path); 26768e93258fSBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) 26778e93258fSBjoern A. Zeeb _dpk_tssi_pause(rtwdev, path, false); 26788e93258fSBjoern A. Zeeb } 26798e93258fSBjoern A. Zeeb } 26808e93258fSBjoern A. Zeeb 2681*df279a26SBjoern A. Zeeb static bool _dpk_bypass_check(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2682*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 26838e93258fSBjoern A. Zeeb { 26848e93258fSBjoern A. Zeeb struct rtw89_fem_info *fem = &rtwdev->fem; 2685*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 26868e93258fSBjoern A. Zeeb 26878e93258fSBjoern A. Zeeb if (fem->epa_2g && chan->band_type == RTW89_BAND_2G) { 26888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 26898e93258fSBjoern A. Zeeb "[DPK] Skip DPK due to 2G_ext_PA exist!!\n"); 26908e93258fSBjoern A. Zeeb return true; 26918e93258fSBjoern A. Zeeb } else if (fem->epa_5g && chan->band_type == RTW89_BAND_5G) { 26928e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 26938e93258fSBjoern A. Zeeb "[DPK] Skip DPK due to 5G_ext_PA exist!!\n"); 26948e93258fSBjoern A. Zeeb return true; 26958e93258fSBjoern A. Zeeb } 26968e93258fSBjoern A. Zeeb 26978e93258fSBjoern A. Zeeb return false; 26988e93258fSBjoern A. Zeeb } 26998e93258fSBjoern A. Zeeb 27008e93258fSBjoern A. Zeeb static void _dpk_force_bypass(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 27018e93258fSBjoern A. Zeeb { 27028e93258fSBjoern A. Zeeb u8 path, kpath; 27038e93258fSBjoern A. Zeeb 27048e93258fSBjoern A. Zeeb kpath = _kpath(rtwdev, phy); 27058e93258fSBjoern A. Zeeb 27068e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 27078e93258fSBjoern A. Zeeb if (kpath & BIT(path)) 27088e93258fSBjoern A. Zeeb _dpk_onoff(rtwdev, path, true); 27098e93258fSBjoern A. Zeeb } 27108e93258fSBjoern A. Zeeb } 27118e93258fSBjoern A. Zeeb 2712*df279a26SBjoern A. Zeeb static void _dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2713*df279a26SBjoern A. Zeeb bool force, enum rtw89_chanctx_idx chanctx_idx) 27148e93258fSBjoern A. Zeeb { 27158e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, 27168e93258fSBjoern A. Zeeb "[DPK] ****** DPK Start (Ver: 0x%x, Cv: %d, RF_para: %d) ******\n", 27178e93258fSBjoern A. Zeeb RTW8852A_DPK_VER, rtwdev->hal.cv, 27188e93258fSBjoern A. Zeeb RTW8852A_RF_REL_VERSION); 27198e93258fSBjoern A. Zeeb 2720*df279a26SBjoern A. Zeeb if (_dpk_bypass_check(rtwdev, phy, chanctx_idx)) 27218e93258fSBjoern A. Zeeb _dpk_force_bypass(rtwdev, phy); 27228e93258fSBjoern A. Zeeb else 2723*df279a26SBjoern A. Zeeb _dpk_cal_select(rtwdev, force, phy, _kpath(rtwdev, phy), 2724*df279a26SBjoern A. Zeeb chanctx_idx); 27258e93258fSBjoern A. Zeeb } 27268e93258fSBjoern A. Zeeb 27278e93258fSBjoern A. Zeeb static void _dpk_onoff(struct rtw89_dev *rtwdev, 27288e93258fSBjoern A. Zeeb enum rtw89_rf_path path, bool off) 27298e93258fSBjoern A. Zeeb { 27308e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 27318e93258fSBjoern A. Zeeb u8 val, kidx = dpk->cur_idx[path]; 27328e93258fSBjoern A. Zeeb 27338e93258fSBjoern A. Zeeb val = dpk->is_dpk_enable && !off && dpk->bp[path][kidx].path_ok; 27348e93258fSBjoern A. Zeeb 27358e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_CH0A + (path << 8) + (kidx << 2), 27368e93258fSBjoern A. Zeeb MASKBYTE3, 0x6 | val); 27378e93258fSBjoern A. Zeeb 27388e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK, "[DPK] S%d[%d] DPK %s !!!\n", path, 27398e93258fSBjoern A. Zeeb kidx, dpk->is_dpk_enable && !off ? "enable" : "disable"); 27408e93258fSBjoern A. Zeeb } 27418e93258fSBjoern A. Zeeb 27428e93258fSBjoern A. Zeeb static void _dpk_track(struct rtw89_dev *rtwdev) 27438e93258fSBjoern A. Zeeb { 27448e93258fSBjoern A. Zeeb struct rtw89_dpk_info *dpk = &rtwdev->dpk; 27458e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 27468e93258fSBjoern A. Zeeb u8 path, kidx; 27478e93258fSBjoern A. Zeeb u8 trk_idx = 0, txagc_rf = 0; 27488e93258fSBjoern A. Zeeb s8 txagc_bb = 0, txagc_bb_tp = 0, ini_diff = 0, txagc_ofst = 0; 27498e93258fSBjoern A. Zeeb u16 pwsf[2]; 27508e93258fSBjoern A. Zeeb u8 cur_ther; 27518e93258fSBjoern A. Zeeb s8 delta_ther[2] = {0}; 27528e93258fSBjoern A. Zeeb 27538e93258fSBjoern A. Zeeb for (path = 0; path < RTW8852A_DPK_RF_PATH; path++) { 27548e93258fSBjoern A. Zeeb kidx = dpk->cur_idx[path]; 27558e93258fSBjoern A. Zeeb 27568e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 27578e93258fSBjoern A. Zeeb "[DPK_TRK] ================[S%d[%d] (CH %d)]================\n", 27588e93258fSBjoern A. Zeeb path, kidx, dpk->bp[path][kidx].ch); 27598e93258fSBjoern A. Zeeb 27608e93258fSBjoern A. Zeeb cur_ther = ewma_thermal_read(&rtwdev->phystat.avg_thermal[path]); 27618e93258fSBjoern A. Zeeb 27628e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 27638e93258fSBjoern A. Zeeb "[DPK_TRK] thermal now = %d\n", cur_ther); 27648e93258fSBjoern A. Zeeb 27658e93258fSBjoern A. Zeeb if (dpk->bp[path][kidx].ch != 0 && cur_ther != 0) 27668e93258fSBjoern A. Zeeb delta_ther[path] = dpk->bp[path][kidx].ther_dpk - cur_ther; 27678e93258fSBjoern A. Zeeb 27688e93258fSBjoern A. Zeeb if (dpk->bp[path][kidx].band == RTW89_BAND_2G) 27698e93258fSBjoern A. Zeeb delta_ther[path] = delta_ther[path] * 3 / 2; 27708e93258fSBjoern A. Zeeb else 27718e93258fSBjoern A. Zeeb delta_ther[path] = delta_ther[path] * 5 / 2; 27728e93258fSBjoern A. Zeeb 27738e93258fSBjoern A. Zeeb txagc_rf = (u8)rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB + (path << 13), 27748e93258fSBjoern A. Zeeb RR_MODOPT_M_TXPWR); 27758e93258fSBjoern A. Zeeb 27768e93258fSBjoern A. Zeeb if (rtwdev->is_tssi_mode[path]) { 27778e93258fSBjoern A. Zeeb trk_idx = (u8)rtw89_read_rf(rtwdev, path, RR_TXA, RR_TXA_TRK); 27788e93258fSBjoern A. Zeeb 27798e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 27808e93258fSBjoern A. Zeeb "[DPK_TRK] txagc_RF / track_idx = 0x%x / %d\n", 27818e93258fSBjoern A. Zeeb txagc_rf, trk_idx); 27828e93258fSBjoern A. Zeeb 27838e93258fSBjoern A. Zeeb txagc_bb = 27848e93258fSBjoern A. Zeeb (s8)rtw89_phy_read32_mask(rtwdev, 27858e93258fSBjoern A. Zeeb R_TXAGC_BB + (path << 13), 27868e93258fSBjoern A. Zeeb MASKBYTE2); 27878e93258fSBjoern A. Zeeb txagc_bb_tp = 27888e93258fSBjoern A. Zeeb (u8)rtw89_phy_read32_mask(rtwdev, 27898e93258fSBjoern A. Zeeb R_TXAGC_TP + (path << 13), 27908e93258fSBjoern A. Zeeb B_TXAGC_TP); 27918e93258fSBjoern A. Zeeb 27928e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 27938e93258fSBjoern A. Zeeb "[DPK_TRK] txagc_bb_tp / txagc_bb = 0x%x / 0x%x\n", 27948e93258fSBjoern A. Zeeb txagc_bb_tp, txagc_bb); 27958e93258fSBjoern A. Zeeb 27968e93258fSBjoern A. Zeeb txagc_ofst = 27978e93258fSBjoern A. Zeeb (s8)rtw89_phy_read32_mask(rtwdev, 27988e93258fSBjoern A. Zeeb R_TXAGC_BB + (path << 13), 27998e93258fSBjoern A. Zeeb MASKBYTE3); 28008e93258fSBjoern A. Zeeb 28018e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 28028e93258fSBjoern A. Zeeb "[DPK_TRK] txagc_offset / delta_ther = %d / %d\n", 28038e93258fSBjoern A. Zeeb txagc_ofst, delta_ther[path]); 28048e93258fSBjoern A. Zeeb 28058e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_DPD_COM + (path << 8), 28068e93258fSBjoern A. Zeeb BIT(15)) == 0x1) 28078e93258fSBjoern A. Zeeb txagc_ofst = 0; 28088e93258fSBjoern A. Zeeb 28098e93258fSBjoern A. Zeeb if (txagc_rf != 0 && cur_ther != 0) 28108e93258fSBjoern A. Zeeb ini_diff = txagc_ofst + delta_ther[path]; 28118e93258fSBjoern A. Zeeb 28128e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_P0_TXDPD + (path << 13), 28138e93258fSBjoern A. Zeeb B_P0_TXDPD) == 0x0) { 28148e93258fSBjoern A. Zeeb pwsf[0] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - 28158e93258fSBjoern A. Zeeb txagc_bb + ini_diff + 28168e93258fSBjoern A. Zeeb tssi_info->extra_ofst[path]; 28178e93258fSBjoern A. Zeeb pwsf[1] = dpk->bp[path][kidx].pwsf + txagc_bb_tp - 28188e93258fSBjoern A. Zeeb txagc_bb + ini_diff + 28198e93258fSBjoern A. Zeeb tssi_info->extra_ofst[path]; 28208e93258fSBjoern A. Zeeb } else { 28218e93258fSBjoern A. Zeeb pwsf[0] = dpk->bp[path][kidx].pwsf + ini_diff + 28228e93258fSBjoern A. Zeeb tssi_info->extra_ofst[path]; 28238e93258fSBjoern A. Zeeb pwsf[1] = dpk->bp[path][kidx].pwsf + ini_diff + 28248e93258fSBjoern A. Zeeb tssi_info->extra_ofst[path]; 28258e93258fSBjoern A. Zeeb } 28268e93258fSBjoern A. Zeeb 28278e93258fSBjoern A. Zeeb } else { 28288e93258fSBjoern A. Zeeb pwsf[0] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; 28298e93258fSBjoern A. Zeeb pwsf[1] = (dpk->bp[path][kidx].pwsf + delta_ther[path]) & 0x1ff; 28308e93258fSBjoern A. Zeeb } 28318e93258fSBjoern A. Zeeb 28328e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_DPK_TRK, B_DPK_TRK_DIS) == 0x0 && 28338e93258fSBjoern A. Zeeb txagc_rf != 0) { 28348e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_RFK_TRACK, 28358e93258fSBjoern A. Zeeb "[DPK_TRK] New pwsf[0] / pwsf[1] = 0x%x / 0x%x\n", 28368e93258fSBjoern A. Zeeb pwsf[0], pwsf[1]); 28378e93258fSBjoern A. Zeeb 28388e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), 28398e93258fSBjoern A. Zeeb 0x000001FF, pwsf[0]); 28408e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_BND + (path << 8) + (kidx << 2), 28418e93258fSBjoern A. Zeeb 0x01FF0000, pwsf[1]); 28428e93258fSBjoern A. Zeeb } 28438e93258fSBjoern A. Zeeb } 28448e93258fSBjoern A. Zeeb } 28458e93258fSBjoern A. Zeeb 28468e93258fSBjoern A. Zeeb static void _tssi_rf_setting(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2847*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 28488e93258fSBjoern A. Zeeb { 28498e93258fSBjoern A. Zeeb enum rtw89_band band = chan->band_type; 28508e93258fSBjoern A. Zeeb 28518e93258fSBjoern A. Zeeb if (band == RTW89_BAND_2G) 28528e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXG, 0x1); 28538e93258fSBjoern A. Zeeb else 28548e93258fSBjoern A. Zeeb rtw89_write_rf(rtwdev, path, RR_TXPOW, RR_TXPOW_TXA, 0x1); 28558e93258fSBjoern A. Zeeb } 28568e93258fSBjoern A. Zeeb 2857*df279a26SBjoern A. Zeeb static void _tssi_set_sys(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2858*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 28598e93258fSBjoern A. Zeeb { 28608e93258fSBjoern A. Zeeb enum rtw89_band band = chan->band_type; 28618e93258fSBjoern A. Zeeb 28628e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_sys_defs_tbl); 28638e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, 28648e93258fSBjoern A. Zeeb &rtw8852a_tssi_sys_defs_2g_tbl, 28658e93258fSBjoern A. Zeeb &rtw8852a_tssi_sys_defs_5g_tbl); 28668e93258fSBjoern A. Zeeb } 28678e93258fSBjoern A. Zeeb 28688e93258fSBjoern A. Zeeb static void _tssi_ini_txpwr_ctrl_bb(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2869*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, 2870*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 28718e93258fSBjoern A. Zeeb { 28728e93258fSBjoern A. Zeeb enum rtw89_band band = chan->band_type; 28738e93258fSBjoern A. Zeeb 28748e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 28758e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_defs_a_tbl, 28768e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_defs_b_tbl); 28778e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, band == RTW89_BAND_2G, 28788e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_defs_2g_tbl, 28798e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_defs_5g_tbl); 28808e93258fSBjoern A. Zeeb } 28818e93258fSBjoern A. Zeeb 28828e93258fSBjoern A. Zeeb static void _tssi_ini_txpwr_ctrl_bb_he_tb(struct rtw89_dev *rtwdev, 28838e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 28848e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 28858e93258fSBjoern A. Zeeb { 28868e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 28878e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_a_tbl, 28888e93258fSBjoern A. Zeeb &rtw8852a_tssi_txpwr_ctrl_bb_he_tb_defs_b_tbl); 28898e93258fSBjoern A. Zeeb } 28908e93258fSBjoern A. Zeeb 28918e93258fSBjoern A. Zeeb static void _tssi_set_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 28928e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 28938e93258fSBjoern A. Zeeb { 28948e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 28958e93258fSBjoern A. Zeeb &rtw8852a_tssi_dck_defs_a_tbl, 28968e93258fSBjoern A. Zeeb &rtw8852a_tssi_dck_defs_b_tbl); 28978e93258fSBjoern A. Zeeb } 28988e93258fSBjoern A. Zeeb 28998e93258fSBjoern A. Zeeb static void _tssi_set_tmeter_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 2900*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 29018e93258fSBjoern A. Zeeb { 29028e93258fSBjoern A. Zeeb #define __get_val(ptr, idx) \ 29038e93258fSBjoern A. Zeeb ({ \ 29048e93258fSBjoern A. Zeeb s8 *__ptr = (ptr); \ 29058e93258fSBjoern A. Zeeb u8 __idx = (idx), __i, __v; \ 29068e93258fSBjoern A. Zeeb u32 __val = 0; \ 29078e93258fSBjoern A. Zeeb for (__i = 0; __i < 4; __i++) { \ 29088e93258fSBjoern A. Zeeb __v = (__ptr[__idx + __i]); \ 29098e93258fSBjoern A. Zeeb __val |= (__v << (8 * __i)); \ 29108e93258fSBjoern A. Zeeb } \ 29118e93258fSBjoern A. Zeeb __val; \ 29128e93258fSBjoern A. Zeeb }) 29138e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 29148e93258fSBjoern A. Zeeb u8 ch = chan->channel; 29158e93258fSBjoern A. Zeeb u8 subband = chan->subband_type; 29168e93258fSBjoern A. Zeeb const s8 *thm_up_a = NULL; 29178e93258fSBjoern A. Zeeb const s8 *thm_down_a = NULL; 29188e93258fSBjoern A. Zeeb const s8 *thm_up_b = NULL; 29198e93258fSBjoern A. Zeeb const s8 *thm_down_b = NULL; 29208e93258fSBjoern A. Zeeb u8 thermal = 0xff; 29218e93258fSBjoern A. Zeeb s8 thm_ofst[64] = {0}; 29228e93258fSBjoern A. Zeeb u32 tmp = 0; 29238e93258fSBjoern A. Zeeb u8 i, j; 29248e93258fSBjoern A. Zeeb 29258e93258fSBjoern A. Zeeb switch (subband) { 29268e93258fSBjoern A. Zeeb default: 29278e93258fSBjoern A. Zeeb case RTW89_CH_2G: 29288e93258fSBjoern A. Zeeb thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_p; 29298e93258fSBjoern A. Zeeb thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_2ga_n; 29308e93258fSBjoern A. Zeeb thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_p; 29318e93258fSBjoern A. Zeeb thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_2gb_n; 29328e93258fSBjoern A. Zeeb break; 29338e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_1: 29348e93258fSBjoern A. Zeeb thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[0]; 29358e93258fSBjoern A. Zeeb thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[0]; 29368e93258fSBjoern A. Zeeb thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[0]; 29378e93258fSBjoern A. Zeeb thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[0]; 29388e93258fSBjoern A. Zeeb break; 29398e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_3: 29408e93258fSBjoern A. Zeeb thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[1]; 29418e93258fSBjoern A. Zeeb thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[1]; 29428e93258fSBjoern A. Zeeb thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[1]; 29438e93258fSBjoern A. Zeeb thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[1]; 29448e93258fSBjoern A. Zeeb break; 29458e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_4: 29468e93258fSBjoern A. Zeeb thm_up_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_p[2]; 29478e93258fSBjoern A. Zeeb thm_down_a = rtw89_8852a_trk_cfg.delta_swingidx_5ga_n[2]; 29488e93258fSBjoern A. Zeeb thm_up_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_p[2]; 29498e93258fSBjoern A. Zeeb thm_down_b = rtw89_8852a_trk_cfg.delta_swingidx_5gb_n[2]; 29508e93258fSBjoern A. Zeeb break; 29518e93258fSBjoern A. Zeeb } 29528e93258fSBjoern A. Zeeb 29538e93258fSBjoern A. Zeeb if (path == RF_PATH_A) { 29548e93258fSBjoern A. Zeeb thermal = tssi_info->thermal[RF_PATH_A]; 29558e93258fSBjoern A. Zeeb 29568e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 29578e93258fSBjoern A. Zeeb "[TSSI] ch=%d thermal_pathA=0x%x\n", ch, thermal); 29588e93258fSBjoern A. Zeeb 29598e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_DIS, 0x0); 29608e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER_TRK, 0x1); 29618e93258fSBjoern A. Zeeb 29628e93258fSBjoern A. Zeeb if (thermal == 0xff) { 29638e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, 32); 29648e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 32); 29658e93258fSBjoern A. Zeeb 29668e93258fSBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 29678e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, 0x0); 29688e93258fSBjoern A. Zeeb 29698e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 29708e93258fSBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 29718e93258fSBjoern A. Zeeb 0x5c00 + i, 0x0); 29728e93258fSBjoern A. Zeeb } 29738e93258fSBjoern A. Zeeb 29748e93258fSBjoern A. Zeeb } else { 29758e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TMETER, B_P0_TMETER, thermal); 29768e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_VAL, 29778e93258fSBjoern A. Zeeb thermal); 29788e93258fSBjoern A. Zeeb 29798e93258fSBjoern A. Zeeb i = 0; 29808e93258fSBjoern A. Zeeb for (j = 0; j < 32; j++) 29818e93258fSBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 29828e93258fSBjoern A. Zeeb -thm_down_a[i++] : 29838e93258fSBjoern A. Zeeb -thm_down_a[DELTA_SWINGIDX_SIZE - 1]; 29848e93258fSBjoern A. Zeeb 29858e93258fSBjoern A. Zeeb i = 1; 29868e93258fSBjoern A. Zeeb for (j = 63; j >= 32; j--) 29878e93258fSBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 29888e93258fSBjoern A. Zeeb thm_up_a[i++] : 29898e93258fSBjoern A. Zeeb thm_up_a[DELTA_SWINGIDX_SIZE - 1]; 29908e93258fSBjoern A. Zeeb 29918e93258fSBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 29928e93258fSBjoern A. Zeeb tmp = __get_val(thm_ofst, i); 29938e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_P0_TSSI_BASE + i, tmp); 29948e93258fSBjoern A. Zeeb 29958e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 29968e93258fSBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 29978e93258fSBjoern A. Zeeb 0x5c00 + i, tmp); 29988e93258fSBjoern A. Zeeb } 29998e93258fSBjoern A. Zeeb } 30008e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x1); 30018e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, R_P0_RFCTM_RDY, 0x0); 30028e93258fSBjoern A. Zeeb 30038e93258fSBjoern A. Zeeb } else { 30048e93258fSBjoern A. Zeeb thermal = tssi_info->thermal[RF_PATH_B]; 30058e93258fSBjoern A. Zeeb 30068e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 30078e93258fSBjoern A. Zeeb "[TSSI] ch=%d thermal_pathB=0x%x\n", ch, thermal); 30088e93258fSBjoern A. Zeeb 30098e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_DIS, 0x0); 30108e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER_TRK, 0x1); 30118e93258fSBjoern A. Zeeb 30128e93258fSBjoern A. Zeeb if (thermal == 0xff) { 30138e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, 32); 30148e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 32); 30158e93258fSBjoern A. Zeeb 30168e93258fSBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 30178e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, 0x0); 30188e93258fSBjoern A. Zeeb 30198e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 30208e93258fSBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 30218e93258fSBjoern A. Zeeb 0x7c00 + i, 0x0); 30228e93258fSBjoern A. Zeeb } 30238e93258fSBjoern A. Zeeb 30248e93258fSBjoern A. Zeeb } else { 30258e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TMETER, B_P1_TMETER, thermal); 30268e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, B_P1_RFCTM_VAL, 30278e93258fSBjoern A. Zeeb thermal); 30288e93258fSBjoern A. Zeeb 30298e93258fSBjoern A. Zeeb i = 0; 30308e93258fSBjoern A. Zeeb for (j = 0; j < 32; j++) 30318e93258fSBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 30328e93258fSBjoern A. Zeeb -thm_down_b[i++] : 30338e93258fSBjoern A. Zeeb -thm_down_b[DELTA_SWINGIDX_SIZE - 1]; 30348e93258fSBjoern A. Zeeb 30358e93258fSBjoern A. Zeeb i = 1; 30368e93258fSBjoern A. Zeeb for (j = 63; j >= 32; j--) 30378e93258fSBjoern A. Zeeb thm_ofst[j] = i < DELTA_SWINGIDX_SIZE ? 30388e93258fSBjoern A. Zeeb thm_up_b[i++] : 30398e93258fSBjoern A. Zeeb thm_up_b[DELTA_SWINGIDX_SIZE - 1]; 30408e93258fSBjoern A. Zeeb 30418e93258fSBjoern A. Zeeb for (i = 0; i < 64; i += 4) { 30428e93258fSBjoern A. Zeeb tmp = __get_val(thm_ofst, i); 30438e93258fSBjoern A. Zeeb rtw89_phy_write32(rtwdev, R_TSSI_THOF + i, tmp); 30448e93258fSBjoern A. Zeeb 30458e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 30468e93258fSBjoern A. Zeeb "[TSSI] write 0x%x val=0x%08x\n", 30478e93258fSBjoern A. Zeeb 0x7c00 + i, tmp); 30488e93258fSBjoern A. Zeeb } 30498e93258fSBjoern A. Zeeb } 30508e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x1); 30518e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_RFCTM, R_P1_RFCTM_RDY, 0x0); 30528e93258fSBjoern A. Zeeb } 30538e93258fSBjoern A. Zeeb #undef __get_val 30548e93258fSBjoern A. Zeeb } 30558e93258fSBjoern A. Zeeb 30568e93258fSBjoern A. Zeeb static void _tssi_set_dac_gain_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 30578e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30588e93258fSBjoern A. Zeeb { 30598e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 30608e93258fSBjoern A. Zeeb &rtw8852a_tssi_dac_gain_tbl_defs_a_tbl, 30618e93258fSBjoern A. Zeeb &rtw8852a_tssi_dac_gain_tbl_defs_b_tbl); 30628e93258fSBjoern A. Zeeb } 30638e93258fSBjoern A. Zeeb 30648e93258fSBjoern A. Zeeb static void _tssi_slope_cal_org(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 30658e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30668e93258fSBjoern A. Zeeb { 30678e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 30688e93258fSBjoern A. Zeeb &rtw8852a_tssi_slope_cal_org_defs_a_tbl, 30698e93258fSBjoern A. Zeeb &rtw8852a_tssi_slope_cal_org_defs_b_tbl); 30708e93258fSBjoern A. Zeeb } 30718e93258fSBjoern A. Zeeb 30728e93258fSBjoern A. Zeeb static void _tssi_set_rf_gap_tbl(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 30738e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30748e93258fSBjoern A. Zeeb { 30758e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 30768e93258fSBjoern A. Zeeb &rtw8852a_tssi_rf_gap_tbl_defs_a_tbl, 30778e93258fSBjoern A. Zeeb &rtw8852a_tssi_rf_gap_tbl_defs_b_tbl); 30788e93258fSBjoern A. Zeeb } 30798e93258fSBjoern A. Zeeb 30808e93258fSBjoern A. Zeeb static void _tssi_set_slope(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 30818e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30828e93258fSBjoern A. Zeeb { 30838e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 30848e93258fSBjoern A. Zeeb &rtw8852a_tssi_slope_defs_a_tbl, 30858e93258fSBjoern A. Zeeb &rtw8852a_tssi_slope_defs_b_tbl); 30868e93258fSBjoern A. Zeeb } 30878e93258fSBjoern A. Zeeb 30888e93258fSBjoern A. Zeeb static void _tssi_set_track(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 30898e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30908e93258fSBjoern A. Zeeb { 30918e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 30928e93258fSBjoern A. Zeeb &rtw8852a_tssi_track_defs_a_tbl, 30938e93258fSBjoern A. Zeeb &rtw8852a_tssi_track_defs_b_tbl); 30948e93258fSBjoern A. Zeeb } 30958e93258fSBjoern A. Zeeb 30968e93258fSBjoern A. Zeeb static void _tssi_set_txagc_offset_mv_avg(struct rtw89_dev *rtwdev, 30978e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 30988e93258fSBjoern A. Zeeb enum rtw89_rf_path path) 30998e93258fSBjoern A. Zeeb { 31008e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 31018e93258fSBjoern A. Zeeb &rtw8852a_tssi_txagc_ofst_mv_avg_defs_a_tbl, 31028e93258fSBjoern A. Zeeb &rtw8852a_tssi_txagc_ofst_mv_avg_defs_b_tbl); 31038e93258fSBjoern A. Zeeb } 31048e93258fSBjoern A. Zeeb 31058e93258fSBjoern A. Zeeb static void _tssi_pak(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3106*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 31078e93258fSBjoern A. Zeeb { 31088e93258fSBjoern A. Zeeb u8 subband = chan->subband_type; 31098e93258fSBjoern A. Zeeb 31108e93258fSBjoern A. Zeeb switch (subband) { 31118e93258fSBjoern A. Zeeb default: 31128e93258fSBjoern A. Zeeb case RTW89_CH_2G: 31138e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 31148e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_a_2g_tbl, 31158e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_b_2g_tbl); 31168e93258fSBjoern A. Zeeb break; 31178e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_1: 31188e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 31198e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_a_5g_1_tbl, 31208e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_b_5g_1_tbl); 31218e93258fSBjoern A. Zeeb break; 31228e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_3: 31238e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 31248e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_a_5g_3_tbl, 31258e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_b_5g_3_tbl); 31268e93258fSBjoern A. Zeeb break; 31278e93258fSBjoern A. Zeeb case RTW89_CH_5G_BAND_4: 31288e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, path == RF_PATH_A, 31298e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_a_5g_4_tbl, 31308e93258fSBjoern A. Zeeb &rtw8852a_tssi_pak_defs_b_5g_4_tbl); 31318e93258fSBjoern A. Zeeb break; 31328e93258fSBjoern A. Zeeb } 31338e93258fSBjoern A. Zeeb } 31348e93258fSBjoern A. Zeeb 31358e93258fSBjoern A. Zeeb static void _tssi_enable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 31368e93258fSBjoern A. Zeeb { 31378e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 31388e93258fSBjoern A. Zeeb u8 i; 31398e93258fSBjoern A. Zeeb 31408e93258fSBjoern A. Zeeb for (i = 0; i < RF_PATH_NUM_8852A; i++) { 31418e93258fSBjoern A. Zeeb _tssi_set_track(rtwdev, phy, i); 31428e93258fSBjoern A. Zeeb _tssi_set_txagc_offset_mv_avg(rtwdev, phy, i); 31438e93258fSBjoern A. Zeeb 31448e93258fSBjoern A. Zeeb rtw89_rfk_parser_by_cond(rtwdev, i == RF_PATH_A, 31458e93258fSBjoern A. Zeeb &rtw8852a_tssi_enable_defs_a_tbl, 31468e93258fSBjoern A. Zeeb &rtw8852a_tssi_enable_defs_b_tbl); 31478e93258fSBjoern A. Zeeb 31488e93258fSBjoern A. Zeeb tssi_info->base_thermal[i] = 31498e93258fSBjoern A. Zeeb ewma_thermal_read(&rtwdev->phystat.avg_thermal[i]); 31508e93258fSBjoern A. Zeeb rtwdev->is_tssi_mode[i] = true; 31518e93258fSBjoern A. Zeeb } 31528e93258fSBjoern A. Zeeb } 31538e93258fSBjoern A. Zeeb 31548e93258fSBjoern A. Zeeb static void _tssi_disable(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 31558e93258fSBjoern A. Zeeb { 31568e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); 31578e93258fSBjoern A. Zeeb 31588e93258fSBjoern A. Zeeb rtwdev->is_tssi_mode[RF_PATH_A] = false; 31598e93258fSBjoern A. Zeeb rtwdev->is_tssi_mode[RF_PATH_B] = false; 31608e93258fSBjoern A. Zeeb } 31618e93258fSBjoern A. Zeeb 31628e93258fSBjoern A. Zeeb static u32 _tssi_get_cck_group(struct rtw89_dev *rtwdev, u8 ch) 31638e93258fSBjoern A. Zeeb { 31648e93258fSBjoern A. Zeeb switch (ch) { 31658e93258fSBjoern A. Zeeb case 1 ... 2: 31668e93258fSBjoern A. Zeeb return 0; 31678e93258fSBjoern A. Zeeb case 3 ... 5: 31688e93258fSBjoern A. Zeeb return 1; 31698e93258fSBjoern A. Zeeb case 6 ... 8: 31708e93258fSBjoern A. Zeeb return 2; 31718e93258fSBjoern A. Zeeb case 9 ... 11: 31728e93258fSBjoern A. Zeeb return 3; 31738e93258fSBjoern A. Zeeb case 12 ... 13: 31748e93258fSBjoern A. Zeeb return 4; 31758e93258fSBjoern A. Zeeb case 14: 31768e93258fSBjoern A. Zeeb return 5; 31778e93258fSBjoern A. Zeeb } 31788e93258fSBjoern A. Zeeb 31798e93258fSBjoern A. Zeeb return 0; 31808e93258fSBjoern A. Zeeb } 31818e93258fSBjoern A. Zeeb 31828e93258fSBjoern A. Zeeb #define TSSI_EXTRA_GROUP_BIT (BIT(31)) 31838e93258fSBjoern A. Zeeb #define TSSI_EXTRA_GROUP(idx) (TSSI_EXTRA_GROUP_BIT | (idx)) 31848e93258fSBjoern A. Zeeb #define IS_TSSI_EXTRA_GROUP(group) ((group) & TSSI_EXTRA_GROUP_BIT) 31858e93258fSBjoern A. Zeeb #define TSSI_EXTRA_GET_GROUP_IDX1(group) ((group) & ~TSSI_EXTRA_GROUP_BIT) 31868e93258fSBjoern A. Zeeb #define TSSI_EXTRA_GET_GROUP_IDX2(group) (TSSI_EXTRA_GET_GROUP_IDX1(group) + 1) 31878e93258fSBjoern A. Zeeb 31888e93258fSBjoern A. Zeeb static u32 _tssi_get_ofdm_group(struct rtw89_dev *rtwdev, u8 ch) 31898e93258fSBjoern A. Zeeb { 31908e93258fSBjoern A. Zeeb switch (ch) { 31918e93258fSBjoern A. Zeeb case 1 ... 2: 31928e93258fSBjoern A. Zeeb return 0; 31938e93258fSBjoern A. Zeeb case 3 ... 5: 31948e93258fSBjoern A. Zeeb return 1; 31958e93258fSBjoern A. Zeeb case 6 ... 8: 31968e93258fSBjoern A. Zeeb return 2; 31978e93258fSBjoern A. Zeeb case 9 ... 11: 31988e93258fSBjoern A. Zeeb return 3; 31998e93258fSBjoern A. Zeeb case 12 ... 14: 32008e93258fSBjoern A. Zeeb return 4; 32018e93258fSBjoern A. Zeeb case 36 ... 40: 32028e93258fSBjoern A. Zeeb return 5; 32038e93258fSBjoern A. Zeeb case 41 ... 43: 32048e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(5); 32058e93258fSBjoern A. Zeeb case 44 ... 48: 32068e93258fSBjoern A. Zeeb return 6; 32078e93258fSBjoern A. Zeeb case 49 ... 51: 32088e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(6); 32098e93258fSBjoern A. Zeeb case 52 ... 56: 32108e93258fSBjoern A. Zeeb return 7; 32118e93258fSBjoern A. Zeeb case 57 ... 59: 32128e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(7); 32138e93258fSBjoern A. Zeeb case 60 ... 64: 32148e93258fSBjoern A. Zeeb return 8; 32158e93258fSBjoern A. Zeeb case 100 ... 104: 32168e93258fSBjoern A. Zeeb return 9; 32178e93258fSBjoern A. Zeeb case 105 ... 107: 32188e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(9); 32198e93258fSBjoern A. Zeeb case 108 ... 112: 32208e93258fSBjoern A. Zeeb return 10; 32218e93258fSBjoern A. Zeeb case 113 ... 115: 32228e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(10); 32238e93258fSBjoern A. Zeeb case 116 ... 120: 32248e93258fSBjoern A. Zeeb return 11; 32258e93258fSBjoern A. Zeeb case 121 ... 123: 32268e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(11); 32278e93258fSBjoern A. Zeeb case 124 ... 128: 32288e93258fSBjoern A. Zeeb return 12; 32298e93258fSBjoern A. Zeeb case 129 ... 131: 32308e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(12); 32318e93258fSBjoern A. Zeeb case 132 ... 136: 32328e93258fSBjoern A. Zeeb return 13; 32338e93258fSBjoern A. Zeeb case 137 ... 139: 32348e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(13); 32358e93258fSBjoern A. Zeeb case 140 ... 144: 32368e93258fSBjoern A. Zeeb return 14; 32378e93258fSBjoern A. Zeeb case 149 ... 153: 32388e93258fSBjoern A. Zeeb return 15; 32398e93258fSBjoern A. Zeeb case 154 ... 156: 32408e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(15); 32418e93258fSBjoern A. Zeeb case 157 ... 161: 32428e93258fSBjoern A. Zeeb return 16; 32438e93258fSBjoern A. Zeeb case 162 ... 164: 32448e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(16); 32458e93258fSBjoern A. Zeeb case 165 ... 169: 32468e93258fSBjoern A. Zeeb return 17; 32478e93258fSBjoern A. Zeeb case 170 ... 172: 32488e93258fSBjoern A. Zeeb return TSSI_EXTRA_GROUP(17); 32498e93258fSBjoern A. Zeeb case 173 ... 177: 32508e93258fSBjoern A. Zeeb return 18; 32518e93258fSBjoern A. Zeeb } 32528e93258fSBjoern A. Zeeb 32538e93258fSBjoern A. Zeeb return 0; 32548e93258fSBjoern A. Zeeb } 32558e93258fSBjoern A. Zeeb 32568e93258fSBjoern A. Zeeb static u32 _tssi_get_trim_group(struct rtw89_dev *rtwdev, u8 ch) 32578e93258fSBjoern A. Zeeb { 32588e93258fSBjoern A. Zeeb switch (ch) { 32598e93258fSBjoern A. Zeeb case 1 ... 8: 32608e93258fSBjoern A. Zeeb return 0; 32618e93258fSBjoern A. Zeeb case 9 ... 14: 32628e93258fSBjoern A. Zeeb return 1; 32638e93258fSBjoern A. Zeeb case 36 ... 48: 32648e93258fSBjoern A. Zeeb return 2; 32658e93258fSBjoern A. Zeeb case 52 ... 64: 32668e93258fSBjoern A. Zeeb return 3; 32678e93258fSBjoern A. Zeeb case 100 ... 112: 32688e93258fSBjoern A. Zeeb return 4; 32698e93258fSBjoern A. Zeeb case 116 ... 128: 32708e93258fSBjoern A. Zeeb return 5; 32718e93258fSBjoern A. Zeeb case 132 ... 144: 32728e93258fSBjoern A. Zeeb return 6; 32738e93258fSBjoern A. Zeeb case 149 ... 177: 32748e93258fSBjoern A. Zeeb return 7; 32758e93258fSBjoern A. Zeeb } 32768e93258fSBjoern A. Zeeb 32778e93258fSBjoern A. Zeeb return 0; 32788e93258fSBjoern A. Zeeb } 32798e93258fSBjoern A. Zeeb 32808e93258fSBjoern A. Zeeb static s8 _tssi_get_ofdm_de(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3281*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 32828e93258fSBjoern A. Zeeb { 32838e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 32848e93258fSBjoern A. Zeeb u8 ch = chan->channel; 32858e93258fSBjoern A. Zeeb u32 gidx, gidx_1st, gidx_2nd; 32868e93258fSBjoern A. Zeeb s8 de_1st = 0; 32878e93258fSBjoern A. Zeeb s8 de_2nd = 0; 32888e93258fSBjoern A. Zeeb s8 val; 32898e93258fSBjoern A. Zeeb 32908e93258fSBjoern A. Zeeb gidx = _tssi_get_ofdm_group(rtwdev, ch); 32918e93258fSBjoern A. Zeeb 32928e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 32938e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs group_idx=0x%x\n", 32948e93258fSBjoern A. Zeeb path, gidx); 32958e93258fSBjoern A. Zeeb 32968e93258fSBjoern A. Zeeb if (IS_TSSI_EXTRA_GROUP(gidx)) { 32978e93258fSBjoern A. Zeeb gidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(gidx); 32988e93258fSBjoern A. Zeeb gidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(gidx); 32998e93258fSBjoern A. Zeeb de_1st = tssi_info->tssi_mcs[path][gidx_1st]; 33008e93258fSBjoern A. Zeeb de_2nd = tssi_info->tssi_mcs[path][gidx_2nd]; 33018e93258fSBjoern A. Zeeb val = (de_1st + de_2nd) / 2; 33028e93258fSBjoern A. Zeeb 33038e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33048e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs de=%d 1st=%d 2nd=%d\n", 33058e93258fSBjoern A. Zeeb path, val, de_1st, de_2nd); 33068e93258fSBjoern A. Zeeb } else { 33078e93258fSBjoern A. Zeeb val = tssi_info->tssi_mcs[path][gidx]; 33088e93258fSBjoern A. Zeeb 33098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33108e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs de=%d\n", path, val); 33118e93258fSBjoern A. Zeeb } 33128e93258fSBjoern A. Zeeb 33138e93258fSBjoern A. Zeeb return val; 33148e93258fSBjoern A. Zeeb } 33158e93258fSBjoern A. Zeeb 33168e93258fSBjoern A. Zeeb static s8 _tssi_get_ofdm_trim_de(struct rtw89_dev *rtwdev, 33178e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, 3318*df279a26SBjoern A. Zeeb enum rtw89_rf_path path, const struct rtw89_chan *chan) 33198e93258fSBjoern A. Zeeb { 33208e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 33218e93258fSBjoern A. Zeeb u8 ch = chan->channel; 33228e93258fSBjoern A. Zeeb u32 tgidx, tgidx_1st, tgidx_2nd; 33238e93258fSBjoern A. Zeeb s8 tde_1st = 0; 33248e93258fSBjoern A. Zeeb s8 tde_2nd = 0; 33258e93258fSBjoern A. Zeeb s8 val; 33268e93258fSBjoern A. Zeeb 33278e93258fSBjoern A. Zeeb tgidx = _tssi_get_trim_group(rtwdev, ch); 33288e93258fSBjoern A. Zeeb 33298e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33308e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_group_idx=0x%x\n", 33318e93258fSBjoern A. Zeeb path, tgidx); 33328e93258fSBjoern A. Zeeb 33338e93258fSBjoern A. Zeeb if (IS_TSSI_EXTRA_GROUP(tgidx)) { 33348e93258fSBjoern A. Zeeb tgidx_1st = TSSI_EXTRA_GET_GROUP_IDX1(tgidx); 33358e93258fSBjoern A. Zeeb tgidx_2nd = TSSI_EXTRA_GET_GROUP_IDX2(tgidx); 33368e93258fSBjoern A. Zeeb tde_1st = tssi_info->tssi_trim[path][tgidx_1st]; 33378e93258fSBjoern A. Zeeb tde_2nd = tssi_info->tssi_trim[path][tgidx_2nd]; 33388e93258fSBjoern A. Zeeb val = (tde_1st + tde_2nd) / 2; 33398e93258fSBjoern A. Zeeb 33408e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33418e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_de=%d 1st=%d 2nd=%d\n", 33428e93258fSBjoern A. Zeeb path, val, tde_1st, tde_2nd); 33438e93258fSBjoern A. Zeeb } else { 33448e93258fSBjoern A. Zeeb val = tssi_info->tssi_trim[path][tgidx]; 33458e93258fSBjoern A. Zeeb 33468e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33478e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs trim_de=%d\n", 33488e93258fSBjoern A. Zeeb path, val); 33498e93258fSBjoern A. Zeeb } 33508e93258fSBjoern A. Zeeb 33518e93258fSBjoern A. Zeeb return val; 33528e93258fSBjoern A. Zeeb } 33538e93258fSBjoern A. Zeeb 33548e93258fSBjoern A. Zeeb static void _tssi_set_efuse_to_de(struct rtw89_dev *rtwdev, 3355*df279a26SBjoern A. Zeeb enum rtw89_phy_idx phy, const struct rtw89_chan *chan) 33568e93258fSBjoern A. Zeeb { 33578e93258fSBjoern A. Zeeb #define __DE_MASK 0x003ff000 33588e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 33598e93258fSBjoern A. Zeeb static const u32 r_cck_long[RF_PATH_NUM_8852A] = {0x5858, 0x7858}; 33608e93258fSBjoern A. Zeeb static const u32 r_cck_short[RF_PATH_NUM_8852A] = {0x5860, 0x7860}; 33618e93258fSBjoern A. Zeeb static const u32 r_mcs_20m[RF_PATH_NUM_8852A] = {0x5838, 0x7838}; 33628e93258fSBjoern A. Zeeb static const u32 r_mcs_40m[RF_PATH_NUM_8852A] = {0x5840, 0x7840}; 33638e93258fSBjoern A. Zeeb static const u32 r_mcs_80m[RF_PATH_NUM_8852A] = {0x5848, 0x7848}; 33648e93258fSBjoern A. Zeeb static const u32 r_mcs_80m_80m[RF_PATH_NUM_8852A] = {0x5850, 0x7850}; 33658e93258fSBjoern A. Zeeb static const u32 r_mcs_5m[RF_PATH_NUM_8852A] = {0x5828, 0x7828}; 33668e93258fSBjoern A. Zeeb static const u32 r_mcs_10m[RF_PATH_NUM_8852A] = {0x5830, 0x7830}; 33678e93258fSBjoern A. Zeeb u8 ch = chan->channel; 33688e93258fSBjoern A. Zeeb u8 i, gidx; 33698e93258fSBjoern A. Zeeb s8 ofdm_de; 33708e93258fSBjoern A. Zeeb s8 trim_de; 33718e93258fSBjoern A. Zeeb s32 val; 33728e93258fSBjoern A. Zeeb 33738e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRIM]: phy=%d ch=%d\n", 33748e93258fSBjoern A. Zeeb phy, ch); 33758e93258fSBjoern A. Zeeb 33768e93258fSBjoern A. Zeeb for (i = 0; i < RF_PATH_NUM_8852A; i++) { 33778e93258fSBjoern A. Zeeb gidx = _tssi_get_cck_group(rtwdev, ch); 3378*df279a26SBjoern A. Zeeb trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); 33798e93258fSBjoern A. Zeeb val = tssi_info->tssi_cck[i][gidx] + trim_de; 33808e93258fSBjoern A. Zeeb 33818e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33828e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d cck[%d]=0x%x trim=0x%x\n", 33838e93258fSBjoern A. Zeeb i, gidx, tssi_info->tssi_cck[i][gidx], trim_de); 33848e93258fSBjoern A. Zeeb 33858e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_cck_long[i], __DE_MASK, val); 33868e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_cck_short[i], __DE_MASK, val); 33878e93258fSBjoern A. Zeeb 33888e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33898e93258fSBjoern A. Zeeb "[TSSI] Set TSSI CCK DE 0x%x[21:12]=0x%x\n", 33908e93258fSBjoern A. Zeeb r_cck_long[i], 33918e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, r_cck_long[i], 33928e93258fSBjoern A. Zeeb __DE_MASK)); 33938e93258fSBjoern A. Zeeb 3394*df279a26SBjoern A. Zeeb ofdm_de = _tssi_get_ofdm_de(rtwdev, phy, i, chan); 3395*df279a26SBjoern A. Zeeb trim_de = _tssi_get_ofdm_trim_de(rtwdev, phy, i, chan); 33968e93258fSBjoern A. Zeeb val = ofdm_de + trim_de; 33978e93258fSBjoern A. Zeeb 33988e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 33998e93258fSBjoern A. Zeeb "[TSSI][TRIM]: path=%d mcs=0x%x trim=0x%x\n", 34008e93258fSBjoern A. Zeeb i, ofdm_de, trim_de); 34018e93258fSBjoern A. Zeeb 34028e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_20m[i], __DE_MASK, val); 34038e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_40m[i], __DE_MASK, val); 34048e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_80m[i], __DE_MASK, val); 34058e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_80m_80m[i], __DE_MASK, val); 34068e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_5m[i], __DE_MASK, val); 34078e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, r_mcs_10m[i], __DE_MASK, val); 34088e93258fSBjoern A. Zeeb 34098e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 34108e93258fSBjoern A. Zeeb "[TSSI] Set TSSI MCS DE 0x%x[21:12]=0x%x\n", 34118e93258fSBjoern A. Zeeb r_mcs_20m[i], 34128e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, r_mcs_20m[i], 34138e93258fSBjoern A. Zeeb __DE_MASK)); 34148e93258fSBjoern A. Zeeb } 34158e93258fSBjoern A. Zeeb #undef __DE_MASK 34168e93258fSBjoern A. Zeeb } 34178e93258fSBjoern A. Zeeb 34188e93258fSBjoern A. Zeeb static void _tssi_track(struct rtw89_dev *rtwdev) 34198e93258fSBjoern A. Zeeb { 34208e93258fSBjoern A. Zeeb static const u32 tx_gain_scale_table[] = { 34218e93258fSBjoern A. Zeeb 0x400, 0x40e, 0x41d, 0x427, 0x43c, 0x44c, 0x45c, 0x46c, 34228e93258fSBjoern A. Zeeb 0x400, 0x39d, 0x3ab, 0x3b8, 0x3c6, 0x3d4, 0x3e2, 0x3f1 34238e93258fSBjoern A. Zeeb }; 34248e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 34258e93258fSBjoern A. Zeeb u8 path; 34268e93258fSBjoern A. Zeeb u8 cur_ther; 34278e93258fSBjoern A. Zeeb s32 delta_ther = 0, gain_offset_int, gain_offset_float; 34288e93258fSBjoern A. Zeeb s8 gain_offset; 34298e93258fSBjoern A. Zeeb 34308e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] %s:\n", 34318e93258fSBjoern A. Zeeb __func__); 34328e93258fSBjoern A. Zeeb 34338e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A]) 34348e93258fSBjoern A. Zeeb return; 34358e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_B]) 34368e93258fSBjoern A. Zeeb return; 34378e93258fSBjoern A. Zeeb 34388e93258fSBjoern A. Zeeb for (path = RF_PATH_A; path < RF_PATH_NUM_8852A; path++) { 34398e93258fSBjoern A. Zeeb if (!tssi_info->tssi_tracking_check[path]) { 34408e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI][TRK] return!!!\n"); 34418e93258fSBjoern A. Zeeb continue; 34428e93258fSBjoern A. Zeeb } 34438e93258fSBjoern A. Zeeb 34448e93258fSBjoern A. Zeeb cur_ther = (u8)rtw89_phy_read32_mask(rtwdev, 34458e93258fSBjoern A. Zeeb R_TSSI_THER + (path << 13), 34468e93258fSBjoern A. Zeeb B_TSSI_THER); 34478e93258fSBjoern A. Zeeb 34488e93258fSBjoern A. Zeeb if (cur_ther == 0 || tssi_info->base_thermal[path] == 0) 34498e93258fSBjoern A. Zeeb continue; 34508e93258fSBjoern A. Zeeb 34518e93258fSBjoern A. Zeeb delta_ther = cur_ther - tssi_info->base_thermal[path]; 34528e93258fSBjoern A. Zeeb 34538e93258fSBjoern A. Zeeb gain_offset = (s8)delta_ther * 15 / 10; 34548e93258fSBjoern A. Zeeb 34558e93258fSBjoern A. Zeeb tssi_info->extra_ofst[path] = gain_offset; 34568e93258fSBjoern A. Zeeb 34578e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 34588e93258fSBjoern A. Zeeb "[TSSI][TRK] base_thermal=%d gain_offset=0x%x path=%d\n", 34598e93258fSBjoern A. Zeeb tssi_info->base_thermal[path], gain_offset, path); 34608e93258fSBjoern A. Zeeb 34618e93258fSBjoern A. Zeeb gain_offset_int = gain_offset >> 3; 34628e93258fSBjoern A. Zeeb gain_offset_float = gain_offset & 7; 34638e93258fSBjoern A. Zeeb 34648e93258fSBjoern A. Zeeb if (gain_offset_int > 15) 34658e93258fSBjoern A. Zeeb gain_offset_int = 15; 34668e93258fSBjoern A. Zeeb else if (gain_offset_int < -16) 34678e93258fSBjoern A. Zeeb gain_offset_int = -16; 34688e93258fSBjoern A. Zeeb 34698e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_EN + (path << 13), 34708e93258fSBjoern A. Zeeb B_DPD_OFT_EN, 0x1); 34718e93258fSBjoern A. Zeeb 34728e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), 34738e93258fSBjoern A. Zeeb B_TXGAIN_SCALE_EN, 0x1); 34748e93258fSBjoern A. Zeeb 34758e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_DPD_OFT_ADDR + (path << 13), 34768e93258fSBjoern A. Zeeb B_DPD_OFT_ADDR, gain_offset_int); 34778e93258fSBjoern A. Zeeb 34788e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_TXGAIN_SCALE + (path << 13), 34798e93258fSBjoern A. Zeeb B_TXGAIN_SCALE_OFT, 34808e93258fSBjoern A. Zeeb tx_gain_scale_table[gain_offset_float]); 34818e93258fSBjoern A. Zeeb } 34828e93258fSBjoern A. Zeeb } 34838e93258fSBjoern A. Zeeb 3484*df279a26SBjoern A. Zeeb static void _tssi_high_power(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3485*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 34868e93258fSBjoern A. Zeeb { 34878e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 34888e93258fSBjoern A. Zeeb u8 ch = chan->channel, ch_tmp; 34898e93258fSBjoern A. Zeeb u8 bw = chan->band_width; 34908e93258fSBjoern A. Zeeb u8 band = chan->band_type; 34918e93258fSBjoern A. Zeeb u8 subband = chan->subband_type; 34928e93258fSBjoern A. Zeeb s8 power; 34938e93258fSBjoern A. Zeeb s32 xdbm; 34948e93258fSBjoern A. Zeeb 34958e93258fSBjoern A. Zeeb if (bw == RTW89_CHANNEL_WIDTH_40) 34968e93258fSBjoern A. Zeeb ch_tmp = ch - 2; 34978e93258fSBjoern A. Zeeb else if (bw == RTW89_CHANNEL_WIDTH_80) 34988e93258fSBjoern A. Zeeb ch_tmp = ch - 6; 34998e93258fSBjoern A. Zeeb else 35008e93258fSBjoern A. Zeeb ch_tmp = ch; 35018e93258fSBjoern A. Zeeb 35028e93258fSBjoern A. Zeeb power = rtw89_phy_read_txpwr_limit(rtwdev, band, bw, RTW89_1TX, 35038e93258fSBjoern A. Zeeb RTW89_RS_MCS, RTW89_NONBF, ch_tmp); 35048e93258fSBjoern A. Zeeb 35058e93258fSBjoern A. Zeeb xdbm = power * 100 / 4; 35068e93258fSBjoern A. Zeeb 35078e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d xdbm=%d\n", 35088e93258fSBjoern A. Zeeb __func__, phy, xdbm); 35098e93258fSBjoern A. Zeeb 35108e93258fSBjoern A. Zeeb if (xdbm > 1800 && subband == RTW89_CH_2G) { 35118e93258fSBjoern A. Zeeb tssi_info->tssi_tracking_check[RF_PATH_A] = true; 35128e93258fSBjoern A. Zeeb tssi_info->tssi_tracking_check[RF_PATH_B] = true; 35138e93258fSBjoern A. Zeeb } else { 35148e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_tracking_defs_tbl); 35158e93258fSBjoern A. Zeeb tssi_info->extra_ofst[RF_PATH_A] = 0; 35168e93258fSBjoern A. Zeeb tssi_info->extra_ofst[RF_PATH_B] = 0; 35178e93258fSBjoern A. Zeeb tssi_info->tssi_tracking_check[RF_PATH_A] = false; 35188e93258fSBjoern A. Zeeb tssi_info->tssi_tracking_check[RF_PATH_B] = false; 35198e93258fSBjoern A. Zeeb } 35208e93258fSBjoern A. Zeeb } 35218e93258fSBjoern A. Zeeb 35228e93258fSBjoern A. Zeeb static void _tssi_hw_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3523*df279a26SBjoern A. Zeeb u8 path, s16 pwr_dbm, u8 enable, const struct rtw89_chan *chan) 35248e93258fSBjoern A. Zeeb { 35258e93258fSBjoern A. Zeeb rtw8852a_bb_set_plcp_tx(rtwdev); 35268e93258fSBjoern A. Zeeb rtw8852a_bb_cfg_tx_path(rtwdev, path); 35278e93258fSBjoern A. Zeeb rtw8852a_bb_set_power(rtwdev, pwr_dbm, phy); 3528*df279a26SBjoern A. Zeeb rtw8852a_bb_set_pmac_pkt_tx(rtwdev, enable, 20, 5000, 0, phy, chan); 35298e93258fSBjoern A. Zeeb } 35308e93258fSBjoern A. Zeeb 3531*df279a26SBjoern A. Zeeb static void _tssi_pre_tx(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3532*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 35338e93258fSBjoern A. Zeeb { 35348e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 3535*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 35368e93258fSBjoern A. Zeeb const struct rtw89_chip_info *mac_reg = rtwdev->chip; 35378e93258fSBjoern A. Zeeb u8 ch = chan->channel, ch_tmp; 35388e93258fSBjoern A. Zeeb u8 bw = chan->band_width; 35398e93258fSBjoern A. Zeeb u8 band = chan->band_type; 35408e93258fSBjoern A. Zeeb u32 tx_en; 3541*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy, 0, chanctx_idx); 35428e93258fSBjoern A. Zeeb s8 power; 35438e93258fSBjoern A. Zeeb s16 xdbm; 35448e93258fSBjoern A. Zeeb u32 i, tx_counter = 0; 35458e93258fSBjoern A. Zeeb 35468e93258fSBjoern A. Zeeb if (bw == RTW89_CHANNEL_WIDTH_40) 35478e93258fSBjoern A. Zeeb ch_tmp = ch - 2; 35488e93258fSBjoern A. Zeeb else if (bw == RTW89_CHANNEL_WIDTH_80) 35498e93258fSBjoern A. Zeeb ch_tmp = ch - 6; 35508e93258fSBjoern A. Zeeb else 35518e93258fSBjoern A. Zeeb ch_tmp = ch; 35528e93258fSBjoern A. Zeeb 35538e93258fSBjoern A. Zeeb power = rtw89_phy_read_txpwr_limit(rtwdev, band, RTW89_CHANNEL_WIDTH_20, 35548e93258fSBjoern A. Zeeb RTW89_1TX, RTW89_RS_OFDM, 35558e93258fSBjoern A. Zeeb RTW89_NONBF, ch_tmp); 35568e93258fSBjoern A. Zeeb 35578e93258fSBjoern A. Zeeb xdbm = (power * 100) >> mac_reg->txpwr_factor_mac; 35588e93258fSBjoern A. Zeeb 35598e93258fSBjoern A. Zeeb if (xdbm > 1800) 35608e93258fSBjoern A. Zeeb xdbm = 68; 35618e93258fSBjoern A. Zeeb else 35628e93258fSBjoern A. Zeeb xdbm = power * 2; 35638e93258fSBjoern A. Zeeb 35648e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 35658e93258fSBjoern A. Zeeb "[TSSI] %s: phy=%d org_power=%d xdbm=%d\n", 35668e93258fSBjoern A. Zeeb __func__, phy, power, xdbm); 35678e93258fSBjoern A. Zeeb 35688e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); 35698e93258fSBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy, &tx_en, RTW89_SCH_TX_SEL_ALL); 35708e93258fSBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy)); 35718e93258fSBjoern A. Zeeb tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD); 35728e93258fSBjoern A. Zeeb 3573*df279a26SBjoern A. Zeeb _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, true, chan); 35748e93258fSBjoern A. Zeeb mdelay(15); 3575*df279a26SBjoern A. Zeeb _tssi_hw_tx(rtwdev, phy, RF_PATH_AB, xdbm, false, chan); 35768e93258fSBjoern A. Zeeb 35778e93258fSBjoern A. Zeeb tx_counter = rtw89_phy_read32_mask(rtwdev, R_TX_COUNTER, MASKLWORD) - 35788e93258fSBjoern A. Zeeb tx_counter; 35798e93258fSBjoern A. Zeeb 35808e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0xc000 && 35818e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, MASKHWORD) != 0x0) { 35828e93258fSBjoern A. Zeeb for (i = 0; i < 6; i++) { 35838e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_A] = 35848e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, 35858e93258fSBjoern A. Zeeb MASKBYTE3); 35868e93258fSBjoern A. Zeeb 35878e93258fSBjoern A. Zeeb if (tssi_info->default_txagc_offset[RF_PATH_A] != 0x0) 35888e93258fSBjoern A. Zeeb break; 35898e93258fSBjoern A. Zeeb } 35908e93258fSBjoern A. Zeeb } 35918e93258fSBjoern A. Zeeb 35928e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0xc000 && 35938e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, MASKHWORD) != 0x0) { 35948e93258fSBjoern A. Zeeb for (i = 0; i < 6; i++) { 35958e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_B] = 35968e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, 35978e93258fSBjoern A. Zeeb MASKBYTE3); 35988e93258fSBjoern A. Zeeb 35998e93258fSBjoern A. Zeeb if (tssi_info->default_txagc_offset[RF_PATH_B] != 0x0) 36008e93258fSBjoern A. Zeeb break; 36018e93258fSBjoern A. Zeeb } 36028e93258fSBjoern A. Zeeb } 36038e93258fSBjoern A. Zeeb 36048e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 36058e93258fSBjoern A. Zeeb "[TSSI] %s: tx counter=%d\n", 36068e93258fSBjoern A. Zeeb __func__, tx_counter); 36078e93258fSBjoern A. Zeeb 36088e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, 36098e93258fSBjoern A. Zeeb "[TSSI] Backup R_TXAGC_BB=0x%x R_TXAGC_BB_S1=0x%x\n", 36108e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_A], 36118e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_B]); 36128e93258fSBjoern A. Zeeb 36138e93258fSBjoern A. Zeeb rtw8852a_bb_tx_mode_switch(rtwdev, phy, 0); 36148e93258fSBjoern A. Zeeb 36158e93258fSBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy, tx_en); 36168e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); 36178e93258fSBjoern A. Zeeb } 36188e93258fSBjoern A. Zeeb 36198e93258fSBjoern A. Zeeb void rtw8852a_rck(struct rtw89_dev *rtwdev) 36208e93258fSBjoern A. Zeeb { 36218e93258fSBjoern A. Zeeb u8 path; 36228e93258fSBjoern A. Zeeb 36238e93258fSBjoern A. Zeeb for (path = 0; path < 2; path++) 36248e93258fSBjoern A. Zeeb _rck(rtwdev, path); 36258e93258fSBjoern A. Zeeb } 36268e93258fSBjoern A. Zeeb 3627*df279a26SBjoern A. Zeeb void rtw8852a_dack(struct rtw89_dev *rtwdev, 3628*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 36298e93258fSBjoern A. Zeeb { 3630*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, RTW89_PHY_0, 0, chanctx_idx); 36318e93258fSBjoern A. Zeeb 36328e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_START); 3633*df279a26SBjoern A. Zeeb _dac_cal(rtwdev, false, chanctx_idx); 36348e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DACK, BTC_WRFK_STOP); 36358e93258fSBjoern A. Zeeb } 36368e93258fSBjoern A. Zeeb 3637*df279a26SBjoern A. Zeeb void rtw8852a_iqk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3638*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 36398e93258fSBjoern A. Zeeb { 36408e93258fSBjoern A. Zeeb u32 tx_en; 3641*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 36428e93258fSBjoern A. Zeeb 36438e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_START); 36448e93258fSBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 36458e93258fSBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 36468e93258fSBjoern A. Zeeb 36478e93258fSBjoern A. Zeeb _iqk_init(rtwdev); 36488e93258fSBjoern A. Zeeb if (rtwdev->dbcc_en) 3649*df279a26SBjoern A. Zeeb _iqk_dbcc(rtwdev, phy_idx, chanctx_idx); 36508e93258fSBjoern A. Zeeb else 3651*df279a26SBjoern A. Zeeb _iqk(rtwdev, phy_idx, false, chanctx_idx); 36528e93258fSBjoern A. Zeeb 36538e93258fSBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 36548e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_IQK, BTC_WRFK_STOP); 36558e93258fSBjoern A. Zeeb } 36568e93258fSBjoern A. Zeeb 36578e93258fSBjoern A. Zeeb void rtw8852a_rx_dck(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3658*df279a26SBjoern A. Zeeb bool is_afe, enum rtw89_chanctx_idx chanctx_idx) 36598e93258fSBjoern A. Zeeb { 36608e93258fSBjoern A. Zeeb u32 tx_en; 3661*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 36628e93258fSBjoern A. Zeeb 36638e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_START); 36648e93258fSBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 36658e93258fSBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 36668e93258fSBjoern A. Zeeb 3667*df279a26SBjoern A. Zeeb _rx_dck(rtwdev, phy_idx, is_afe, chanctx_idx); 36688e93258fSBjoern A. Zeeb 36698e93258fSBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 36708e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_RXDCK, BTC_WRFK_STOP); 36718e93258fSBjoern A. Zeeb } 36728e93258fSBjoern A. Zeeb 3673*df279a26SBjoern A. Zeeb void rtw8852a_dpk(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx, 3674*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 36758e93258fSBjoern A. Zeeb { 36768e93258fSBjoern A. Zeeb u32 tx_en; 3677*df279a26SBjoern A. Zeeb u8 phy_map = rtw89_btc_phymap(rtwdev, phy_idx, 0, chanctx_idx); 36788e93258fSBjoern A. Zeeb 36798e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_START); 36808e93258fSBjoern A. Zeeb rtw89_chip_stop_sch_tx(rtwdev, phy_idx, &tx_en, RTW89_SCH_TX_SEL_ALL); 36818e93258fSBjoern A. Zeeb _wait_rx_mode(rtwdev, _kpath(rtwdev, phy_idx)); 36828e93258fSBjoern A. Zeeb 36838e93258fSBjoern A. Zeeb rtwdev->dpk.is_dpk_enable = true; 36848e93258fSBjoern A. Zeeb rtwdev->dpk.is_dpk_reload_en = false; 3685*df279a26SBjoern A. Zeeb _dpk(rtwdev, phy_idx, false, chanctx_idx); 36868e93258fSBjoern A. Zeeb 36878e93258fSBjoern A. Zeeb rtw89_chip_resume_sch_tx(rtwdev, phy_idx, tx_en); 36888e93258fSBjoern A. Zeeb rtw89_btc_ntfy_wl_rfk(rtwdev, phy_map, BTC_WRFKT_DPK, BTC_WRFK_STOP); 36898e93258fSBjoern A. Zeeb } 36908e93258fSBjoern A. Zeeb 36918e93258fSBjoern A. Zeeb void rtw8852a_dpk_track(struct rtw89_dev *rtwdev) 36928e93258fSBjoern A. Zeeb { 36938e93258fSBjoern A. Zeeb _dpk_track(rtwdev); 36948e93258fSBjoern A. Zeeb } 36958e93258fSBjoern A. Zeeb 3696*df279a26SBjoern A. Zeeb void rtw8852a_tssi(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3697*df279a26SBjoern A. Zeeb enum rtw89_chanctx_idx chanctx_idx) 36988e93258fSBjoern A. Zeeb { 3699*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan = rtw89_chan_get(rtwdev, chanctx_idx); 37008e93258fSBjoern A. Zeeb u8 i; 37018e93258fSBjoern A. Zeeb 37028e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", 37038e93258fSBjoern A. Zeeb __func__, phy); 37048e93258fSBjoern A. Zeeb 37058e93258fSBjoern A. Zeeb _tssi_disable(rtwdev, phy); 37068e93258fSBjoern A. Zeeb 37078e93258fSBjoern A. Zeeb for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { 3708*df279a26SBjoern A. Zeeb _tssi_rf_setting(rtwdev, phy, i, chan); 3709*df279a26SBjoern A. Zeeb _tssi_set_sys(rtwdev, phy, chan); 3710*df279a26SBjoern A. Zeeb _tssi_ini_txpwr_ctrl_bb(rtwdev, phy, i, chan); 37118e93258fSBjoern A. Zeeb _tssi_ini_txpwr_ctrl_bb_he_tb(rtwdev, phy, i); 37128e93258fSBjoern A. Zeeb _tssi_set_dck(rtwdev, phy, i); 3713*df279a26SBjoern A. Zeeb _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); 37148e93258fSBjoern A. Zeeb _tssi_set_dac_gain_tbl(rtwdev, phy, i); 37158e93258fSBjoern A. Zeeb _tssi_slope_cal_org(rtwdev, phy, i); 37168e93258fSBjoern A. Zeeb _tssi_set_rf_gap_tbl(rtwdev, phy, i); 37178e93258fSBjoern A. Zeeb _tssi_set_slope(rtwdev, phy, i); 3718*df279a26SBjoern A. Zeeb _tssi_pak(rtwdev, phy, i, chan); 37198e93258fSBjoern A. Zeeb } 37208e93258fSBjoern A. Zeeb 37218e93258fSBjoern A. Zeeb _tssi_enable(rtwdev, phy); 3722*df279a26SBjoern A. Zeeb _tssi_set_efuse_to_de(rtwdev, phy, chan); 3723*df279a26SBjoern A. Zeeb _tssi_high_power(rtwdev, phy, chan); 3724*df279a26SBjoern A. Zeeb _tssi_pre_tx(rtwdev, phy, chanctx_idx); 37258e93258fSBjoern A. Zeeb } 37268e93258fSBjoern A. Zeeb 3727*df279a26SBjoern A. Zeeb void rtw8852a_tssi_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 3728*df279a26SBjoern A. Zeeb const struct rtw89_chan *chan) 37298e93258fSBjoern A. Zeeb { 37308e93258fSBjoern A. Zeeb u8 i; 37318e93258fSBjoern A. Zeeb 37328e93258fSBjoern A. Zeeb rtw89_debug(rtwdev, RTW89_DBG_TSSI, "[TSSI] %s: phy=%d\n", 37338e93258fSBjoern A. Zeeb __func__, phy); 37348e93258fSBjoern A. Zeeb 37358e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A]) 37368e93258fSBjoern A. Zeeb return; 37378e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_B]) 37388e93258fSBjoern A. Zeeb return; 37398e93258fSBjoern A. Zeeb 37408e93258fSBjoern A. Zeeb _tssi_disable(rtwdev, phy); 37418e93258fSBjoern A. Zeeb 37428e93258fSBjoern A. Zeeb for (i = RF_PATH_A; i < RF_PATH_NUM_8852A; i++) { 3743*df279a26SBjoern A. Zeeb _tssi_rf_setting(rtwdev, phy, i, chan); 3744*df279a26SBjoern A. Zeeb _tssi_set_sys(rtwdev, phy, chan); 3745*df279a26SBjoern A. Zeeb _tssi_set_tmeter_tbl(rtwdev, phy, i, chan); 3746*df279a26SBjoern A. Zeeb _tssi_pak(rtwdev, phy, i, chan); 37478e93258fSBjoern A. Zeeb } 37488e93258fSBjoern A. Zeeb 37498e93258fSBjoern A. Zeeb _tssi_enable(rtwdev, phy); 3750*df279a26SBjoern A. Zeeb _tssi_set_efuse_to_de(rtwdev, phy, chan); 37518e93258fSBjoern A. Zeeb } 37528e93258fSBjoern A. Zeeb 37538e93258fSBjoern A. Zeeb void rtw8852a_tssi_track(struct rtw89_dev *rtwdev) 37548e93258fSBjoern A. Zeeb { 37558e93258fSBjoern A. Zeeb _tssi_track(rtwdev); 37568e93258fSBjoern A. Zeeb } 37578e93258fSBjoern A. Zeeb 37588e93258fSBjoern A. Zeeb static 37598e93258fSBjoern A. Zeeb void _rtw8852a_tssi_avg_scan(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 37608e93258fSBjoern A. Zeeb { 37618e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) 37628e93258fSBjoern A. Zeeb return; 37638e93258fSBjoern A. Zeeb 37648e93258fSBjoern A. Zeeb /* disable */ 37658e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); 37668e93258fSBjoern A. Zeeb 37678e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x0); 37688e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x0); 37698e93258fSBjoern A. Zeeb 37708e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x0); 37718e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x0); 37728e93258fSBjoern A. Zeeb 37738e93258fSBjoern A. Zeeb /* enable */ 37748e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); 37758e93258fSBjoern A. Zeeb } 37768e93258fSBjoern A. Zeeb 37778e93258fSBjoern A. Zeeb static 37788e93258fSBjoern A. Zeeb void _rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy) 37798e93258fSBjoern A. Zeeb { 37808e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) 37818e93258fSBjoern A. Zeeb return; 37828e93258fSBjoern A. Zeeb 37838e93258fSBjoern A. Zeeb /* disable */ 37848e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_disable_defs_tbl); 37858e93258fSBjoern A. Zeeb 37868e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_AVG, B_P0_TSSI_AVG, 0x4); 37878e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_MV_AVG, B_P0_TSSI_MV_AVG, 0x2); 37888e93258fSBjoern A. Zeeb 37898e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_AVG, B_P1_TSSI_AVG, 0x4); 37908e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_MV_AVG, B_P1_TSSI_MV_AVG, 0x2); 37918e93258fSBjoern A. Zeeb 37928e93258fSBjoern A. Zeeb /* enable */ 37938e93258fSBjoern A. Zeeb rtw89_rfk_parser(rtwdev, &rtw8852a_tssi_enable_defs_ab_tbl); 37948e93258fSBjoern A. Zeeb } 37958e93258fSBjoern A. Zeeb 37968e93258fSBjoern A. Zeeb static void rtw8852a_tssi_set_avg(struct rtw89_dev *rtwdev, 37978e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, bool enable) 37988e93258fSBjoern A. Zeeb { 37998e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) 38008e93258fSBjoern A. Zeeb return; 38018e93258fSBjoern A. Zeeb 38028e93258fSBjoern A. Zeeb if (enable) { 38038e93258fSBjoern A. Zeeb /* SCAN_START */ 38048e93258fSBjoern A. Zeeb _rtw8852a_tssi_avg_scan(rtwdev, phy); 38058e93258fSBjoern A. Zeeb } else { 38068e93258fSBjoern A. Zeeb /* SCAN_END */ 38078e93258fSBjoern A. Zeeb _rtw8852a_tssi_set_avg(rtwdev, phy); 38088e93258fSBjoern A. Zeeb } 38098e93258fSBjoern A. Zeeb } 38108e93258fSBjoern A. Zeeb 38118e93258fSBjoern A. Zeeb static void rtw8852a_tssi_default_txagc(struct rtw89_dev *rtwdev, 38128e93258fSBjoern A. Zeeb enum rtw89_phy_idx phy, bool enable) 38138e93258fSBjoern A. Zeeb { 38148e93258fSBjoern A. Zeeb struct rtw89_tssi_info *tssi_info = &rtwdev->tssi; 38158e93258fSBjoern A. Zeeb u8 i; 38168e93258fSBjoern A. Zeeb 38178e93258fSBjoern A. Zeeb if (!rtwdev->is_tssi_mode[RF_PATH_A] && !rtwdev->is_tssi_mode[RF_PATH_B]) 38188e93258fSBjoern A. Zeeb return; 38198e93258fSBjoern A. Zeeb 38208e93258fSBjoern A. Zeeb if (enable) { 38218e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0xc000 && 38228e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, B_TXAGC_BB_OFT) != 0x0) { 38238e93258fSBjoern A. Zeeb for (i = 0; i < 6; i++) { 38248e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_A] = 38258e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB, 38268e93258fSBjoern A. Zeeb B_TXAGC_BB); 38278e93258fSBjoern A. Zeeb if (tssi_info->default_txagc_offset[RF_PATH_A]) 38288e93258fSBjoern A. Zeeb break; 38298e93258fSBjoern A. Zeeb } 38308e93258fSBjoern A. Zeeb } 38318e93258fSBjoern A. Zeeb 38328e93258fSBjoern A. Zeeb if (rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0xc000 && 38338e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, B_TXAGC_BB_S1_OFT) != 0x0) { 38348e93258fSBjoern A. Zeeb for (i = 0; i < 6; i++) { 38358e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_B] = 38368e93258fSBjoern A. Zeeb rtw89_phy_read32_mask(rtwdev, R_TXAGC_BB_S1, 38378e93258fSBjoern A. Zeeb B_TXAGC_BB_S1); 38388e93258fSBjoern A. Zeeb if (tssi_info->default_txagc_offset[RF_PATH_B]) 38398e93258fSBjoern A. Zeeb break; 38408e93258fSBjoern A. Zeeb } 38418e93258fSBjoern A. Zeeb } 38428e93258fSBjoern A. Zeeb } else { 38438e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT, 38448e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_A]); 38458e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT, 38468e93258fSBjoern A. Zeeb tssi_info->default_txagc_offset[RF_PATH_B]); 38478e93258fSBjoern A. Zeeb 38488e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x0); 38498e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P0_TSSI_TRK, B_P0_TSSI_OFT_EN, 0x1); 38508e93258fSBjoern A. Zeeb 38518e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x0); 38528e93258fSBjoern A. Zeeb rtw89_phy_write32_mask(rtwdev, R_P1_TSSI_TRK, B_P1_TSSI_OFT_EN, 0x1); 38538e93258fSBjoern A. Zeeb } 38548e93258fSBjoern A. Zeeb } 38558e93258fSBjoern A. Zeeb 38568e93258fSBjoern A. Zeeb void rtw8852a_wifi_scan_notify(struct rtw89_dev *rtwdev, 38578e93258fSBjoern A. Zeeb bool scan_start, enum rtw89_phy_idx phy_idx) 38588e93258fSBjoern A. Zeeb { 38598e93258fSBjoern A. Zeeb if (scan_start) { 38608e93258fSBjoern A. Zeeb rtw8852a_tssi_default_txagc(rtwdev, phy_idx, true); 38618e93258fSBjoern A. Zeeb rtw8852a_tssi_set_avg(rtwdev, phy_idx, true); 38628e93258fSBjoern A. Zeeb } else { 38638e93258fSBjoern A. Zeeb rtw8852a_tssi_default_txagc(rtwdev, phy_idx, false); 38648e93258fSBjoern A. Zeeb rtw8852a_tssi_set_avg(rtwdev, phy_idx, false); 38658e93258fSBjoern A. Zeeb } 38668e93258fSBjoern A. Zeeb } 3867