1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 
8 #include <linux/kernel.h>
9 #include "odm_precomp.h"
10 
CheckPositive(struct dm_odm_t * pDM_Odm,const u32 Condition1,const u32 Condition2)11 static bool CheckPositive(
12 	struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2
13 )
14 {
15 	u8 _BoardType =
16 		((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /*  _GLNA */
17 		((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /*  _GPA */
18 		((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /*  _ALNA */
19 		((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /*  _APA */
20 		((pDM_Odm->BoardType & BIT2) >> 2) << 4;  /*  _BT */
21 
22 	u32 cond1 = Condition1, cond2 = Condition2;
23 	u32 driver1 =
24 		pDM_Odm->CutVersion << 24 |
25 		pDM_Odm->SupportPlatform << 16 |
26 		pDM_Odm->PackageType << 12 |
27 		pDM_Odm->SupportInterface << 8  |
28 		_BoardType;
29 
30 	u32 driver2 =
31 		pDM_Odm->TypeGLNA << 0 |
32 		pDM_Odm->TypeGPA << 8 |
33 		pDM_Odm->TypeALNA << 16 |
34 		pDM_Odm->TypeAPA << 24;
35 
36 
37 	/*  Value Defined Check =============== */
38 	/* QFN Type [15:12] and Cut Version [27:24] need to do value check */
39 
40 	if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000)))
41 		return false;
42 	if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000)))
43 		return false;
44 
45 	/*  Bit Defined Check ================ */
46 	/*  We don't care [31:28] and [23:20] */
47 	/*  */
48 	cond1   &= 0x000F0FFF;
49 	driver1 &= 0x000F0FFF;
50 
51 	if ((cond1 & driver1) == cond1) {
52 		u32 bitMask = 0;
53 
54 		if ((cond1 & 0x0F) == 0) /*  BoardType is DONTCARE */
55 			return true;
56 
57 		if ((cond1 & BIT0) != 0) /* GLNA */
58 			bitMask |= 0x000000FF;
59 		if ((cond1 & BIT1) != 0) /* GPA */
60 			bitMask |= 0x0000FF00;
61 		if ((cond1 & BIT2) != 0) /* ALNA */
62 			bitMask |= 0x00FF0000;
63 		if ((cond1 & BIT3) != 0) /* APA */
64 			bitMask |= 0xFF000000;
65 
66 		/*  BoardType of each RF path is matched */
67 		if ((cond2 & bitMask) == (driver2 & bitMask))
68 			return true;
69 	}
70 	return false;
71 }
72 
73 /******************************************************************************
74 *                           AGC_TAB.TXT
75 ******************************************************************************/
76 
77 static u32 Array_MP_8723B_AGC_TAB[] = {
78 		0xC78, 0xFD000001,
79 		0xC78, 0xFC010001,
80 		0xC78, 0xFB020001,
81 		0xC78, 0xFA030001,
82 		0xC78, 0xF9040001,
83 		0xC78, 0xF8050001,
84 		0xC78, 0xF7060001,
85 		0xC78, 0xF6070001,
86 		0xC78, 0xF5080001,
87 		0xC78, 0xF4090001,
88 		0xC78, 0xF30A0001,
89 		0xC78, 0xF20B0001,
90 		0xC78, 0xF10C0001,
91 		0xC78, 0xF00D0001,
92 		0xC78, 0xEF0E0001,
93 		0xC78, 0xEE0F0001,
94 		0xC78, 0xED100001,
95 		0xC78, 0xEC110001,
96 		0xC78, 0xEB120001,
97 		0xC78, 0xEA130001,
98 		0xC78, 0xE9140001,
99 		0xC78, 0xE8150001,
100 		0xC78, 0xE7160001,
101 		0xC78, 0xE6170001,
102 		0xC78, 0xE5180001,
103 		0xC78, 0xE4190001,
104 		0xC78, 0xE31A0001,
105 		0xC78, 0xA51B0001,
106 		0xC78, 0xA41C0001,
107 		0xC78, 0xA31D0001,
108 		0xC78, 0x671E0001,
109 		0xC78, 0x661F0001,
110 		0xC78, 0x65200001,
111 		0xC78, 0x64210001,
112 		0xC78, 0x63220001,
113 		0xC78, 0x4A230001,
114 		0xC78, 0x49240001,
115 		0xC78, 0x48250001,
116 		0xC78, 0x47260001,
117 		0xC78, 0x46270001,
118 		0xC78, 0x45280001,
119 		0xC78, 0x44290001,
120 		0xC78, 0x432A0001,
121 		0xC78, 0x422B0001,
122 		0xC78, 0x292C0001,
123 		0xC78, 0x282D0001,
124 		0xC78, 0x272E0001,
125 		0xC78, 0x262F0001,
126 		0xC78, 0x0A300001,
127 		0xC78, 0x09310001,
128 		0xC78, 0x08320001,
129 		0xC78, 0x07330001,
130 		0xC78, 0x06340001,
131 		0xC78, 0x05350001,
132 		0xC78, 0x04360001,
133 		0xC78, 0x03370001,
134 		0xC78, 0x02380001,
135 		0xC78, 0x01390001,
136 		0xC78, 0x013A0001,
137 		0xC78, 0x013B0001,
138 		0xC78, 0x013C0001,
139 		0xC78, 0x013D0001,
140 		0xC78, 0x013E0001,
141 		0xC78, 0x013F0001,
142 		0xC78, 0xFC400001,
143 		0xC78, 0xFB410001,
144 		0xC78, 0xFA420001,
145 		0xC78, 0xF9430001,
146 		0xC78, 0xF8440001,
147 		0xC78, 0xF7450001,
148 		0xC78, 0xF6460001,
149 		0xC78, 0xF5470001,
150 		0xC78, 0xF4480001,
151 		0xC78, 0xF3490001,
152 		0xC78, 0xF24A0001,
153 		0xC78, 0xF14B0001,
154 		0xC78, 0xF04C0001,
155 		0xC78, 0xEF4D0001,
156 		0xC78, 0xEE4E0001,
157 		0xC78, 0xED4F0001,
158 		0xC78, 0xEC500001,
159 		0xC78, 0xEB510001,
160 		0xC78, 0xEA520001,
161 		0xC78, 0xE9530001,
162 		0xC78, 0xE8540001,
163 		0xC78, 0xE7550001,
164 		0xC78, 0xE6560001,
165 		0xC78, 0xE5570001,
166 		0xC78, 0xE4580001,
167 		0xC78, 0xE3590001,
168 		0xC78, 0xA65A0001,
169 		0xC78, 0xA55B0001,
170 		0xC78, 0xA45C0001,
171 		0xC78, 0xA35D0001,
172 		0xC78, 0x675E0001,
173 		0xC78, 0x665F0001,
174 		0xC78, 0x65600001,
175 		0xC78, 0x64610001,
176 		0xC78, 0x63620001,
177 		0xC78, 0x62630001,
178 		0xC78, 0x61640001,
179 		0xC78, 0x48650001,
180 		0xC78, 0x47660001,
181 		0xC78, 0x46670001,
182 		0xC78, 0x45680001,
183 		0xC78, 0x44690001,
184 		0xC78, 0x436A0001,
185 		0xC78, 0x426B0001,
186 		0xC78, 0x286C0001,
187 		0xC78, 0x276D0001,
188 		0xC78, 0x266E0001,
189 		0xC78, 0x256F0001,
190 		0xC78, 0x24700001,
191 		0xC78, 0x09710001,
192 		0xC78, 0x08720001,
193 		0xC78, 0x07730001,
194 		0xC78, 0x06740001,
195 		0xC78, 0x05750001,
196 		0xC78, 0x04760001,
197 		0xC78, 0x03770001,
198 		0xC78, 0x02780001,
199 		0xC78, 0x01790001,
200 		0xC78, 0x017A0001,
201 		0xC78, 0x017B0001,
202 		0xC78, 0x017C0001,
203 		0xC78, 0x017D0001,
204 		0xC78, 0x017E0001,
205 		0xC78, 0x017F0001,
206 		0xC50, 0x69553422,
207 		0xC50, 0x69553420,
208 		0x824, 0x00390204,
209 
210 };
211 
ODM_ReadAndConfig_MP_8723B_AGC_TAB(struct dm_odm_t * pDM_Odm)212 void ODM_ReadAndConfig_MP_8723B_AGC_TAB(struct dm_odm_t *pDM_Odm)
213 {
214 	u32 i = 0;
215 	u32 ArrayLen = ARRAY_SIZE(Array_MP_8723B_AGC_TAB);
216 	u32 *Array = Array_MP_8723B_AGC_TAB;
217 
218 	for (i = 0; i < ArrayLen; i += 2) {
219 		u32 v1 = Array[i];
220 		u32 v2 = Array[i+1];
221 
222 		/*  This (offset, data) pair doesn't care the condition. */
223 		if (v1 < 0x40000000) {
224 			odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2);
225 			continue;
226 		} else {
227 			/*  This line is the beginning of branch. */
228 			bool bMatched = true;
229 			u8  cCond  = (u8)((v1 & (BIT29|BIT28)) >> 28);
230 
231 			if (cCond == COND_ELSE) { /*  ELSE, ENDIF */
232 				bMatched = true;
233 				READ_NEXT_PAIR(v1, v2, i);
234 			} else if (!CheckPositive(pDM_Odm, v1, v2)) {
235 				bMatched = false;
236 				READ_NEXT_PAIR(v1, v2, i);
237 				READ_NEXT_PAIR(v1, v2, i);
238 			} else {
239 				READ_NEXT_PAIR(v1, v2, i);
240 				bMatched = true;
241 				READ_NEXT_PAIR(v1, v2, i);
242 			}
243 
244 			if (!bMatched) {
245 				/*  Condition isn't matched.
246 				*   Discard the following (offset, data) pairs.
247 				*/
248 				while (v1 < 0x40000000 && i < ArrayLen-2)
249 					READ_NEXT_PAIR(v1, v2, i);
250 
251 				i -= 2; /*  prevent from for-loop += 2 */
252 			} else {
253 				/*  Configure matched pairs and skip to end of if-else. */
254 				while (v1 < 0x40000000 && i < ArrayLen-2) {
255 					odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2);
256 					READ_NEXT_PAIR(v1, v2, i);
257 				}
258 
259 				/*  Keeps reading until ENDIF. */
260 				cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
261 				while (cCond != COND_ENDIF && i < ArrayLen-2) {
262 					READ_NEXT_PAIR(v1, v2, i);
263 					cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
264 				}
265 			}
266 		}
267 	}
268 }
269 
270 /******************************************************************************
271 *                           PHY_REG.TXT
272 ******************************************************************************/
273 
274 static u32 Array_MP_8723B_PHY_REG[] = {
275 		0x800, 0x80040000,
276 		0x804, 0x00000003,
277 		0x808, 0x0000FC00,
278 		0x80C, 0x0000000A,
279 		0x810, 0x10001331,
280 		0x814, 0x020C3D10,
281 		0x818, 0x02200385,
282 		0x81C, 0x00000000,
283 		0x820, 0x01000100,
284 		0x824, 0x00190204,
285 		0x828, 0x00000000,
286 		0x82C, 0x00000000,
287 		0x830, 0x00000000,
288 		0x834, 0x00000000,
289 		0x838, 0x00000000,
290 		0x83C, 0x00000000,
291 		0x840, 0x00010000,
292 		0x844, 0x00000000,
293 		0x848, 0x00000000,
294 		0x84C, 0x00000000,
295 		0x850, 0x00000000,
296 		0x854, 0x00000000,
297 		0x858, 0x569A11A9,
298 		0x85C, 0x01000014,
299 		0x860, 0x66F60110,
300 		0x864, 0x061F0649,
301 		0x868, 0x00000000,
302 		0x86C, 0x27272700,
303 		0x870, 0x07000760,
304 		0x874, 0x25004000,
305 		0x878, 0x00000808,
306 		0x87C, 0x00000000,
307 		0x880, 0xB0000C1C,
308 		0x884, 0x00000001,
309 		0x888, 0x00000000,
310 		0x88C, 0xCCC000C0,
311 		0x890, 0x00000800,
312 		0x894, 0xFFFFFFFE,
313 		0x898, 0x40302010,
314 		0x89C, 0x00706050,
315 		0x900, 0x00000000,
316 		0x904, 0x00000023,
317 		0x908, 0x00000000,
318 		0x90C, 0x81121111,
319 		0x910, 0x00000002,
320 		0x914, 0x00000201,
321 		0xA00, 0x00D047C8,
322 		0xA04, 0x80FF800C,
323 		0xA08, 0x8C838300,
324 		0xA0C, 0x2E7F120F,
325 		0xA10, 0x9500BB78,
326 		0xA14, 0x1114D028,
327 		0xA18, 0x00881117,
328 		0xA1C, 0x89140F00,
329 		0xA20, 0x1A1B0000,
330 		0xA24, 0x090E1317,
331 		0xA28, 0x00000204,
332 		0xA2C, 0x00D30000,
333 		0xA70, 0x101FBF00,
334 		0xA74, 0x00000007,
335 		0xA78, 0x00000900,
336 		0xA7C, 0x225B0606,
337 		0xA80, 0x21806490,
338 		0xB2C, 0x00000000,
339 		0xC00, 0x48071D40,
340 		0xC04, 0x03A05611,
341 		0xC08, 0x000000E4,
342 		0xC0C, 0x6C6C6C6C,
343 		0xC10, 0x08800000,
344 		0xC14, 0x40000100,
345 		0xC18, 0x08800000,
346 		0xC1C, 0x40000100,
347 		0xC20, 0x00000000,
348 		0xC24, 0x00000000,
349 		0xC28, 0x00000000,
350 		0xC2C, 0x00000000,
351 		0xC30, 0x69E9AC44,
352 		0xC34, 0x469652AF,
353 		0xC38, 0x49795994,
354 		0xC3C, 0x0A97971C,
355 		0xC40, 0x1F7C403F,
356 		0xC44, 0x000100B7,
357 		0xC48, 0xEC020107,
358 		0xC4C, 0x007F037F,
359 		0xC50, 0x69553420,
360 		0xC54, 0x43BC0094,
361 		0xC58, 0x00013149,
362 		0xC5C, 0x00250492,
363 		0xC60, 0x00000000,
364 		0xC64, 0x7112848B,
365 		0xC68, 0x47C00BFF,
366 		0xC6C, 0x00000036,
367 		0xC70, 0x2C7F000D,
368 		0xC74, 0x020610DB,
369 		0xC78, 0x0000001F,
370 		0xC7C, 0x00B91612,
371 		0xC80, 0x390000E4,
372 		0xC84, 0x20F60000,
373 		0xC88, 0x40000100,
374 		0xC8C, 0x20200000,
375 		0xC90, 0x00020E1A,
376 		0xC94, 0x00000000,
377 		0xC98, 0x00020E1A,
378 		0xC9C, 0x00007F7F,
379 		0xCA0, 0x00000000,
380 		0xCA4, 0x000300A0,
381 		0xCA8, 0x00000000,
382 		0xCAC, 0x00000000,
383 		0xCB0, 0x00000000,
384 		0xCB4, 0x00000000,
385 		0xCB8, 0x00000000,
386 		0xCBC, 0x28000000,
387 		0xCC0, 0x00000000,
388 		0xCC4, 0x00000000,
389 		0xCC8, 0x00000000,
390 		0xCCC, 0x00000000,
391 		0xCD0, 0x00000000,
392 		0xCD4, 0x00000000,
393 		0xCD8, 0x64B22427,
394 		0xCDC, 0x00766932,
395 		0xCE0, 0x00222222,
396 		0xCE4, 0x00000000,
397 		0xCE8, 0x37644302,
398 		0xCEC, 0x2F97D40C,
399 		0xD00, 0x00000740,
400 		0xD04, 0x40020401,
401 		0xD08, 0x0000907F,
402 		0xD0C, 0x20010201,
403 		0xD10, 0xA0633333,
404 		0xD14, 0x3333BC53,
405 		0xD18, 0x7A8F5B6F,
406 		0xD2C, 0xCC979975,
407 		0xD30, 0x00000000,
408 		0xD34, 0x80608000,
409 		0xD38, 0x00000000,
410 		0xD3C, 0x00127353,
411 		0xD40, 0x00000000,
412 		0xD44, 0x00000000,
413 		0xD48, 0x00000000,
414 		0xD4C, 0x00000000,
415 		0xD50, 0x6437140A,
416 		0xD54, 0x00000000,
417 		0xD58, 0x00000282,
418 		0xD5C, 0x30032064,
419 		0xD60, 0x4653DE68,
420 		0xD64, 0x04518A3C,
421 		0xD68, 0x00002101,
422 		0xD6C, 0x2A201C16,
423 		0xD70, 0x1812362E,
424 		0xD74, 0x322C2220,
425 		0xD78, 0x000E3C24,
426 		0xE00, 0x2D2D2D2D,
427 		0xE04, 0x2D2D2D2D,
428 		0xE08, 0x0390272D,
429 		0xE10, 0x2D2D2D2D,
430 		0xE14, 0x2D2D2D2D,
431 		0xE18, 0x2D2D2D2D,
432 		0xE1C, 0x2D2D2D2D,
433 		0xE28, 0x00000000,
434 		0xE30, 0x1000DC1F,
435 		0xE34, 0x10008C1F,
436 		0xE38, 0x02140102,
437 		0xE3C, 0x681604C2,
438 		0xE40, 0x01007C00,
439 		0xE44, 0x01004800,
440 		0xE48, 0xFB000000,
441 		0xE4C, 0x000028D1,
442 		0xE50, 0x1000DC1F,
443 		0xE54, 0x10008C1F,
444 		0xE58, 0x02140102,
445 		0xE5C, 0x28160D05,
446 		0xE60, 0x00000008,
447 		0xE68, 0x001B2556,
448 		0xE6C, 0x00C00096,
449 		0xE70, 0x00C00096,
450 		0xE74, 0x01000056,
451 		0xE78, 0x01000014,
452 		0xE7C, 0x01000056,
453 		0xE80, 0x01000014,
454 		0xE84, 0x00C00096,
455 		0xE88, 0x01000056,
456 		0xE8C, 0x00C00096,
457 		0xED0, 0x00C00096,
458 		0xED4, 0x00C00096,
459 		0xED8, 0x00C00096,
460 		0xEDC, 0x000000D6,
461 		0xEE0, 0x000000D6,
462 		0xEEC, 0x01C00016,
463 		0xF14, 0x00000003,
464 		0xF4C, 0x00000000,
465 		0xF00, 0x00000300,
466 		0x820, 0x01000100,
467 		0x800, 0x83040000,
468 
469 };
470 
ODM_ReadAndConfig_MP_8723B_PHY_REG(struct dm_odm_t * pDM_Odm)471 void ODM_ReadAndConfig_MP_8723B_PHY_REG(struct dm_odm_t *pDM_Odm)
472 {
473 	u32 i = 0;
474 	u32 ArrayLen = ARRAY_SIZE(Array_MP_8723B_PHY_REG);
475 	u32 *Array = Array_MP_8723B_PHY_REG;
476 
477 	for (i = 0; i < ArrayLen; i += 2) {
478 		u32 v1 = Array[i];
479 		u32 v2 = Array[i+1];
480 
481 		/*  This (offset, data) pair doesn't care the condition. */
482 		if (v1 < 0x40000000) {
483 			odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2);
484 			continue;
485 		} else {
486 			/*  This line is the beginning of branch. */
487 			bool bMatched = true;
488 			u8  cCond  = (u8)((v1 & (BIT29|BIT28)) >> 28);
489 
490 			if (cCond == COND_ELSE) { /*  ELSE, ENDIF */
491 				bMatched = true;
492 				READ_NEXT_PAIR(v1, v2, i);
493 			} else if (!CheckPositive(pDM_Odm, v1, v2)) {
494 				bMatched = false;
495 				READ_NEXT_PAIR(v1, v2, i);
496 				READ_NEXT_PAIR(v1, v2, i);
497 			} else {
498 				READ_NEXT_PAIR(v1, v2, i);
499 				bMatched = true;
500 				READ_NEXT_PAIR(v1, v2, i);
501 			}
502 
503 			if (!bMatched) {
504 				/*  Condition isn't matched.
505 				*   Discard the following (offset, data) pairs.
506 				*/
507 				while (v1 < 0x40000000 && i < ArrayLen-2)
508 					READ_NEXT_PAIR(v1, v2, i);
509 
510 				i -= 2; /*  prevent from for-loop += 2 */
511 			} else { /*  Configure matched pairs and skip to end of if-else. */
512 				while (v1 < 0x40000000 && i < ArrayLen-2) {
513 					odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2);
514 					READ_NEXT_PAIR(v1, v2, i);
515 				}
516 
517 				/*  Keeps reading until ENDIF. */
518 				cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
519 				while (cCond != COND_ENDIF && i < ArrayLen-2) {
520 					READ_NEXT_PAIR(v1, v2, i);
521 					cCond = (u8)((v1 & (BIT29|BIT28)) >> 28);
522 				}
523 			}
524 		}
525 	}
526 }
527 
528 /******************************************************************************
529 *                           PHY_REG_PG.TXT
530 ******************************************************************************/
531 
532 static u32 Array_MP_8723B_PHY_REG_PG[] = {
533 	0, 0x00000e08, 0x0000ff00, 0x00003800,
534 	0, 0x0000086c, 0xffffff00, 0x32343600,
535 	0, 0x00000e00, 0xffffffff, 0x40424444,
536 	0, 0x00000e04, 0xffffffff, 0x28323638,
537 	0, 0x00000e10, 0xffffffff, 0x38404244,
538 	0, 0x00000e14, 0xffffffff, 0x26303436
539 };
540 
ODM_ReadAndConfig_MP_8723B_PHY_REG_PG(struct dm_odm_t * pDM_Odm)541 void ODM_ReadAndConfig_MP_8723B_PHY_REG_PG(struct dm_odm_t *pDM_Odm)
542 {
543 	u32 i = 0;
544 	u32 *Array = Array_MP_8723B_PHY_REG_PG;
545 
546 	pDM_Odm->PhyRegPgVersion = 1;
547 	pDM_Odm->PhyRegPgValueType = PHY_REG_PG_EXACT_VALUE;
548 
549 	for (i = 0; i < ARRAY_SIZE(Array_MP_8723B_PHY_REG_PG); i += 4) {
550 		u32 v1 = Array[i];
551 		u32 v2 = Array[i+1];
552 		u32 v3 = Array[i+2];
553 		u32 v4 = Array[i+3];
554 
555 		odm_ConfigBB_PHY_REG_PG_8723B(pDM_Odm, v1, v2, v3, v4);
556 	}
557 }
558