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