1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2024 Realtek Corporation.*/ 3 4 #include "../wifi.h" 5 #include "../rtl8192d/reg.h" 6 #include "../rtl8192d/phy_common.h" 7 #include "phy.h" 8 #include "rf.h" 9 10 bool rtl92du_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) 11 { 12 struct rtl_priv *rtlpriv = rtl_priv(hw); 13 struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 14 u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; 15 u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; 16 bool bresult = true; /* true: need to enable BB/RF power */ 17 u32 maskforphyset = 0; 18 u16 val16; 19 u8 u1btmp; 20 21 rtlhal->during_mac0init_radiob = false; 22 rtlhal->during_mac1init_radioa = false; 23 rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); 24 25 /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ 26 u1btmp = rtl_read_byte(rtlpriv, mac_reg); 27 if (!(u1btmp & mac_on_bit)) { 28 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); 29 /* Enable BB and RF power */ 30 31 maskforphyset = bmac0 ? MAC0_ACCESS_PHY1 : MAC1_ACCESS_PHY0; 32 33 val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset); 34 val16 &= 0xfffc; 35 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset, val16); 36 37 val16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset); 38 val16 |= BIT(13) | BIT(0) | BIT(1); 39 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN | maskforphyset, val16); 40 } else { 41 /* We think if MAC1 is ON,then radio_a.txt 42 * and radio_b.txt has been load. 43 */ 44 bresult = false; 45 } 46 rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); 47 return bresult; 48 } 49 50 void rtl92du_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) 51 { 52 struct rtl_priv *rtlpriv = rtl_priv(hw); 53 struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 54 u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON; 55 u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0; 56 u32 maskforphyset = 0; 57 u8 u1btmp; 58 59 rtlhal->during_mac0init_radiob = false; 60 rtlhal->during_mac1init_radioa = false; 61 rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); 62 63 /* check MAC0 enable or not again now, if 64 * enabled, not power down radio A. 65 */ 66 u1btmp = rtl_read_byte(rtlpriv, mac_reg); 67 if (!(u1btmp & mac_on_bit)) { 68 rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); 69 /* power down RF radio A according to YuNan's advice. */ 70 maskforphyset = bmac0 ? MAC0_ACCESS_PHY1 : MAC1_ACCESS_PHY0; 71 rtl_write_dword(rtlpriv, RFPGA0_XA_LSSIPARAMETER | maskforphyset, 72 0x00000000); 73 } 74 rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); 75 } 76 77 bool rtl92du_phy_rf6052_config(struct ieee80211_hw *hw) 78 { 79 bool mac1_initradioa_first = false, mac0_initradiob_first = false; 80 bool need_pwrdown_radioa = false, need_pwrdown_radiob = false; 81 struct rtl_priv *rtlpriv = rtl_priv(hw); 82 struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 83 struct rtl_phy *rtlphy = &rtlpriv->phy; 84 struct bb_reg_def *pphyreg; 85 bool true_bpath = false; 86 bool rtstatus = true; 87 u32 u4_regvalue = 0; 88 u8 rfpath; 89 90 if (rtlphy->rf_type == RF_1T1R) 91 rtlphy->num_total_rfpath = 1; 92 else 93 rtlphy->num_total_rfpath = 2; 94 95 /* Single phy mode: use radio_a radio_b config path_A path_B 96 * separately by MAC0, and MAC1 needn't configure RF; 97 * Dual PHY mode: MAC0 use radio_a config 1st phy path_A, 98 * MAC1 use radio_b config 2nd PHY path_A. 99 * DMDP, MAC0 on G band, MAC1 on A band. 100 */ 101 if (rtlhal->macphymode == DUALMAC_DUALPHY) { 102 if (rtlhal->current_bandtype == BAND_ON_2_4G && 103 rtlhal->interfaceindex == 0) { 104 /* MAC0 needs PHY1 load radio_b.txt. */ 105 if (rtl92du_phy_enable_anotherphy(hw, true)) { 106 rtlphy->num_total_rfpath = 2; 107 mac0_initradiob_first = true; 108 } else { 109 /* We think if MAC1 is ON,then radio_a.txt and 110 * radio_b.txt has been load. 111 */ 112 return rtstatus; 113 } 114 } else if (rtlhal->current_bandtype == BAND_ON_5G && 115 rtlhal->interfaceindex == 1) { 116 /* MAC1 needs PHY0 load radio_a.txt. */ 117 if (rtl92du_phy_enable_anotherphy(hw, false)) { 118 rtlphy->num_total_rfpath = 2; 119 mac1_initradioa_first = true; 120 } else { 121 /* We think if MAC0 is ON, then radio_a.txt and 122 * radio_b.txt has been load. 123 */ 124 return rtstatus; 125 } 126 } else if (rtlhal->interfaceindex == 1) { 127 /* MAC0 enabled, only init radia B. */ 128 true_bpath = true; 129 } 130 } 131 132 for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { 133 /* Mac1 use PHY0 write */ 134 if (mac1_initradioa_first) { 135 if (rfpath == RF90_PATH_A) { 136 rtlhal->during_mac1init_radioa = true; 137 need_pwrdown_radioa = true; 138 } else if (rfpath == RF90_PATH_B) { 139 rtlhal->during_mac1init_radioa = false; 140 mac1_initradioa_first = false; 141 rfpath = RF90_PATH_A; 142 true_bpath = true; 143 rtlphy->num_total_rfpath = 1; 144 } 145 } else if (mac0_initradiob_first) { 146 /* Mac0 use PHY1 write */ 147 if (rfpath == RF90_PATH_A) 148 rtlhal->during_mac0init_radiob = false; 149 if (rfpath == RF90_PATH_B) { 150 rtlhal->during_mac0init_radiob = true; 151 mac0_initradiob_first = false; 152 need_pwrdown_radiob = true; 153 rfpath = RF90_PATH_A; 154 true_bpath = true; 155 rtlphy->num_total_rfpath = 1; 156 } 157 } 158 159 pphyreg = &rtlphy->phyreg_def[rfpath]; 160 161 switch (rfpath) { 162 case RF90_PATH_A: 163 case RF90_PATH_C: 164 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, 165 BRFSI_RFENV); 166 break; 167 case RF90_PATH_B: 168 case RF90_PATH_D: 169 u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, 170 BRFSI_RFENV << 16); 171 break; 172 } 173 174 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); 175 udelay(1); 176 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); 177 udelay(1); 178 179 /* Set bit number of Address and Data for RF register */ 180 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, 181 B3WIREADDRESSLENGTH, 0x0); 182 udelay(1); 183 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); 184 udelay(1); 185 186 switch (rfpath) { 187 case RF90_PATH_A: 188 if (true_bpath) 189 rtstatus = rtl92du_phy_config_rf_with_headerfile( 190 hw, radiob_txt, 191 (enum radio_path)rfpath); 192 else 193 rtstatus = rtl92du_phy_config_rf_with_headerfile( 194 hw, radioa_txt, 195 (enum radio_path)rfpath); 196 break; 197 case RF90_PATH_B: 198 rtstatus = 199 rtl92du_phy_config_rf_with_headerfile(hw, radiob_txt, 200 (enum radio_path)rfpath); 201 break; 202 case RF90_PATH_C: 203 break; 204 case RF90_PATH_D: 205 break; 206 } 207 208 switch (rfpath) { 209 case RF90_PATH_A: 210 case RF90_PATH_C: 211 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, 212 u4_regvalue); 213 break; 214 case RF90_PATH_B: 215 case RF90_PATH_D: 216 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16, 217 u4_regvalue); 218 break; 219 } 220 221 if (!rtstatus) { 222 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 223 "Radio[%d] Fail!!\n", rfpath); 224 return rtstatus; 225 } 226 } 227 228 /* check MAC0 enable or not again, if enabled, 229 * not power down radio A. 230 * check MAC1 enable or not again, if enabled, 231 * not power down radio B. 232 */ 233 if (need_pwrdown_radioa) 234 rtl92du_phy_powerdown_anotherphy(hw, false); 235 else if (need_pwrdown_radiob) 236 rtl92du_phy_powerdown_anotherphy(hw, true); 237 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); 238 239 return rtstatus; 240 } 241