1*a0ccc12fSBjoern A. Zeeb // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2*a0ccc12fSBjoern A. Zeeb /* Copyright(c) 2024 Realtek Corporation 3*a0ccc12fSBjoern A. Zeeb */ 4*a0ccc12fSBjoern A. Zeeb 5*a0ccc12fSBjoern A. Zeeb #include "main.h" 6*a0ccc12fSBjoern A. Zeeb #include "coex.h" 7*a0ccc12fSBjoern A. Zeeb #include "phy.h" 8*a0ccc12fSBjoern A. Zeeb #include "reg.h" 9*a0ccc12fSBjoern A. Zeeb #include "rtw88xxa.h" 10*a0ccc12fSBjoern A. Zeeb #include "rtw8821a.h" 11*a0ccc12fSBjoern A. Zeeb #include "rtw8821a_table.h" 12*a0ccc12fSBjoern A. Zeeb #include "tx.h" 13*a0ccc12fSBjoern A. Zeeb 14*a0ccc12fSBjoern A. Zeeb static void rtw8821a_power_off(struct rtw_dev *rtwdev) 15*a0ccc12fSBjoern A. Zeeb { 16*a0ccc12fSBjoern A. Zeeb rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); 17*a0ccc12fSBjoern A. Zeeb } 18*a0ccc12fSBjoern A. Zeeb 19*a0ccc12fSBjoern A. Zeeb static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) 20*a0ccc12fSBjoern A. Zeeb { 21*a0ccc12fSBjoern A. Zeeb static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; 22*a0ccc12fSBjoern A. Zeeb s8 rx_pwr_all = 0; 23*a0ccc12fSBjoern A. Zeeb s8 lna_gain; 24*a0ccc12fSBjoern A. Zeeb 25*a0ccc12fSBjoern A. Zeeb switch (lna_idx) { 26*a0ccc12fSBjoern A. Zeeb case 5: 27*a0ccc12fSBjoern A. Zeeb case 4: 28*a0ccc12fSBjoern A. Zeeb case 2: 29*a0ccc12fSBjoern A. Zeeb case 1: 30*a0ccc12fSBjoern A. Zeeb case 0: 31*a0ccc12fSBjoern A. Zeeb lna_gain = lna_gain_table[lna_idx]; 32*a0ccc12fSBjoern A. Zeeb rx_pwr_all = lna_gain - 2 * vga_idx; 33*a0ccc12fSBjoern A. Zeeb break; 34*a0ccc12fSBjoern A. Zeeb default: 35*a0ccc12fSBjoern A. Zeeb break; 36*a0ccc12fSBjoern A. Zeeb } 37*a0ccc12fSBjoern A. Zeeb 38*a0ccc12fSBjoern A. Zeeb return rx_pwr_all; 39*a0ccc12fSBjoern A. Zeeb } 40*a0ccc12fSBjoern A. Zeeb 41*a0ccc12fSBjoern A. Zeeb static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, 42*a0ccc12fSBjoern A. Zeeb struct rtw_rx_pkt_stat *pkt_stat) 43*a0ccc12fSBjoern A. Zeeb { 44*a0ccc12fSBjoern A. Zeeb rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, 45*a0ccc12fSBjoern A. Zeeb rtw8821a_cck_rx_pwr); 46*a0ccc12fSBjoern A. Zeeb } 47*a0ccc12fSBjoern A. Zeeb 48*a0ccc12fSBjoern A. Zeeb static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) 49*a0ccc12fSBjoern A. Zeeb { 50*a0ccc12fSBjoern A. Zeeb } 51*a0ccc12fSBjoern A. Zeeb 52*a0ccc12fSBjoern A. Zeeb #define CAL_NUM_8821A 3 53*a0ccc12fSBjoern A. Zeeb #define MACBB_REG_NUM_8821A 8 54*a0ccc12fSBjoern A. Zeeb #define AFE_REG_NUM_8821A 4 55*a0ccc12fSBjoern A. Zeeb #define RF_REG_NUM_8821A 3 56*a0ccc12fSBjoern A. Zeeb 57*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, 58*a0ccc12fSBjoern A. Zeeb const u32 *backup_rf_reg, u32 rf_num) 59*a0ccc12fSBjoern A. Zeeb { 60*a0ccc12fSBjoern A. Zeeb u32 i; 61*a0ccc12fSBjoern A. Zeeb 62*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 63*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 64*a0ccc12fSBjoern A. Zeeb 65*a0ccc12fSBjoern A. Zeeb /* Save RF Parameters */ 66*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rf_num; i++) 67*a0ccc12fSBjoern A. Zeeb rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, 68*a0ccc12fSBjoern A. Zeeb backup_rf_reg[i], MASKDWORD); 69*a0ccc12fSBjoern A. Zeeb } 70*a0ccc12fSBjoern A. Zeeb 71*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, 72*a0ccc12fSBjoern A. Zeeb const u32 *backup_rf_reg, 73*a0ccc12fSBjoern A. Zeeb u32 *RF_backup, u32 rf_reg_num) 74*a0ccc12fSBjoern A. Zeeb { 75*a0ccc12fSBjoern A. Zeeb u32 i; 76*a0ccc12fSBjoern A. Zeeb 77*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 78*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 79*a0ccc12fSBjoern A. Zeeb 80*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rf_reg_num; i++) 81*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], 82*a0ccc12fSBjoern A. Zeeb RFREG_MASK, RF_backup[i]); 83*a0ccc12fSBjoern A. Zeeb } 84*a0ccc12fSBjoern A. Zeeb 85*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, 86*a0ccc12fSBjoern A. Zeeb const u32 *backup_afe_reg, u32 afe_num) 87*a0ccc12fSBjoern A. Zeeb { 88*a0ccc12fSBjoern A. Zeeb u32 i; 89*a0ccc12fSBjoern A. Zeeb 90*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 91*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 92*a0ccc12fSBjoern A. Zeeb 93*a0ccc12fSBjoern A. Zeeb /* Reload AFE Parameters */ 94*a0ccc12fSBjoern A. Zeeb for (i = 0; i < afe_num; i++) 95*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); 96*a0ccc12fSBjoern A. Zeeb 97*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 98*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 99*a0ccc12fSBjoern A. Zeeb 100*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); 101*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); 102*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); 103*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); 104*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); 105*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000); 106*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); 107*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); 108*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x0); 109*a0ccc12fSBjoern A. Zeeb } 110*a0ccc12fSBjoern A. Zeeb 111*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, 112*a0ccc12fSBjoern A. Zeeb unsigned int rx_x, unsigned int rx_y) 113*a0ccc12fSBjoern A. Zeeb { 114*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 115*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 116*a0ccc12fSBjoern A. Zeeb 117*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 118*a0ccc12fSBjoern A. Zeeb 0x000003ff, rx_x >> 1); 119*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 120*a0ccc12fSBjoern A. Zeeb 0x03ff0000, (rx_y >> 1) & 0x3ff); 121*a0ccc12fSBjoern A. Zeeb } 122*a0ccc12fSBjoern A. Zeeb 123*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, 124*a0ccc12fSBjoern A. Zeeb unsigned int tx_x, unsigned int tx_y) 125*a0ccc12fSBjoern A. Zeeb { 126*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 127*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 128*a0ccc12fSBjoern A. Zeeb 129*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); 130*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); 131*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); 132*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); 133*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); 134*a0ccc12fSBjoern A. Zeeb } 135*a0ccc12fSBjoern A. Zeeb 136*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal, 137*a0ccc12fSBjoern A. Zeeb bool *tx0iqkok, 138*a0ccc12fSBjoern A. Zeeb int tx_x0[CAL_NUM_8821A], 139*a0ccc12fSBjoern A. Zeeb int tx_y0[CAL_NUM_8821A]) 140*a0ccc12fSBjoern A. Zeeb { 141*a0ccc12fSBjoern A. Zeeb u32 cal_retry, delay_count, iqk_ready, tx_fail; 142*a0ccc12fSBjoern A. Zeeb int tx_dt[3], vdf_y[3], vdf_x[3]; 143*a0ccc12fSBjoern A. Zeeb int k; 144*a0ccc12fSBjoern A. Zeeb 145*a0ccc12fSBjoern A. Zeeb for (k = 0; k < 3; k++) { 146*a0ccc12fSBjoern A. Zeeb switch (k) { 147*a0ccc12fSBjoern A. Zeeb case 0: 148*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 149*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 150*a0ccc12fSBjoern A. Zeeb 0x18008c38); 151*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 152*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38); 153*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); 154*a0ccc12fSBjoern A. Zeeb break; 155*a0ccc12fSBjoern A. Zeeb case 1: 156*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 157*a0ccc12fSBjoern A. Zeeb BIT(28), 0x0); 158*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE, 159*a0ccc12fSBjoern A. Zeeb BIT(28), 0x0); 160*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); 161*a0ccc12fSBjoern A. Zeeb break; 162*a0ccc12fSBjoern A. Zeeb case 2: 163*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 164*a0ccc12fSBjoern A. Zeeb "vdf_y[1] = %x vdf_y[0] = %x\n", 165*a0ccc12fSBjoern A. Zeeb vdf_y[1] >> 21 & 0x00007ff, 166*a0ccc12fSBjoern A. Zeeb vdf_y[0] >> 21 & 0x00007ff); 167*a0ccc12fSBjoern A. Zeeb 168*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 169*a0ccc12fSBjoern A. Zeeb "vdf_x[1] = %x vdf_x[0] = %x\n", 170*a0ccc12fSBjoern A. Zeeb vdf_x[1] >> 21 & 0x00007ff, 171*a0ccc12fSBjoern A. Zeeb vdf_x[0] >> 21 & 0x00007ff); 172*a0ccc12fSBjoern A. Zeeb 173*a0ccc12fSBjoern A. Zeeb tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20); 174*a0ccc12fSBjoern A. Zeeb tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; 175*a0ccc12fSBjoern A. Zeeb tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); 176*a0ccc12fSBjoern A. Zeeb 177*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 178*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 179*a0ccc12fSBjoern A. Zeeb 0x18008c20); 180*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 181*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20); 182*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1); 183*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000, 184*a0ccc12fSBjoern A. Zeeb tx_dt[cal] & 0x00003fff); 185*a0ccc12fSBjoern A. Zeeb break; 186*a0ccc12fSBjoern A. Zeeb } 187*a0ccc12fSBjoern A. Zeeb 188*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 189*a0ccc12fSBjoern A. Zeeb 190*a0ccc12fSBjoern A. Zeeb for (cal_retry = 0; cal_retry < 10; cal_retry++) { 191*a0ccc12fSBjoern A. Zeeb /* one shot */ 192*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); 193*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); 194*a0ccc12fSBjoern A. Zeeb 195*a0ccc12fSBjoern A. Zeeb mdelay(10); 196*a0ccc12fSBjoern A. Zeeb 197*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 198*a0ccc12fSBjoern A. Zeeb 199*a0ccc12fSBjoern A. Zeeb for (delay_count = 0; delay_count < 20; delay_count++) { 200*a0ccc12fSBjoern A. Zeeb iqk_ready = rtw_read32_mask(rtwdev, 201*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 202*a0ccc12fSBjoern A. Zeeb BIT(10)); 203*a0ccc12fSBjoern A. Zeeb 204*a0ccc12fSBjoern A. Zeeb /* Originally: if (~iqk_ready || delay_count > 20) 205*a0ccc12fSBjoern A. Zeeb * that looks like a typo so make it more explicit 206*a0ccc12fSBjoern A. Zeeb */ 207*a0ccc12fSBjoern A. Zeeb iqk_ready = true; 208*a0ccc12fSBjoern A. Zeeb 209*a0ccc12fSBjoern A. Zeeb if (iqk_ready) 210*a0ccc12fSBjoern A. Zeeb break; 211*a0ccc12fSBjoern A. Zeeb 212*a0ccc12fSBjoern A. Zeeb mdelay(1); 213*a0ccc12fSBjoern A. Zeeb } 214*a0ccc12fSBjoern A. Zeeb 215*a0ccc12fSBjoern A. Zeeb if (delay_count < 20) { 216*a0ccc12fSBjoern A. Zeeb /* ============TXIQK Check============== */ 217*a0ccc12fSBjoern A. Zeeb tx_fail = rtw_read32_mask(rtwdev, 218*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 219*a0ccc12fSBjoern A. Zeeb BIT(12)); 220*a0ccc12fSBjoern A. Zeeb 221*a0ccc12fSBjoern A. Zeeb /* Originally: if (~tx_fail) { 222*a0ccc12fSBjoern A. Zeeb * It looks like a typo, so make it more explicit. 223*a0ccc12fSBjoern A. Zeeb */ 224*a0ccc12fSBjoern A. Zeeb tx_fail = false; 225*a0ccc12fSBjoern A. Zeeb 226*a0ccc12fSBjoern A. Zeeb if (!tx_fail) { 227*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 228*a0ccc12fSBjoern A. Zeeb 0x02000000); 229*a0ccc12fSBjoern A. Zeeb vdf_x[k] = rtw_read32_mask(rtwdev, 230*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 231*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 232*a0ccc12fSBjoern A. Zeeb vdf_x[k] <<= 21; 233*a0ccc12fSBjoern A. Zeeb 234*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 235*a0ccc12fSBjoern A. Zeeb 0x04000000); 236*a0ccc12fSBjoern A. Zeeb vdf_y[k] = rtw_read32_mask(rtwdev, 237*a0ccc12fSBjoern A. Zeeb REG_IQKA_END, 238*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 239*a0ccc12fSBjoern A. Zeeb vdf_y[k] <<= 21; 240*a0ccc12fSBjoern A. Zeeb 241*a0ccc12fSBjoern A. Zeeb *tx0iqkok = true; 242*a0ccc12fSBjoern A. Zeeb break; 243*a0ccc12fSBjoern A. Zeeb } 244*a0ccc12fSBjoern A. Zeeb 245*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_Y, 246*a0ccc12fSBjoern A. Zeeb 0x000007ff, 0x0); 247*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_X, 248*a0ccc12fSBjoern A. Zeeb 0x000007ff, 0x200); 249*a0ccc12fSBjoern A. Zeeb } 250*a0ccc12fSBjoern A. Zeeb 251*a0ccc12fSBjoern A. Zeeb *tx0iqkok = false; 252*a0ccc12fSBjoern A. Zeeb } 253*a0ccc12fSBjoern A. Zeeb } 254*a0ccc12fSBjoern A. Zeeb 255*a0ccc12fSBjoern A. Zeeb if (k == 3) { 256*a0ccc12fSBjoern A. Zeeb tx_x0[cal] = vdf_x[k - 1]; 257*a0ccc12fSBjoern A. Zeeb tx_y0[cal] = vdf_y[k - 1]; 258*a0ccc12fSBjoern A. Zeeb } 259*a0ccc12fSBjoern A. Zeeb } 260*a0ccc12fSBjoern A. Zeeb 261*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal, 262*a0ccc12fSBjoern A. Zeeb bool *tx0iqkok, 263*a0ccc12fSBjoern A. Zeeb int tx_x0[CAL_NUM_8821A], 264*a0ccc12fSBjoern A. Zeeb int tx_y0[CAL_NUM_8821A]) 265*a0ccc12fSBjoern A. Zeeb { 266*a0ccc12fSBjoern A. Zeeb u32 cal_retry, delay_count, iqk_ready, tx_fail; 267*a0ccc12fSBjoern A. Zeeb 268*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 269*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); 270*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 271*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); 272*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 273*a0ccc12fSBjoern A. Zeeb 274*a0ccc12fSBjoern A. Zeeb for (cal_retry = 0; cal_retry < 10; cal_retry++) { 275*a0ccc12fSBjoern A. Zeeb /* one shot */ 276*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); 277*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); 278*a0ccc12fSBjoern A. Zeeb 279*a0ccc12fSBjoern A. Zeeb mdelay(10); 280*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 281*a0ccc12fSBjoern A. Zeeb 282*a0ccc12fSBjoern A. Zeeb for (delay_count = 0; delay_count < 20; delay_count++) { 283*a0ccc12fSBjoern A. Zeeb iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); 284*a0ccc12fSBjoern A. Zeeb 285*a0ccc12fSBjoern A. Zeeb /* Originally: if (~iqk_ready || delay_count > 20) 286*a0ccc12fSBjoern A. Zeeb * that looks like a typo so make it more explicit 287*a0ccc12fSBjoern A. Zeeb */ 288*a0ccc12fSBjoern A. Zeeb iqk_ready = true; 289*a0ccc12fSBjoern A. Zeeb 290*a0ccc12fSBjoern A. Zeeb if (iqk_ready) 291*a0ccc12fSBjoern A. Zeeb break; 292*a0ccc12fSBjoern A. Zeeb 293*a0ccc12fSBjoern A. Zeeb mdelay(1); 294*a0ccc12fSBjoern A. Zeeb } 295*a0ccc12fSBjoern A. Zeeb 296*a0ccc12fSBjoern A. Zeeb if (delay_count < 20) { 297*a0ccc12fSBjoern A. Zeeb /* ============TXIQK Check============== */ 298*a0ccc12fSBjoern A. Zeeb tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); 299*a0ccc12fSBjoern A. Zeeb 300*a0ccc12fSBjoern A. Zeeb /* Originally: if (~tx_fail) { 301*a0ccc12fSBjoern A. Zeeb * It looks like a typo, so make it more explicit. 302*a0ccc12fSBjoern A. Zeeb */ 303*a0ccc12fSBjoern A. Zeeb tx_fail = false; 304*a0ccc12fSBjoern A. Zeeb 305*a0ccc12fSBjoern A. Zeeb if (!tx_fail) { 306*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); 307*a0ccc12fSBjoern A. Zeeb tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, 308*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 309*a0ccc12fSBjoern A. Zeeb tx_x0[cal] <<= 21; 310*a0ccc12fSBjoern A. Zeeb 311*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); 312*a0ccc12fSBjoern A. Zeeb tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, 313*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 314*a0ccc12fSBjoern A. Zeeb tx_y0[cal] <<= 21; 315*a0ccc12fSBjoern A. Zeeb 316*a0ccc12fSBjoern A. Zeeb *tx0iqkok = true; 317*a0ccc12fSBjoern A. Zeeb break; 318*a0ccc12fSBjoern A. Zeeb } 319*a0ccc12fSBjoern A. Zeeb 320*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); 321*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); 322*a0ccc12fSBjoern A. Zeeb } 323*a0ccc12fSBjoern A. Zeeb 324*a0ccc12fSBjoern A. Zeeb *tx0iqkok = false; 325*a0ccc12fSBjoern A. Zeeb } 326*a0ccc12fSBjoern A. Zeeb } 327*a0ccc12fSBjoern A. Zeeb 328*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok, 329*a0ccc12fSBjoern A. Zeeb int rx_x0[CAL_NUM_8821A], 330*a0ccc12fSBjoern A. Zeeb int rx_y0[CAL_NUM_8821A]) 331*a0ccc12fSBjoern A. Zeeb { 332*a0ccc12fSBjoern A. Zeeb u32 cal_retry, delay_count, iqk_ready, rx_fail; 333*a0ccc12fSBjoern A. Zeeb 334*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 335*a0ccc12fSBjoern A. Zeeb 336*a0ccc12fSBjoern A. Zeeb for (cal_retry = 0; cal_retry < 10; cal_retry++) { 337*a0ccc12fSBjoern A. Zeeb /* one shot */ 338*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); 339*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); 340*a0ccc12fSBjoern A. Zeeb 341*a0ccc12fSBjoern A. Zeeb mdelay(10); 342*a0ccc12fSBjoern A. Zeeb 343*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 344*a0ccc12fSBjoern A. Zeeb 345*a0ccc12fSBjoern A. Zeeb for (delay_count = 0; delay_count < 20; delay_count++) { 346*a0ccc12fSBjoern A. Zeeb iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); 347*a0ccc12fSBjoern A. Zeeb 348*a0ccc12fSBjoern A. Zeeb /* Originally: if (~iqk_ready || delay_count > 20) 349*a0ccc12fSBjoern A. Zeeb * that looks like a typo so make it more explicit 350*a0ccc12fSBjoern A. Zeeb */ 351*a0ccc12fSBjoern A. Zeeb iqk_ready = true; 352*a0ccc12fSBjoern A. Zeeb 353*a0ccc12fSBjoern A. Zeeb if (iqk_ready) 354*a0ccc12fSBjoern A. Zeeb break; 355*a0ccc12fSBjoern A. Zeeb 356*a0ccc12fSBjoern A. Zeeb mdelay(1); 357*a0ccc12fSBjoern A. Zeeb } 358*a0ccc12fSBjoern A. Zeeb 359*a0ccc12fSBjoern A. Zeeb if (delay_count < 20) { 360*a0ccc12fSBjoern A. Zeeb /* ============RXIQK Check============== */ 361*a0ccc12fSBjoern A. Zeeb rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); 362*a0ccc12fSBjoern A. Zeeb if (!rx_fail) { 363*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); 364*a0ccc12fSBjoern A. Zeeb rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, 365*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 366*a0ccc12fSBjoern A. Zeeb rx_x0[cal] <<= 21; 367*a0ccc12fSBjoern A. Zeeb 368*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); 369*a0ccc12fSBjoern A. Zeeb rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, 370*a0ccc12fSBjoern A. Zeeb 0x07ff0000); 371*a0ccc12fSBjoern A. Zeeb rx_y0[cal] <<= 21; 372*a0ccc12fSBjoern A. Zeeb 373*a0ccc12fSBjoern A. Zeeb *rx0iqkok = true; 374*a0ccc12fSBjoern A. Zeeb break; 375*a0ccc12fSBjoern A. Zeeb } 376*a0ccc12fSBjoern A. Zeeb 377*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 378*a0ccc12fSBjoern A. Zeeb 0x000003ff, 0x200 >> 1); 379*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, 380*a0ccc12fSBjoern A. Zeeb 0x03ff0000, 0x0 >> 1); 381*a0ccc12fSBjoern A. Zeeb } 382*a0ccc12fSBjoern A. Zeeb 383*a0ccc12fSBjoern A. Zeeb *rx0iqkok = false; 384*a0ccc12fSBjoern A. Zeeb } 385*a0ccc12fSBjoern A. Zeeb } 386*a0ccc12fSBjoern A. Zeeb 387*a0ccc12fSBjoern A. Zeeb static void rtw8821a_iqk(struct rtw_dev *rtwdev) 388*a0ccc12fSBjoern A. Zeeb { 389*a0ccc12fSBjoern A. Zeeb int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; 390*a0ccc12fSBjoern A. Zeeb const struct rtw_efuse *efuse = &rtwdev->efuse; 391*a0ccc12fSBjoern A. Zeeb int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; 392*a0ccc12fSBjoern A. Zeeb const struct rtw_hal *hal = &rtwdev->hal; 393*a0ccc12fSBjoern A. Zeeb bool tx0iqkok = false, rx0iqkok = false; 394*a0ccc12fSBjoern A. Zeeb int rx_x_temp = 0, rx_y_temp = 0; 395*a0ccc12fSBjoern A. Zeeb int rx_x0[2][CAL_NUM_8821A]; 396*a0ccc12fSBjoern A. Zeeb int rx_y0[2][CAL_NUM_8821A]; 397*a0ccc12fSBjoern A. Zeeb int tx_x0[CAL_NUM_8821A]; 398*a0ccc12fSBjoern A. Zeeb int tx_y0[CAL_NUM_8821A]; 399*a0ccc12fSBjoern A. Zeeb bool rx_finish1 = false; 400*a0ccc12fSBjoern A. Zeeb bool rx_finish2 = false; 401*a0ccc12fSBjoern A. Zeeb bool vdf_enable; 402*a0ccc12fSBjoern A. Zeeb u32 cal; 403*a0ccc12fSBjoern A. Zeeb int i; 404*a0ccc12fSBjoern A. Zeeb 405*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 406*a0ccc12fSBjoern A. Zeeb "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", 407*a0ccc12fSBjoern A. Zeeb hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); 408*a0ccc12fSBjoern A. Zeeb 409*a0ccc12fSBjoern A. Zeeb vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; 410*a0ccc12fSBjoern A. Zeeb 411*a0ccc12fSBjoern A. Zeeb for (cal = 0; cal < CAL_NUM_8821A; cal++) { 412*a0ccc12fSBjoern A. Zeeb /* path-A LOK */ 413*a0ccc12fSBjoern A. Zeeb 414*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 415*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 416*a0ccc12fSBjoern A. Zeeb 417*a0ccc12fSBjoern A. Zeeb /* ========path-A AFE all on======== */ 418*a0ccc12fSBjoern A. Zeeb /* Port 0 DAC/ADC on */ 419*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); 420*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); 421*a0ccc12fSBjoern A. Zeeb 422*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); 423*a0ccc12fSBjoern A. Zeeb 424*a0ccc12fSBjoern A. Zeeb /* hardware 3-wire off */ 425*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); 426*a0ccc12fSBjoern A. Zeeb 427*a0ccc12fSBjoern A. Zeeb /* LOK setting */ 428*a0ccc12fSBjoern A. Zeeb 429*a0ccc12fSBjoern A. Zeeb /* 1. DAC/ADC sampling rate (160 MHz) */ 430*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); 431*a0ccc12fSBjoern A. Zeeb 432*a0ccc12fSBjoern A. Zeeb /* 2. LoK RF setting (at BW = 20M) */ 433*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); 434*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3); 435*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 436*a0ccc12fSBjoern A. Zeeb 0x20000); 437*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 438*a0ccc12fSBjoern A. Zeeb 0x0003f); 439*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 440*a0ccc12fSBjoern A. Zeeb 0xf3fc3); 441*a0ccc12fSBjoern A. Zeeb 442*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 443*a0ccc12fSBjoern A. Zeeb 0x931d5); 444*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); 445*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); 446*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); 447*a0ccc12fSBjoern A. Zeeb /* TX (X,Y) */ 448*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); 449*a0ccc12fSBjoern A. Zeeb /* RX (X,Y) */ 450*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); 451*a0ccc12fSBjoern A. Zeeb /* [0]:AGC_en, [15]:idac_K_Mask */ 452*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); 453*a0ccc12fSBjoern A. Zeeb 454*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 455*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 456*a0ccc12fSBjoern A. Zeeb 457*a0ccc12fSBjoern A. Zeeb if (efuse->ext_pa_5g) 458*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 459*a0ccc12fSBjoern A. Zeeb 0x821403f7); 460*a0ccc12fSBjoern A. Zeeb else 461*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 462*a0ccc12fSBjoern A. Zeeb 0x821403f4); 463*a0ccc12fSBjoern A. Zeeb 464*a0ccc12fSBjoern A. Zeeb if (hal->current_band_type == RTW_BAND_5G) 465*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); 466*a0ccc12fSBjoern A. Zeeb else 467*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); 468*a0ccc12fSBjoern A. Zeeb 469*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 470*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); 471*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 472*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); 473*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); 474*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); 475*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); 476*a0ccc12fSBjoern A. Zeeb 477*a0ccc12fSBjoern A. Zeeb mdelay(10); 478*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); 479*a0ccc12fSBjoern A. Zeeb 480*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 481*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 482*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, 483*a0ccc12fSBjoern A. Zeeb rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); 484*a0ccc12fSBjoern A. Zeeb 485*a0ccc12fSBjoern A. Zeeb if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) 486*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 487*a0ccc12fSBjoern A. Zeeb RF18_BW_MASK, 0x1); 488*a0ccc12fSBjoern A. Zeeb else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) 489*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 490*a0ccc12fSBjoern A. Zeeb RF18_BW_MASK, 0x0); 491*a0ccc12fSBjoern A. Zeeb 492*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 493*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 494*a0ccc12fSBjoern A. Zeeb 495*a0ccc12fSBjoern A. Zeeb /* 3. TX RF setting */ 496*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 497*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 498*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); 499*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 500*a0ccc12fSBjoern A. Zeeb 0x20000); 501*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 502*a0ccc12fSBjoern A. Zeeb 0x0003f); 503*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 504*a0ccc12fSBjoern A. Zeeb 0xf3fc3); 505*a0ccc12fSBjoern A. Zeeb 506*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); 507*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); 508*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); 509*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); 510*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); 511*a0ccc12fSBjoern A. Zeeb /* TX (X,Y) */ 512*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); 513*a0ccc12fSBjoern A. Zeeb /* RX (X,Y) */ 514*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); 515*a0ccc12fSBjoern A. Zeeb /* [0]:AGC_en, [15]:idac_K_Mask */ 516*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910); 517*a0ccc12fSBjoern A. Zeeb 518*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 519*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 520*a0ccc12fSBjoern A. Zeeb 521*a0ccc12fSBjoern A. Zeeb if (efuse->ext_pa_5g) 522*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 523*a0ccc12fSBjoern A. Zeeb 0x821403f7); 524*a0ccc12fSBjoern A. Zeeb else 525*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 526*a0ccc12fSBjoern A. Zeeb 0x821403e3); 527*a0ccc12fSBjoern A. Zeeb 528*a0ccc12fSBjoern A. Zeeb if (hal->current_band_type == RTW_BAND_5G) 529*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); 530*a0ccc12fSBjoern A. Zeeb else 531*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); 532*a0ccc12fSBjoern A. Zeeb 533*a0ccc12fSBjoern A. Zeeb if (vdf_enable) 534*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok, 535*a0ccc12fSBjoern A. Zeeb tx_x0, tx_y0); 536*a0ccc12fSBjoern A. Zeeb else 537*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok, 538*a0ccc12fSBjoern A. Zeeb tx_x0, tx_y0); 539*a0ccc12fSBjoern A. Zeeb 540*a0ccc12fSBjoern A. Zeeb if (!tx0iqkok) 541*a0ccc12fSBjoern A. Zeeb break; /* TXK fail, Don't do RXK */ 542*a0ccc12fSBjoern A. Zeeb 543*a0ccc12fSBjoern A. Zeeb /* ====== RX IQK ====== */ 544*a0ccc12fSBjoern A. Zeeb /* [31] = 0 --> Page C */ 545*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); 546*a0ccc12fSBjoern A. Zeeb /* 1. RX RF setting */ 547*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); 548*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 549*a0ccc12fSBjoern A. Zeeb 0x30000); 550*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 551*a0ccc12fSBjoern A. Zeeb 0x0002f); 552*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 553*a0ccc12fSBjoern A. Zeeb 0xfffbb); 554*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); 555*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8); 556*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); 557*a0ccc12fSBjoern A. Zeeb 558*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, 559*a0ccc12fSBjoern A. Zeeb (tx_x0[cal] >> 21) & 0x000007ff); 560*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, 561*a0ccc12fSBjoern A. Zeeb (tx_y0[cal] >> 21) & 0x000007ff); 562*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); 563*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); 564*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); 565*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); 566*a0ccc12fSBjoern A. Zeeb 567*a0ccc12fSBjoern A. Zeeb /* [31] = 1 --> Page C1 */ 568*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); 569*a0ccc12fSBjoern A. Zeeb 570*a0ccc12fSBjoern A. Zeeb /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 571*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); 572*a0ccc12fSBjoern A. Zeeb /* RX_Tone_idx[9:0], RxK_Mask[29] */ 573*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); 574*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119); 575*a0ccc12fSBjoern A. Zeeb 576*a0ccc12fSBjoern A. Zeeb if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) 577*a0ccc12fSBjoern A. Zeeb rx_iqk_loop = 2; /* for 2% fail; */ 578*a0ccc12fSBjoern A. Zeeb else 579*a0ccc12fSBjoern A. Zeeb rx_iqk_loop = 1; 580*a0ccc12fSBjoern A. Zeeb 581*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rx_iqk_loop; i++) { 582*a0ccc12fSBjoern A. Zeeb if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0) 583*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ 584*a0ccc12fSBjoern A. Zeeb else 585*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); 586*a0ccc12fSBjoern A. Zeeb 587*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, 588*a0ccc12fSBjoern A. Zeeb rx_x0[i], rx_y0[i]); 589*a0ccc12fSBjoern A. Zeeb } 590*a0ccc12fSBjoern A. Zeeb 591*a0ccc12fSBjoern A. Zeeb if (tx0iqkok) 592*a0ccc12fSBjoern A. Zeeb tx_average++; 593*a0ccc12fSBjoern A. Zeeb if (rx0iqkok) 594*a0ccc12fSBjoern A. Zeeb rx_average++; 595*a0ccc12fSBjoern A. Zeeb } 596*a0ccc12fSBjoern A. Zeeb 597*a0ccc12fSBjoern A. Zeeb /* FillIQK Result */ 598*a0ccc12fSBjoern A. Zeeb 599*a0ccc12fSBjoern A. Zeeb if (tx_average == 0) 600*a0ccc12fSBjoern A. Zeeb return; 601*a0ccc12fSBjoern A. Zeeb 602*a0ccc12fSBjoern A. Zeeb for (i = 0; i < tx_average; i++) 603*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 604*a0ccc12fSBjoern A. Zeeb "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", 605*a0ccc12fSBjoern A. Zeeb i, (tx_x0[i] >> 21) & 0x000007ff, 606*a0ccc12fSBjoern A. Zeeb i, (tx_y0[i] >> 21) & 0x000007ff); 607*a0ccc12fSBjoern A. Zeeb 608*a0ccc12fSBjoern A. Zeeb if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0, 609*a0ccc12fSBjoern A. Zeeb &tx_x, &tx_y, true, true)) 610*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y); 611*a0ccc12fSBjoern A. Zeeb else 612*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0); 613*a0ccc12fSBjoern A. Zeeb 614*a0ccc12fSBjoern A. Zeeb if (rx_average == 0) 615*a0ccc12fSBjoern A. Zeeb return; 616*a0ccc12fSBjoern A. Zeeb 617*a0ccc12fSBjoern A. Zeeb for (i = 0; i < rx_average; i++) { 618*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 619*a0ccc12fSBjoern A. Zeeb "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", 620*a0ccc12fSBjoern A. Zeeb i, (rx_x0[0][i] >> 21) & 0x000007ff, 621*a0ccc12fSBjoern A. Zeeb i, (rx_y0[0][i] >> 21) & 0x000007ff); 622*a0ccc12fSBjoern A. Zeeb 623*a0ccc12fSBjoern A. Zeeb if (rx_iqk_loop == 2) 624*a0ccc12fSBjoern A. Zeeb rtw_dbg(rtwdev, RTW_DBG_RFK, 625*a0ccc12fSBjoern A. Zeeb "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", 626*a0ccc12fSBjoern A. Zeeb i, (rx_x0[1][i] >> 21) & 0x000007ff, 627*a0ccc12fSBjoern A. Zeeb i, (rx_y0[1][i] >> 21) & 0x000007ff); 628*a0ccc12fSBjoern A. Zeeb } 629*a0ccc12fSBjoern A. Zeeb 630*a0ccc12fSBjoern A. Zeeb rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], 631*a0ccc12fSBjoern A. Zeeb &rx_x_temp, &rx_y_temp, true, true); 632*a0ccc12fSBjoern A. Zeeb 633*a0ccc12fSBjoern A. Zeeb if (rx_finish1) { 634*a0ccc12fSBjoern A. Zeeb rx_x = rx_x_temp; 635*a0ccc12fSBjoern A. Zeeb rx_y = rx_y_temp; 636*a0ccc12fSBjoern A. Zeeb } 637*a0ccc12fSBjoern A. Zeeb 638*a0ccc12fSBjoern A. Zeeb if (rx_iqk_loop == 2) { 639*a0ccc12fSBjoern A. Zeeb rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4, 640*a0ccc12fSBjoern A. Zeeb rx_x0[1], rx_y0[1], 641*a0ccc12fSBjoern A. Zeeb &rx_x, &rx_y, true, true); 642*a0ccc12fSBjoern A. Zeeb 643*a0ccc12fSBjoern A. Zeeb if (rx_finish1 && rx_finish2) { 644*a0ccc12fSBjoern A. Zeeb rx_x = (rx_x + rx_x_temp) / 2; 645*a0ccc12fSBjoern A. Zeeb rx_y = (rx_y + rx_y_temp) / 2; 646*a0ccc12fSBjoern A. Zeeb } 647*a0ccc12fSBjoern A. Zeeb } 648*a0ccc12fSBjoern A. Zeeb 649*a0ccc12fSBjoern A. Zeeb if (rx_finish1 || rx_finish2) 650*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y); 651*a0ccc12fSBjoern A. Zeeb else 652*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0); 653*a0ccc12fSBjoern A. Zeeb } 654*a0ccc12fSBjoern A. Zeeb 655*a0ccc12fSBjoern A. Zeeb static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) 656*a0ccc12fSBjoern A. Zeeb { 657*a0ccc12fSBjoern A. Zeeb static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { 658*a0ccc12fSBjoern A. Zeeb 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c 659*a0ccc12fSBjoern A. Zeeb }; 660*a0ccc12fSBjoern A. Zeeb static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { 661*a0ccc12fSBjoern A. Zeeb 0xc5c, 0xc60, 0xc64, 0xc68 662*a0ccc12fSBjoern A. Zeeb }; 663*a0ccc12fSBjoern A. Zeeb static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { 664*a0ccc12fSBjoern A. Zeeb 0x65, 0x8f, 0x0 665*a0ccc12fSBjoern A. Zeeb }; 666*a0ccc12fSBjoern A. Zeeb u32 macbb_backup[MACBB_REG_NUM_8821A]; 667*a0ccc12fSBjoern A. Zeeb u32 afe_backup[AFE_REG_NUM_8821A]; 668*a0ccc12fSBjoern A. Zeeb u32 rfa_backup[RF_REG_NUM_8821A]; 669*a0ccc12fSBjoern A. Zeeb 670*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, 671*a0ccc12fSBjoern A. Zeeb backup_macbb_reg, MACBB_REG_NUM_8821A); 672*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, 673*a0ccc12fSBjoern A. Zeeb backup_afe_reg, AFE_REG_NUM_8821A); 674*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, 675*a0ccc12fSBjoern A. Zeeb backup_rf_reg, RF_REG_NUM_8821A); 676*a0ccc12fSBjoern A. Zeeb 677*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_configure_mac(rtwdev); 678*a0ccc12fSBjoern A. Zeeb 679*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk(rtwdev); 680*a0ccc12fSBjoern A. Zeeb 681*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, 682*a0ccc12fSBjoern A. Zeeb rfa_backup, RF_REG_NUM_8821A); 683*a0ccc12fSBjoern A. Zeeb rtw8821a_iqk_restore_afe(rtwdev, afe_backup, 684*a0ccc12fSBjoern A. Zeeb backup_afe_reg, AFE_REG_NUM_8821A); 685*a0ccc12fSBjoern A. Zeeb rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, 686*a0ccc12fSBjoern A. Zeeb backup_macbb_reg, MACBB_REG_NUM_8821A); 687*a0ccc12fSBjoern A. Zeeb } 688*a0ccc12fSBjoern A. Zeeb 689*a0ccc12fSBjoern A. Zeeb static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) 690*a0ccc12fSBjoern A. Zeeb { 691*a0ccc12fSBjoern A. Zeeb rtw8821a_do_iqk(rtwdev); 692*a0ccc12fSBjoern A. Zeeb } 693*a0ccc12fSBjoern A. Zeeb 694*a0ccc12fSBjoern A. Zeeb static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) 695*a0ccc12fSBjoern A. Zeeb { 696*a0ccc12fSBjoern A. Zeeb struct rtw_dm_info *dm_info = &rtwdev->dm_info; 697*a0ccc12fSBjoern A. Zeeb 698*a0ccc12fSBjoern A. Zeeb if (!dm_info->pwr_trk_triggered) { 699*a0ccc12fSBjoern A. Zeeb rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, 700*a0ccc12fSBjoern A. Zeeb GENMASK(17, 16), 0x03); 701*a0ccc12fSBjoern A. Zeeb dm_info->pwr_trk_triggered = true; 702*a0ccc12fSBjoern A. Zeeb return; 703*a0ccc12fSBjoern A. Zeeb } 704*a0ccc12fSBjoern A. Zeeb 705*a0ccc12fSBjoern A. Zeeb rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); 706*a0ccc12fSBjoern A. Zeeb dm_info->pwr_trk_triggered = false; 707*a0ccc12fSBjoern A. Zeeb } 708*a0ccc12fSBjoern A. Zeeb 709*a0ccc12fSBjoern A. Zeeb static void rtw8821a_led_set(struct led_classdev *led, 710*a0ccc12fSBjoern A. Zeeb enum led_brightness brightness) 711*a0ccc12fSBjoern A. Zeeb { 712*a0ccc12fSBjoern A. Zeeb struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev); 713*a0ccc12fSBjoern A. Zeeb u32 gpio8_cfg; 714*a0ccc12fSBjoern A. Zeeb u8 ledcfg; 715*a0ccc12fSBjoern A. Zeeb 716*a0ccc12fSBjoern A. Zeeb if (brightness == LED_OFF) { 717*a0ccc12fSBjoern A. Zeeb gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); 718*a0ccc12fSBjoern A. Zeeb gpio8_cfg &= ~BIT(24); 719*a0ccc12fSBjoern A. Zeeb gpio8_cfg |= BIT(16) | BIT(8); 720*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); 721*a0ccc12fSBjoern A. Zeeb } else { 722*a0ccc12fSBjoern A. Zeeb ledcfg = rtw_read8(rtwdev, REG_LED_CFG + 2); 723*a0ccc12fSBjoern A. Zeeb gpio8_cfg = rtw_read32(rtwdev, REG_GPIO_PIN_CTRL_2); 724*a0ccc12fSBjoern A. Zeeb 725*a0ccc12fSBjoern A. Zeeb ledcfg &= BIT(7) | BIT(6); 726*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_LED_CFG + 2, ledcfg); 727*a0ccc12fSBjoern A. Zeeb 728*a0ccc12fSBjoern A. Zeeb gpio8_cfg &= ~(BIT(24) | BIT(8)); 729*a0ccc12fSBjoern A. Zeeb gpio8_cfg |= BIT(16); 730*a0ccc12fSBjoern A. Zeeb rtw_write32(rtwdev, REG_GPIO_PIN_CTRL_2, gpio8_cfg); 731*a0ccc12fSBjoern A. Zeeb } 732*a0ccc12fSBjoern A. Zeeb } 733*a0ccc12fSBjoern A. Zeeb 734*a0ccc12fSBjoern A. Zeeb static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, 735*a0ccc12fSBjoern A. Zeeb struct rtw_tx_pkt_info *pkt_info, 736*a0ccc12fSBjoern A. Zeeb u8 *txdesc) 737*a0ccc12fSBjoern A. Zeeb { 738*a0ccc12fSBjoern A. Zeeb fill_txdesc_checksum_common(txdesc, 16); 739*a0ccc12fSBjoern A. Zeeb } 740*a0ccc12fSBjoern A. Zeeb 741*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev) 742*a0ccc12fSBjoern A. Zeeb { 743*a0ccc12fSBjoern A. Zeeb u8 val8; 744*a0ccc12fSBjoern A. Zeeb 745*a0ccc12fSBjoern A. Zeeb /* BT report packet sample rate */ 746*a0ccc12fSBjoern A. Zeeb rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); 747*a0ccc12fSBjoern A. Zeeb 748*a0ccc12fSBjoern A. Zeeb val8 = BIT_STATIS_BT_EN; 749*a0ccc12fSBjoern A. Zeeb if (rtwdev->efuse.share_ant) 750*a0ccc12fSBjoern A. Zeeb val8 |= BIT_R_GRANTALL_WLMASK; 751*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8); 752*a0ccc12fSBjoern A. Zeeb 753*a0ccc12fSBjoern A. Zeeb /* enable BT counter statistics */ 754*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3); 755*a0ccc12fSBjoern A. Zeeb 756*a0ccc12fSBjoern A. Zeeb /* enable PTA */ 757*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); 758*a0ccc12fSBjoern A. Zeeb } 759*a0ccc12fSBjoern A. Zeeb 760*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, 761*a0ccc12fSBjoern A. Zeeb u8 pos_type) 762*a0ccc12fSBjoern A. Zeeb { 763*a0ccc12fSBjoern A. Zeeb bool share_ant = rtwdev->efuse.share_ant; 764*a0ccc12fSBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 765*a0ccc12fSBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 766*a0ccc12fSBjoern A. Zeeb u32 phase = coex_dm->cur_ant_pos_type; 767*a0ccc12fSBjoern A. Zeeb 768*a0ccc12fSBjoern A. Zeeb if (!rtwdev->efuse.btcoex) 769*a0ccc12fSBjoern A. Zeeb return; 770*a0ccc12fSBjoern A. Zeeb 771*a0ccc12fSBjoern A. Zeeb switch (phase) { 772*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_POWERON: 773*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_INIT: 774*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 775*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 776*a0ccc12fSBjoern A. Zeeb rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); 777*a0ccc12fSBjoern A. Zeeb 778*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_RFE_CTRL8, 779*a0ccc12fSBjoern A. Zeeb share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); 780*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); 781*a0ccc12fSBjoern A. Zeeb break; 782*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_WONLY: 783*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 784*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 785*a0ccc12fSBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); 786*a0ccc12fSBjoern A. Zeeb 787*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); 788*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); 789*a0ccc12fSBjoern A. Zeeb break; 790*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_2G: 791*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 792*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 793*a0ccc12fSBjoern A. Zeeb rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); 794*a0ccc12fSBjoern A. Zeeb 795*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_RFE_CTRL8, 796*a0ccc12fSBjoern A. Zeeb share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); 797*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); 798*a0ccc12fSBjoern A. Zeeb break; 799*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_5G: 800*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 801*a0ccc12fSBjoern A. Zeeb rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 802*a0ccc12fSBjoern A. Zeeb rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); 803*a0ccc12fSBjoern A. Zeeb 804*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); 805*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 806*a0ccc12fSBjoern A. Zeeb share_ant ? 0x2 : 0x1); 807*a0ccc12fSBjoern A. Zeeb break; 808*a0ccc12fSBjoern A. Zeeb case COEX_SET_ANT_WOFF: 809*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); 810*a0ccc12fSBjoern A. Zeeb rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); 811*a0ccc12fSBjoern A. Zeeb rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); 812*a0ccc12fSBjoern A. Zeeb 813*a0ccc12fSBjoern A. Zeeb rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); 814*a0ccc12fSBjoern A. Zeeb rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 815*a0ccc12fSBjoern A. Zeeb share_ant ? 0x2 : 0x1); 816*a0ccc12fSBjoern A. Zeeb break; 817*a0ccc12fSBjoern A. Zeeb default: 818*a0ccc12fSBjoern A. Zeeb rtw_warn(rtwdev, "%s: not handling phase %d\n", 819*a0ccc12fSBjoern A. Zeeb __func__, phase); 820*a0ccc12fSBjoern A. Zeeb break; 821*a0ccc12fSBjoern A. Zeeb } 822*a0ccc12fSBjoern A. Zeeb } 823*a0ccc12fSBjoern A. Zeeb 824*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) 825*a0ccc12fSBjoern A. Zeeb { 826*a0ccc12fSBjoern A. Zeeb } 827*a0ccc12fSBjoern A. Zeeb 828*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) 829*a0ccc12fSBjoern A. Zeeb { 830*a0ccc12fSBjoern A. Zeeb } 831*a0ccc12fSBjoern A. Zeeb 832*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) 833*a0ccc12fSBjoern A. Zeeb { 834*a0ccc12fSBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 835*a0ccc12fSBjoern A. Zeeb struct rtw_coex_rfe *coex_rfe = &coex->rfe; 836*a0ccc12fSBjoern A. Zeeb 837*a0ccc12fSBjoern A. Zeeb coex_rfe->ant_switch_exist = true; 838*a0ccc12fSBjoern A. Zeeb } 839*a0ccc12fSBjoern A. Zeeb 840*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) 841*a0ccc12fSBjoern A. Zeeb { 842*a0ccc12fSBjoern A. Zeeb struct rtw_coex *coex = &rtwdev->coex; 843*a0ccc12fSBjoern A. Zeeb struct rtw_coex_dm *coex_dm = &coex->dm; 844*a0ccc12fSBjoern A. Zeeb struct rtw_efuse *efuse = &rtwdev->efuse; 845*a0ccc12fSBjoern A. Zeeb bool share_ant = efuse->share_ant; 846*a0ccc12fSBjoern A. Zeeb 847*a0ccc12fSBjoern A. Zeeb if (share_ant) 848*a0ccc12fSBjoern A. Zeeb return; 849*a0ccc12fSBjoern A. Zeeb 850*a0ccc12fSBjoern A. Zeeb if (wl_pwr == coex_dm->cur_wl_pwr_lvl) 851*a0ccc12fSBjoern A. Zeeb return; 852*a0ccc12fSBjoern A. Zeeb 853*a0ccc12fSBjoern A. Zeeb coex_dm->cur_wl_pwr_lvl = wl_pwr; 854*a0ccc12fSBjoern A. Zeeb } 855*a0ccc12fSBjoern A. Zeeb 856*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) 857*a0ccc12fSBjoern A. Zeeb { 858*a0ccc12fSBjoern A. Zeeb } 859*a0ccc12fSBjoern A. Zeeb 860*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8821a_ops = { 861*a0ccc12fSBjoern A. Zeeb .power_on = rtw88xxa_power_on, 862*a0ccc12fSBjoern A. Zeeb .power_off = rtw8821a_power_off, 863*a0ccc12fSBjoern A. Zeeb .phy_set_param = NULL, 864*a0ccc12fSBjoern A. Zeeb .read_efuse = rtw88xxa_read_efuse, 865*a0ccc12fSBjoern A. Zeeb .query_phy_status = rtw8821a_query_phy_status, 866*a0ccc12fSBjoern A. Zeeb .set_channel = rtw88xxa_set_channel, 867*a0ccc12fSBjoern A. Zeeb .mac_init = NULL, 868*a0ccc12fSBjoern A. Zeeb .read_rf = rtw88xxa_phy_read_rf, 869*a0ccc12fSBjoern A. Zeeb .write_rf = rtw_phy_write_rf_reg_sipi, 870*a0ccc12fSBjoern A. Zeeb .set_antenna = NULL, 871*a0ccc12fSBjoern A. Zeeb .set_tx_power_index = rtw88xxa_set_tx_power_index, 872*a0ccc12fSBjoern A. Zeeb .cfg_ldo25 = rtw8821a_cfg_ldo25, 873*a0ccc12fSBjoern A. Zeeb .efuse_grant = rtw88xxa_efuse_grant, 874*a0ccc12fSBjoern A. Zeeb .false_alarm_statistics = rtw88xxa_false_alarm_statistics, 875*a0ccc12fSBjoern A. Zeeb .phy_calibration = rtw8821a_phy_calibration, 876*a0ccc12fSBjoern A. Zeeb .cck_pd_set = rtw88xxa_phy_cck_pd_set, 877*a0ccc12fSBjoern A. Zeeb .pwr_track = rtw8821a_pwr_track, 878*a0ccc12fSBjoern A. Zeeb .config_bfee = NULL, 879*a0ccc12fSBjoern A. Zeeb .set_gid_table = NULL, 880*a0ccc12fSBjoern A. Zeeb .cfg_csi_rate = NULL, 881*a0ccc12fSBjoern A. Zeeb .led_set = rtw8821a_led_set, 882*a0ccc12fSBjoern A. Zeeb .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, 883*a0ccc12fSBjoern A. Zeeb .coex_set_init = rtw8821a_coex_cfg_init, 884*a0ccc12fSBjoern A. Zeeb .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, 885*a0ccc12fSBjoern A. Zeeb .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, 886*a0ccc12fSBjoern A. Zeeb .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, 887*a0ccc12fSBjoern A. Zeeb .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, 888*a0ccc12fSBjoern A. Zeeb .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, 889*a0ccc12fSBjoern A. Zeeb .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, 890*a0ccc12fSBjoern A. Zeeb }; 891*a0ccc12fSBjoern A. Zeeb 892*a0ccc12fSBjoern A. Zeeb static const struct rtw_page_table page_table_8821a[] = { 893*a0ccc12fSBjoern A. Zeeb /* hq_num, nq_num, lq_num, exq_num, gapq_num */ 894*a0ccc12fSBjoern A. Zeeb {0, 0, 0, 0, 0}, /* SDIO */ 895*a0ccc12fSBjoern A. Zeeb {0, 0, 0, 0, 0}, /* PCI */ 896*a0ccc12fSBjoern A. Zeeb {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */ 897*a0ccc12fSBjoern A. Zeeb {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */ 898*a0ccc12fSBjoern A. Zeeb {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */ 899*a0ccc12fSBjoern A. Zeeb }; 900*a0ccc12fSBjoern A. Zeeb 901*a0ccc12fSBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8821a[] = { 902*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 903*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 904*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 905*a0ccc12fSBjoern A. Zeeb 906*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 907*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 908*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 909*a0ccc12fSBjoern A. Zeeb 910*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, 911*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 912*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 913*a0ccc12fSBjoern A. Zeeb 914*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, 915*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 916*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, 917*a0ccc12fSBjoern A. Zeeb 918*a0ccc12fSBjoern A. Zeeb {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, 919*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, 920*a0ccc12fSBjoern A. Zeeb RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, 921*a0ccc12fSBjoern A. Zeeb }; 922*a0ccc12fSBjoern A. Zeeb 923*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8821a = { 924*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_EXTRA] = { 925*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, 926*a0ccc12fSBjoern A. Zeeb }, 927*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_LOW] = { 928*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, 929*a0ccc12fSBjoern A. Zeeb }, 930*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_NORMAL] = { 931*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, 932*a0ccc12fSBjoern A. Zeeb }, 933*a0ccc12fSBjoern A. Zeeb .prio[RTW_DMA_MAPPING_HIGH] = { 934*a0ccc12fSBjoern A. Zeeb .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, 935*a0ccc12fSBjoern A. Zeeb }, 936*a0ccc12fSBjoern A. Zeeb .wsize = false, 937*a0ccc12fSBjoern A. Zeeb }; 938*a0ccc12fSBjoern A. Zeeb 939*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg rtw8821a_dig[] = { 940*a0ccc12fSBjoern A. Zeeb [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, 941*a0ccc12fSBjoern A. Zeeb }; 942*a0ccc12fSBjoern A. Zeeb 943*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { 944*a0ccc12fSBjoern A. Zeeb [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, 945*a0ccc12fSBjoern A. Zeeb .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, 946*a0ccc12fSBjoern A. Zeeb .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, 947*a0ccc12fSBjoern A. Zeeb }; 948*a0ccc12fSBjoern A. Zeeb 949*a0ccc12fSBjoern A. Zeeb /* TODO */ 950*a0ccc12fSBjoern A. Zeeb /* rssi in percentage % (dbm = % - 100) */ 951*a0ccc12fSBjoern A. Zeeb static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40}; 952*a0ccc12fSBjoern A. Zeeb static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101}; 953*a0ccc12fSBjoern A. Zeeb 954*a0ccc12fSBjoern A. Zeeb /* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a 955*a0ccc12fSBjoern A. Zeeb * are copied from rtw8821c.c because the 8821au driver's tables are not 956*a0ccc12fSBjoern A. Zeeb * compatible with the coex code in rtw88. 957*a0ccc12fSBjoern A. Zeeb * 958*a0ccc12fSBjoern A. Zeeb * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51, 959*a0ccc12fSBjoern A. Zeeb * otherwise the firmware gets confused after pausing the music: 960*a0ccc12fSBjoern A. Zeeb * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00] 961*a0ccc12fSBjoern A. Zeeb * - 81 means PAN (personal area network) when it should be 4x (A2DP) 962*a0ccc12fSBjoern A. Zeeb * The music is not smooth with the PAN algorithm. 963*a0ccc12fSBjoern A. Zeeb */ 964*a0ccc12fSBjoern A. Zeeb 965*a0ccc12fSBjoern A. Zeeb /* Shared-Antenna Coex Table */ 966*a0ccc12fSBjoern A. Zeeb static const struct coex_table_para table_sant_8821a[] = { 967*a0ccc12fSBjoern A. Zeeb {0x55555555, 0x55555555}, /* case-0 */ 968*a0ccc12fSBjoern A. Zeeb {0x55555555, 0x55555555}, 969*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x66555555}, 970*a0ccc12fSBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 971*a0ccc12fSBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 972*a0ccc12fSBjoern A. Zeeb {0xfafafafa, 0xfafafafa}, /* case-5 */ 973*a0ccc12fSBjoern A. Zeeb {0x6a5a5555, 0xaaaaaaaa}, 974*a0ccc12fSBjoern A. Zeeb {0x6a5a56aa, 0x6a5a56aa}, 975*a0ccc12fSBjoern A. Zeeb {0x6a5a5a5a, 0x6a5a5a5a}, 976*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 977*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-10 */ 978*a0ccc12fSBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, 979*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6a5a5aaa}, 980*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6aaa6aaa}, 981*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6a5a5aaa}, 982*a0ccc12fSBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, /* case-15 */ 983*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 984*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0x6afa5afa}, 985*a0ccc12fSBjoern A. Zeeb {0xaaffffaa, 0xfafafafa}, 986*a0ccc12fSBjoern A. Zeeb {0xaa5555aa, 0x5a5a5a5a}, 987*a0ccc12fSBjoern A. Zeeb {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ 988*a0ccc12fSBjoern A. Zeeb {0xaa5555aa, 0xaaaaaaaa}, 989*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0x55555555}, 990*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 991*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0x5a5a5a5a}, 992*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0x5a5a5aaa}, /* case-25 */ 993*a0ccc12fSBjoern A. Zeeb {0x55555555, 0x5a5a5a5a}, 994*a0ccc12fSBjoern A. Zeeb {0x55555555, 0xaaaaaaaa}, 995*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6a5a6a5a}, 996*a0ccc12fSBjoern A. Zeeb {0x66556655, 0x66556655}, 997*a0ccc12fSBjoern A. Zeeb {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ 998*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0x5aaa5aaa}, 999*a0ccc12fSBjoern A. Zeeb {0x56555555, 0x5a5a5aaa} 1000*a0ccc12fSBjoern A. Zeeb }; 1001*a0ccc12fSBjoern A. Zeeb 1002*a0ccc12fSBjoern A. Zeeb /* Non-Shared-Antenna Coex Table */ 1003*a0ccc12fSBjoern A. Zeeb static const struct coex_table_para table_nsant_8821a[] = { 1004*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-100 */ 1005*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 1006*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x66555555}, 1007*a0ccc12fSBjoern A. Zeeb {0xaaaaaaaa, 0xaaaaaaaa}, 1008*a0ccc12fSBjoern A. Zeeb {0x5a5a5a5a, 0x5a5a5a5a}, 1009*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0xffffffff}, /* case-105 */ 1010*a0ccc12fSBjoern A. Zeeb {0x5afa5afa, 0x5afa5afa}, 1011*a0ccc12fSBjoern A. Zeeb {0x55555555, 0xfafafafa}, 1012*a0ccc12fSBjoern A. Zeeb {0x66555555, 0xfafafafa}, 1013*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x5a5a5a5a}, 1014*a0ccc12fSBjoern A. Zeeb {0x66555555, 0x6a5a5a5a}, /* case-110 */ 1015*a0ccc12fSBjoern A. Zeeb {0x66555555, 0xaaaaaaaa}, 1016*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 1017*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 1018*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xaaaaaaaa}, 1019*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xffff55ff}, /* case-115 */ 1020*a0ccc12fSBjoern A. Zeeb {0xaaffffaa, 0x5afa5afa}, 1021*a0ccc12fSBjoern A. Zeeb {0xaaffffaa, 0xaaaaaaaa}, 1022*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0xfafafafa}, 1023*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0xfafafafa}, 1024*a0ccc12fSBjoern A. Zeeb {0xffffffff, 0xaaaaaaaa}, /* case-120 */ 1025*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 1026*a0ccc12fSBjoern A. Zeeb {0xffff55ff, 0x5afa5afa}, 1027*a0ccc12fSBjoern A. Zeeb {0x55ff55ff, 0x55ff55ff} 1028*a0ccc12fSBjoern A. Zeeb }; 1029*a0ccc12fSBjoern A. Zeeb 1030*a0ccc12fSBjoern A. Zeeb /* Shared-Antenna TDMA */ 1031*a0ccc12fSBjoern A. Zeeb static const struct coex_tdma_para tdma_sant_8821a[] = { 1032*a0ccc12fSBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ 1033*a0ccc12fSBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ 1034*a0ccc12fSBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, 1035*a0ccc12fSBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x11} }, 1036*a0ccc12fSBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 1037*a0ccc12fSBjoern A. Zeeb { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ 1038*a0ccc12fSBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 1039*a0ccc12fSBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x10} }, 1040*a0ccc12fSBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1041*a0ccc12fSBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 1042*a0ccc12fSBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ 1043*a0ccc12fSBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x15} }, 1044*a0ccc12fSBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x10, 0x14} }, 1045*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, 1046*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 1047*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ 1048*a0ccc12fSBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 1049*a0ccc12fSBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x11, 0x50} }, 1050*a0ccc12fSBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 1051*a0ccc12fSBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 1052*a0ccc12fSBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ 1053*a0ccc12fSBjoern A. Zeeb { {0x51, 0x4a, 0x03, 0x10, 0x50} }, 1054*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x30, 0x54} }, 1055*a0ccc12fSBjoern A. Zeeb { {0x55, 0x08, 0x03, 0x10, 0x54} }, 1056*a0ccc12fSBjoern A. Zeeb { {0x65, 0x10, 0x03, 0x11, 0x10} }, 1057*a0ccc12fSBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ 1058*a0ccc12fSBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 1059*a0ccc12fSBjoern A. Zeeb { {0x61, 0x08, 0x03, 0x11, 0x11} } 1060*a0ccc12fSBjoern A. Zeeb }; 1061*a0ccc12fSBjoern A. Zeeb 1062*a0ccc12fSBjoern A. Zeeb /* Non-Shared-Antenna TDMA */ 1063*a0ccc12fSBjoern A. Zeeb static const struct coex_tdma_para tdma_nsant_8821a[] = { 1064*a0ccc12fSBjoern A. Zeeb { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ 1065*a0ccc12fSBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x11} }, 1066*a0ccc12fSBjoern A. Zeeb { {0x61, 0x25, 0x03, 0x11, 0x11} }, 1067*a0ccc12fSBjoern A. Zeeb { {0x61, 0x35, 0x03, 0x11, 0x11} }, 1068*a0ccc12fSBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x11} }, 1069*a0ccc12fSBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ 1070*a0ccc12fSBjoern A. Zeeb { {0x61, 0x45, 0x03, 0x11, 0x10} }, 1071*a0ccc12fSBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1072*a0ccc12fSBjoern A. Zeeb { {0x61, 0x30, 0x03, 0x11, 0x10} }, 1073*a0ccc12fSBjoern A. Zeeb { {0x61, 0x20, 0x03, 0x11, 0x10} }, 1074*a0ccc12fSBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ 1075*a0ccc12fSBjoern A. Zeeb { {0x61, 0x10, 0x03, 0x11, 0x11} }, 1076*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */ 1077*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */ 1078*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x03, 0x10, 0x55} }, 1079*a0ccc12fSBjoern A. Zeeb { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ 1080*a0ccc12fSBjoern A. Zeeb { {0x51, 0x45, 0x03, 0x10, 0x50} }, 1081*a0ccc12fSBjoern A. Zeeb { {0x51, 0x3a, 0x03, 0x10, 0x50} }, 1082*a0ccc12fSBjoern A. Zeeb { {0x51, 0x30, 0x03, 0x10, 0x50} }, 1083*a0ccc12fSBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, 1084*a0ccc12fSBjoern A. Zeeb { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ 1085*a0ccc12fSBjoern A. Zeeb { {0x51, 0x10, 0x03, 0x10, 0x50} } 1086*a0ccc12fSBjoern A. Zeeb }; 1087*a0ccc12fSBjoern A. Zeeb 1088*a0ccc12fSBjoern A. Zeeb /* TODO */ 1089*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8821a[] = { 1090*a0ccc12fSBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 1091*a0ccc12fSBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 1092*a0ccc12fSBjoern A. Zeeb {8, 17, true, 4}, 1093*a0ccc12fSBjoern A. Zeeb {7, 18, true, 4}, 1094*a0ccc12fSBjoern A. Zeeb {6, 19, true, 4}, 1095*a0ccc12fSBjoern A. Zeeb {5, 20, true, 4} 1096*a0ccc12fSBjoern A. Zeeb }; 1097*a0ccc12fSBjoern A. Zeeb 1098*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8821a[] = { 1099*a0ccc12fSBjoern A. Zeeb {0, 0, false, 7}, /* for normal */ 1100*a0ccc12fSBjoern A. Zeeb {0, 20, false, 7}, /* for WL-CPT */ 1101*a0ccc12fSBjoern A. Zeeb {3, 24, true, 5}, 1102*a0ccc12fSBjoern A. Zeeb {2, 26, true, 5}, 1103*a0ccc12fSBjoern A. Zeeb {1, 27, true, 5}, 1104*a0ccc12fSBjoern A. Zeeb {0, 28, true, 5} 1105*a0ccc12fSBjoern A. Zeeb }; 1106*a0ccc12fSBjoern A. Zeeb 1107*a0ccc12fSBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); 1108*a0ccc12fSBjoern A. Zeeb 1109*a0ccc12fSBjoern A. Zeeb static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; 1110*a0ccc12fSBjoern A. Zeeb 1111*a0ccc12fSBjoern A. Zeeb static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = { 1112*a0ccc12fSBjoern A. Zeeb {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 1113*a0ccc12fSBjoern A. Zeeb {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 1114*a0ccc12fSBjoern A. Zeeb {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 1115*a0ccc12fSBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 1116*a0ccc12fSBjoern A. Zeeb {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 1117*a0ccc12fSBjoern A. Zeeb {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 1118*a0ccc12fSBjoern A. Zeeb {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 1119*a0ccc12fSBjoern A. Zeeb {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 1120*a0ccc12fSBjoern A. Zeeb {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, 1121*a0ccc12fSBjoern A. Zeeb {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, 1122*a0ccc12fSBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 1123*a0ccc12fSBjoern A. Zeeb {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, 1124*a0ccc12fSBjoern A. Zeeb {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, 1125*a0ccc12fSBjoern A. Zeeb {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, 1126*a0ccc12fSBjoern A. Zeeb {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, 1127*a0ccc12fSBjoern A. Zeeb {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, 1128*a0ccc12fSBjoern A. Zeeb {0, 0, RTW_REG_DOMAIN_NL}, 1129*a0ccc12fSBjoern A. Zeeb {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, 1130*a0ccc12fSBjoern A. Zeeb {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 1131*a0ccc12fSBjoern A. Zeeb {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, 1132*a0ccc12fSBjoern A. Zeeb {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 1133*a0ccc12fSBjoern A. Zeeb {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, 1134*a0ccc12fSBjoern A. Zeeb }; 1135*a0ccc12fSBjoern A. Zeeb 1136*a0ccc12fSBjoern A. Zeeb const struct rtw_chip_info rtw8821a_hw_spec = { 1137*a0ccc12fSBjoern A. Zeeb .ops = &rtw8821a_ops, 1138*a0ccc12fSBjoern A. Zeeb .id = RTW_CHIP_TYPE_8821A, 1139*a0ccc12fSBjoern A. Zeeb .fw_name = "rtw88/rtw8821a_fw.bin", 1140*a0ccc12fSBjoern A. Zeeb .wlan_cpu = RTW_WCPU_11N, 1141*a0ccc12fSBjoern A. Zeeb .tx_pkt_desc_sz = 40, 1142*a0ccc12fSBjoern A. Zeeb .tx_buf_desc_sz = 16, 1143*a0ccc12fSBjoern A. Zeeb .rx_pkt_desc_sz = 24, 1144*a0ccc12fSBjoern A. Zeeb .rx_buf_desc_sz = 8, 1145*a0ccc12fSBjoern A. Zeeb .phy_efuse_size = 512, 1146*a0ccc12fSBjoern A. Zeeb .log_efuse_size = 512, 1147*a0ccc12fSBjoern A. Zeeb .ptct_efuse_size = 0, 1148*a0ccc12fSBjoern A. Zeeb .txff_size = 65536, 1149*a0ccc12fSBjoern A. Zeeb .rxff_size = 16128, 1150*a0ccc12fSBjoern A. Zeeb .rsvd_drv_pg_num = 8, 1151*a0ccc12fSBjoern A. Zeeb .txgi_factor = 1, 1152*a0ccc12fSBjoern A. Zeeb .is_pwr_by_rate_dec = true, 1153*a0ccc12fSBjoern A. Zeeb .max_power_index = 0x3f, 1154*a0ccc12fSBjoern A. Zeeb .csi_buf_pg_num = 0, 1155*a0ccc12fSBjoern A. Zeeb .band = RTW_BAND_2G | RTW_BAND_5G, 1156*a0ccc12fSBjoern A. Zeeb .page_size = 256, 1157*a0ccc12fSBjoern A. Zeeb .dig_min = 0x20, 1158*a0ccc12fSBjoern A. Zeeb .ht_supported = true, 1159*a0ccc12fSBjoern A. Zeeb .vht_supported = true, 1160*a0ccc12fSBjoern A. Zeeb .lps_deep_mode_supported = 0, 1161*a0ccc12fSBjoern A. Zeeb .sys_func_en = 0xFD, 1162*a0ccc12fSBjoern A. Zeeb .pwr_on_seq = card_enable_flow_8821a, 1163*a0ccc12fSBjoern A. Zeeb .pwr_off_seq = card_disable_flow_8821a, 1164*a0ccc12fSBjoern A. Zeeb .page_table = page_table_8821a, 1165*a0ccc12fSBjoern A. Zeeb .rqpn_table = rqpn_table_8821a, 1166*a0ccc12fSBjoern A. Zeeb .prioq_addrs = &prioq_addrs_8821a, 1167*a0ccc12fSBjoern A. Zeeb .intf_table = NULL, 1168*a0ccc12fSBjoern A. Zeeb .dig = rtw8821a_dig, 1169*a0ccc12fSBjoern A. Zeeb .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, 1170*a0ccc12fSBjoern A. Zeeb .ltecoex_addr = NULL, 1171*a0ccc12fSBjoern A. Zeeb .mac_tbl = &rtw8821a_mac_tbl, 1172*a0ccc12fSBjoern A. Zeeb .agc_tbl = &rtw8821a_agc_tbl, 1173*a0ccc12fSBjoern A. Zeeb .bb_tbl = &rtw8821a_bb_tbl, 1174*a0ccc12fSBjoern A. Zeeb .rf_tbl = {&rtw8821a_rf_a_tbl}, 1175*a0ccc12fSBjoern A. Zeeb .rfe_defs = rtw8821a_rfe_defs, 1176*a0ccc12fSBjoern A. Zeeb .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), 1177*a0ccc12fSBjoern A. Zeeb .rx_ldpc = false, 1178*a0ccc12fSBjoern A. Zeeb .hw_feature_report = false, 1179*a0ccc12fSBjoern A. Zeeb .c2h_ra_report_size = 4, 1180*a0ccc12fSBjoern A. Zeeb .old_datarate_fb_limit = true, 1181*a0ccc12fSBjoern A. Zeeb .usb_tx_agg_desc_num = 6, 1182*a0ccc12fSBjoern A. Zeeb .iqk_threshold = 8, 1183*a0ccc12fSBjoern A. Zeeb .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, 1184*a0ccc12fSBjoern A. Zeeb .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, 1185*a0ccc12fSBjoern A. Zeeb 1186*a0ccc12fSBjoern A. Zeeb .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ 1187*a0ccc12fSBjoern A. Zeeb .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */ 1188*a0ccc12fSBjoern A. Zeeb .scbd_support = false, 1189*a0ccc12fSBjoern A. Zeeb .new_scbd10_def = false, 1190*a0ccc12fSBjoern A. Zeeb .ble_hid_profile_support = false, 1191*a0ccc12fSBjoern A. Zeeb .wl_mimo_ps_support = false, 1192*a0ccc12fSBjoern A. Zeeb .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, 1193*a0ccc12fSBjoern A. Zeeb .bt_rssi_type = COEX_BTRSSI_RATIO, 1194*a0ccc12fSBjoern A. Zeeb .ant_isolation = 10, 1195*a0ccc12fSBjoern A. Zeeb .rssi_tolerance = 2, 1196*a0ccc12fSBjoern A. Zeeb .wl_rssi_step = wl_rssi_step_8821a, 1197*a0ccc12fSBjoern A. Zeeb .bt_rssi_step = bt_rssi_step_8821a, 1198*a0ccc12fSBjoern A. Zeeb .table_sant_num = ARRAY_SIZE(table_sant_8821a), 1199*a0ccc12fSBjoern A. Zeeb .table_sant = table_sant_8821a, 1200*a0ccc12fSBjoern A. Zeeb .table_nsant_num = ARRAY_SIZE(table_nsant_8821a), 1201*a0ccc12fSBjoern A. Zeeb .table_nsant = table_nsant_8821a, 1202*a0ccc12fSBjoern A. Zeeb .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a), 1203*a0ccc12fSBjoern A. Zeeb .tdma_sant = tdma_sant_8821a, 1204*a0ccc12fSBjoern A. Zeeb .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a), 1205*a0ccc12fSBjoern A. Zeeb .tdma_nsant = tdma_nsant_8821a, 1206*a0ccc12fSBjoern A. Zeeb .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a), 1207*a0ccc12fSBjoern A. Zeeb .wl_rf_para_tx = rf_para_tx_8821a, 1208*a0ccc12fSBjoern A. Zeeb .wl_rf_para_rx = rf_para_rx_8821a, 1209*a0ccc12fSBjoern A. Zeeb .bt_afh_span_bw20 = 0x20, 1210*a0ccc12fSBjoern A. Zeeb .bt_afh_span_bw40 = 0x30, 1211*a0ccc12fSBjoern A. Zeeb .afh_5g_num = ARRAY_SIZE(afh_5g_8821a), 1212*a0ccc12fSBjoern A. Zeeb .afh_5g = afh_5g_8821a, 1213*a0ccc12fSBjoern A. Zeeb 1214*a0ccc12fSBjoern A. Zeeb .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a), 1215*a0ccc12fSBjoern A. Zeeb .coex_info_hw_regs = coex_info_hw_regs_8821a, 1216*a0ccc12fSBjoern A. Zeeb }; 1217*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw8821a_hw_spec); 1218*a0ccc12fSBjoern A. Zeeb 1219*a0ccc12fSBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); 1220*a0ccc12fSBjoern A. Zeeb 1221*a0ccc12fSBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation"); 1222*a0ccc12fSBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); 1223*a0ccc12fSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL"); 1224