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