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