xref: /linux/drivers/net/wireless/realtek/rtw89/rtw8922a.c (revision 4e73826089ce899357580bbf6e0afe4e6f9900b7)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2023  Realtek Corporation
3  */
4 
5 #include "debug.h"
6 #include "efuse.h"
7 #include "fw.h"
8 #include "mac.h"
9 #include "phy.h"
10 #include "reg.h"
11 #include "rtw8922a.h"
12 
13 #define RTW8922A_FW_FORMAT_MAX 0
14 #define RTW8922A_FW_BASENAME "rtw89/rtw8922a_fw"
15 #define RTW8922A_MODULE_FIRMWARE \
16 	RTW8922A_FW_BASENAME ".bin"
17 
18 static const struct rtw89_hfc_ch_cfg rtw8922a_hfc_chcfg_pcie[] = {
19 	{2, 1641, grp_0}, /* ACH 0 */
20 	{2, 1641, grp_0}, /* ACH 1 */
21 	{2, 1641, grp_0}, /* ACH 2 */
22 	{2, 1641, grp_0}, /* ACH 3 */
23 	{2, 1641, grp_1}, /* ACH 4 */
24 	{2, 1641, grp_1}, /* ACH 5 */
25 	{2, 1641, grp_1}, /* ACH 6 */
26 	{2, 1641, grp_1}, /* ACH 7 */
27 	{2, 1641, grp_0}, /* B0MGQ */
28 	{2, 1641, grp_0}, /* B0HIQ */
29 	{2, 1641, grp_1}, /* B1MGQ */
30 	{2, 1641, grp_1}, /* B1HIQ */
31 	{0, 0, 0}, /* FWCMDQ */
32 	{0, 0, 0}, /* BMC */
33 	{0, 0, 0}, /* H2D */
34 };
35 
36 static const struct rtw89_hfc_pub_cfg rtw8922a_hfc_pubcfg_pcie = {
37 	1651, /* Group 0 */
38 	1651, /* Group 1 */
39 	3302, /* Public Max */
40 	0, /* WP threshold */
41 };
42 
43 static const struct rtw89_hfc_param_ini rtw8922a_hfc_param_ini_pcie[] = {
44 	[RTW89_QTA_SCC] = {rtw8922a_hfc_chcfg_pcie, &rtw8922a_hfc_pubcfg_pcie,
45 			   &rtw89_mac_size.hfc_prec_cfg_c0, RTW89_HCIFC_POH},
46 	[RTW89_QTA_DLFW] = {NULL, NULL, &rtw89_mac_size.hfc_prec_cfg_c2,
47 			    RTW89_HCIFC_POH},
48 	[RTW89_QTA_INVALID] = {NULL},
49 };
50 
51 static const struct rtw89_dle_mem rtw8922a_dle_mem_pcie[] = {
52 	[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size0_v1,
53 			   &rtw89_mac_size.ple_size0_v1, &rtw89_mac_size.wde_qt0_v1,
54 			   &rtw89_mac_size.wde_qt0_v1, &rtw89_mac_size.ple_qt0,
55 			   &rtw89_mac_size.ple_qt1, &rtw89_mac_size.ple_rsvd_qt0,
56 			   &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
57 	[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size4_v1,
58 			    &rtw89_mac_size.ple_size3_v1, &rtw89_mac_size.wde_qt4,
59 			    &rtw89_mac_size.wde_qt4, &rtw89_mac_size.ple_qt9,
60 			    &rtw89_mac_size.ple_qt9, &rtw89_mac_size.ple_rsvd_qt1,
61 			    &rtw89_mac_size.rsvd0_size0, &rtw89_mac_size.rsvd1_size0},
62 	[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
63 			       NULL},
64 };
65 
66 static const struct rtw89_reg_imr rtw8922a_imr_dmac_regs[] = {
67 	{R_BE_DISP_HOST_IMR, B_BE_DISP_HOST_IMR_CLR, B_BE_DISP_HOST_IMR_SET},
68 	{R_BE_DISP_CPU_IMR, B_BE_DISP_CPU_IMR_CLR, B_BE_DISP_CPU_IMR_SET},
69 	{R_BE_DISP_OTHER_IMR, B_BE_DISP_OTHER_IMR_CLR, B_BE_DISP_OTHER_IMR_SET},
70 	{R_BE_PKTIN_ERR_IMR, B_BE_PKTIN_ERR_IMR_CLR, B_BE_PKTIN_ERR_IMR_SET},
71 	{R_BE_INTERRUPT_MASK_REG, B_BE_INTERRUPT_MASK_REG_CLR, B_BE_INTERRUPT_MASK_REG_SET},
72 	{R_BE_MLO_ERR_IDCT_IMR, B_BE_MLO_ERR_IDCT_IMR_CLR, B_BE_MLO_ERR_IDCT_IMR_SET},
73 	{R_BE_MPDU_TX_ERR_IMR, B_BE_MPDU_TX_ERR_IMR_CLR, B_BE_MPDU_TX_ERR_IMR_SET},
74 	{R_BE_MPDU_RX_ERR_IMR, B_BE_MPDU_RX_ERR_IMR_CLR, B_BE_MPDU_RX_ERR_IMR_SET},
75 	{R_BE_SEC_ERROR_IMR, B_BE_SEC_ERROR_IMR_CLR, B_BE_SEC_ERROR_IMR_SET},
76 	{R_BE_CPUIO_ERR_IMR, B_BE_CPUIO_ERR_IMR_CLR, B_BE_CPUIO_ERR_IMR_SET},
77 	{R_BE_WDE_ERR_IMR, B_BE_WDE_ERR_IMR_CLR, B_BE_WDE_ERR_IMR_SET},
78 	{R_BE_WDE_ERR1_IMR, B_BE_WDE_ERR1_IMR_CLR, B_BE_WDE_ERR1_IMR_SET},
79 	{R_BE_PLE_ERR_IMR, B_BE_PLE_ERR_IMR_CLR, B_BE_PLE_ERR_IMR_SET},
80 	{R_BE_PLE_ERRFLAG1_IMR, B_BE_PLE_ERRFLAG1_IMR_CLR, B_BE_PLE_ERRFLAG1_IMR_SET},
81 	{R_BE_WDRLS_ERR_IMR, B_BE_WDRLS_ERR_IMR_CLR, B_BE_WDRLS_ERR_IMR_SET},
82 	{R_BE_TXPKTCTL_B0_ERRFLAG_IMR, B_BE_TXPKTCTL_B0_ERRFLAG_IMR_CLR,
83 	 B_BE_TXPKTCTL_B0_ERRFLAG_IMR_SET},
84 	{R_BE_TXPKTCTL_B1_ERRFLAG_IMR, B_BE_TXPKTCTL_B1_ERRFLAG_IMR_CLR,
85 	 B_BE_TXPKTCTL_B1_ERRFLAG_IMR_SET},
86 	{R_BE_BBRPT_COM_ERR_IMR, B_BE_BBRPT_COM_ERR_IMR_CLR, B_BE_BBRPT_COM_ERR_IMR_SET},
87 	{R_BE_BBRPT_CHINFO_ERR_IMR, B_BE_BBRPT_CHINFO_ERR_IMR_CLR,
88 	 B_BE_BBRPT_CHINFO_ERR_IMR_SET},
89 	{R_BE_BBRPT_DFS_ERR_IMR, B_BE_BBRPT_DFS_ERR_IMR_CLR, B_BE_BBRPT_DFS_ERR_IMR_SET},
90 	{R_BE_LA_ERRFLAG_IMR, B_BE_LA_ERRFLAG_IMR_CLR, B_BE_LA_ERRFLAG_IMR_SET},
91 	{R_BE_CH_INFO_DBGFLAG_IMR, B_BE_CH_INFO_DBGFLAG_IMR_CLR, B_BE_CH_INFO_DBGFLAG_IMR_SET},
92 	{R_BE_PLRLS_ERR_IMR, B_BE_PLRLS_ERR_IMR_CLR, B_BE_PLRLS_ERR_IMR_SET},
93 	{R_BE_HAXI_IDCT_MSK, B_BE_HAXI_IDCT_MSK_CLR, B_BE_HAXI_IDCT_MSK_SET},
94 };
95 
96 static const struct rtw89_imr_table rtw8922a_imr_dmac_table = {
97 	.regs = rtw8922a_imr_dmac_regs,
98 	.n_regs = ARRAY_SIZE(rtw8922a_imr_dmac_regs),
99 };
100 
101 static const struct rtw89_reg_imr rtw8922a_imr_cmac_regs[] = {
102 	{R_BE_RESP_IMR, B_BE_RESP_IMR_CLR, B_BE_RESP_IMR_SET},
103 	{R_BE_RX_ERROR_FLAG_IMR, B_BE_RX_ERROR_FLAG_IMR_CLR, B_BE_RX_ERROR_FLAG_IMR_SET},
104 	{R_BE_TX_ERROR_FLAG_IMR, B_BE_TX_ERROR_FLAG_IMR_CLR, B_BE_TX_ERROR_FLAG_IMR_SET},
105 	{R_BE_RX_ERROR_FLAG_IMR_1, B_BE_TX_ERROR_FLAG_IMR_1_CLR, B_BE_TX_ERROR_FLAG_IMR_1_SET},
106 	{R_BE_PTCL_IMR1, B_BE_PTCL_IMR1_CLR, B_BE_PTCL_IMR1_SET},
107 	{R_BE_PTCL_IMR0, B_BE_PTCL_IMR0_CLR, B_BE_PTCL_IMR0_SET},
108 	{R_BE_PTCL_IMR_2, B_BE_PTCL_IMR_2_CLR, B_BE_PTCL_IMR_2_SET},
109 	{R_BE_SCHEDULE_ERR_IMR, B_BE_SCHEDULE_ERR_IMR_CLR, B_BE_SCHEDULE_ERR_IMR_SET},
110 	{R_BE_C0_TXPWR_IMR, B_BE_C0_TXPWR_IMR_CLR, B_BE_C0_TXPWR_IMR_SET},
111 	{R_BE_TRXPTCL_ERROR_INDICA_MASK, B_BE_TRXPTCL_ERROR_INDICA_MASK_CLR,
112 	 B_BE_TRXPTCL_ERROR_INDICA_MASK_SET},
113 	{R_BE_RX_ERR_IMR, B_BE_RX_ERR_IMR_CLR, B_BE_RX_ERR_IMR_SET},
114 	{R_BE_PHYINFO_ERR_IMR_V1, B_BE_PHYINFO_ERR_IMR_V1_CLR, B_BE_PHYINFO_ERR_IMR_V1_SET},
115 };
116 
117 static const struct rtw89_imr_table rtw8922a_imr_cmac_table = {
118 	.regs = rtw8922a_imr_cmac_regs,
119 	.n_regs = ARRAY_SIZE(rtw8922a_imr_cmac_regs),
120 };
121 
122 static const struct rtw89_efuse_block_cfg rtw8922a_efuse_blocks[] = {
123 	[RTW89_EFUSE_BLOCK_SYS]			= {.offset = 0x00000, .size = 0x310},
124 	[RTW89_EFUSE_BLOCK_RF]			= {.offset = 0x10000, .size = 0x240},
125 	[RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO]	= {.offset = 0x20000, .size = 0x4800},
126 	[RTW89_EFUSE_BLOCK_HCI_DIG_USB]		= {.offset = 0x30000, .size = 0x890},
127 	[RTW89_EFUSE_BLOCK_HCI_PHY_PCIE]	= {.offset = 0x40000, .size = 0x200},
128 	[RTW89_EFUSE_BLOCK_HCI_PHY_USB3]	= {.offset = 0x50000, .size = 0x80},
129 	[RTW89_EFUSE_BLOCK_HCI_PHY_USB2]	= {.offset = 0x60000, .size = 0x0},
130 	[RTW89_EFUSE_BLOCK_ADIE]		= {.offset = 0x70000, .size = 0x10},
131 };
132 
133 static int rtw8922a_pwr_on_func(struct rtw89_dev *rtwdev)
134 {
135 	struct rtw89_hal *hal = &rtwdev->hal;
136 	u32 val32;
137 	int ret;
138 
139 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_AFSM_WLSUS_EN |
140 						    B_BE_AFSM_PCIE_SUS_EN);
141 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_DIS_WLBT_PDNSUSEN_SOPC);
142 	rtw89_write32_set(rtwdev, R_BE_WLLPS_CTRL, B_BE_DIS_WLBT_LPSEN_LOPC);
143 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APDM_HPDN);
144 	rtw89_write32_clr(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
145 
146 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_RDY_SYSPWR,
147 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
148 	if (ret)
149 		return ret;
150 
151 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
152 	rtw89_write32_set(rtwdev, R_BE_WLRESUME_CTRL, B_BE_LPSROP_CMAC0 |
153 						      B_BE_LPSROP_CMAC1);
154 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFN_ONMAC);
155 
156 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFN_ONMAC),
157 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
158 	if (ret)
159 		return ret;
160 
161 	rtw89_write32_clr(rtwdev, R_BE_AFE_ON_CTRL1, B_BE_REG_CK_MON_CK960M_EN);
162 	rtw89_write8_set(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
163 						      B_BE_POW_PC_LDO_PORT1);
164 	rtw89_write32_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
165 						       B_BE_R_SYM_ISO_ADDA_P12PP);
166 	rtw89_write8_set(rtwdev, R_BE_PLATFORM_ENABLE, B_BE_PLATFORM_EN);
167 	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
168 
169 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HAXIDMA_IO_ST,
170 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
171 	if (ret)
172 		return ret;
173 
174 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
175 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
176 	if (ret)
177 		return ret;
178 
179 	rtw89_write32_set(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
180 
181 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_BE_HCI_WLAN_IO_ST,
182 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
183 	if (ret)
184 		return ret;
185 
186 	rtw89_write32_clr(rtwdev, R_BE_SYS_SDIO_CTRL, B_BE_PCIE_FORCE_IBX_EN);
187 
188 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0x02);
189 	if (ret)
190 		return ret;
191 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x01, 0x01);
192 	if (ret)
193 		return ret;
194 
195 	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
196 
197 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x40, 0x40);
198 	if (ret)
199 		return ret;
200 
201 	rtw89_write32_set(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
202 
203 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x20, 0x20);
204 	if (ret)
205 		return ret;
206 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x04, 0x04);
207 	if (ret)
208 		return ret;
209 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x08, 0x08);
210 	if (ret)
211 		return ret;
212 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x10);
213 	if (ret)
214 		return ret;
215 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xEB, 0xFF);
216 	if (ret)
217 		return ret;
218 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xEB, 0xFF);
219 	if (ret)
220 		return ret;
221 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x01, 0x01);
222 	if (ret)
223 		return ret;
224 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x02, 0x02);
225 	if (ret)
226 		return ret;
227 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x80);
228 	if (ret)
229 		return ret;
230 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF1, 0, 0x40);
231 	if (ret)
232 		return ret;
233 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XREF_RF2, 0, 0x40);
234 	if (ret)
235 		return ret;
236 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, 0x40, 0x60);
237 	if (ret)
238 		return ret;
239 
240 	if (hal->cv != CHIP_CAV) {
241 		rtw89_write32_set(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
242 		rtw89_write32_set(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_ISO_EB2CORE);
243 		rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_B);
244 
245 		mdelay(1);
246 
247 		rtw89_write32_clr(rtwdev, R_BE_SYS_ISO_CTRL, B_BE_PWC_EV2EF_S);
248 		rtw89_write32_clr(rtwdev, R_BE_PMC_DBG_CTRL2, B_BE_SYSON_DIS_PMCR_BE_WRMSK);
249 	}
250 
251 	rtw89_write32_set(rtwdev, R_BE_DMAC_FUNC_EN,
252 			  B_BE_MAC_FUNC_EN | B_BE_DMAC_FUNC_EN | B_BE_MPDU_PROC_EN |
253 			  B_BE_WD_RLS_EN | B_BE_DLE_WDE_EN | B_BE_TXPKT_CTRL_EN |
254 			  B_BE_STA_SCH_EN | B_BE_DLE_PLE_EN | B_BE_PKT_BUF_EN |
255 			  B_BE_DMAC_TBL_EN | B_BE_PKT_IN_EN | B_BE_DLE_CPUIO_EN |
256 			  B_BE_DISPATCHER_EN | B_BE_BBRPT_EN | B_BE_MAC_SEC_EN |
257 			  B_BE_H_AXIDMA_EN | B_BE_DMAC_MLO_EN | B_BE_PLRLS_EN |
258 			  B_BE_P_AXIDMA_EN | B_BE_DLE_DATACPUIO_EN | B_BE_LTR_CTL_EN);
259 
260 	set_bit(RTW89_FLAG_DMAC_FUNC, rtwdev->flags);
261 
262 	rtw89_write32_set(rtwdev, R_BE_CMAC_SHARE_FUNC_EN,
263 			  B_BE_CMAC_SHARE_EN | B_BE_RESPBA_EN | B_BE_ADDRSRCH_EN |
264 			  B_BE_BTCOEX_EN);
265 	rtw89_write32_set(rtwdev, R_BE_CMAC_FUNC_EN,
266 			  B_BE_CMAC_EN | B_BE_CMAC_TXEN |  B_BE_CMAC_RXEN |
267 			  B_BE_SIGB_EN | B_BE_PHYINTF_EN | B_BE_CMAC_DMA_EN |
268 			  B_BE_PTCLTOP_EN | B_BE_SCHEDULER_EN | B_BE_TMAC_EN |
269 			  B_BE_RMAC_EN | B_BE_TXTIME_EN | B_BE_RESP_PKTCTL_EN);
270 
271 	set_bit(RTW89_FLAG_CMAC0_FUNC, rtwdev->flags);
272 
273 	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
274 						       B_BE_FEN_BBPLAT_RSTB);
275 
276 	return 0;
277 }
278 
279 static int rtw8922a_pwr_off_func(struct rtw89_dev *rtwdev)
280 {
281 	u32 val32;
282 	int ret;
283 
284 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x10, 0x10);
285 	if (ret)
286 		return ret;
287 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x08);
288 	if (ret)
289 		return ret;
290 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x04);
291 	if (ret)
292 		return ret;
293 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xC6, 0xFF);
294 	if (ret)
295 		return ret;
296 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xC6, 0xFF);
297 	if (ret)
298 		return ret;
299 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x80, 0x80);
300 	if (ret)
301 		return ret;
302 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x02);
303 	if (ret)
304 		return ret;
305 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x01);
306 	if (ret)
307 		return ret;
308 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x02, 0xFF);
309 	if (ret)
310 		return ret;
311 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL, 0x00, 0xFF);
312 	if (ret)
313 		return ret;
314 
315 	rtw89_write32_set(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_R_SYM_ISO_ADDA_P02PP |
316 						       B_BE_R_SYM_ISO_ADDA_P12PP);
317 	rtw89_write8_clr(rtwdev, R_BE_ANAPAR_POW_MAC, B_BE_POW_PC_LDO_PORT0 |
318 						      B_BE_POW_PC_LDO_PORT1);
319 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_EN_WLON);
320 	rtw89_write8_clr(rtwdev, R_BE_FEN_RST_ENABLE, B_BE_FEN_BB_IP_RSTN |
321 						      B_BE_FEN_BBPLAT_RSTB);
322 	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC0_1P3);
323 
324 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x20);
325 	if (ret)
326 		return ret;
327 
328 	rtw89_write32_clr(rtwdev, R_BE_SYS_ADIE_PAD_PWR_CTRL, B_BE_SYM_PADPDN_WL_RFC1_1P3);
329 
330 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, 0x40);
331 	if (ret)
332 		return ret;
333 
334 	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HAXIDMA_IO_EN);
335 
336 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_IO_ST),
337 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
338 	if (ret)
339 		return ret;
340 
341 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HAXIDMA_BACKUP_RESTORE_ST),
342 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
343 	if (ret)
344 		return ret;
345 
346 	rtw89_write32_clr(rtwdev, R_BE_HCI_OPT_CTRL, B_BE_HCI_WLAN_IO_EN);
347 
348 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_HCI_WLAN_IO_ST),
349 				1000, 3000000, false, rtwdev, R_BE_HCI_OPT_CTRL);
350 	if (ret)
351 		return ret;
352 
353 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_OFFMAC);
354 
355 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_BE_APFM_OFFMAC),
356 				1000, 3000000, false, rtwdev, R_BE_SYS_PW_CTRL);
357 	if (ret)
358 		return ret;
359 
360 	rtw89_write32(rtwdev, R_BE_WLLPS_CTRL, 0x0000A1B2);
361 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_XTAL_OFF_A_DIE);
362 	rtw89_write32_set(rtwdev, R_BE_SYS_PW_CTRL, B_BE_APFM_SWLPS);
363 	rtw89_write32(rtwdev, R_BE_UDM1, 0);
364 
365 	return 0;
366 }
367 
368 static void rtw8922a_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
369 					struct rtw8922a_efuse *map)
370 {
371 	struct rtw8922a_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
372 	u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
373 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
374 	u8 i, j;
375 
376 	tssi->thermal[RF_PATH_A] = map->path_a_therm;
377 	tssi->thermal[RF_PATH_B] = map->path_b_therm;
378 
379 	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
380 		memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
381 		       sizeof(ofst[i]->cck_tssi));
382 
383 		for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
384 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
385 				    "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
386 				    i, j, tssi->tssi_cck[i][j]);
387 
388 		memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
389 		       sizeof(ofst[i]->bw40_tssi));
390 		memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
391 		       ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
392 		memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
393 		       sizeof(tssi->tssi_6g_mcs[i]));
394 
395 		for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
396 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
397 				    "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
398 				    i, j, tssi->tssi_mcs[i][j]);
399 	}
400 }
401 
402 static void rtw8922a_efuse_parsing_gain_offset(struct rtw89_dev *rtwdev,
403 					       struct rtw8922a_efuse *map)
404 {
405 	struct rtw89_phy_efuse_gain *gain = &rtwdev->efuse_gain;
406 	bool all_0xff = true, all_0x00 = true;
407 	int i, j;
408 	u8 t;
409 
410 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_a._2g_cck;
411 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_CCK] = map->rx_gain_b._2g_cck;
412 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_a._2g_ofdm;
413 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_2G_OFDM] = map->rx_gain_b._2g_ofdm;
414 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_a._5g_low;
415 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_LOW] = map->rx_gain_b._5g_low;
416 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_a._5g_mid;
417 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_MID] = map->rx_gain_b._5g_mid;
418 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_a._5g_high;
419 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_5G_HIGH] = map->rx_gain_b._5g_high;
420 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_a._6g_l0;
421 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L0] = map->rx_gain_6g_b._6g_l0;
422 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_a._6g_l1;
423 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_L1] = map->rx_gain_6g_b._6g_l1;
424 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_a._6g_m0;
425 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M0] = map->rx_gain_6g_b._6g_m0;
426 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_a._6g_m1;
427 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_M1] = map->rx_gain_6g_b._6g_m1;
428 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_a._6g_h0;
429 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H0] = map->rx_gain_6g_b._6g_h0;
430 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_a._6g_h1;
431 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_H1] = map->rx_gain_6g_b._6g_h1;
432 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_a._6g_uh0;
433 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH0] = map->rx_gain_6g_b._6g_uh0;
434 	gain->offset[RF_PATH_A][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_a._6g_uh1;
435 	gain->offset[RF_PATH_B][RTW89_GAIN_OFFSET_6G_UH1] = map->rx_gain_6g_b._6g_uh1;
436 
437 	for (i = RF_PATH_A; i <= RF_PATH_B; i++)
438 		for (j = 0; j < RTW89_GAIN_OFFSET_NR; j++) {
439 			t = gain->offset[i][j];
440 			if (t != 0xff)
441 				all_0xff = false;
442 			if (t != 0x0)
443 				all_0x00 = false;
444 
445 			/* transform: sign-bit + U(7,2) to S(8,2) */
446 			if (t & 0x80)
447 				gain->offset[i][j] = (t ^ 0x7f) + 1;
448 		}
449 
450 	gain->offset_valid = !all_0xff && !all_0x00;
451 }
452 
453 static void rtw8922a_read_efuse_mac_addr(struct rtw89_dev *rtwdev, u32 addr)
454 {
455 	struct rtw89_efuse *efuse = &rtwdev->efuse;
456 	u16 val;
457 	int i;
458 
459 	for (i = 0; i < ETH_ALEN; i += 2, addr += 2) {
460 		val = rtw89_read16(rtwdev, addr);
461 		efuse->addr[i] = val & 0xff;
462 		efuse->addr[i + 1] = val >> 8;
463 	}
464 }
465 
466 static int rtw8922a_read_efuse_pci_sdio(struct rtw89_dev *rtwdev, u8 *log_map)
467 {
468 	struct rtw89_efuse *efuse = &rtwdev->efuse;
469 
470 	if (rtwdev->hci.type == RTW89_HCI_TYPE_PCIE)
471 		rtw8922a_read_efuse_mac_addr(rtwdev, 0x3104);
472 	else
473 		ether_addr_copy(efuse->addr, log_map + 0x001A);
474 
475 	return 0;
476 }
477 
478 static int rtw8922a_read_efuse_usb(struct rtw89_dev *rtwdev, u8 *log_map)
479 {
480 	rtw8922a_read_efuse_mac_addr(rtwdev, 0x4078);
481 
482 	return 0;
483 }
484 
485 static int rtw8922a_read_efuse_rf(struct rtw89_dev *rtwdev, u8 *log_map)
486 {
487 	struct rtw8922a_efuse *map = (struct rtw8922a_efuse *)log_map;
488 	struct rtw89_efuse *efuse = &rtwdev->efuse;
489 
490 	efuse->rfe_type = map->rfe_type;
491 	efuse->xtal_cap = map->xtal_k;
492 	efuse->country_code[0] = map->country_code[0];
493 	efuse->country_code[1] = map->country_code[1];
494 	rtw8922a_efuse_parsing_tssi(rtwdev, map);
495 	rtw8922a_efuse_parsing_gain_offset(rtwdev, map);
496 
497 	rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
498 
499 	return 0;
500 }
501 
502 static int rtw8922a_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map,
503 			       enum rtw89_efuse_block block)
504 {
505 	switch (block) {
506 	case RTW89_EFUSE_BLOCK_HCI_DIG_PCIE_SDIO:
507 		return rtw8922a_read_efuse_pci_sdio(rtwdev, log_map);
508 	case RTW89_EFUSE_BLOCK_HCI_DIG_USB:
509 		return rtw8922a_read_efuse_usb(rtwdev, log_map);
510 	case RTW89_EFUSE_BLOCK_RF:
511 		return rtw8922a_read_efuse_rf(rtwdev, log_map);
512 	default:
513 		return 0;
514 	}
515 }
516 
517 #define THM_TRIM_POSITIVE_MASK BIT(6)
518 #define THM_TRIM_MAGNITUDE_MASK GENMASK(5, 0)
519 
520 static void rtw8922a_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
521 						 u8 *phycap_map)
522 {
523 	static const u32 thm_trim_addr[RF_PATH_NUM_8922A] = {0x1706, 0x1733};
524 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
525 	u32 addr = rtwdev->chip->phycap_addr;
526 	bool pg = true;
527 	u8 pg_th;
528 	s8 val;
529 	u8 i;
530 
531 	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
532 		pg_th = phycap_map[thm_trim_addr[i] - addr];
533 		if (pg_th == 0xff) {
534 			info->thermal_trim[i] = 0;
535 			pg = false;
536 			break;
537 		}
538 
539 		val = u8_get_bits(pg_th, THM_TRIM_MAGNITUDE_MASK);
540 
541 		if (!(pg_th & THM_TRIM_POSITIVE_MASK))
542 			val *= -1;
543 
544 		info->thermal_trim[i] = val;
545 
546 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
547 			    "[THERMAL][TRIM] path=%d thermal_trim=0x%x (%d)\n",
548 			    i, pg_th, val);
549 	}
550 
551 	info->pg_thermal_trim = pg;
552 }
553 
554 static void rtw8922a_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
555 						 u8 *phycap_map)
556 {
557 	static const u32 pabias_trim_addr[RF_PATH_NUM_8922A] = {0x1707, 0x1734};
558 	static const u32 check_pa_pad_trim_addr = 0x1700;
559 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
560 	u32 addr = rtwdev->chip->phycap_addr;
561 	u8 val;
562 	u8 i;
563 
564 	val = phycap_map[check_pa_pad_trim_addr - addr];
565 	if (val != 0xff)
566 		info->pg_pa_bias_trim = true;
567 
568 	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
569 		info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
570 
571 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
572 			    "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
573 			    i, info->pa_bias_trim[i]);
574 	}
575 }
576 
577 static void rtw8922a_phycap_parsing_pad_bias_trim(struct rtw89_dev *rtwdev,
578 						  u8 *phycap_map)
579 {
580 	static const u32 pad_bias_trim_addr[RF_PATH_NUM_8922A] = {0x1708, 0x1735};
581 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
582 	u32 addr = rtwdev->chip->phycap_addr;
583 	u8 i;
584 
585 	for (i = 0; i < RF_PATH_NUM_8922A; i++) {
586 		info->pad_bias_trim[i] = phycap_map[pad_bias_trim_addr[i] - addr];
587 
588 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
589 			    "[PAD_BIAS][TRIM] path=%d pad_bias_trim=0x%x\n",
590 			    i, info->pad_bias_trim[i]);
591 	}
592 }
593 
594 static int rtw8922a_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
595 {
596 	rtw8922a_phycap_parsing_thermal_trim(rtwdev, phycap_map);
597 	rtw8922a_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
598 	rtw8922a_phycap_parsing_pad_bias_trim(rtwdev, phycap_map);
599 
600 	return 0;
601 }
602 
603 #ifdef CONFIG_PM
604 static const struct wiphy_wowlan_support rtw_wowlan_stub_8922a = {
605 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
606 	.n_patterns = RTW89_MAX_PATTERN_NUM,
607 	.pattern_max_len = RTW89_MAX_PATTERN_SIZE,
608 	.pattern_min_len = 1,
609 };
610 #endif
611 
612 static const struct rtw89_chip_ops rtw8922a_chip_ops = {
613 	.read_efuse		= rtw8922a_read_efuse,
614 	.read_phycap		= rtw8922a_read_phycap,
615 	.pwr_on_func		= rtw8922a_pwr_on_func,
616 	.pwr_off_func		= rtw8922a_pwr_off_func,
617 };
618 
619 const struct rtw89_chip_info rtw8922a_chip_info = {
620 	.chip_id		= RTL8922A,
621 	.chip_gen		= RTW89_CHIP_BE,
622 	.ops			= &rtw8922a_chip_ops,
623 	.mac_def		= &rtw89_mac_gen_be,
624 	.phy_def		= &rtw89_phy_gen_be,
625 	.fw_basename		= RTW8922A_FW_BASENAME,
626 	.fw_format_max		= RTW8922A_FW_FORMAT_MAX,
627 	.try_ce_fw		= false,
628 	.bbmcu_nr		= 1,
629 	.needed_fw_elms		= RTW89_BE_GEN_DEF_NEEDED_FW_ELEMENTS,
630 	.fifo_size		= 589824,
631 	.small_fifo_size	= false,
632 	.dle_scc_rsvd_size	= 0,
633 	.max_amsdu_limit	= 8000,
634 	.dis_2g_40m_ul_ofdma	= false,
635 	.rsvd_ple_ofst		= 0x8f800,
636 	.hfc_param_ini		= rtw8922a_hfc_param_ini_pcie,
637 	.dle_mem		= rtw8922a_dle_mem_pcie,
638 	.wde_qempty_acq_grpnum	= 4,
639 	.wde_qempty_mgq_grpsel	= 4,
640 	.rf_base_addr		= {0xe000, 0xf000},
641 	.pwr_on_seq		= NULL,
642 	.pwr_off_seq		= NULL,
643 	.bb_table		= NULL,
644 	.bb_gain_table		= NULL,
645 	.rf_table		= {},
646 	.nctl_table		= NULL,
647 	.nctl_post_table	= NULL,
648 	.dflt_parms		= NULL, /* load parm from fw */
649 	.rfe_parms_conf		= NULL, /* load parm from fw */
650 	.txpwr_factor_rf	= 2,
651 	.txpwr_factor_mac	= 1,
652 	.dig_table		= NULL,
653 	.tssi_dbw_table		= NULL,
654 	.support_chanctx_num	= 1,
655 	.support_bands		= BIT(NL80211_BAND_2GHZ) |
656 				  BIT(NL80211_BAND_5GHZ) |
657 				  BIT(NL80211_BAND_6GHZ),
658 	.support_unii4		= true,
659 	.ul_tb_waveform_ctrl	= false,
660 	.ul_tb_pwr_diff		= false,
661 	.hw_sec_hdr		= true,
662 	.rf_path_num		= 2,
663 	.tx_nss			= 2,
664 	.rx_nss			= 2,
665 	.acam_num		= 128,
666 	.bcam_num		= 20,
667 	.scam_num		= 32,
668 	.bacam_num		= 8,
669 	.bacam_dynamic_num	= 8,
670 	.bacam_ver		= RTW89_BACAM_V1,
671 	.ppdu_max_usr		= 16,
672 	.sec_ctrl_efuse_size	= 4,
673 	.physical_efuse_size	= 0x1300,
674 	.logical_efuse_size	= 0x70000,
675 	.limit_efuse_size	= 0x40000,
676 	.dav_phy_efuse_size	= 0,
677 	.dav_log_efuse_size	= 0,
678 	.efuse_blocks		= rtw8922a_efuse_blocks,
679 	.phycap_addr		= 0x1700,
680 	.phycap_size		= 0x38,
681 
682 	.ps_mode_supported	= BIT(RTW89_PS_MODE_RFOFF) |
683 				  BIT(RTW89_PS_MODE_CLK_GATED) |
684 				  BIT(RTW89_PS_MODE_PWR_GATED),
685 	.low_power_hci_modes	= 0,
686 	.hci_func_en_addr	= R_BE_HCI_FUNC_EN,
687 	.h2c_desc_size		= sizeof(struct rtw89_rxdesc_short_v2),
688 	.txwd_body_size		= sizeof(struct rtw89_txwd_body_v2),
689 	.txwd_info_size		= sizeof(struct rtw89_txwd_info_v2),
690 	.cfo_src_fd		= true,
691 	.cfo_hw_comp            = true,
692 	.dcfo_comp		= NULL,
693 	.dcfo_comp_sft		= 0,
694 	.imr_info		= NULL,
695 	.imr_dmac_table		= &rtw8922a_imr_dmac_table,
696 	.imr_cmac_table		= &rtw8922a_imr_cmac_table,
697 	.bss_clr_vld		= {R_BSS_CLR_VLD_V2, B_BSS_CLR_VLD0_V2},
698 	.bss_clr_map_reg	= R_BSS_CLR_MAP_V2,
699 	.dma_ch_mask		= 0,
700 #ifdef CONFIG_PM
701 	.wowlan_stub		= &rtw_wowlan_stub_8922a,
702 #endif
703 	.xtal_info		= NULL,
704 };
705 EXPORT_SYMBOL(rtw8922a_chip_info);
706 
707 MODULE_FIRMWARE(RTW8922A_MODULE_FIRMWARE);
708 MODULE_AUTHOR("Realtek Corporation");
709 MODULE_DESCRIPTION("Realtek 802.11be wireless 8922A driver");
710 MODULE_LICENSE("Dual BSD/GPL");
711