X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=sboot%2Fmagpie_1_1%2Fsboot%2Fcmnos%2Feeprom%2Fsrc%2Fcmnos_eeprom.c;fp=sboot%2Fmagpie_1_1%2Fsboot%2Fcmnos%2Feeprom%2Fsrc%2Fcmnos_eeprom.c;h=b6a56076b13187fab21965070ed6e311b6c76de6;hb=ff66305a044be28464fa0969ea2d605bb268d478;hp=0000000000000000000000000000000000000000;hpb=60b496560eec004ded92ae4dad43b3d102c6658d;p=open-ath9k-htc-firmware.git diff --git a/sboot/magpie_1_1/sboot/cmnos/eeprom/src/cmnos_eeprom.c b/sboot/magpie_1_1/sboot/cmnos/eeprom/src/cmnos_eeprom.c new file mode 100755 index 0000000..b6a5607 --- /dev/null +++ b/sboot/magpie_1_1/sboot/cmnos/eeprom/src/cmnos_eeprom.c @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2013 Qualcomm Atheros, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted (subject to the limitations in the + * disclaimer below) provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Qualcomm Atheros nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE + * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT + * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "athos_api.h" + + +#if SYSTEM_MODULE_EEPROM + +// DEBUG DELAY OF RC ACCESS!!!!!! SHOULD BE FIXED! +#define PCIE_RC_ACCESS_DELAY 20 + +#define PCI_RC_RESET_BIT BIT6 +#define PCI_RC_PHY_RESET_BIT BIT7 +#define PCI_RC_PLL_RESET_BIT BIT8 +#define PCI_RC_PHY_SHIFT_RESET_BIT BIT10 + +#define H_EEPROM_CTRL 0x401c + #define B_EEP_CTRL_CLKDIV (BIT2|BIT3|BIT4|BIT5|BIT6|BIT7) + #define B_EEP_CTRL_NOT_PRESENT (BIT8) + #define B_EEP_CTRL_CORRUPT (BIT9) + +#define H_EEPROM_STS_DATA 0x407c + #define B_EEP_STS_STATE_BUSY (BIT16) + #define B_EEP_STS_IS_BUSY (BIT17) + #define B_EEP_STS_PROTECTED (BIT18) + #define B_EEP_STS_DATA_NOT_EXIST (BIT19) + +#define CMD_PCI_RC_RESET_ON() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)| \ + (PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT))) + +#define CMD_PCI_RC_RESET_CLR() HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, \ + (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)& \ + (~(PCI_RC_PHY_SHIFT_RESET_BIT|PCI_RC_PLL_RESET_BIT|PCI_RC_PHY_RESET_BIT|PCI_RC_RESET_BIT)))) + + +//////////////////////////////////////////////////////////////////////////////////////////////// + + +/*! eep write half word + * + * offset: is the offset address you want to do the write operation + * data: is the data to write to eeprom + * + * return: TRUE/FALSE + */ +LOCAL BOOLEAN cmnos_eeprom_write_hword(uint16_t offset, uint16_t data) +{ + /*! - Livy sugguest not use the retry, since it'll be huge retry count + * so that, supposed that if the apb or pcie_rc is working fine, + * we should always could see the NOT_BUSY, otherwise, + * it should have something worng!, put a little delay in there, + * + * - debug string here will be noisy!! + */ + //uint16_t retryCnt = 1000; + +#if defined(PROJECT_MAGPIE) + //gpio configuration, set GPIOs output to value set in output reg + HAL_WORD_REG_WRITE((EEPROM_CTRL_BASE+0x4054), (HAL_WORD_REG_READ((EEPROM_CTRL_BASE+0x4054)) | 0x20000)); + HAL_WORD_REG_WRITE((EEPROM_CTRL_BASE+0x4060), 0); + HAL_WORD_REG_WRITE((EEPROM_CTRL_BASE+0x4064), 0); + + //GPIO3 always drive output + HAL_WORD_REG_WRITE((EEPROM_CTRL_BASE+0x404c), 0xc0); + + //Set 0 on GPIO3 + HAL_WORD_REG_WRITE((EEPROM_CTRL_BASE+0x4048), 0x0); +#endif + + HAL_WORD_REG_WRITE(EEPROM_ADDR_BASE + offset*4, (uint32_t)data); + + //while( retryCnt-- > 0 ) + while(1) + { + if( (HAL_WORD_REG_READ((EEPROM_CTRL_BASE+H_EEPROM_STS_DATA))&(B_EEP_STS_STATE_BUSY | B_EEP_STS_IS_BUSY)) == 0 ) + { + return(TRUE); + } +// A_DELAY_USECS(100); + } + + return FALSE; +} + +/*! eep read half word + * + * offset: is the offset address you want to do the read operation + * + * return: the data we read from eeprom + */ +LOCAL BOOLEAN cmnos_eeprom_read_hword(uint16_t offset, uint16_t *mData) +{ + uint32_t mStsData; + //uint16_t retryCnt = 1000; + + HAL_WORD_REG_READ(EEPROM_ADDR_BASE + offset*4); + + //while( retryCnt-- > 0 ) + while(1) + { + mStsData = HAL_WORD_REG_READ((EEPROM_CTRL_BASE+H_EEPROM_STS_DATA)); + + if( (mStsData&(B_EEP_STS_STATE_BUSY | B_EEP_STS_IS_BUSY)) == 0 ) + { + *mData = (uint16_t)(mStsData & 0xffff); + return TRUE; + } +// A_DELAY_USECS(100); + } + + return FALSE; +} +////////////////////////////////////////////////////////////////////////////////////////////////////// + +LOCAL BOOLEAN eep_state = FALSE; +LOCAL BOOLEAN eep_exist = FALSE; + + +/*!- Initialize eeprom, actually we link up the pcie_rc for accessing the eeprom in client card + * + */ +LOCAL T_EEP_RET +cmnos_eep_is_exist(void) +{ + if( FALSE != eep_state ) + { + if( FALSE == eep_exist ) + { + uint16_t mData = HAL_WORD_REG_READ((EEPROM_CTRL_BASE+H_EEPROM_CTRL)); + + if( mData&B_EEP_CTRL_NOT_PRESENT ) + return RET_NOT_EXIST; + else if ( mData&B_EEP_CTRL_CORRUPT ) + return RET_EEP_CORRUPT; + else { + eep_exist = TRUE; + return RET_SUCCESS; + } + } + else // already done the checking, fast response + return RET_SUCCESS; + } + + return RET_NOT_INIT; +} + +/*!- eeprom write + * + * offset: where to write + * len: number of half-word of the pBuf + * pBuf: data buffer to write + */ +LOCAL T_EEP_RET +cmnos_eep_write(uint16_t offset, uint16_t len, uint16_t *pBuf) +{ + T_EEP_RET retVal; + uint16_t *pData = (uint16_t*)pBuf; + uint16_t i, j; + + uint16_t eep_start_ofst = EEPROM_START_OFFSET; + uint16_t eep_end_ofst = EEPROM_END_OFFSET; + + + if( FALSE != eep_state ) + { + if( (offset < eep_start_ofst) || (offset > eep_end_ofst) || ((offset+len) > eep_end_ofst) ) + { + A_PUTS("-E10-"); + retVal = RET_EEP_OVERFLOW; + } + else + { + for(i=offset, j=0; i eep_end_ofst) || ((offset+len) > eep_end_ofst) ) + { + A_PUTS("-E13-"); + retVal = RET_EEP_OVERFLOW; + } + else + { + for(i=(offset); i0) + { + reg_value = HAL_WORD_REG_READ(0x00040018); + if( reg_value & BIT0 ) + break; + A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); + } + + /* init fail, can't detect PCI_RC LINK UP, give up the init */ + if( i<=0 ) + { + DEBUG_SYSTEM_STATE |= BIT26; + goto ERR_DONE; + } + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x47; + HAL_WORD_REG_WRITE(0x14000004, (HAL_WORD_REG_READ(0x14000004)|0x116)); + A_DELAY_USECS(PCIE_RC_ACCESS_DELAY); + + DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x48; + HAL_WORD_REG_WRITE(0x14000010, (HAL_WORD_REG_READ(0x14000010)|EEPROM_CTRL_BASE)); + eep_state = TRUE; + } + +#elif defined(PROJECT_K2) + eep_state = TRUE; +#endif /* End of #if defined(PROJECT_MAGPIE) */ + if (TRUE == eep_state) + { + /* Read offset 1 location to determine if this EEPROM is protected somewhere */ + HAL_WORD_REG_READ(EEPROM_ADDR_BASE + 4); + + while(1) + { + mStsData = HAL_WORD_REG_READ((EEPROM_CTRL_BASE+H_EEPROM_STS_DATA)); + + /* If this location is protected or EEPROM does not exist, return immediately */ + if ( mStsData & (B_EEP_STS_PROTECTED | B_EEP_STS_DATA_NOT_EXIST) ) + { + eep_state = FALSE; + break; + } + + if ( ( mStsData & (B_EEP_STS_STATE_BUSY | B_EEP_STS_IS_BUSY) ) == 0 ) + { + if (mStsData & 0xffff) + cmnos_eeprom_write_hword( (uint16_t)1, (uint16_t)0 ); + + break; + } + + A_DELAY_USECS(100); + } + } +ERR_DONE: + +} + + +void +cmnos_eep_module_install(struct eep_api *tbl) +{ + tbl->_eep_init = cmnos_eep_init; + tbl->_eep_read = cmnos_eep_read; + tbl->_eep_write = cmnos_eep_write; + tbl->_eep_is_exist = cmnos_eep_is_exist; +} + +#endif /* SYSTEM_MODULE_EEPROM */ +