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 u8 rtw8922a_chlk_reload_sel_tbl(struct rtw89_dev *rtwdev, 256 const struct rtw89_chan *chan, u8 path) 257 { 258 struct rtw89_rfk_mcc_info *rfk_mcc = &rtwdev->rfk_mcc; 259 struct rtw89_rfk_chan_desc desc[__RTW89_RFK_CHS_NR_V1] = {}; 260 u8 tbl_sel; 261 262 for (tbl_sel = 0; tbl_sel < ARRAY_SIZE(desc); tbl_sel++) { 263 struct rtw89_rfk_chan_desc *p = &desc[tbl_sel]; 264 265 p->ch = rfk_mcc->data[path].ch[tbl_sel]; 266 267 p->has_band = true; 268 p->band = rfk_mcc->data[path].band[tbl_sel]; 269 270 p->has_bw = true; 271 p->bw = rfk_mcc->data[path].bw[tbl_sel]; 272 } 273 274 tbl_sel = rtw89_rfk_chan_lookup(rtwdev, desc, ARRAY_SIZE(desc), chan); 275 276 rfk_mcc->data[path].ch[tbl_sel] = chan->channel; 277 rfk_mcc->data[path].band[tbl_sel] = chan->band_type; 278 rfk_mcc->data[path].bw[tbl_sel] = chan->band_width; 279 rfk_mcc->data[path].table_idx = tbl_sel; 280 281 return tbl_sel; 282 } 283 284 static void rtw8922a_chlk_reload(struct rtw89_dev *rtwdev) 285 { 286 const struct rtw89_chan *chan0, *chan1; 287 u8 s0_tbl, s1_tbl; 288 289 switch (rtwdev->mlo_dbcc_mode) { 290 default: 291 case MLO_2_PLUS_0_1RF: 292 chan0 = rtw89_mgnt_chan_get(rtwdev, 0); 293 chan1 = chan0; 294 break; 295 case MLO_0_PLUS_2_1RF: 296 chan1 = rtw89_mgnt_chan_get(rtwdev, 1); 297 chan0 = chan1; 298 break; 299 case MLO_1_PLUS_1_1RF: 300 chan0 = rtw89_mgnt_chan_get(rtwdev, 0); 301 chan1 = rtw89_mgnt_chan_get(rtwdev, 1); 302 break; 303 } 304 305 s0_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan0, 0); 306 s1_tbl = rtw8922a_chlk_reload_sel_tbl(rtwdev, chan1, 1); 307 308 rtw8922a_chlk_ktbl_sel(rtwdev, RF_A, s0_tbl); 309 rtw8922a_chlk_ktbl_sel(rtwdev, RF_B, s1_tbl); 310 } 311 312 static void rtw8922a_rfk_mlo_ctrl(struct rtw89_dev *rtwdev) 313 { 314 enum _rf_syn_pow syn_pow; 315 316 if (!rtwdev->dbcc_en) 317 goto set_rfk_reload; 318 319 switch (rtwdev->mlo_dbcc_mode) { 320 case MLO_0_PLUS_2_1RF: 321 syn_pow = RF_SYN_OFF_ON; 322 break; 323 case MLO_0_PLUS_2_2RF: 324 case MLO_1_PLUS_1_2RF: 325 case MLO_2_PLUS_0_1RF: 326 case MLO_2_PLUS_0_2RF: 327 case MLO_2_PLUS_2_2RF: 328 case MLO_DBCC_NOT_SUPPORT: 329 default: 330 syn_pow = RF_SYN_ON_OFF; 331 break; 332 case MLO_1_PLUS_1_1RF: 333 case DBCC_LEGACY: 334 syn_pow = RF_SYN_ALLON; 335 break; 336 } 337 338 rtw8922a_set_syn01(rtwdev, syn_pow); 339 340 set_rfk_reload: 341 rtw8922a_chlk_reload(rtwdev); 342 } 343 344 static void rtw8922a_rfk_pll_init(struct rtw89_dev *rtwdev) 345 { 346 int ret; 347 u8 tmp; 348 349 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_PLL_1, &tmp); 350 if (ret) 351 return; 352 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_PLL_1, tmp | 0xf8, 0xFF); 353 if (ret) 354 return; 355 356 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_APBT, &tmp); 357 if (ret) 358 return; 359 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_APBT, tmp & ~0x60, 0xFF); 360 if (ret) 361 return; 362 363 ret = rtw89_mac_read_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, &tmp); 364 if (ret) 365 return; 366 ret = rtw89_mac_write_xtal_si(rtwdev, XTAL_SI_XTAL_PLL, tmp | 0x38, 0xFF); 367 if (ret) 368 return; 369 } 370 371 void rtw8922a_rfk_hw_init(struct rtw89_dev *rtwdev) 372 { 373 if (rtwdev->dbcc_en) 374 rtw8922a_rfk_mlo_ctrl(rtwdev); 375 376 rtw8922a_rfk_pll_init(rtwdev); 377 } 378 379 void rtw8922a_pre_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 380 { 381 bool mlo_1_1; 382 383 if (!rtwdev->dbcc_en) 384 return; 385 386 mlo_1_1 = rtw89_is_mlo_1_1(rtwdev); 387 if (mlo_1_1) 388 rtw8922a_set_syn01(rtwdev, RF_SYN_ALLON); 389 else if (phy_idx == RTW89_PHY_0) 390 rtw8922a_set_syn01(rtwdev, RF_SYN_ON_OFF); 391 else 392 rtw8922a_set_syn01(rtwdev, RF_SYN_OFF_ON); 393 394 fsleep(1000); 395 } 396 397 void rtw8922a_post_set_channel_rf(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx) 398 { 399 rtw8922a_rfk_mlo_ctrl(rtwdev); 400 } 401