| /******************************************************************************* |
| Copyright (C) Marvell International Ltd. and its affiliates |
| |
| This software file (the "File") is owned and distributed by Marvell |
| International Ltd. and/or its affiliates ("Marvell") under the following |
| alternative licensing terms. Once you have made an election to distribute the |
| File under one of the following license alternatives, please (i) delete this |
| introductory statement regarding license alternatives, (ii) delete the two |
| license alternatives that you have not elected to use and (iii) preserve the |
| Marvell copyright notice above. |
| |
| ******************************************************************************** |
| Marvell Commercial License Option |
| |
| If you received this File from Marvell and you have entered into a commercial |
| license agreement (a "Commercial License") with Marvell, the File is licensed |
| to you under the terms of the applicable Commercial License. |
| |
| ******************************************************************************** |
| Marvell GPL License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File in accordance with the terms and conditions of the General |
| Public License Version 2, June 1991 (the "GPL License"), a copy of which is |
| available along with the File in the license.txt file or by writing to the Free |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or |
| on the worldwide web at http://www.gnu.org/licenses/gpl.txt. |
| |
| THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED |
| WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY |
| DISCLAIMED. The GPL License provides additional details about this warranty |
| disclaimer. |
| ******************************************************************************** |
| Marvell BSD License Option |
| |
| If you received this File from Marvell, you may opt to use, redistribute and/or |
| modify this File under the following licensing terms. |
| Redistribution and use in source and binary forms, with or without modification, |
| are permitted 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 Marvell nor the names of its contributors may be |
| used to endorse or promote products derived from this software without |
| specific prior written permission. |
| |
| 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 "ctrlEnv/mvCtrlEnvLib.h" |
| #include "ctrlEnv/mvCtrlEnvSpec.h" |
| #include "boardEnv/mvBoardEnvLib.h" |
| #include "ctrlEnv/sys/mvCpuIf.h" |
| #include "cpu/mvCpu.h" |
| #include "cntmr/mvCntmr.h" |
| #include "gpp/mvGpp.h" |
| #include "twsi/mvTwsi.h" |
| #include "pex/mvPex.h" |
| #include "pci/mvPci.h" |
| #include "device/mvDevice.h" |
| |
| #if defined(CONFIG_MV_ETH_NETA) |
| #include "neta/gbe/mvEthRegs.h" |
| #elif defined(CONFIG_MV_ETH_PP2) |
| #include "pp2/gbe/mvPp2GbeRegs.h" |
| #endif |
| |
| #include "gpp/mvGppRegs.h" |
| |
| /* defines */ |
| #undef MV_DEBUG |
| #ifdef MV_DEBUG |
| #define DB(x) x |
| #else |
| #define DB(x) |
| #endif |
| |
| extern MV_BOARD_INFO *marvellBoardInfoTbl[]; |
| extern MV_BOARD_INFO *customerBoardInfoTbl[]; |
| extern MV_BOARD_SATR_INFO boardSatrInfo[]; |
| MV_BOARD_CONFIG_TYPE_INFO boardConfigTypesInfo[] = MV_BOARD_CONFIG_INFO; |
| |
| /* Locals */ |
| static MV_DEV_CS_INFO *mvBoardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass); |
| /* Global variables should be removed from BSS (set to a non-zero value) |
| for avoiding memory corruption during early access upon code relocation */ |
| static MV_BOARD_INFO *board = (MV_BOARD_INFO *)-1; |
| MV_U32 boardOptionsConfig[MV_CONFIG_TYPE_MAX_OPTION]; |
| |
| /******************************************************************************* |
| * mvBoardisUsbPortConnected |
| * |
| * DESCRIPTION: |
| * return True if requested USB type and port num exists on current board |
| * |
| * INPUT: |
| * usbTypeID - requested USB type : USB3_UNIT_ID / USB_UNIT_ID |
| * usbPortNumbder - requested USB port number (according to xHCI MAC port num) |
| * |
| * OUTPUT: None |
| * |
| * RETURN: MV_TRUE if requested port/type exist on board |
| |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsUsbPortConnected(MV_UNIT_ID usbTypeID, MV_U8 usbPortNumber) |
| { |
| /* USB Port board mapping is not supported by Avanta-LP |
| Controller mapping is done via mvCtrlUsbMapGet.*/ |
| if (usbPortNumber >= mvCtrlUsbMaxGet()) |
| return MV_FALSE; |
| return MV_TRUE; |
| } |
| |
| |
| |
| /******************************************************************************* |
| * mvBoardIdIndexGet |
| * |
| * DESCRIPTION: |
| * returns an index for board arrays with direct memory access, according to board id |
| * |
| * INPUT: |
| * boardId. |
| * |
| * OUTPUT: |
| * direct access index for board arrays |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardIdIndexGet(MV_U32 boardId) |
| { |
| /* Marvell Boards use 0x10 as base for Board ID: mask MSB to receive index for board ID*/ |
| return boardId & (MARVELL_BOARD_ID_BASE - 1); |
| } |
| |
| /******************************************************************************* |
| * mvBoardEnvInit |
| * |
| * DESCRIPTION: |
| * In this function the board environment take care of device bank |
| * initialization. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardEnvInit(MV_VOID) |
| { |
| mvBoardSet(mvBoardIdGet()); |
| |
| /* FPGA board doesn't use MPP neither GPIO */ |
| #if !defined(CONFIG_MACH_AVANTA_LP_FPGA) |
| MV_U32 nandDev; |
| MV_U32 norDev; |
| |
| nandDev = mvBoardGetDevCSNum(0, BOARD_DEV_NAND_FLASH); |
| if (nandDev != 0xFFFFFFFF) { |
| /* Set NAND interface access parameters */ |
| nandDev = BOOT_CS; |
| MV_REG_WRITE(DEV_BANK_PARAM_REG(nandDev), board->nandFlashReadParams); |
| MV_REG_WRITE(DEV_BANK_PARAM_REG_WR(nandDev), board->nandFlashWriteParams); |
| MV_REG_WRITE(DEV_NAND_CTRL_REG, board->nandFlashControl); |
| } |
| |
| norDev = mvBoardGetDevCSNum(0, BOARD_DEV_NOR_FLASH); |
| if (norDev != 0xFFFFFFFF) { |
| /* Set NOR interface access parameters */ |
| MV_REG_WRITE(DEV_BANK_PARAM_REG(norDev), board->norFlashReadParams); |
| MV_REG_WRITE(DEV_BANK_PARAM_REG_WR(norDev), board->norFlashWriteParams); |
| MV_REG_WRITE(DEV_BUS_SYNC_CTRL, 0x11); |
| } |
| |
| /* Set GPP Out value */ |
| MV_REG_WRITE(GPP_DATA_OUT_REG(0), board->gppOutValLow); |
| MV_REG_WRITE(GPP_DATA_OUT_REG(1), board->gppOutValMid); |
| MV_REG_WRITE(GPP_DATA_OUT_REG(2), board->gppOutValHigh); |
| |
| /* set GPP polarity */ |
| mvGppPolaritySet(0, 0xFFFFFFFF, board->gppPolarityValLow); |
| mvGppPolaritySet(1, 0xFFFFFFFF, board->gppPolarityValMid); |
| mvGppPolaritySet(2, 0xFFFFFFFF, board->gppPolarityValHigh); |
| |
| /* Set GPP Out Enable */ |
| mvGppTypeSet(0, 0xFFFFFFFF, board->gppOutEnValLow); |
| mvGppTypeSet(1, 0xFFFFFFFF, board->gppOutEnValMid); |
| mvGppTypeSet(2, 0xFFFFFFFF, board->gppOutEnValHigh); |
| |
| #endif |
| } |
| |
| /******************************************************************************* |
| * mvBoardModelGet - Get Board model |
| * |
| * DESCRIPTION: |
| * This function returns 16bit describing board model. |
| * Board model is constructed of one byte major and minor numbers in the |
| * following manner: |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * String describing board model. |
| * |
| *******************************************************************************/ |
| MV_U16 mvBoardModelGet(MV_VOID) |
| { |
| return mvBoardIdIndexGet(mvBoardIdGet()) >> 16; |
| } |
| |
| /******************************************************************************* |
| * mbBoardRevlGet - Get Board revision |
| * |
| * DESCRIPTION: |
| * This function returns a 32bit describing the board revision. |
| * Board revision is constructed of 4bytes. 2bytes describes major number |
| * and the other 2bytes describes minor munber. |
| * For example for board revision 3.4 the function will return |
| * 0x00030004. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * String describing board model. |
| * |
| *******************************************************************************/ |
| MV_U16 mvBoardRevGet(MV_VOID) |
| { |
| return mvBoardIdIndexGet(mvBoardIdGet()) & 0xFFFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardNameGet - Get Board name |
| * |
| * DESCRIPTION: |
| * This function returns a string describing the board model and revision. |
| * String is extracted from board I2C EEPROM. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * pNameBuff - Buffer to contain board name string. Minimum size 32 chars. |
| * |
| * RETURN: |
| * |
| * MV_ERROR if informantion can not be read. |
| *******************************************************************************/ |
| MV_STATUS mvBoardNameGet(char *pNameBuff, MV_U32 size) |
| { |
| mvOsSNPrintf(pNameBuff, size, "%s", board->boardName); |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsPortInSgmii - |
| * |
| * DESCRIPTION: |
| * This routine returns MV_TRUE for port number works in SGMII or MV_FALSE |
| * For all other options. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE - port in SGMII. |
| * MV_FALSE - other. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum) |
| { |
| MV_U32 ethComplex; |
| #if defined(CONFIG_MACH_AVANTA_LP_FPGA) |
| return ethPortNum == 2; |
| #endif |
| ethComplex = mvBoardEthComplexConfigGet(); |
| if ((ethPortNum == 0 && (ethComplex & MV_ETHCOMP_GE_MAC0_2_COMPHY_1 || |
| ethComplex & MV_ETHCOMP_GE_MAC0_2_COMPHY_2 || ethComplex & MV_ETHCOMP_GE_MAC0_2_COMPHY_3)) || |
| (ethPortNum == 1 && (ethComplex & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES || |
| (ethComplex & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP)))) |
| return MV_TRUE; |
| return MV_FALSE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsPortInGmii |
| * |
| * DESCRIPTION: |
| * This routine returns MV_TRUE for port number works in SGMII or MV_FALSE |
| * For all other options. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE - port in SGMII. |
| * MV_FALSE - other. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsPortInGmii(MV_U32 ethPortNum) |
| { |
| return MV_FALSE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardPhyAddrGet - Get the phy address |
| * |
| * DESCRIPTION: |
| * This routine returns the Phy address of a given ethernet port. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit describing Phy address, -1 if the port number is wrong. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum) |
| { |
| #if defined(CONFIG_MACH_AVANTA_LP_FPGA) |
| return 8; |
| #endif |
| |
| if (ethPortNum >= board->numBoardMacInfo) { |
| DB(mvOsPrintf("%s: Error: invalid ethPortNum (%d)\n", __func__, ethPortNum)); |
| return MV_ERROR; |
| } |
| |
| return board->pBoardMacInfo[ethPortNum].boardEthSmiAddr; |
| } |
| |
| /******************************************************************************* |
| * mvBoardPhyAddrSet - Set the phy address |
| * |
| * DESCRIPTION: |
| * This routine sets the Phy address of a given ethernet port. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * smiAddr - requested phy address |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardPhyAddrSet(MV_U32 ethPortNum, MV_U32 smiAddr) |
| { |
| if (ethPortNum >= board->numBoardMacInfo) { |
| DB(mvOsPrintf("%s: Error: invalid ethPortNum (%d)\n", __func__, ethPortNum)); |
| return; |
| } |
| |
| board->pBoardMacInfo[ethPortNum].boardEthSmiAddr = smiAddr; |
| } |
| /******************************************************************************* |
| * mvBoardQuadPhyAddr0Get - Get the PHY address |
| * |
| * DESCRIPTION: |
| * This routine returns the PHY address of a given Ethernet port. |
| * Required to initialize QUAD PHY through a specific PHY address |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit describing PHY address, -1 if the port number is wrong. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardQuadPhyAddr0Get(MV_U32 ethPortNum) |
| { |
| if (ethPortNum >= board->numBoardMacInfo) { |
| DB(mvOsPrintf("%s: Error: invalid ethPortNum (%d)\n", __func__, ethPortNum)); |
| return MV_ERROR; |
| } |
| |
| return board->pBoardMacInfo[ethPortNum].boardEthSmiAddr0; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSpecInitGet - |
| * |
| * DESCRIPTION: |
| * This routine returns the board specific initializtion information. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * A pointer to the array holding the board specific initializations. |
| * |
| *******************************************************************************/ |
| MV_BOARD_SPEC_INIT *mvBoardSpecInitGet(MV_VOID) |
| { |
| return board->pBoardSpecInit; |
| } |
| |
| /******************************************************************************* |
| * mvBoardMacSpeedGet - Get the Mac speed |
| * |
| * DESCRIPTION: |
| * This routine returns the Mac speed if pre define of a given ethernet port. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_BOARD_MAC_SPEED, -1 if the port number is wrong. |
| * |
| *******************************************************************************/ |
| MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum) |
| { |
| if (ethPortNum >= board->numBoardMacInfo) { |
| mvOsPrintf("%s: Error: wrong eth port (%d)\n", __func__, ethPortNum); |
| return BOARD_MAC_SPEED_100M; |
| } |
| |
| #if defined(CONFIG_MACH_AVANTA_LP_FPGA) |
| return (ethPortNum == 2) ? BOARD_MAC_SPEED_1000M : BOARD_MAC_SPEED_100M; |
| #endif |
| |
| return board->pBoardMacInfo[ethPortNum].boardMacSpeed; |
| } |
| |
| /******************************************************************************* |
| * mvBoardMacSpeedSet - Set the Mac speed |
| * |
| * DESCRIPTION: |
| * This routine Sets the Mac speed of a given ethernet port. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * macSpeed - Requested MAC speed |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardMacSpeedSet(MV_U32 ethPortNum, MV_BOARD_MAC_SPEED macSpeed) |
| { |
| if (ethPortNum >= board->numBoardMacInfo) |
| mvOsPrintf("%s: Error: wrong eth port (%d)\n", __func__, ethPortNum); |
| |
| board->pBoardMacInfo[ethPortNum].boardMacSpeed = macSpeed; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsPortLoopback - |
| * |
| * DESCRIPTION: |
| * This routine returns MV_TRUE for loopback port number or MV_FALSE |
| * For all other options. |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE - port is loopback. |
| * MV_FALSE - other. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsPortLoopback(MV_U32 ethPortNum) |
| { |
| return (ethPortNum == 2); |
| } |
| |
| /******************************************************************************* |
| * mvBoardTclkGet |
| * |
| * DESCRIPTION: |
| * This routine extract the controller core clock, aka, TCLK clock. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit clock cycles in Hertz. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardTclkGet(MV_VOID) |
| { |
| MV_U32 tclk; |
| #ifdef CONFIG_MACH_AVANTA_LP_FPGA |
| /* FPGA is limited to 25Mhz */ |
| return MV_FPGA_CORE_CLK; |
| #else |
| tclk = (MV_REG_READ(MPP_SAMPLE_AT_RESET(1))); |
| tclk = ((tclk & 0x400000) >> 22); |
| switch (tclk) { |
| case 0: |
| return MV_BOARD_TCLK_166MHZ; |
| case 1: |
| return MV_BOARD_TCLK_200MHZ; |
| default: |
| return MV_BOARD_TCLK_200MHZ; |
| } |
| #endif |
| } |
| |
| /******************************************************************************* |
| * mvBoardL2ClkGet |
| * |
| * DESCRIPTION: |
| * This routine extract the L2 Cache frequency/clock. |
| * Note: this function is called at the very early stage |
| * in Linux Kernel, hence, it has to read from SoC register, not |
| * from pre-built database. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit clock cycles in Hertz. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardL2ClkGet(MV_VOID) |
| { |
| #ifdef CONFIG_MACH_AVANTA_LP_FPGA |
| return MV_FPGA_L2_CLK; |
| #else |
| MV_U32 clkSelect; |
| MV_FREQ_MODE freqMode; |
| |
| clkSelect = MV_REG_READ(MPP_SAMPLE_AT_RESET(1)); |
| clkSelect = clkSelect & (0x1f << 17); |
| clkSelect >>= 17; |
| |
| mvCtrlFreqModeGet(clkSelect, &freqMode); |
| |
| return 1000000 * freqMode.l2Freq; |
| #endif |
| } |
| |
| /******************************************************************************* |
| * mvBoardSysClkGet - Get the board SysClk (CPU bus clock , i.e. DDR clock) |
| * |
| * DESCRIPTION: |
| * This routine extract the CPU bus clock. |
| * |
| * INPUT: |
| * countNum - Counter number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit clock cycles in Hertz. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSysClkGet(MV_VOID) |
| { |
| MV_FREQ_MODE freqMode; |
| #ifdef CONFIG_MACH_AVANTA_LP_FPGA |
| /* FPGA is limited to 25Mhz */ |
| return MV_FPGA_SYS_CLK; |
| #else |
| if (MV_ERROR != mvCtrlCpuDdrL2FreqGet(&freqMode)) |
| return (MV_U32)(1000000 * freqMode.ddrFreq); |
| else |
| return MV_ERROR; |
| #endif |
| } |
| |
| /******************************************************************************* |
| * mvBoardDebugLedNumGet - Get number of debug Leds |
| * |
| * DESCRIPTION: |
| * INPUT: |
| * boardId |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId) |
| { |
| return board->activeLedsNumber; |
| } |
| |
| /******************************************************************************* |
| * mvBoardDebugLed - Set the board debug Leds |
| * |
| * DESCRIPTION: turn on/off status leds. |
| * Note: assume MPP leds are part of group 0 only. |
| * |
| * INPUT: |
| * hexNum - Number to be displied in hex by Leds. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardDebugLed(MV_U32 hexNum) |
| { |
| /* empty */ |
| } |
| |
| /******************************************************************************* |
| * mvBoarGpioPinNumGet |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * gppClass - MV_BOARD_GPP_CLASS enum. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * GPIO pin number. The function return -1 for bad parameters. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS gppClass, MV_U32 index) |
| { |
| MV_U32 i, indexFound = 0; |
| |
| for (i = 0; i < board->numBoardGppInfo; i++) { |
| if (board->pBoardGppInfo[i].devClass == gppClass) { |
| if (indexFound == index) |
| return (MV_U32)board->pBoardGppInfo[i].gppPinNum; |
| else |
| indexFound++; |
| } |
| } |
| |
| return MV_ERROR; |
| } |
| |
| /******************************************************************************* |
| * mvBoardReset |
| * |
| * DESCRIPTION: |
| * Reset the board |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardReset(MV_VOID) |
| { |
| MV_32 resetPin; |
| |
| /* Get gpp reset pin if define */ |
| resetPin = mvBoardResetGpioPinGet(); |
| if (resetPin != MV_ERROR) |
| MV_REG_BIT_RESET(GPP_DATA_OUT_REG((int)(resetPin/32)), (1 << (resetPin % 32))); |
| else |
| { |
| /* No gpp reset pin was found, try to reset using system reset out */ |
| MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT0); |
| MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0); |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardResetGpioPinGet |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * GPIO pin number. The function return -1 for bad parameters. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardResetGpioPinGet(MV_VOID) |
| { |
| return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0); |
| } |
| |
| /******************************************************************************* |
| * mvBoardSDIOGpioPinGet |
| * |
| * DESCRIPTION: |
| * used for hotswap detection |
| * INPUT: |
| * type - Type of SDIO GPP to get. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * GPIO pin number. The function return -1 for bad parameters. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardSDIOGpioPinGet(MV_BOARD_GPP_CLASS type) |
| { |
| if (type != BOARD_GPP_SDIO_POWER && |
| type != BOARD_GPP_SDIO_DETECT && |
| type != BOARD_GPP_SDIO_WP) |
| return MV_FAIL; |
| |
| return mvBoarGpioPinNumGet(type, 0); |
| } |
| |
| /******************************************************************************* |
| * mvBoardUSBVbusGpioPinGet - return Vbus input GPP |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * int devNo. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * GPIO pin number. The function return -1 for bad parameters. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId) |
| { |
| return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId); |
| } |
| |
| /******************************************************************************* |
| * mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * int devNo. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * GPIO pin number. The function return -1 for bad parameters. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId) |
| { |
| return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId); |
| } |
| |
| /******************************************************************************* |
| * mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins |
| * |
| * DESCRIPTION: |
| * This function returns a 32-bit mask of GPP pins that connected to |
| * interrupt generating sources on board. |
| * For example if UART channel A is hardwired to GPP pin 8 and |
| * UART channel B is hardwired to GPP pin 4 the fuinction will return |
| * the value 0x000000110 |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * See description. The function return -1 if board is not identified. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardGpioIntMaskGet(MV_U32 gppGrp) |
| { |
| switch (gppGrp) { |
| case 0: |
| return board->intsGppMaskLow; |
| break; |
| case 1: |
| return board->intsGppMaskMid; |
| break; |
| case 2: |
| return board->intsGppMaskHigh; |
| break; |
| default: |
| return MV_ERROR; |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardSlicMppModeGet - Get board MPP Group type for SLIC unit (pre-defined) |
| * |
| * DESCRIPTION: |
| * if not using auto detection mudules according to board configuration settings, |
| * use pre-defined SLIC type from board information |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit value describing MPP control register value. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSlicUnitTypeGet(MV_VOID) |
| { |
| return board->pBoardModTypeValue->boardMppSlic; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSlicUnitTypeSet - Get board MPP Group type for SLIC unit (pre-defined) |
| * |
| * DESCRIPTION: |
| * if not using auto detection mudules according to board configuration settings, |
| * use pre-defined SLIC type from board information |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit value describing MPP control register value. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardSlicUnitTypeSet(MV_U32 slicType) |
| { |
| if (slicType >= MV_BOARD_SLIC_MAX_OPTION) { |
| mvOsPrintf("%s: Error: Unsupported SLIC/TDM configuration selected (%x)\n", |
| __func__, slicType); |
| slicType = MV_BOARD_SLIC_DISABLED; |
| } |
| |
| board->boardTdmInfoIndex = slicType; |
| board->pBoardModTypeValue->boardMppSlic = slicType; |
| } |
| /******************************************************************************* |
| * mvBoardMppGet - Get board dependent MPP register value |
| * |
| * DESCRIPTION: |
| * MPP settings are derived from board design. |
| * MPP group consist of 8 MPPs. An MPP group represents MPP |
| * control register. |
| * This function retrieves board dependend MPP register value. |
| * |
| * INPUT: |
| * mppGroupNum - MPP group number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit value describing MPP control register value. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardMppGet(MV_U32 mppGroupNum) |
| { |
| return board->pBoardMppConfigValue->mppGroup[mppGroupNum]; |
| } |
| |
| /******************************************************************************* |
| * mvBoardMppSet - Set board dependent MPP register value |
| * |
| * DESCRIPTION: |
| * This function updates board dependend MPP register value. |
| * |
| * INPUT: |
| * mppGroupNum - MPP group number. |
| * mppValue - new MPP value to be written |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * -None |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardMppSet(MV_U32 mppGroupNum, MV_U32 mppValue) |
| { |
| board->pBoardMppConfigValue->mppGroup[mppGroupNum] = mppValue; |
| } |
| |
| /******************************************************************************* |
| * mvBoardMppTypeSet - Set board dependent MPP Group Type value |
| * |
| * DESCRIPTION: |
| * This function updates board dependend MPP Group Type value. |
| * |
| * INPUT: |
| * mppGroupNum - MPP group number. |
| * groupType - new MPP Group type. derrive MPP Value using groupType |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * -None |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardMppTypeSet(MV_U32 mppGroupNum, MV_U32 groupType) |
| { |
| MV_U32 mppVal; |
| MV_U32 mppGroups[MV_BOARD_MAX_MPP_GROUPS][MV_BOARD_MPP_GROUPS_MAX_TYPES] = MPP_GROUP_TYPES; |
| |
| mppVal = mppGroups[mppGroupNum][groupType]; |
| mvBoardMppSet(mppGroupNum,mppVal); |
| |
| /* add Group types update here (if needed for later usage), |
| * and add mvBoardMppTypeGet to detect which type is in use currently */ |
| } |
| |
| /******************************************************************************* |
| * mvBoardInfoUpdate - Update Board information structures according to auto-detection. |
| * |
| * DESCRIPTION: |
| * Update board information according to detection using TWSI bus. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardInfoUpdate(MV_VOID) |
| { |
| MV_U32 smiAddress, slicDev, ethComplex; |
| MV_BOARD_MAC_SPEED macSpeed = BOARD_MAC_SPEED_AUTO; /*if Mac is not connected to switch, auto-negotiate speed*/ |
| |
| /* Update Ethernet complex according to board configuration */ |
| mvBoardEthComplexInfoUpdate(); |
| |
| /* Update SMI phy address for MAC0/1 */ |
| ethComplex = mvBoardEthComplexConfigGet(); |
| if (ethComplex & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) |
| smiAddress = 0x0; |
| else if (ethComplex & MV_ETHCOMP_GE_MAC0_2_RGMII0) |
| smiAddress = 0x5; |
| else { /* else if MAC0 is connected to SW port 6 */ |
| if (ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0) |
| smiAddress = 0x5; |
| else |
| smiAddress = -1; |
| if (ethComplex & MV_ETHCOMP_GE_MAC0_2_SW_P6) { |
| if (ethComplex & MV_ETHCOMP_P2P_MAC0_2_SW_SPEED_2G) /* else if MAC0 is connected to SW port 6 */ |
| macSpeed = BOARD_MAC_SPEED_2000M; |
| else |
| macSpeed = BOARD_MAC_SPEED_1000M; |
| } |
| } |
| |
| mvBoardPhyAddrSet(0, smiAddress); |
| mvBoardMacSpeedSet(0, macSpeed); |
| |
| macSpeed = BOARD_MAC_SPEED_AUTO; /*if Mac is not connected to switch, auto-negotiate speed*/ |
| if (ethComplex & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) |
| smiAddress = 0x3; |
| /* MAC1 to RGMII, or MAC1 to SGMII: both configs use the same SMI address (0x1) */ |
| else if (ethComplex & (MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES)) |
| smiAddress = 0x1; |
| else if (ethComplex & MV_ETHCOMP_GE_MAC1_2_RGMII0) |
| smiAddress = 0x5; |
| else { |
| smiAddress = -1; /* no SMI address if connected to switch */ |
| if (!(ethComplex & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP)) |
| macSpeed = BOARD_MAC_SPEED_1000M; |
| } |
| mvBoardPhyAddrSet(1, smiAddress); |
| mvBoardMacSpeedSet(1, macSpeed); |
| |
| /* Update SLIC device configuration */ |
| slicDev = mvBoardSysConfigGet(MV_CONFIG_SLIC_TDM_DEVICE); |
| if ((slicDev == SLIC_TDM2C_ID || slicDev == SLIC_TDMMC_ID) && (ethComplex & MV_ETHCOMP_GE_MAC1_2_RGMII1)) |
| mvOsPrintf("%s: Error: board configuration conflict between MAC1 to RGMII-1, " \ |
| "and External TDM - using RGMII-1 (disabled External TDM)\n\n", __func__); |
| |
| if (slicDev == SLIC_TDMMC_ID) { |
| if (ethComplex & MV_ETHCOMP_GE_MAC0_2_RGMII0) |
| mvOsPrintf("%s: Error: board configuration conflict between MAC0 to RGMII-0, " \ |
| "and External TDM - using External TDM (disabled RGMII-0)\n\n", __func__); |
| |
| if (ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0) |
| mvOsPrintf("%s: Error: board configuration conflict between SW P4 to RGMII-0, " \ |
| "and External TDM - using External TDM (disabled RGMII-0)\n\n", __func__); |
| |
| if (ethComplex & MV_ETHCOMP_GE_MAC1_2_RGMII0) |
| mvOsPrintf("%s: Error: board configuration conflict between MAC1 to RGMII-0, " \ |
| "and External TDM - using External TDM (disabled RGMII-0)\n\n", __func__); |
| } |
| mvBoardSlicUnitTypeSet(slicDev); |
| |
| /* Update MPP group types and values according to board configuration */ |
| mvBoardMppIdUpdate(); |
| |
| /* specific initializations required only for DB-6660 */ |
| if (mvBoardIdGet() == DB_6660_ID) { |
| /* Verify board config vs. SerDes actual setup (Common phy Selector) */ |
| mvBoardVerifySerdesCofig(); |
| |
| /* Enable Super-Speed mode on Avanta DB boards (900Mah output) */ |
| mvBoardUsbSsEnSet(MV_TRUE); |
| |
| /* If needed, enable SFP0 TX for SGMII, for DB-6660 */ |
| if (ethComplex & MV_ETHCOMP_GE_MAC0_2_COMPHY_2) |
| mvBoardSgmiiSfp0TxSet(MV_TRUE); |
| /* If needed, enable SFP1 TX for SGMII, for DB-6660 */ |
| if (ethComplex & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP) |
| mvBoardSgmiiSfp1TxSet(MV_TRUE); |
| /* Check conflicts between device bus module and NAND */ |
| mvBoardAudioModuleConfigCheck(); |
| |
| /* Check DDR buswidth configuration */ |
| mvBoardDDRBusWidthCheck(); |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardVerifySerdesCofig - Verify board config vs. SerDes actual setup (Common phy Selector) |
| * |
| * DESCRIPTION: |
| read board configuration for SerDes lanes 1-3 (SerDes 1 is pre-fixed to PCI-e) |
| and compare it to SerDes common phy Selector (Actual SerDes config in use) |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardVerifySerdesCofig(MV_VOID) |
| { |
| MV_U32 i, laneConfig, laneSelector; |
| MV_CONFIG_TYPE_ID configID = MV_CONFIG_LANE1; |
| |
| /* Lane 1 & Lane 3 use the same values for SerDes config and selector, |
| * Lane2 values are reversed: |
| * | Value | board Config | Selector | |
| * | 0x0 | SATA0 | SGMII-0 | |
| * | 0x1 | SGMII-0 | SATA0 | */ |
| for (i = 0; i < 4; i++) { |
| if (i == 0) /* lane0 is hard-coded to PCIe0 - not selected by board configuration */ |
| laneConfig = 1; |
| else /* lane 1-3 are selected at board configuration */ |
| laneConfig = mvBoardSysConfigGet(configID++); |
| /* using different Mask/Offset, since SATA1 option at lane1 was |
| ** not supported in Z1, Z2, Z3 */ |
| laneSelector = mvBoardLaneSelectorGet(i); |
| if ((i != 2 && laneSelector != laneConfig) || /* lanes 1,3 use the same value */ |
| (i == 2 && laneSelector == laneConfig)) { /* lane 2 use opposite values */ |
| mvOsPrintf("Error: board configuration conflicts with SerDes configuration\n"); |
| mvOsPrintf("SerDes#%d: Board configuration= %x SerDes Selector = %x\n" \ |
| , i, laneConfig, laneSelector); |
| } |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardMppIdUpdate - Update MPP ID's according to modules auto-detection. |
| * |
| * DESCRIPTION: |
| * Update MPP ID's according to on-board modules as detected using TWSI bus. |
| * Update board information for changed mpp values |
| Must run AFTER mvBoardEthComplexInfoUpdate |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardMppIdUpdate(MV_VOID) |
| { |
| MV_BOARD_BOOT_SRC bootDev; |
| MV_SLIC_UNIT_TYPE slicDev; |
| MV_U32 ethComplexOptions = mvBoardEthComplexConfigGet(); |
| MV_BOOL singleCpu, tdmLqUnit; |
| MV_U32 tdmmcType; |
| |
| /* MPP Groups initialization : */ |
| /* Set Group 0-1 - Boot device (else if booting from SPI1: Set Groups 3-4) */ |
| bootDev = mvBoardBootDeviceGroupSet(); |
| |
| /* Group 2 - SLIC Tdm unit */ |
| slicDev = mvBoardSlicUnitTypeGet(); |
| mvBoardMppTypeSet(2, slicDev); |
| |
| /* Groups 3-4 - (only if not Booting from SPI1)*/ |
| if (bootDev != MSAR_0_BOOT_SPI1_FLASH) { |
| tdmLqUnit = (slicDev == SLIC_LANTIQ_ID); |
| if (ethComplexOptions & (MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES | |
| MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP)) { |
| mvBoardMppTypeSet(3, GE1_RGMII1_UNIT); |
| mvBoardMppTypeSet(4, (tdmLqUnit ? GE1_RGMII1_CPU_SMI_CTRL_TDM_LQ_UNIT : \ |
| GE1_RGMII1_CPU_SMI_CTRL_REF_CLK_OUT)); |
| } else { /* if RGMII-1 isn't used, set SPI1 MPP's */ |
| mvBoardMppTypeSet(3, SDIO_SPI1_UNIT); |
| mvBoardMppTypeSet(4, (tdmLqUnit ? SPI1_CPU_SMI_CTRL_TDM_LQ_UNIT : \ |
| SPI1_CPU_SMI_CTRL_REF_CLK_OUT)); |
| } |
| } |
| |
| /* Groups 5-6-7 Set GE0, GE1_RGMII0, or Switch port 4 */ |
| singleCpu = (mvCtrlGetCpuNum() == 0); /* if using Dual CPU ,set UART1 */ |
| /* If TDMMC is enabled, set proper MPP for chip selection and interrupt */ |
| tdmmcType = (mvBoardSlicUnitTypeGet() == SLIC_TDMMC_ID); |
| if (ethComplexOptions & MV_ETHCOMP_GE_MAC0_2_RGMII0) { |
| mvBoardMppTypeSet(5, GE0_UNIT_PON_TX_FAULT); |
| mvBoardMppTypeSet(6, tdmmcType ? GE0_UNIT_TDMMC : GE0_UNIT); |
| mvBoardMppTypeSet(7, (singleCpu ? GE0_UNIT_LED_MATRIX : GE0_UNIT_UA1_PTP)); |
| } else if (ethComplexOptions & MV_ETHCOMP_SW_P4_2_RGMII0) { |
| mvBoardMppTypeSet(5, SWITCH_P4_PON_TX_FAULT); |
| mvBoardMppTypeSet(6, tdmmcType ? SWITCH_P4_TDMMC : SWITCH_P4); |
| mvBoardMppTypeSet(7, (singleCpu ? SWITCH_P4_LED_MATRIX : SWITCH_P4_UA1_PTP)); |
| } else if (ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_RGMII0) { |
| mvBoardMppTypeSet(5, GE1_RGMII0_UNIT_PON_TX_FAULT); |
| mvBoardMppTypeSet(6, tdmmcType ? GE1_RGMII0_UNIT_TDMMC : GE1_RGMII0_UNIT); |
| mvBoardMppTypeSet(7, (singleCpu ? GE1_RGMII0_UNIT_LED_MATRIX : GE1_RGMII0_UNIT_UA1_PTP)); |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardEthComplexInfoUpdate |
| * |
| * DESCRIPTION: |
| * Verify and Update etherntComplex configuration, |
| * according to modules detection (S@R & board configuration) |
| * |
| * INPUT: |
| * updateSetup: |
| * MV_TRUE : update configuration in board structure (occurs once on startup) |
| * MV_FALSE : only verify if configuration is valid, when altered config at runtime |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_OK - on success, |
| * MV_ERROR - On failure. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardEthComplexInfoUpdate() |
| { |
| MV_U32 ethComplexOptions = 0x0; |
| |
| ethComplexOptions = mvBoardEthComplexMacConfigCheck(); |
| if (ethComplexOptions == MV_ERROR) |
| return MV_ERROR; |
| |
| /* read if using 2G speed for MAC0 to Switch*/ |
| if (mvBoardSysConfigGet(MV_CONFIG_MAC0_SW_SPEED) == 0x0) |
| ethComplexOptions |= MV_ETHCOMP_P2P_MAC0_2_SW_SPEED_2G; |
| |
| if (mvBoardSysConfigGet(MV_CONFIG_SGMII0_CAPACITY) == 0x1) |
| ethComplexOptions |= MV_ETHCOMP_GE_MAC0_2_COMPHY_SPEED_2G; |
| |
| /* if MAC1 is NOT connected to PON SerDes using SGMII or SFP --> connect PON MAC to to PON SerDes */ |
| if ((ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES) == MV_FALSE && |
| (ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP) == MV_FALSE) |
| ethComplexOptions |= MV_ETHCOMP_P2P_MAC_2_PON_ETH_SERDES; |
| |
| /* Switch Ports*/ |
| if ((ethComplexOptions & MV_ETHCOMP_GE_MAC0_2_SW_P6) || |
| (ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_SW_P4)) { |
| /* if MAC0 is NOT connected to GE_PHY_P0 --> connect Switch port 0 to QUAD_PHY_P0 */ |
| if ((ethComplexOptions & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) == MV_FALSE) |
| ethComplexOptions |= MV_ETHCOMP_SW_P0_2_GE_PHY_P0; |
| |
| /* if MAC1 is BOT connected to GE_PHY_P3 --> connect Switch port 3 to QUAD_PHY_P3 */ |
| if ((ethComplexOptions & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) == MV_FALSE) |
| ethComplexOptions |= MV_ETHCOMP_SW_P3_2_GE_PHY_P3; |
| |
| /* connect Switch ports 2/3 to QUAD_PHY_P2/3 */ |
| ethComplexOptions |= (MV_ETHCOMP_SW_P1_2_GE_PHY_P1 | MV_ETHCOMP_SW_P2_2_GE_PHY_P2); |
| } |
| if (mvBoardSysConfigGet(MV_CONFIG_SW_P4) == 0x1) { |
| ethComplexOptions |= MV_ETHCOMP_SW_P4_2_RGMII0; |
| ethComplexOptions |= MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY; |
| } |
| |
| mvBoardEthComplexConfigSet(ethComplexOptions); |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardEthComplexMacConfigCheck |
| * |
| * DESCRIPTION: |
| * Verify and return etherntComplex MAC0 configuration, |
| * according to modules detection (S@R & board configuration) |
| * |
| * INPUT: |
| * None. |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_ETH_COMPLEX_TOPOLOGY which defines MAC0 and MAC1 board configuration |
| * |
| *******************************************************************************/ |
| MV_ETH_COMPLEX_TOPOLOGY mvBoardEthComplexMacConfigCheck() |
| { |
| MV_ETH_COMPLEX_TOPOLOGY mac0Config, mac1Config; |
| |
| /* Ethernet Complex initialization : */ |
| /* MAC0/1 */ |
| mac0Config = mvBoardMac0ConfigGet(); |
| mac1Config = mvBoardMac1ConfigGet(); |
| |
| if (mac0Config == MV_ERROR || mac1Config == MV_ERROR) { |
| mvOsPrintf("Warning: Will use default configuration.\n\n"); |
| return MV_ERROR; |
| } |
| |
| return mac0Config | mac1Config; |
| } |
| /******************************************************************************* |
| * mvBoardBootDeviceGroupSet - test board Boot configuration and set MPP groups |
| * |
| * DESCRIPTION: |
| * read board BOOT configuration and set MPP groups accordingly |
| * - Sets groups 0-1 for NAND or SPI0 Boot |
| * Or groups 3-4 for SPI1 Boot |
| * - return Selected boot device |
| * |
| * INPUT: |
| * |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * the selected MV_BOARD_BOOT_SRC |
| * |
| *******************************************************************************/ |
| MV_BOARD_BOOT_SRC mvBoardBootDeviceGroupSet() |
| { |
| MV_U32 groupType; |
| MV_BOARD_BOOT_SRC bootSrc = mvBoardBootDeviceGet(); |
| |
| switch (bootSrc) { |
| case MSAR_0_BOOT_NAND_NEW: |
| mvBoardMppTypeSet(0, NAND_BOOT_V2); |
| mvBoardMppTypeSet(1, NAND_BOOT_V2); |
| break; |
| case MSAR_0_BOOT_SPI_FLASH: |
| /* read SPDIF_AUDIO/I2S_AUDIO board configuration for DB-6660 board */ |
| if ((mvBoardIdGet() == DB_6660_ID) && |
| ((mvBoardSysConfigGet(MV_CONFIG_DEVICE_BUS_MODULE) == 0x2) || /* 0x2=I2S_AUDIO */ |
| (mvBoardSysConfigGet(MV_CONFIG_DEVICE_BUS_MODULE) == 0x3))) /* 0x3=SPDIF_AUDIO */ |
| groupType = SPI0_BOOT_SPDIF_I2S_AUDIO; |
| else |
| groupType = SPI0_BOOT; |
| |
| mvBoardMppTypeSet(0, groupType); |
| mvBoardMppTypeSet(1, groupType); |
| break; |
| case MSAR_0_BOOT_SPI1_FLASH: /* MSAR_0_SPI1 - update Groups 3-4 */ |
| mvBoardMppTypeSet(3, SDIO_SPI1_UNIT); |
| if ( mvBoardSlicUnitTypeGet() == SLIC_LANTIQ_ID) |
| mvBoardMppTypeSet(4, SPI1_CPU_SMI_CTRL_TDM_LQ_UNIT); |
| else /*REF_CLK_OUT*/ |
| mvBoardMppTypeSet(4, SPI1_CPU_SMI_CTRL_REF_CLK_OUT); |
| mvBoardMppTypeSet(0, SPI0_BOOT_SPDIF_I2S_AUDIO); |
| mvBoardMppTypeSet(1, SPI0_BOOT_SPDIF_I2S_AUDIO); |
| break; |
| default: |
| return MV_ERROR; |
| } |
| return bootSrc; |
| } |
| |
| /******************************************************************************* |
| * mvBoardBootDeviceGet - Get the Selected S@R boot device |
| * |
| * DESCRIPTION: |
| * read board BOOT configuration from S@R and return Boot device accordingly |
| * |
| * INPUT: |
| * |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * the selected MV_BOARD_BOOT_SRC |
| * |
| *******************************************************************************/ |
| MV_BOARD_BOOT_SRC mvBoardBootDeviceGet() |
| { |
| MV_U32 satrBootDeviceValue; |
| MV_SATR_BOOT_TABLE satrTable[] = MV_SATR_TABLE_VAL; |
| MV_SATR_BOOT_TABLE satrBootEntry; |
| MV_BOARD_BOOT_SRC defaultBootSrc; |
| |
| /* prepare default boot source, in case of: |
| * 1. S@R read ERROR |
| * 2. Boot from UART is selected as boot source at S@R |
| * Pre-compiled image type (SPI/NAND) is selected as boot source |
| */ |
| #if defined(MV_SPI_BOOT) |
| defaultBootSrc = MSAR_0_BOOT_SPI_FLASH; |
| DB(mvOsPrintf("default boot source is SPI-0\n")); |
| #elif defined(MV_NAND_BOOT) |
| defaultBootSrc = MSAR_0_BOOT_NAND_NEW; |
| DB(mvOsPrintf("default boot source is NAND\n")); |
| #endif |
| |
| if (mvCtrlSatRRead(MV_SATR_BOOT_DEVICE, &satrBootDeviceValue) != MV_OK) { |
| mvOsPrintf("%s: Error: failed to read boot source\n", __func__); |
| mvOsPrintf("Using pre-compiled image type as boot source\n"); |
| return defaultBootSrc; |
| } |
| |
| /* Get boot source entry from Satr boot table */ |
| satrBootEntry = satrTable[satrBootDeviceValue]; |
| |
| /* If booting from UART, return pre-compiled boot source*/ |
| if (satrBootEntry.bootSrc == MSAR_0_BOOT_UART) { |
| mvOsPrintf("\t** Booting from UART (restore DIP-switch to"); |
| mvOsPrintf(" requested boot source before reset!) **\n"); |
| return defaultBootSrc; |
| } |
| |
| /* If not booting from SPI, return boot source*/ |
| if (satrBootEntry.bootSrc != MSAR_0_BOOT_SPI_FLASH) |
| return satrBootEntry.bootSrc; |
| |
| /* if booting from SPI ,verify which CS (0/1) */ |
| if (mvBoardBootAttrGet(satrBootDeviceValue, 1) == MSAR_0_SPI0) |
| return MSAR_0_BOOT_SPI_FLASH; |
| else |
| return MSAR_0_BOOT_SPI1_FLASH; |
| } |
| |
| /******************************************************************************* |
| * mvBoardBootAttrGet - Get the selected S@R Boot device attributes[1/2/3] |
| * |
| * DESCRIPTION: |
| * read board BOOT configuration and return attributes accordingly |
| * |
| * INPUT: satrBootDevice - BOOT_DEVICE value from S@R.* |
| * attrNum - attribute number [1/2/3] |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * the selected attribute value |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardBootAttrGet(MV_U32 satrBootDeviceValue, MV_U8 attrNum) |
| { |
| MV_SATR_BOOT_TABLE satrTable[] = MV_SATR_TABLE_VAL; |
| MV_SATR_BOOT_TABLE satrBootEntry = satrTable[satrBootDeviceValue]; |
| |
| switch (attrNum) { |
| case 1: |
| return satrBootEntry.attr1; |
| break; |
| case 2: |
| return satrBootEntry.attr2; |
| break; |
| case 3: |
| return satrBootEntry.attr3; |
| break; |
| default: |
| return MV_ERROR; |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardMac0ConfigGet - test board configuration and return the correct MAC0 config |
| * |
| * DESCRIPTION: |
| * test board configuration regarding MAC0 |
| * if configured to SGMII-0 , will check which lane is configured to SGMII, |
| * and return its MV_ETH_COMPLEX_TOPOLOGY define |
| * else return error |
| * |
| * INPUT: None. |
| * |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * if configured correct, the MV_ETH_COMPLEX_TOPOLOGY define, else MV_ERROR |
| * |
| *******************************************************************************/ |
| MV_ETH_COMPLEX_TOPOLOGY mvBoardMac0ConfigGet() |
| { |
| MV_ETH_COMPLEX_TOPOLOGY sgmiiLane; |
| MV_STATUS isSgmiiLaneEnabled = MV_FALSE; |
| MV_U32 mac0Config = mvBoardSysConfigGet(MV_CONFIG_MAC0); |
| |
| if (mac0Config == MV_ERROR) { |
| mvOsPrintf("%s: Error: failed reading MAC0 board configuration\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* Serdes lane board configuration is only for DB-6660 */ |
| if (mvBoardIdGet() == DB_6660_ID) |
| isSgmiiLaneEnabled = mvBoardLaneSGMIIGet(&sgmiiLane); |
| else if (mac0Config == MAC0_2_SGMII) { |
| mvOsPrintf("%s: Warning: only DB-6660 board supports MAC0 to SGMII", __func__); |
| return MV_ERROR; |
| } |
| |
| /* if a Serdes lane is configured to SGMII, and conflicts MAC0 settings, |
| * then the selected Serdes lane will be used (overriding MAC0 settings) */ |
| |
| if (isSgmiiLaneEnabled == MV_TRUE && mac0Config != MAC0_2_SGMII) { |
| mvOsPrintf("Warning: a Serdes lane is set to SGMII, but MAC0 is not set to"); |
| mvOsPrintf(" SGMII - Overriding MAC0 setting to be SGMII.\n\n"); |
| |
| return sgmiiLane; |
| } |
| |
| switch (mac0Config) { |
| case MAC0_2_SW_P6: |
| return MV_ETHCOMP_GE_MAC0_2_SW_P6; |
| case MAC0_2_GE_PHY_P0: |
| return MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0; |
| case MAC0_2_RGMII: |
| return MV_ETHCOMP_GE_MAC0_2_RGMII0; |
| case MAC0_2_SGMII: |
| if (isSgmiiLaneEnabled == MV_TRUE) |
| return sgmiiLane; |
| } |
| |
| /* if MAC0 set to SGMII, but no Serdes lane selected, --> ERROR (use defaults) */ |
| mvOsPrintf("Warning: MAC0 is set to SGMII but no Serdes lane is set to SGMII\n\n"); |
| return MV_ERROR; |
| |
| } |
| |
| /******************************************************************************* |
| * mvBoardMac1ConfigGet - test board configuration and return the correct MAC1 config |
| * |
| * DESCRIPTION: |
| * test board configuration regarding PON_SERDES |
| * if MAC0 is configured to PON SerDes Connection return its MV_ETH_COMPLEX_TOPOLOGY define |
| * else test MV_CONFIG_MAC1 configuration |
| * |
| * INPUT: None. |
| * |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * if configured correct, the MV_ETH_COMPLEX_TOPOLOGY define, else MV_ERROR |
| * |
| *******************************************************************************/ |
| MV_ETH_COMPLEX_TOPOLOGY mvBoardMac1ConfigGet() |
| { |
| if (mvBoardSysConfigGet(MV_CONFIG_PON_SERDES) == 0x1) |
| return MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES; |
| if (mvBoardSysConfigGet(MV_CONFIG_PON_SERDES) == 0x2) |
| return MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP; |
| /* else Scan MAC1 config to decide its connection */ |
| switch (mvBoardSysConfigGet(MV_CONFIG_MAC1)) { |
| case 0x0: |
| return MV_ETHCOMP_GE_MAC1_2_RGMII1; |
| break; |
| case 0x1: |
| return MV_ETHCOMP_GE_MAC1_2_SW_P4; |
| break; |
| case 0x2: |
| return MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3; |
| break; |
| case 0x3: |
| return MV_ETHCOMP_GE_MAC1_2_RGMII0; |
| break; |
| default: |
| mvOsPrintf("%s: Error: Configuration conflict for MAC1 connection.\n", __func__); |
| return MV_ERROR; |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsLaneSGMII - check if a board lane is configured to SGMII-0 |
| * |
| * DESCRIPTION: |
| * test board configuration regarding lanes-1/2/3 |
| * if one of them is configured to SGMII-0 , will return its MV_ETH_COMPLEX_TOPOLOGY define |
| * else return error |
| * |
| * INPUT: None. |
| * |
| * OUTPUT: None. |
| * |
| * RETURN: |
| * MV_TRUE if SGMII settings are valid and Enabled only for a single lane |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardLaneSGMIIGet(MV_ETH_COMPLEX_TOPOLOGY *sgmiiConfig) |
| { |
| MV_BOOL isSgmiiLaneEnabled = MV_FALSE; |
| MV_U8 i; |
| MV_ETH_COMPLEX_TOPOLOGY laneConfig = 0; |
| MV_ETH_COMPLEX_TOPOLOGY laneOptions[] = {MV_ETHCOMP_GE_MAC0_2_COMPHY_1, \ |
| MV_ETHCOMP_GE_MAC0_2_COMPHY_2, \ |
| MV_ETHCOMP_GE_MAC0_2_COMPHY_3 }; |
| MV_CONFIG_TYPE_ID configID[] = {MV_CONFIG_LANE1, MV_CONFIG_LANE2, MV_CONFIG_LANE3}; |
| |
| |
| if (sgmiiConfig == NULL) { |
| mvOsPrintf("%s: Error: NULL pointer parameter\n", __func__); |
| return MV_FALSE; |
| } |
| |
| for (i = 0; i < 3; i++) { |
| /* if not set to SGMII, check next lane*/ |
| if (mvBoardSysConfigGet(configID[i]) != 0x1) |
| continue; |
| |
| /* if no Lane already set to SGMII */ |
| if (isSgmiiLaneEnabled == MV_FALSE) { |
| laneConfig = laneOptions[i]; |
| isSgmiiLaneEnabled = MV_TRUE; |
| } else { /* SGMII was already set in the previous lanes */ |
| mvOsPrintf("%s: Error: Only one Serdes lanes can be configured to SGMII\n\n", __func__); |
| return MV_FALSE; |
| } |
| } |
| |
| if (isSgmiiLaneEnabled != MV_TRUE) |
| return MV_FALSE; |
| |
| *sgmiiConfig = laneConfig; |
| |
| return MV_TRUE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsInternalSwitchConnected |
| * |
| * DESCRIPTION: |
| * This routine returns port's connection status |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 1 - if ethPortNum is connected to switch, 0 otherwise |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardIsInternalSwitchConnected(void) |
| { |
| MV_U32 ethComplex = mvBoardEthComplexConfigGet(); |
| |
| if ((ethComplex & MV_ETHCOMP_GE_MAC0_2_SW_P6) || |
| (ethComplex & MV_ETHCOMP_GE_MAC1_2_SW_P4)) |
| return MV_TRUE; |
| else |
| return MV_FALSE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSwitchConnectedPortGet - |
| * |
| * DESCRIPTION: |
| * This routine returns the switch port connected to the ethPort |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * switch port connected to the ethPort |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardSwitchConnectedPortGet(MV_U32 ethPort) |
| { |
| MV_U32 ethComplex = mvBoardEthComplexConfigGet(); |
| |
| if (ethPort >= board->numBoardMacInfo) { |
| mvOsPrintf("%s: Error: Illegal port number(%u)\n", __func__, ethPort); |
| return MV_FALSE; |
| } |
| |
| if ((ethPort == 0) && (ethComplex & MV_ETHCOMP_GE_MAC0_2_SW_P6)) |
| return 6; |
| else if ((ethPort == 1) && (ethComplex & MV_ETHCOMP_GE_MAC1_2_SW_P4)) |
| return 4; |
| else |
| return -1; |
| |
| } |
| |
| /******************************************************************************* |
| * mvBoardSwitchPortsMaskGet - |
| * |
| * DESCRIPTION: |
| * This routine returns a mask describing all the connected switch ports |
| * |
| * INPUT: |
| * switchIdx - index of the switch. Only 0 is supported. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSwitchPortsMaskGet(MV_U32 switchIdx) |
| { |
| MV_U32 mask = 0, c = mvBoardEthComplexConfigGet(); |
| |
| if (c & MV_ETHCOMP_SW_P0_2_GE_PHY_P0) |
| mask |= BIT0; |
| if (c & MV_ETHCOMP_SW_P1_2_GE_PHY_P1) |
| mask |= BIT1; |
| if (c & MV_ETHCOMP_SW_P2_2_GE_PHY_P2) |
| mask |= BIT2; |
| if (c & MV_ETHCOMP_SW_P3_2_GE_PHY_P3) |
| mask |= BIT3; |
| if ((c & MV_ETHCOMP_SW_P4_2_RGMII0) || (c & MV_ETHCOMP_GE_MAC1_2_SW_P4)) |
| mask |= BIT4; |
| if (c & MV_ETHCOMP_GE_MAC0_2_SW_P6) |
| mask |= BIT6; |
| |
| return mask; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSwitchPortForceLinkGet |
| * |
| * DESCRIPTION: |
| * Return the switch ports force link bitmask. |
| * |
| * INPUT: |
| * switchIdx - index of the switch. Only 0 is supported. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * the ports bitmask, -1 if the switch is not connected. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSwitchPortForceLinkGet(MV_U32 switchIdx) |
| { |
| MV_U32 mask = 0, c = mvBoardEthComplexConfigGet(); |
| |
| if (c & MV_ETHCOMP_GE_MAC1_2_SW_P4) |
| mask |= BIT4; |
| if (c & MV_ETHCOMP_GE_MAC0_2_SW_P6) |
| mask |= BIT6; |
| |
| /* If switch port 4 is connected to RGMII-0, the PHY SMI is controlled by CPU MAC, |
| * To avoid address conflict between internal PHY (0x1), SMI is not handled by switch. |
| * Auto-negotiation can not be applied with this configuration - so we use force link */ |
| if (c & MV_ETHCOMP_SW_P4_2_RGMII0) |
| mask |= BIT4; |
| return mask; |
| |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsSwitchConnected |
| * |
| * DESCRIPTION: |
| * This routine returns port's connection status, this route provide a unified inerface |
| * for other modules to call without care of the switch conntection mode - external or internal |
| * if the switch is connected |
| * |
| * INPUT: |
| * ethPortNum - Ethernet port number. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 1 - if ethPortNum is connected to switch, 0 otherwise |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardIsSwitchConnected(void) |
| { |
| return mvBoardIsInternalSwitchConnected(); |
| |
| } |
| |
| /* this temporary functions to compile switch code. |
| mvEthE6171SwitchBasicInit is not used by alp code */ |
| MV_BOOL mvBoardSwitchCpuPortIsRgmii(MV_U32 switchIdx) |
| { |
| return MV_FALSE; |
| } |
| MV_32 mvBoardSwitchPhyAddrGet(MV_U32 switchIdx) |
| { |
| return -1; |
| } |
| |
| /******************************************************************************* |
| * mvBoardFreqModesNumGet |
| * |
| * DESCRIPTION: Return the number of supported frequency modes for this SoC |
| * |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Number of supported frequency modes |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardFreqModesNumGet() |
| { |
| MV_U32 freqNum; |
| |
| switch (mvCtrlModelGet()) { |
| case MV_6610_DEV_ID: |
| case MV_6610F_DEV_ID: |
| freqNum = FREQ_MODES_NUM_6610; |
| break; |
| case MV_6650_DEV_ID: |
| case MV_6650F_DEV_ID: |
| case MV_6658_DEV_ID: |
| freqNum = FREQ_MODES_NUM_6650; |
| break; |
| case MV_6660_DEV_ID: |
| case MV_6665_DEV_ID: |
| if (mvCtrlRevGet() <= MV_88F66X0_Z3_ID) |
| freqNum = FREQ_MODES_NUM_6660_Z_REV; |
| else |
| freqNum = FREQ_MODES_NUM_6660; |
| break; |
| default: |
| mvOsPrintf("%s: Error: failed to read ctrlModel (SoC ID)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return freqNum; |
| } |
| |
| |
| /******************************************************************************* |
| * mvBoardConfigWrite - write MPP's config and Board general environment configuration |
| * |
| * DESCRIPTION: |
| * This function writes the environment information that was initialized |
| * by mvBoardConfigInit, such as MPP settings, Mux configuration, |
| * and Board specific initializations. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardConfigWrite(void) |
| { |
| MV_U32 mppGroup, i, reg; |
| MV_BOARD_SPEC_INIT *boardSpec; |
| |
| for (mppGroup = 0; mppGroup < MV_MPP_MAX_GROUP; mppGroup++) { |
| MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mvBoardMppGet(mppGroup)); |
| } |
| |
| boardSpec = mvBoardSpecInitGet(); |
| if (boardSpec != NULL) { |
| i = 0; |
| while (boardSpec[i].reg != TBL_TERM) { |
| reg = MV_REG_READ(boardSpec[i].reg); |
| reg &= ~boardSpec[i].mask; |
| reg |= (boardSpec[i].val & boardSpec[i].mask); |
| MV_REG_WRITE(boardSpec[i].reg, reg); |
| i++; |
| } |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardTdmSpiModeGet - return SLIC/DAA connection |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardTdmSpiModeGet(MV_VOID) |
| { |
| return 0; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTdmDevicesCountGet |
| * |
| * DESCRIPTION: |
| * Return the number of TDM devices on board. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Number of devices. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardTdmDevicesCountGet(void) |
| { |
| MV_16 index = board->boardTdmInfoIndex; |
| |
| if (index == -1) |
| return 0; |
| |
| return board->numBoardTdmInfo[index]; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTdmSpiCsGet |
| * |
| * DESCRIPTION: |
| * Return the SPI Chip-select number for a given device. |
| * |
| * INPUT: |
| * devId - The Slic device ID to get the SPI CS for. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * The SPI CS if found, -1 otherwise. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardTdmSpiCsGet(MV_U8 devId) |
| { |
| MV_16 index; |
| |
| index = board->boardTdmInfoIndex; |
| if (index == -1) |
| return 0; |
| |
| if (devId >= board->numBoardTdmInfo[index]) |
| return -1; |
| |
| return board->pBoardTdmInt2CsInfo[index][devId].spiCs; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTdmSpiIdGet |
| * |
| * DESCRIPTION: |
| * Return SPI port ID per board. |
| * |
| * INPUT: |
| * None |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * SPI port ID. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardTdmSpiIdGet(MV_VOID) |
| { |
| MV_16 index; |
| |
| index = board->boardTdmInfoIndex; |
| if (index == -1) |
| return 0; |
| |
| return board->pBoardTdmSpiInfo[index].spiId; |
| } |
| |
| /******************************************************************************* |
| * mvBoardAudioModuleConfigCheck |
| * |
| * DESCRIPTION: |
| * Check if used audio modules when booting from NAND |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardAudioModuleConfigCheck(MV_VOID) |
| { |
| if ((mvBoardBootDeviceGet() == MSAR_0_BOOT_NAND_NEW) && |
| ((mvBoardSysConfigGet(MV_CONFIG_DEVICE_BUS_MODULE) == 0x2) || /* 0x2=I2S_AUDIO */ |
| (mvBoardSysConfigGet(MV_CONFIG_DEVICE_BUS_MODULE) == 0x3))) /* 0x3=SPDIF_AUDIO */ |
| mvOsPrintf("Error: Audio modules not supported when booting from NAND\n"); |
| } |
| |
| /******************************************************************************* |
| * mvBoardDDRBusWidthCheck |
| * |
| * DESCRIPTION: |
| * Check if DDR buswidth is different from the board configuration |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardDDRBusWidthCheck(MV_VOID) |
| { |
| MV_U32 configVar, ddrVar; |
| |
| /* DDR buswidth field control relevant for MV88F6660 SoC */ |
| if (mvBoardIdGet() != DB_6660_ID) |
| return; |
| |
| configVar = (mvBoardSysConfigGet(MV_CONFIG_DDR_BUSWIDTH) == 0x0) ? 32 : 16; |
| ddrVar = mvCtrlDDRBudWidth(); |
| |
| if (configVar != ddrVar) |
| mvOsPrintf("Error: Mismatch between DDR buswidth - %d, and board configuration DDR buswidth - %d\n",\ |
| ddrVar, configVar); |
| } |
| |
| |
| /******************************************************************************* |
| * mvBoardConfigurationPrint |
| * |
| * DESCRIPTION: |
| * Print on-board detected modules. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardConfigurationPrint(MV_VOID) |
| { |
| char *lane1[] = {"PCIe1", "SGMII-0", "SATA-1", "Unconnected" }; |
| char *tdmSlic[] = {"None", "SSI", "ISI", "ZSI", "TDM2C", "TDMMC"}; |
| MV_U32 slicDevice, ethConfig = mvBoardEthComplexConfigGet(); |
| MV_U16 modelID = mvCtrlModelGet(); |
| |
| mvOsOutput("\nBoard configuration:\n"); |
| |
| mvOsOutput("\tEEPROM/Dip Switch: %s\n", mvBoardIsEepromEnabled() ? "EEPROM" : "DIP-Switch"); |
| |
| /* Mac configuration */ |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_COMPHY_1) |
| mvOsOutput("\tSGMII0 on MAC0 [Lane1]\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_COMPHY_2) |
| mvOsOutput("\tSGMII0 on MAC0 [Lane2]\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_COMPHY_3) |
| mvOsOutput("\tSGMII0 on MAC0 [Lane3]\n"); |
| |
| |
| /* Switch configuration */ |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_SW_P6) |
| mvOsOutput("\tEthernet Switch port 6 on MAC0 [CPU Port], %s Speed\n" |
| , (ethConfig & MV_ETHCOMP_P2P_MAC0_2_SW_SPEED_2G) ? "2G" : "1G"); |
| else if ((ethConfig & MV_ETHCOMP_GE_MAC1_2_SW_P4) && |
| !(ethConfig & MV_ETHCOMP_GE_MAC0_2_SW_P6)) |
| mvOsOutput("\tEthernet Switch port 4 on MAC1 [CPU Port], 1G Speed\n"); |
| if ((ethConfig & MV_ETHCOMP_GE_MAC0_2_SW_P6) && |
| (ethConfig & MV_ETHCOMP_GE_MAC1_2_SW_P4)) { |
| mvOsOutput("\tEthernet Switch port 4 on MAC1, 1G Speed\n"); |
| } |
| |
| /* RGMII */ |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_RGMII0) |
| mvOsOutput("\tRGMII0 Module on MAC0\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC1_2_RGMII1) |
| mvOsOutput("\tRGMII1 Module on MAC1\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC1_2_RGMII0) |
| mvOsOutput("\tRGMII0 Module on MAC1\n"); |
| if (ethConfig & MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY) |
| mvOsOutput("\tExternal PHY-RGMII0 Module on Switch port #4, 1G speed\n"); |
| else if (ethConfig & MV_ETHCOMP_SW_P4_2_RGMII0) |
| mvOsOutput("\tRGMII0 Module on Switch port #4, 1G speed\n"); |
| |
| /* Internal GE Quad Phy */ |
| if (ethConfig & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) |
| mvOsOutput("\tGE-PHY-0 on MAC0\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) |
| mvOsOutput("\tGE-PHY-3 on MAC1\n"); |
| if ((ethConfig & MV_ETHCOMP_SW_P0_2_GE_PHY_P0) && (ethConfig & MV_ETHCOMP_SW_P1_2_GE_PHY_P1) |
| && (ethConfig & MV_ETHCOMP_SW_P2_2_GE_PHY_P2) && (ethConfig & MV_ETHCOMP_SW_P3_2_GE_PHY_P3)) |
| mvOsOutput("\t4xGE-PHY Module on 4 Switch ports\n"); |
| else { |
| if (ethConfig & MV_ETHCOMP_SW_P0_2_GE_PHY_P0) |
| mvOsOutput("\tGE-PHY-0 Module on Switch port #0\n"); |
| if (ethConfig & MV_ETHCOMP_SW_P1_2_GE_PHY_P1) |
| mvOsOutput("\tGE-PHY-1 Module on Switch port #1\n"); |
| if (ethConfig & MV_ETHCOMP_SW_P2_2_GE_PHY_P2) |
| mvOsOutput("\tGE-PHY-2 Module on Switch port #2\n"); |
| if (ethConfig & MV_ETHCOMP_SW_P3_2_GE_PHY_P3) |
| mvOsOutput("\tGE-PHY-3 Module on Switch port #3\n"); |
| } |
| |
| if (ethConfig & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES) |
| mvOsOutput("\tPON ETH SERDES on MAC1 [SGMII1]\n"); |
| if (ethConfig & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP) |
| mvOsOutput("\tPON ETH SERDES on MAC1 [SFP]\n"); |
| if (ethConfig & MV_ETHCOMP_P2P_MAC_2_PON_ETH_SERDES) |
| mvOsOutput("\tPON ETH SERDES on P2P MAC\n"); |
| |
| /* TDM / Slic configuration */ |
| slicDevice = mvBoardSlicUnitTypeGet(); |
| if (slicDevice < MV_BOARD_SLIC_MAX_OPTION) /* 4 supported configurations */ |
| mvOsOutput("\tTDM/SLIC: %s\n", tdmSlic[slicDevice]); |
| else |
| mvOsOutput("\tTDM/SLIC: Unsupported configuration\n"); |
| |
| /* SERDES Lanes*/ |
| mvOsOutput("\nSERDES configuration:\n"); |
| mvOsOutput("\tLane #0: PCIe0\n"); /* Lane 0 is always PCIe0 */ |
| |
| /* Dynamic config for SerDes lanes is relevant only to MV88F6660/65/58 */ |
| if (modelID != MV_6660_DEV_ID && modelID != MV_6665_DEV_ID && modelID != MV_6658_DEV_ID) |
| return; |
| |
| mvOsOutput("\tLane #1: %s\n", lane1[mvBoardLaneSelectorGet(1)]); |
| /* SERDES lanes #2,#3 are relevant only to MV88F6660/65 SoC */ |
| if (modelID != MV_6660_DEV_ID && modelID != MV_6665_DEV_ID) |
| return; |
| mvOsOutput("\tLane #2: %s\n", (mvBoardLaneSelectorGet(2) ? "SATA-0" : "SGMII-0")); |
| mvOsOutput("\tLane #3: %s\n", (mvBoardLaneSelectorGet(3) ? "SGMII-0" : "USB3")); |
| } |
| |
| /******************************************************************************* |
| * mvBoardLaneSelectorGet |
| * |
| * DESCRIPTION: |
| * Get Lane Selector |
| * |
| * INPUT: |
| * Lane number |
| * |
| * OUTPUT: |
| * |
| * RETURN: |
| * Lane selector |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardLaneSelectorGet(MV_U32 laneNum) |
| { |
| MV_U32 revID = mvCtrlRevGet(); |
| MV_U32 laneSelector, selector = MV_REG_READ(MV_COMMON_PHY_REGS_OFFSET); |
| if (revID <= MV_88F66X0_Z3_ID) |
| laneSelector = (selector & SERDES_LANE_MASK_Z_REV(laneNum)) >> SERDES_LANE_OFFS_Z_REV(laneNum); |
| else |
| laneSelector = (selector & SERDES_LANE_MASK(laneNum)) >> SERDES_LANE_OFFS(laneNum); |
| return laneSelector; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsGbEPortConnected |
| * |
| * DESCRIPTION: |
| * Checks if a given GbE port is actually connected to the GE-PHY, internal Switch or any RGMII module. |
| * |
| * INPUT: |
| * port - GbE port number (0 or 1). |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE if port is connected, MV_FALSE otherwise. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsGbEPortConnected(MV_U32 ethPortNum) |
| { |
| return MV_FALSE; |
| } |
| |
| /* Board devices API managments */ |
| |
| /******************************************************************************* |
| * mvBoardGetDeviceNumber - Get number of device of some type on the board |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * number of those devices else the function returns 0 |
| * |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_U32 foundIndex = 0, devNum; |
| |
| for (devNum = START_DEV_CS; devNum < board->numBoardDeviceIf; devNum++) |
| if (board->pDevCsInfo[devNum].devClass == devClass) |
| foundIndex++; |
| |
| return foundIndex; |
| } |
| |
| /******************************************************************************* |
| * mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devIndex - The device sequential number on the board |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * Base address else the function returns 0xffffffff |
| * |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass); |
| |
| if (devEntry) |
| return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS)); |
| |
| return 0xFFFFFFFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devIndex - The device sequential number on the board |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * Bus width else the function returns 0xffffffff |
| * |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass); |
| |
| if (devEntry) |
| return devEntry->busWidth; |
| |
| return 0xFFFFFFFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardGetDeviceWinSize - Get the window size of a device existing on the board |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devIndex - The device sequential number on the board |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * window size else the function returns 0xffffffff |
| * |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass); |
| |
| if (devEntry) |
| return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS)); |
| |
| return 0xFFFFFFFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardGetDevEntry - returns the entry pointer of a device on the board |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devIndex - The device sequential number on the board |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * dev number else the function returns 0x0 |
| * |
| *******************************************************************************/ |
| static MV_DEV_CS_INFO *mvBoardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_U32 foundIndex = 0, devIndex; |
| |
| for (devIndex = START_DEV_CS; devIndex < board->numBoardDeviceIf; devIndex++) { |
| if (board->pDevCsInfo[devIndex].devClass == devClass) { |
| if (foundIndex == devNum) |
| return &(board->pDevCsInfo[devIndex]); |
| foundIndex++; |
| } |
| } |
| |
| /* device not found */ |
| return NULL; |
| } |
| |
| /******************************************************************************* |
| * mvBoardGetDevCSNum |
| * |
| * DESCRIPTION: |
| * Return the device's chip-select number. |
| * |
| * INPUT: |
| * devIndex - The device sequential number on the board |
| * devType - The device type ( Flash,RTC , etc .. ) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * If the device is found on the board the then the functions returns the |
| * dev number else the function returns 0x0 |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass) |
| { |
| MV_DEV_CS_INFO *devEntry = mvBoardGetDevEntry(devNum, devClass); |
| |
| if (devEntry) |
| return devEntry->deviceCS; |
| |
| return 0xFFFFFFFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIoExpValGet - read a specified value from IO Expanders |
| * |
| * DESCRIPTION: |
| * This function returns specified value from IO Expanders |
| * |
| * INPUT: |
| * ioInfo - relevant IO Expander information |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_U8 :return requested value , if TWSI read was succesfull, else 0xFF. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardIoExpValGet(MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo) |
| { |
| MV_U8 val, mask; |
| |
| if (ioInfo==NULL) |
| return (MV_U8)MV_ERROR; |
| |
| if (mvBoardTwsiGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum, ioInfo->regNum, &val, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Read from IO Expander at 0x%x failed\n", __func__ |
| , mvBoardTwsiAddrGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum)); |
| return (MV_U8)MV_ERROR; |
| } |
| |
| mask = (1 << ioInfo->offset); |
| return (val & mask) >> ioInfo->offset; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIoExpValSet - write a specified value to IO Expanders |
| * |
| * DESCRIPTION: |
| * This function writes specified value to IO Expanders |
| * |
| * INPUT: |
| * ioInfo - relevant IO Expander information |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_U8 :return requested value , if TWSI read was succesfull, else 0xFF. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardIoExpValSet(MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo, MV_U8 value) |
| { |
| MV_U8 readVal, configVal; |
| |
| if (ioInfo == NULL) { |
| mvOsPrintf("%s: Error: Write to IO Expander failed (invalid Expander info)\n", __func__); |
| return MV_ERROR; |
| } |
| /* Read Value */ |
| if (mvBoardTwsiGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum, |
| ioInfo->regNum, &readVal, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Read from IO Expander failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* Read Configuration Value */ |
| if (mvBoardTwsiGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum, |
| ioInfo->regNum + 6, &configVal, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Read Configuration from IO Expander failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* Modify Configuration value to Enable write for requested bit */ |
| configVal &= ~(1 << ioInfo->offset); /* clean bit of old value */ |
| if (mvBoardTwsiSet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum, |
| ioInfo->regNum + 6, &configVal, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Enable Write to IO Expander at 0x%x failed\n", __func__ |
| , mvBoardTwsiAddrGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum)); |
| return MV_ERROR; |
| } |
| |
| /* Modify */ |
| readVal &= ~(1 << ioInfo->offset); /* clean bit of old value */ |
| readVal |= (value << ioInfo->offset); |
| |
| /* Write */ |
| if (mvBoardTwsiSet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum, |
| ioInfo->regNum + 2, &readVal, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO Expander at 0x%x failed\n", __func__ |
| , mvBoardTwsiAddrGet(BOARD_DEV_TWSI_IO_EXPANDER, ioInfo->expanderNum)); |
| return MV_ERROR; |
| } |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTwsiAddrTypeGet |
| * |
| * DESCRIPTION: |
| * Return the TWSI address type for a given twsi device class. |
| * |
| * INPUT: |
| * twsiClass - The TWSI device to return the address type for. |
| * index - The TWSI device index (Pass 0 in case of a single |
| * device) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * The TWSI address type. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardTwsiAddrTypeGet(MV_BOARD_TWSI_CLASS twsiClass, MV_U32 index) |
| { |
| int i; |
| MV_U32 indexFound = 0; |
| |
| for (i = 0; i < board->numBoardTwsiDev; i++) { |
| if (board->pBoardTwsiDev[i].devClass == twsiClass) { |
| if (indexFound == index) |
| return board->pBoardTwsiDev[i].twsiDevAddrType; |
| else |
| indexFound++; |
| } |
| } |
| DB(mvOsPrintf("%s: Error: read TWSI address type failed\n", __func__)); |
| return MV_ERROR; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTwsiAddrGet |
| * |
| * DESCRIPTION: |
| * Return the TWSI address for a given twsi device class. |
| * |
| * INPUT: |
| * twsiClass - The TWSI device to return the address type for. |
| * index - The TWSI device index (Pass 0 in case of a single |
| * device) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * The TWSI address. |
| * |
| *******************************************************************************/ |
| MV_U8 mvBoardTwsiAddrGet(MV_BOARD_TWSI_CLASS twsiClass, MV_U32 index) |
| { |
| int i; |
| |
| for (i = 0; i < board->numBoardTwsiDev; i++) { |
| if ((board->pBoardTwsiDev[i].devClass == twsiClass) \ |
| && (board->pBoardTwsiDev[i].devClassId == index)){ |
| return board->pBoardTwsiDev[i].twsiDevAddr; |
| } |
| } |
| |
| return 0xFF; |
| } |
| |
| /******************************************************************************* |
| * mvBoardEthComplexConfigGet - Return ethernet complex board configuration. |
| * |
| * DESCRIPTION: |
| * Returns the ethernet / Sata complex configuration from the board spec |
| * structure. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit value describing the ethernet complex config. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardEthComplexConfigGet(MV_VOID) |
| { |
| return board->pBoardModTypeValue->ethSataComplexOpt; |
| } |
| |
| /******************************************************************************* |
| * mvBoardEthComplexConfigSet - Set ethernet complex board configuration. |
| * |
| * DESCRIPTION: |
| * Sets the ethernet / Sata complex configuration in the board spec |
| * structure. |
| * |
| * INPUT: |
| * ethConfig - 32bit value describing the ethernet complex config. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardEthComplexConfigSet(MV_U32 ethConfig) |
| { |
| /* Set ethernet complex configuration. */ |
| board->pBoardModTypeValue->ethSataComplexOpt = ethConfig; |
| return; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSatrInfoConfig |
| * |
| * DESCRIPTION: |
| * Return the SAR fields information for a given SAR class. |
| * |
| * INPUT: |
| * satrClass - The SATR field to return the information for. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_BOARD_SATR_INFO struct with mask, offset and register number. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardSatrInfoConfig(MV_SATR_TYPE_ID satrClass, MV_BOARD_SATR_INFO *satrInfo, MV_BOOL read) |
| { |
| int i; |
| MV_U32 boardId = mvBoardIdIndexGet(mvBoardIdGet()); |
| |
| /* verify existence of requested SATR type, and pull its data, |
| * if write sequence, check if field is writeable for running board */ |
| for (i = 0; i < MV_SATR_WRITE_MAX_OPTION ; i++) |
| if (boardSatrInfo[i].satrId == satrClass) { |
| |
| /* if read sequence, or an authorized write sequence -> return true */ |
| if (read == MV_TRUE || boardSatrInfo[i].isWriteable[boardId]) { |
| *satrInfo = boardSatrInfo[i]; |
| return MV_OK; |
| } |
| else |
| return MV_ERROR; |
| } |
| DB(mvOsPrintf("%s: Error: requested MV_SATR_TYPE_ID was not found (%d)\n", __func__,satrClass)); |
| return MV_ERROR; |
| } |
| |
| /******************************************************************************* |
| * mvBoardConfigTypeGet |
| * |
| * DESCRIPTION: |
| * Return the Config type fields information for a given Config type class. |
| * |
| * INPUT: |
| * configClass - The Config type field to return the information for. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_BOARD_CONFIG_TYPE_INFO struct with mask, offset and register number. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardConfigTypeGet(MV_CONFIG_TYPE_ID configClass, MV_BOARD_CONFIG_TYPE_INFO *configInfo) |
| { |
| int i; |
| MV_U32 boardId = mvBoardIdIndexGet(mvBoardIdGet()); |
| |
| /* verify existence of requested config type, pull its data, |
| * and check if field is relevant to current running board */ |
| for (i = 0; i < MV_CONFIG_TYPE_MAX_OPTION ; i++) |
| if (boardConfigTypesInfo[i].configId == configClass) { |
| *configInfo = boardConfigTypesInfo[i]; |
| if (boardConfigTypesInfo[i].isActiveForBoard[boardId]) |
| return MV_TRUE; |
| else |
| return MV_FALSE; |
| } |
| mvOsPrintf("%s: Error: requested MV_CONFIG_TYPE_ID was not found (%d)\n", __func__, configClass); |
| return MV_FALSE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIoExpanderTypeGet |
| * |
| * DESCRIPTION: |
| * Return the Config type fields information for a given Config type class. |
| * |
| * INPUT: |
| * configClass - The Config type field to return the information for. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_BOARD_CONFIG_TYPE_INFO struct with mask, offset and register number. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_TYPE_ID ioClass, |
| MV_BOARD_IO_EXPANDER_TYPE_INFO *ioInfo) |
| { |
| MV_U32 i; |
| |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioe_db6660[] = MV_BOARD_IO_EXP_DB6660_INFO; |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioe_db6650[] = MV_BOARD_IO_EXP_DB6650_INFO; |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioe_rd6660[] = MV_BOARD_IO_EXP_RD6660_INFO; |
| MV_BOARD_IO_EXPANDER_TYPE_INFO *ioe; |
| MV_U8 n = 0; |
| |
| switch (mvBoardIdGet()) { |
| case DB_6650_ID: |
| ioe = ioe_db6650; |
| n = ARRSZ(ioe_db6650); |
| break; |
| case DB_6660_ID: |
| ioe = ioe_db6660; |
| n = ARRSZ(ioe_db6660); |
| break; |
| case RD_6660_ID: |
| ioe = ioe_rd6660; |
| n = ARRSZ(ioe_rd6660); |
| break; |
| default: |
| mvOsPrintf("%s: Error: IO Expander doesn't exists on board\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* verify existance of requested config type, pull its data */ |
| for (i = 0; i < n ; i++) |
| if (ioe[i].ioFieldid == ioClass) { |
| |
| *ioInfo = ioe[i]; |
| return MV_OK; |
| } |
| |
| mvOsPrintf("%s: Error: requested IO expander id was not found (%d)\n", |
| __func__, ioClass); |
| return MV_ERROR; |
| } |
| |
| /******************************************************************************* |
| * mvBoardExtPhyBufferSelect - enable/disable buffer status |
| * |
| * DESCRIPTION: |
| * This function enables/disables the buffer status. |
| * |
| * INPUT: |
| * enable - Boolean to indicate requested status |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardExtPhyBufferSelect(MV_BOOL enable) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_EXT_PHY_SMI_EN, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (External Phy SMI Buffer select)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enable ? 0x0 : 0x1)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardSgmiiSfp0TxSet - enable/disable SGMII_SFP0_TX_DISABLE status |
| * |
| * DESCRIPTION: |
| * This function enables/disables the field status. |
| * |
| * INPUT: |
| * enable - Boolean to indicate requested status |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardSgmiiSfp0TxSet(MV_BOOL enable) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_SFP0_TX_DIS, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (SFP0_TX_DIS)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enable ? 0x0 : 0x1)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardSgmiiSfp1TxSet - enable/disable SGMII_SFP1_TX_DISABLE status |
| * |
| * DESCRIPTION: |
| * This function enables/disables the field status. |
| * |
| * INPUT: |
| * enable - Boolean to indicate requested status |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| ********************************************************************************/ |
| MV_STATUS mvBoardSgmiiSfp1TxSet(MV_BOOL enable) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_SFP1_TX_DIS, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (SFP1_TX_DIS)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enable ? 0x0 : 0x1)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardHDDSelecteExternal - Select External / Internal HDD |
| * |
| * DESCRIPTION: |
| * This function External / Internal HDD |
| * HDD_SELECT = 1 --> Routes SATA signals to External connector |
| * HDD_SELECT = 0 --> Routes SATA signals to Internal connector |
| * |
| * INPUT: |
| * enableInternal - Boolean to indicate requested status |
| * MV_TRUE --> set Internal HDD |
| * MV_FALSE --> set External HDD |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardHddExtSet(MV_BOOL enableExternal) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_HDD_SELECT, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (USB_SS_EN)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enableExternal ? 0x1 : 0x0)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardHDDPowerSet - enable HDD Power status |
| * |
| * DESCRIPTION: |
| * This function enables/disables HDD Power status. |
| * HDD_SELECT = 1 --> Enables SATA power |
| * |
| * INPUT: |
| * enable - Boolean to indicate requested status |
| * MV_TRUE --> Enables SATA power |
| * MV_FALSE --> Disables SATA power |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardHDDPowerSet(MV_BOOL enable) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_HDD_PWR_EN, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (USB_SS_EN)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enable ? 0x1 : 0x1)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardUsbSsEnSet - enable/disable USB_SS_EN status |
| * |
| * DESCRIPTION: |
| * This function enables/disables USB_SS_EN status. |
| * USB_SS_EN = 1 --> Enable USB 3.0 900mA current limit |
| * |
| * INPUT: |
| * enable - Boolean to indicate requested status |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * None. |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardUsbSsEnSet(MV_BOOL enable) |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_USB_SUPER_SPEED, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Write to IO expander failed (USB_SS_EN)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| return mvBoardIoExpValSet(&ioInfo, (enable ? 0x1 : 0x0)); |
| } |
| |
| /******************************************************************************* |
| * mvBoardSet - Set Board model |
| * |
| * DESCRIPTION: |
| * This function sets the board ID. |
| * Board ID is 32bit word constructed of board model (16bit) and |
| * board revision (16bit) in the following way: 0xMMMMRRRR. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * void |
| * |
| *******************************************************************************/ |
| static MV_U32 gBoardId = -1; |
| MV_VOID mvBoardSet(MV_U32 boardId) |
| { |
| /* board ID's >0x10 are for Marvell Boards */ |
| if (boardId >= MARVELL_BOARD_ID_BASE && boardId < MV_MAX_MARVELL_BOARD_ID) { /* Marvell Board */ |
| board = marvellBoardInfoTbl[mvBoardIdIndexGet(boardId)]; |
| gBoardId = boardId; |
| } else if (boardId >= CUTOMER_BOARD_ID_BASE && boardId < MV_MAX_CUSTOMER_BOARD_ID) { /* Customer Board */ |
| board = customerBoardInfoTbl[mvBoardIdIndexGet(boardId)]; |
| gBoardId = boardId; |
| } else { |
| mvOsPrintf("%s: Error: wrong board Id (%d)\n", __func__, boardId); |
| gBoardId = 0; |
| board = customerBoardInfoTbl[gBoardId]; |
| mvOsPrintf("Applying default board ID (%d: %s)\n", gBoardId, board->boardName); |
| } |
| } |
| |
| /******************************************************************************* |
| * mvBoardIdGet - Get Board model |
| * |
| * DESCRIPTION: |
| * This function returns board ID. |
| * Board ID is 32bit word constructed of board model (16bit) and |
| * board revision (16bit) in the following way: 0xMMMMRRRR. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 32bit board ID number, '-1' if board is undefined. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardIdGet(MV_VOID) |
| { |
| if (gBoardId != -1) |
| return gBoardId; |
| |
| #ifdef CONFIG_CUSTOMER_BOARD_SUPPORT |
| #ifdef CONFIG_CUSTOMER_BOARD_0 |
| gBoardId = AVANTA_LP_CUSTOMER_BOARD_ID0; |
| #elif CONFIG_CUSTOMER_BOARD_1 |
| gBoardId = AVANTA_LP_CUSTOMER_BOARD_ID1; |
| #endif |
| #else |
| |
| MV_U32 readValue; |
| |
| readValue = MV_REG_READ(MPP_SAMPLE_AT_RESET(1)); |
| readValue = ((readValue & (0xF0)) >> 4); |
| |
| if (readValue < MV_MARVELL_BOARD_NUM && readValue >= 0) { |
| gBoardId = MARVELL_BOARD_ID_BASE + readValue; |
| } else { |
| mvOsPrintf("%s: Error: read wrong board (%d)\n", __func__, readValue); |
| return MV_INVALID_BOARD_ID; |
| } |
| #endif |
| |
| return gBoardId; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTwsiGet - |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * device num - one of three devices |
| * reg num - 0 or 1 |
| * byteCnt - how many bytes to read/write |
| * pData - type must correspond with byteCnt |
| * (for example, if byteCnt = 4, pData must be a pointer for 32bit var) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * reg value |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardTwsiGet(MV_BOARD_TWSI_CLASS twsiClass, MV_U8 devNum, MV_U8 regNum, MV_U8 *pData, MV_U32 byteCnt) |
| { |
| MV_TWSI_SLAVE twsiSlave; |
| MV_TWSI_ADDR slave; |
| |
| /* TWSI init */ |
| slave.type = ADDR7_BIT; |
| slave.address = 0; |
| mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0); |
| |
| DB(mvOsPrintf("Board: TWSI Read device\n")); |
| twsiSlave.slaveAddr.address = mvBoardTwsiAddrGet(twsiClass, devNum); |
| twsiSlave.slaveAddr.type = mvBoardTwsiAddrTypeGet(twsiClass, devNum); |
| DB(mvOsPrintf("%s: TWSI Read addr %x, type %x\n", __func__, |
| twsiSlave.slaveAddr.address, twsiSlave.slaveAddr.type)); |
| twsiSlave.validOffset = MV_TRUE; |
| /* Use offset as command */ |
| twsiSlave.offset = regNum; |
| |
| if (twsiClass == BOARD_DEV_TWSI_EEPROM) |
| twsiSlave.moreThen256 = MV_TRUE; |
| else |
| twsiSlave.moreThen256 = MV_FALSE; |
| |
| if (MV_OK != mvTwsiRead(0, &twsiSlave, pData, byteCnt)) { |
| mvOsPrintf("%s: Twsi Read fail\n", __func__); |
| return MV_ERROR; |
| } |
| DB(mvOsPrintf("Board: Read S@R succeded\n")); |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardTwsiSet |
| * |
| * DESCRIPTION: |
| * |
| * INPUT: |
| * devNum - one of three devices |
| * regNum - 0 or 1 |
| * regVal - valuei |
| * byteCnt - how many bytes to read/write |
| * regVal - type must correspond with byteCnt |
| * (for example, if byteCnt = 4, regVal must be a pointer for 32bit var) |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * reg value |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardTwsiSet(MV_BOARD_TWSI_CLASS twsiClass, MV_U8 devNum, MV_U8 regNum, MV_U8 *regVal, MV_U32 byteCnt) |
| { |
| MV_TWSI_SLAVE twsiSlave; |
| MV_TWSI_ADDR slave; |
| |
| /* TWSI init */ |
| slave.type = ADDR7_BIT; |
| slave.address = 0; |
| mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0); |
| |
| /* Read MPP module ID */ |
| twsiSlave.slaveAddr.address = mvBoardTwsiAddrGet(twsiClass, devNum); |
| twsiSlave.slaveAddr.type = mvBoardTwsiAddrTypeGet(twsiClass, devNum); |
| twsiSlave.validOffset = MV_TRUE; |
| DB(mvOsPrintf("%s: TWSI Write addr %x, type %x, data %x\n", __func__, |
| twsiSlave.slaveAddr.address, twsiSlave.slaveAddr.type, *regVal)); |
| /* Use offset as command */ |
| twsiSlave.offset = regNum; |
| |
| /* need to use 2 address bytes when accessing EEPROM */ |
| if (twsiClass == BOARD_DEV_TWSI_EEPROM) |
| twsiSlave.moreThen256 = MV_TRUE; /* use 2 address bytes */ |
| else |
| twsiSlave.moreThen256 = MV_FALSE; /* use 1 address byte */ |
| |
| |
| if (MV_OK != mvTwsiWrite(0, &twsiSlave, regVal, byteCnt)) { |
| DB(mvOsPrintf("%s: Write S@R fail\n", __func__)); |
| return MV_ERROR; |
| } |
| DB(mvOsPrintf("%s: Write S@R succeded\n", __func__)); |
| |
| return MV_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * mvBoardEepromWrite - Write a new configuration value for a specific field |
| * |
| * DESCRIPTION: |
| * Verify if the EEPROM have been initialized (if not, initialize it): |
| * EEPROM expected mapping: |
| * [0x0] - configuration 1st byte |
| * [0x1] - configuration 2nd byte |
| * [0x2] - configuration 3rd byte |
| * [0x4-0x7] - 32bit pattern to detect if EEPROM is initialized |
| * INPUT: |
| * None |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Returns MV_TRUE if a chip responded, MV_FALSE on failure |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardEepromWrite(MV_CONFIG_TYPE_ID configType, MV_U8 value) |
| { |
| MV_BOARD_CONFIG_TYPE_INFO configInfo; |
| MV_U8 readValue, regNum; |
| |
| if (mvBoardConfigTypeGet(configType, &configInfo) != MV_TRUE) { |
| mvOsPrintf("%s: Error: Write configuration to EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| /* check if value is bigger then field's limit */ |
| if (value > configInfo.mask >> configInfo.offset) { |
| mvOsPrintf("%s: Error: Requested write value is not valid (%d)\n", __func__, value); |
| return MV_ERROR; |
| } |
| /* reg num is according to DIP-switch mapping (each Expander conatins 2 registers) */ |
| regNum = configInfo.expanderNum * 2 + configInfo.regNum; |
| |
| /* Read */ |
| if (mvBoardTwsiGet(BOARD_DEV_TWSI_EEPROM, 0, regNum , &readValue, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Read configuration from EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* Modify */ |
| readValue &= ~configInfo.mask; |
| readValue |= (value << configInfo.offset); |
| |
| /* Write */ |
| if (mvBoardTwsiSet(BOARD_DEV_TWSI_EEPROM, 0, regNum, &readValue, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Write configuration to EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* Update local array information */ |
| mvBoardSysConfigSet(configInfo.configId, value); |
| |
| /* run conflict verification sequence on MAC and SerDes configuration */ |
| mvBoardEthComplexMacConfigCheck(); |
| |
| /* Check conflicts between device bus module and NAND */ |
| mvBoardAudioModuleConfigCheck(); |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardEepromWriteDefaultCfg - Write default configuration to EEPROM |
| * |
| * DESCRIPTION: |
| * Write default configuration to EEPROM |
| * EEPROM expected mapping: |
| * [0x0-0x3](32bits) - board configuration |
| * [0x4-0x7](32bits) - pattern |
| * INPUT: |
| * None |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Returns MV_TRUE if a chip responded, MV_FALSE on failure |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardEepromWriteDefaultCfg(void) |
| { |
| MV_U8 i; |
| MV_U32 defaultValue[1] = MV_BOARD_CONFIG_DEFAULT_VALUE; |
| /* write default board configuration */ |
| for (i = 0; i < MV_BOARD_CONFIG_MAX_BYTE_COUNT/4; i++) { |
| /* Swap byte's order to be from LSB to MSB: |
| - When reading 32bit variables, the I2C commands display the bytes from LSB to MSB |
| - mvBoardTwsiSet/Get writes/reads bytes according to their actual address location |
| - in order to keep I2C output aligned with original written data |
| we reverse the byte order to be from LSB to MSB before each read/write */ |
| defaultValue[i] = cpu_to_be32(defaultValue[i]); |
| if (mvBoardTwsiSet(BOARD_DEV_TWSI_EEPROM, 0, i * 4, (MV_U8 *)&defaultValue[i], 4) != MV_OK) { |
| mvOsPrintf("%s: Error: Set default configuration to EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| } |
| |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardEepromInit - Verify if the EEPROM have been initialized |
| * |
| * DESCRIPTION: |
| * Verify if the EEPROM have been initialized (if not, initialize it): |
| * EEPROM expected mapping: |
| * [0x0] - configuration 1st byte |
| * [0x1] - configuration 2nd byte |
| * [0x2] - configuration 3rd byte |
| * [0x4-0x7] - 32bit pattern |
| * INPUT: |
| * None |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * Returns MV_TRUE if a chip responded, MV_FALSE on failure |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardEepromInit() |
| { |
| MV_U32 readValue, i, pattern = 0; |
| MV_U32 patternByte = be32_to_cpu(EEPROM_VERIFICATION_PATTERN); |
| |
| if (mvBoardIsEepromEnabled() != MV_TRUE) { |
| DB(printf("%s: EEPROM doesn't exists on board\n" , __func__)); |
| return MV_ERROR; |
| } |
| |
| /* verify EEPROM: read 4 bytes at address 0x4 (read magic pattern) */ |
| for (i = 0; i < 4; i++) { |
| if (mvBoardTwsiGet(BOARD_DEV_TWSI_EEPROM, 0, 0x4 + i, (MV_U8 *)&readValue, 1) != MV_OK) { |
| mvOsPrintf("%s: Error: Read pattern from EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| readValue = MV_32BIT_LE_FAST(readValue); |
| /* shift byte to correct location in 32bit pattern */ |
| pattern |= (readValue & 0x000000FF) << (32 - 8*(i+1)); |
| readValue = 0; |
| } |
| |
| /* If EEPROM is initialized with magic pattern, continue and exit*/ |
| if (pattern == EEPROM_VERIFICATION_PATTERN) |
| return MV_OK; |
| |
| /* Else write default configuration and set magic pattern */ |
| if (mvBoardEepromWriteDefaultCfg() != MV_OK) { |
| mvOsPrintf("%s: Error: Write configuration to EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| /* shift bytes to correct location from 32bit pattern to 1 byte chunks*/ |
| if (mvBoardTwsiSet(BOARD_DEV_TWSI_EEPROM, 0, 4, (MV_U8 *)&patternByte, 4) != MV_OK) { |
| mvOsPrintf("%s: Error: Write configuration to EEPROM failed\n", __func__); |
| return MV_ERROR; |
| } |
| |
| mvOsPrintf("\n%s: Initialized EEPROM with default board ", __func__); |
| mvOsPrintf("configuration (1st use of EEPROM)\n\n"); |
| return MV_OK; |
| } |
| |
| /******************************************************************************* |
| * mvBoardDefaultValueGet |
| * |
| * DESCRIPTION: This function get the option number and return the default value |
| * |
| * INPUT: option number |
| * |
| * OUTPUT: None |
| * |
| * RETURN: default value |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardDefaultValueGet(int option) |
| { |
| return 0; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsEepromEnabled - read EEPROM and verify if EEPROM exists |
| * |
| * DESCRIPTION: |
| * This function returns MV_TRUE if board configuration EEPROM exists on board. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_BOOL : MV_TRUE if EEPROM exists, else return MV_FALSE. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsEepromEnabled() |
| { |
| MV_BOARD_IO_EXPANDER_TYPE_INFO ioInfo; |
| MV_U8 value, addr = mvBoardTwsiAddrGet(BOARD_DEV_TWSI_EEPROM, 0); |
| MV_U32 boardId = mvBoardIdGet(); |
| |
| if (boardId != DB_6650_ID && boardId != DB_6660_ID) { |
| mvOsPrintf("Error: EEPROM is available only on Development boards (DB-6650/60)\n"); |
| return MV_FALSE; |
| } |
| |
| if (addr == 0xFF) |
| return MV_FALSE; |
| |
| if (mvBoardIoExpanderTypeGet(MV_IO_EXPANDER_JUMPER2_EEPROM_ENABLED, &ioInfo) != MV_OK) { |
| mvOsPrintf("%s: Error: Read from IO expander failed (EEPROM enabled jumper)\n", __func__); |
| return MV_FALSE; |
| } |
| |
| value = mvBoardIoExpValGet(&ioInfo); |
| if (value == 0x1) { /* Jumper is OUT: EEPROM disabled */ |
| DB(mvOsPrintf("%s: EEPROM Jumper is disabled\n", __func__)); |
| return MV_OK; |
| } |
| /* else Jumper is IN: EEPROM enabled */ |
| DB(mvOsPrintf("%s: EEPROM Jumper is enabled\n", __func__)); |
| |
| DB(mvOsPrintf("%s probing for i2c chip 0x%x\n", __func__, addr)); |
| if (mvTwsiProbe((MV_U32)addr, mvBoardTclkGet()) == MV_TRUE) |
| return MV_TRUE; /* EEPROM enabled */ |
| else |
| return MV_FALSE; /* EEPROM disabled */ |
| } |
| |
| /******************************************************************************* |
| * mvBoardSmiScanModeGet - Get Switch SMI scan mode |
| * |
| * DESCRIPTION: |
| * This routine returns Switch SMI scan mode. |
| * |
| * INPUT: |
| * switchIdx - index of the switch. Only 0 is supported. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant. |
| * |
| *******************************************************************************/ |
| MV_32 mvBoardSmiScanModeGet(MV_U32 switchIdx) |
| { |
| return BOARD_ETH_SWITCH_SMI_SCAN_MODE; |
| } |
| |
| /******************************************************************************* |
| * mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port |
| * |
| * DESCRIPTION: |
| * This routine returns the Switch CPU port if connected, -1 else. |
| * |
| * INPUT: |
| * switchIdx - index of the switch. Only 0 is supported. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * the Switch CPU port, -1 if the switch is not connected. |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSwitchCpuPortGet(MV_U32 switchIdx) |
| { |
| MV_U32 c = mvBoardEthComplexConfigGet(); |
| MV_U32 cpuPort = -1; |
| |
| if (c & MV_ETHCOMP_GE_MAC0_2_SW_P6) |
| cpuPort = 6; |
| else if (c & MV_ETHCOMP_GE_MAC1_2_SW_P4) |
| cpuPort = 4; |
| else |
| mvOsPrintf("%s: Error: No CPU port.\n", __func__); |
| |
| return cpuPort; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsEthConnected - detect if a certain Ethernet port is connected |
| * |
| * DESCRIPTION: |
| * This routine returns true if a certain Ethernet port is connected |
| * |
| * INPUT: |
| * ethNum - index of the ethernet port requested |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE if the requested ethernet port is connected. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsEthConnected(MV_U32 ethNum) |
| { |
| MV_U32 c = mvBoardEthComplexConfigGet(); |
| MV_BOOL isConnected = MV_FALSE; |
| |
| if (ethNum >= board->numBoardMacInfo) { |
| mvOsPrintf("%s: Error: Illegal port number(%u)\n", __func__, ethNum); |
| return MV_FALSE; |
| } |
| |
| /* Determine if port is connected: |
| * If set as active in Ethernet complex board configuration */ |
| if (ethNum == 0 && ((c & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) || |
| (c & MV_ETHCOMP_GE_MAC0_2_RGMII0) || |
| (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_1) || |
| (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_2) || |
| (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_3) || |
| (c & MV_ETHCOMP_GE_MAC0_2_SW_P6))) |
| isConnected = MV_TRUE; |
| |
| if (ethNum == 1 && ((c & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) || |
| (c & MV_ETHCOMP_GE_MAC1_2_RGMII1) || |
| (c & MV_ETHCOMP_GE_MAC1_2_RGMII0) || |
| (c & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES) || |
| (c & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP) || |
| (c & MV_ETHCOMP_GE_MAC1_2_SW_P4))) |
| isConnected = MV_TRUE; |
| |
| if (ethNum == 2 && mvBoardIsPortLoopback(ethNum)) |
| isConnected = MV_TRUE; |
| |
| return isConnected; |
| } |
| |
| /******************************************************************************* |
| * mvBoardIsEthActive - detect if a certain Ethernet port is Active and usable |
| * |
| * DESCRIPTION: |
| * This routine returns true if a certain Ethernet port is |
| * Active and usable as a regular eth interface |
| * |
| * INPUT: |
| * ethNum - index of the ethernet port requested |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE if the requested ethernet port is Active and usable. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardIsEthActive(MV_U32 ethNum) |
| { |
| MV_U32 c = mvBoardEthComplexConfigGet(); |
| MV_BOOL isActive = MV_FALSE; |
| |
| if (ethNum >= board->numBoardMacInfo) { |
| mvOsPrintf("%s: Error: Illegal port number(%u)\n", __func__, ethNum); |
| return MV_FALSE; |
| } |
| |
| /* |
| * Determine if port is active - both connected and usable: |
| * 1. connected : if MAC is set as connected in Ethernet complex board configuration |
| * 2. usable : - MAC always usable when connected to RGMII, COMPHY, or GE-PHY |
| * - if connected to switch ,a MAC is usable only as the CPU Port |
| * (if another MAC is connected to switch, it's used for Loopback) |
| */ |
| if (ethNum == 0 && ((c & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) || |
| (c & MV_ETHCOMP_GE_MAC0_2_RGMII0) || |
| (c & MV_ETHCOMP_GE_MAC0_2_COMPHY_2) || |
| ((c & MV_ETHCOMP_GE_MAC0_2_SW_P6) && mvBoardMacCpuPortGet() == 0))) |
| isActive = MV_TRUE; |
| |
| if (ethNum == 1 && ((c & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) || |
| (c & MV_ETHCOMP_GE_MAC1_2_RGMII1) || |
| (c & MV_ETHCOMP_GE_MAC1_2_RGMII0) || |
| (c & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES) || |
| (c & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP) || |
| ((c & MV_ETHCOMP_GE_MAC1_2_SW_P4) && mvBoardMacCpuPortGet() == 1))) |
| isActive = MV_TRUE; |
| |
| return isActive; |
| } |
| /******************************************************************************* |
| * mvBoardMacCpuPortGet - returns the MAC CPU port connected to switch |
| * |
| * DESCRIPTION: |
| * This routine returns true returns the MAC CPU port connected to switch |
| * |
| * INPUT: |
| * None |
| * |
| * OUTPUT: |
| * None |
| * |
| * RETURN: |
| * the MAC CPU port number connected to switch |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardMacCpuPortGet(MV_VOID) |
| { |
| MV_U32 c = mvBoardEthComplexConfigGet(); |
| MV_U32 macCpuPort = -1; |
| |
| if (c & MV_ETHCOMP_GE_MAC0_2_SW_P6) /* MAC0 is the default CPU port */ |
| macCpuPort = 0; |
| /* only If MAC0 isn't connected to switch, then MAC1 is the CPU port |
| * If both MAC0 and MAC1 connected to switch, MAC1 is used for Loopback */ |
| else if (c & MV_ETHCOMP_GE_MAC1_2_SW_P4) |
| macCpuPort = 1; |
| else |
| DB(mvOsPrintf("%s: Error: No MAC CPU port.\n", __func__)); |
| |
| return macCpuPort; |
| } |
| |
| /******************************************************************************* |
| * mvBoardConfigAutoDetectEnabled |
| * |
| * DESCRIPTION: |
| * Indicate if the board supports auto configuration and detection of |
| * modules. This is usually enabled for DB boards only. |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_TRUE if auto-config/detection is enabled. |
| * MV_FALSE otherwise. |
| * |
| *******************************************************************************/ |
| MV_BOOL mvBoardConfigAutoDetectEnabled() |
| { |
| return board->configAutoDetect; |
| } |
| |
| /******************************************************************************* |
| * mvBoardConfigurationConflicts |
| * |
| * DESCRIPTION: |
| * Check if there is any conflicts with the board configurations |
| * |
| * INPUT: |
| * field = Field name of configuration |
| * writeVal = option number |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_OK: if there is no conflicts |
| * MV_ERROR: conflict in one configuration |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardConfigVerify(MV_CONFIG_TYPE_ID field, MV_U8 writeVal) |
| { |
| MV_U32 c = mvBoardEthComplexConfigGet(); |
| /* Config Lane1: 0x2 = SATA1, 0x3 = Unconnected are supported only for A0 |
| ** config MAC1 to RGMII0 are supported only for A0 */ |
| if (((field == MV_CONFIG_LANE1 && (writeVal == 0x2 || writeVal == 0x3)) || |
| (field == MV_CONFIG_MAC1 && writeVal == 0x3)) && |
| (mvCtrlRevGet() <= MV_88F66X0_Z3_ID)) { |
| mvOsPrintf("Error: this option is not supported in Z stepping revision\n"); |
| return MV_ERROR; |
| } |
| if (field == MV_CONFIG_MAC1 && (c & (MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES | |
| MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP))) { |
| mvOsPrintf("Warning: MAC1 is connected to PON Serdes\n" |
| "To alter MAC1 settings, please update 'ponserdes' field first\n"); |
| return MV_ERROR; |
| } |
| /* 0x3 = RGMII0, check if MAC0 is connected to RGMII0 */ |
| if (field == MV_CONFIG_MAC1 && writeVal == 0x3 && (c & MV_ETHCOMP_GE_MAC0_2_RGMII0)) { |
| mvOsPrintf("Warning: MAC0 is connected to RGMII0 Module\n"); |
| return MV_ERROR; |
| } |
| /* 0x2 = RGMII0, check if MAC1 is connected to RGMII0 */ |
| if (field == MV_CONFIG_MAC0 && writeVal == 0x2 && (c & MV_ETHCOMP_GE_MAC1_2_RGMII0)) { |
| mvOsPrintf("Warning: MAC1 is connected to RGMII0 Module\n"); |
| return MV_ERROR; |
| } |
| if (field == MV_CONFIG_SW_P4 && writeVal == 0x1 && (!(c & MV_ETHCOMP_GE_MAC1_2_RGMII1) || |
| !(c & MV_ETHCOMP_GE_MAC0_2_SW_P6))) { |
| mvOsPrintf("Warning: Connect Switch port 4 to RGMII0 enabled only with MAC1->RGMII1, "\ |
| "and MAC0->SW-P6\n"); |
| return MV_ERROR; |
| } |
| |
| |
| |
| return MV_OK; |
| |
| } |
| /******************************************************************************* |
| * mvBoardSysConfigInit |
| * |
| * DESCRIPTION: Initialize S@R configuration |
| * 1. initialize all board configuration fields |
| * 3. read relevant board configuration (using TWSI/EEPROM access) |
| * **from this point, all reads from S@R & board config will use mvCtrlSatRRead/Write functions** |
| * |
| * INPUT: None |
| * |
| * OUTPUT: None |
| * |
| * RETURN: NONE |
| * |
| *******************************************************************************/ |
| MV_VOID mvBoardSysConfigInit() |
| { |
| MV_U8 regNum, i, configVal[MV_IO_EXP_MAX_REGS], readValue, bitsNum; |
| MV_BOARD_CONFIG_TYPE_INFO configInfo; |
| MV_BOOL readSuccess = MV_FALSE; |
| MV_BOOL isEepromEnabled = mvBoardIsEepromEnabled(); |
| |
| memset(&boardOptionsConfig, 0x0, sizeof(MV_U32) * MV_CONFIG_TYPE_MAX_OPTION); |
| |
| /*Read rest of Board Configuration, EEPROM / Dip Switch access read : */ |
| if (mvCtrlBoardConfigGet(configVal) != MV_OK) { |
| mvOsPrintf("%s: Error: mvCtrlBoardConfigGet failed\n", __func__); |
| return; |
| } |
| |
| /* Save values Locally in configVal[] */ |
| for (i = 0; i < MV_CONFIG_TYPE_MAX_OPTION; i++) { |
| /* Get board configuration field information (Mask, offset, etc..) */ |
| if (mvBoardConfigTypeGet(i, &configInfo) != MV_TRUE) |
| continue; |
| |
| /* each Expander conatins 2 registers */ |
| regNum = configInfo.expanderNum * 2 + configInfo.regNum; |
| readValue = (configVal[regNum] & configInfo.mask) >> configInfo.offset; |
| |
| /* |
| * Workaround for DIP Switch IO Expander 0x21 bug in DB-6660 board |
| * Bug: Pins at IO expander 0x21 are reversed (only on DB-6660) |
| * example : instead of reading 00000110, we read 01100000 |
| * WA step 1 (mvCtrlBoardConfigGet) |
| * after reading IO expander, reverse bits of both registers |
| * WA step 2 (in mvCtrlSysConfigInit): |
| * after reversing bits, swap MSB and LSB - due to Dip-Switch reversed mapping |
| */ |
| if (!isEepromEnabled && configInfo.expanderNum == 0) { |
| bitsNum = mvCountMaskBits(configInfo.mask); |
| readValue = mvReverseBits(readValue) >> (8-bitsNum); |
| } |
| |
| boardOptionsConfig[configInfo.configId] = readValue; |
| readSuccess = MV_TRUE; |
| } |
| |
| if (readSuccess == MV_FALSE) |
| mvOsPrintf("%s: Error: Read board configuration from EEPROM/Dip Switch failed\n", __func__); |
| } |
| |
| /******************************************************************************* |
| * mvBoardSysConfigGet |
| * |
| * DESCRIPTION: Read Board configuration Field |
| * |
| * INPUT: configField - Field description enum |
| * |
| * OUTPUT: None |
| * |
| * RETURN: |
| * if field is valid - returns requested Board configuration field value |
| * |
| *******************************************************************************/ |
| MV_U32 mvBoardSysConfigGet(MV_CONFIG_TYPE_ID configField) |
| { |
| MV_BOARD_CONFIG_TYPE_INFO configInfo; |
| |
| if (!mvBoardConfigAutoDetectEnabled()) { |
| mvOsPrintf("%s: Error Failed to read board config (Auto detection disabled)\n", __func__); |
| return MV_ERROR; |
| } |
| |
| if (configField < MV_CONFIG_TYPE_MAX_OPTION && |
| mvBoardConfigTypeGet(configField, &configInfo) != MV_TRUE) { |
| DB(mvOsPrintf("%s: Error: Requested board config is invalid for this board" \ |
| " (%d)\n", __func__, configField)); |
| return MV_ERROR; |
| } |
| |
| return boardOptionsConfig[configField]; |
| |
| } |
| |
| /******************************************************************************* |
| * mvBoardSysConfigSet |
| * |
| * DESCRIPTION: Write Board configuration Field to local array |
| * |
| * INPUT: configField - Field description enum |
| * |
| * OUTPUT: None |
| * |
| * RETURN: |
| * Write requested Board configuration field value to local array |
| * |
| *******************************************************************************/ |
| MV_STATUS mvBoardSysConfigSet(MV_CONFIG_TYPE_ID configField, MV_U8 value) |
| { |
| MV_BOARD_CONFIG_TYPE_INFO configInfo; |
| |
| if (configField < MV_CONFIG_TYPE_MAX_OPTION && |
| mvBoardConfigTypeGet(configField, &configInfo) != MV_TRUE) { |
| DB(mvOsPrintf("Error: Requested board config is invalid for this board" \ |
| " (%d)\n", configField)); |
| return MV_ERROR; |
| } |
| |
| boardOptionsConfig[configField] = value; |
| |
| return MV_OK; |
| } |
| |
| |
| /******************************************************************************* |
| * mvBoardNandECCModeGet |
| * |
| * DESCRIPTION: |
| * Obtain NAND ECC mode |
| * |
| * INPUT: |
| * None. |
| * |
| * OUTPUT: |
| * None. |
| * |
| * RETURN: |
| * MV_NFC_ECC_MODE type |
| * |
| *******************************************************************************/ |
| MV_NFC_ECC_MODE mvBoardNandECCModeGet() |
| { |
| #if defined(MV_NAND_4BIT_MODE) |
| return MV_NFC_ECC_BCH_2K; |
| #elif defined(MV_NAND_8BIT_MODE) |
| return MV_NFC_ECC_BCH_1K; |
| #elif defined(MV_NAND_12BIT_MODE) |
| return MV_NFC_ECC_BCH_704B; |
| #elif defined(MV_NAND_16BIT_MODE) |
| return MV_NFC_ECC_BCH_512B; |
| #else |
| return MV_NFC_ECC_DISABLE; |
| #endif |
| } |
| |
| MV_NAND_IF_MODE mvBoardNandIfGet() |
| { |
| MV_BOARD_BOOT_SRC boot_src = mvBoardBootDeviceGet(); |
| switch (boot_src) { |
| case MSAR_0_BOOT_NAND_NEW: |
| return NAND_IF_NFC; |
| case MSAR_0_BOOT_NAND_SPI: |
| #ifdef MV_NAND_SPI |
| return NAND_IF_SPI; |
| #else |
| mvOsPrintf("%s: Error: NAND_IF_SPI isn't defined while " \ |
| "MSAR configured to MSAR_0_BOOT_NAND_SPI\n", |
| __func__); |
| return NAND_IF_NONE; |
| #endif |
| default: |
| return board->nandIfMode; |
| } |
| } |