1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2014 Realtek Corporation.*/
5 #include "phy_common.h"
6 #include "../rtl8723ae/reg.h"
7 #include <linux/module.h>
9 /* These routines are common to RTL8723AE and RTL8723bE */
11 u32
rtl8723_phy_query_bb_reg(struct ieee80211_hw
*hw
,
12 u32 regaddr
, u32 bitmask
)
14 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
15 u32 returnvalue
, originalvalue
, bitshift
;
17 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
18 "regaddr(%#x), bitmask(%#x)\n", regaddr
, bitmask
);
19 originalvalue
= rtl_read_dword(rtlpriv
, regaddr
);
20 bitshift
= rtl8723_phy_calculate_bit_shift(bitmask
);
21 returnvalue
= (originalvalue
& bitmask
) >> bitshift
;
23 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
24 "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask
,
25 regaddr
, originalvalue
);
28 EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg
);
30 void rtl8723_phy_set_bb_reg(struct ieee80211_hw
*hw
, u32 regaddr
,
31 u32 bitmask
, u32 data
)
33 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
34 u32 originalvalue
, bitshift
;
36 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
37 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr
, bitmask
,
40 if (bitmask
!= MASKDWORD
) {
41 originalvalue
= rtl_read_dword(rtlpriv
, regaddr
);
42 bitshift
= rtl8723_phy_calculate_bit_shift(bitmask
);
43 data
= ((originalvalue
& (~bitmask
)) | (data
<< bitshift
));
46 rtl_write_dword(rtlpriv
, regaddr
, data
);
48 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
49 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
50 regaddr
, bitmask
, data
);
52 EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg
);
54 u32
rtl8723_phy_calculate_bit_shift(u32 bitmask
)
58 return i
? i
- 1 : 32;
60 EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift
);
62 u32
rtl8723_phy_rf_serial_read(struct ieee80211_hw
*hw
,
63 enum radio_path rfpath
, u32 offset
)
65 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
66 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
67 struct bb_reg_def
*pphyreg
= &rtlphy
->phyreg_def
[rfpath
];
69 u32 tmplong
, tmplong2
;
75 if (RT_CANNOT_IO(hw
)) {
76 pr_err("return all one\n");
79 tmplong
= rtl_get_bbreg(hw
, RFPGA0_XA_HSSIPARAMETER2
, MASKDWORD
);
80 if (rfpath
== RF90_PATH_A
)
83 tmplong2
= rtl_get_bbreg(hw
, pphyreg
->rfhssi_para2
, MASKDWORD
);
84 tmplong2
= (tmplong2
& (~BLSSIREADADDRESS
)) |
85 (newoffset
<< 23) | BLSSIREADEDGE
;
86 rtl_set_bbreg(hw
, RFPGA0_XA_HSSIPARAMETER2
, MASKDWORD
,
87 tmplong
& (~BLSSIREADEDGE
));
88 rtl_set_bbreg(hw
, pphyreg
->rfhssi_para2
, MASKDWORD
, tmplong2
);
89 rtl_set_bbreg(hw
, RFPGA0_XA_HSSIPARAMETER2
, MASKDWORD
,
90 tmplong
| BLSSIREADEDGE
);
92 if (rfpath
== RF90_PATH_A
)
93 rfpi_enable
= (u8
) rtl_get_bbreg(hw
, RFPGA0_XA_HSSIPARAMETER1
,
95 else if (rfpath
== RF90_PATH_B
)
96 rfpi_enable
= (u8
) rtl_get_bbreg(hw
, RFPGA0_XB_HSSIPARAMETER1
,
99 retvalue
= rtl_get_bbreg(hw
, pphyreg
->rf_rbpi
,
102 retvalue
= rtl_get_bbreg(hw
, pphyreg
->rf_rb
,
104 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
105 "RFR-%d Addr[0x%x]=0x%x\n",
106 rfpath
, pphyreg
->rf_rb
, retvalue
);
109 EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read
);
111 void rtl8723_phy_rf_serial_write(struct ieee80211_hw
*hw
,
112 enum radio_path rfpath
,
113 u32 offset
, u32 data
)
117 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
118 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
119 struct bb_reg_def
*pphyreg
= &rtlphy
->phyreg_def
[rfpath
];
121 if (RT_CANNOT_IO(hw
)) {
127 data_and_addr
= ((newoffset
<< 20) | (data
& 0x000fffff)) & 0x0fffffff;
128 rtl_set_bbreg(hw
, pphyreg
->rf3wire_offset
, MASKDWORD
, data_and_addr
);
129 rtl_dbg(rtlpriv
, COMP_RF
, DBG_TRACE
,
130 "RFW-%d Addr[0x%x]=0x%x\n",
131 rfpath
, pphyreg
->rf3wire_offset
,
134 EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write
);
136 long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw
*hw
,
137 enum wireless_mode wirelessmode
,
143 switch (wirelessmode
) {
144 case WIRELESS_MODE_B
:
147 case WIRELESS_MODE_G
:
148 case WIRELESS_MODE_N_24G
:
155 pwrout_dbm
= txpwridx
/ 2 + offset
;
158 EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm
);
160 void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw
*hw
)
162 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
163 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
165 rtlphy
->phyreg_def
[RF90_PATH_A
].rfintfs
= RFPGA0_XAB_RFINTERFACESW
;
166 rtlphy
->phyreg_def
[RF90_PATH_B
].rfintfs
= RFPGA0_XAB_RFINTERFACESW
;
167 rtlphy
->phyreg_def
[RF90_PATH_C
].rfintfs
= RFPGA0_XCD_RFINTERFACESW
;
168 rtlphy
->phyreg_def
[RF90_PATH_D
].rfintfs
= RFPGA0_XCD_RFINTERFACESW
;
170 rtlphy
->phyreg_def
[RF90_PATH_A
].rfintfi
= RFPGA0_XAB_RFINTERFACERB
;
171 rtlphy
->phyreg_def
[RF90_PATH_B
].rfintfi
= RFPGA0_XAB_RFINTERFACERB
;
172 rtlphy
->phyreg_def
[RF90_PATH_C
].rfintfi
= RFPGA0_XCD_RFINTERFACERB
;
173 rtlphy
->phyreg_def
[RF90_PATH_D
].rfintfi
= RFPGA0_XCD_RFINTERFACERB
;
175 rtlphy
->phyreg_def
[RF90_PATH_A
].rfintfo
= RFPGA0_XA_RFINTERFACEOE
;
176 rtlphy
->phyreg_def
[RF90_PATH_B
].rfintfo
= RFPGA0_XB_RFINTERFACEOE
;
178 rtlphy
->phyreg_def
[RF90_PATH_A
].rfintfe
= RFPGA0_XA_RFINTERFACEOE
;
179 rtlphy
->phyreg_def
[RF90_PATH_B
].rfintfe
= RFPGA0_XB_RFINTERFACEOE
;
181 rtlphy
->phyreg_def
[RF90_PATH_A
].rf3wire_offset
=
182 RFPGA0_XA_LSSIPARAMETER
;
183 rtlphy
->phyreg_def
[RF90_PATH_B
].rf3wire_offset
=
184 RFPGA0_XB_LSSIPARAMETER
;
186 rtlphy
->phyreg_def
[RF90_PATH_A
].rflssi_select
= RFPGA0_XAB_RFPARAMETER
;
187 rtlphy
->phyreg_def
[RF90_PATH_B
].rflssi_select
= RFPGA0_XAB_RFPARAMETER
;
188 rtlphy
->phyreg_def
[RF90_PATH_C
].rflssi_select
= RFPGA0_XCD_RFPARAMETER
;
189 rtlphy
->phyreg_def
[RF90_PATH_D
].rflssi_select
= RFPGA0_XCD_RFPARAMETER
;
191 rtlphy
->phyreg_def
[RF90_PATH_A
].rftxgain_stage
= RFPGA0_TXGAINSTAGE
;
192 rtlphy
->phyreg_def
[RF90_PATH_B
].rftxgain_stage
= RFPGA0_TXGAINSTAGE
;
193 rtlphy
->phyreg_def
[RF90_PATH_C
].rftxgain_stage
= RFPGA0_TXGAINSTAGE
;
194 rtlphy
->phyreg_def
[RF90_PATH_D
].rftxgain_stage
= RFPGA0_TXGAINSTAGE
;
196 rtlphy
->phyreg_def
[RF90_PATH_A
].rfhssi_para1
= RFPGA0_XA_HSSIPARAMETER1
;
197 rtlphy
->phyreg_def
[RF90_PATH_B
].rfhssi_para1
= RFPGA0_XB_HSSIPARAMETER1
;
199 rtlphy
->phyreg_def
[RF90_PATH_A
].rfhssi_para2
= RFPGA0_XA_HSSIPARAMETER2
;
200 rtlphy
->phyreg_def
[RF90_PATH_B
].rfhssi_para2
= RFPGA0_XB_HSSIPARAMETER2
;
202 rtlphy
->phyreg_def
[RF90_PATH_A
].rfsw_ctrl
= RFPGA0_XAB_SWITCHCONTROL
;
203 rtlphy
->phyreg_def
[RF90_PATH_B
].rfsw_ctrl
= RFPGA0_XAB_SWITCHCONTROL
;
204 rtlphy
->phyreg_def
[RF90_PATH_C
].rfsw_ctrl
= RFPGA0_XCD_SWITCHCONTROL
;
205 rtlphy
->phyreg_def
[RF90_PATH_D
].rfsw_ctrl
= RFPGA0_XCD_SWITCHCONTROL
;
207 rtlphy
->phyreg_def
[RF90_PATH_A
].rfagc_control1
= ROFDM0_XAAGCCORE1
;
208 rtlphy
->phyreg_def
[RF90_PATH_B
].rfagc_control1
= ROFDM0_XBAGCCORE1
;
209 rtlphy
->phyreg_def
[RF90_PATH_C
].rfagc_control1
= ROFDM0_XCAGCCORE1
;
210 rtlphy
->phyreg_def
[RF90_PATH_D
].rfagc_control1
= ROFDM0_XDAGCCORE1
;
212 rtlphy
->phyreg_def
[RF90_PATH_A
].rfagc_control2
= ROFDM0_XAAGCCORE2
;
213 rtlphy
->phyreg_def
[RF90_PATH_B
].rfagc_control2
= ROFDM0_XBAGCCORE2
;
214 rtlphy
->phyreg_def
[RF90_PATH_C
].rfagc_control2
= ROFDM0_XCAGCCORE2
;
215 rtlphy
->phyreg_def
[RF90_PATH_D
].rfagc_control2
= ROFDM0_XDAGCCORE2
;
217 rtlphy
->phyreg_def
[RF90_PATH_A
].rfrxiq_imbal
= ROFDM0_XARXIQIMBALANCE
;
218 rtlphy
->phyreg_def
[RF90_PATH_B
].rfrxiq_imbal
= ROFDM0_XBRXIQIMBALANCE
;
219 rtlphy
->phyreg_def
[RF90_PATH_C
].rfrxiq_imbal
= ROFDM0_XCRXIQIMBANLANCE
;
220 rtlphy
->phyreg_def
[RF90_PATH_D
].rfrxiq_imbal
= ROFDM0_XDRXIQIMBALANCE
;
222 rtlphy
->phyreg_def
[RF90_PATH_A
].rfrx_afe
= ROFDM0_XARXAFE
;
223 rtlphy
->phyreg_def
[RF90_PATH_B
].rfrx_afe
= ROFDM0_XBRXAFE
;
224 rtlphy
->phyreg_def
[RF90_PATH_C
].rfrx_afe
= ROFDM0_XCRXAFE
;
225 rtlphy
->phyreg_def
[RF90_PATH_D
].rfrx_afe
= ROFDM0_XDRXAFE
;
227 rtlphy
->phyreg_def
[RF90_PATH_A
].rftxiq_imbal
= ROFDM0_XATXIQIMBALANCE
;
228 rtlphy
->phyreg_def
[RF90_PATH_B
].rftxiq_imbal
= ROFDM0_XBTXIQIMBALANCE
;
229 rtlphy
->phyreg_def
[RF90_PATH_C
].rftxiq_imbal
= ROFDM0_XCTXIQIMBALANCE
;
230 rtlphy
->phyreg_def
[RF90_PATH_D
].rftxiq_imbal
= ROFDM0_XDTXIQIMBALANCE
;
232 rtlphy
->phyreg_def
[RF90_PATH_A
].rftx_afe
= ROFDM0_XATXAFE
;
233 rtlphy
->phyreg_def
[RF90_PATH_B
].rftx_afe
= ROFDM0_XBTXAFE
;
234 rtlphy
->phyreg_def
[RF90_PATH_C
].rftx_afe
= ROFDM0_XCTXAFE
;
235 rtlphy
->phyreg_def
[RF90_PATH_D
].rftx_afe
= ROFDM0_XDTXAFE
;
237 rtlphy
->phyreg_def
[RF90_PATH_A
].rf_rb
= RFPGA0_XA_LSSIREADBACK
;
238 rtlphy
->phyreg_def
[RF90_PATH_B
].rf_rb
= RFPGA0_XB_LSSIREADBACK
;
239 rtlphy
->phyreg_def
[RF90_PATH_C
].rf_rb
= RFPGA0_XC_LSSIREADBACK
;
240 rtlphy
->phyreg_def
[RF90_PATH_D
].rf_rb
= RFPGA0_XD_LSSIREADBACK
;
242 rtlphy
->phyreg_def
[RF90_PATH_A
].rf_rbpi
= TRANSCEIVEA_HSPI_READBACK
;
243 rtlphy
->phyreg_def
[RF90_PATH_B
].rf_rbpi
= TRANSCEIVEB_HSPI_READBACK
;
246 EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def
);
248 bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd
*cmdtable
,
251 enum swchnlcmd_id cmdid
,
252 u32 para1
, u32 para2
,
255 struct swchnlcmd
*pcmd
;
257 if (cmdtable
== NULL
) {
258 WARN_ONCE(true, "rtl8723-common: cmdtable cannot be NULL.\n");
262 if (cmdtableidx
>= cmdtablesz
)
265 pcmd
= cmdtable
+ cmdtableidx
;
269 pcmd
->msdelay
= msdelay
;
272 EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray
);
274 void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw
*hw
,
280 u32 oldval_0
, x
, tx0_a
, reg
;
283 if (final_candidate
== 0xFF) {
286 oldval_0
= (rtl_get_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
,
287 MASKDWORD
) >> 22) & 0x3FF;
288 x
= result
[final_candidate
][0];
289 if ((x
& 0x00000200) != 0)
291 tx0_a
= (x
* oldval_0
) >> 8;
292 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
, 0x3FF, tx0_a
);
293 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(31),
294 ((x
* oldval_0
>> 7) & 0x1));
295 y
= result
[final_candidate
][1];
296 if ((y
& 0x00000200) != 0)
298 tx0_c
= (y
* oldval_0
) >> 8;
299 rtl_set_bbreg(hw
, ROFDM0_XCTXAFE
, 0xF0000000,
300 ((tx0_c
& 0x3C0) >> 6));
301 rtl_set_bbreg(hw
, ROFDM0_XATXIQIMBALANCE
, 0x003F0000,
303 rtl_set_bbreg(hw
, ROFDM0_ECCATHRESHOLD
, BIT(29),
304 ((y
* oldval_0
>> 7) & 0x1));
307 reg
= result
[final_candidate
][2];
308 rtl_set_bbreg(hw
, ROFDM0_XARXIQIMBALANCE
, 0x3FF, reg
);
309 reg
= result
[final_candidate
][3] & 0x3F;
310 rtl_set_bbreg(hw
, ROFDM0_XARXIQIMBALANCE
, 0xFC00, reg
);
311 reg
= (result
[final_candidate
][3] >> 6) & 0xF;
312 rtl_set_bbreg(hw
, 0xca0, 0xF0000000, reg
);
315 EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix
);
317 void rtl8723_save_adda_registers(struct ieee80211_hw
*hw
, u32
*addareg
,
318 u32
*addabackup
, u32 registernum
)
322 for (i
= 0; i
< registernum
; i
++)
323 addabackup
[i
] = rtl_get_bbreg(hw
, addareg
[i
], MASKDWORD
);
325 EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers
);
327 void rtl8723_phy_save_mac_registers(struct ieee80211_hw
*hw
,
328 u32
*macreg
, u32
*macbackup
)
330 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
333 for (i
= 0; i
< (IQK_MAC_REG_NUM
- 1); i
++)
334 macbackup
[i
] = rtl_read_byte(rtlpriv
, macreg
[i
]);
335 macbackup
[i
] = rtl_read_dword(rtlpriv
, macreg
[i
]);
337 EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers
);
339 void rtl8723_phy_reload_adda_registers(struct ieee80211_hw
*hw
,
340 u32
*addareg
, u32
*addabackup
,
345 for (i
= 0; i
< regiesternum
; i
++)
346 rtl_set_bbreg(hw
, addareg
[i
], MASKDWORD
, addabackup
[i
]);
348 EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers
);
350 void rtl8723_phy_reload_mac_registers(struct ieee80211_hw
*hw
,
351 u32
*macreg
, u32
*macbackup
)
353 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
356 for (i
= 0; i
< (IQK_MAC_REG_NUM
- 1); i
++)
357 rtl_write_byte(rtlpriv
, macreg
[i
], (u8
) macbackup
[i
]);
358 rtl_write_dword(rtlpriv
, macreg
[i
], macbackup
[i
]);
360 EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers
);
362 void rtl8723_phy_path_adda_on(struct ieee80211_hw
*hw
, u32
*addareg
,
363 bool is_patha_on
, bool is2t
)
365 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
369 if (rtlhal
->hw_type
== HARDWARE_TYPE_RTL8723AE
) {
370 pathon
= is_patha_on
? 0x04db25a4 : 0x0b1b25a4;
373 rtl_set_bbreg(hw
, addareg
[0], MASKDWORD
, 0x0b1b25a0);
375 rtl_set_bbreg(hw
, addareg
[0], MASKDWORD
, pathon
);
380 rtl_set_bbreg(hw
, addareg
[0], MASKDWORD
, pathon
);
383 for (i
= 1; i
< IQK_ADDA_REG_NUM
; i
++)
384 rtl_set_bbreg(hw
, addareg
[i
], MASKDWORD
, pathon
);
386 EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on
);
388 void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw
*hw
,
389 u32
*macreg
, u32
*macbackup
)
391 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
394 rtl_write_byte(rtlpriv
, macreg
[i
], 0x3F);
396 for (i
= 1; i
< (IQK_MAC_REG_NUM
- 1); i
++)
397 rtl_write_byte(rtlpriv
, macreg
[i
],
398 (u8
) (macbackup
[i
] & (~BIT(3))));
399 rtl_write_byte(rtlpriv
, macreg
[i
], (u8
) (macbackup
[i
] & (~BIT(5))));
401 EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration
);
403 void rtl8723_phy_path_a_standby(struct ieee80211_hw
*hw
)
405 rtl_set_bbreg(hw
, 0xe28, MASKDWORD
, 0x0);
406 rtl_set_bbreg(hw
, 0x840, MASKDWORD
, 0x00010000);
407 rtl_set_bbreg(hw
, 0xe28, MASKDWORD
, 0x80800000);
409 EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby
);
411 void rtl8723_phy_pi_mode_switch(struct ieee80211_hw
*hw
, bool pi_mode
)
415 mode
= pi_mode
? 0x01000100 : 0x01000000;
416 rtl_set_bbreg(hw
, 0x820, MASKDWORD
, mode
);
417 rtl_set_bbreg(hw
, 0x828, MASKDWORD
, mode
);
419 EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch
);