xref: /linux/drivers/staging/rtl8723bs/core/rtw_efuse.c (revision 37bb2e7217b01404e2abf9d90d8e5705a5603b52)
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #include <drv_types.h>
8 #include <hal_data.h>
9 #include <linux/jiffies.h>
10 
11 
12 /* Define global variables */
13 u8 fakeEfuseBank;
14 u32 fakeEfuseUsedBytes;
15 u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0};
16 u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0};
17 u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0};
18 
19 u32 BTEfuseUsedBytes;
20 u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
21 u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
22 u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
23 
24 u32 fakeBTEfuseUsedBytes;
25 u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
26 u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0};
27 u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0};
28 
29 /*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
30 u8
Efuse_CalculateWordCnts(u8 word_en)31 Efuse_CalculateWordCnts(u8 word_en)
32 {
33 	u8 word_cnts = 0;
34 
35 	if (!(word_en & BIT(0)))
36 		word_cnts++; /*  0 : write enable */
37 	if (!(word_en & BIT(1)))
38 		word_cnts++;
39 	if (!(word_en & BIT(2)))
40 		word_cnts++;
41 	if (!(word_en & BIT(3)))
42 		word_cnts++;
43 	return word_cnts;
44 }
45 
46 /*-----------------------------------------------------------------------------
47  * Function:	EFUSE_Read1Byte
48  *
49  * Overview:	Copy from WMAC fot EFUSE read 1 byte.
50  *
51  * Input:       NONE
52  *
53  * Output:      NONE
54  *
55  * Return:      NONE
56  *
57  * Revised History:
58  * When			Who		Remark
59  * 09/23/2008	MHC		Copy from WMAC.
60  *
61  */
62 u8
EFUSE_Read1Byte(struct adapter * Adapter,u16 Address)63 EFUSE_Read1Byte(
64 struct adapter *Adapter,
65 u16		Address)
66 {
67 	u8 Bytetemp = {0x00};
68 	u8 temp = {0x00};
69 	u32 k = 0;
70 	u16 contentLen = 0;
71 
72 	Hal_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen);
73 
74 	if (Address < contentLen) {/* E-fuse 512Byte */
75 		/* Write E-fuse Register address bit0~7 */
76 		temp = Address & 0xFF;
77 		rtw_write8(Adapter, EFUSE_CTRL + 1, temp);
78 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 2);
79 		/* Write E-fuse Register address bit8~9 */
80 		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
81 		rtw_write8(Adapter, EFUSE_CTRL + 2, temp);
82 
83 		/* Write 0x30[31]= 0 */
84 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
85 		temp = Bytetemp & 0x7F;
86 		rtw_write8(Adapter, EFUSE_CTRL + 3, temp);
87 
88 		/* Wait Write-ready (0x30[31]= 1) */
89 		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
90 		while (!(Bytetemp & 0x80)) {
91 			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL + 3);
92 			k++;
93 			if (k == 1000)
94 				break;
95 		}
96 		return rtw_read8(Adapter, EFUSE_CTRL);
97 	} else
98 		return 0xFF;
99 
100 } /* EFUSE_Read1Byte */
101 
102 /*  11/16/2008 MH Read one byte from real Efuse. */
103 u8
efuse_OneByteRead(struct adapter * padapter,u16 addr,u8 * data)104 efuse_OneByteRead(
105 struct adapter *padapter,
106 u16	addr,
107 u8	*data)
108 {
109 	u32 tmpidx = 0;
110 	u8 bResult;
111 	u8 readbyte;
112 
113 	/*  <20130121, Kordan> For SMIC EFUSE specificatoin. */
114 	/* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */
115 	/* PHY_SetMacReg(padapter, 0x34, BIT11, 0); */
116 	rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) & (~BIT11));
117 
118 	/*  -----------------e-fuse reg ctrl --------------------------------- */
119 	/* address */
120 	rtw_write8(padapter, EFUSE_CTRL + 1, (u8)(addr & 0xff));
121 	rtw_write8(padapter, EFUSE_CTRL + 2, ((u8)((addr >> 8) & 0x03)) |
122 	(rtw_read8(padapter, EFUSE_CTRL + 2) & 0xFC));
123 
124 	/* rtw_write8(padapter, EFUSE_CTRL+3,  0x72); read cmd */
125 	/* Write bit 32 0 */
126 	readbyte = rtw_read8(padapter, EFUSE_CTRL + 3);
127 	rtw_write8(padapter, EFUSE_CTRL + 3, (readbyte & 0x7f));
128 
129 	while (!(0x80 & rtw_read8(padapter, EFUSE_CTRL + 3)) && (tmpidx < 1000)) {
130 		mdelay(1);
131 		tmpidx++;
132 	}
133 	if (tmpidx < 100) {
134 		*data = rtw_read8(padapter, EFUSE_CTRL);
135 		bResult = true;
136 	} else {
137 		*data = 0xff;
138 		bResult = false;
139 	}
140 
141 	return bResult;
142 }
143 
144 /*-----------------------------------------------------------------------------
145  * Function:	Efuse_ReadAllMap
146  *
147  * Overview:	Read All Efuse content
148  *
149  * Input:       NONE
150  *
151  * Output:      NONE
152  *
153  * Return:      NONE
154  *
155  * Revised History:
156  * When			Who		Remark
157  * 11/11/2008	MHC		Create Version 0.
158  *
159  */
Efuse_ReadAllMap(struct adapter * padapter,u8 efuseType,u8 * Efuse)160 static void Efuse_ReadAllMap(struct adapter *padapter, u8 efuseType, u8 *Efuse)
161 {
162 	u16 mapLen = 0;
163 
164 	Hal_EfusePowerSwitch(padapter, true);
165 
166 	Hal_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
167 
168 	Hal_ReadEFuse(padapter, efuseType, 0, mapLen, Efuse);
169 
170 	Hal_EfusePowerSwitch(padapter, false);
171 }
172 
173 /*-----------------------------------------------------------------------------
174  * Function:	efuse_ShadowRead1Byte
175  *		efuse_ShadowRead2Byte
176  *		efuse_ShadowRead4Byte
177  *
178  * Overview:	Read from efuse init map by one/two/four bytes !!!!!
179  *
180  * Input:       NONE
181  *
182  * Output:      NONE
183  *
184  * Return:      NONE
185  *
186  * Revised History:
187  * When			Who		Remark
188  * 11/12/2008	MHC		Create Version 0.
189  *
190  */
efuse_ShadowRead1Byte(struct adapter * padapter,u16 Offset,u8 * Value)191 static void efuse_ShadowRead1Byte(struct adapter *padapter, u16 Offset, u8 *Value)
192 {
193 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
194 
195 	*Value = pEEPROM->efuse_eeprom_data[Offset];
196 
197 }	/*  EFUSE_ShadowRead1Byte */
198 
199 /* Read Two Bytes */
efuse_ShadowRead2Byte(struct adapter * padapter,u16 Offset,u16 * Value)200 static void efuse_ShadowRead2Byte(struct adapter *padapter, u16 Offset, u16 *Value)
201 {
202 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
203 
204 	*Value = pEEPROM->efuse_eeprom_data[Offset];
205 	*Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8;
206 
207 }	/*  EFUSE_ShadowRead2Byte */
208 
209 /* Read Four Bytes */
efuse_ShadowRead4Byte(struct adapter * padapter,u16 Offset,u32 * Value)210 static void efuse_ShadowRead4Byte(struct adapter *padapter, u16 Offset, u32 *Value)
211 {
212 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
213 
214 	*Value = pEEPROM->efuse_eeprom_data[Offset];
215 	*Value |= pEEPROM->efuse_eeprom_data[Offset + 1] << 8;
216 	*Value |= pEEPROM->efuse_eeprom_data[Offset + 2] << 16;
217 	*Value |= pEEPROM->efuse_eeprom_data[Offset + 3] << 24;
218 
219 }	/*  efuse_ShadowRead4Byte */
220 
221 /*-----------------------------------------------------------------------------
222  * Function:	EFUSE_ShadowMapUpdate
223  *
224  * Overview:	Transfer current EFUSE content to shadow init and modify map.
225  *
226  * Input:       NONE
227  *
228  * Output:      NONE
229  *
230  * Return:      NONE
231  *
232  * Revised History:
233  * When			Who		Remark
234  * 11/13/2008	MHC		Create Version 0.
235  *
236  */
EFUSE_ShadowMapUpdate(struct adapter * padapter,u8 efuseType)237 void EFUSE_ShadowMapUpdate(struct adapter *padapter, u8 efuseType)
238 {
239 	struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
240 	u16 mapLen = 0;
241 
242 	Hal_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen);
243 
244 	if (pEEPROM->bautoload_fail_flag)
245 		memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
246 	else
247 		Efuse_ReadAllMap(padapter, efuseType, pEEPROM->efuse_eeprom_data);
248 
249 	/* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */
250 	/* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */
251 } /*  EFUSE_ShadowMapUpdate */
252 
253 
254 /*-----------------------------------------------------------------------------
255  * Function:	EFUSE_ShadowRead
256  *
257  * Overview:	Read from efuse init map !!!!!
258  *
259  * Input:       NONE
260  *
261  * Output:      NONE
262  *
263  * Return:      NONE
264  *
265  * Revised History:
266  * When			Who		Remark
267  * 11/12/2008	MHC		Create Version 0.
268  *
269  */
EFUSE_ShadowRead(struct adapter * padapter,u8 Type,u16 Offset,u32 * Value)270 void EFUSE_ShadowRead(struct adapter *padapter, u8 Type, u16 Offset, u32 *Value)
271 {
272 	if (Type == 1)
273 		efuse_ShadowRead1Byte(padapter, Offset, (u8 *)Value);
274 	else if (Type == 2)
275 		efuse_ShadowRead2Byte(padapter, Offset, (u16 *)Value);
276 	else if (Type == 4)
277 		efuse_ShadowRead4Byte(padapter, Offset, (u32 *)Value);
278 
279 }	/* EFUSE_ShadowRead*/
280