xref: /linux/drivers/net/wireless/realtek/rtlwifi/rtl8192du/rf.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
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