1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2022  Realtek Corporation
3  */
4 
5 #include "coex.h"
6 #include "debug.h"
7 #include "fw.h"
8 #include "mac.h"
9 #include "phy.h"
10 #include "reg.h"
11 #include "rtw8852c.h"
12 #include "rtw8852c_table.h"
13 
14 static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
15 	[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_mac_size.wde_size19,
16 			   &rtw89_mac_size.ple_size19, &rtw89_mac_size.wde_qt18,
17 			   &rtw89_mac_size.wde_qt18, &rtw89_mac_size.ple_qt46,
18 			   &rtw89_mac_size.ple_qt47},
19 	[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_mac_size.wde_size18,
20 			    &rtw89_mac_size.ple_size18, &rtw89_mac_size.wde_qt17,
21 			    &rtw89_mac_size.wde_qt17, &rtw89_mac_size.ple_qt44,
22 			    &rtw89_mac_size.ple_qt45},
23 	[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
24 			       NULL},
25 };
26 
27 static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
28 	R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
29 	R_AX_H2CREG_DATA3_V1
30 };
31 
32 static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
33 	R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1,
34 	R_AX_C2HREG_DATA3_V1
35 };
36 
37 static const struct rtw89_page_regs rtw8852c_page_regs = {
38 	.hci_fc_ctrl	= R_AX_HCI_FC_CTRL_V1,
39 	.ch_page_ctrl	= R_AX_CH_PAGE_CTRL_V1,
40 	.ach_page_ctrl	= R_AX_ACH0_PAGE_CTRL_V1,
41 	.ach_page_info	= R_AX_ACH0_PAGE_INFO_V1,
42 	.pub_page_info3	= R_AX_PUB_PAGE_INFO3_V1,
43 	.pub_page_ctrl1	= R_AX_PUB_PAGE_CTRL1_V1,
44 	.pub_page_ctrl2	= R_AX_PUB_PAGE_CTRL2_V1,
45 	.pub_page_info1	= R_AX_PUB_PAGE_INFO1_V1,
46 	.pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1,
47 	.wp_page_ctrl1	= R_AX_WP_PAGE_CTRL1_V1,
48 	.wp_page_ctrl2	= R_AX_WP_PAGE_CTRL2_V1,
49 	.wp_page_info1	= R_AX_WP_PAGE_INFO1_V1,
50 };
51 
52 static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
53 	R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
54 };
55 
56 static const struct rtw89_imr_info rtw8852c_imr_info = {
57 	.wdrls_imr_set		= B_AX_WDRLS_IMR_SET_V1,
58 	.wsec_imr_reg		= R_AX_SEC_ERROR_FLAG_IMR,
59 	.wsec_imr_set		= B_AX_TX_HANG_IMR | B_AX_RX_HANG_IMR,
60 	.mpdu_tx_imr_set	= B_AX_MPDU_TX_IMR_SET_V1,
61 	.mpdu_rx_imr_set	= B_AX_MPDU_RX_IMR_SET_V1,
62 	.sta_sch_imr_set	= B_AX_STA_SCHEDULER_IMR_SET,
63 	.txpktctl_imr_b0_reg	= R_AX_TXPKTCTL_B0_ERRFLAG_IMR,
64 	.txpktctl_imr_b0_clr	= B_AX_TXPKTCTL_IMR_B0_CLR_V1,
65 	.txpktctl_imr_b0_set	= B_AX_TXPKTCTL_IMR_B0_SET_V1,
66 	.txpktctl_imr_b1_reg	= R_AX_TXPKTCTL_B1_ERRFLAG_IMR,
67 	.txpktctl_imr_b1_clr	= B_AX_TXPKTCTL_IMR_B1_CLR_V1,
68 	.txpktctl_imr_b1_set	= B_AX_TXPKTCTL_IMR_B1_SET_V1,
69 	.wde_imr_clr		= B_AX_WDE_IMR_CLR_V1,
70 	.wde_imr_set		= B_AX_WDE_IMR_SET_V1,
71 	.ple_imr_clr		= B_AX_PLE_IMR_CLR_V1,
72 	.ple_imr_set		= B_AX_PLE_IMR_SET_V1,
73 	.host_disp_imr_clr	= B_AX_HOST_DISP_IMR_CLR_V1,
74 	.host_disp_imr_set	= B_AX_HOST_DISP_IMR_SET_V1,
75 	.cpu_disp_imr_clr	= B_AX_CPU_DISP_IMR_CLR_V1,
76 	.cpu_disp_imr_set	= B_AX_CPU_DISP_IMR_SET_V1,
77 	.other_disp_imr_clr	= B_AX_OTHER_DISP_IMR_CLR_V1,
78 	.other_disp_imr_set	= B_AX_OTHER_DISP_IMR_SET_V1,
79 	.bbrpt_chinfo_err_imr_reg = R_AX_BBRPT_CHINFO_ERR_IMR,
80 	.bbrpt_err_imr_set	= R_AX_BBRPT_CHINFO_IMR_SET_V1,
81 	.bbrpt_dfs_err_imr_reg	= R_AX_BBRPT_DFS_ERR_IMR,
82 	.ptcl_imr_clr		= B_AX_PTCL_IMR_CLR_V1,
83 	.ptcl_imr_set		= B_AX_PTCL_IMR_SET_V1,
84 	.cdma_imr_0_reg		= R_AX_RX_ERR_FLAG_IMR,
85 	.cdma_imr_0_clr		= B_AX_RX_ERR_IMR_CLR_V1,
86 	.cdma_imr_0_set		= B_AX_RX_ERR_IMR_SET_V1,
87 	.cdma_imr_1_reg		= R_AX_TX_ERR_FLAG_IMR,
88 	.cdma_imr_1_clr		= B_AX_TX_ERR_IMR_CLR_V1,
89 	.cdma_imr_1_set		= B_AX_TX_ERR_IMR_SET_V1,
90 	.phy_intf_imr_reg	= R_AX_PHYINFO_ERR_IMR_V1,
91 	.phy_intf_imr_clr	= B_AX_PHYINFO_IMR_CLR_V1,
92 	.phy_intf_imr_set	= B_AX_PHYINFO_IMR_SET_V1,
93 	.rmac_imr_reg		= R_AX_RX_ERR_IMR,
94 	.rmac_imr_clr		= B_AX_RMAC_IMR_CLR_V1,
95 	.rmac_imr_set		= B_AX_RMAC_IMR_SET_V1,
96 	.tmac_imr_reg		= R_AX_TRXPTCL_ERROR_INDICA_MASK,
97 	.tmac_imr_clr		= B_AX_TMAC_IMR_CLR_V1,
98 	.tmac_imr_set		= B_AX_TMAC_IMR_SET_V1,
99 };
100 
101 static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
102 {
103 	u32 val32;
104 	u32 ret;
105 
106 	val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
107 	if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
108 		rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
109 
110 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
111 						    B_AX_AFSM_PCIE_SUS_EN);
112 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
113 	rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
114 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
115 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
116 
117 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
118 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
119 	if (ret)
120 		return ret;
121 
122 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
123 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
124 
125 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
126 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
127 	if (ret)
128 		return ret;
129 
130 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
131 	rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
132 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
133 	rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
134 
135 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
136 	rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
137 
138 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
139 	rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
140 	rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN |
141 						  B_AX_R_SYM_WLCMAC1_P3_PC_EN |
142 						  B_AX_R_SYM_WLCMAC1_P2_PC_EN |
143 						  B_AX_R_SYM_WLCMAC1_P1_PC_EN |
144 						  B_AX_R_SYM_WLCMAC1_PC_EN);
145 	rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
146 
147 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
148 				      XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
149 	if (ret)
150 		return ret;
151 
152 	rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
153 
154 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
155 				      XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
156 	if (ret)
157 		return ret;
158 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
159 				      XTAL_SI_OFF_WEI);
160 	if (ret)
161 		return ret;
162 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
163 				      XTAL_SI_OFF_EI);
164 	if (ret)
165 		return ret;
166 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF);
167 	if (ret)
168 		return ret;
169 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
170 				      XTAL_SI_PON_WEI);
171 	if (ret)
172 		return ret;
173 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
174 				      XTAL_SI_PON_EI);
175 	if (ret)
176 		return ret;
177 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
178 	if (ret)
179 		return ret;
180 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
181 	if (ret)
182 		return ret;
183 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
184 	if (ret)
185 		return ret;
186 
187 	rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
188 	rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
189 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
190 
191 	fsleep(1000);
192 
193 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
194 	rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
195 	rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
196 			  B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
197 			  B_AX_LED1_PULL_LOW_EN);
198 
199 	rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
200 			  B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
201 			  B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
202 			  B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
203 			  B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
204 			  B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
205 			  B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN);
206 
207 	rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
208 			  B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
209 			  B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN |
210 			  B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
211 			  B_AX_TMAC_EN | B_AX_RMAC_EN);
212 
213 	return 0;
214 }
215 
216 static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
217 {
218 	u32 val32;
219 	u32 ret;
220 
221 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
222 				      XTAL_SI_RFC2RF);
223 	if (ret)
224 		return ret;
225 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI);
226 	if (ret)
227 		return ret;
228 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI);
229 	if (ret)
230 		return ret;
231 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00);
232 	if (ret)
233 		return ret;
234 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10);
235 	if (ret)
236 		return ret;
237 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
238 				      XTAL_SI_SRAM2RFC);
239 	if (ret)
240 		return ret;
241 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI);
242 	if (ret)
243 		return ret;
244 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI);
245 	if (ret)
246 		return ret;
247 
248 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
249 	rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
250 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
251 			  B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
252 	rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
253 
254 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL);
255 	if (ret)
256 		return ret;
257 
258 	rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
259 
260 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL);
261 	if (ret)
262 		return ret;
263 
264 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
265 
266 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
267 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
268 	if (ret)
269 		return ret;
270 
271 	rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
272 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
273 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
274 
275 	return 0;
276 }
277 
278 static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
279 				     struct rtw8852c_efuse *map)
280 {
281 	ether_addr_copy(efuse->addr, map->e.mac_addr);
282 	efuse->rfe_type = map->rfe_type;
283 	efuse->xtal_cap = map->xtal_k;
284 }
285 
286 static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
287 					struct rtw8852c_efuse *map)
288 {
289 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
290 	struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
291 	u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
292 	u8 i, j;
293 
294 	tssi->thermal[RF_PATH_A] = map->path_a_therm;
295 	tssi->thermal[RF_PATH_B] = map->path_b_therm;
296 
297 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
298 		memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
299 		       sizeof(ofst[i]->cck_tssi));
300 
301 		for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
302 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
303 				    "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
304 				    i, j, tssi->tssi_cck[i][j]);
305 
306 		memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
307 		       sizeof(ofst[i]->bw40_tssi));
308 		memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
309 		       ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
310 		memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
311 		       sizeof(tssi->tssi_6g_mcs[i]));
312 
313 		for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
314 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
315 				    "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
316 				    i, j, tssi->tssi_mcs[i][j]);
317 	}
318 }
319 
320 static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map)
321 {
322 	struct rtw89_efuse *efuse = &rtwdev->efuse;
323 	struct rtw8852c_efuse *map;
324 
325 	map = (struct rtw8852c_efuse *)log_map;
326 
327 	efuse->country_code[0] = map->country_code[0];
328 	efuse->country_code[1] = map->country_code[1];
329 	rtw8852c_efuse_parsing_tssi(rtwdev, map);
330 
331 	switch (rtwdev->hci.type) {
332 	case RTW89_HCI_TYPE_PCIE:
333 		rtw8852c_e_efuse_parsing(efuse, map);
334 		break;
335 	default:
336 		return -ENOTSUPP;
337 	}
338 
339 	rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
340 
341 	return 0;
342 }
343 
344 static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
345 {
346 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
347 	static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
348 	static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
349 	u32 addr = rtwdev->chip->phycap_addr;
350 	bool pg = false;
351 	u32 ofst;
352 	u8 i, j;
353 
354 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
355 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
356 			/* addrs are in decreasing order */
357 			ofst = tssi_trim_addr[i] - addr - j;
358 			tssi->tssi_trim[i][j] = phycap_map[ofst];
359 
360 			if (phycap_map[ofst] != 0xff)
361 				pg = true;
362 		}
363 
364 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
365 			/* addrs are in decreasing order */
366 			ofst = tssi_trim_addr_6g[i] - addr - j;
367 			tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
368 
369 			if (phycap_map[ofst] != 0xff)
370 				pg = true;
371 		}
372 	}
373 
374 	if (!pg) {
375 		memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
376 		memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
377 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
378 			    "[TSSI][TRIM] no PG, set all trim info to 0\n");
379 	}
380 
381 	for (i = 0; i < RF_PATH_NUM_8852C; i++)
382 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
383 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
384 				    "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
385 				    i, j, tssi->tssi_trim[i][j],
386 				    tssi_trim_addr[i] - j);
387 }
388 
389 static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
390 						 u8 *phycap_map)
391 {
392 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
393 	static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
394 	u32 addr = rtwdev->chip->phycap_addr;
395 	u8 i;
396 
397 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
398 		info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
399 
400 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
401 			    "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
402 			    i, info->thermal_trim[i]);
403 
404 		if (info->thermal_trim[i] != 0xff)
405 			info->pg_thermal_trim = true;
406 	}
407 }
408 
409 static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
410 {
411 #define __thm_setting(raw)				\
412 ({							\
413 	u8 __v = (raw);					\
414 	((__v & 0x1) << 3) | ((__v & 0x1f) >> 1);	\
415 })
416 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
417 	u8 i, val;
418 
419 	if (!info->pg_thermal_trim) {
420 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
421 			    "[THERMAL][TRIM] no PG, do nothing\n");
422 
423 		return;
424 	}
425 
426 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
427 		val = __thm_setting(info->thermal_trim[i]);
428 		rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
429 
430 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
431 			    "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
432 			    i, val);
433 	}
434 #undef __thm_setting
435 }
436 
437 static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
438 						 u8 *phycap_map)
439 {
440 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
441 	static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
442 	u32 addr = rtwdev->chip->phycap_addr;
443 	u8 i;
444 
445 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
446 		info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
447 
448 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
449 			    "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
450 			    i, info->pa_bias_trim[i]);
451 
452 		if (info->pa_bias_trim[i] != 0xff)
453 			info->pg_pa_bias_trim = true;
454 	}
455 }
456 
457 static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
458 {
459 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
460 	u8 pabias_2g, pabias_5g;
461 	u8 i;
462 
463 	if (!info->pg_pa_bias_trim) {
464 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
465 			    "[PA_BIAS][TRIM] no PG, do nothing\n");
466 
467 		return;
468 	}
469 
470 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
471 		pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
472 		pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
473 
474 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
475 			    "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
476 			    i, pabias_2g, pabias_5g);
477 
478 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
479 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
480 	}
481 }
482 
483 static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
484 {
485 	rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
486 	rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
487 	rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
488 
489 	return 0;
490 }
491 
492 static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
493 {
494 	rtw8852c_thermal_trim(rtwdev);
495 	rtw8852c_pa_bias_trim(rtwdev);
496 }
497 
498 static
499 void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
500 				     s8 pw_ofst, enum rtw89_mac_idx mac_idx)
501 {
502 	s8 pw_ofst_2tx;
503 	s8 val_1t;
504 	s8 val_2t;
505 	u32 reg;
506 	u8 i;
507 
508 	if (pw_ofst < -32 || pw_ofst > 31) {
509 		rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
510 		return;
511 	}
512 	val_1t = pw_ofst << 2;
513 	pw_ofst_2tx = max(pw_ofst - 3, -32);
514 	val_2t = pw_ofst_2tx << 2;
515 
516 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t);
517 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t);
518 
519 	for (i = 0; i < 4; i++) {
520 		/* 1TX */
521 		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
522 		rtw89_write32_mask(rtwdev, reg,
523 				   B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
524 				   val_1t);
525 		/* 2TX */
526 		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
527 		rtw89_write32_mask(rtwdev, reg,
528 				   B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
529 				   val_2t);
530 	}
531 }
532 
533 static
534 void rtw8852c_set_trx_mask(struct rtw89_dev *rtwdev, u8 path, u8 group, u32 val)
535 {
536 	rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x20000);
537 	rtw89_write_rf(rtwdev, path, RR_LUTWA, RFREG_MASK, group);
538 	rtw89_write_rf(rtwdev, path, RR_LUTWD0, RFREG_MASK, val);
539 	rtw89_write_rf(rtwdev, path, RR_LUTWE, RFREG_MASK, 0x0);
540 }
541 
542 static void rtw8852c_btc_init_cfg(struct rtw89_dev *rtwdev)
543 {
544 	struct rtw89_btc *btc = &rtwdev->btc;
545 	struct rtw89_btc_module *module = &btc->mdinfo;
546 	const struct rtw89_chip_info *chip = rtwdev->chip;
547 	const struct rtw89_mac_ax_coex coex_params = {
548 		.pta_mode = RTW89_MAC_AX_COEX_RTK_MODE,
549 		.direction = RTW89_MAC_AX_COEX_INNER,
550 	};
551 
552 	/* PTA init  */
553 	rtw89_mac_coex_init_v1(rtwdev, &coex_params);
554 
555 	/* set WL Tx response = Hi-Pri */
556 	chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_TX_RESP, true);
557 	chip->ops->btc_set_wl_pri(rtwdev, BTC_PRI_MASK_BEACON, true);
558 
559 	/* set rf gnt debug off */
560 	rtw89_write_rf(rtwdev, RF_PATH_A, RR_WLSEL, RFREG_MASK, 0x0);
561 	rtw89_write_rf(rtwdev, RF_PATH_B, RR_WLSEL, RFREG_MASK, 0x0);
562 
563 	/* set WL Tx thru in TRX mask table if GNT_WL = 0 && BT_S1 = ss group */
564 	if (module->ant.type == BTC_ANT_SHARED) {
565 		rtw8852c_set_trx_mask(rtwdev,
566 				      RF_PATH_A, BTC_BT_SS_GROUP, 0x5ff);
567 		rtw8852c_set_trx_mask(rtwdev,
568 				      RF_PATH_B, BTC_BT_SS_GROUP, 0x5ff);
569 		/* set path-A(S0) Tx/Rx no-mask if GNT_WL=0 && BT_S1=tx group */
570 		rtw8852c_set_trx_mask(rtwdev,
571 				      RF_PATH_A, BTC_BT_TX_GROUP, 0x5ff);
572 	} else { /* set WL Tx stb if GNT_WL = 0 && BT_S1 = ss group for 3-ant */
573 		rtw8852c_set_trx_mask(rtwdev,
574 				      RF_PATH_A, BTC_BT_SS_GROUP, 0x5df);
575 		rtw8852c_set_trx_mask(rtwdev,
576 				      RF_PATH_B, BTC_BT_SS_GROUP, 0x5df);
577 	}
578 
579 	/* set PTA break table */
580 	rtw89_write32(rtwdev, R_AX_BT_BREAK_TABLE, BTC_BREAK_PARAM);
581 
582 	 /* enable BT counter 0xda10[1:0] = 2b'11 */
583 	rtw89_write32_set(rtwdev,
584 			  R_AX_BT_CNT_CFG, B_AX_BT_CNT_EN |
585 			  B_AX_BT_CNT_RST_V1);
586 	btc->cx.wl.status.map.init_ok = true;
587 }
588 
589 static int rtw8852c_mac_enable_bb_rf(struct rtw89_dev *rtwdev)
590 {
591 	int ret;
592 
593 	rtw89_write8_set(rtwdev, R_AX_SYS_FUNC_EN,
594 			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
595 
596 	rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
597 	rtw89_write32_clr(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
598 	rtw89_write32_set(rtwdev, R_AX_WLRF_CTRL, B_AX_AFC_AFEDIG);
599 
600 	rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S0_LDO_VSEL_F_MASK, 0x1);
601 	rtw89_write32_mask(rtwdev, R_AX_AFE_OFF_CTRL1, B_AX_S1_LDO_VSEL_F_MASK, 0x1);
602 
603 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL0, 0x7, FULL_BIT_MASK);
604 	if (ret)
605 		return ret;
606 
607 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0x6c, FULL_BIT_MASK);
608 	if (ret)
609 		return ret;
610 
611 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0xc7, FULL_BIT_MASK);
612 	if (ret)
613 		return ret;
614 
615 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0xc7, FULL_BIT_MASK);
616 	if (ret)
617 		return ret;
618 
619 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL3, 0xd, FULL_BIT_MASK);
620 	if (ret)
621 		return ret;
622 
623 	return 0;
624 }
625 
626 static void rtw8852c_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
627 {
628 	rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN,
629 			 B_AX_FEN_BBRSTB | B_AX_FEN_BB_GLB_RSTN);
630 }
631 
632 static const struct rtw89_chip_ops rtw8852c_chip_ops = {
633 	.enable_bb_rf		= rtw8852c_mac_enable_bb_rf,
634 	.disable_bb_rf		= rtw8852c_mac_disable_bb_rf,
635 	.read_efuse		= rtw8852c_read_efuse,
636 	.read_phycap		= rtw8852c_read_phycap,
637 	.power_trim		= rtw8852c_power_trim,
638 	.read_rf		= rtw89_phy_read_rf_v1,
639 	.write_rf		= rtw89_phy_write_rf_v1,
640 	.set_txpwr_ul_tb_offset	= rtw8852c_set_txpwr_ul_tb_offset,
641 	.pwr_on_func		= rtw8852c_pwr_on_func,
642 	.pwr_off_func		= rtw8852c_pwr_off_func,
643 	.fill_txdesc		= rtw89_core_fill_txdesc_v1,
644 	.fill_txdesc_fwcmd	= rtw89_core_fill_txdesc_fwcmd_v1,
645 	.cfg_ctrl_path		= rtw89_mac_cfg_ctrl_path_v1,
646 	.mac_cfg_gnt		= rtw89_mac_cfg_gnt_v1,
647 	.stop_sch_tx		= rtw89_mac_stop_sch_tx_v1,
648 	.resume_sch_tx		= rtw89_mac_resume_sch_tx_v1,
649 	.h2c_dctl_sec_cam	= rtw89_fw_h2c_dctl_sec_cam_v1,
650 
651 	.btc_init_cfg		= rtw8852c_btc_init_cfg,
652 };
653 
654 const struct rtw89_chip_info rtw8852c_chip_info = {
655 	.chip_id		= RTL8852C,
656 	.ops			= &rtw8852c_chip_ops,
657 	.fw_name		= "rtw89/rtw8852c_fw.bin",
658 	.dle_mem		= rtw8852c_dle_mem_pcie,
659 	.rf_base_addr		= {0xe000, 0xf000},
660 	.pwr_on_seq		= NULL,
661 	.pwr_off_seq		= NULL,
662 	.bb_table		= &rtw89_8852c_phy_bb_table,
663 	.bb_gain_table		= &rtw89_8852c_phy_bb_gain_table,
664 	.rf_table		= {&rtw89_8852c_phy_radiob_table,
665 				   &rtw89_8852c_phy_radioa_table,},
666 	.nctl_table		= &rtw89_8852c_phy_nctl_table,
667 	.byr_table		= &rtw89_8852c_byr_table,
668 	.txpwr_lmt_2g		= &rtw89_8852c_txpwr_lmt_2g,
669 	.txpwr_lmt_5g		= &rtw89_8852c_txpwr_lmt_5g,
670 	.txpwr_lmt_6g		= &rtw89_8852c_txpwr_lmt_6g,
671 	.txpwr_lmt_ru_2g	= &rtw89_8852c_txpwr_lmt_ru_2g,
672 	.txpwr_lmt_ru_5g	= &rtw89_8852c_txpwr_lmt_ru_5g,
673 	.txpwr_lmt_ru_6g	= &rtw89_8852c_txpwr_lmt_ru_6g,
674 	.txpwr_factor_rf	= 2,
675 	.txpwr_factor_mac	= 1,
676 	.dig_table		= NULL,
677 	.hw_sec_hdr		= true,
678 	.sec_ctrl_efuse_size	= 4,
679 	.physical_efuse_size	= 1216,
680 	.logical_efuse_size	= 2048,
681 	.limit_efuse_size	= 1280,
682 	.dav_phy_efuse_size	= 96,
683 	.dav_log_efuse_size	= 16,
684 	.phycap_addr		= 0x590,
685 	.phycap_size		= 0x60,
686 	.h2c_cctl_func_id	= H2C_FUNC_MAC_CCTLINFO_UD_V1,
687 	.hci_func_en_addr	= R_AX_HCI_FUNC_EN_V1,
688 	.h2c_desc_size		= sizeof(struct rtw89_rxdesc_short),
689 	.txwd_body_size		= sizeof(struct rtw89_txwd_body_v1),
690 	.h2c_ctrl_reg		= R_AX_H2CREG_CTRL_V1,
691 	.h2c_regs		= rtw8852c_h2c_regs,
692 	.c2h_ctrl_reg		= R_AX_C2HREG_CTRL_V1,
693 	.c2h_regs		= rtw8852c_c2h_regs,
694 	.page_regs		= &rtw8852c_page_regs,
695 	.dcfo_comp		= &rtw8852c_dcfo_comp,
696 	.dcfo_comp_sft		= 5,
697 	.imr_info		= &rtw8852c_imr_info
698 };
699 EXPORT_SYMBOL(rtw8852c_chip_info);
700 
701 MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
702 MODULE_AUTHOR("Realtek Corporation");
703 MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
704 MODULE_LICENSE("Dual BSD/GPL");
705