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