1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2022  Realtek Corporation
3  */
4 
5 #include "debug.h"
6 #include "fw.h"
7 #include "mac.h"
8 #include "phy.h"
9 #include "reg.h"
10 #include "rtw8852c.h"
11 
12 static const struct rtw89_dle_mem rtw8852c_dle_mem_pcie[] = {
13 	[RTW89_QTA_SCC] = {RTW89_QTA_SCC, &rtw89_wde_size19, &rtw89_ple_size19,
14 			   &rtw89_wde_qt18, &rtw89_wde_qt18, &rtw89_ple_qt46,
15 			   &rtw89_ple_qt47},
16 	[RTW89_QTA_DLFW] = {RTW89_QTA_DLFW, &rtw89_wde_size18,
17 			    &rtw89_ple_size18, &rtw89_wde_qt17, &rtw89_wde_qt17,
18 			    &rtw89_ple_qt44, &rtw89_ple_qt45},
19 	[RTW89_QTA_INVALID] = {RTW89_QTA_INVALID, NULL, NULL, NULL, NULL, NULL,
20 			       NULL},
21 };
22 
23 static const u32 rtw8852c_h2c_regs[RTW89_H2CREG_MAX] = {
24 	R_AX_H2CREG_DATA0_V1, R_AX_H2CREG_DATA1_V1, R_AX_H2CREG_DATA2_V1,
25 	R_AX_H2CREG_DATA3_V1
26 };
27 
28 static const u32 rtw8852c_c2h_regs[RTW89_H2CREG_MAX] = {
29 	R_AX_C2HREG_DATA0_V1, R_AX_C2HREG_DATA1_V1, R_AX_C2HREG_DATA2_V1,
30 	R_AX_C2HREG_DATA3_V1
31 };
32 
33 static const struct rtw89_page_regs rtw8852c_page_regs = {
34 	.hci_fc_ctrl	= R_AX_HCI_FC_CTRL_V1,
35 	.ch_page_ctrl	= R_AX_CH_PAGE_CTRL_V1,
36 	.ach_page_ctrl	= R_AX_ACH0_PAGE_CTRL_V1,
37 	.ach_page_info	= R_AX_ACH0_PAGE_INFO_V1,
38 	.pub_page_info3	= R_AX_PUB_PAGE_INFO3_V1,
39 	.pub_page_ctrl1	= R_AX_PUB_PAGE_CTRL1_V1,
40 	.pub_page_ctrl2	= R_AX_PUB_PAGE_CTRL2_V1,
41 	.pub_page_info1	= R_AX_PUB_PAGE_INFO1_V1,
42 	.pub_page_info2 = R_AX_PUB_PAGE_INFO2_V1,
43 	.wp_page_ctrl1	= R_AX_WP_PAGE_CTRL1_V1,
44 	.wp_page_ctrl2	= R_AX_WP_PAGE_CTRL2_V1,
45 	.wp_page_info1	= R_AX_WP_PAGE_INFO1_V1,
46 };
47 
48 static const struct rtw89_reg_def rtw8852c_dcfo_comp = {
49 	R_DCFO_COMP_S0_V1, B_DCFO_COMP_S0_V1_MSK
50 };
51 
52 static int rtw8852c_pwr_on_func(struct rtw89_dev *rtwdev)
53 {
54 	u32 val32;
55 	u32 ret;
56 
57 	val32 = rtw89_read32_mask(rtwdev, R_AX_SYS_STATUS1, B_AX_PAD_HCI_SEL_V2_MASK);
58 	if (val32 == MAC_AX_HCI_SEL_PCIE_USB)
59 		rtw89_write32_set(rtwdev, R_AX_LDO_AON_CTRL0, B_AX_PD_REGU_L);
60 
61 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_AFSM_WLSUS_EN |
62 						    B_AX_AFSM_PCIE_SUS_EN);
63 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_DIS_WLBT_PDNSUSEN_SOPC);
64 	rtw89_write32_set(rtwdev, R_AX_WLLPS_CTRL, B_AX_DIS_WLBT_LPSEN_LOPC);
65 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APDM_HPDN);
66 	rtw89_write32_clr(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
67 
68 	ret = read_poll_timeout(rtw89_read32, val32, val32 & B_AX_RDY_SYSPWR,
69 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
70 	if (ret)
71 		return ret;
72 
73 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
74 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFN_ONMAC);
75 
76 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFN_ONMAC),
77 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
78 	if (ret)
79 		return ret;
80 
81 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
82 	rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
83 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
84 	rtw89_write8_clr(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
85 
86 	rtw89_write8_set(rtwdev, R_AX_PLATFORM_ENABLE, B_AX_PLATFORM_EN);
87 	rtw89_write32_clr(rtwdev, R_AX_SYS_SDIO_CTRL, B_AX_PCIE_CALIB_EN_V1);
88 
89 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_CMAC1_FEN);
90 	rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND, B_AX_R_SYM_ISO_CMAC12PP);
91 	rtw89_write32_clr(rtwdev, R_AX_AFE_CTRL1, B_AX_R_SYM_WLCMAC1_P4_PC_EN |
92 						  B_AX_R_SYM_WLCMAC1_P3_PC_EN |
93 						  B_AX_R_SYM_WLCMAC1_P2_PC_EN |
94 						  B_AX_R_SYM_WLCMAC1_P1_PC_EN |
95 						  B_AX_R_SYM_WLCMAC1_PC_EN);
96 	rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
97 
98 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
99 				      XTAL_SI_GND_SHDN_WL, XTAL_SI_GND_SHDN_WL);
100 	if (ret)
101 		return ret;
102 
103 	rtw89_write32_set(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
104 
105 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL,
106 				      XTAL_SI_SHDN_WL, XTAL_SI_SHDN_WL);
107 	if (ret)
108 		return ret;
109 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_WEI,
110 				      XTAL_SI_OFF_WEI);
111 	if (ret)
112 		return ret;
113 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_OFF_EI,
114 				      XTAL_SI_OFF_EI);
115 	if (ret)
116 		return ret;
117 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_RFC2RF);
118 	if (ret)
119 		return ret;
120 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_WEI,
121 				      XTAL_SI_PON_WEI);
122 	if (ret)
123 		return ret;
124 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_PON_EI,
125 				      XTAL_SI_PON_EI);
126 	if (ret)
127 		return ret;
128 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SRAM2RFC);
129 	if (ret)
130 		return ret;
131 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_2, 0, XTAL_SI_LDO_LPS);
132 	if (ret)
133 		return ret;
134 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_XMD_4, 0, XTAL_SI_LPS_CAP);
135 	if (ret)
136 		return ret;
137 
138 	rtw89_write32_set(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
139 	rtw89_write32_set(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_ISO_EB2CORE);
140 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B15);
141 
142 	fsleep(1000);
143 
144 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL, B_AX_PWC_EV2EF_B14);
145 	rtw89_write32_clr(rtwdev, R_AX_PMC_DBG_CTRL2, B_AX_SYSON_DIS_PMCR_AX_WRMSK);
146 	rtw89_write32_set(rtwdev, R_AX_GPIO0_15_EECS_EESK_LED1_PULL_LOW_EN,
147 			  B_AX_EECS_PULL_LOW_EN | B_AX_EESK_PULL_LOW_EN |
148 			  B_AX_LED1_PULL_LOW_EN);
149 
150 	rtw89_write32_set(rtwdev, R_AX_DMAC_FUNC_EN,
151 			  B_AX_MAC_FUNC_EN | B_AX_DMAC_FUNC_EN | B_AX_MPDU_PROC_EN |
152 			  B_AX_WD_RLS_EN | B_AX_DLE_WDE_EN | B_AX_TXPKT_CTRL_EN |
153 			  B_AX_STA_SCH_EN | B_AX_DLE_PLE_EN | B_AX_PKT_BUF_EN |
154 			  B_AX_DMAC_TBL_EN | B_AX_PKT_IN_EN | B_AX_DLE_CPUIO_EN |
155 			  B_AX_DISPATCHER_EN | B_AX_BBRPT_EN | B_AX_MAC_SEC_EN |
156 			  B_AX_MAC_UN_EN | B_AX_H_AXIDMA_EN);
157 
158 	rtw89_write32_set(rtwdev, R_AX_CMAC_FUNC_EN,
159 			  B_AX_CMAC_EN | B_AX_CMAC_TXEN | B_AX_CMAC_RXEN |
160 			  B_AX_FORCE_CMACREG_GCKEN | B_AX_PHYINTF_EN |
161 			  B_AX_CMAC_DMA_EN | B_AX_PTCLTOP_EN | B_AX_SCHEDULER_EN |
162 			  B_AX_TMAC_EN | B_AX_RMAC_EN);
163 
164 	return 0;
165 }
166 
167 static int rtw8852c_pwr_off_func(struct rtw89_dev *rtwdev)
168 {
169 	u32 val32;
170 	u32 ret;
171 
172 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_RFC2RF,
173 				      XTAL_SI_RFC2RF);
174 	if (ret)
175 		return ret;
176 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_EI);
177 	if (ret)
178 		return ret;
179 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_OFF_WEI);
180 	if (ret)
181 		return ret;
182 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S0, 0, XTAL_SI_RF00);
183 	if (ret)
184 		return ret;
185 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_WL_RFC_S1, 0, XTAL_SI_RF10);
186 	if (ret)
187 		return ret;
188 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, XTAL_SI_SRAM2RFC,
189 				      XTAL_SI_SRAM2RFC);
190 	if (ret)
191 		return ret;
192 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_EI);
193 	if (ret)
194 		return ret;
195 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_PON_WEI);
196 	if (ret)
197 		return ret;
198 
199 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_EN_WLON);
200 	rtw89_write8_clr(rtwdev, R_AX_SYS_FUNC_EN, B_AX_FEN_BB_GLB_RSTN | B_AX_FEN_BBRSTB);
201 	rtw89_write32_clr(rtwdev, R_AX_SYS_ISO_CTRL_EXTEND,
202 			  B_AX_R_SYM_FEN_WLBBGLB_1 | B_AX_R_SYM_FEN_WLBBFUN_1);
203 	rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_RFC_1P3);
204 
205 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_SHDN_WL);
206 	if (ret)
207 		return ret;
208 
209 	rtw89_write32_clr(rtwdev, R_AX_SYS_ADIE_PAD_PWR_CTRL, B_AX_SYM_PADPDN_WL_PTA_1P3);
210 
211 	ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_ANAPAR_WL, 0, XTAL_SI_GND_SHDN_WL);
212 	if (ret)
213 		return ret;
214 
215 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_OFFMAC);
216 
217 	ret = read_poll_timeout(rtw89_read32, val32, !(val32 & B_AX_APFM_OFFMAC),
218 				1000, 20000, false, rtwdev, R_AX_SYS_PW_CTRL);
219 	if (ret)
220 		return ret;
221 
222 	rtw89_write32(rtwdev, R_AX_WLLPS_CTRL, 0x0001A0B0);
223 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_XTAL_OFF_A_DIE);
224 	rtw89_write32_set(rtwdev, R_AX_SYS_PW_CTRL, B_AX_APFM_SWLPS);
225 
226 	return 0;
227 }
228 
229 static void rtw8852c_e_efuse_parsing(struct rtw89_efuse *efuse,
230 				     struct rtw8852c_efuse *map)
231 {
232 	ether_addr_copy(efuse->addr, map->e.mac_addr);
233 	efuse->rfe_type = map->rfe_type;
234 	efuse->xtal_cap = map->xtal_k;
235 }
236 
237 static void rtw8852c_efuse_parsing_tssi(struct rtw89_dev *rtwdev,
238 					struct rtw8852c_efuse *map)
239 {
240 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
241 	struct rtw8852c_tssi_offset *ofst[] = {&map->path_a_tssi, &map->path_b_tssi};
242 	u8 *bw40_1s_tssi_6g_ofst[] = {map->bw40_1s_tssi_6g_a, map->bw40_1s_tssi_6g_b};
243 	u8 i, j;
244 
245 	tssi->thermal[RF_PATH_A] = map->path_a_therm;
246 	tssi->thermal[RF_PATH_B] = map->path_b_therm;
247 
248 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
249 		memcpy(tssi->tssi_cck[i], ofst[i]->cck_tssi,
250 		       sizeof(ofst[i]->cck_tssi));
251 
252 		for (j = 0; j < TSSI_CCK_CH_GROUP_NUM; j++)
253 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
254 				    "[TSSI][EFUSE] path=%d cck[%d]=0x%x\n",
255 				    i, j, tssi->tssi_cck[i][j]);
256 
257 		memcpy(tssi->tssi_mcs[i], ofst[i]->bw40_tssi,
258 		       sizeof(ofst[i]->bw40_tssi));
259 		memcpy(tssi->tssi_mcs[i] + TSSI_MCS_2G_CH_GROUP_NUM,
260 		       ofst[i]->bw40_1s_tssi_5g, sizeof(ofst[i]->bw40_1s_tssi_5g));
261 		memcpy(tssi->tssi_6g_mcs[i], bw40_1s_tssi_6g_ofst[i],
262 		       sizeof(tssi->tssi_6g_mcs[i]));
263 
264 		for (j = 0; j < TSSI_MCS_CH_GROUP_NUM; j++)
265 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
266 				    "[TSSI][EFUSE] path=%d mcs[%d]=0x%x\n",
267 				    i, j, tssi->tssi_mcs[i][j]);
268 	}
269 }
270 
271 static int rtw8852c_read_efuse(struct rtw89_dev *rtwdev, u8 *log_map)
272 {
273 	struct rtw89_efuse *efuse = &rtwdev->efuse;
274 	struct rtw8852c_efuse *map;
275 
276 	map = (struct rtw8852c_efuse *)log_map;
277 
278 	efuse->country_code[0] = map->country_code[0];
279 	efuse->country_code[1] = map->country_code[1];
280 	rtw8852c_efuse_parsing_tssi(rtwdev, map);
281 
282 	switch (rtwdev->hci.type) {
283 	case RTW89_HCI_TYPE_PCIE:
284 		rtw8852c_e_efuse_parsing(efuse, map);
285 		break;
286 	default:
287 		return -ENOTSUPP;
288 	}
289 
290 	rtw89_info(rtwdev, "chip rfe_type is %d\n", efuse->rfe_type);
291 
292 	return 0;
293 }
294 
295 static void rtw8852c_phycap_parsing_tssi(struct rtw89_dev *rtwdev, u8 *phycap_map)
296 {
297 	struct rtw89_tssi_info *tssi = &rtwdev->tssi;
298 	static const u32 tssi_trim_addr[RF_PATH_NUM_8852C] = {0x5D6, 0x5AB};
299 	static const u32 tssi_trim_addr_6g[RF_PATH_NUM_8852C] = {0x5CE, 0x5A3};
300 	u32 addr = rtwdev->chip->phycap_addr;
301 	bool pg = false;
302 	u32 ofst;
303 	u8 i, j;
304 
305 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
306 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++) {
307 			/* addrs are in decreasing order */
308 			ofst = tssi_trim_addr[i] - addr - j;
309 			tssi->tssi_trim[i][j] = phycap_map[ofst];
310 
311 			if (phycap_map[ofst] != 0xff)
312 				pg = true;
313 		}
314 
315 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM_6G; j++) {
316 			/* addrs are in decreasing order */
317 			ofst = tssi_trim_addr_6g[i] - addr - j;
318 			tssi->tssi_trim_6g[i][j] = phycap_map[ofst];
319 
320 			if (phycap_map[ofst] != 0xff)
321 				pg = true;
322 		}
323 	}
324 
325 	if (!pg) {
326 		memset(tssi->tssi_trim, 0, sizeof(tssi->tssi_trim));
327 		memset(tssi->tssi_trim_6g, 0, sizeof(tssi->tssi_trim_6g));
328 		rtw89_debug(rtwdev, RTW89_DBG_TSSI,
329 			    "[TSSI][TRIM] no PG, set all trim info to 0\n");
330 	}
331 
332 	for (i = 0; i < RF_PATH_NUM_8852C; i++)
333 		for (j = 0; j < TSSI_TRIM_CH_GROUP_NUM; j++)
334 			rtw89_debug(rtwdev, RTW89_DBG_TSSI,
335 				    "[TSSI] path=%d idx=%d trim=0x%x addr=0x%x\n",
336 				    i, j, tssi->tssi_trim[i][j],
337 				    tssi_trim_addr[i] - j);
338 }
339 
340 static void rtw8852c_phycap_parsing_thermal_trim(struct rtw89_dev *rtwdev,
341 						 u8 *phycap_map)
342 {
343 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
344 	static const u32 thm_trim_addr[RF_PATH_NUM_8852C] = {0x5DF, 0x5DC};
345 	u32 addr = rtwdev->chip->phycap_addr;
346 	u8 i;
347 
348 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
349 		info->thermal_trim[i] = phycap_map[thm_trim_addr[i] - addr];
350 
351 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
352 			    "[THERMAL][TRIM] path=%d thermal_trim=0x%x\n",
353 			    i, info->thermal_trim[i]);
354 
355 		if (info->thermal_trim[i] != 0xff)
356 			info->pg_thermal_trim = true;
357 	}
358 }
359 
360 static void rtw8852c_thermal_trim(struct rtw89_dev *rtwdev)
361 {
362 #define __thm_setting(raw)				\
363 ({							\
364 	u8 __v = (raw);					\
365 	((__v & 0x1) << 3) | ((__v & 0x1f) >> 1);	\
366 })
367 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
368 	u8 i, val;
369 
370 	if (!info->pg_thermal_trim) {
371 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
372 			    "[THERMAL][TRIM] no PG, do nothing\n");
373 
374 		return;
375 	}
376 
377 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
378 		val = __thm_setting(info->thermal_trim[i]);
379 		rtw89_write_rf(rtwdev, i, RR_TM2, RR_TM2_OFF, val);
380 
381 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
382 			    "[THERMAL][TRIM] path=%d thermal_setting=0x%x\n",
383 			    i, val);
384 	}
385 #undef __thm_setting
386 }
387 
388 static void rtw8852c_phycap_parsing_pa_bias_trim(struct rtw89_dev *rtwdev,
389 						 u8 *phycap_map)
390 {
391 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
392 	static const u32 pabias_trim_addr[RF_PATH_NUM_8852C] = {0x5DE, 0x5DB};
393 	u32 addr = rtwdev->chip->phycap_addr;
394 	u8 i;
395 
396 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
397 		info->pa_bias_trim[i] = phycap_map[pabias_trim_addr[i] - addr];
398 
399 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
400 			    "[PA_BIAS][TRIM] path=%d pa_bias_trim=0x%x\n",
401 			    i, info->pa_bias_trim[i]);
402 
403 		if (info->pa_bias_trim[i] != 0xff)
404 			info->pg_pa_bias_trim = true;
405 	}
406 }
407 
408 static void rtw8852c_pa_bias_trim(struct rtw89_dev *rtwdev)
409 {
410 	struct rtw89_power_trim_info *info = &rtwdev->pwr_trim;
411 	u8 pabias_2g, pabias_5g;
412 	u8 i;
413 
414 	if (!info->pg_pa_bias_trim) {
415 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
416 			    "[PA_BIAS][TRIM] no PG, do nothing\n");
417 
418 		return;
419 	}
420 
421 	for (i = 0; i < RF_PATH_NUM_8852C; i++) {
422 		pabias_2g = FIELD_GET(GENMASK(3, 0), info->pa_bias_trim[i]);
423 		pabias_5g = FIELD_GET(GENMASK(7, 4), info->pa_bias_trim[i]);
424 
425 		rtw89_debug(rtwdev, RTW89_DBG_RFK,
426 			    "[PA_BIAS][TRIM] path=%d 2G=0x%x 5G=0x%x\n",
427 			    i, pabias_2g, pabias_5g);
428 
429 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXG, pabias_2g);
430 		rtw89_write_rf(rtwdev, i, RR_BIASA, RR_BIASA_TXA, pabias_5g);
431 	}
432 }
433 
434 static int rtw8852c_read_phycap(struct rtw89_dev *rtwdev, u8 *phycap_map)
435 {
436 	rtw8852c_phycap_parsing_tssi(rtwdev, phycap_map);
437 	rtw8852c_phycap_parsing_thermal_trim(rtwdev, phycap_map);
438 	rtw8852c_phycap_parsing_pa_bias_trim(rtwdev, phycap_map);
439 
440 	return 0;
441 }
442 
443 static void rtw8852c_power_trim(struct rtw89_dev *rtwdev)
444 {
445 	rtw8852c_thermal_trim(rtwdev);
446 	rtw8852c_pa_bias_trim(rtwdev);
447 }
448 
449 static
450 void rtw8852c_set_txpwr_ul_tb_offset(struct rtw89_dev *rtwdev,
451 				     s8 pw_ofst, enum rtw89_mac_idx mac_idx)
452 {
453 	s8 pw_ofst_2tx;
454 	s8 val_1t;
455 	s8 val_2t;
456 	u32 reg;
457 	u8 i;
458 
459 	if (pw_ofst < -32 || pw_ofst > 31) {
460 		rtw89_warn(rtwdev, "[ULTB] Err pwr_offset=%d\n", pw_ofst);
461 		return;
462 	}
463 	val_1t = pw_ofst << 2;
464 	pw_ofst_2tx = max(pw_ofst - 3, -32);
465 	val_2t = pw_ofst_2tx << 2;
466 
467 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_1tx=0x%x\n", val_1t);
468 	rtw89_debug(rtwdev, RTW89_DBG_TXPWR, "[ULTB] val_2tx=0x%x\n", val_2t);
469 
470 	for (i = 0; i < 4; i++) {
471 		/* 1TX */
472 		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_1T, mac_idx);
473 		rtw89_write32_mask(rtwdev, reg,
474 				   B_AX_PWR_UL_TB_1T_V1_MASK << (8 * i),
475 				   val_1t);
476 		/* 2TX */
477 		reg = rtw89_mac_reg_by_idx(R_AX_PWR_UL_TB_2T, mac_idx);
478 		rtw89_write32_mask(rtwdev, reg,
479 				   B_AX_PWR_UL_TB_2T_V1_MASK << (8 * i),
480 				   val_2t);
481 	}
482 }
483 
484 static const struct rtw89_chip_ops rtw8852c_chip_ops = {
485 	.read_efuse		= rtw8852c_read_efuse,
486 	.read_phycap		= rtw8852c_read_phycap,
487 	.power_trim		= rtw8852c_power_trim,
488 	.read_rf		= rtw89_phy_read_rf_v1,
489 	.write_rf		= rtw89_phy_write_rf_v1,
490 	.set_txpwr_ul_tb_offset	= rtw8852c_set_txpwr_ul_tb_offset,
491 	.pwr_on_func		= rtw8852c_pwr_on_func,
492 	.pwr_off_func		= rtw8852c_pwr_off_func,
493 	.cfg_ctrl_path		= rtw89_mac_cfg_ctrl_path_v1,
494 	.mac_cfg_gnt		= rtw89_mac_cfg_gnt_v1,
495 	.stop_sch_tx		= rtw89_mac_stop_sch_tx_v1,
496 	.resume_sch_tx		= rtw89_mac_resume_sch_tx_v1,
497 };
498 
499 const struct rtw89_chip_info rtw8852c_chip_info = {
500 	.chip_id		= RTL8852C,
501 	.ops			= &rtw8852c_chip_ops,
502 	.fw_name		= "rtw89/rtw8852c_fw.bin",
503 	.dle_mem		= rtw8852c_dle_mem_pcie,
504 	.rf_base_addr		= {0xe000, 0xf000},
505 	.pwr_on_seq		= NULL,
506 	.pwr_off_seq		= NULL,
507 	.sec_ctrl_efuse_size	= 4,
508 	.physical_efuse_size	= 1216,
509 	.logical_efuse_size	= 2048,
510 	.limit_efuse_size	= 1280,
511 	.dav_phy_efuse_size	= 96,
512 	.dav_log_efuse_size	= 16,
513 	.phycap_addr		= 0x590,
514 	.phycap_size		= 0x60,
515 	.hci_func_en_addr	= R_AX_HCI_FUNC_EN_V1,
516 	.h2c_ctrl_reg		= R_AX_H2CREG_CTRL_V1,
517 	.h2c_regs		= rtw8852c_h2c_regs,
518 	.c2h_ctrl_reg		= R_AX_C2HREG_CTRL_V1,
519 	.c2h_regs		= rtw8852c_c2h_regs,
520 	.page_regs		= &rtw8852c_page_regs,
521 	.dcfo_comp		= &rtw8852c_dcfo_comp,
522 	.dcfo_comp_sft		= 5,
523 };
524 EXPORT_SYMBOL(rtw8852c_chip_info);
525 
526 MODULE_FIRMWARE("rtw89/rtw8852c_fw.bin");
527 MODULE_AUTHOR("Realtek Corporation");
528 MODULE_DESCRIPTION("Realtek 802.11ax wireless 8852C driver");
529 MODULE_LICENSE("Dual BSD/GPL");
530