xref: /freebsd/sys/contrib/dev/rtw88/rtw8812a.c (revision a0ccc12f6882a886d89ae279c541b2c2b62c6aca)
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 "rtw8812a.h"
11*a0ccc12fSBjoern A. Zeeb #include "rtw8812a_table.h"
12*a0ccc12fSBjoern A. Zeeb #include "tx.h"
13*a0ccc12fSBjoern A. Zeeb 
14*a0ccc12fSBjoern A. Zeeb static void rtw8812a_power_off(struct rtw_dev *rtwdev)
15*a0ccc12fSBjoern A. Zeeb {
16*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a);
17*a0ccc12fSBjoern A. Zeeb }
18*a0ccc12fSBjoern A. Zeeb 
19*a0ccc12fSBjoern A. Zeeb static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx)
20*a0ccc12fSBjoern A. Zeeb {
21*a0ccc12fSBjoern A. Zeeb 	s8 rx_pwr_all = 0;
22*a0ccc12fSBjoern A. Zeeb 
23*a0ccc12fSBjoern A. Zeeb 	switch (lna_idx) {
24*a0ccc12fSBjoern A. Zeeb 	case 7:
25*a0ccc12fSBjoern A. Zeeb 		if (vga_idx <= 27)
26*a0ccc12fSBjoern A. Zeeb 			rx_pwr_all = -94 + 2 * (27 - vga_idx);
27*a0ccc12fSBjoern A. Zeeb 		else
28*a0ccc12fSBjoern A. Zeeb 			rx_pwr_all = -94;
29*a0ccc12fSBjoern A. Zeeb 		break;
30*a0ccc12fSBjoern A. Zeeb 	case 6:
31*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = -42 + 2 * (2 - vga_idx);
32*a0ccc12fSBjoern A. Zeeb 		break;
33*a0ccc12fSBjoern A. Zeeb 	case 5:
34*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = -36 + 2 * (7 - vga_idx);
35*a0ccc12fSBjoern A. Zeeb 		break;
36*a0ccc12fSBjoern A. Zeeb 	case 4:
37*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = -30 + 2 * (7 - vga_idx);
38*a0ccc12fSBjoern A. Zeeb 		break;
39*a0ccc12fSBjoern A. Zeeb 	case 3:
40*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = -18 + 2 * (7 - vga_idx);
41*a0ccc12fSBjoern A. Zeeb 		break;
42*a0ccc12fSBjoern A. Zeeb 	case 2:
43*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = 2 * (5 - vga_idx);
44*a0ccc12fSBjoern A. Zeeb 		break;
45*a0ccc12fSBjoern A. Zeeb 	case 1:
46*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = 14 - 2 * vga_idx;
47*a0ccc12fSBjoern A. Zeeb 		break;
48*a0ccc12fSBjoern A. Zeeb 	case 0:
49*a0ccc12fSBjoern A. Zeeb 		rx_pwr_all = 20 - 2 * vga_idx;
50*a0ccc12fSBjoern A. Zeeb 		break;
51*a0ccc12fSBjoern A. Zeeb 	default:
52*a0ccc12fSBjoern A. Zeeb 		break;
53*a0ccc12fSBjoern A. Zeeb 	}
54*a0ccc12fSBjoern A. Zeeb 
55*a0ccc12fSBjoern A. Zeeb 	return rx_pwr_all;
56*a0ccc12fSBjoern A. Zeeb }
57*a0ccc12fSBjoern A. Zeeb 
58*a0ccc12fSBjoern A. Zeeb static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status,
59*a0ccc12fSBjoern A. Zeeb 				      struct rtw_rx_pkt_stat *pkt_stat)
60*a0ccc12fSBjoern A. Zeeb {
61*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat,
62*a0ccc12fSBjoern A. Zeeb 				  rtw8812a_cck_rx_pwr);
63*a0ccc12fSBjoern A. Zeeb 
64*a0ccc12fSBjoern A. Zeeb 	if (pkt_stat->rate >= DESC_RATE6M)
65*a0ccc12fSBjoern A. Zeeb 		return;
66*a0ccc12fSBjoern A. Zeeb 
67*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->hal.cck_high_power)
68*a0ccc12fSBjoern A. Zeeb 		return;
69*a0ccc12fSBjoern A. Zeeb 
70*a0ccc12fSBjoern A. Zeeb 	if (pkt_stat->rssi >= 80)
71*a0ccc12fSBjoern A. Zeeb 		pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) +
72*a0ccc12fSBjoern A. Zeeb 				 ((pkt_stat->rssi - 80) >> 1) + 80;
73*a0ccc12fSBjoern A. Zeeb 	else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20)
74*a0ccc12fSBjoern A. Zeeb 		pkt_stat->rssi += 3;
75*a0ccc12fSBjoern A. Zeeb }
76*a0ccc12fSBjoern A. Zeeb 
77*a0ccc12fSBjoern A. Zeeb static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable)
78*a0ccc12fSBjoern A. Zeeb {
79*a0ccc12fSBjoern A. Zeeb }
80*a0ccc12fSBjoern A. Zeeb 
81*a0ccc12fSBjoern A. Zeeb static void rtw8812a_do_lck(struct rtw_dev *rtwdev)
82*a0ccc12fSBjoern A. Zeeb {
83*a0ccc12fSBjoern A. Zeeb 	u32 cont_tx, lc_cal, i;
84*a0ccc12fSBjoern A. Zeeb 
85*a0ccc12fSBjoern A. Zeeb 	cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000);
86*a0ccc12fSBjoern A. Zeeb 
87*a0ccc12fSBjoern A. Zeeb 	lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK);
88*a0ccc12fSBjoern A. Zeeb 
89*a0ccc12fSBjoern A. Zeeb 	if (!cont_tx)
90*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_TXPAUSE, 0xff);
91*a0ccc12fSBjoern A. Zeeb 
92*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1);
93*a0ccc12fSBjoern A. Zeeb 
94*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1);
95*a0ccc12fSBjoern A. Zeeb 
96*a0ccc12fSBjoern A. Zeeb 	mdelay(150);
97*a0ccc12fSBjoern A. Zeeb 
98*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < 5; i++) {
99*a0ccc12fSBjoern A. Zeeb 		if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1)
100*a0ccc12fSBjoern A. Zeeb 			break;
101*a0ccc12fSBjoern A. Zeeb 
102*a0ccc12fSBjoern A. Zeeb 		mdelay(10);
103*a0ccc12fSBjoern A. Zeeb 	}
104*a0ccc12fSBjoern A. Zeeb 
105*a0ccc12fSBjoern A. Zeeb 	if (i == 5)
106*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n");
107*a0ccc12fSBjoern A. Zeeb 
108*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
109*a0ccc12fSBjoern A. Zeeb 
110*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0);
111*a0ccc12fSBjoern A. Zeeb 
112*a0ccc12fSBjoern A. Zeeb 	if (!cont_tx)
113*a0ccc12fSBjoern A. Zeeb 		rtw_write8(rtwdev, REG_TXPAUSE, 0);
114*a0ccc12fSBjoern A. Zeeb 
115*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal);
116*a0ccc12fSBjoern A. Zeeb }
117*a0ccc12fSBjoern A. Zeeb 
118*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup,
119*a0ccc12fSBjoern A. Zeeb 				   u32 *rfb_backup, const u32 *backup_rf_reg,
120*a0ccc12fSBjoern A. Zeeb 				   u32 rf_num)
121*a0ccc12fSBjoern A. Zeeb {
122*a0ccc12fSBjoern A. Zeeb 	u32 i;
123*a0ccc12fSBjoern A. Zeeb 
124*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
125*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
126*a0ccc12fSBjoern A. Zeeb 
127*a0ccc12fSBjoern A. Zeeb 	/* Save RF Parameters */
128*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < rf_num; i++) {
129*a0ccc12fSBjoern A. Zeeb 		rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A,
130*a0ccc12fSBjoern A. Zeeb 					    backup_rf_reg[i], MASKDWORD);
131*a0ccc12fSBjoern A. Zeeb 		rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B,
132*a0ccc12fSBjoern A. Zeeb 					    backup_rf_reg[i], MASKDWORD);
133*a0ccc12fSBjoern A. Zeeb 	}
134*a0ccc12fSBjoern A. Zeeb }
135*a0ccc12fSBjoern A. Zeeb 
136*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev,
137*a0ccc12fSBjoern A. Zeeb 				    enum rtw_rf_path path,
138*a0ccc12fSBjoern A. Zeeb 				    const u32 *backup_rf_reg,
139*a0ccc12fSBjoern A. Zeeb 				    u32 *RF_backup, u32 rf_reg_num)
140*a0ccc12fSBjoern A. Zeeb {
141*a0ccc12fSBjoern A. Zeeb 	u32 i;
142*a0ccc12fSBjoern A. Zeeb 
143*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
144*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
145*a0ccc12fSBjoern A. Zeeb 
146*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < rf_reg_num; i++)
147*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, path, backup_rf_reg[i],
148*a0ccc12fSBjoern A. Zeeb 			     RFREG_MASK, RF_backup[i]);
149*a0ccc12fSBjoern A. Zeeb 
150*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0);
151*a0ccc12fSBjoern A. Zeeb }
152*a0ccc12fSBjoern A. Zeeb 
153*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup,
154*a0ccc12fSBjoern A. Zeeb 				     const u32 *backup_afe_reg, u32 afe_num)
155*a0ccc12fSBjoern A. Zeeb {
156*a0ccc12fSBjoern A. Zeeb 	u32 i;
157*a0ccc12fSBjoern A. Zeeb 
158*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
159*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
160*a0ccc12fSBjoern A. Zeeb 
161*a0ccc12fSBjoern A. Zeeb 	/* Reload AFE Parameters */
162*a0ccc12fSBjoern A. Zeeb 	for (i = 0; i < afe_num; i++)
163*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]);
164*a0ccc12fSBjoern A. Zeeb 
165*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
166*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
167*a0ccc12fSBjoern A. Zeeb 
168*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0);
169*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0);
170*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0);
171*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
172*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1);
173*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1);
174*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1);
175*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1);
176*a0ccc12fSBjoern A. Zeeb 
177*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TXTONEB, 0x0);
178*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXTONEB, 0x0);
179*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TXPITMB, 0x0);
180*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);
181*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1);
182*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1);
183*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1);
184*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1);
185*a0ccc12fSBjoern A. Zeeb }
186*a0ccc12fSBjoern A. Zeeb 
187*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
188*a0ccc12fSBjoern A. Zeeb 				 unsigned int rx_x, unsigned int rx_y)
189*a0ccc12fSBjoern A. Zeeb {
190*a0ccc12fSBjoern A. Zeeb 	switch (path) {
191*a0ccc12fSBjoern A. Zeeb 	case RF_PATH_A:
192*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
193*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
194*a0ccc12fSBjoern A. Zeeb 		if (rx_x >> 1 >= 0x112 ||
195*a0ccc12fSBjoern A. Zeeb 		    (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
196*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
197*a0ccc12fSBjoern A. Zeeb 					 0x000003ff, 0x100);
198*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
199*a0ccc12fSBjoern A. Zeeb 					 0x03ff0000, 0);
200*a0ccc12fSBjoern A. Zeeb 		} else {
201*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
202*a0ccc12fSBjoern A. Zeeb 					 0x000003ff, rx_x >> 1);
203*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A,
204*a0ccc12fSBjoern A. Zeeb 					 0x03ff0000, rx_y >> 1);
205*a0ccc12fSBjoern A. Zeeb 		}
206*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
207*a0ccc12fSBjoern A. Zeeb 			"rx_x = %x;;rx_y = %x ====>fill to IQC\n",
208*a0ccc12fSBjoern A. Zeeb 			rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
209*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n",
210*a0ccc12fSBjoern A. Zeeb 			rtw_read32(rtwdev, REG_RX_IQC_AB_A));
211*a0ccc12fSBjoern A. Zeeb 		break;
212*a0ccc12fSBjoern A. Zeeb 	case RF_PATH_B:
213*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
214*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
215*a0ccc12fSBjoern A. Zeeb 		if (rx_x >> 1 >= 0x112 ||
216*a0ccc12fSBjoern A. Zeeb 		    (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) {
217*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
218*a0ccc12fSBjoern A. Zeeb 					 0x000003ff, 0x100);
219*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
220*a0ccc12fSBjoern A. Zeeb 					 0x03ff0000, 0);
221*a0ccc12fSBjoern A. Zeeb 		} else {
222*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
223*a0ccc12fSBjoern A. Zeeb 					 0x000003ff, rx_x >> 1);
224*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B,
225*a0ccc12fSBjoern A. Zeeb 					 0x03ff0000, rx_y >> 1);
226*a0ccc12fSBjoern A. Zeeb 		}
227*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
228*a0ccc12fSBjoern A. Zeeb 			"rx_x = %x;;rx_y = %x ====>fill to IQC\n",
229*a0ccc12fSBjoern A. Zeeb 			rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff);
230*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n",
231*a0ccc12fSBjoern A. Zeeb 			rtw_read32(rtwdev, REG_RX_IQC_AB_B));
232*a0ccc12fSBjoern A. Zeeb 		break;
233*a0ccc12fSBjoern A. Zeeb 	default:
234*a0ccc12fSBjoern A. Zeeb 		break;
235*a0ccc12fSBjoern A. Zeeb 	}
236*a0ccc12fSBjoern A. Zeeb }
237*a0ccc12fSBjoern A. Zeeb 
238*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path,
239*a0ccc12fSBjoern A. Zeeb 				 unsigned int tx_x, unsigned int tx_y)
240*a0ccc12fSBjoern A. Zeeb {
241*a0ccc12fSBjoern A. Zeeb 	switch (path) {
242*a0ccc12fSBjoern A. Zeeb 	case RF_PATH_A:
243*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
244*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
245*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1);
246*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1);
247*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1);
248*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1);
249*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y);
250*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x);
251*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
252*a0ccc12fSBjoern A. Zeeb 			"tx_x = %x;;tx_y = %x =====> fill to IQC\n",
253*a0ccc12fSBjoern A. Zeeb 			tx_x & 0x000007ff, tx_y & 0x000007ff);
254*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
255*a0ccc12fSBjoern A. Zeeb 			"0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
256*a0ccc12fSBjoern A. Zeeb 			rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff),
257*a0ccc12fSBjoern A. Zeeb 			rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff));
258*a0ccc12fSBjoern A. Zeeb 		break;
259*a0ccc12fSBjoern A. Zeeb 	case RF_PATH_B:
260*a0ccc12fSBjoern A. Zeeb 		/* [31] = 1 --> Page C1 */
261*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
262*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1);
263*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1);
264*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1);
265*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1);
266*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y);
267*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x);
268*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
269*a0ccc12fSBjoern A. Zeeb 			"tx_x = %x;;tx_y = %x =====> fill to IQC\n",
270*a0ccc12fSBjoern A. Zeeb 			tx_x & 0x000007ff, tx_y & 0x000007ff);
271*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
272*a0ccc12fSBjoern A. Zeeb 			"0xed4 = %x;;0xecc = %x ====>fill to IQC\n",
273*a0ccc12fSBjoern A. Zeeb 			rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff),
274*a0ccc12fSBjoern A. Zeeb 			rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff));
275*a0ccc12fSBjoern A. Zeeb 		break;
276*a0ccc12fSBjoern A. Zeeb 	default:
277*a0ccc12fSBjoern A. Zeeb 		break;
278*a0ccc12fSBjoern A. Zeeb 	}
279*a0ccc12fSBjoern A. Zeeb }
280*a0ccc12fSBjoern A. Zeeb 
281*a0ccc12fSBjoern A. Zeeb static void rtw8812a_iqk(struct rtw_dev *rtwdev)
282*a0ccc12fSBjoern A. Zeeb {
283*a0ccc12fSBjoern A. Zeeb 	int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10];
284*a0ccc12fSBjoern A. Zeeb 	int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10];
285*a0ccc12fSBjoern A. Zeeb 	bool iqk0_ready = false, tx0_finish = false, rx0_finish = false;
286*a0ccc12fSBjoern A. Zeeb 	bool iqk1_ready = false, tx1_finish = false, rx1_finish = false;
287*a0ccc12fSBjoern A. Zeeb 	u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0;
288*a0ccc12fSBjoern A. Zeeb 	int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0;
289*a0ccc12fSBjoern A. Zeeb 	int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0;
290*a0ccc12fSBjoern A. Zeeb 	struct rtw_efuse *efuse = &rtwdev->efuse;
291*a0ccc12fSBjoern A. Zeeb 	bool tx0_fail = true, rx0_fail = true;
292*a0ccc12fSBjoern A. Zeeb 	bool tx1_fail = true, rx1_fail = true;
293*a0ccc12fSBjoern A. Zeeb 	u8 cal0_retry, cal1_retry;
294*a0ccc12fSBjoern A. Zeeb 	u8 delay_count;
295*a0ccc12fSBjoern A. Zeeb 
296*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
297*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
298*a0ccc12fSBjoern A. Zeeb 
299*a0ccc12fSBjoern A. Zeeb 	/* ========path-A AFE all on======== */
300*a0ccc12fSBjoern A. Zeeb 	/* Port 0 DAC/ADC on */
301*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777);
302*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777);
303*a0ccc12fSBjoern A. Zeeb 
304*a0ccc12fSBjoern A. Zeeb 	/* Port 1 DAC/ADC on */
305*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777);
306*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777);
307*a0ccc12fSBjoern A. Zeeb 
308*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979);
309*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979);
310*a0ccc12fSBjoern A. Zeeb 
311*a0ccc12fSBjoern A. Zeeb 	/* hardware 3-wire off */
312*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4);
313*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4);
314*a0ccc12fSBjoern A. Zeeb 
315*a0ccc12fSBjoern A. Zeeb 	/* DAC/ADC sampling rate (160 MHz) */
316*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7);
317*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7);
318*a0ccc12fSBjoern A. Zeeb 
319*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
320*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
321*a0ccc12fSBjoern A. Zeeb 	/* ====== path A TX IQK RF setting ====== */
322*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002);
323*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
324*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
325*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
326*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
327*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001);
328*a0ccc12fSBjoern A. Zeeb 
329*a0ccc12fSBjoern A. Zeeb 	/* ====== path B TX IQK RF setting ====== */
330*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002);
331*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000);
332*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd);
333*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f);
334*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5);
335*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001);
336*a0ccc12fSBjoern A. Zeeb 
337*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
338*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1);
339*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1);
340*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */
341*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */
342*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */
343*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
344*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
345*a0ccc12fSBjoern A. Zeeb 
346*a0ccc12fSBjoern A. Zeeb 	if (efuse->ext_pa_5g) {
347*a0ccc12fSBjoern A. Zeeb 		if (efuse->rfe_option == 1) {
348*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3);
349*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3);
350*a0ccc12fSBjoern A. Zeeb 		} else {
351*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7);
352*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7);
353*a0ccc12fSBjoern A. Zeeb 		}
354*a0ccc12fSBjoern A. Zeeb 	} else {
355*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1);
356*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1);
357*a0ccc12fSBjoern A. Zeeb 	}
358*a0ccc12fSBjoern A. Zeeb 
359*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->hal.current_band_type == RTW_BAND_5G) {
360*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96);
361*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96);
362*a0ccc12fSBjoern A. Zeeb 	} else {
363*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96);
364*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96);
365*a0ccc12fSBjoern A. Zeeb 
366*a0ccc12fSBjoern A. Zeeb 		if (efuse->rfe_option == 3) {
367*a0ccc12fSBjoern A. Zeeb 			if (efuse->ext_pa_2g)
368*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
369*a0ccc12fSBjoern A. Zeeb 					    0x821403e3);
370*a0ccc12fSBjoern A. Zeeb 			else
371*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE,
372*a0ccc12fSBjoern A. Zeeb 					    0x821403f7);
373*a0ccc12fSBjoern A. Zeeb 		}
374*a0ccc12fSBjoern A. Zeeb 	}
375*a0ccc12fSBjoern A. Zeeb 
376*a0ccc12fSBjoern A. Zeeb 	/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
377*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10);
378*a0ccc12fSBjoern A. Zeeb 	/* RX_Tone_idx[9:0], RxK_Mask[29] */
379*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10);
380*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000);
381*a0ccc12fSBjoern A. Zeeb 	/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
382*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10);
383*a0ccc12fSBjoern A. Zeeb 	/* RX_Tone_idx[9:0], RxK_Mask[29] */
384*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10);
385*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000);
386*a0ccc12fSBjoern A. Zeeb 
387*a0ccc12fSBjoern A. Zeeb 	cal0_retry = 0;
388*a0ccc12fSBjoern A. Zeeb 	cal1_retry = 0;
389*a0ccc12fSBjoern A. Zeeb 	while (1) {
390*a0ccc12fSBjoern A. Zeeb 		/* one shot */
391*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
392*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
393*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000);
394*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000);
395*a0ccc12fSBjoern A. Zeeb 
396*a0ccc12fSBjoern A. Zeeb 		mdelay(10);
397*a0ccc12fSBjoern A. Zeeb 
398*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
399*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
400*a0ccc12fSBjoern A. Zeeb 
401*a0ccc12fSBjoern A. Zeeb 		for (delay_count = 0; delay_count < 20; delay_count++) {
402*a0ccc12fSBjoern A. Zeeb 			if (!tx0_finish)
403*a0ccc12fSBjoern A. Zeeb 				iqk0_ready = rtw_read32_mask(rtwdev,
404*a0ccc12fSBjoern A. Zeeb 							     REG_IQKA_END,
405*a0ccc12fSBjoern A. Zeeb 							     BIT(10));
406*a0ccc12fSBjoern A. Zeeb 			if (!tx1_finish)
407*a0ccc12fSBjoern A. Zeeb 				iqk1_ready = rtw_read32_mask(rtwdev,
408*a0ccc12fSBjoern A. Zeeb 							     REG_IQKB_END,
409*a0ccc12fSBjoern A. Zeeb 							     BIT(10));
410*a0ccc12fSBjoern A. Zeeb 			if (iqk0_ready && iqk1_ready)
411*a0ccc12fSBjoern A. Zeeb 				break;
412*a0ccc12fSBjoern A. Zeeb 
413*a0ccc12fSBjoern A. Zeeb 			mdelay(1);
414*a0ccc12fSBjoern A. Zeeb 		}
415*a0ccc12fSBjoern A. Zeeb 
416*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n",
417*a0ccc12fSBjoern A. Zeeb 			delay_count);
418*a0ccc12fSBjoern A. Zeeb 
419*a0ccc12fSBjoern A. Zeeb 		if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
420*a0ccc12fSBjoern A. Zeeb 			/* ============TXIQK Check============== */
421*a0ccc12fSBjoern A. Zeeb 			tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12));
422*a0ccc12fSBjoern A. Zeeb 			tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12));
423*a0ccc12fSBjoern A. Zeeb 
424*a0ccc12fSBjoern A. Zeeb 			if (!(tx0_fail || tx0_finish)) {
425*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000);
426*a0ccc12fSBjoern A. Zeeb 				tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
427*a0ccc12fSBjoern A. Zeeb 								      REG_IQKA_END,
428*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
429*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000);
430*a0ccc12fSBjoern A. Zeeb 				tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev,
431*a0ccc12fSBjoern A. Zeeb 								      REG_IQKA_END,
432*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
433*a0ccc12fSBjoern A. Zeeb 
434*a0ccc12fSBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
435*a0ccc12fSBjoern A. Zeeb 					"tx_x0[%d] = %x ;; tx_y0[%d] = %x\n",
436*a0ccc12fSBjoern A. Zeeb 					tx0_avg, tx_x0_temp[tx0_avg],
437*a0ccc12fSBjoern A. Zeeb 					tx0_avg, tx_y0_temp[tx0_avg]);
438*a0ccc12fSBjoern A. Zeeb 
439*a0ccc12fSBjoern A. Zeeb 				tx_x0_temp[tx0_avg] <<= 21;
440*a0ccc12fSBjoern A. Zeeb 				tx_y0_temp[tx0_avg] <<= 21;
441*a0ccc12fSBjoern A. Zeeb 
442*a0ccc12fSBjoern A. Zeeb 				tx0_avg++;
443*a0ccc12fSBjoern A. Zeeb 			} else {
444*a0ccc12fSBjoern A. Zeeb 				cal0_retry++;
445*a0ccc12fSBjoern A. Zeeb 				if (cal0_retry == 10)
446*a0ccc12fSBjoern A. Zeeb 					break;
447*a0ccc12fSBjoern A. Zeeb 			}
448*a0ccc12fSBjoern A. Zeeb 
449*a0ccc12fSBjoern A. Zeeb 			if (!(tx1_fail || tx1_finish)) {
450*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000);
451*a0ccc12fSBjoern A. Zeeb 				tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev,
452*a0ccc12fSBjoern A. Zeeb 								      REG_IQKB_END,
453*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
454*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000);
455*a0ccc12fSBjoern A. Zeeb 				tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev,
456*a0ccc12fSBjoern A. Zeeb 								      REG_IQKB_END,
457*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
458*a0ccc12fSBjoern A. Zeeb 
459*a0ccc12fSBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
460*a0ccc12fSBjoern A. Zeeb 					"tx_x1[%d] = %x ;; tx_y1[%d] = %x\n",
461*a0ccc12fSBjoern A. Zeeb 					tx1_avg, tx_x1_temp[tx1_avg],
462*a0ccc12fSBjoern A. Zeeb 					tx1_avg, tx_y1_temp[tx1_avg]);
463*a0ccc12fSBjoern A. Zeeb 
464*a0ccc12fSBjoern A. Zeeb 				tx_x1_temp[tx1_avg] <<= 21;
465*a0ccc12fSBjoern A. Zeeb 				tx_y1_temp[tx1_avg] <<= 21;
466*a0ccc12fSBjoern A. Zeeb 
467*a0ccc12fSBjoern A. Zeeb 				tx1_avg++;
468*a0ccc12fSBjoern A. Zeeb 			} else {
469*a0ccc12fSBjoern A. Zeeb 				cal1_retry++;
470*a0ccc12fSBjoern A. Zeeb 				if (cal1_retry == 10)
471*a0ccc12fSBjoern A. Zeeb 					break;
472*a0ccc12fSBjoern A. Zeeb 			}
473*a0ccc12fSBjoern A. Zeeb 		} else {
474*a0ccc12fSBjoern A. Zeeb 			cal0_retry++;
475*a0ccc12fSBjoern A. Zeeb 			cal1_retry++;
476*a0ccc12fSBjoern A. Zeeb 
477*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
478*a0ccc12fSBjoern A. Zeeb 				"delay 20ms TX IQK Not Ready!!!!!\n");
479*a0ccc12fSBjoern A. Zeeb 
480*a0ccc12fSBjoern A. Zeeb 			if (cal0_retry == 10)
481*a0ccc12fSBjoern A. Zeeb 				break;
482*a0ccc12fSBjoern A. Zeeb 		}
483*a0ccc12fSBjoern A. Zeeb 
484*a0ccc12fSBjoern A. Zeeb 		if (tx0_avg >= 2)
485*a0ccc12fSBjoern A. Zeeb 			tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4,
486*a0ccc12fSBjoern A. Zeeb 							 tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0,
487*a0ccc12fSBjoern A. Zeeb 							 false, false);
488*a0ccc12fSBjoern A. Zeeb 
489*a0ccc12fSBjoern A. Zeeb 		if (tx1_avg >= 2)
490*a0ccc12fSBjoern A. Zeeb 			tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4,
491*a0ccc12fSBjoern A. Zeeb 							 tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1,
492*a0ccc12fSBjoern A. Zeeb 							 false, false);
493*a0ccc12fSBjoern A. Zeeb 
494*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
495*a0ccc12fSBjoern A. Zeeb 			"tx0_average = %d, tx1_average = %d\n",
496*a0ccc12fSBjoern A. Zeeb 			tx0_avg, tx1_avg);
497*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
498*a0ccc12fSBjoern A. Zeeb 			"tx0_finish = %d, tx1_finish = %d\n",
499*a0ccc12fSBjoern A. Zeeb 			tx0_finish, tx1_finish);
500*a0ccc12fSBjoern A. Zeeb 
501*a0ccc12fSBjoern A. Zeeb 		if (tx0_finish && tx1_finish)
502*a0ccc12fSBjoern A. Zeeb 			break;
503*a0ccc12fSBjoern A. Zeeb 
504*a0ccc12fSBjoern A. Zeeb 		if ((cal0_retry + tx0_avg) >= 10 ||
505*a0ccc12fSBjoern A. Zeeb 		    (cal1_retry + tx1_avg) >= 10)
506*a0ccc12fSBjoern A. Zeeb 			break;
507*a0ccc12fSBjoern A. Zeeb 	}
508*a0ccc12fSBjoern A. Zeeb 
509*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry);
510*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry);
511*a0ccc12fSBjoern A. Zeeb 
512*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
513*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
514*a0ccc12fSBjoern A. Zeeb 	/* Load LOK */
515*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00,
516*a0ccc12fSBjoern A. Zeeb 		     rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00));
517*a0ccc12fSBjoern A. Zeeb 	rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00,
518*a0ccc12fSBjoern A. Zeeb 		     rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00));
519*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
520*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
521*a0ccc12fSBjoern A. Zeeb 
522*a0ccc12fSBjoern A. Zeeb 	/* [31] = 0 --> Page C */
523*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
524*a0ccc12fSBjoern A. Zeeb 	if (tx0_finish) {
525*a0ccc12fSBjoern A. Zeeb 		/* ====== path A RX IQK RF setting====== */
526*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000);
527*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK,
528*a0ccc12fSBjoern A. Zeeb 			     0x30000);
529*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK,
530*a0ccc12fSBjoern A. Zeeb 			     0x3f7ff);
531*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK,
532*a0ccc12fSBjoern A. Zeeb 			     0xfe7bf);
533*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001);
534*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);
535*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000);
536*a0ccc12fSBjoern A. Zeeb 	}
537*a0ccc12fSBjoern A. Zeeb 	if (tx1_finish) {
538*a0ccc12fSBjoern A. Zeeb 		/* ====== path B RX IQK RF setting====== */
539*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000);
540*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK,
541*a0ccc12fSBjoern A. Zeeb 			     0x30000);
542*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK,
543*a0ccc12fSBjoern A. Zeeb 			     0x3f7ff);
544*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK,
545*a0ccc12fSBjoern A. Zeeb 			     0xfe7bf);
546*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001);
547*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1);
548*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000);
549*a0ccc12fSBjoern A. Zeeb 	}
550*a0ccc12fSBjoern A. Zeeb 
551*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1);
552*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0);
553*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000);
554*a0ccc12fSBjoern A. Zeeb 
555*a0ccc12fSBjoern A. Zeeb 	if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
556*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911);
557*a0ccc12fSBjoern A. Zeeb 	else
558*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890);
559*a0ccc12fSBjoern A. Zeeb 
560*a0ccc12fSBjoern A. Zeeb 	if (efuse->rfe_option == 1) {
561*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);
562*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077);
563*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);
564*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077);
565*a0ccc12fSBjoern A. Zeeb 	} else {
566*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717);
567*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077);
568*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717);
569*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077);
570*a0ccc12fSBjoern A. Zeeb 	}
571*a0ccc12fSBjoern A. Zeeb 
572*a0ccc12fSBjoern A. Zeeb 	/* [31] = 1 --> Page C1 */
573*a0ccc12fSBjoern A. Zeeb 	rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
574*a0ccc12fSBjoern A. Zeeb 
575*a0ccc12fSBjoern A. Zeeb 	if (tx0_finish) {
576*a0ccc12fSBjoern A. Zeeb 		/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
577*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10);
578*a0ccc12fSBjoern A. Zeeb 		/* RX_Tone_idx[9:0], RxK_Mask[29] */
579*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10);
580*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119);
581*a0ccc12fSBjoern A. Zeeb 	}
582*a0ccc12fSBjoern A. Zeeb 	if (tx1_finish) {
583*a0ccc12fSBjoern A. Zeeb 		/* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
584*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10);
585*a0ccc12fSBjoern A. Zeeb 		/* RX_Tone_idx[9:0], RxK_Mask[29] */
586*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10);
587*a0ccc12fSBjoern A. Zeeb 		rtw_write32(rtwdev, REG_TXPITMB, 0x82140119);
588*a0ccc12fSBjoern A. Zeeb 	}
589*a0ccc12fSBjoern A. Zeeb 
590*a0ccc12fSBjoern A. Zeeb 	cal0_retry = 0;
591*a0ccc12fSBjoern A. Zeeb 	cal1_retry = 0;
592*a0ccc12fSBjoern A. Zeeb 	while (1) {
593*a0ccc12fSBjoern A. Zeeb 		/* one shot */
594*a0ccc12fSBjoern A. Zeeb 		/* [31] = 0 --> Page C */
595*a0ccc12fSBjoern A. Zeeb 		rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
596*a0ccc12fSBjoern A. Zeeb 
597*a0ccc12fSBjoern A. Zeeb 		if (tx0_finish) {
598*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
599*a0ccc12fSBjoern A. Zeeb 					 tx_x0 & 0x000007ff);
600*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
601*a0ccc12fSBjoern A. Zeeb 					 tx_y0 & 0x000007ff);
602*a0ccc12fSBjoern A. Zeeb 			/* [31] = 1 --> Page C1 */
603*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
604*a0ccc12fSBjoern A. Zeeb 			if (efuse->rfe_option == 1)
605*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500);
606*a0ccc12fSBjoern A. Zeeb 			else
607*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0);
608*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000);
609*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000);
610*a0ccc12fSBjoern A. Zeeb 			mdelay(5);
611*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000);
612*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000);
613*a0ccc12fSBjoern A. Zeeb 		}
614*a0ccc12fSBjoern A. Zeeb 
615*a0ccc12fSBjoern A. Zeeb 		if (tx1_finish) {
616*a0ccc12fSBjoern A. Zeeb 			/* [31] = 0 --> Page C */
617*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0);
618*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000,
619*a0ccc12fSBjoern A. Zeeb 					 tx_x1 & 0x000007ff);
620*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF,
621*a0ccc12fSBjoern A. Zeeb 					 tx_y1 & 0x000007ff);
622*a0ccc12fSBjoern A. Zeeb 			/* [31] = 1 --> Page C1 */
623*a0ccc12fSBjoern A. Zeeb 			rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1);
624*a0ccc12fSBjoern A. Zeeb 			if (efuse->rfe_option == 1)
625*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RXPITMB, 0x28161500);
626*a0ccc12fSBjoern A. Zeeb 			else
627*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0);
628*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000);
629*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000);
630*a0ccc12fSBjoern A. Zeeb 			mdelay(5);
631*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000);
632*a0ccc12fSBjoern A. Zeeb 			rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000);
633*a0ccc12fSBjoern A. Zeeb 		}
634*a0ccc12fSBjoern A. Zeeb 
635*a0ccc12fSBjoern A. Zeeb 		for (delay_count = 0; delay_count < 20; delay_count++) {
636*a0ccc12fSBjoern A. Zeeb 			if (!rx0_finish && tx0_finish)
637*a0ccc12fSBjoern A. Zeeb 				iqk0_ready = rtw_read32_mask(rtwdev,
638*a0ccc12fSBjoern A. Zeeb 							     REG_IQKA_END,
639*a0ccc12fSBjoern A. Zeeb 							     BIT(10));
640*a0ccc12fSBjoern A. Zeeb 			if (!rx1_finish && tx1_finish)
641*a0ccc12fSBjoern A. Zeeb 				iqk1_ready = rtw_read32_mask(rtwdev,
642*a0ccc12fSBjoern A. Zeeb 							     REG_IQKB_END,
643*a0ccc12fSBjoern A. Zeeb 							     BIT(10));
644*a0ccc12fSBjoern A. Zeeb 			if (iqk0_ready && iqk1_ready)
645*a0ccc12fSBjoern A. Zeeb 				break;
646*a0ccc12fSBjoern A. Zeeb 
647*a0ccc12fSBjoern A. Zeeb 			mdelay(1);
648*a0ccc12fSBjoern A. Zeeb 		}
649*a0ccc12fSBjoern A. Zeeb 
650*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n",
651*a0ccc12fSBjoern A. Zeeb 			delay_count);
652*a0ccc12fSBjoern A. Zeeb 
653*a0ccc12fSBjoern A. Zeeb 		if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
654*a0ccc12fSBjoern A. Zeeb 			/* ============RXIQK Check============== */
655*a0ccc12fSBjoern A. Zeeb 			rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11));
656*a0ccc12fSBjoern A. Zeeb 			rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11));
657*a0ccc12fSBjoern A. Zeeb 
658*a0ccc12fSBjoern A. Zeeb 			if (!(rx0_fail || rx0_finish) && tx0_finish) {
659*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000);
660*a0ccc12fSBjoern A. Zeeb 				rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev,
661*a0ccc12fSBjoern A. Zeeb 								      REG_IQKA_END,
662*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
663*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000);
664*a0ccc12fSBjoern A. Zeeb 				rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev,
665*a0ccc12fSBjoern A. Zeeb 								      REG_IQKA_END,
666*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
667*a0ccc12fSBjoern A. Zeeb 
668*a0ccc12fSBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
669*a0ccc12fSBjoern A. Zeeb 					"rx_x0[%d] = %x ;; rx_y0[%d] = %x\n",
670*a0ccc12fSBjoern A. Zeeb 					rx0_avg, rx_x0_temp[rx0_avg],
671*a0ccc12fSBjoern A. Zeeb 					rx0_avg, rx_y0_temp[rx0_avg]);
672*a0ccc12fSBjoern A. Zeeb 
673*a0ccc12fSBjoern A. Zeeb 				rx_x0_temp[rx0_avg] <<= 21;
674*a0ccc12fSBjoern A. Zeeb 				rx_y0_temp[rx0_avg] <<= 21;
675*a0ccc12fSBjoern A. Zeeb 
676*a0ccc12fSBjoern A. Zeeb 				rx0_avg++;
677*a0ccc12fSBjoern A. Zeeb 			} else {
678*a0ccc12fSBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
679*a0ccc12fSBjoern A. Zeeb 					"1. RXA_cal_retry = %d\n", cal0_retry);
680*a0ccc12fSBjoern A. Zeeb 
681*a0ccc12fSBjoern A. Zeeb 				cal0_retry++;
682*a0ccc12fSBjoern A. Zeeb 				if (cal0_retry == 10)
683*a0ccc12fSBjoern A. Zeeb 					break;
684*a0ccc12fSBjoern A. Zeeb 			}
685*a0ccc12fSBjoern A. Zeeb 
686*a0ccc12fSBjoern A. Zeeb 			if (!(rx1_fail || rx1_finish) && tx1_finish) {
687*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000);
688*a0ccc12fSBjoern A. Zeeb 				rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev,
689*a0ccc12fSBjoern A. Zeeb 								      REG_IQKB_END,
690*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
691*a0ccc12fSBjoern A. Zeeb 				rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000);
692*a0ccc12fSBjoern A. Zeeb 				rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev,
693*a0ccc12fSBjoern A. Zeeb 								      REG_IQKB_END,
694*a0ccc12fSBjoern A. Zeeb 								      0x07ff0000);
695*a0ccc12fSBjoern A. Zeeb 
696*a0ccc12fSBjoern A. Zeeb 				rtw_dbg(rtwdev, RTW_DBG_RFK,
697*a0ccc12fSBjoern A. Zeeb 					"rx_x1[%d] = %x ;; rx_y1[%d] = %x\n",
698*a0ccc12fSBjoern A. Zeeb 					rx1_avg, rx_x1_temp[rx1_avg],
699*a0ccc12fSBjoern A. Zeeb 					rx1_avg, rx_y1_temp[rx1_avg]);
700*a0ccc12fSBjoern A. Zeeb 
701*a0ccc12fSBjoern A. Zeeb 				rx_x1_temp[rx1_avg] <<= 21;
702*a0ccc12fSBjoern A. Zeeb 				rx_y1_temp[rx1_avg] <<= 21;
703*a0ccc12fSBjoern A. Zeeb 
704*a0ccc12fSBjoern A. Zeeb 				rx1_avg++;
705*a0ccc12fSBjoern A. Zeeb 			} else {
706*a0ccc12fSBjoern A. Zeeb 				cal1_retry++;
707*a0ccc12fSBjoern A. Zeeb 				if (cal1_retry == 10)
708*a0ccc12fSBjoern A. Zeeb 					break;
709*a0ccc12fSBjoern A. Zeeb 			}
710*a0ccc12fSBjoern A. Zeeb 		} else {
711*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
712*a0ccc12fSBjoern A. Zeeb 				"2. RXA_cal_retry = %d\n", cal0_retry);
713*a0ccc12fSBjoern A. Zeeb 
714*a0ccc12fSBjoern A. Zeeb 			cal0_retry++;
715*a0ccc12fSBjoern A. Zeeb 			cal1_retry++;
716*a0ccc12fSBjoern A. Zeeb 
717*a0ccc12fSBjoern A. Zeeb 			rtw_dbg(rtwdev, RTW_DBG_RFK,
718*a0ccc12fSBjoern A. Zeeb 				"delay 20ms RX IQK Not Ready!!!!!\n");
719*a0ccc12fSBjoern A. Zeeb 
720*a0ccc12fSBjoern A. Zeeb 			if (cal0_retry == 10)
721*a0ccc12fSBjoern A. Zeeb 				break;
722*a0ccc12fSBjoern A. Zeeb 		}
723*a0ccc12fSBjoern A. Zeeb 
724*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n",
725*a0ccc12fSBjoern A. Zeeb 			cal0_retry);
726*a0ccc12fSBjoern A. Zeeb 
727*a0ccc12fSBjoern A. Zeeb 		if (rx0_avg >= 2)
728*a0ccc12fSBjoern A. Zeeb 			rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4,
729*a0ccc12fSBjoern A. Zeeb 							 rx_x0_temp, rx_y0_temp,
730*a0ccc12fSBjoern A. Zeeb 							 &rx_x0, &rx_y0,
731*a0ccc12fSBjoern A. Zeeb 							 true, false);
732*a0ccc12fSBjoern A. Zeeb 
733*a0ccc12fSBjoern A. Zeeb 		if (rx1_avg >= 2)
734*a0ccc12fSBjoern A. Zeeb 			rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4,
735*a0ccc12fSBjoern A. Zeeb 							 rx_x1_temp, rx_y1_temp,
736*a0ccc12fSBjoern A. Zeeb 							 &rx_x1, &rx_y1,
737*a0ccc12fSBjoern A. Zeeb 							 true, false);
738*a0ccc12fSBjoern A. Zeeb 
739*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
740*a0ccc12fSBjoern A. Zeeb 			"rx0_average = %d, rx1_average = %d\n",
741*a0ccc12fSBjoern A. Zeeb 			rx0_avg, rx1_avg);
742*a0ccc12fSBjoern A. Zeeb 		rtw_dbg(rtwdev, RTW_DBG_RFK,
743*a0ccc12fSBjoern A. Zeeb 			"rx0_finish = %d, rx1_finish = %d\n",
744*a0ccc12fSBjoern A. Zeeb 			rx0_finish, rx1_finish);
745*a0ccc12fSBjoern A. Zeeb 
746*a0ccc12fSBjoern A. Zeeb 		if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish))
747*a0ccc12fSBjoern A. Zeeb 			break;
748*a0ccc12fSBjoern A. Zeeb 
749*a0ccc12fSBjoern A. Zeeb 		if ((cal0_retry + rx0_avg) >= 10 ||
750*a0ccc12fSBjoern A. Zeeb 		    (cal1_retry + rx1_avg) >= 10 ||
751*a0ccc12fSBjoern A. Zeeb 		    rx0_avg == 3 || rx1_avg == 3)
752*a0ccc12fSBjoern A. Zeeb 			break;
753*a0ccc12fSBjoern A. Zeeb 	}
754*a0ccc12fSBjoern A. Zeeb 
755*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry);
756*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry);
757*a0ccc12fSBjoern A. Zeeb 
758*a0ccc12fSBjoern A. Zeeb 	/* FillIQK Result */
759*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n");
760*a0ccc12fSBjoern A. Zeeb 
761*a0ccc12fSBjoern A. Zeeb 	if (tx0_finish)
762*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0);
763*a0ccc12fSBjoern A. Zeeb 	else
764*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);
765*a0ccc12fSBjoern A. Zeeb 
766*a0ccc12fSBjoern A. Zeeb 	if (rx0_finish)
767*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0);
768*a0ccc12fSBjoern A. Zeeb 	else
769*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0);
770*a0ccc12fSBjoern A. Zeeb 
771*a0ccc12fSBjoern A. Zeeb 	rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n");
772*a0ccc12fSBjoern A. Zeeb 
773*a0ccc12fSBjoern A. Zeeb 	if (tx1_finish)
774*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1);
775*a0ccc12fSBjoern A. Zeeb 	else
776*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);
777*a0ccc12fSBjoern A. Zeeb 
778*a0ccc12fSBjoern A. Zeeb 	if (rx1_finish)
779*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1);
780*a0ccc12fSBjoern A. Zeeb 	else
781*a0ccc12fSBjoern A. Zeeb 		rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0);
782*a0ccc12fSBjoern A. Zeeb }
783*a0ccc12fSBjoern A. Zeeb 
784*a0ccc12fSBjoern A. Zeeb #define MACBB_REG_NUM_8812A 9
785*a0ccc12fSBjoern A. Zeeb #define AFE_REG_NUM_8812A 12
786*a0ccc12fSBjoern A. Zeeb #define RF_REG_NUM_8812A 3
787*a0ccc12fSBjoern A. Zeeb 
788*a0ccc12fSBjoern A. Zeeb static void rtw8812a_do_iqk(struct rtw_dev *rtwdev)
789*a0ccc12fSBjoern A. Zeeb {
790*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = {
791*a0ccc12fSBjoern A. Zeeb 		0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c
792*a0ccc12fSBjoern A. Zeeb 	};
793*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = {
794*a0ccc12fSBjoern A. Zeeb 		0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4,
795*a0ccc12fSBjoern A. Zeeb 		0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4
796*a0ccc12fSBjoern A. Zeeb 	};
797*a0ccc12fSBjoern A. Zeeb 	static const u32 backup_rf_reg[RF_REG_NUM_8812A] = {
798*a0ccc12fSBjoern A. Zeeb 		0x65, 0x8f, 0x0
799*a0ccc12fSBjoern A. Zeeb 	};
800*a0ccc12fSBjoern A. Zeeb 	u32 macbb_backup[MACBB_REG_NUM_8812A] = {};
801*a0ccc12fSBjoern A. Zeeb 	u32 afe_backup[AFE_REG_NUM_8812A] = {};
802*a0ccc12fSBjoern A. Zeeb 	u32 rfa_backup[RF_REG_NUM_8812A] = {};
803*a0ccc12fSBjoern A. Zeeb 	u32 rfb_backup[RF_REG_NUM_8812A] = {};
804*a0ccc12fSBjoern A. Zeeb 	u32 reg_cb8, reg_eb8;
805*a0ccc12fSBjoern A. Zeeb 
806*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup,
807*a0ccc12fSBjoern A. Zeeb 				   backup_macbb_reg, MACBB_REG_NUM_8812A);
808*a0ccc12fSBjoern A. Zeeb 
809*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));
810*a0ccc12fSBjoern A. Zeeb 	reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A);
811*a0ccc12fSBjoern A. Zeeb 	reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B);
812*a0ccc12fSBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));
813*a0ccc12fSBjoern A. Zeeb 
814*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_backup_afe(rtwdev, afe_backup,
815*a0ccc12fSBjoern A. Zeeb 				backup_afe_reg, AFE_REG_NUM_8812A);
816*a0ccc12fSBjoern A. Zeeb 	rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup,
817*a0ccc12fSBjoern A. Zeeb 			       backup_rf_reg, RF_REG_NUM_8812A);
818*a0ccc12fSBjoern A. Zeeb 
819*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_configure_mac(rtwdev);
820*a0ccc12fSBjoern A. Zeeb 
821*a0ccc12fSBjoern A. Zeeb 	rtw8812a_iqk(rtwdev);
822*a0ccc12fSBjoern A. Zeeb 
823*a0ccc12fSBjoern A. Zeeb 	rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg,
824*a0ccc12fSBjoern A. Zeeb 				rfa_backup, RF_REG_NUM_8812A);
825*a0ccc12fSBjoern A. Zeeb 	rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg,
826*a0ccc12fSBjoern A. Zeeb 				rfb_backup, RF_REG_NUM_8812A);
827*a0ccc12fSBjoern A. Zeeb 
828*a0ccc12fSBjoern A. Zeeb 	rtw8812a_iqk_restore_afe(rtwdev, afe_backup,
829*a0ccc12fSBjoern A. Zeeb 				 backup_afe_reg, AFE_REG_NUM_8812A);
830*a0ccc12fSBjoern A. Zeeb 
831*a0ccc12fSBjoern A. Zeeb 	rtw_write32_set(rtwdev, REG_CCASEL, BIT(31));
832*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8);
833*a0ccc12fSBjoern A. Zeeb 	rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8);
834*a0ccc12fSBjoern A. Zeeb 	rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31));
835*a0ccc12fSBjoern A. Zeeb 
836*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup,
837*a0ccc12fSBjoern A. Zeeb 				    backup_macbb_reg, MACBB_REG_NUM_8812A);
838*a0ccc12fSBjoern A. Zeeb }
839*a0ccc12fSBjoern A. Zeeb 
840*a0ccc12fSBjoern A. Zeeb static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev)
841*a0ccc12fSBjoern A. Zeeb {
842*a0ccc12fSBjoern A. Zeeb 	u8 channel = rtwdev->hal.current_channel;
843*a0ccc12fSBjoern A. Zeeb 
844*a0ccc12fSBjoern A. Zeeb 	rtw8812a_do_iqk(rtwdev);
845*a0ccc12fSBjoern A. Zeeb 
846*a0ccc12fSBjoern A. Zeeb 	/* The official driver wants to do this after connecting
847*a0ccc12fSBjoern A. Zeeb 	 * but before first writing a new igi (phydm_get_new_igi).
848*a0ccc12fSBjoern A. Zeeb 	 * Here seems close enough.
849*a0ccc12fSBjoern A. Zeeb 	 */
850*a0ccc12fSBjoern A. Zeeb 	if (channel >= 36 && channel <= 64)
851*a0ccc12fSBjoern A. Zeeb 		rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl);
852*a0ccc12fSBjoern A. Zeeb 	else if (channel >= 100)
853*a0ccc12fSBjoern A. Zeeb 		rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl);
854*a0ccc12fSBjoern A. Zeeb }
855*a0ccc12fSBjoern A. Zeeb 
856*a0ccc12fSBjoern A. Zeeb static void rtw8812a_pwr_track(struct rtw_dev *rtwdev)
857*a0ccc12fSBjoern A. Zeeb {
858*a0ccc12fSBjoern A. Zeeb 	struct rtw_dm_info *dm_info = &rtwdev->dm_info;
859*a0ccc12fSBjoern A. Zeeb 
860*a0ccc12fSBjoern A. Zeeb 	if (!dm_info->pwr_trk_triggered) {
861*a0ccc12fSBjoern A. Zeeb 		rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER,
862*a0ccc12fSBjoern A. Zeeb 			     GENMASK(17, 16), 0x03);
863*a0ccc12fSBjoern A. Zeeb 		dm_info->pwr_trk_triggered = true;
864*a0ccc12fSBjoern A. Zeeb 		return;
865*a0ccc12fSBjoern A. Zeeb 	}
866*a0ccc12fSBjoern A. Zeeb 
867*a0ccc12fSBjoern A. Zeeb 	rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk);
868*a0ccc12fSBjoern A. Zeeb 	dm_info->pwr_trk_triggered = false;
869*a0ccc12fSBjoern A. Zeeb }
870*a0ccc12fSBjoern A. Zeeb 
871*a0ccc12fSBjoern A. Zeeb static void rtw8812a_led_set(struct led_classdev *led,
872*a0ccc12fSBjoern A. Zeeb 			     enum led_brightness brightness)
873*a0ccc12fSBjoern A. Zeeb {
874*a0ccc12fSBjoern A. Zeeb 	struct rtw_dev *rtwdev = container_of(led, struct rtw_dev, led_cdev);
875*a0ccc12fSBjoern A. Zeeb 	u8 ledcfg;
876*a0ccc12fSBjoern A. Zeeb 
877*a0ccc12fSBjoern A. Zeeb 	ledcfg = rtw_read8(rtwdev, REG_LED_CFG);
878*a0ccc12fSBjoern A. Zeeb 	ledcfg &= BIT(6) | BIT(4);
879*a0ccc12fSBjoern A. Zeeb 	ledcfg |= BIT(5);
880*a0ccc12fSBjoern A. Zeeb 
881*a0ccc12fSBjoern A. Zeeb 	if (brightness == LED_OFF)
882*a0ccc12fSBjoern A. Zeeb 		ledcfg |= BIT(3);
883*a0ccc12fSBjoern A. Zeeb 
884*a0ccc12fSBjoern A. Zeeb 	rtw_write8(rtwdev, REG_LED_CFG, ledcfg);
885*a0ccc12fSBjoern A. Zeeb }
886*a0ccc12fSBjoern A. Zeeb 
887*a0ccc12fSBjoern A. Zeeb static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev,
888*a0ccc12fSBjoern A. Zeeb 					  struct rtw_tx_pkt_info *pkt_info,
889*a0ccc12fSBjoern A. Zeeb 					  u8 *txdesc)
890*a0ccc12fSBjoern A. Zeeb {
891*a0ccc12fSBjoern A. Zeeb 	fill_txdesc_checksum_common(txdesc, 16);
892*a0ccc12fSBjoern A. Zeeb }
893*a0ccc12fSBjoern A. Zeeb 
894*a0ccc12fSBjoern A. Zeeb static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev)
895*a0ccc12fSBjoern A. Zeeb {
896*a0ccc12fSBjoern A. Zeeb }
897*a0ccc12fSBjoern A. Zeeb 
898*a0ccc12fSBjoern A. Zeeb static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev)
899*a0ccc12fSBjoern A. Zeeb {
900*a0ccc12fSBjoern A. Zeeb }
901*a0ccc12fSBjoern A. Zeeb 
902*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev)
903*a0ccc12fSBjoern A. Zeeb {
904*a0ccc12fSBjoern A. Zeeb }
905*a0ccc12fSBjoern A. Zeeb 
906*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr)
907*a0ccc12fSBjoern A. Zeeb {
908*a0ccc12fSBjoern A. Zeeb }
909*a0ccc12fSBjoern A. Zeeb 
910*a0ccc12fSBjoern A. Zeeb static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain)
911*a0ccc12fSBjoern A. Zeeb {
912*a0ccc12fSBjoern A. Zeeb }
913*a0ccc12fSBjoern A. Zeeb 
914*a0ccc12fSBjoern A. Zeeb static const struct rtw_chip_ops rtw8812a_ops = {
915*a0ccc12fSBjoern A. Zeeb 	.power_on		= rtw88xxa_power_on,
916*a0ccc12fSBjoern A. Zeeb 	.power_off		= rtw8812a_power_off,
917*a0ccc12fSBjoern A. Zeeb 	.phy_set_param		= NULL,
918*a0ccc12fSBjoern A. Zeeb 	.read_efuse		= rtw88xxa_read_efuse,
919*a0ccc12fSBjoern A. Zeeb 	.query_phy_status	= rtw8812a_query_phy_status,
920*a0ccc12fSBjoern A. Zeeb 	.set_channel		= rtw88xxa_set_channel,
921*a0ccc12fSBjoern A. Zeeb 	.mac_init		= NULL,
922*a0ccc12fSBjoern A. Zeeb 	.read_rf		= rtw88xxa_phy_read_rf,
923*a0ccc12fSBjoern A. Zeeb 	.write_rf		= rtw_phy_write_rf_reg_sipi,
924*a0ccc12fSBjoern A. Zeeb 	.set_antenna		= NULL,
925*a0ccc12fSBjoern A. Zeeb 	.set_tx_power_index	= rtw88xxa_set_tx_power_index,
926*a0ccc12fSBjoern A. Zeeb 	.cfg_ldo25		= rtw8812a_cfg_ldo25,
927*a0ccc12fSBjoern A. Zeeb 	.efuse_grant		= rtw88xxa_efuse_grant,
928*a0ccc12fSBjoern A. Zeeb 	.false_alarm_statistics	= rtw88xxa_false_alarm_statistics,
929*a0ccc12fSBjoern A. Zeeb 	.phy_calibration	= rtw8812a_phy_calibration,
930*a0ccc12fSBjoern A. Zeeb 	.cck_pd_set		= rtw88xxa_phy_cck_pd_set,
931*a0ccc12fSBjoern A. Zeeb 	.pwr_track		= rtw8812a_pwr_track,
932*a0ccc12fSBjoern A. Zeeb 	.config_bfee		= NULL,
933*a0ccc12fSBjoern A. Zeeb 	.set_gid_table		= NULL,
934*a0ccc12fSBjoern A. Zeeb 	.cfg_csi_rate		= NULL,
935*a0ccc12fSBjoern A. Zeeb 	.led_set		= rtw8812a_led_set,
936*a0ccc12fSBjoern A. Zeeb 	.fill_txdesc_checksum	= rtw8812a_fill_txdesc_checksum,
937*a0ccc12fSBjoern A. Zeeb 	.coex_set_init		= rtw8812a_coex_cfg_init,
938*a0ccc12fSBjoern A. Zeeb 	.coex_set_ant_switch	= NULL,
939*a0ccc12fSBjoern A. Zeeb 	.coex_set_gnt_fix	= rtw8812a_coex_cfg_gnt_fix,
940*a0ccc12fSBjoern A. Zeeb 	.coex_set_gnt_debug	= NULL,
941*a0ccc12fSBjoern A. Zeeb 	.coex_set_rfe_type	= rtw8821a_coex_cfg_rfe_type,
942*a0ccc12fSBjoern A. Zeeb 	.coex_set_wl_tx_power	= rtw8821a_coex_cfg_wl_tx_power,
943*a0ccc12fSBjoern A. Zeeb 	.coex_set_wl_rx_gain	= rtw8821a_coex_cfg_wl_rx_gain,
944*a0ccc12fSBjoern A. Zeeb };
945*a0ccc12fSBjoern A. Zeeb 
946*a0ccc12fSBjoern A. Zeeb static const struct rtw_page_table page_table_8812a[] = {
947*a0ccc12fSBjoern A. Zeeb 	/* hq_num, nq_num, lq_num, exq_num, gapq_num */
948*a0ccc12fSBjoern A. Zeeb 	{0, 0, 0, 0, 0},	/* SDIO */
949*a0ccc12fSBjoern A. Zeeb 	{0, 0, 0, 0, 0},	/* PCI */
950*a0ccc12fSBjoern A. Zeeb 	{16, 0, 0, 0, 1},	/* 2 bulk out endpoints */
951*a0ccc12fSBjoern A. Zeeb 	{16, 0, 16, 0, 1},	/* 3 bulk out endpoints */
952*a0ccc12fSBjoern A. Zeeb 	{16, 0, 16, 0, 1},	/* 4 bulk out endpoints */
953*a0ccc12fSBjoern A. Zeeb };
954*a0ccc12fSBjoern A. Zeeb 
955*a0ccc12fSBjoern A. Zeeb static const struct rtw_rqpn rqpn_table_8812a[] = {
956*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
957*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
958*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
959*a0ccc12fSBjoern A. Zeeb 
960*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
961*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
962*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
963*a0ccc12fSBjoern A. Zeeb 
964*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH,
965*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
966*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
967*a0ccc12fSBjoern A. Zeeb 
968*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL,
969*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
970*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH},
971*a0ccc12fSBjoern A. Zeeb 
972*a0ccc12fSBjoern A. Zeeb 	{RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL,
973*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW,
974*a0ccc12fSBjoern A. Zeeb 	 RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH},
975*a0ccc12fSBjoern A. Zeeb };
976*a0ccc12fSBjoern A. Zeeb 
977*a0ccc12fSBjoern A. Zeeb static const struct rtw_prioq_addrs prioq_addrs_8812a = {
978*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_EXTRA] = {
979*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3,
980*a0ccc12fSBjoern A. Zeeb 	},
981*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_LOW] = {
982*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1,
983*a0ccc12fSBjoern A. Zeeb 	},
984*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_NORMAL] = {
985*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1,
986*a0ccc12fSBjoern A. Zeeb 	},
987*a0ccc12fSBjoern A. Zeeb 	.prio[RTW_DMA_MAPPING_HIGH] = {
988*a0ccc12fSBjoern A. Zeeb 		.rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2,
989*a0ccc12fSBjoern A. Zeeb 	},
990*a0ccc12fSBjoern A. Zeeb 	.wsize = false,
991*a0ccc12fSBjoern A. Zeeb };
992*a0ccc12fSBjoern A. Zeeb 
993*a0ccc12fSBjoern A. Zeeb static const struct rtw_hw_reg rtw8812a_dig[] = {
994*a0ccc12fSBjoern A. Zeeb 	[0] = { .addr = REG_RXIGI_A, .mask = 0x7f },
995*a0ccc12fSBjoern A. Zeeb 	[1] = { .addr = REG_RXIGI_B, .mask = 0x7f },
996*a0ccc12fSBjoern A. Zeeb };
997*a0ccc12fSBjoern A. Zeeb 
998*a0ccc12fSBjoern A. Zeeb static const struct rtw_rfe_def rtw8812a_rfe_defs[] = {
999*a0ccc12fSBjoern A. Zeeb 	[0] = { .phy_pg_tbl	= &rtw8812a_bb_pg_tbl,
1000*a0ccc12fSBjoern A. Zeeb 		.txpwr_lmt_tbl	= &rtw8812a_txpwr_lmt_tbl,
1001*a0ccc12fSBjoern A. Zeeb 		.pwr_track_tbl	= &rtw8812a_rtw_pwr_track_tbl, },
1002*a0ccc12fSBjoern A. Zeeb 	[1] = { .phy_pg_tbl	= &rtw8812a_bb_pg_tbl,
1003*a0ccc12fSBjoern A. Zeeb 		.txpwr_lmt_tbl	= &rtw8812a_txpwr_lmt_tbl,
1004*a0ccc12fSBjoern A. Zeeb 		.pwr_track_tbl	= &rtw8812a_rtw_pwr_track_tbl, },
1005*a0ccc12fSBjoern A. Zeeb 	[2] = { .phy_pg_tbl	= &rtw8812a_bb_pg_tbl,
1006*a0ccc12fSBjoern A. Zeeb 		.txpwr_lmt_tbl	= &rtw8812a_txpwr_lmt_tbl,
1007*a0ccc12fSBjoern A. Zeeb 		.pwr_track_tbl	= &rtw8812a_rtw_pwr_track_tbl, },
1008*a0ccc12fSBjoern A. Zeeb 	[3] = { .phy_pg_tbl	= &rtw8812a_bb_pg_rfe3_tbl,
1009*a0ccc12fSBjoern A. Zeeb 		.txpwr_lmt_tbl	= &rtw8812a_txpwr_lmt_tbl,
1010*a0ccc12fSBjoern A. Zeeb 		.pwr_track_tbl	= &rtw8812a_rtw_pwr_track_rfe3_tbl, },
1011*a0ccc12fSBjoern A. Zeeb };
1012*a0ccc12fSBjoern A. Zeeb 
1013*a0ccc12fSBjoern A. Zeeb static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40};
1014*a0ccc12fSBjoern A. Zeeb static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101};
1015*a0ccc12fSBjoern A. Zeeb 
1016*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_tx_8812a[] = {
1017*a0ccc12fSBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
1018*a0ccc12fSBjoern A. Zeeb 	{0, 20, false, 7}, /* for WL-CPT */
1019*a0ccc12fSBjoern A. Zeeb 	{8, 17, true, 4},
1020*a0ccc12fSBjoern A. Zeeb 	{7, 18, true, 4},
1021*a0ccc12fSBjoern A. Zeeb 	{6, 19, true, 4},
1022*a0ccc12fSBjoern A. Zeeb 	{5, 20, true, 4}
1023*a0ccc12fSBjoern A. Zeeb };
1024*a0ccc12fSBjoern A. Zeeb 
1025*a0ccc12fSBjoern A. Zeeb static const struct coex_rf_para rf_para_rx_8812a[] = {
1026*a0ccc12fSBjoern A. Zeeb 	{0, 0, false, 7},  /* for normal */
1027*a0ccc12fSBjoern A. Zeeb 	{0, 20, false, 7}, /* for WL-CPT */
1028*a0ccc12fSBjoern A. Zeeb 	{3, 24, true, 5},
1029*a0ccc12fSBjoern A. Zeeb 	{2, 26, true, 5},
1030*a0ccc12fSBjoern A. Zeeb 	{1, 27, true, 5},
1031*a0ccc12fSBjoern A. Zeeb 	{0, 28, true, 5}
1032*a0ccc12fSBjoern A. Zeeb };
1033*a0ccc12fSBjoern A. Zeeb 
1034*a0ccc12fSBjoern A. Zeeb static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a));
1035*a0ccc12fSBjoern A. Zeeb 
1036*a0ccc12fSBjoern A. Zeeb const struct rtw_chip_info rtw8812a_hw_spec = {
1037*a0ccc12fSBjoern A. Zeeb 	.ops = &rtw8812a_ops,
1038*a0ccc12fSBjoern A. Zeeb 	.id = RTW_CHIP_TYPE_8812A,
1039*a0ccc12fSBjoern A. Zeeb 	.fw_name = "rtw88/rtw8812a_fw.bin",
1040*a0ccc12fSBjoern A. Zeeb 	.wlan_cpu = RTW_WCPU_11N,
1041*a0ccc12fSBjoern A. Zeeb 	.tx_pkt_desc_sz = 40,
1042*a0ccc12fSBjoern A. Zeeb 	.tx_buf_desc_sz = 16,
1043*a0ccc12fSBjoern A. Zeeb 	.rx_pkt_desc_sz = 24,
1044*a0ccc12fSBjoern A. Zeeb 	.rx_buf_desc_sz = 8,
1045*a0ccc12fSBjoern A. Zeeb 	.phy_efuse_size = 512,
1046*a0ccc12fSBjoern A. Zeeb 	.log_efuse_size = 512,
1047*a0ccc12fSBjoern A. Zeeb 	.ptct_efuse_size = 0,
1048*a0ccc12fSBjoern A. Zeeb 	.txff_size = 131072,
1049*a0ccc12fSBjoern A. Zeeb 	.rxff_size = 16128,
1050*a0ccc12fSBjoern A. Zeeb 	.rsvd_drv_pg_num = 9,
1051*a0ccc12fSBjoern A. Zeeb 	.txgi_factor = 1,
1052*a0ccc12fSBjoern A. Zeeb 	.is_pwr_by_rate_dec = true,
1053*a0ccc12fSBjoern A. Zeeb 	.max_power_index = 0x3f,
1054*a0ccc12fSBjoern A. Zeeb 	.csi_buf_pg_num = 0,
1055*a0ccc12fSBjoern A. Zeeb 	.band = RTW_BAND_2G | RTW_BAND_5G,
1056*a0ccc12fSBjoern A. Zeeb 	.page_size = 512,
1057*a0ccc12fSBjoern A. Zeeb 	.dig_min = 0x20,
1058*a0ccc12fSBjoern A. Zeeb 	.ht_supported = true,
1059*a0ccc12fSBjoern A. Zeeb 	.vht_supported = true,
1060*a0ccc12fSBjoern A. Zeeb 	.lps_deep_mode_supported = 0,
1061*a0ccc12fSBjoern A. Zeeb 	.sys_func_en = 0xFD,
1062*a0ccc12fSBjoern A. Zeeb 	.pwr_on_seq = card_enable_flow_8812a,
1063*a0ccc12fSBjoern A. Zeeb 	.pwr_off_seq = card_disable_flow_8812a,
1064*a0ccc12fSBjoern A. Zeeb 	.page_table = page_table_8812a,
1065*a0ccc12fSBjoern A. Zeeb 	.rqpn_table = rqpn_table_8812a,
1066*a0ccc12fSBjoern A. Zeeb 	.prioq_addrs = &prioq_addrs_8812a,
1067*a0ccc12fSBjoern A. Zeeb 	.intf_table = NULL,
1068*a0ccc12fSBjoern A. Zeeb 	.dig = rtw8812a_dig,
1069*a0ccc12fSBjoern A. Zeeb 	.rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B},
1070*a0ccc12fSBjoern A. Zeeb 	.ltecoex_addr = NULL,
1071*a0ccc12fSBjoern A. Zeeb 	.mac_tbl = &rtw8812a_mac_tbl,
1072*a0ccc12fSBjoern A. Zeeb 	.agc_tbl = &rtw8812a_agc_tbl,
1073*a0ccc12fSBjoern A. Zeeb 	.bb_tbl = &rtw8812a_bb_tbl,
1074*a0ccc12fSBjoern A. Zeeb 	.rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl},
1075*a0ccc12fSBjoern A. Zeeb 	.rfe_defs = rtw8812a_rfe_defs,
1076*a0ccc12fSBjoern A. Zeeb 	.rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs),
1077*a0ccc12fSBjoern A. Zeeb 	.rx_ldpc = false,
1078*a0ccc12fSBjoern A. Zeeb 	.hw_feature_report = false,
1079*a0ccc12fSBjoern A. Zeeb 	.c2h_ra_report_size = 4,
1080*a0ccc12fSBjoern A. Zeeb 	.old_datarate_fb_limit = true,
1081*a0ccc12fSBjoern A. Zeeb 	.usb_tx_agg_desc_num = 1,
1082*a0ccc12fSBjoern A. Zeeb 	.iqk_threshold = 8,
1083*a0ccc12fSBjoern A. Zeeb 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
1084*a0ccc12fSBjoern A. Zeeb 	.max_scan_ie_len = IEEE80211_MAX_DATA_LEN,
1085*a0ccc12fSBjoern A. Zeeb 
1086*a0ccc12fSBjoern A. Zeeb 	.coex_para_ver = 0, /* no coex code in 8812au driver */
1087*a0ccc12fSBjoern A. Zeeb 	.bt_desired_ver = 0,
1088*a0ccc12fSBjoern A. Zeeb 	.scbd_support = false,
1089*a0ccc12fSBjoern A. Zeeb 	.new_scbd10_def = false,
1090*a0ccc12fSBjoern A. Zeeb 	.ble_hid_profile_support = false,
1091*a0ccc12fSBjoern A. Zeeb 	.wl_mimo_ps_support = false,
1092*a0ccc12fSBjoern A. Zeeb 	.pstdma_type = COEX_PSTDMA_FORCE_LPSOFF,
1093*a0ccc12fSBjoern A. Zeeb 	.bt_rssi_type = COEX_BTRSSI_RATIO,
1094*a0ccc12fSBjoern A. Zeeb 	.ant_isolation = 15,
1095*a0ccc12fSBjoern A. Zeeb 	.rssi_tolerance = 2,
1096*a0ccc12fSBjoern A. Zeeb 	.wl_rssi_step = wl_rssi_step_8812a,
1097*a0ccc12fSBjoern A. Zeeb 	.bt_rssi_step = bt_rssi_step_8812a,
1098*a0ccc12fSBjoern A. Zeeb 	.table_sant_num = 0,
1099*a0ccc12fSBjoern A. Zeeb 	.table_sant = NULL,
1100*a0ccc12fSBjoern A. Zeeb 	.table_nsant_num = 0,
1101*a0ccc12fSBjoern A. Zeeb 	.table_nsant = NULL,
1102*a0ccc12fSBjoern A. Zeeb 	.tdma_sant_num = 0,
1103*a0ccc12fSBjoern A. Zeeb 	.tdma_sant = NULL,
1104*a0ccc12fSBjoern A. Zeeb 	.tdma_nsant_num = 0,
1105*a0ccc12fSBjoern A. Zeeb 	.tdma_nsant = NULL,
1106*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a),
1107*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_tx = rf_para_tx_8812a,
1108*a0ccc12fSBjoern A. Zeeb 	.wl_rf_para_rx = rf_para_rx_8812a,
1109*a0ccc12fSBjoern A. Zeeb 	.bt_afh_span_bw20 = 0x20,
1110*a0ccc12fSBjoern A. Zeeb 	.bt_afh_span_bw40 = 0x30,
1111*a0ccc12fSBjoern A. Zeeb 	.afh_5g_num = 0,
1112*a0ccc12fSBjoern A. Zeeb 	.afh_5g = NULL,
1113*a0ccc12fSBjoern A. Zeeb 	.coex_info_hw_regs_num = 0,
1114*a0ccc12fSBjoern A. Zeeb 	.coex_info_hw_regs = NULL,
1115*a0ccc12fSBjoern A. Zeeb };
1116*a0ccc12fSBjoern A. Zeeb EXPORT_SYMBOL(rtw8812a_hw_spec);
1117*a0ccc12fSBjoern A. Zeeb 
1118*a0ccc12fSBjoern A. Zeeb MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin");
1119*a0ccc12fSBjoern A. Zeeb 
1120*a0ccc12fSBjoern A. Zeeb MODULE_AUTHOR("Realtek Corporation");
1121*a0ccc12fSBjoern A. Zeeb MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver");
1122*a0ccc12fSBjoern A. Zeeb MODULE_LICENSE("Dual BSD/GPL");
1123