linux/drivers/staging/rtl8723bs/hal/HalPhyRf.c
<<
>>
Prefs
   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}
 274