1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* Copyright(c) 2023 Realtek Corporation 3 */ 4 5 #include "chan.h" 6 #include "debug.h" 7 #include "mac.h" 8 #include "phy.h" 9 #include "reg.h" 10 #include "rtw8922a.h" 11 #include "rtw8922a_rfk.h" 12 13 static void rtw8922a_tssi_cont_en(struct rtw89_dev *rtwdev, bool en, 14 enum rtw89_rf_path path) 15 { 16 static const u32 tssi_trk_man[2] = {R_TSSI_PWR_P0, R_TSSI_PWR_P1}; 17 18 if (en) 19 rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 0); 20 else 21 rtw89_phy_write32_mask(rtwdev, tssi_trk_man[path], B_TSSI_CONT_EN, 1); 22 } 23 24 void rtw8922a_tssi_cont_en_phyidx(struct rtw89_dev *rtwdev, bool en, u8 phy_idx) 25 { 26 if (rtwdev->mlo_dbcc_mode == MLO_1_PLUS_1_1RF) { 27 if (phy_idx == RTW89_PHY_0) 28 rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A); 29 else 30 rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B); 31 } else { 32 rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_A); 33 rtw8922a_tssi_cont_en(rtwdev, en, RF_PATH_B); 34 } 35 } 36 37 static 38 void rtw8922a_ctl_band_ch_bw(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy, 39 u8 central_ch, enum rtw89_band band, 40 enum rtw89_bandwidth bw) 41 { 42 const u32 rf_addr[2] = {RR_CFGCH, RR_CFGCH_V1}; 43 struct rtw89_hal *hal = &rtwdev->hal; 44 u32 rf_reg[RF_PATH_NUM_8922A][2]; 45 u8 synpath; 46 u32 rf18; 47 u8 kpath; 48 u8 path; 49 u8 i; 50 51 rf_reg[RF_PATH_A][0] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[0], RFREG_MASK); 52 rf_reg[RF_PATH_A][1] = rtw89_read_rf(rtwdev, RF_PATH_A, rf_addr[1], RFREG_MASK); 53 rf_reg[RF_PATH_B][0] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[0], RFREG_MASK); 54 rf_reg[RF_PATH_B][1] = rtw89_read_rf(rtwdev, RF_PATH_B, rf_addr[1], RFREG_MASK); 55 56 kpath = rtw89_phy_get_kpath(rtwdev, phy); 57 synpath = rtw89_phy_get_syn_sel(rtwdev, phy); 58 59 rf18 = rtw89_read_rf(rtwdev, synpath, RR_CFGCH, RFREG_MASK); 60 if (rf18 == INV_RF_DATA) { 61 rtw89_warn(rtwdev, "[RFK] Invalid RF18 value\n"); 62 return; 63 } 64 65 for (path = 0; path < RF_PATH_NUM_8922A; path++) { 66 if (!(kpath & BIT(path))) 67 continue; 68 69 for (i = 0; i < 2; i++) { 70 if (rf_reg[path][i] == INV_RF_DATA) { 71 rtw89_warn(rtwdev, 72 "[RFK] Invalid RF_0x18 for Path-%d\n", path); 73 return; 74 } 75 76 rf_reg[path][i] &= ~(RR_CFGCH_BAND1 | RR_CFGCH_BW | 77 RR_CFGCH_BAND0 | RR_CFGCH_CH); 78 rf_reg[path][i] |= u32_encode_bits(central_ch, RR_CFGCH_CH); 79 80 if (band == RTW89_BAND_2G) 81 rtw89_write_rf(rtwdev, path, RR_SMD, RR_VCO2, 0x0); 82 else 83 rtw89_write_rf(rtwdev, path, RR_SMD, RR_VCO2, 0x1); 84 85 switch (band) { 86 case RTW89_BAND_2G: 87 default: 88 break; 89 case RTW89_BAND_5G: 90 rf_reg[path][i] |= 91 u32_encode_bits(CFGCH_BAND1_5G, RR_CFGCH_BAND1) | 92 u32_encode_bits(CFGCH_BAND0_5G, RR_CFGCH_BAND0); 93 break; 94 case RTW89_BAND_6G: 95 rf_reg[path][i] |= 96 u32_encode_bits(CFGCH_BAND1_6G, RR_CFGCH_BAND1) | 97 u32_encode_bits(CFGCH_BAND0_6G, RR_CFGCH_BAND0); 98 break; 99 } 100 101 switch (bw) { 102 case RTW89_CHANNEL_WIDTH_5: 103 case RTW89_CHANNEL_WIDTH_10: 104 case RTW89_CHANNEL_WIDTH_20: 105 default: 106 break; 107 case RTW89_CHANNEL_WIDTH_40: 108 rf_reg[path][i] |= 109 u32_encode_bits(CFGCH_BW_V2_40M, RR_CFGCH_BW_V2); 110 break; 111 case RTW89_CHANNEL_WIDTH_80: 112 rf_reg[path][i] |= 113 u32_encode_bits(CFGCH_BW_V2_80M, RR_CFGCH_BW_V2); 114 break; 115 case RTW89_CHANNEL_WIDTH_160: 116 rf_reg[path][i] |= 117 u32_encode_bits(CFGCH_BW_V2_160M, RR_CFGCH_BW_V2); 118 break; 119 case RTW89_CHANNEL_WIDTH_320: 120 rf_reg[path][i] |= 121 u32_encode_bits(CFGCH_BW_V2_320M, RR_CFGCH_BW_V2); 122 break; 123 } 124 125 rtw89_write_rf(rtwdev, path, rf_addr[i], 126 RFREG_MASK, rf_reg[path][i]); 127 fsleep(100); 128 } 129 } 130 131 if (hal->cv != CHIP_CAV) 132 return; 133 134 if (band == RTW89_BAND_2G) { 135 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); 136 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003); 137 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c990); 138 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38); 139 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); 140 } else { 141 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x80000); 142 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWA, RFREG_MASK, 0x00003); 143 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD1, RFREG_MASK, 0x0c190); 144 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWD0, RFREG_MASK, 0xebe38); 145 rtw89_write_rf(rtwdev, RF_PATH_A, RR_LUTWE, RFREG_MASK, 0x00000); 146 } 147 } 148 149 void rtw8922a_set_channel_rf(struct rtw89_dev *rtwdev, 150 const struct rtw89_chan *chan, 151 enum rtw89_phy_idx phy_idx) 152 { 153 rtw8922a_ctl_band_ch_bw(rtwdev, phy_idx, chan->channel, chan->band_type, 154 chan->band_width); 155 } 156 157 enum _rf_syn_pow { 158 RF_SYN_ON_OFF, 159 RF_SYN_OFF_ON, 160 RF_SYN_ALLON, 161 RF_SYN_ALLOFF, 162 }; 163 164 static void rtw8922a_set_syn01_cav(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) 165 { 166 if (syn == RF_SYN_ALLON) { 167 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); 168 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2); 169 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); 170 171 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); 172 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2); 173 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); 174 } else if (syn == RF_SYN_ON_OFF) { 175 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); 176 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x2); 177 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x3); 178 179 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0); 180 } else if (syn == RF_SYN_OFF_ON) { 181 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); 182 183 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); 184 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x2); 185 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x3); 186 } else if (syn == RF_SYN_ALLOFF) { 187 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN, 0x0); 188 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN, 0x0); 189 } 190 } 191 192 static void rtw8922a_set_syn01_cbv(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) 193 { 194 if (syn == RF_SYN_ALLON) { 195 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); 196 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); 197 } else if (syn == RF_SYN_ON_OFF) { 198 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0xf); 199 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); 200 } else if (syn == RF_SYN_OFF_ON) { 201 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); 202 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0xf); 203 } else if (syn == RF_SYN_ALLOFF) { 204 rtw89_write_rf(rtwdev, RF_PATH_A, RR_POW, RR_POW_SYN_V1, 0x0); 205 rtw89_write_rf(rtwdev, RF_PATH_B, RR_POW, RR_POW_SYN_V1, 0x0); 206 } 207 } 208 209 static void rtw8922a_set_syn01(struct rtw89_dev *rtwdev, enum _rf_syn_pow syn) 210 { 211 struct rtw89_hal *hal = &rtwdev->hal; 212 213 rtw89_debug(rtwdev, RTW89_DBG_RFK, "SYN config=%d\n", syn); 214 215 if (hal->cv == CHIP_CAV) 216 rtw8922a_set_syn01_cav(rtwdev, syn); 217 else 218 rtw8922a_set_syn01_cbv(rtwdev, syn); 219 } 220 221 static void rtw8922a_chlk_ktbl_sel(struct rtw89_dev *rtwdev, u8 kpath, u8 idx) 222 { 223 u32 tmp; 224 225 if (idx > 2) { 226 rtw89_warn(rtwdev, "[DBCC][ERROR]indx is out of limit!! index(%d)", idx); 227 return; 228 } 229 230 if (kpath & RF_A) { 231 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_EN, 0x1); 232 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_IQC_V1, idx); 233 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL, B_COEF_SEL_MDPD_V1, idx); 234 rtw89_write_rf(rtwdev, RF_PATH_A, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); 235 236 tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(0)); 237 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G3, tmp); 238 tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL, BIT(1)); 239 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT, B_CFIR_LUT_G5, tmp); 240 } 241 242 if (kpath & RF_B) { 243 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_EN, 0x1); 244 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_IQC_V1, idx); 245 rtw89_phy_write32_mask(rtwdev, R_COEF_SEL_C1, B_COEF_SEL_MDPD_V1, idx); 246 rtw89_write_rf(rtwdev, RF_PATH_B, RR_MODOPT, RR_TXG_SEL, 0x4 | idx); 247 248 tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(0)); 249 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G3, tmp); 250 tmp = rtw89_phy_read32_mask(rtwdev, R_COEF_SEL_C1, BIT(1)); 251 rtw89_phy_write32_mask(rtwdev, R_CFIR_LUT_C1, B_CFIR_LUT_G5, tmp); 252 } 253 } 254 255 static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) 256 { 257 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 258 struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; 259 enum rtw89_chanctx_idx chanctx_idx; 260 const struct rtw89_chan *chan; 261 enum rtw89_entity_mode mode; 262 u8 s0_tbl, s1_tbl; 263 u8 tbl_sel; 264 265 mode = rtw89_get_entity_mode(rtwdev); 266 switch (mode) { 267 case RTW89_ENTITY_MODE_MCC_PREPARE: 268 chanctx_idx = RTW89_CHANCTX_1; 269 break; 270 default: 271 chanctx_idx = RTW89_CHANCTX_0; 272 break; 273 } 274 275 chan = rtw89_chan_get(rtwdev, chanctx_idx); 276 277 for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { 278 struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; 279 280 p->ch = rfk_mcc->ch[tbl_sel]; 281 282 p->has_band = true; 283 p->band = rfk_mcc->band[tbl_sel]; 284 285 p->has_bw = true; 286 p->bw = rfk_mcc->bw[tbl_sel]; 287 } 288 289 tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); 290 291 rfk_mcc->ch[tbl_sel] = chan->channel; 292 rfk_mcc->band[tbl_sel] = chan->band_type; 293 rfk_mcc->bw[tbl_sel] = chan->band_width; 294 rfk_mcc->table_idx = tbl_sel; 295 296 s0_tbl = tbl_sel; 297 s1_tbl = tbl_sel; 298 299 rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl); 300 rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl); 301 } 302 303 static void rtw8922a_rfk_mlo_ctrl(struct rtw89_dev *rtwdev) 304 { 305 enum _rf_syn_pow syn_pow; 306 307 if (!rtwdev->dbcc_en) 308 goto set_rfk_reload; 309 310 switch (rtwdev->mlo_dbcc_mode) { 311 case MLO_0_PLUS_2_1RF: 312 syn_pow = RF_SYN_OFF_ON; 313 break; 314 case MLO_0_PLUS_2_2RF: 315 case MLO_1_PLUS_1_2RF: 316 case MLO_2_PLUS_0_1RF: 317 case MLO_2_PLUS_0_2RF: 318 case MLO_2_PLUS_2_2RF: 319 case MLO_DBCC_NOT_SUPPORT: 320 default: 321 syn_pow = RF_SYN_ON_OFF; 322 break; 323 case MLO_1_PLUS_1_1RF: 324 case DBCC_LEGACY: 325 syn_pow = RF_SYN_ALLON; 326 break; 327 } 328 329 rtw8922a_set_syn01(rtwdev, syn_pow); 330 331 set_rfk_reload: 332 rtw8922a_chlk_reload(rtwdev); 333 } 334 335 static void rtw8922a_rfk_pll_init(struct rtw89_dev *rtwdev) 336 { 337 int ret; 338 u8 tmp; 339 340 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_PLL_1, &tmp); 341 if (ret) 342 return; 343 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, tmp | 0xf8, 0xFF); 344 if (ret) 345 return; 346 347 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_APBT, &tmp); 348 if (ret) 349 return; 350 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_APBT, tmp & ~0x60, 0xFF); 351 if (ret) 352 return; 353 354 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, &tmp); 355 if (ret) 356 return; 357 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, tmp | 0x38, 0xFF); 358 if (ret) 359 return; 360 } 361 362 void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev) 363 { 364 if (rtwdev->dbcc_en) 365 rtw8922a_rfk_mlo_ctrl(rtwdev); 366 367 rtw8922a_rfk_pll_init(rtwdev); 368 } 369 370 void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 371 { 372 bool mlo_1_1; 373 374 if (!rtwdev->dbcc_en) 375 return; 376 377 mlo_1_1 = rtw89_is_mlo_1_1(rtwdev); 378 if (mlo_1_1) 379 rtw8922a_set_syn01(rtwdev, RF_SYN_ALLON); 380 else if (phy_idx == RTW89_PHY_0) 381 rtw8922a_set_syn01(rtwdev, RF_SYN_ON_OFF); 382 else 383 rtw8922a_set_syn01(rtwdev, RF_SYN_OFF_ON); 384 385 fsleep(1000); 386 } 387 388 void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 389 { 390 rtw8922a_rfk_mlo_ctrl(rtwdev); 391 } 392