halrf_txgapcal.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 Realtek Corporation.
  4. *
  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.
  8. *
  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
  12. * more details.
  13. *
  14. * The full GNU General Public License is included in this distribution in the
  15. * file called LICENSE.
  16. *
  17. * Contact Information:
  18. * wlanfae <wlanfae@realtek.com>
  19. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20. * Hsinchu 300, Taiwan.
  21. *
  22. * Larry Finger <Larry.Finger@lwfinger.net>
  23. *
  24. *****************************************************************************/
  25. #include "mp_precomp.h"
  26. #include "phydm_precomp.h"
  27. void odm_bub_sort(u32 *data, u32 n)
  28. {
  29. int i, j, temp, sp;
  30. for (i = n - 1; i >= 0; i--) {
  31. sp = 1;
  32. for (j = 0; j < i; j++) {
  33. if (data[j] < data[j + 1]) {
  34. temp = data[j];
  35. data[j] = data[j + 1];
  36. data[j + 1] = temp;
  37. sp = 0;
  38. }
  39. }
  40. if (sp == 1)
  41. break;
  42. }
  43. }
  44. #if (RTL8197F_SUPPORT == 1)
  45. u4Byte
  46. odm_tx_gain_gap_psd_8197f(
  47. void *dm_void,
  48. u1Byte rf_path,
  49. u4Byte rf56)
  50. {
  51. PDM_ODM_T dm = (PDM_ODM_T)dm_void;
  52. u1Byte i, j;
  53. u4Byte psd_vaule[5], psd_avg_time = 5, psd_vaule_temp;
  54. u4Byte iqk_ctl_addr[2][6] = {{0xe30, 0xe34, 0xe50, 0xe54, 0xe38, 0xe3c},
  55. {0xe50, 0xe54, 0xe30, 0xe34, 0xe58, 0xe5c}};
  56. u4Byte psd_finish_bit[2] = {0x04000000, 0x20000000};
  57. u4Byte psd_fail_bit[2] = {0x08000000, 0x40000000};
  58. u4Byte psd_cntl_value[2][2] = {{0x38008c1c, 0x10008c1c},
  59. {0x38008c2c, 0x10008c2c}};
  60. u4Byte psd_report_addr[2] = {0xea0, 0xec0};
  61. odm_set_rf_reg(dm, rf_path, RF_0xdf, bRFRegOffsetMask, 0x00e02);
  62. ODM_delay_us(100);
  63. odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x0);
  64. odm_set_rf_reg(dm, rf_path, RF_0x56, 0xfff, rf56);
  65. while (rf56 != (odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff)))
  66. odm_set_rf_reg(dm, rf_path, RF_0x56, 0xfff, rf56);
  67. odm_set_bb_reg(dm, R_0xd94, 0xffffffff, 0x44FFBB44);
  68. odm_set_bb_reg(dm, R_0xe70, 0xffffffff, 0x00400040);
  69. odm_set_bb_reg(dm, R_0xc04, 0xffffffff, 0x6f005403);
  70. odm_set_bb_reg(dm, R_0xc08, 0xffffffff, 0x000804e4);
  71. odm_set_bb_reg(dm, R_0x874, 0xffffffff, 0x04203400);
  72. odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x80800000);
  73. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][0], 0xffffffff, psd_cntl_value[rf_path][0]);
  74. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][1], 0xffffffff, psd_cntl_value[rf_path][1]);
  75. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][2], 0xffffffff, psd_cntl_value[rf_path][0]);
  76. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][3], 0xffffffff, psd_cntl_value[rf_path][0]);
  77. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][4], 0xffffffff, 0x8215001F);
  78. odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][5], 0xffffffff, 0x2805001F);
  79. odm_set_bb_reg(dm, R_0xe40, 0xffffffff, 0x81007C00);
  80. odm_set_bb_reg(dm, R_0xe44, 0xffffffff, 0x81004800);
  81. odm_set_bb_reg(dm, R_0xe4c, 0xffffffff, 0x0046a8d0);
  82. for (i = 0; i < psd_avg_time; i++) {
  83. for (j = 0; j < 1000; j++) {
  84. odm_set_bb_reg(dm, R_0xe48, 0xffffffff, 0xfa005800);
  85. odm_set_bb_reg(dm, R_0xe48, 0xffffffff, 0xf8005800);
  86. while (!odm_get_bb_reg(dm, R_0xeac, psd_finish_bit[rf_path]))
  87. ; /*wait finish bit*/
  88. if (!odm_get_bb_reg(dm, R_0xeac, psd_fail_bit[rf_path])) { /*check fail bit*/
  89. psd_vaule[i] = odm_get_bb_reg(dm, psd_report_addr[rf_path], 0xffffffff);
  90. if (psd_vaule[i] > 0xffff)
  91. break;
  92. }
  93. }
  94. RF_DBG(dm, DBG_RF_IQK,
  95. "[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x time=%d psd_vaule=0x%x\n",
  96. odm_get_rf_reg(dm, rf_path, RF_0x0, 0xff), rf56,
  97. odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff), j,
  98. psd_vaule[i]);
  99. }
  100. odm_bub_sort(psd_vaule, psd_avg_time);
  101. psd_vaule_temp = psd_vaule[(UINT)(psd_avg_time / 2)];
  102. odm_set_bb_reg(dm, R_0xd94, 0xffffffff, 0x44BBBB44);
  103. odm_set_bb_reg(dm, R_0xe70, 0xffffffff, 0x80408040);
  104. odm_set_bb_reg(dm, R_0xc04, 0xffffffff, 0x6f005433);
  105. odm_set_bb_reg(dm, R_0xc08, 0xffffffff, 0x000004e4);
  106. odm_set_bb_reg(dm, R_0x874, 0xffffffff, 0x04003400);
  107. odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x00000000);
  108. RF_DBG(dm, DBG_RF_IQK,
  109. "[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x psd_vaule_temp=0x%x\n",
  110. odm_get_rf_reg(dm, rf_path, RF_0x0, 0xff), rf56,
  111. odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff), psd_vaule_temp);
  112. odm_set_rf_reg(dm, rf_path, RF_0xdf, bRFRegOffsetMask, 0x00602);
  113. return psd_vaule_temp;
  114. }
  115. void odm_tx_gain_gap_calibration_8197f(
  116. void *dm_void)
  117. {
  118. PDM_ODM_T dm = (PDM_ODM_T)dm_void;
  119. u1Byte rf_path, rf0_idx, rf0_idx_current, rf0_idx_next, i, delta_gain_retry = 3;
  120. s1Byte delta_gain_gap_pre, delta_gain_gap[2][11];
  121. u4Byte rf56_current, rf56_next, psd_value_current, psd_value_next;
  122. u4Byte psd_gap, rf56_current_temp[2][11];
  123. s4Byte rf33[2][11];
  124. memset(rf33, 0x0, sizeof(rf33));
  125. for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
  126. if (rf_path == RF_PATH_A)
  127. odm_set_bb_reg(dm, R_0x88c, (BIT(21) | BIT(20)), 0x3); /*disable 3-wire*/
  128. else if (rf_path == RF_PATH_B)
  129. odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22)), 0x3); /*disable 3-wire*/
  130. ODM_delay_us(100);
  131. for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
  132. rf0_idx_current = 3 * (rf0_idx - 1) + 1;
  133. odm_set_rf_reg(dm, rf_path, RF_0x0, 0xff, rf0_idx_current);
  134. ODM_delay_us(100);
  135. rf56_current_temp[rf_path][rf0_idx] = odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff);
  136. rf56_current = rf56_current_temp[rf_path][rf0_idx];
  137. rf0_idx_next = 3 * rf0_idx + 1;
  138. odm_set_rf_reg(dm, rf_path, RF_0x0, 0xff, rf0_idx_next);
  139. ODM_delay_us(100);
  140. rf56_next = odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff);
  141. RF_DBG(dm, DBG_RF_IQK,
  142. "[TGGC] rf56_current[%d][%d]=0x%x rf56_next[%d][%d]=0x%x\n",
  143. rf_path, rf0_idx, rf56_current, rf_path, rf0_idx,
  144. rf56_next);
  145. if ((rf56_current >> 5) == (rf56_next >> 5)) {
  146. delta_gain_gap[rf_path][rf0_idx] = 0;
  147. RF_DBG(dm, DBG_RF_IQK,
  148. "[TGGC] rf56_current[11:5] == rf56_next[%d][%d][11:5]=0x%x delta_gain_gap[%d][%d]=%d\n",
  149. rf_path, rf0_idx, (rf56_next >> 5),
  150. rf_path, rf0_idx,
  151. delta_gain_gap[rf_path][rf0_idx]);
  152. continue;
  153. }
  154. RF_DBG(dm, DBG_RF_IQK,
  155. "[TGGC] rf56_current[%d][%d][11:5]=0x%x != rf56_next[%d][%d][11:5]=0x%x\n",
  156. rf_path, rf0_idx, (rf56_current >> 5), rf_path,
  157. rf0_idx, (rf56_next >> 5));
  158. for (i = 0; i < delta_gain_retry; i++) {
  159. psd_value_current = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_current);
  160. psd_value_next = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_next - 2);
  161. psd_gap = psd_value_next / (psd_value_current / 1000);
  162. #if 0
  163. if (psd_gap > 1413)
  164. delta_gain_gap[rf_path][rf0_idx] = 1;
  165. else if (psd_gap > 1122)
  166. delta_gain_gap[rf_path][rf0_idx] = 0;
  167. else
  168. delta_gain_gap[rf_path][rf0_idx] = -1;
  169. #endif
  170. if (psd_gap > 1445)
  171. delta_gain_gap[rf_path][rf0_idx] = 1;
  172. else if (psd_gap > 1096)
  173. delta_gain_gap[rf_path][rf0_idx] = 0;
  174. else
  175. delta_gain_gap[rf_path][rf0_idx] = -1;
  176. if (i == 0)
  177. delta_gain_gap_pre = delta_gain_gap[rf_path][rf0_idx];
  178. RF_DBG(dm, DBG_RF_IQK,
  179. "[TGGC] psd_value_current=0x%x psd_value_next=0x%x psd_value_next/psd_value_current=%d delta_gain_gap[%d][%d]=%d\n",
  180. psd_value_current, psd_value_next,
  181. psd_gap, rf_path, rf0_idx,
  182. delta_gain_gap[rf_path][rf0_idx]);
  183. if (i == 0 && delta_gain_gap[rf_path][rf0_idx] == 0)
  184. break;
  185. if (delta_gain_gap_pre != delta_gain_gap[rf_path][rf0_idx]) {
  186. delta_gain_gap[rf_path][rf0_idx] = 0;
  187. RF_DBG(dm, DBG_RF_IQK, "[TGGC] delta_gain_gap_pre(%d) != delta_gain_gap[%d][%d](%d) time=%d\n",
  188. delta_gain_gap_pre, rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx], i);
  189. break;
  190. }
  191. RF_DBG(dm, DBG_RF_IQK,
  192. "[TGGC] delta_gain_gap_pre(%d) == delta_gain_gap[%d][%d](%d) time=%d\n",
  193. delta_gain_gap_pre, rf_path, rf0_idx,
  194. delta_gain_gap[rf_path][rf0_idx], i);
  195. }
  196. }
  197. if (rf_path == RF_PATH_A)
  198. odm_set_bb_reg(dm, R_0x88c, (BIT(21) | BIT(20)), 0x0); /*enable 3-wire*/
  199. else if (rf_path == RF_PATH_B)
  200. odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22)), 0x0); /*enable 3-wire*/
  201. ODM_delay_us(100);
  202. }
  203. /*odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22) | BIT(21) | BIT(20)), 0x0);*/ /*enable 3-wire*/
  204. for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
  205. odm_set_rf_reg(dm, rf_path, RF_0xef, bRFRegOffsetMask, 0x00100);
  206. for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
  207. rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + (rf56_current_temp[rf_path][rf0_idx] & 0x1f);
  208. for (i = rf0_idx; i <= 10; i++)
  209. rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + delta_gain_gap[rf_path][i];
  210. if (rf33[rf_path][rf0_idx] >= 0x1d)
  211. rf33[rf_path][rf0_idx] = 0x1d;
  212. else if (rf33[rf_path][rf0_idx] <= 0x2)
  213. rf33[rf_path][rf0_idx] = 0x2;
  214. rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + ((rf0_idx - 1) * 0x4000) + (rf56_current_temp[rf_path][rf0_idx] & 0xfffe0);
  215. RF_DBG(dm, DBG_RF_IQK,
  216. "[TGGC] rf56[%d][%d]=0x%05x rf33[%d][%d]=0x%05x\n",
  217. rf_path, rf0_idx,
  218. rf56_current_temp[rf_path][rf0_idx], rf_path,
  219. rf0_idx, rf33[rf_path][rf0_idx]);
  220. odm_set_rf_reg(dm, rf_path, RF_0x33, bRFRegOffsetMask, rf33[rf_path][rf0_idx]);
  221. }
  222. odm_set_rf_reg(dm, rf_path, RF_0xef, bRFRegOffsetMask, 0x00000);
  223. }
  224. }
  225. #endif
  226. void odm_tx_gain_gap_calibration(void *dm_void)
  227. {
  228. PDM_ODM_T dm = (PDM_ODM_T)dm_void;
  229. #if (RTL8197F_SUPPORT == 1)
  230. if (dm->SupportICType & ODM_RTL8197F)
  231. odm_tx_gain_gap_calibration_8197f(dm_void);
  232. #endif
  233. }