1 /******************************************************************************
3 * Copyright(c) 2007 - 2016 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
26 #include "../mp_precomp.h"
27 #include "../phydm_precomp.h"
30 get_mix_mode_tx_agc_bb_swing_offset_8822b(void *dm_void,
31 enum pwrtrack_method method,
32 u8 rf_path, u8 tx_power_index_offest)
34 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
35 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
37 u8 bb_swing_upper_bound = cali_info->default_ofdm_index + 10;
38 u8 bb_swing_lower_bound = 0;
41 u8 tx_bb_swing_index = cali_info->default_ofdm_index;
44 dm, ODM_COMP_TX_PWR_TRACK,
45 "Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d, tx_power_index_offest=%d\n",
46 rf_path, cali_info->absolute_ofdm_swing_idx[rf_path],
47 tx_power_index_offest);
49 if (tx_power_index_offest > 0XF)
50 tx_power_index_offest = 0XF;
52 if (cali_info->absolute_ofdm_swing_idx[rf_path] >= 0 &&
53 cali_info->absolute_ofdm_swing_idx[rf_path] <=
54 tx_power_index_offest) {
55 tx_agc_index = cali_info->absolute_ofdm_swing_idx[rf_path];
56 tx_bb_swing_index = cali_info->default_ofdm_index;
57 } else if (cali_info->absolute_ofdm_swing_idx[rf_path] >
58 tx_power_index_offest) {
59 tx_agc_index = tx_power_index_offest;
60 cali_info->remnant_ofdm_swing_idx[rf_path] =
61 cali_info->absolute_ofdm_swing_idx[rf_path] -
62 tx_power_index_offest;
63 tx_bb_swing_index = cali_info->default_ofdm_index +
64 cali_info->remnant_ofdm_swing_idx[rf_path];
66 if (tx_bb_swing_index > bb_swing_upper_bound)
67 tx_bb_swing_index = bb_swing_upper_bound;
71 if (cali_info->default_ofdm_index >
72 (cali_info->absolute_ofdm_swing_idx[rf_path] * (-1)))
74 cali_info->default_ofdm_index +
75 cali_info->absolute_ofdm_swing_idx[rf_path];
77 tx_bb_swing_index = bb_swing_lower_bound;
79 if (tx_bb_swing_index < bb_swing_lower_bound)
80 tx_bb_swing_index = bb_swing_lower_bound;
83 cali_info->absolute_ofdm_swing_idx[rf_path] = tx_agc_index;
84 cali_info->bb_swing_idx_ofdm[rf_path] = tx_bb_swing_index;
87 dm, ODM_COMP_TX_PWR_TRACK,
88 "MixMode Offset Path_%d cali_info->absolute_ofdm_swing_idx[rf_path]=%d cali_info->bb_swing_idx_ofdm[rf_path]=%d tx_power_index_offest=%d\n",
89 rf_path, cali_info->absolute_ofdm_swing_idx[rf_path],
90 cali_info->bb_swing_idx_ofdm[rf_path], tx_power_index_offest);
95 void odm_tx_pwr_track_set_pwr8822b(void *dm_void, enum pwrtrack_method method,
96 u8 rf_path, u8 channel_mapped_index)
98 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
99 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
100 u8 tx_power_index_offest = 0;
101 u8 tx_power_index = 0;
103 struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
104 struct rtl_phy *rtlphy = &rtlpriv->phy;
105 u8 channel = rtlphy->current_channel;
106 u8 band_width = rtlphy->current_chan_bw;
110 u16 rate = *dm->forced_data_rate;
112 if (!rate) /*auto rate*/
113 tx_rate = dm->tx_rate;
118 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK, "Call:%s tx_rate=0x%X\n",
121 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
122 "pRF->default_ofdm_index=%d pRF->default_cck_index=%d\n",
123 cali_info->default_ofdm_index,
124 cali_info->default_cck_index);
127 dm, ODM_COMP_TX_PWR_TRACK,
128 "pRF->absolute_ofdm_swing_idx=%d pRF->remnant_ofdm_swing_idx=%d pRF->absolute_cck_swing_idx=%d pRF->remnant_cck_swing_idx=%d rf_path=%d\n",
129 cali_info->absolute_ofdm_swing_idx[rf_path],
130 cali_info->remnant_ofdm_swing_idx[rf_path],
131 cali_info->absolute_cck_swing_idx[rf_path],
132 cali_info->remnant_cck_swing_idx, rf_path);
134 if (dm->number_linked_client != 0)
135 tx_power_index = odm_get_tx_power_index(
136 dm, (enum odm_rf_radio_path)rf_path, tx_rate,
137 band_width, channel);
139 if (tx_power_index >= 63)
142 tx_power_index_offest = 63 - tx_power_index;
144 ODM_RT_TRACE(dm, ODM_COMP_TX_PWR_TRACK,
145 "tx_power_index=%d tx_power_index_offest=%d rf_path=%d\n",
146 tx_power_index, tx_power_index_offest, rf_path);
149 BBSWING) { /*use for mp driver clean power tracking status*/
153 dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) |
155 cali_info->absolute_ofdm_swing_idx[rf_path]);
157 dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000,
158 tx_scaling_table_jaguar
160 ->bb_swing_idx_ofdm[rf_path]]);
164 dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) |
166 cali_info->absolute_ofdm_swing_idx[rf_path]);
168 dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000,
169 tx_scaling_table_jaguar
171 ->bb_swing_idx_ofdm[rf_path]]);
177 } else if (method == MIX_MODE) {
180 get_mix_mode_tx_agc_bb_swing_offset_8822b(
181 dm, method, rf_path, tx_power_index_offest);
183 dm, 0xC94, (BIT(29) | BIT(28) | BIT(27) |
185 cali_info->absolute_ofdm_swing_idx[rf_path]);
187 dm, REG_A_TX_SCALE_JAGUAR, 0xFFE00000,
188 tx_scaling_table_jaguar
190 ->bb_swing_idx_ofdm[rf_path]]);
193 dm, ODM_COMP_TX_PWR_TRACK,
194 "TXAGC(0xC94)=0x%x BBSwing(0xc1c)=0x%x BBSwingIndex=%d rf_path=%d\n",
195 odm_get_bb_reg(dm, 0xC94,
196 (BIT(29) | BIT(28) | BIT(27) |
198 odm_get_bb_reg(dm, 0xc1c, 0xFFE00000),
199 cali_info->bb_swing_idx_ofdm[rf_path], rf_path);
203 get_mix_mode_tx_agc_bb_swing_offset_8822b(
204 dm, method, rf_path, tx_power_index_offest);
206 dm, 0xE94, (BIT(29) | BIT(28) | BIT(27) |
208 cali_info->absolute_ofdm_swing_idx[rf_path]);
210 dm, REG_B_TX_SCALE_JAGUAR, 0xFFE00000,
211 tx_scaling_table_jaguar
213 ->bb_swing_idx_ofdm[rf_path]]);
216 dm, ODM_COMP_TX_PWR_TRACK,
217 "TXAGC(0xE94)=0x%x BBSwing(0xe1c)=0x%x BBSwingIndex=%d rf_path=%d\n",
218 odm_get_bb_reg(dm, 0xE94,
219 (BIT(29) | BIT(28) | BIT(27) |
221 odm_get_bb_reg(dm, 0xe1c, 0xFFE00000),
222 cali_info->bb_swing_idx_ofdm[rf_path], rf_path);
231 void get_delta_swing_table_8822b(void *dm_void, u8 **temperature_up_a,
232 u8 **temperature_down_a, u8 **temperature_up_b,
233 u8 **temperature_down_b)
235 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
236 struct dm_rf_calibration_struct *cali_info = &dm->rf_calibrate_info;
238 struct rtl_priv *rtlpriv = (struct rtl_priv *)dm->adapter;
239 struct rtl_phy *rtlphy = &rtlpriv->phy;
240 u8 channel = rtlphy->current_channel;
242 *temperature_up_a = cali_info->delta_swing_table_idx_2ga_p;
243 *temperature_down_a = cali_info->delta_swing_table_idx_2ga_n;
244 *temperature_up_b = cali_info->delta_swing_table_idx_2gb_p;
245 *temperature_down_b = cali_info->delta_swing_table_idx_2gb_n;
247 if (channel >= 36 && channel <= 64) {
248 *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[0];
249 *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[0];
250 *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[0];
251 *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[0];
252 } else if (channel >= 100 && channel <= 144) {
253 *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[1];
254 *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[1];
255 *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[1];
256 *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[1];
257 } else if (channel >= 149 && channel <= 177) {
258 *temperature_up_a = cali_info->delta_swing_table_idx_5ga_p[2];
259 *temperature_down_a = cali_info->delta_swing_table_idx_5ga_n[2];
260 *temperature_up_b = cali_info->delta_swing_table_idx_5gb_p[2];
261 *temperature_down_b = cali_info->delta_swing_table_idx_5gb_n[2];
265 static void _phy_lc_calibrate_8822b(struct phy_dm_struct *dm)
267 u32 lc_cal = 0, cnt = 0;
270 lc_cal = odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK);
273 odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK,
278 for (cnt = 0; cnt < 100; cnt++) {
279 if (odm_get_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, 0x8000) != 0x1)
284 /*Recover channel number*/
285 odm_set_rf_reg(dm, ODM_RF_PATH_A, RF_CHNLBW, RFREGOFFSETMASK, lc_cal);
288 void phy_lc_calibrate_8822b(void *dm_void)
290 struct phy_dm_struct *dm = (struct phy_dm_struct *)dm_void;
291 bool is_start_cont_tx = false, is_single_tone = false,
292 is_carrier_suppression = false;
294 u64 progressing_time;
296 if (is_start_cont_tx || is_single_tone || is_carrier_suppression) {
297 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
298 "[LCK]continues TX ing !!! LCK return\n");
302 start_time = odm_get_current_time(dm);
303 _phy_lc_calibrate_8822b(dm);
304 progressing_time = odm_get_progressing_time(dm, start_time);
305 ODM_RT_TRACE(dm, ODM_COMP_CALIBRATION,
306 "[LCK]LCK progressing_time = %lld\n", progressing_time);
309 void configure_txpower_track_8822b(struct txpwrtrack_cfg *config)
311 config->swing_table_size_cck = TXSCALE_TABLE_SIZE;
312 config->swing_table_size_ofdm = TXSCALE_TABLE_SIZE;
313 config->threshold_iqk = IQK_THRESHOLD;
314 config->threshold_dpk = DPK_THRESHOLD;
315 config->average_thermal_num = AVG_THERMAL_NUM_8822B;
316 config->rf_path_count = MAX_PATH_NUM_8822B;
317 config->thermal_reg_addr = RF_T_METER_8822B;
319 config->odm_tx_pwr_track_set_pwr = odm_tx_pwr_track_set_pwr8822b;
320 config->do_iqk = do_iqk_8822b;
321 config->phy_lc_calibrate = phy_lc_calibrate_8822b;
323 config->get_delta_swing_table = get_delta_swing_table_8822b;
326 void phy_set_rf_path_switch_8822b(struct phy_dm_struct *dm, bool is_main)
329 odm_set_bb_reg(dm, 0x4C, (BIT(24) | BIT(23)), 0x2);
330 odm_set_bb_reg(dm, 0x974, 0xff, 0xff);
332 /*odm_set_bb_reg(dm, 0x1991, 0x3, 0x0);*/
333 odm_set_bb_reg(dm, 0x1990, (BIT(9) | BIT(8)), 0x0);
335 /*odm_set_bb_reg(dm, 0xCBE, 0x8, 0x0);*/
336 odm_set_bb_reg(dm, 0xCBC, BIT(19), 0x0);
338 odm_set_bb_reg(dm, 0xCB4, 0xff, 0x77);
340 odm_set_bb_reg(dm, 0x70, MASKBYTE3, 0x0e);
341 odm_set_bb_reg(dm, 0x1704, MASKDWORD, 0x0000ff00);
342 odm_set_bb_reg(dm, 0x1700, MASKDWORD, 0xc00f0038);
345 /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x2); WiFi */
346 odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x2); /*WiFi */
348 /*odm_set_bb_reg(dm, 0xCBD, 0x3, 0x1); BT*/
349 odm_set_bb_reg(dm, 0xCBC, (BIT(9) | BIT(8)), 0x1); /*BT*/