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 local variable------------------------------*/
27 #define REG_EFUSE_CTRL 0x0030
28 #define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */
31 #define VOLTAGE_V25 0x03
32 #define LDOE25_SHIFT 28
34 /*-----------------------------------------------------------------------------
35 * Function: Efuse_PowerSwitch
37 * Overview: When we want to enable write operation, we should change to
38 * pwr on state. When we stop write, we should switch to 500k mode
39 * and disable LDO 2.5V.
49 * 11/17/2008 MHC Create Version 0.
51 *---------------------------------------------------------------------------*/
52 static void Efuse_PowerSwitch(struct rtw_adapter
*padapter
,
53 u8 bWrite
, u8 PwrState
)
58 if (PwrState
== true) {
59 rtl8723au_write8(padapter
, REG_EFUSE_ACCESS
, EFUSE_ACCESS_ON
);
61 /* 1.2V Power: From VDDON with Power
62 Cut(0x0000h[15]), defualt valid */
63 tmpV16
= rtl8723au_read16(padapter
, REG_SYS_ISO_CTRL
);
64 if (!(tmpV16
& PWC_EV12V
)) {
66 rtl8723au_write16(padapter
, REG_SYS_ISO_CTRL
, tmpV16
);
68 /* Reset: 0x0000h[28], default valid */
69 tmpV16
= rtl8723au_read16(padapter
, REG_SYS_FUNC_EN
);
70 if (!(tmpV16
& FEN_ELDR
)) {
72 rtl8723au_write16(padapter
, REG_SYS_FUNC_EN
, tmpV16
);
75 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock
76 from ANA, default valid */
77 tmpV16
= rtl8723au_read16(padapter
, REG_SYS_CLKR
);
78 if ((!(tmpV16
& LOADER_CLK_EN
)) || (!(tmpV16
& ANA8M
))) {
79 tmpV16
|= (LOADER_CLK_EN
| ANA8M
);
80 rtl8723au_write16(padapter
, REG_SYS_CLKR
, tmpV16
);
84 /* Enable LDO 2.5V before read/write action */
85 tempval
= rtl8723au_read8(padapter
, EFUSE_TEST
+ 3);
87 tempval
|= (VOLTAGE_V25
<< 4);
88 rtl8723au_write8(padapter
, EFUSE_TEST
+ 3,
92 rtl8723au_write8(padapter
, REG_EFUSE_ACCESS
, EFUSE_ACCESS_OFF
);
95 /* Disable LDO 2.5V after read/write action */
96 tempval
= rtl8723au_read8(padapter
, EFUSE_TEST
+ 3);
97 rtl8723au_write8(padapter
, EFUSE_TEST
+ 3,
103 /*-----------------------------------------------------------------------------
104 * Function: efuse_GetCurrentSize23a
106 * Overview: Get current efuse size!!!
116 * 11/16/2008 MHC Create Version 0.
118 *---------------------------------------------------------------------------*/
120 Efuse_GetCurrentSize23a(struct rtw_adapter
*pAdapter
, u8 efuseType
)
124 if (efuseType
== EFUSE_WIFI
)
125 ret
= rtl8723a_EfuseGetCurrentSize_WiFi(pAdapter
);
127 ret
= rtl8723a_EfuseGetCurrentSize_BT(pAdapter
);
132 /* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */
134 Efuse_CalculateWordCnts23a(u8 word_en
)
137 if (!(word_en
& BIT(0))) word_cnts
++; /* 0 : write enable */
138 if (!(word_en
& BIT(1))) word_cnts
++;
139 if (!(word_en
& BIT(2))) word_cnts
++;
140 if (!(word_en
& BIT(3))) word_cnts
++;
146 /* Execute E-Fuse read byte operation. */
147 /* Refered from SD1 Richard. */
150 /* 1. Boot from E-Fuse and successfully auto-load. */
151 /* 2. PASSIVE_LEVEL (USB interface) */
153 /* Created by Roger, 2008.10.21. */
156 ReadEFuseByte23a(struct rtw_adapter
*Adapter
, u16 _offset
, u8
*pbuf
)
163 rtl8723au_write8(Adapter
, EFUSE_CTRL
+1, (_offset
& 0xff));
164 readbyte
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+2);
165 rtl8723au_write8(Adapter
, EFUSE_CTRL
+2,
166 ((_offset
>> 8) & 0x03) | (readbyte
& 0xfc));
169 readbyte
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
170 rtl8723au_write8(Adapter
, EFUSE_CTRL
+3, readbyte
& 0x7f);
172 /* Check bit 32 read-ready */
174 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
175 /* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */
176 while(!(((value32
>> 24) & 0xff) & 0x80) && (retry
<10000))
178 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
182 /* 20100205 Joseph: Add delay suggested by SD1 Victor. */
183 /* This fix the problem that Efuse read error in high temperature condition. */
184 /* Designer says that there shall be some delay after ready bit is set, or the */
185 /* result will always stay on last data we read. */
187 value32
= rtl8723au_read32(Adapter
, EFUSE_CTRL
);
189 *pbuf
= (u8
)(value32
& 0xff);
193 EFUSE_GetEfuseDefinition23a(struct rtw_adapter
*pAdapter
, u8 efuseType
,
201 case TYPE_EFUSE_MAX_SECTION
:
202 pMax_section
= (u8
*) pOut
;
204 if (efuseType
== EFUSE_WIFI
)
205 *pMax_section
= EFUSE_MAX_SECTION_8723A
;
207 *pMax_section
= EFUSE_BT_MAX_SECTION
;
210 case TYPE_EFUSE_REAL_CONTENT_LEN
:
211 pu2Tmp
= (u16
*) pOut
;
213 if (efuseType
== EFUSE_WIFI
)
214 *pu2Tmp
= EFUSE_REAL_CONTENT_LEN_8723A
;
216 *pu2Tmp
= EFUSE_BT_REAL_CONTENT_LEN
;
219 case TYPE_AVAILABLE_EFUSE_BYTES_BANK
:
220 pu2Tmp
= (u16
*) pOut
;
222 if (efuseType
== EFUSE_WIFI
)
223 *pu2Tmp
= (EFUSE_REAL_CONTENT_LEN_8723A
-
224 EFUSE_OOB_PROTECT_BYTES
);
226 *pu2Tmp
= (EFUSE_BT_REAL_BANK_CONTENT_LEN
-
227 EFUSE_PROTECT_BYTES_BANK
);
230 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL
:
231 pu2Tmp
= (u16
*) pOut
;
233 if (efuseType
== EFUSE_WIFI
)
234 *pu2Tmp
= (EFUSE_REAL_CONTENT_LEN_8723A
-
235 EFUSE_OOB_PROTECT_BYTES
);
237 *pu2Tmp
= (EFUSE_BT_REAL_CONTENT_LEN
-
238 (EFUSE_PROTECT_BYTES_BANK
* 3));
241 case TYPE_EFUSE_MAP_LEN
:
242 pu2Tmp
= (u16
*) pOut
;
244 if (efuseType
== EFUSE_WIFI
)
245 *pu2Tmp
= EFUSE_MAP_LEN_8723A
;
247 *pu2Tmp
= EFUSE_BT_MAP_LEN
;
250 case TYPE_EFUSE_PROTECT_BYTES_BANK
:
251 pu1Tmp
= (u8
*) pOut
;
253 if (efuseType
== EFUSE_WIFI
)
254 *pu1Tmp
= EFUSE_OOB_PROTECT_BYTES
;
256 *pu1Tmp
= EFUSE_PROTECT_BYTES_BANK
;
259 case TYPE_EFUSE_CONTENT_LEN_BANK
:
260 pu2Tmp
= (u16
*) pOut
;
262 if (efuseType
== EFUSE_WIFI
)
263 *pu2Tmp
= EFUSE_REAL_CONTENT_LEN_8723A
;
265 *pu2Tmp
= EFUSE_BT_REAL_BANK_CONTENT_LEN
;
269 pu1Tmp
= (u8
*) pOut
;
275 /*-----------------------------------------------------------------------------
276 * Function: EFUSE_Read1Byte23a
278 * Overview: Copy from WMAC fot EFUSE read 1 byte.
288 * 09/23/2008 MHC Copy from WMAC.
290 *---------------------------------------------------------------------------*/
292 EFUSE_Read1Byte23a(struct rtw_adapter
*Adapter
, u16 Address
)
295 u8 Bytetemp
= {0x00};
300 EFUSE_GetEfuseDefinition23a(Adapter
, EFUSE_WIFI
,
301 TYPE_EFUSE_REAL_CONTENT_LEN
,
302 (void *)&contentLen
);
304 if (Address
< contentLen
) /* E-fuse 512Byte */
306 /* Write E-fuse Register address bit0~7 */
307 temp
= Address
& 0xFF;
308 rtl8723au_write8(Adapter
, EFUSE_CTRL
+1, temp
);
309 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+2);
310 /* Write E-fuse Register address bit8~9 */
311 temp
= ((Address
>> 8) & 0x03) | (Bytetemp
& 0xFC);
312 rtl8723au_write8(Adapter
, EFUSE_CTRL
+2, temp
);
314 /* Write 0x30[31]= 0 */
315 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
316 temp
= Bytetemp
& 0x7F;
317 rtl8723au_write8(Adapter
, EFUSE_CTRL
+3, temp
);
319 /* Wait Write-ready (0x30[31]= 1) */
320 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
321 while(!(Bytetemp
& 0x80))
323 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
331 data
= rtl8723au_read8(Adapter
, EFUSE_CTRL
);
336 }/* EFUSE_Read1Byte23a */
338 /*-----------------------------------------------------------------------------
339 * Function: EFUSE_Write1Byte
341 * Overview: Copy from WMAC fot EFUSE write 1 byte.
351 * 09/23/2008 MHC Copy from WMAC.
353 *---------------------------------------------------------------------------*/
357 struct rtw_adapter
* Adapter
,
362 struct rtw_adapter
* Adapter
,
366 u8 Bytetemp
= {0x00};
371 /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr =%x Data =%x\n", Address, Value)); */
372 EFUSE_GetEfuseDefinition23a(Adapter
, EFUSE_WIFI
,
373 TYPE_EFUSE_REAL_CONTENT_LEN
,
374 (void *)&contentLen
);
376 if (Address
< contentLen
) /* E-fuse 512Byte */
378 rtl8723au_write8(Adapter
, EFUSE_CTRL
, Value
);
380 /* Write E-fuse Register address bit0~7 */
381 temp
= Address
& 0xFF;
382 rtl8723au_write8(Adapter
, EFUSE_CTRL
+1, temp
);
383 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+2);
385 /* Write E-fuse Register address bit8~9 */
386 temp
= ((Address
>> 8) & 0x03) | (Bytetemp
& 0xFC);
387 rtl8723au_write8(Adapter
, EFUSE_CTRL
+2, temp
);
389 /* Write 0x30[31]= 1 */
390 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
391 temp
= Bytetemp
| 0x80;
392 rtl8723au_write8(Adapter
, EFUSE_CTRL
+3, temp
);
394 /* Wait Write-ready (0x30[31]= 0) */
395 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
396 while(Bytetemp
& 0x80)
398 Bytetemp
= rtl8723au_read8(Adapter
, EFUSE_CTRL
+3);
407 }/* EFUSE_Write1Byte */
409 /* 11/16/2008 MH Read one byte from real Efuse. */
411 efuse_OneByteRead23a(struct rtw_adapter
*pAdapter
, u16 addr
, u8
*data
)
416 /* -----------------e-fuse reg ctrl --------------------------------- */
418 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+1, (u8
)(addr
&0xff));
419 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+2, ((u8
)((addr
>>8) &0x03)) |
420 (rtl8723au_read8(pAdapter
, EFUSE_CTRL
+2)&0xFC));
422 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+3, 0x72);/* read cmd */
424 while(!(0x80 &rtl8723au_read8(pAdapter
, EFUSE_CTRL
+3)) && (tmpidx
<100))
427 *data
= rtl8723au_read8(pAdapter
, EFUSE_CTRL
);
436 /* 11/16/2008 MH Write one byte to reald Efuse. */
438 efuse_OneByteWrite23a(struct rtw_adapter
*pAdapter
, u16 addr
, u8 data
)
443 /* RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data =%x\n", addr, data)); */
447 /* -----------------e-fuse reg ctrl --------------------------------- */
449 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+1, (u8
)(addr
&0xff));
450 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+2,
451 (rtl8723au_read8(pAdapter
, EFUSE_CTRL
+2)&0xFC)|(u8
)((addr
>>8)&0x03));
452 rtl8723au_write8(pAdapter
, EFUSE_CTRL
, data
);/* data */
454 rtl8723au_write8(pAdapter
, EFUSE_CTRL
+3, 0xF2);/* write cmd */
456 while((0x80 & rtl8723au_read8(pAdapter
, EFUSE_CTRL
+3)) &&
469 /*-----------------------------------------------------------------------------
470 * Function: efuse_WordEnableDataRead23a
472 * Overview: Read allowed word in current efuse section data.
482 * 11/16/2008 MHC Create Version 0.
483 * 11/21/2008 MHC Fix Write bug when we only enable late word.
485 *---------------------------------------------------------------------------*/
487 efuse_WordEnableDataRead23a(u8 word_en
,
491 if (!(word_en
&BIT(0)))
493 targetdata
[0] = sourdata
[0];
494 targetdata
[1] = sourdata
[1];
496 if (!(word_en
&BIT(1)))
498 targetdata
[2] = sourdata
[2];
499 targetdata
[3] = sourdata
[3];
501 if (!(word_en
&BIT(2)))
503 targetdata
[4] = sourdata
[4];
504 targetdata
[5] = sourdata
[5];
506 if (!(word_en
&BIT(3)))
508 targetdata
[6] = sourdata
[6];
509 targetdata
[7] = sourdata
[7];
513 static int efuse_read8(struct rtw_adapter
*padapter
, u16 address
, u8
*value
)
515 return efuse_OneByteRead23a(padapter
, address
, value
);
518 static int efuse_write8(struct rtw_adapter
*padapter
, u16 address
, u8
*value
)
520 return efuse_OneByteWrite23a(padapter
, address
, *value
);
524 * read/wirte raw efuse data
526 int rtw_efuse_access23a(struct rtw_adapter
*padapter
, u8 bWrite
, u16 start_addr
,
530 u16 real_content_len
= 0, max_available_size
= 0;
532 int (*rw8
)(struct rtw_adapter
*, u16
, u8
*);
534 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
535 TYPE_EFUSE_REAL_CONTENT_LEN
,
536 (void *)&real_content_len
);
537 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
538 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL
,
539 (void *)&max_available_size
);
541 if (start_addr
> real_content_len
)
544 if (true == bWrite
) {
545 if ((start_addr
+ cnts
) > max_available_size
)
551 Efuse_PowerSwitch(padapter
, bWrite
, true);
553 /* e-fuse one byte read / write */
554 for (i
= 0; i
< cnts
; i
++) {
555 if (start_addr
>= real_content_len
) {
560 res
= rw8(padapter
, start_addr
++, data
++);
565 Efuse_PowerSwitch(padapter
, bWrite
, false);
570 u16
efuse_GetMaxSize23a(struct rtw_adapter
*padapter
)
573 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
574 TYPE_AVAILABLE_EFUSE_BYTES_TOTAL
,
579 int efuse_GetCurrentSize23a(struct rtw_adapter
*padapter
, u16
*size
)
581 Efuse_PowerSwitch(padapter
, false, true);
582 *size
= Efuse_GetCurrentSize23a(padapter
, EFUSE_WIFI
);
583 Efuse_PowerSwitch(padapter
, false, false);
588 int rtw_efuse_map_read23a(struct rtw_adapter
*padapter
,
589 u16 addr
, u16 cnts
, u8
*data
)
593 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_WIFI
,
594 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
596 if ((addr
+ cnts
) > mapLen
)
599 Efuse_PowerSwitch(padapter
, false, true);
601 rtl8723a_readefuse(padapter
, EFUSE_WIFI
, addr
, cnts
, data
);
603 Efuse_PowerSwitch(padapter
, false, false);
608 int rtw_BT_efuse_map_read23a(struct rtw_adapter
*padapter
,
609 u16 addr
, u16 cnts
, u8
*data
)
613 EFUSE_GetEfuseDefinition23a(padapter
, EFUSE_BT
,
614 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
616 if ((addr
+ cnts
) > mapLen
)
619 Efuse_PowerSwitch(padapter
, false, true);
621 rtl8723a_readefuse(padapter
, EFUSE_BT
, addr
, cnts
, data
);
623 Efuse_PowerSwitch(padapter
, false, false);
628 /*-----------------------------------------------------------------------------
629 * Function: Efuse_ReadAllMap
631 * Overview: Read All Efuse content
641 * 11/11/2008 MHC Create Version 0.
643 *---------------------------------------------------------------------------*/
645 Efuse_ReadAllMap(struct rtw_adapter
*pAdapter
, u8 efuseType
, u8
*Efuse
);
647 Efuse_ReadAllMap(struct rtw_adapter
*pAdapter
, u8 efuseType
, u8
*Efuse
)
651 Efuse_PowerSwitch(pAdapter
, false, true);
653 EFUSE_GetEfuseDefinition23a(pAdapter
, efuseType
, TYPE_EFUSE_MAP_LEN
,
656 rtl8723a_readefuse(pAdapter
, efuseType
, 0, mapLen
, Efuse
);
658 Efuse_PowerSwitch(pAdapter
, false, false);
661 /*-----------------------------------------------------------------------------
662 * Function: efuse_ShadowRead1Byte
663 * efuse_ShadowRead2Byte
664 * efuse_ShadowRead4Byte
666 * Overview: Read from efuse init map by one/two/four bytes !!!!!
676 * 11/12/2008 MHC Create Version 0.
678 *---------------------------------------------------------------------------*/
680 efuse_ShadowRead1Byte(
681 struct rtw_adapter
* pAdapter
,
685 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
687 *Value
= pEEPROM
->efuse_eeprom_data
[Offset
];
688 } /* EFUSE_ShadowRead23a1Byte */
692 efuse_ShadowRead2Byte(
693 struct rtw_adapter
* pAdapter
,
697 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
699 *Value
= pEEPROM
->efuse_eeprom_data
[Offset
];
700 *Value
|= pEEPROM
->efuse_eeprom_data
[Offset
+1]<<8;
701 } /* EFUSE_ShadowRead23a2Byte */
703 /* Read Four Bytes */
705 efuse_ShadowRead4Byte(
706 struct rtw_adapter
* pAdapter
,
710 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
712 *Value
= pEEPROM
->efuse_eeprom_data
[Offset
];
713 *Value
|= pEEPROM
->efuse_eeprom_data
[Offset
+1]<<8;
714 *Value
|= pEEPROM
->efuse_eeprom_data
[Offset
+2]<<16;
715 *Value
|= pEEPROM
->efuse_eeprom_data
[Offset
+3]<<24;
716 } /* efuse_ShadowRead4Byte */
718 /*-----------------------------------------------------------------------------
719 * Function: EFUSE_ShadowMapUpdate23a
721 * Overview: Transfer current EFUSE content to shadow init and modify map.
731 * 11/13/2008 MHC Create Version 0.
733 *---------------------------------------------------------------------------*/
734 void EFUSE_ShadowMapUpdate23a(struct rtw_adapter
*pAdapter
, u8 efuseType
)
736 struct eeprom_priv
*pEEPROM
= GET_EEPROM_EFUSE_PRIV(pAdapter
);
739 EFUSE_GetEfuseDefinition23a(pAdapter
, efuseType
,
740 TYPE_EFUSE_MAP_LEN
, (void *)&mapLen
);
742 if (pEEPROM
->bautoload_fail_flag
== true)
743 memset(pEEPROM
->efuse_eeprom_data
, 0xFF, mapLen
);
745 Efuse_ReadAllMap(pAdapter
, efuseType
,
746 pEEPROM
->efuse_eeprom_data
);
748 }/* EFUSE_ShadowMapUpdate23a */
750 /*-----------------------------------------------------------------------------
751 * Function: EFUSE_ShadowRead23a
753 * Overview: Read from efuse init map !!!!!
763 * 11/12/2008 MHC Create Version 0.
765 *---------------------------------------------------------------------------*/
768 struct rtw_adapter
* pAdapter
,
774 efuse_ShadowRead1Byte(pAdapter
, Offset
, (u8
*)Value
);
776 efuse_ShadowRead2Byte(pAdapter
, Offset
, (u16
*)Value
);
778 efuse_ShadowRead4Byte(pAdapter
, Offset
, (u32
*)Value
);
779 } /* EFUSE_ShadowRead23a */