The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_aic.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
    3  *
    4  * Permission to use, copy, modify, and/or distribute this software for any
    5  * purpose with or without fee is hereby granted, provided that the above
    6  * copyright notice and this permission notice appear in all copies.
    7  *
    8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
   10  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
   11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
   12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
   13  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
   14  * PERFORMANCE OF THIS SOFTWARE.
   15  */
   16 
   17 
   18 #include "opt_ah.h"
   19 
   20 #ifdef AH_SUPPORT_AR9300
   21 
   22 #include "ah.h"
   23 #include "ah_internal.h"
   24 
   25 #include "ar9300/ar9300.h"
   26 #include "ar9300/ar9300reg.h"
   27 #include "ar9300/ar9300phy.h"
   28 
   29 #if ATH_SUPPORT_AIC
   30 
   31 #define ATH_AIC_TEST_PATTERN    1
   32 
   33 struct ath_aic_sram_info {
   34     HAL_BOOL        valid;
   35     u_int8_t    rot_quad_att_db;
   36     HAL_BOOL        vga_quad_sign;
   37     u_int8_t    rot_dir_att_db;
   38     HAL_BOOL        vga_dir_sign;
   39     u_int8_t    com_att_6db;
   40     };
   41 
   42 struct ath_aic_out_info {
   43     int16_t     dir_path_gain_lin;
   44     int16_t     quad_path_gain_lin;
   45     struct ath_aic_sram_info sram;
   46     };
   47 
   48 #define ATH_AIC_MAX_COM_ATT_DB_TABLE    6
   49 #define ATH_AIC_MAX_AIC_LIN_TABLE       69
   50 #define ATH_AIC_MIN_ROT_DIR_ATT_DB      0
   51 #define ATH_AIC_MIN_ROT_QUAD_ATT_DB     0
   52 #define ATH_AIC_MAX_ROT_DIR_ATT_DB      37
   53 #define ATH_AIC_MAX_ROT_QUAD_ATT_DB     37
   54 #define ATH_AIC_SRAM_AUTO_INCREMENT     0x80000000
   55 #define ATH_AIC_SRAM_GAIN_TABLE_OFFSET  0x280
   56 #define ATH_AIC_SRAM_CAL_OFFSET         0x140
   57 #define ATH_AIC_MAX_CAL_COUNT           5
   58 #define ATH_AIC_MEAS_MAG_THRESH         20
   59 #define ATH_AIC_BT_JUPITER_CTRL         0x66820
   60 #define ATH_AIC_BT_AIC_ENABLE           0x02
   61 
   62 
   63 static const u_int8_t com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = {
   64         0, 3, 9, 15, 21, 27};
   65 
   66 static const u_int16_t aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE] = {
   67         8191, 7300, 6506, 5799, 5168, 4606, 4105, 3659,
   68         3261, 2906, 2590, 2309, 2057, 1834, 1634, 1457,
   69         1298, 1157, 1031,  919,  819,  730,  651,  580,
   70          517,  461,  411,  366,  326,  291,  259,  231,
   71          206,  183,  163,  146,  130,  116,  103,   92,
   72           82,   73,   65,   58,   52,   46,   41,   37,
   73           33,   29,   26,   23,   21,   18,   16,   15,
   74           13,   12,   10,    9,    8,    7,    7,    6,
   75            5,    5,    4,    4,    3};
   76 
   77 #if ATH_AIC_TEST_PATTERN
   78 static const u_int32_t aic_test_pattern[ATH_AIC_MAX_BT_CHANNEL] = {
   79 0x00000,    // 0
   80 0x00000,
   81 0x00000,
   82 0x00000,
   83 0x00000,
   84 0x00000,
   85 0x00000,
   86 0x00000,
   87 0x00000,
   88 0x1918d,
   89 0x1938d,    // 10
   90 0x00000,
   91 0x1978d,
   92 0x19e8d,
   93 0x00000,
   94 0x00000,
   95 0x00000,
   96 0x00000,
   97 0x00000,
   98 0x00000,
   99 0x00000,    // 20
  100 0x00000,
  101 0x00000,
  102 0x1ce8f,
  103 0x00000,
  104 0x00000,
  105 0x00000,
  106 0x00000,
  107 0x1ca93,
  108 0x1c995,
  109 0x00000,    // 30
  110 0x1c897,
  111 0x1c899,
  112 0x00000,
  113 0x00000,
  114 0x1c79f,
  115 0x00000,
  116 0x1c7a5,
  117 0x1c6ab,
  118 0x00000,
  119 0x00000,    // 40
  120 0x00000,
  121 0x00000,
  122 0x1c63f,
  123 0x00000,
  124 0x1c52b,
  125 0x1c525,
  126 0x1c523,
  127 0x00000,
  128 0x00000,
  129 0x00000,    // 50
  130 0x00000,
  131 0x00000,
  132 0x1c617,
  133 0x00000,
  134 0x1c615,
  135 0x1c613,
  136 0x00000,
  137 0x00000,
  138 0x00000,
  139 0x00000,    // 60
  140 0x1c80f,
  141 0x1c90f,
  142 0x1c90f,
  143 0x1ca0f,
  144 0x1ca0d,
  145 0x1cb0d,
  146 0x00000,
  147 0x00000,
  148 0x00000,
  149 0x00000,    // 70
  150 0x1d00d,
  151 0x00000,
  152 0x00000,
  153 0x00000,
  154 0x00000,
  155 0x00000,
  156 0x00000,
  157 0x00000
  158 };
  159 #endif
  160 
  161 static void
  162 ar9300_aic_gain_table(struct ath_hal *ah)
  163 {
  164     u_int32_t   aic_atten_word[19], i;
  165 
  166     /* Program gain table */
  167     aic_atten_word[0] = (0x1 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x0 & 0xf)<<5 | 
  168                 (0x1f & 0x1f); // -01 dB: 4'd1, 5'd31,  00 dB: 4'd0, 5'd31;
  169     aic_atten_word[1] = (0x3 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x2 & 0xf)<<5 | 
  170                 (0x1f & 0x1f); // -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31;
  171     aic_atten_word[2] = (0x5 & 0xf)<<14 | (0x1f & 0x1f)<<9 | (0x4 & 0xf)<<5 | 
  172                 (0x1f & 0x1f); // -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31;
  173     aic_atten_word[3] = (0x1 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x0 & 0xf)<<5 | 
  174                 (0x1e & 0x1f); // -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30;
  175     aic_atten_word[4] = (0x3 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x2 & 0xf)<<5 | 
  176                 (0x1e & 0x1f); // -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30;
  177     aic_atten_word[5] = (0x5 & 0xf)<<14 | (0x1e & 0x1f)<<9 | (0x4 & 0xf)<<5 | 
  178                 (0x1e & 0x1f); // -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30;
  179     aic_atten_word[6] = (0x1 & 0xf)<<14 | (0xf & 0x1f)<<9  | (0x0 & 0xf)<<5 | 
  180                 (0xf & 0x1f);  // -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15;
  181     aic_atten_word[7] = (0x3 & 0xf)<<14 | (0xf & 0x1f)<<9  | (0x2 & 0xf)<<5 | 
  182                 (0xf & 0x1f);  // -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15;
  183     aic_atten_word[8] = (0x5 & 0xf)<<14 | (0xf & 0x1f)<<9  | (0x4 & 0xf)<<5 | 
  184                 (0xf & 0x1f);  // -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15;
  185     aic_atten_word[9] = (0x1 & 0xf)<<14 | (0x7 & 0x1f)<<9  | (0x0 & 0xf)<<5 | 
  186                 (0x7 & 0x1f);  // -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07;
  187     aic_atten_word[10] =(0x3 & 0xf)<<14 | (0x7 & 0x1f)<<9  | (0x2 & 0xf)<<5 | 
  188                 (0x7 & 0x1f);  // -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07;
  189     aic_atten_word[11] =(0x5 & 0xf)<<14 | (0x7 & 0x1f)<<9  | (0x4 & 0xf)<<5 | 
  190                 (0x7 & 0x1f);  // -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07;
  191     aic_atten_word[12] =(0x7 & 0xf)<<14 | (0x7 & 0x1f)<<9  | (0x6 & 0xf)<<5 | 
  192                 (0x7 & 0x1f);  // -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07;
  193     aic_atten_word[13] =(0x3 & 0xf)<<14 | (0x3 & 0x1f)<<9  | (0x2 & 0xf)<<5 | 
  194                 (0x3 & 0x1f);  // -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03;
  195     aic_atten_word[14] =(0x5 & 0xf)<<14 | (0x3 & 0x1f)<<9  | (0x4 & 0xf)<<5 | 
  196                 (0x3 & 0x1f);  // -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03;    
  197     aic_atten_word[15] =(0x1 & 0xf)<<14 | (0x1 & 0x1f)<<9  | (0x0 & 0xf)<<5 | 
  198                 (0x1 & 0x1f);  // -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01;
  199     aic_atten_word[16] =(0x3 & 0xf)<<14 | (0x1 & 0x1f)<<9  | (0x2 & 0xf)<<5 | 
  200                 (0x1 & 0x1f);  // -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01;
  201     aic_atten_word[17] =(0x5 & 0xf)<<14 | (0x1 & 0x1f)<<9  | (0x4 & 0xf)<<5 | 
  202                 (0x1 & 0x1f);  // -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01;
  203     aic_atten_word[18] =(0x7 & 0xf)<<14 | (0x1 & 0x1f)<<9  | (0x6 & 0xf)<<5 | 
  204                 (0x1 & 0x1f);  // -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01;
  205 
  206     /* Write to Gain table with auto increment enabled. */
  207     OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000), 
  208                  (ATH_AIC_SRAM_AUTO_INCREMENT | 
  209                   ATH_AIC_SRAM_GAIN_TABLE_OFFSET));
  210 
  211     for (i = 0; i < 19; i++) {
  212         OS_REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000),
  213                     aic_atten_word[i]);
  214     }
  215 
  216 }
  217 
  218 static int16_t 
  219 ar9300_aic_find_valid (struct ath_aic_sram_info *cal_sram, 
  220                            HAL_BOOL dir,
  221                            u_int8_t index)
  222 {
  223     int16_t i;
  224 
  225     if (dir) {
  226         /* search forward */
  227         for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  228             if (cal_sram[i].valid) {
  229                 break;
  230             }
  231         }
  232     }
  233     else {
  234         /* search backword */
  235         for (i = index - 1; i >= 0; i--) {
  236             if (cal_sram[i].valid) {
  237                 break;
  238             }
  239         }
  240     }
  241     if ((i >= ATH_AIC_MAX_BT_CHANNEL) || (i < 0)) {
  242         i = -1;
  243     }
  244 
  245     return i;
  246 }
  247 
  248 static int16_t
  249 ar9300_aic_find_index (u_int8_t type, int16_t value)
  250 {
  251     int16_t i = -1;
  252 
  253     /* 
  254      * type 0: aic_lin_table, 1: com_att_db_table
  255      */
  256 
  257     if (type == 0) {
  258         /* Find in aic_lin_table */
  259         for (i = ATH_AIC_MAX_AIC_LIN_TABLE - 1; i >= 0; i--) {
  260             if (aic_lin_table[i] >= value) {
  261                 break;
  262             }
  263         }
  264     }
  265     else if (type == 1) {
  266         /* find in com_att_db_table */
  267         for (i = 0; i < ATH_AIC_MAX_COM_ATT_DB_TABLE; i++) {
  268             if (com_att_db_table[i] > value) {
  269                 i--;
  270                 break;
  271             }
  272         }
  273         if (i >= ATH_AIC_MAX_COM_ATT_DB_TABLE) {
  274             i = -1;
  275         }
  276     }
  277 
  278     return i;
  279 }
  280 
  281 static HAL_BOOL
  282 ar9300_aic_cal_post_process (struct ath_hal *ah)
  283 {
  284     struct ath_hal_9300 *ahp = AH9300(ah);
  285     struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL];
  286     struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL];
  287     u_int32_t dir_path_gain_idx, quad_path_gain_idx, value;
  288     u_int32_t fixed_com_att_db;
  289     int8_t dir_path_sign, quad_path_sign;
  290     int16_t i;
  291     HAL_BOOL ret = AH_TRUE;
  292 
  293     /* Read CAL_SRAM and get valid values. */
  294     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) CAL_SRAM:\n");
  295 
  296     for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  297         OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, 
  298                     (ATH_AIC_SRAM_CAL_OFFSET + i*4));
  299 #if ATH_AIC_TEST_PATTERN
  300         value = aic_test_pattern[i];
  301 #else
  302         value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
  303 #endif
  304         cal_sram[i].valid = MS(value, AR_PHY_AIC_SRAM_VALID);
  305         cal_sram[i].rot_quad_att_db = MS(value, 
  306                                          AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB);
  307         cal_sram[i].vga_quad_sign = MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN);
  308         cal_sram[i].rot_dir_att_db = MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB);
  309         cal_sram[i].vga_dir_sign = MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN);
  310         cal_sram[i].com_att_6db = MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB);
  311 
  312         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  313                 "(AIC) %2d   %2d   %2d   %2d   %2d   %2d   %2d   0x%05x\n",
  314                 i, cal_sram[i].vga_quad_sign,
  315                 cal_sram[i].vga_dir_sign,
  316                 cal_sram[i].rot_dir_att_db,
  317                 cal_sram[i].rot_quad_att_db,
  318                 cal_sram[i].com_att_6db,
  319                 cal_sram[i].valid,
  320                 value);
  321 
  322         if (cal_sram[i].valid) {
  323             dir_path_gain_idx = cal_sram[i].rot_dir_att_db +
  324                         com_att_db_table[cal_sram[i].com_att_6db];
  325             quad_path_gain_idx = cal_sram[i].rot_quad_att_db +
  326                         com_att_db_table[cal_sram[i].com_att_6db];
  327             dir_path_sign = (cal_sram[i].vga_dir_sign) ? 1 : -1;
  328             quad_path_sign = (cal_sram[i].vga_quad_sign) ? 1 : -1;
  329             aic_sram[i].dir_path_gain_lin = dir_path_sign *
  330                         aic_lin_table[dir_path_gain_idx];
  331             aic_sram[i].quad_path_gain_lin = quad_path_sign *
  332                         aic_lin_table[quad_path_gain_idx];
  333         }
  334     }
  335 
  336     for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  337         int16_t start_idx, end_idx;
  338 
  339         if (cal_sram[i].valid) {
  340             continue;
  341         }
  342 
  343         start_idx = ar9300_aic_find_valid(cal_sram, 0, i);
  344         end_idx = ar9300_aic_find_valid(cal_sram, 1, i);
  345 
  346         if (start_idx < 0)
  347         {
  348             /* extrapolation */
  349             start_idx = end_idx;
  350             end_idx = ar9300_aic_find_valid(cal_sram, 1, start_idx);
  351 
  352             if (end_idx < 0) {
  353                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  354                         "(AIC) Error (1): i = %d, start_idx = %d \n",
  355                         i, start_idx);
  356                 ret = AH_FALSE;
  357                 break;
  358             }
  359             aic_sram[i].dir_path_gain_lin = 
  360                     ((aic_sram[start_idx].dir_path_gain_lin - 
  361                       aic_sram[end_idx].dir_path_gain_lin) *
  362                      (start_idx - i) + ((end_idx - i) >> 1)) / 
  363                      (end_idx - i) +
  364                      aic_sram[start_idx].dir_path_gain_lin;
  365             aic_sram[i].quad_path_gain_lin = 
  366                     ((aic_sram[start_idx].quad_path_gain_lin - 
  367                       aic_sram[end_idx].quad_path_gain_lin) *
  368                      (start_idx - i) + ((end_idx - i) >> 1)) / 
  369                      (end_idx - i) +
  370                      aic_sram[start_idx].quad_path_gain_lin;
  371         }
  372         if (end_idx < 0)
  373         {
  374             /* extrapolation */
  375             end_idx = ar9300_aic_find_valid(cal_sram, 0, start_idx);
  376 
  377             if (end_idx < 0) {
  378                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  379                         "(AIC) Error (2): i = %d, start_idx = %d\n",
  380                         i, start_idx);
  381                 ret = AH_FALSE;
  382                 break;
  383             }
  384             aic_sram[i].dir_path_gain_lin = 
  385                     ((aic_sram[start_idx].dir_path_gain_lin - 
  386                       aic_sram[end_idx].dir_path_gain_lin) *
  387                      (i - start_idx) + ((start_idx - end_idx) >> 1)) / 
  388                      (start_idx - end_idx) +
  389                      aic_sram[start_idx].dir_path_gain_lin;
  390             aic_sram[i].quad_path_gain_lin = 
  391                     ((aic_sram[start_idx].quad_path_gain_lin - 
  392                       aic_sram[end_idx].quad_path_gain_lin) *
  393                      (i - start_idx) + ((start_idx - end_idx) >> 1)) / 
  394                      (start_idx - end_idx) + 
  395                      aic_sram[start_idx].quad_path_gain_lin;
  396             
  397         }
  398         else {
  399             /* interpolation */
  400             aic_sram[i].dir_path_gain_lin = 
  401                     (((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) +
  402                      ((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) +
  403                      ((end_idx - start_idx) >> 1)) / 
  404                      (end_idx - start_idx);
  405             aic_sram[i].quad_path_gain_lin = 
  406                     (((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) +
  407                      ((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) +
  408                      ((end_idx - start_idx) >> 1))/ 
  409                      (end_idx - start_idx);
  410         }
  411     }
  412 
  413     /* From dir/quad_path_gain_lin to sram. */
  414     i = ar9300_aic_find_valid(cal_sram, 1, 0);
  415     if (i < 0) {
  416         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  417                 "(AIC) Error (3): can't find valid. Force it to 0.\n");
  418         i = 0;
  419         ret = AH_FALSE;
  420     }
  421     fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db];
  422 
  423     for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  424         int16_t rot_dir_path_att_db, rot_quad_path_att_db;
  425 
  426         aic_sram[i].sram.vga_dir_sign = (aic_sram[i].dir_path_gain_lin >= 0)
  427                                         ? 1 : 0;
  428         aic_sram[i].sram.vga_quad_sign= (aic_sram[i].quad_path_gain_lin >= 0) 
  429                                         ? 1 : 0;
  430 
  431         rot_dir_path_att_db = 
  432             ar9300_aic_find_index(0, abs(aic_sram[i].dir_path_gain_lin)) -
  433             fixed_com_att_db;
  434         rot_quad_path_att_db = 
  435             ar9300_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) -
  436             fixed_com_att_db;
  437 
  438         aic_sram[i].sram.com_att_6db = ar9300_aic_find_index(1, 
  439                                                             fixed_com_att_db);
  440 
  441         aic_sram[i].sram.valid = 1;
  442         aic_sram[i].sram.rot_dir_att_db = 
  443             MIN(MAX(rot_dir_path_att_db, ATH_AIC_MIN_ROT_DIR_ATT_DB),
  444                 ATH_AIC_MAX_ROT_DIR_ATT_DB);
  445         aic_sram[i].sram.rot_quad_att_db = 
  446             MIN(MAX(rot_quad_path_att_db, ATH_AIC_MIN_ROT_QUAD_ATT_DB),
  447                 ATH_AIC_MAX_ROT_QUAD_ATT_DB);
  448     }
  449 
  450     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Post processing results:\n");
  451 
  452     for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  453         ahp->ah_aic_sram[i] = (SM(aic_sram[i].sram.vga_dir_sign, 
  454                                   AR_PHY_AIC_SRAM_VGA_DIR_SIGN) |
  455                                SM(aic_sram[i].sram.vga_quad_sign, 
  456                                   AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) |
  457                                SM(aic_sram[i].sram.com_att_6db, 
  458                                   AR_PHY_AIC_SRAM_COM_ATT_6DB) |
  459                                SM(aic_sram[i].sram.valid, 
  460                                   AR_PHY_AIC_SRAM_VALID) |
  461                                SM(aic_sram[i].sram.rot_dir_att_db, 
  462                                   AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) |
  463                                SM(aic_sram[i].sram.rot_quad_att_db, 
  464                                   AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB));
  465 
  466 
  467         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
  468                 "(AIC) ch%02d 0x%05x  %2d  %2d  %2d  %2d  %2d  %2d  %d  %d\n",
  469                 i, 
  470                 ahp->ah_aic_sram[i],
  471                 aic_sram[i].sram.vga_quad_sign,
  472                 aic_sram[i].sram.vga_dir_sign,
  473                 aic_sram[i].sram.rot_dir_att_db,
  474                 aic_sram[i].sram.rot_quad_att_db,
  475                 aic_sram[i].sram.com_att_6db,
  476                 aic_sram[i].sram.valid,
  477                 aic_sram[i].dir_path_gain_lin,
  478                 aic_sram[i].quad_path_gain_lin);
  479     }
  480 
  481     return ret;
  482 }
  483 
  484 u_int32_t
  485 ar9300_aic_calibration(struct ath_hal *ah)
  486 {
  487     u_int32_t   aic_ctrl_b0[5], aic_ctrl_b1[5];
  488     u_int32_t   aic_stat_b0[2], aic_stat_b1[2];
  489     u_int32_t   aic_stat, value;
  490     u_int32_t   i, cal_count = ATH_AIC_MAX_CAL_COUNT;
  491     struct ath_hal_9300 *ahp = AH9300(ah);
  492 
  493     if (AR_SREV_JUPITER_10(ah)) {
  494         aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_10;
  495         aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_10;
  496         aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_10;
  497         aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_10;
  498         aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_10;
  499         aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_10;
  500         aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_10;
  501         aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_10;
  502         aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_10;
  503         aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_10;
  504     }
  505     else {
  506         aic_ctrl_b0[0] = AR_PHY_AIC_CTRL_0_B0_20;
  507         aic_ctrl_b0[1] = AR_PHY_AIC_CTRL_1_B0_20;
  508         aic_ctrl_b0[2] = AR_PHY_AIC_CTRL_2_B0_20;
  509         aic_ctrl_b0[3] = AR_PHY_AIC_CTRL_3_B0_20;
  510         aic_ctrl_b0[4] = AR_PHY_AIC_CTRL_4_B0_20;
  511         aic_ctrl_b1[0] = AR_PHY_AIC_CTRL_0_B1_20;
  512         aic_ctrl_b1[1] = AR_PHY_AIC_CTRL_1_B1_20;
  513         aic_ctrl_b1[4] = AR_PHY_AIC_CTRL_4_B1_20;
  514         aic_stat_b0[0] = AR_PHY_AIC_STAT_0_B0_20;
  515         aic_stat_b0[1] = AR_PHY_AIC_STAT_1_B0_20;
  516         aic_stat_b1[0] = AR_PHY_AIC_STAT_0_B1_20;
  517         aic_stat_b1[1] = AR_PHY_AIC_STAT_1_B1_20;
  518     }
  519 
  520     /* Config LNA gain difference */
  521     OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
  522     OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
  523 
  524     OS_REG_WRITE(ah, aic_ctrl_b0[0], 
  525                 (SM(0, AR_PHY_AIC_MON_ENABLE) |
  526                  SM(40, AR_PHY_AIC_CAL_MAX_HOP_COUNT) |
  527                  SM(1, AR_PHY_AIC_CAL_MIN_VALID_COUNT) | //26
  528                  SM(37, AR_PHY_AIC_F_WLAN) |
  529                  SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
  530                  SM(0, AR_PHY_AIC_CAL_ENABLE) |
  531                  SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
  532                  SM(0, AR_PHY_AIC_ENABLE)));
  533 
  534     OS_REG_WRITE(ah, aic_ctrl_b1[0], 
  535                 (SM(0, AR_PHY_AIC_MON_ENABLE) |
  536                  SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
  537                  SM(0, AR_PHY_AIC_CAL_ENABLE) |
  538                  SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
  539                  SM(0, AR_PHY_AIC_ENABLE)));
  540 
  541     OS_REG_WRITE(ah, aic_ctrl_b0[1], 
  542                 (SM(8, AR_PHY_AIC_CAL_BT_REF_DELAY) |
  543                  SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) | 
  544                  SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) | 
  545                  SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
  546                  SM(1, AR_PHY_AIC_STDBY_COND) |
  547                  SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
  548                  SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
  549                  SM(15, AR_PHY_AIC_RSSI_MAX) |
  550                  SM(0, AR_PHY_AIC_RSSI_MIN)));
  551 
  552     OS_REG_WRITE(ah, aic_ctrl_b1[1], 
  553                 (SM(6, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
  554                  SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
  555                  SM(15, AR_PHY_AIC_RSSI_MAX) |
  556                  SM(0, AR_PHY_AIC_RSSI_MIN)));
  557 
  558     OS_REG_WRITE(ah, aic_ctrl_b0[2], 
  559                 (SM(44, AR_PHY_AIC_RADIO_DELAY) |
  560                  SM(7, AR_PHY_AIC_CAL_STEP_SIZE_CORR) |
  561                  SM(12, AR_PHY_AIC_CAL_ROT_IDX_CORR) |
  562                  SM(2, AR_PHY_AIC_CAL_CONV_CHECK_FACTOR) |
  563                  SM(5, AR_PHY_AIC_ROT_IDX_COUNT_MAX) |
  564                  SM(1, AR_PHY_AIC_CAL_SYNTH_TOGGLE) |
  565                  SM(1, AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX) |
  566                  SM(200, AR_PHY_AIC_CAL_SYNTH_SETTLING)));
  567 
  568     OS_REG_WRITE(ah, aic_ctrl_b0[3], 
  569                 (SM(20, AR_PHY_AIC_MON_MAX_HOP_COUNT) |
  570                  SM(10, AR_PHY_AIC_MON_MIN_STALE_COUNT) |
  571                  SM(1, AR_PHY_AIC_MON_PWR_EST_LONG) |
  572                  SM(2, AR_PHY_AIC_MON_PD_TALLY_SCALING) |
  573                  SM(18, AR_PHY_AIC_MON_PERF_THR) |
  574                  SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED) |
  575                  SM(2, AR_PHY_AIC_CAL_TARGET_MAG_SETTING) |
  576                  SM(3, AR_PHY_AIC_CAL_PERF_CHECK_FACTOR) |
  577                  SM(1, AR_PHY_AIC_CAL_PWR_EST_LONG)));
  578     
  579     ar9300_aic_gain_table(ah);
  580 
  581     /* Need to enable AIC reference signal in BT modem. */
  582     OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL, 
  583                 (OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) | 
  584                  ATH_AIC_BT_AIC_ENABLE));
  585 
  586     while (cal_count)
  587     {
  588         /* Start calibration */
  589         OS_REG_CLR_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
  590         OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_CH_VALID_RESET);
  591         OS_REG_SET_BIT(ah, aic_ctrl_b1[0], AR_PHY_AIC_CAL_ENABLE);
  592 
  593         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start calibration #%d\n",
  594                 (ATH_AIC_MAX_CAL_COUNT - cal_count));
  595 
  596         /* Wait until calibration is completed. */
  597         for (i = 0; i < 10000; i++) {
  598             /* 
  599              * Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE.
  600              * Sometimes CAL_DONE bit is not asserted.
  601              */
  602             if ((OS_REG_READ(ah, aic_ctrl_b1[0]) & AR_PHY_AIC_CAL_ENABLE) == 0)
  603             {
  604                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Cal is done at #%d\n", i);
  605                 break;
  606             }
  607             OS_DELAY(1);
  608         }
  609 
  610         /* print out status registers */
  611         aic_stat = OS_REG_READ(ah, aic_stat_b1[0]);
  612         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  613                 "(AIC) CAL_DONE = %d, CAL_ACTIVE = %d, MEAS_COUNT = %d\n",
  614                 MS(aic_stat, AR_PHY_AIC_CAL_DONE),
  615                 MS(aic_stat, AR_PHY_AIC_CAL_ACTIVE),
  616                 MS(aic_stat, AR_PHY_AIC_MEAS_COUNT));
  617         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  618                 "(AIC) ANT_ISO = %d, HOP_COUNT = %d, VALID_COUNT = %d\n",
  619                 MS(aic_stat, AR_PHY_AIC_CAL_ANT_ISO_EST),
  620                 MS(aic_stat, AR_PHY_AIC_CAL_HOP_COUNT),
  621                 MS(aic_stat, AR_PHY_AIC_CAL_VALID_COUNT));
  622         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  623                 "(AIC) BT_WEAK = %d, BT_STRONG = %d, , \n",
  624                 MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_WEAK_ERR),
  625                 MS(aic_stat, AR_PHY_AIC_CAL_BT_TOO_STRONG_ERR));
  626 
  627         aic_stat = OS_REG_READ(ah, aic_stat_b1[1]);
  628         HALDEBUG(ah, HAL_DEBUG_BT_COEX, 
  629                 "(AIC) MEAS_MAG_MIN = %d, CAL_AIC_SM = %d, AIC_SM = %d\n",
  630                 MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN),
  631                 MS(aic_stat, AR_PHY_AIC_CAL_AIC_SM),
  632                 MS(aic_stat, AR_PHY_AIC_SM));
  633 
  634         if (i >= 10000) {
  635             HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed.\n");
  636             break;
  637         }
  638 
  639         /* print out calibration result */
  640         if (MS(aic_stat, AR_PHY_AIC_MEAS_MAG_MIN) < ATH_AIC_MEAS_MAG_THRESH) {
  641             for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  642                 OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, 
  643                             (ATH_AIC_SRAM_CAL_OFFSET + i*4));
  644                 value = OS_REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
  645                 if (value & 0x01) {
  646                     HALDEBUG(ah, HAL_DEBUG_BT_COEX,
  647                              "(AIC) BT chan %02d: 0x%08x\n", i, value);
  648                 }
  649             }
  650             break;
  651         }
  652         cal_count--;
  653     }
  654 
  655     if (!cal_count) {
  656         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Calibration failed2.\n");
  657     }
  658 
  659     /* Disable AIC reference signal in BT modem. */
  660     OS_REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL, 
  661                 (OS_REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) & 
  662                  ~ATH_AIC_BT_AIC_ENABLE));
  663 
  664     ahp->ah_aic_enabled = ar9300_aic_cal_post_process(ah) ? AH_TRUE : AH_FALSE;
  665 
  666     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) ah_aic_enable = %d\n",
  667              ahp->ah_aic_enabled);
  668     return 0;
  669 }
  670 
  671 
  672 u_int32_t
  673 ar9300_aic_start_normal (struct ath_hal *ah)
  674 {
  675     struct ath_hal_9300 *ahp = AH9300(ah);
  676     u_int32_t aic_ctrl0_b1, aic_ctrl1_b0, aic_ctrl1_b1;
  677     int16_t i;
  678 
  679     /* Config LNA gain difference */
  680     OS_REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x22180600);
  681     OS_REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x52443a2e);
  682 
  683     ar9300_aic_gain_table(ah);
  684 
  685     OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, ATH_AIC_SRAM_AUTO_INCREMENT);
  686 
  687     for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
  688         OS_REG_WRITE(ah, AR_PHY_AIC_SRAM_DATA_B1, ahp->ah_aic_sram[i]);
  689     }
  690 
  691     if (AR_SREV_JUPITER_10(ah)) {
  692         aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_10;
  693         aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_10;
  694         aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_10;
  695     }
  696     else {
  697         aic_ctrl0_b1 = AR_PHY_AIC_CTRL_0_B1_20;
  698         aic_ctrl1_b0 = AR_PHY_AIC_CTRL_1_B0_20;
  699         aic_ctrl1_b1 = AR_PHY_AIC_CTRL_1_B1_20;
  700     }
  701 
  702     OS_REG_WRITE(ah, aic_ctrl1_b0,
  703                 (SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
  704                  SM(1, AR_PHY_AIC_STDBY_COND) |
  705                  SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
  706                  SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
  707                  SM(15, AR_PHY_AIC_RSSI_MAX) |
  708                  SM(0, AR_PHY_AIC_RSSI_MIN)));
  709 
  710     OS_REG_WRITE(ah, aic_ctrl1_b1,
  711                 (SM(15, AR_PHY_AIC_RSSI_MAX) |
  712                  SM(0, AR_PHY_AIC_RSSI_MIN)));
  713 
  714     OS_REG_WRITE(ah, aic_ctrl0_b1, 
  715                 (SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
  716                  SM(1, AR_PHY_AIC_ENABLE)));
  717 
  718     ahp->ah_aic_enabled = AH_TRUE;
  719 
  720     HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(AIC) Start normal operation mode.\n");
  721     return 0;
  722 }
  723 #endif
  724 
  725 #endif
  726 
  727 

Cache object: a306762d353a86a98391883569c6cc1f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.