xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8189fs/hal/phydm/halrf/halrf_txgapcal.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
odm_bub_sort(u32 * data,u32 n)28 void odm_bub_sort(u32 *data, u32 n)
29 {
30 	int i, j, temp, sp;
31 
32 	for (i = n - 1; i >= 0; i--) {
33 		sp = 1;
34 		for (j = 0; j < i; j++) {
35 			if (data[j] < data[j + 1]) {
36 				temp = data[j];
37 				data[j] = data[j + 1];
38 				data[j + 1] = temp;
39 				sp = 0;
40 			}
41 		}
42 		if (sp == 1)
43 			break;
44 	}
45 }
46 
47 #if (RTL8197F_SUPPORT == 1)
48 
49 u4Byte
odm_tx_gain_gap_psd_8197f(void * dm_void,u1Byte rf_path,u4Byte rf56)50 odm_tx_gain_gap_psd_8197f(
51 	void *dm_void,
52 	u1Byte rf_path,
53 	u4Byte rf56)
54 {
55 	PDM_ODM_T dm = (PDM_ODM_T)dm_void;
56 
57 	u1Byte i, j;
58 	u4Byte psd_vaule[5], psd_avg_time = 5, psd_vaule_temp;
59 
60 	u4Byte iqk_ctl_addr[2][6] = {{0xe30, 0xe34, 0xe50, 0xe54, 0xe38, 0xe3c},
61 				     {0xe50, 0xe54, 0xe30, 0xe34, 0xe58, 0xe5c}};
62 
63 	u4Byte psd_finish_bit[2] = {0x04000000, 0x20000000};
64 	u4Byte psd_fail_bit[2] = {0x08000000, 0x40000000};
65 
66 	u4Byte psd_cntl_value[2][2] = {{0x38008c1c, 0x10008c1c},
67 				       {0x38008c2c, 0x10008c2c}};
68 
69 	u4Byte psd_report_addr[2] = {0xea0, 0xec0};
70 
71 	odm_set_rf_reg(dm, rf_path, RF_0xdf, bRFRegOffsetMask, 0x00e02);
72 
73 	ODM_delay_us(100);
74 
75 	odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x0);
76 
77 	odm_set_rf_reg(dm, rf_path, RF_0x56, 0xfff, rf56);
78 	while (rf56 != (odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff)))
79 		odm_set_rf_reg(dm, rf_path, RF_0x56, 0xfff, rf56);
80 
81 	odm_set_bb_reg(dm, R_0xd94, 0xffffffff, 0x44FFBB44);
82 	odm_set_bb_reg(dm, R_0xe70, 0xffffffff, 0x00400040);
83 	odm_set_bb_reg(dm, R_0xc04, 0xffffffff, 0x6f005403);
84 	odm_set_bb_reg(dm, R_0xc08, 0xffffffff, 0x000804e4);
85 	odm_set_bb_reg(dm, R_0x874, 0xffffffff, 0x04203400);
86 	odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x80800000);
87 
88 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][0], 0xffffffff, psd_cntl_value[rf_path][0]);
89 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][1], 0xffffffff, psd_cntl_value[rf_path][1]);
90 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][2], 0xffffffff, psd_cntl_value[rf_path][0]);
91 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][3], 0xffffffff, psd_cntl_value[rf_path][0]);
92 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][4], 0xffffffff, 0x8215001F);
93 	odm_set_bb_reg(dm, iqk_ctl_addr[rf_path][5], 0xffffffff, 0x2805001F);
94 
95 	odm_set_bb_reg(dm, R_0xe40, 0xffffffff, 0x81007C00);
96 	odm_set_bb_reg(dm, R_0xe44, 0xffffffff, 0x81004800);
97 	odm_set_bb_reg(dm, R_0xe4c, 0xffffffff, 0x0046a8d0);
98 
99 	for (i = 0; i < psd_avg_time; i++) {
100 		for (j = 0; j < 1000; j++) {
101 			odm_set_bb_reg(dm, R_0xe48, 0xffffffff, 0xfa005800);
102 			odm_set_bb_reg(dm, R_0xe48, 0xffffffff, 0xf8005800);
103 
104 			while (!odm_get_bb_reg(dm, R_0xeac, psd_finish_bit[rf_path]))
105 				; /*wait finish bit*/
106 
107 			if (!odm_get_bb_reg(dm, R_0xeac, psd_fail_bit[rf_path])) { /*check fail bit*/
108 
109 				psd_vaule[i] = odm_get_bb_reg(dm, psd_report_addr[rf_path], 0xffffffff);
110 
111 				if (psd_vaule[i] > 0xffff)
112 					break;
113 			}
114 		}
115 
116 		RF_DBG(dm, DBG_RF_IQK,
117 		       "[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x time=%d psd_vaule=0x%x\n",
118 		       odm_get_rf_reg(dm, rf_path, RF_0x0, 0xff), rf56,
119 		       odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff), j,
120 		       psd_vaule[i]);
121 	}
122 
123 	odm_bub_sort(psd_vaule, psd_avg_time);
124 
125 	psd_vaule_temp = psd_vaule[(UINT)(psd_avg_time / 2)];
126 
127 	odm_set_bb_reg(dm, R_0xd94, 0xffffffff, 0x44BBBB44);
128 	odm_set_bb_reg(dm, R_0xe70, 0xffffffff, 0x80408040);
129 	odm_set_bb_reg(dm, R_0xc04, 0xffffffff, 0x6f005433);
130 	odm_set_bb_reg(dm, R_0xc08, 0xffffffff, 0x000004e4);
131 	odm_set_bb_reg(dm, R_0x874, 0xffffffff, 0x04003400);
132 	odm_set_bb_reg(dm, R_0xe28, 0xffffffff, 0x00000000);
133 
134 	RF_DBG(dm, DBG_RF_IQK,
135 	       "[TGGC] rf0=0x%x rf56=0x%x rf56_reg=0x%x psd_vaule_temp=0x%x\n",
136 	       odm_get_rf_reg(dm, rf_path, RF_0x0, 0xff), rf56,
137 	       odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff), psd_vaule_temp);
138 
139 	odm_set_rf_reg(dm, rf_path, RF_0xdf, bRFRegOffsetMask, 0x00602);
140 
141 	return psd_vaule_temp;
142 }
143 
odm_tx_gain_gap_calibration_8197f(void * dm_void)144 void odm_tx_gain_gap_calibration_8197f(
145 	void *dm_void)
146 {
147 	PDM_ODM_T dm = (PDM_ODM_T)dm_void;
148 
149 	u1Byte rf_path, rf0_idx, rf0_idx_current, rf0_idx_next, i, delta_gain_retry = 3;
150 
151 	s1Byte delta_gain_gap_pre, delta_gain_gap[2][11];
152 	u4Byte rf56_current, rf56_next, psd_value_current, psd_value_next;
153 	u4Byte psd_gap, rf56_current_temp[2][11];
154 	s4Byte rf33[2][11];
155 
156 	memset(rf33, 0x0, sizeof(rf33));
157 
158 	for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
159 		if (rf_path == RF_PATH_A)
160 			odm_set_bb_reg(dm, R_0x88c, (BIT(21) | BIT(20)), 0x3); /*disable 3-wire*/
161 		else if (rf_path == RF_PATH_B)
162 			odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22)), 0x3); /*disable 3-wire*/
163 
164 		ODM_delay_us(100);
165 
166 		for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
167 			rf0_idx_current = 3 * (rf0_idx - 1) + 1;
168 			odm_set_rf_reg(dm, rf_path, RF_0x0, 0xff, rf0_idx_current);
169 			ODM_delay_us(100);
170 			rf56_current_temp[rf_path][rf0_idx] = odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff);
171 			rf56_current = rf56_current_temp[rf_path][rf0_idx];
172 
173 			rf0_idx_next = 3 * rf0_idx + 1;
174 			odm_set_rf_reg(dm, rf_path, RF_0x0, 0xff, rf0_idx_next);
175 			ODM_delay_us(100);
176 			rf56_next = odm_get_rf_reg(dm, rf_path, RF_0x56, 0xfff);
177 
178 			RF_DBG(dm, DBG_RF_IQK,
179 			       "[TGGC] rf56_current[%d][%d]=0x%x rf56_next[%d][%d]=0x%x\n",
180 			       rf_path, rf0_idx, rf56_current, rf_path, rf0_idx,
181 			       rf56_next);
182 
183 			if ((rf56_current >> 5) == (rf56_next >> 5)) {
184 				delta_gain_gap[rf_path][rf0_idx] = 0;
185 
186 				RF_DBG(dm, DBG_RF_IQK,
187 				       "[TGGC] rf56_current[11:5] == rf56_next[%d][%d][11:5]=0x%x delta_gain_gap[%d][%d]=%d\n",
188 				       rf_path, rf0_idx, (rf56_next >> 5),
189 				       rf_path, rf0_idx,
190 				       delta_gain_gap[rf_path][rf0_idx]);
191 
192 				continue;
193 			}
194 
195 			RF_DBG(dm, DBG_RF_IQK,
196 			       "[TGGC] rf56_current[%d][%d][11:5]=0x%x != rf56_next[%d][%d][11:5]=0x%x\n",
197 			       rf_path, rf0_idx, (rf56_current >> 5), rf_path,
198 			       rf0_idx, (rf56_next >> 5));
199 
200 			for (i = 0; i < delta_gain_retry; i++) {
201 				psd_value_current = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_current);
202 
203 				psd_value_next = odm_tx_gain_gap_psd_8197f(dm, rf_path, rf56_next - 2);
204 
205 				psd_gap = psd_value_next / (psd_value_current / 1000);
206 
207 #if 0
208 				if (psd_gap > 1413)
209 					delta_gain_gap[rf_path][rf0_idx] = 1;
210 				else if (psd_gap > 1122)
211 					delta_gain_gap[rf_path][rf0_idx] = 0;
212 				else
213 					delta_gain_gap[rf_path][rf0_idx] = -1;
214 #endif
215 
216 				if (psd_gap > 1445)
217 					delta_gain_gap[rf_path][rf0_idx] = 1;
218 				else if (psd_gap > 1096)
219 					delta_gain_gap[rf_path][rf0_idx] = 0;
220 				else
221 					delta_gain_gap[rf_path][rf0_idx] = -1;
222 
223 				if (i == 0)
224 					delta_gain_gap_pre = delta_gain_gap[rf_path][rf0_idx];
225 
226 				RF_DBG(dm, DBG_RF_IQK,
227 				       "[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",
228 				       psd_value_current, psd_value_next,
229 				       psd_gap, rf_path, rf0_idx,
230 				       delta_gain_gap[rf_path][rf0_idx]);
231 
232 				if (i == 0 && delta_gain_gap[rf_path][rf0_idx] == 0)
233 					break;
234 
235 				if (delta_gain_gap_pre != delta_gain_gap[rf_path][rf0_idx]) {
236 					delta_gain_gap[rf_path][rf0_idx] = 0;
237 
238 					RF_DBG(dm, DBG_RF_IQK, "[TGGC] delta_gain_gap_pre(%d) != delta_gain_gap[%d][%d](%d) time=%d\n",
239 					       delta_gain_gap_pre, rf_path, rf0_idx, delta_gain_gap[rf_path][rf0_idx], i);
240 
241 					break;
242 				}
243 
244 				RF_DBG(dm, DBG_RF_IQK,
245 				       "[TGGC] delta_gain_gap_pre(%d) == delta_gain_gap[%d][%d](%d) time=%d\n",
246 				       delta_gain_gap_pre, rf_path, rf0_idx,
247 				       delta_gain_gap[rf_path][rf0_idx], i);
248 			}
249 		}
250 
251 		if (rf_path == RF_PATH_A)
252 			odm_set_bb_reg(dm, R_0x88c, (BIT(21) | BIT(20)), 0x0); /*enable 3-wire*/
253 		else if (rf_path == RF_PATH_B)
254 			odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22)), 0x0); /*enable 3-wire*/
255 
256 		ODM_delay_us(100);
257 	}
258 
259 #if 0
260 	/*odm_set_bb_reg(dm, R_0x88c, (BIT(23) | BIT(22) | BIT(21) | BIT(20)), 0x0);*/ /*enable 3-wire*/
261 #endif
262 
263 	for (rf_path = RF_PATH_A; rf_path <= RF_PATH_B; rf_path++) {
264 		odm_set_rf_reg(dm, rf_path, RF_0xef, bRFRegOffsetMask, 0x00100);
265 
266 		for (rf0_idx = 1; rf0_idx <= 10; rf0_idx++) {
267 			rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + (rf56_current_temp[rf_path][rf0_idx] & 0x1f);
268 
269 			for (i = rf0_idx; i <= 10; i++)
270 				rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + delta_gain_gap[rf_path][i];
271 
272 			if (rf33[rf_path][rf0_idx] >= 0x1d)
273 				rf33[rf_path][rf0_idx] = 0x1d;
274 			else if (rf33[rf_path][rf0_idx] <= 0x2)
275 				rf33[rf_path][rf0_idx] = 0x2;
276 
277 			rf33[rf_path][rf0_idx] = rf33[rf_path][rf0_idx] + ((rf0_idx - 1) * 0x4000) + (rf56_current_temp[rf_path][rf0_idx] & 0xfffe0);
278 
279 			RF_DBG(dm, DBG_RF_IQK,
280 			       "[TGGC] rf56[%d][%d]=0x%05x rf33[%d][%d]=0x%05x\n",
281 			       rf_path, rf0_idx,
282 			       rf56_current_temp[rf_path][rf0_idx], rf_path,
283 			       rf0_idx, rf33[rf_path][rf0_idx]);
284 
285 			odm_set_rf_reg(dm, rf_path, RF_0x33, bRFRegOffsetMask, rf33[rf_path][rf0_idx]);
286 		}
287 
288 		odm_set_rf_reg(dm, rf_path, RF_0xef, bRFRegOffsetMask, 0x00000);
289 	}
290 }
291 #endif
292 
odm_tx_gain_gap_calibration(void * dm_void)293 void odm_tx_gain_gap_calibration(void *dm_void)
294 {
295 	PDM_ODM_T dm = (PDM_ODM_T)dm_void;
296 #if (RTL8197F_SUPPORT == 1)
297 	if (dm->SupportICType & ODM_RTL8197F)
298 		odm_tx_gain_gap_calibration_8197f(dm_void);
299 #endif
300 }
301