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