906b5782d1658c07994bcdcd63feb388544157cd
[deliverable/linux.git] / drivers / staging / rtl8723au / core / rtw_efuse.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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 ******************************************************************************/
15 #define _RTW_EFUSE_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19
20 #include <rtw_efuse.h>
21 #include <rtl8723a_hal.h>
22 #include <usb_ops_linux.h>
23
24 #define REG_EFUSE_CTRL 0x0030
25 #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control */
26
27 #define VOLTAGE_V25 0x03
28 #define LDOE25_SHIFT 28
29
30 /*
31 * When we want to enable write operation, we should change to
32 * pwr on state. When we stop write, we should switch to 500k mode
33 * and disable LDO 2.5V.
34 */
35 static void Efuse_PowerSwitch(struct rtw_adapter *padapter,
36 u8 bWrite, u8 PwrState)
37 {
38 u8 tempval;
39 u16 tmpV16;
40
41 if (PwrState == true) {
42 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
43
44 /*
45 * 1.2V Power: From VDDON with Power
46 * Cut(0x0000h[15]), default valid
47 */
48 tmpV16 = rtl8723au_read16(padapter, REG_SYS_ISO_CTRL);
49 if (!(tmpV16 & PWC_EV12V)) {
50 tmpV16 |= PWC_EV12V;
51 rtl8723au_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
52 }
53 /* Reset: 0x0000h[28], default valid */
54 tmpV16 = rtl8723au_read16(padapter, REG_SYS_FUNC_EN);
55 if (!(tmpV16 & FEN_ELDR)) {
56 tmpV16 |= FEN_ELDR;
57 rtl8723au_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
58 }
59
60 /*
61 * Clock: Gated(0x0008h[5]) 8M(0x0008h[1])
62 * clock from ANA, default valid
63 */
64 tmpV16 = rtl8723au_read16(padapter, REG_SYS_CLKR);
65 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
66 tmpV16 |= (LOADER_CLK_EN | ANA8M);
67 rtl8723au_write16(padapter, REG_SYS_CLKR, tmpV16);
68 }
69
70 if (bWrite == true) {
71 /* Enable LDO 2.5V before read/write action */
72 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
73 tempval &= 0x0F;
74 tempval |= (VOLTAGE_V25 << 4);
75 rtl8723au_write8(padapter, EFUSE_TEST + 3,
76 tempval | 0x80);
77 }
78 } else {
79 rtl8723au_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
80
81 if (bWrite == true) {
82 /* Disable LDO 2.5V after read/write action */
83 tempval = rtl8723au_read8(padapter, EFUSE_TEST + 3);
84 rtl8723au_write8(padapter, EFUSE_TEST + 3,
85 tempval & 0x7F);
86 }
87 }
88 }
89
90 u16 Efuse_GetCurrentSize23a(struct rtw_adapter *pAdapter, u8 efuseType)
91 {
92 u16 ret = 0;
93
94 if (efuseType == EFUSE_WIFI)
95 ret = rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter);
96 else
97 ret = rtl8723a_EfuseGetCurrentSize_BT(pAdapter);
98
99 return ret;
100 }
101
102 /* Get current efuse area enabled word */
103 u8 Efuse_CalculateWordCnts23a(u8 word_en)
104 {
105 return hweight8((~word_en) & 0xf);
106 }
107
108 /*
109 * Description: Execute E-Fuse read byte operation.
110 *
111 * Assumptions: 1. Boot from E-Fuse and successfully auto-load.
112 * 2. PASSIVE_LEVEL (USB interface)
113 */
114 void ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf)
115 {
116 u32 value32;
117 u8 readbyte;
118 u16 retry;
119
120 /* Write Address */
121 rtl8723au_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
122 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
123 rtl8723au_write8(Adapter, EFUSE_CTRL+2,
124 ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
125
126 /* Write bit 32 0 */
127 readbyte = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
128 rtl8723au_write8(Adapter, EFUSE_CTRL+3, readbyte & 0x7f);
129
130 /* Check bit 32 read-ready */
131 retry = 0;
132 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
133 while (!((value32 >> 24) & 0x80) && retry < 10000) {
134 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
135 retry++;
136 }
137
138 /*
139 * Added suggested delay. This fixes the problem that
140 * Efuse read error in high temperature condition.
141 * Designer says that there shall be some delay after
142 * ready bit is set, or the result will always stay
143 * on last data we read.
144 */
145 udelay(50);
146 value32 = rtl8723au_read32(Adapter, EFUSE_CTRL);
147
148 *pbuf = (u8)(value32 & 0xff);
149 }
150
151 void EFUSE_GetEfuseDefinition23a(struct rtw_adapter *pAdapter, u8 efuseType,
152 u8 type, void *pOut)
153 {
154 u8 *pu1Tmp;
155 u16 *pu2Tmp;
156 u8 *pMax_section;
157
158 switch (type) {
159 case TYPE_EFUSE_MAX_SECTION:
160 pMax_section = pOut;
161
162 if (efuseType == EFUSE_WIFI)
163 *pMax_section = EFUSE_MAX_SECTION_8723A;
164 else
165 *pMax_section = EFUSE_BT_MAX_SECTION;
166 break;
167
168 case TYPE_EFUSE_REAL_CONTENT_LEN:
169 pu2Tmp = pOut;
170
171 if (efuseType == EFUSE_WIFI)
172 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
173 else
174 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
175 break;
176
177 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
178 pu2Tmp = pOut;
179
180 if (efuseType == EFUSE_WIFI)
181 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
182 EFUSE_OOB_PROTECT_BYTES);
183 else
184 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN -
185 EFUSE_PROTECT_BYTES_BANK);
186 break;
187
188 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
189 pu2Tmp = pOut;
190
191 if (efuseType == EFUSE_WIFI)
192 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A -
193 EFUSE_OOB_PROTECT_BYTES);
194 else
195 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN -
196 (EFUSE_PROTECT_BYTES_BANK * 3));
197 break;
198
199 case TYPE_EFUSE_MAP_LEN:
200 pu2Tmp = pOut;
201
202 if (efuseType == EFUSE_WIFI)
203 *pu2Tmp = EFUSE_MAP_LEN_8723A;
204 else
205 *pu2Tmp = EFUSE_BT_MAP_LEN;
206 break;
207
208 case TYPE_EFUSE_PROTECT_BYTES_BANK:
209 pu1Tmp = pOut;
210
211 if (efuseType == EFUSE_WIFI)
212 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
213 else
214 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
215 break;
216
217 case TYPE_EFUSE_CONTENT_LEN_BANK:
218 pu2Tmp = pOut;
219
220 if (efuseType == EFUSE_WIFI)
221 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
222 else
223 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
224 break;
225
226 default:
227 pu1Tmp = pOut;
228 *pu1Tmp = 0;
229 break;
230 }
231 }
232
233 /* Copy from WMAC for EFUSE read 1 byte. */
234 u8 EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address)
235 {
236 u8 data;
237 u8 Bytetemp = {0x00};
238 u8 temp = {0x00};
239 u32 k = 0;
240 u16 contentLen = 0;
241
242 EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
243 TYPE_EFUSE_REAL_CONTENT_LEN,
244 (void *)&contentLen);
245
246 if (Address < contentLen) { /* E-fuse 512Byte */
247 /* Write E-fuse Register address bit0~7 */
248 temp = Address & 0xFF;
249 rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
250 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
251 /* Write E-fuse Register address bit8~9 */
252 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
253 rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
254
255 /* Write 0x30[31]= 0 */
256 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
257 temp = Bytetemp & 0x7F;
258 rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
259
260 /* Wait Write-ready (0x30[31]= 1) */
261 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
262 while (!(Bytetemp & 0x80)) {
263 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
264 k++;
265 if (k == 1000) {
266 k = 0;
267 break;
268 }
269 }
270 data = rtl8723au_read8(Adapter, EFUSE_CTRL);
271 return data;
272 } else
273 return 0xFF;
274 }
275
276 /* Copy from WMAC fot EFUSE write 1 byte. */
277 void EFUSE_Write1Byte(struct rtw_adapter *Adapter, u16 Address, u8 Value)
278 {
279 u8 Bytetemp = {0x00};
280 u8 temp = {0x00};
281 u32 k = 0;
282 u16 contentLen = 0;
283
284 EFUSE_GetEfuseDefinition23a(Adapter, EFUSE_WIFI,
285 TYPE_EFUSE_REAL_CONTENT_LEN,
286 (void *)&contentLen);
287
288 if (Address < contentLen) { /* E-fuse 512Byte */
289 rtl8723au_write8(Adapter, EFUSE_CTRL, Value);
290
291 /* Write E-fuse Register address bit0~7 */
292 temp = Address & 0xFF;
293 rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp);
294 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+2);
295
296 /* Write E-fuse Register address bit8~9 */
297 temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
298 rtl8723au_write8(Adapter, EFUSE_CTRL+2, temp);
299
300 /* Write 0x30[31]= 1 */
301 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
302 temp = Bytetemp | 0x80;
303 rtl8723au_write8(Adapter, EFUSE_CTRL+3, temp);
304
305 /* Wait Write-ready (0x30[31]= 0) */
306 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
307 while (Bytetemp & 0x80) {
308 Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3);
309 k++;
310 if (k == 100) {
311 k = 0;
312 break;
313 }
314 }
315 }
316 }
317
318 /* Read one byte from real Efuse. */
319 int efuse_OneByteRead23a(struct rtw_adapter *pAdapter, u16 addr, u8 *data)
320 {
321 u8 tmpidx = 0;
322 int bResult;
323
324 /* -----------------e-fuse reg ctrl ---------------------------- */
325 /* address */
326 rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
327 rtl8723au_write8(pAdapter, EFUSE_CTRL + 2,
328 ((u8)((addr >> 8) & 0x03)) |
329 (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC));
330
331 rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0x72); /* read cmd */
332
333 while (!(0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
334 (tmpidx < 100))
335 tmpidx++;
336 if (tmpidx < 100) {
337 *data = rtl8723au_read8(pAdapter, EFUSE_CTRL);
338 bResult = _SUCCESS;
339 } else {
340 *data = 0xff;
341 bResult = _FAIL;
342 }
343 return bResult;
344 }
345
346 /* Write one byte to reald Efuse. */
347 int efuse_OneByteWrite23a(struct rtw_adapter *pAdapter, u16 addr, u8 data)
348 {
349 u8 tmpidx = 0;
350 int bResult;
351
352 /* return 0; */
353
354 /* -----------------e-fuse reg ctrl ------------------------- */
355 /* address */
356 rtl8723au_write8(pAdapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
357 rtl8723au_write8(pAdapter, EFUSE_CTRL + 2,
358 (rtl8723au_read8(pAdapter, EFUSE_CTRL + 2) & 0xFC) |
359 (u8)((addr >> 8) & 0x03));
360 rtl8723au_write8(pAdapter, EFUSE_CTRL, data); /* data */
361
362 rtl8723au_write8(pAdapter, EFUSE_CTRL + 3, 0xF2); /* write cmd */
363
364 while ((0x80 & rtl8723au_read8(pAdapter, EFUSE_CTRL + 3)) &&
365 (tmpidx < 100)) {
366 tmpidx++;
367 }
368
369 if (tmpidx < 100)
370 bResult = _SUCCESS;
371 else
372 bResult = _FAIL;
373
374 return bResult;
375 }
376
377 /* Read allowed word in current efuse section data. */
378 void efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata)
379 {
380 if (!(word_en&BIT(0))) {
381 targetdata[0] = sourdata[0];
382 targetdata[1] = sourdata[1];
383 }
384 if (!(word_en&BIT(1))) {
385 targetdata[2] = sourdata[2];
386 targetdata[3] = sourdata[3];
387 }
388 if (!(word_en&BIT(2))) {
389 targetdata[4] = sourdata[4];
390 targetdata[5] = sourdata[5];
391 }
392 if (!(word_en&BIT(3))) {
393 targetdata[6] = sourdata[6];
394 targetdata[7] = sourdata[7];
395 }
396 }
397
398 static int efuse_read8(struct rtw_adapter *padapter, u16 address, u8 *value)
399 {
400 return efuse_OneByteRead23a(padapter, address, value);
401 }
402
403 static int efuse_write8(struct rtw_adapter *padapter, u16 address, u8 *value)
404 {
405 return efuse_OneByteWrite23a(padapter, address, *value);
406 }
407
408 /* read/write raw efuse data */
409 int rtw_efuse_access23a(struct rtw_adapter *padapter, u8 bWrite, u16 start_addr,
410 u16 cnts, u8 *data)
411 {
412 int i = 0;
413 u16 real_content_len = 0, max_available_size = 0;
414 int res = _FAIL;
415 int (*rw8)(struct rtw_adapter *, u16, u8*);
416
417 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
418 TYPE_EFUSE_REAL_CONTENT_LEN,
419 (void *)&real_content_len);
420 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
421 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
422 (void *)&max_available_size);
423
424 if (start_addr > real_content_len)
425 return _FAIL;
426
427 if (true == bWrite) {
428 if ((start_addr + cnts) > max_available_size)
429 return _FAIL;
430 rw8 = &efuse_write8;
431 } else
432 rw8 = &efuse_read8;
433
434 Efuse_PowerSwitch(padapter, bWrite, true);
435
436 /* e-fuse one byte read/write */
437 for (i = 0; i < cnts; i++) {
438 if (start_addr >= real_content_len) {
439 res = _FAIL;
440 break;
441 }
442
443 res = rw8(padapter, start_addr++, data++);
444 if (res == _FAIL)
445 break;
446 }
447
448 Efuse_PowerSwitch(padapter, bWrite, false);
449
450 return res;
451 }
452
453 u16 efuse_GetMaxSize23a(struct rtw_adapter *padapter)
454 {
455 u16 max_size;
456
457 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
458 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL,
459 (void *)&max_size);
460 return max_size;
461 }
462
463 int rtw_efuse_map_read23a(struct rtw_adapter *padapter,
464 u16 addr, u16 cnts, u8 *data)
465 {
466 u16 mapLen = 0;
467
468 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_WIFI,
469 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
470
471 if ((addr + cnts) > mapLen)
472 return _FAIL;
473
474 Efuse_PowerSwitch(padapter, false, true);
475
476 rtl8723a_readefuse(padapter, EFUSE_WIFI, addr, cnts, data);
477
478 Efuse_PowerSwitch(padapter, false, false);
479
480 return _SUCCESS;
481 }
482
483 int rtw_BT_efuse_map_read23a(struct rtw_adapter *padapter,
484 u16 addr, u16 cnts, u8 *data)
485 {
486 u16 mapLen = 0;
487
488 EFUSE_GetEfuseDefinition23a(padapter, EFUSE_BT,
489 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
490
491 if ((addr + cnts) > mapLen)
492 return _FAIL;
493
494 Efuse_PowerSwitch(padapter, false, true);
495
496 rtl8723a_readefuse(padapter, EFUSE_BT, addr, cnts, data);
497
498 Efuse_PowerSwitch(padapter, false, false);
499
500 return _SUCCESS;
501 }
502
503 /* Read All Efuse content */
504 void Efuse_ReadAllMap(struct rtw_adapter *pAdapter, u8 efuseType, u8 *Efuse)
505 {
506 u16 mapLen = 0;
507
508 Efuse_PowerSwitch(pAdapter, false, true);
509
510 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN,
511 (void *)&mapLen);
512
513 rtl8723a_readefuse(pAdapter, efuseType, 0, mapLen, Efuse);
514
515 Efuse_PowerSwitch(pAdapter, false, false);
516 }
517
518 /*
519 * Functions: efuse_ShadowRead1Byte
520 * efuse_ShadowRead2Byte
521 * efuse_ShadowRead4Byte
522 *
523 * Read from efuse init map by one/two/four bytes
524 */
525 static void efuse_ShadowRead1Byte(struct rtw_adapter *pAdapter, u16 Offset,
526 u8 *Value)
527 {
528 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
529
530 *Value = pEEPROM->efuse_eeprom_data[Offset];
531 }
532
533 static void efuse_ShadowRead2Byte(struct rtw_adapter *pAdapter, u16 Offset,
534 u16 *Value)
535 {
536 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
537
538 *Value = pEEPROM->efuse_eeprom_data[Offset];
539 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
540 }
541
542 static void efuse_ShadowRead4Byte(struct rtw_adapter *pAdapter, u16 Offset,
543 u32 *Value)
544 {
545 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
546
547 *Value = pEEPROM->efuse_eeprom_data[Offset];
548 *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
549 *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
550 *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
551 }
552
553 /* Transfer current EFUSE content to shadow init and modify map. */
554 void EFUSE_ShadowMapUpdate23a(struct rtw_adapter *pAdapter, u8 efuseType)
555 {
556 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
557 u16 mapLen = 0;
558
559 EFUSE_GetEfuseDefinition23a(pAdapter, efuseType,
560 TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
561
562 if (pEEPROM->bautoload_fail_flag == true)
563 memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
564 else
565 Efuse_ReadAllMap(pAdapter, efuseType,
566 pEEPROM->efuse_eeprom_data);
567 }
568
569 /* Read from efuse init map */
570 void EFUSE_ShadowRead23a(struct rtw_adapter *pAdapter, u8 Type,
571 u16 Offset, u32 *Value)
572 {
573 if (Type == 1)
574 efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
575 else if (Type == 2)
576 efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
577 else if (Type == 4)
578 efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
579 }
This page took 0.04271 seconds and 4 git commands to generate.