diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-05 18:16:23 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-05 18:16:23 -0700 |
commit | c6a677c6f37bb7abc85ba7e3465e82b9f7eb1d91 (patch) | |
tree | 9d0d4bb2e150837297cddc5be7f1b4950e9ab228 /drivers/staging/rtl8723bs/core/rtw_efuse.c | |
parent | e87d51ac61f88ae44fe14b34abe08566032d726b (diff) | |
parent | 11270059e8d0b6f80801fac910c4ef751ca05c4c (diff) | |
download | op-kernel-dev-c6a677c6f37bb7abc85ba7e3465e82b9f7eb1d91.zip op-kernel-dev-c6a677c6f37bb7abc85ba7e3465e82b9f7eb1d91.tar.gz |
Merge tag 'staging-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging/IIO updates from Greg KH:
"Here is the big staging tree update for 4.12-rc1.
It's a big one, adding about 350k new lines of crap^Wcode, mostly all
in a big dump of media drivers from Intel. But there's other new
drivers in here as well, yet-another-wifi driver, new IIO drivers, and
a new crypto accelerator.
We also deleted a bunch of stuff, mostly in patch cleanups, but also
the Android ION code has shrunk a lot, and the Android low memory
killer driver was finally deleted, much to the celebration of the -mm
developers.
All of these have been in linux-next with a few build issues that will
show up when you merge to your tree"
Merge conflicts in the new rtl8723bs driver (due to the wifi changes
this merge window) handled as per linux-next, courtesy of Stephen
Rothwell.
* tag 'staging-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1182 commits)
staging: fsl-mc/dpio: add cpu <--> LE conversion for dpaa2_fd
staging: ks7010: remove line continuations in quoted strings
staging: vt6656: use tabs instead of spaces
staging: android: ion: Fix unnecessary initialization of static variable
staging: media: atomisp: fix range checking on clk_num
staging: media: atomisp: fix misspelled word in comment
staging: media: atomisp: kmap() can't fail
staging: atomisp: remove #ifdef for runtime PM functions
staging: atomisp: satm include directory is gone
atomisp: remove some more unused files
atomisp: remove hmm_load/store/clear indirections
atomisp: kill off mmgr_free
atomisp: clean up the hmm init/cleanup indirections
atomisp: handle allocation calls before init in the hmm layer
staging: fsl-dpaa2/eth: Add maintainer for Ethernet driver
staging: fsl-dpaa2/eth: Add TODO file
staging: fsl-dpaa2/eth: Add trace points
staging: fsl-dpaa2/eth: Add driver specific stats
staging: fsl-dpaa2/eth: Add ethtool support
staging: fsl-dpaa2/eth: Add Freescale DPAA2 Ethernet driver
...
Diffstat (limited to 'drivers/staging/rtl8723bs/core/rtw_efuse.c')
-rw-r--r-- | drivers/staging/rtl8723bs/core/rtw_efuse.c | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/drivers/staging/rtl8723bs/core/rtw_efuse.c b/drivers/staging/rtl8723bs/core/rtw_efuse.c new file mode 100644 index 0000000..8e29802 --- /dev/null +++ b/drivers/staging/rtl8723bs/core/rtw_efuse.c @@ -0,0 +1,635 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + ******************************************************************************/ +#define _RTW_EFUSE_C_ + +#include <drv_types.h> +#include <rtw_debug.h> +#include <hal_data.h> +#include <linux/jiffies.h> + + +/*------------------------Define local variable------------------------------*/ +u8 fakeEfuseBank = 0; +u32 fakeEfuseUsedBytes = 0; +u8 fakeEfuseContent[EFUSE_MAX_HW_SIZE] = {0}; +u8 fakeEfuseInitMap[EFUSE_MAX_MAP_LEN] = {0}; +u8 fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN] = {0}; + +u32 BTEfuseUsedBytes = 0; +u8 BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +u8 BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; + +u32 fakeBTEfuseUsedBytes = 0; +u8 fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE]; +u8 fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN] = {0}; +/*------------------------Define local variable------------------------------*/ + +/* */ +#define REG_EFUSE_CTRL 0x0030 +#define EFUSE_CTRL REG_EFUSE_CTRL /* E-Fuse Control. */ +/* */ + +bool +Efuse_Read1ByteFromFakeContent( + struct adapter *padapter, + u16 Offset, + u8 *Value); +bool +Efuse_Read1ByteFromFakeContent( + struct adapter *padapter, + u16 Offset, + u8 *Value) +{ + if (Offset >= EFUSE_MAX_HW_SIZE) { + return false; + } + /* DbgPrint("Read fake content, offset = %d\n", Offset); */ + if (fakeEfuseBank == 0) + *Value = fakeEfuseContent[Offset]; + else + *Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset]; + return true; +} + +bool +Efuse_Write1ByteToFakeContent( + struct adapter *padapter, + u16 Offset, + u8 Value); +bool +Efuse_Write1ByteToFakeContent( + struct adapter *padapter, + u16 Offset, + u8 Value) +{ + if (Offset >= EFUSE_MAX_HW_SIZE) { + return false; + } + if (fakeEfuseBank == 0) + fakeEfuseContent[Offset] = Value; + else{ + fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value; + } + return true; +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_PowerSwitch + * + * Overview: When we want to enable write operation, we should change to + * pwr on state. When we stop write, we should switch to 500k mode + * and disable LDO 2.5V. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/17/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +Efuse_PowerSwitch( +struct adapter *padapter, +u8 bWrite, +u8 PwrState) +{ + padapter->HalFunc.EfusePowerSwitch(padapter, bWrite, PwrState); +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_GetCurrentSize + * + * Overview: Get current efuse size!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +u16 +Efuse_GetCurrentSize( + struct adapter *padapter, + u8 efuseType, + bool bPseudoTest) +{ + u16 ret = 0; + + ret = padapter->HalFunc.EfuseGetCurrentSize(padapter, efuseType, bPseudoTest); + + return ret; +} + +/* 11/16/2008 MH Add description. Get current efuse area enabled word!!. */ +u8 +Efuse_CalculateWordCnts(u8 word_en) +{ + u8 word_cnts = 0; + if (!(word_en & BIT(0))) + word_cnts++; /* 0 : write enable */ + if (!(word_en & BIT(1))) + word_cnts++; + if (!(word_en & BIT(2))) + word_cnts++; + if (!(word_en & BIT(3))) + word_cnts++; + return word_cnts; +} + +/* */ +/* Description: */ +/* 1. Execute E-Fuse read byte operation according as map offset and */ +/* save to E-Fuse table. */ +/* 2. Refered from SD1 Richard. */ +/* */ +/* Assumption: */ +/* 1. Boot from E-Fuse and successfully auto-load. */ +/* 2. PASSIVE_LEVEL (USB interface) */ +/* */ +/* Created by Roger, 2008.10.21. */ +/* */ +/* 2008/12/12 MH 1. Reorganize code flow and reserve bytes. and add description. */ +/* 2. Add efuse utilization collect. */ +/* 2008/12/22 MH Read Efuse must check if we write section 1 data again!!! Sec1 */ +/* write addr must be after sec5. */ +/* */ + +void +efuse_ReadEFuse( + struct adapter *Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, +bool bPseudoTest + ); +void +efuse_ReadEFuse( + struct adapter *Adapter, + u8 efuseType, + u16 _offset, + u16 _size_byte, + u8 *pbuf, +bool bPseudoTest + ) +{ + Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest); +} + +void +EFUSE_GetEfuseDefinition( + struct adapter *padapter, + u8 efuseType, + u8 type, + void *pOut, + bool bPseudoTest + ) +{ + padapter->HalFunc.EFUSEGetEfuseDefinition(padapter, efuseType, type, pOut, bPseudoTest); +} + +/*----------------------------------------------------------------------------- + * Function: EFUSE_Read1Byte + * + * Overview: Copy from WMAC fot EFUSE read 1 byte. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 09/23/2008 MHC Copy from WMAC. + * + *---------------------------------------------------------------------------*/ +u8 +EFUSE_Read1Byte( +struct adapter *Adapter, +u16 Address) +{ + u8 data; + u8 Bytetemp = {0x00}; + u8 temp = {0x00}; + u32 k = 0; + u16 contentLen = 0; + + EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen, false); + + if (Address < contentLen) {/* E-fuse 512Byte */ + /* Write E-fuse Register address bit0~7 */ + temp = Address & 0xFF; + rtw_write8(Adapter, EFUSE_CTRL+1, temp); + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2); + /* Write E-fuse Register address bit8~9 */ + temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC); + rtw_write8(Adapter, EFUSE_CTRL+2, temp); + + /* Write 0x30[31]= 0 */ + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + temp = Bytetemp & 0x7F; + rtw_write8(Adapter, EFUSE_CTRL+3, temp); + + /* Wait Write-ready (0x30[31]= 1) */ + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + while (!(Bytetemp & 0x80)) { + Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3); + k++; + if (k == 1000) { + k = 0; + break; + } + } + data = rtw_read8(Adapter, EFUSE_CTRL); + return data; + } else + return 0xFF; + +} /* EFUSE_Read1Byte */ + +/* 11/16/2008 MH Read one byte from real Efuse. */ +u8 +efuse_OneByteRead( +struct adapter *padapter, +u16 addr, +u8 *data, +bool bPseudoTest) +{ + u32 tmpidx = 0; + u8 bResult; + u8 readbyte; + + /* DBG_871X("===> EFUSE_OneByteRead(), addr = %x\n", addr); */ + /* DBG_871X("===> EFUSE_OneByteRead() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */ + + if (bPseudoTest) { + bResult = Efuse_Read1ByteFromFakeContent(padapter, addr, data); + return bResult; + } + + /* <20130121, Kordan> For SMIC EFUSE specificatoin. */ + /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */ + /* PHY_SetMacReg(padapter, 0x34, BIT11, 0); */ + rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) & (~BIT11)); + + /* -----------------e-fuse reg ctrl --------------------------------- */ + /* address */ + rtw_write8(padapter, EFUSE_CTRL+1, (u8)(addr&0xff)); + rtw_write8(padapter, EFUSE_CTRL+2, ((u8)((addr>>8) & 0x03)) | + (rtw_read8(padapter, EFUSE_CTRL+2)&0xFC)); + + /* rtw_write8(padapter, EFUSE_CTRL+3, 0x72); read cmd */ + /* Write bit 32 0 */ + readbyte = rtw_read8(padapter, EFUSE_CTRL+3); + rtw_write8(padapter, EFUSE_CTRL+3, (readbyte & 0x7f)); + + while (!(0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 1000)) { + mdelay(1); + tmpidx++; + } + if (tmpidx < 100) { + *data = rtw_read8(padapter, EFUSE_CTRL); + bResult = true; + } else{ + *data = 0xff; + bResult = false; + DBG_871X("%s: [ERROR] addr = 0x%x bResult =%d time out 1s !!!\n", __func__, addr, bResult); + DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL)); + } + + return bResult; +} + +/* 11/16/2008 MH Write one byte to reald Efuse. */ +u8 +efuse_OneByteWrite( +struct adapter *padapter, +u16 addr, +u8 data, +bool bPseudoTest) +{ + u8 tmpidx = 0; + u8 bResult = false; + u32 efuseValue = 0; + + /* DBG_871X("===> EFUSE_OneByteWrite(), addr = %x data =%x\n", addr, data); */ + /* DBG_871X("===> EFUSE_OneByteWrite() start, 0x34 = 0x%X\n", rtw_read32(padapter, EFUSE_TEST)); */ + + if (bPseudoTest) { + bResult = Efuse_Write1ByteToFakeContent(padapter, addr, data); + return bResult; + } + + + /* -----------------e-fuse reg ctrl --------------------------------- */ + /* address */ + + + efuseValue = rtw_read32(padapter, EFUSE_CTRL); + efuseValue |= (BIT21|BIT31); + efuseValue &= ~(0x3FFFF); + efuseValue |= ((addr<<8 | data) & 0x3FFFF); + + + /* <20130227, Kordan> 8192E MP chip A-cut had better not set 0x34[11] until B-Cut. */ + + /* <20130121, Kordan> For SMIC EFUSE specificatoin. */ + /* 0x34[11]: SW force PGMEN input of efuse to high. (for the bank selected by 0x34[9:8]) */ + /* PHY_SetMacReg(padapter, 0x34, BIT11, 1); */ + rtw_write16(padapter, 0x34, rtw_read16(padapter, 0x34) | (BIT11)); + rtw_write32(padapter, EFUSE_CTRL, 0x90600000|((addr<<8 | data))); + + while ((0x80 & rtw_read8(padapter, EFUSE_CTRL+3)) && (tmpidx < 100)) { + mdelay(1); + tmpidx++; + } + + if (tmpidx < 100) { + bResult = true; + } else{ + bResult = false; + DBG_871X("%s: [ERROR] addr = 0x%x , efuseValue = 0x%x , bResult =%d time out 1s !!!\n", + __func__, addr, efuseValue, bResult); + DBG_871X("%s: [ERROR] EFUSE_CTRL = 0x%08x !!!\n", __func__, rtw_read32(padapter, EFUSE_CTRL)); + } + + /* disable Efuse program enable */ + PHY_SetMacReg(padapter, EFUSE_TEST, BIT(11), 0); + + return bResult; +} + +int +Efuse_PgPacketRead(struct adapter *padapter, + u8 offset, + u8 *data, + bool bPseudoTest) +{ + int ret = 0; + + ret = padapter->HalFunc.Efuse_PgPacketRead(padapter, offset, data, bPseudoTest); + + return ret; +} + +int +Efuse_PgPacketWrite(struct adapter *padapter, + u8 offset, + u8 word_en, + u8 *data, + bool bPseudoTest) +{ + int ret; + + ret = padapter->HalFunc.Efuse_PgPacketWrite(padapter, offset, word_en, data, bPseudoTest); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: efuse_WordEnableDataRead + * + * Overview: Read allowed word in current efuse section data. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/16/2008 MHC Create Version 0. + * 11/21/2008 MHC Fix Write bug when we only enable late word. + * + *---------------------------------------------------------------------------*/ +void +efuse_WordEnableDataRead(u8 word_en, + u8 *sourdata, + u8 *targetdata) +{ + if (!(word_en&BIT(0))) { + targetdata[0] = sourdata[0]; + targetdata[1] = sourdata[1]; + } + if (!(word_en&BIT(1))) { + targetdata[2] = sourdata[2]; + targetdata[3] = sourdata[3]; + } + if (!(word_en&BIT(2))) { + targetdata[4] = sourdata[4]; + targetdata[5] = sourdata[5]; + } + if (!(word_en&BIT(3))) { + targetdata[6] = sourdata[6]; + targetdata[7] = sourdata[7]; + } +} + + +u8 +Efuse_WordEnableDataWrite(struct adapter *padapter, + u16 efuse_addr, + u8 word_en, + u8 *data, + bool bPseudoTest) +{ + u8 ret = 0; + + ret = padapter->HalFunc.Efuse_WordEnableDataWrite(padapter, efuse_addr, word_en, data, bPseudoTest); + + return ret; +} + +/*----------------------------------------------------------------------------- + * Function: Efuse_ReadAllMap + * + * Overview: Read All Efuse content + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/11/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +Efuse_ReadAllMap( + struct adapter *padapter, + u8 efuseType, + u8 *Efuse, + bool bPseudoTest); +void +Efuse_ReadAllMap( + struct adapter *padapter, + u8 efuseType, + u8 *Efuse, + bool bPseudoTest) +{ + u16 mapLen = 0; + + Efuse_PowerSwitch(padapter, false, true); + + EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest); + + efuse_ReadEFuse(padapter, efuseType, 0, mapLen, Efuse, bPseudoTest); + + Efuse_PowerSwitch(padapter, false, false); +} + +/*----------------------------------------------------------------------------- + * Function: efuse_ShadowRead1Byte + * efuse_ShadowRead2Byte + * efuse_ShadowRead4Byte + * + * Overview: Read from efuse init map by one/two/four bytes !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +static void +efuse_ShadowRead1Byte( +struct adapter *padapter, +u16 Offset, + u8 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + +} /* EFUSE_ShadowRead1Byte */ + +/* Read Two Bytes */ +static void +efuse_ShadowRead2Byte( +struct adapter *padapter, +u16 Offset, + u16 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + +} /* EFUSE_ShadowRead2Byte */ + +/* Read Four Bytes */ +static void +efuse_ShadowRead4Byte( +struct adapter *padapter, +u16 Offset, + u32 *Value) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); + + *Value = pEEPROM->efuse_eeprom_data[Offset]; + *Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8; + *Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16; + *Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24; + +} /* efuse_ShadowRead4Byte */ + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowMapUpdate + * + * Overview: Transfer current EFUSE content to shadow init and modify map. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/13/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void EFUSE_ShadowMapUpdate( + struct adapter *padapter, + u8 efuseType, + bool bPseudoTest) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter); + u16 mapLen = 0; + + EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, bPseudoTest); + + if (pEEPROM->bautoload_fail_flag == true) { + memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen); + } else{ + Efuse_ReadAllMap(padapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest); + } + + /* PlatformMoveMemory((void *)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0], */ + /* void *)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen); */ +} /* EFUSE_ShadowMapUpdate */ + + +/*----------------------------------------------------------------------------- + * Function: EFUSE_ShadowRead + * + * Overview: Read from efuse init map !!!!! + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 11/12/2008 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void +EFUSE_ShadowRead( + struct adapter *padapter, + u8 Type, + u16 Offset, + u32 *Value) +{ + if (Type == 1) + efuse_ShadowRead1Byte(padapter, Offset, (u8 *)Value); + else if (Type == 2) + efuse_ShadowRead2Byte(padapter, Offset, (u16 *)Value); + else if (Type == 4) + efuse_ShadowRead4Byte(padapter, Offset, (u32 *)Value); + +} /* EFUSE_ShadowRead*/ |