1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtw_efuse.h>
21 #include <rtl8723a_hal.h>
22 #include <usb_ops_linux.h>
24 #define REG_EFUSE_CTRL 0x0030
25 #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control */
27 #define VOLTAGE_V25 0x03
28 #define LDOE25_SHIFT 28
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.
35 static void Efuse_PowerSwitch(struct rtw_adapter
*padapter
,
36 u8 bWrite
, u8 PwrState
)
41 if (PwrState
== true) {
42 rtl8723au_write8(padapter
, REG_EFUSE_ACCESS
, EFUSE_ACCESS_ON
);
45 * 1.2V Power: From VDDON with Power
46 * Cut(0x0000h[15]), default valid
48 tmpV16
= rtl8723au_read16(padapter
, REG_SYS_ISO_CTRL
);
49 if (!(tmpV16
& PWC_EV12V
)) {
51 rtl8723au_write16(padapter
, REG_SYS_ISO_CTRL
, tmpV16
);
53 /* Reset: 0x0000h[28], default valid */
54 tmpV16
= rtl8723au_read16(padapter
, REG_SYS_FUNC_EN
);
55 if (!(tmpV16
& FEN_ELDR
)) {
57 rtl8723au_write16(padapter
, REG_SYS_FUNC_EN
, tmpV16
);
61 * Clock: Gated(0x0008h[5]) 8M(0x0008h[1])
62 * clock from ANA, default valid
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
);
71 /* Enable LDO 2.5V before read/write action */
72 tempval
= rtl8723au_read8(padapter
, EFUSE_TEST
+ 3);
74 tempval
|= (VOLTAGE_V25
<< 4);
75 rtl8723au_write8(padapter
, EFUSE_TEST
+ 3,
79 rtl8723au_write8(padapter
, REG_EFUSE_ACCESS
, EFUSE_ACCESS_OFF
);
82 /* Disable LDO 2.5V after read/write action */
83 tempval
= rtl8723au_read8(padapter
, EFUSE_TEST
+ 3);
84 rtl8723au_write8(padapter
, EFUSE_TEST
+ 3,
90 u16
Efuse_GetCurrentSize23a(struct rtw_adapter
*pAdapter
, u8 efuseType
)
94 if (efuseType
== EFUSE_WIFI
)
95 ret
= rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter
);
97 ret
= rtl8723a_EfuseGetCurrentSize_BT(pAdapter
);
102 /* Get current efuse area enabled word */
103 u8
Efuse_CalculateWordCnts23a(u8 word_en
)
105 return hweight8((~word_en
) & 0xf);
109 * Description: Execute E-Fuse read byte operation.
111 * Assumptions: 1. Boot from E-Fuse and successfully auto-load.
112 * 2. PASSIVE_LEVEL (USB interface)
114 void ReadEFuseByte23a(struct rtw_adapter
*Adapter
, u16 _offset
, u8
*pbuf
)
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));
127 readbyte
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
128 rtl8723au_write8(Adapter
, EFUSE_CTRL
+3, readbyte
& 0x7f);
130 /* Check bit 32 read-ready */
132 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
133 while (!((value32
>> 24) & 0x80) && retry
< 10000) {
134 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
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.
146 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
148 *pbuf
= (u8
)(value32
& 0xff);
151 void EFUSE_GetEfuseDefinition23a(struct rtw_adapter
*pAdapter
, u8 efuseType
,
159 case TYPE_EFUSE_MAX_SECTION
:
162 if (efuseType
== EFUSE_WIFI
)
163 *pMax_section
= EFUSE_MAX_SECTION_8723A
;
165 *pMax_section
= EFUSE_BT_MAX_SECTION
;
168 case TYPE_EFUSE_REAL_CONTENT_LEN
:
171 if (efuseType
== EFUSE_WIFI
)
172 *pu2Tmp
= EFUSE_REAL_CONTENT_LEN_8723A
;
174 *pu2Tmp
= EFUSE_BT_REAL_CONTENT_LEN
;
177 case TYPE_AVAILABLE_EFUSE_BYTES_BANK
:
180 if (efuseType
== EFUSE_WIFI
)
181 *pu2Tmp
= (EFUSE_REAL_CONTENT_LEN_8723A
-
182 EFUSE_OOB_PROTECT_BYTES
);
184 *pu2Tmp
= (EFUSE_BT_REAL_BANK_CONTENT_LEN
-
185 EFUSE_PROTECT_BYTES_BANK
);
188 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL
:
191 if (efuseType
== EFUSE_WIFI
)
192 *pu2Tmp
= (EFUSE_REAL_CONTENT_LEN_8723A
-
193 EFUSE_OOB_PROTECT_BYTES
);
195 *pu2Tmp
= (EFUSE_BT_REAL_CONTENT_LEN
-
196 (EFUSE_PROTECT_BYTES_BANK
* 3));
199 case TYPE_EFUSE_MAP_LEN
:
202 if (efuseType
== EFUSE_WIFI
)
203 *pu2Tmp
= EFUSE_MAP_LEN_8723A
;
205 *pu2Tmp
= EFUSE_BT_MAP_LEN
;
208 case TYPE_EFUSE_PROTECT_BYTES_BANK
:
211 if (efuseType
== EFUSE_WIFI
)
212 *pu1Tmp
= EFUSE_OOB_PROTECT_BYTES
;
214 *pu1Tmp
= EFUSE_PROTECT_BYTES_BANK
;
217 case TYPE_EFUSE_CONTENT_LEN_BANK
:
220 if (efuseType
== EFUSE_WIFI
)
221 *pu2Tmp
= EFUSE_REAL_CONTENT_LEN_8723A
;
223 *pu2Tmp
= EFUSE_BT_REAL_BANK_CONTENT_LEN
;
233 /* Copy from WMAC for EFUSE read 1 byte. */
234 u8
EFUSE_Read1Byte23a(struct rtw_adapter
*Adapter
, u16 Address
)
237 u8 Bytetemp
= {0x00};
242 EFUSE_GetEfuseDefinition23a(Adapter
, EFUSE_WIFI
,
243 TYPE_EFUSE_REAL_CONTENT_LEN
,
244 (void *)&contentLen
);
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
);
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
);
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);
270 data
= rtl8723au_read8(Adapter
, EFUSE_CTRL
);
276 /* Copy from WMAC fot EFUSE write 1 byte. */
277 void EFUSE_Write1Byte(struct rtw_adapter
*Adapter
, u16 Address
, u8 Value
)
279 u8 Bytetemp
= {0x00};
284 EFUSE_GetEfuseDefinition23a(Adapter
, EFUSE_WIFI
,
285 TYPE_EFUSE_REAL_CONTENT_LEN
,
286 (void *)&contentLen
);
288 if (Address
< contentLen
) { /* E-fuse 512Byte */
289 rtl8723au_write8(Adapter
, EFUSE_CTRL
, Value
);
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);
296 /* Write E-fuse Register address bit8~9 */
297 temp
= ((Address
>> 8) & 0x03) | (Bytetemp
& 0xFC);
298 rtl8723au_write8(Adapter
, EFUSE_CTRL
+2, temp
);
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
);
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);
318 /* Read one byte from real Efuse. */
319 int efuse_OneByteRead23a(struct rtw_adapter
*pAdapter
, u16 addr
, u8
*data
)
324 /* -----------------e-fuse reg ctrl ---------------------------- */
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));
331 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+ 3, 0x72); /* read cmd */
333 while (!(0x80 & rtl8723au_read8(pAdapter
, EFUSE_CTRL
+ 3)) &&
337 *data
= rtl8723au_read8(pAdapter
, EFUSE_CTRL
);
346 /* Write one byte to reald Efuse. */
347 int efuse_OneByteWrite23a(struct rtw_adapter
*pAdapter
, u16 addr
, u8 data
)
354 /* -----------------e-fuse reg ctrl ------------------------- */
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 */
362 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+ 3, 0xF2); /* write cmd */
364 while ((0x80 & rtl8723au_read8(pAdapter
, EFUSE_CTRL
+ 3)) &&
377 /* Read allowed word in current efuse section data. */
378 void efuse_WordEnableDataRead23a(u8 word_en
, u8
*sourdata
, u8
*targetdata
)
380 if (!(word_en
&BIT(0))) {
381 targetdata
[0] = sourdata
[0];
382 targetdata
[1] = sourdata
[1];
384 if (!(word_en
&BIT(1))) {
385 targetdata
[2] = sourdata
[2];
386 targetdata
[3] = sourdata
[3];
388 if (!(word_en
&BIT(2))) {
389 targetdata
[4] = sourdata
[4];
390 targetdata
[5] = sourdata
[5];
392 if (!(word_en
&BIT(3))) {
393 targetdata
[6] = sourdata
[6];
394 targetdata
[7] = sourdata
[7];
398 static int efuse_read8(struct rtw_adapter
*padapter
, u16 address
, u8
*value
)
400 return efuse_OneByteRead23a(padapter
, address
, value
);
403 static int efuse_write8(struct rtw_adapter
*padapter
, u16 address
, u8
*value
)
405 return efuse_OneByteWrite23a(padapter
, address
, *value
);
408 /* read/write raw efuse data */
409 int rtw_efuse_access23a(struct rtw_adapter
*padapter
, u8 bWrite
, u16 start_addr
,
413 u16 real_content_len
= 0, max_available_size
= 0;
415 int (*rw8
)(struct rtw_adapter
*, u16
, u8
*);
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
);
424 if (start_addr
> real_content_len
)
427 if (true == bWrite
) {
428 if ((start_addr
+ cnts
) > max_available_size
)
434 Efuse_PowerSwitch(padapter
, bWrite
, true);
436 /* e-fuse one byte read/write */
437 for (i
= 0; i
< cnts
; i
++) {
438 if (start_addr
>= real_content_len
) {
443 res
= rw8(padapter
, start_addr
++, data
++);
448 Efuse_PowerSwitch(padapter
, bWrite
, false);
453 u16
efuse_GetMaxSize23a(struct rtw_adapter
*padapter
)
457 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
458 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL
,
463 int rtw_efuse_map_read23a(struct rtw_adapter
*padapter
,
464 u16 addr
, u16 cnts
, u8
*data
)
468 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
469 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
471 if ((addr
+ cnts
) > mapLen
)
474 Efuse_PowerSwitch(padapter
, false, true);
476 rtl8723a_readefuse(padapter
, EFUSE_WIFI
, addr
, cnts
, data
);
478 Efuse_PowerSwitch(padapter
, false, false);
483 int rtw_BT_efuse_map_read23a(struct rtw_adapter
*padapter
,
484 u16 addr
, u16 cnts
, u8
*data
)
488 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_BT
,
489 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
491 if ((addr
+ cnts
) > mapLen
)
494 Efuse_PowerSwitch(padapter
, false, true);
496 rtl8723a_readefuse(padapter
, EFUSE_BT
, addr
, cnts
, data
);
498 Efuse_PowerSwitch(padapter
, false, false);
503 /* Read All Efuse content */
504 void Efuse_ReadAllMap(struct rtw_adapter
*pAdapter
, u8 efuseType
, u8
*Efuse
)
508 Efuse_PowerSwitch(pAdapter
, false, true);
510 EFUSE_GetEfuseDefinition23a(pAdapter
, efuseType
, TYPE_EFUSE_MAP_LEN
,
513 rtl8723a_readefuse(pAdapter
, efuseType
, 0, mapLen
, Efuse
);
515 Efuse_PowerSwitch(pAdapter
, false, false);
519 * Functions: efuse_ShadowRead1Byte
520 * efuse_ShadowRead2Byte
521 * efuse_ShadowRead4Byte
523 * Read from efuse init map by one/two/four bytes
525 static void efuse_ShadowRead1Byte(struct rtw_adapter
*pAdapter
, u16 Offset
,
528 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
530 *Value
= pEEPROM
->efuse_eeprom_data
[Offset
];
533 static void efuse_ShadowRead2Byte(struct rtw_adapter
*pAdapter
, u16 Offset
,
536 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
538 *Value
= pEEPROM
->efuse_eeprom_data
[Offset
];
539 *Value
|= pEEPROM
->efuse_eeprom_data
[Offset
+1]<<8;
542 static void efuse_ShadowRead4Byte(struct rtw_adapter
*pAdapter
, u16 Offset
,
545 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
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;
553 /* Transfer current EFUSE content to shadow init and modify map. */
554 void EFUSE_ShadowMapUpdate23a(struct rtw_adapter
*pAdapter
, u8 efuseType
)
556 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
559 EFUSE_GetEfuseDefinition23a(pAdapter
, efuseType
,
560 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
562 if (pEEPROM
->bautoload_fail_flag
== true)
563 memset(pEEPROM
->efuse_eeprom_data
, 0xFF, mapLen
);
565 Efuse_ReadAllMap(pAdapter
, efuseType
,
566 pEEPROM
->efuse_eeprom_data
);
569 /* Read from efuse init map */
570 void EFUSE_ShadowRead23a(struct rtw_adapter
*pAdapter
, u8 Type
,
571 u16 Offset
, u32
*Value
)
574 efuse_ShadowRead1Byte(pAdapter
, Offset
, (u8
*)Value
);
576 efuse_ShadowRead2Byte(pAdapter
, Offset
, (u16
*)Value
);
578 efuse_ShadowRead4Byte(pAdapter
, Offset
, (u32
*)Value
);