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