HalPhyRf.c (10153B)
1// SPDX-License-Identifier: GPL-2.0 2/****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 8/* include "Mp_Precomp.h" */ 9#include "odm_precomp.h" 10 11void ConfigureTxpowerTrack(struct dm_odm_t *pDM_Odm, struct txpwrtrack_cfg *pConfig) 12{ 13 ConfigureTxpowerTrack_8723B(pConfig); 14} 15 16/* */ 17/* <20121113, Kordan> This function should be called when TxAGC changed. */ 18/* Otherwise the previous compensation is gone, because we record the */ 19/* delta of temperature between two TxPowerTracking watch dogs. */ 20/* */ 21/* NOTE: If Tx BB swing or Tx scaling is varified during run-time, still */ 22/* need to call this function. */ 23/* */ 24void ODM_ClearTxPowerTrackingState(struct dm_odm_t *pDM_Odm) 25{ 26 struct hal_com_data *pHalData = GET_HAL_DATA(pDM_Odm->Adapter); 27 u8 p = 0; 28 29 pDM_Odm->BbSwingIdxCckBase = pDM_Odm->DefaultCckIndex; 30 pDM_Odm->BbSwingIdxCck = pDM_Odm->DefaultCckIndex; 31 pDM_Odm->RFCalibrateInfo.CCK_index = 0; 32 33 for (p = RF_PATH_A; p < MAX_RF_PATH; ++p) { 34 pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->DefaultOfdmIndex; 35 pDM_Odm->BbSwingIdxOfdm[p] = pDM_Odm->DefaultOfdmIndex; 36 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = pDM_Odm->DefaultOfdmIndex; 37 38 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; 39 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] = 0; 40 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] = 0; 41 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; 42 43 /* Initial Mix mode power tracking */ 44 pDM_Odm->Absolute_OFDMSwingIdx[p] = 0; 45 pDM_Odm->Remnant_OFDMSwingIdx[p] = 0; 46 } 47 48 /* Initial at Modify Tx Scaling Mode */ 49 pDM_Odm->Modify_TxAGC_Flag_PathA = false; 50 /* Initial at Modify Tx Scaling Mode */ 51 pDM_Odm->Modify_TxAGC_Flag_PathB = false; 52 pDM_Odm->Remnant_CCKSwingIdx = 0; 53 pDM_Odm->RFCalibrateInfo.ThermalValue = pHalData->EEPROMThermalMeter; 54 pDM_Odm->RFCalibrateInfo.ThermalValue_IQK = pHalData->EEPROMThermalMeter; 55 pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = pHalData->EEPROMThermalMeter; 56} 57 58void ODM_TXPowerTrackingCallback_ThermalMeter(struct adapter *Adapter) 59{ 60 61 struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); 62 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv; 63 64 u8 ThermalValue = 0, delta, delta_LCK, p = 0, i = 0; 65 u8 ThermalValue_AVG_count = 0; 66 u32 ThermalValue_AVG = 0; 67 68 u8 OFDM_min_index = 0; /* OFDM BB Swing should be less than +3.0dB, which is required by Arthur */ 69 u8 Indexforchannel = 0; /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel) */ 70 71 struct txpwrtrack_cfg c; 72 73 74 /* 4 1. The following TWO tables decide the final index of OFDM/CCK swing table. */ 75 u8 *deltaSwingTableIdx_TUP_A; 76 u8 *deltaSwingTableIdx_TDOWN_A; 77 u8 *deltaSwingTableIdx_TUP_B; 78 u8 *deltaSwingTableIdx_TDOWN_B; 79 80 /* 4 2. Initialization (7 steps in total) */ 81 82 ConfigureTxpowerTrack(pDM_Odm, &c); 83 84 (*c.GetDeltaSwingTable)( 85 pDM_Odm, 86 (u8 **)&deltaSwingTableIdx_TUP_A, 87 (u8 **)&deltaSwingTableIdx_TDOWN_A, 88 (u8 **)&deltaSwingTableIdx_TUP_B, 89 (u8 **)&deltaSwingTableIdx_TDOWN_B 90 ); 91 92 /* cosa add for debug */ 93 pDM_Odm->RFCalibrateInfo.TXPowerTrackingCallbackCnt++; 94 pDM_Odm->RFCalibrateInfo.bTXPowerTrackingInit = true; 95 96 ThermalValue = (u8)PHY_QueryRFReg(pDM_Odm->Adapter, RF_PATH_A, c.ThermalRegAddr, 0xfc00); /* 0x42: RF Reg[15:10] 88E */ 97 if ( 98 !pDM_Odm->RFCalibrateInfo.TxPowerTrackControl || 99 pHalData->EEPROMThermalMeter == 0 || 100 pHalData->EEPROMThermalMeter == 0xFF 101 ) 102 return; 103 104 /* 4 3. Initialize ThermalValues of RFCalibrateInfo */ 105 106 /* 4 4. Calculate average thermal meter */ 107 108 pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index] = ThermalValue; 109 pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index++; 110 if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index == c.AverageThermalNum) /* Average times = c.AverageThermalNum */ 111 pDM_Odm->RFCalibrateInfo.ThermalValue_AVG_index = 0; 112 113 for (i = 0; i < c.AverageThermalNum; i++) { 114 if (pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]) { 115 ThermalValue_AVG += pDM_Odm->RFCalibrateInfo.ThermalValue_AVG[i]; 116 ThermalValue_AVG_count++; 117 } 118 } 119 120 /* Calculate Average ThermalValue after average enough times */ 121 if (ThermalValue_AVG_count) { 122 ThermalValue = (u8)(ThermalValue_AVG / ThermalValue_AVG_count); 123 } 124 125 /* 4 5. Calculate delta, delta_LCK */ 126 /* delta" here is used to determine whether thermal value changes or not. */ 127 delta = 128 (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue) ? 129 (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue) : 130 (pDM_Odm->RFCalibrateInfo.ThermalValue - ThermalValue); 131 delta_LCK = 132 (ThermalValue > pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) ? 133 (ThermalValue - pDM_Odm->RFCalibrateInfo.ThermalValue_LCK) : 134 (pDM_Odm->RFCalibrateInfo.ThermalValue_LCK - ThermalValue); 135 136 /* 4 6. If necessary, do LCK. */ 137 /* Delta temperature is equal to or larger than 20 centigrade. */ 138 if (delta_LCK >= c.Threshold_IQK) { 139 pDM_Odm->RFCalibrateInfo.ThermalValue_LCK = ThermalValue; 140 if (c.PHY_LCCalibrate) 141 (*c.PHY_LCCalibrate)(pDM_Odm); 142 } 143 144 /* 3 7. If necessary, move the index of swing table to adjust Tx power. */ 145 if (delta > 0 && pDM_Odm->RFCalibrateInfo.TxPowerTrackControl) { 146 /* delta" here is used to record the absolute value of difference. */ 147 delta = 148 ThermalValue > pHalData->EEPROMThermalMeter ? 149 (ThermalValue - pHalData->EEPROMThermalMeter) : 150 (pHalData->EEPROMThermalMeter - ThermalValue); 151 152 if (delta >= TXPWR_TRACK_TABLE_SIZE) 153 delta = TXPWR_TRACK_TABLE_SIZE - 1; 154 155 /* 4 7.1 The Final Power Index = BaseIndex + PowerIndexOffset */ 156 if (ThermalValue > pHalData->EEPROMThermalMeter) { 157 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_A] = 158 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A]; 159 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A] = 160 deltaSwingTableIdx_TUP_A[delta]; 161 162 /* Record delta swing for mix mode power tracking */ 163 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_A] = 164 deltaSwingTableIdx_TUP_A[delta]; 165 166 if (c.RfPathCount > 1) { 167 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_B] = 168 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B]; 169 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B] = 170 deltaSwingTableIdx_TUP_B[delta]; 171 172 /* Record delta swing for mix mode power tracking */ 173 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_B] = 174 deltaSwingTableIdx_TUP_B[delta]; 175 } 176 177 } else { 178 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_A] = 179 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A]; 180 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_A] = 181 -1 * deltaSwingTableIdx_TDOWN_A[delta]; 182 183 /* Record delta swing for mix mode power tracking */ 184 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_A] = 185 -1 * deltaSwingTableIdx_TDOWN_A[delta]; 186 187 if (c.RfPathCount > 1) { 188 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[RF_PATH_B] = 189 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B]; 190 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[RF_PATH_B] = 191 -1 * deltaSwingTableIdx_TDOWN_B[delta]; 192 193 /* Record delta swing for mix mode power tracking */ 194 pDM_Odm->Absolute_OFDMSwingIdx[RF_PATH_B] = 195 -1 * deltaSwingTableIdx_TDOWN_B[delta]; 196 } 197 } 198 199 for (p = RF_PATH_A; p < c.RfPathCount; p++) { 200 if ( 201 pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] == 202 pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p] 203 ) /* If Thermal value changes but lookup table value still the same */ 204 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; 205 else 206 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = pDM_Odm->RFCalibrateInfo.DeltaPowerIndex[p] - pDM_Odm->RFCalibrateInfo.DeltaPowerIndexLast[p]; /* Power Index Diff between 2 times Power Tracking */ 207 208 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = 209 pDM_Odm->BbSwingIdxOfdmBase[p] + 210 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]; 211 212 pDM_Odm->RFCalibrateInfo.CCK_index = 213 pDM_Odm->BbSwingIdxCckBase + 214 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p]; 215 216 pDM_Odm->BbSwingIdxCck = 217 pDM_Odm->RFCalibrateInfo.CCK_index; 218 219 pDM_Odm->BbSwingIdxOfdm[p] = 220 pDM_Odm->RFCalibrateInfo.OFDM_index[p]; 221 222 /* 4 7.1 Handle boundary conditions of index. */ 223 if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] > c.SwingTableSize_OFDM-1) 224 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = c.SwingTableSize_OFDM-1; 225 else if (pDM_Odm->RFCalibrateInfo.OFDM_index[p] < OFDM_min_index) 226 pDM_Odm->RFCalibrateInfo.OFDM_index[p] = OFDM_min_index; 227 } 228 if (pDM_Odm->RFCalibrateInfo.CCK_index > c.SwingTableSize_CCK-1) 229 pDM_Odm->RFCalibrateInfo.CCK_index = c.SwingTableSize_CCK-1; 230 /* else if (pDM_Odm->RFCalibrateInfo.CCK_index < 0) */ 231 /* pDM_Odm->RFCalibrateInfo.CCK_index = 0; */ 232 } else { 233 for (p = RF_PATH_A; p < c.RfPathCount; p++) 234 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[p] = 0; 235 } 236 237 /* Print Swing base & current */ 238 for (p = RF_PATH_A; p < c.RfPathCount; p++) { 239 } 240 241 if ( 242 (pDM_Odm->RFCalibrateInfo.PowerIndexOffset[RF_PATH_A] != 0 || 243 pDM_Odm->RFCalibrateInfo.PowerIndexOffset[RF_PATH_B] != 0) && 244 pDM_Odm->RFCalibrateInfo.TxPowerTrackControl 245 ) { 246 /* 4 7.2 Configure the Swing Table to adjust Tx Power. */ 247 248 pDM_Odm->RFCalibrateInfo.bTxPowerChanged = true; /* Always true after Tx Power is adjusted by power tracking. */ 249 /* */ 250 /* 2012/04/23 MH According to Luke's suggestion, we can not write BB digital */ 251 /* to increase TX power. Otherwise, EVM will be bad. */ 252 /* */ 253 /* 2012/04/25 MH Add for tx power tracking to set tx power in tx agc for 88E. */ 254 255 if (ThermalValue > pHalData->EEPROMThermalMeter) { 256 for (p = RF_PATH_A; p < c.RfPathCount; p++) 257 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, 0); 258 } else { 259 for (p = RF_PATH_A; p < c.RfPathCount; p++) 260 (*c.ODM_TxPwrTrackSetPwr)(pDM_Odm, MIX_MODE, p, Indexforchannel); 261 } 262 263 /* Record last time Power Tracking result as base. */ 264 pDM_Odm->BbSwingIdxCckBase = pDM_Odm->BbSwingIdxCck; 265 for (p = RF_PATH_A; p < c.RfPathCount; p++) 266 pDM_Odm->BbSwingIdxOfdmBase[p] = pDM_Odm->BbSwingIdxOfdm[p]; 267 268 /* Record last Power Tracking Thermal Value */ 269 pDM_Odm->RFCalibrateInfo.ThermalValue = ThermalValue; 270 } 271 272 pDM_Odm->RFCalibrateInfo.TXPowercount = 0; 273}