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