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
rtl92du_phy_enable_anotherphy(struct ieee80211_hw * hw,bool bmac0)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
rtl92du_phy_powerdown_anotherphy(struct ieee80211_hw * hw,bool bmac0)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
rtl92du_phy_rf6052_config(struct ieee80211_hw * hw)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