| /******************************************************************************* |
| 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 "mvBoardEnvSpec.h" |
| #include "mvBoardEnvLib.h" |
| #include "mv_phy.h" |
| #include "ctrlEnv/mvCtrlEnvRegs.h" |
| #ifdef CONFIG_ARMADA_39X |
| #include "ctrlEnv/mvCtrlNetCompLib.h" |
| #endif |
| #if defined(MV_ETH_NETA) |
| #include "neta/gbe/mvEthRegs.h" |
| #include "neta/gbe/mvNeta.h" |
| #elif defined (MV_ETH_PP2) |
| #include "pp2/gmac/mvEthGmacRegs.h" |
| #include "pp2/gmac/mvEthGmacApi.h" |
| #include "ctrlEnv/mvCtrlEthCompLib.h" |
| #else |
| #include "eth/gbe/mvEthRegs.h" |
| #endif |
| #include "mvSysEthPhyApi.h" |
| #include "ethSwitch/mvSwitchRegs.h" |
| #include "ethSwitch/mvSwitch.h" |
| |
| #if defined (MV88F66XX) |
| static void mvAlpBoardEgigaPhyInit(MV_BOOL mv_eeeEnable) |
| { |
| MV_U32 ethComplex = mvBoardEthComplexConfigGet(); |
| |
| /* Set SMI control to CPU, before initializing PHY */ |
| mvCtrlSmiMasterSet(CPU_SMI_CTRL); |
| |
| /* Init PHY connected to MAC0 */ |
| if (ethComplex & (MV_ETHCOMP_GE_MAC0_2_RGMII0 | |
| MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0)) |
| mvEthPhyInit(0, mv_eeeEnable); |
| |
| /* Initialize PHY through MAC0, even though that PHY is not connected |
| * to MAC1. This external PHY is connected to the switch, but the |
| * external SMI control is granted to the CPU, and that why MAC0 is |
| * initializing this PHY, even though it's connected to the switch */ |
| if (ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY) |
| mvEthPhyInit(0, mv_eeeEnable); |
| |
| /* Init PHY connected to MAC1 */ |
| if (ethComplex & (MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3 | MV_ETHCOMP_GE_MAC1_2_RGMII0)) |
| mvEthPhyInit(1, mv_eeeEnable); |
| |
| /* if MAC-1 is connected to RGMII-1 or PON serdes via SGMII, |
| * and SW_P4 is not connected RGMII-0, |
| * and MAC-1 is not connected to PON serdes via SFP, no need to init the PHY */ |
| if ((ethComplex & (MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES)) && |
| !(ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY) && |
| !(ethComplex & MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP)) { |
| |
| /* enable external phy cpu ctrl - MAC1 is polling this phy */ |
| mvBoardExtPhyBufferSelect(MV_TRUE); |
| |
| mvEthPhyInit(1, MV_FALSE); |
| |
| } |
| |
| #if 0 /* the following configurations were not fully implemented yet */ |
| /* if Switch is connected to RGMII-0, it has to auto-poll the phy */ |
| if (ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0) { |
| mvCtrlSmiMasterSet(SWITCH_SMI_CTRL); |
| /* disable external phy cpu ctrl - Switch is SMI master */ |
| mvBoardExtPhyBufferSelect(MV_FALSE); |
| |
| /* implement differentiation between internal Phy#1 to external Phy#1 |
| * Solve phy address conflicts */ |
| } |
| |
| /* |
| * Due to phy address 0x1 conflict, the following configurations demands : |
| * 1. 'Disconnect' quad phy 0x1 from switch (EthComplex connectivity) |
| * 2. Enable SMI Switch control, using mvCtrlSmiMasterSet(SWITCH_SMI_CTRL); |
| * 3. use mvBoardExtPhyBufferSelect(MV_FALSE); to toggle external phy buffer limit |
| */ |
| |
| /* if SW_P4 is connected RGMII-0 && MAC-1 is NOT connected to RGMII-1 */ |
| /* |
| if ((ethComplex & MV_ETHCOMP_SW_P4_2_RGMII0) && |
| !(ethComplex & MV_ETHCOMP_GE_MAC1_2_RGMII1 )) { |
| mvEthPhyInit(???, MV_FALSE); |
| */ |
| |
| /* if SW_P4 is connected RGMII-0 && MAC-1 is connected to RGMII-1 */ |
| /* |
| * if (ethComplex & (MV_ETHCOMP_GE_MAC1_2_RGMII1 | |
| MV_ETHCOMP_SW_P4_2_RGMII0)) { |
| */ |
| #endif |
| } |
| #endif /* MV88F66XX */ |
| |
| #if defined (MV88F66XX) || defined (MV88F672X) |
| void mvBoardPhyShutDown(MV_U16 phyAddr) |
| { |
| MV_U16 phyRegData; |
| |
| /* Set GE-PHY SMI source as CPU MAC (CPU is shutting down the PHY) */ |
| mvEthComplexGphyPortSmiSrcSet(phyAddr, 0); |
| |
| mvEthPhyRegRead(phyAddr, 0x0, &phyRegData); |
| mvEthPhyRegWrite(phyAddr, 0x0, phyRegData | BIT11); |
| mvEthPhyRegRead(phyAddr, 0x10, &phyRegData); |
| mvEthPhyRegWrite(phyAddr, 0x10, phyRegData | BIT2); |
| |
| /* set GE-PHY SMI source as switch |
| * (avoid future conflicts when CPU access external PHYs with same SMI address) */ |
| mvEthComplexGphyPortSmiSrcSet(phyAddr, 1); |
| } |
| |
| void mvBoardLedMatrixPhyInit(MV_U16 smiAddr, MV_BOOL internalPhy) |
| { |
| MV_U16 value = (internalPhy == MV_TRUE ? 0x1791 : 0x1771); |
| |
| mvEthPhyRegWrite(smiAddr, 0x16, 0x3); |
| mvOsDelay(10); |
| mvEthPhyRegWrite(smiAddr, 0x10, value); |
| mvOsDelay(10); |
| mvEthPhyRegWrite(smiAddr, 0x11, 0x8801); |
| mvOsDelay(10); |
| mvEthPhyRegWrite(smiAddr, 0x16, 0x0); |
| mvOsDelay(10); |
| } |
| |
| /******************************************************************************* |
| * switchPhyRegWrite 0 0 16 0 - Initialize LEDS Matrix |
| *******************************************************************************/ |
| void mvBoardLedMatrixInit(void) |
| { |
| #ifdef MV_INCLUDE_SWITCH |
| MV_U8 i; |
| #endif |
| |
| if (mvCtrlDevFamilyIdGet(0) == MV_88F67X0) |
| /* Led matrix mode in 7Bit */ |
| MV_REG_WRITE(LED_MATRIX_CONTROL_REG(0), BIT0 | BIT1); |
| else { |
| /* Led matrix mode in 12Bit */ |
| /* Enable Matrix, Set Mode B signals assignment, invert C1-C3 in Matrix*/ |
| MV_REG_WRITE(LED_MATRIX_CONTROL_REG(0), BIT0 | BIT2 | BIT5); |
| /* initialize LEDS general configuration */ |
| MV_REG_WRITE(LED_MATRIX_CONTROL_REG(1), 0x2db6db6d); |
| /* Use an internal device signal to drive the LED Matrix Control */ |
| MV_REG_WRITE(LED_MATRIX_CONTROL_REG(2), BIT0 | BIT2 | BIT3 | BIT5); |
| |
| #ifdef MV_INCLUDE_SWITCH |
| /* initialize internal PHYs controlled by switch */ |
| if (mvBoardIsInternalSwitchConnected() == MV_TRUE) { |
| for (i = 0; i < 4; i++) { |
| mvOsDelay(10); |
| mvEthSwitchPhyRegWrite(0x0, i, 0x16, 0x3); |
| mvOsDelay(10); |
| mvEthSwitchPhyRegWrite(0x0, i, 0x10, 0x1791); |
| mvOsDelay(10); |
| mvEthSwitchPhyRegWrite(0x0, i, 0x11, 0x8801); |
| mvOsDelay(10); |
| mvEthSwitchPhyRegWrite(0x0, i, 0x16, 0x0); |
| } |
| } |
| #endif |
| } |
| |
| /* initialize External RGMII-0 PHY (SMI controlled by MAC0 @address 0x1) */ |
| if(mvBoardEthComplexConfigGet() & MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY) |
| mvBoardLedMatrixPhyInit(0x1, MV_FALSE); |
| if(mvBoardEthComplexConfigGet() & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0) |
| mvBoardLedMatrixPhyInit(0x0, MV_TRUE); |
| if(mvBoardEthComplexConfigGet() & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3) |
| mvBoardLedMatrixPhyInit(0x3, MV_TRUE); |
| |
| } |
| |
| #endif /* MV88F66XX || MV88F672X*/ |
| |
| /*********************************************************** |
| * Init the 10G PHY of the board * |
| ***********************************************************/ |
| MV_STATUS mvBoard10GPhyInit(MV_U32 port) |
| { |
| #ifdef CONFIG_MV_ETH_10G |
| MV_U32 portType; |
| |
| portType = mvBoardPortTypeGet(port); |
| if ((portType == MV_PORT_TYPE_RXAUI) || (portType == MV_PORT_TYPE_XAUI)) { |
| mvNetComplexNssSelect(1); |
| if (MV_ERROR == mvEth10gPhyInit(port, MV_FALSE)) { |
| mvNetComplexNssSelect(0); |
| mvCtrlPwrClckSet(ETH_GIG_UNIT_ID, port, MV_FALSE); |
| mvOsPrintf("PHY error - Failed to initialize 10G PHY (port %d).\n", port); |
| return MV_FAIL; |
| } |
| mvNetComplexNssSelect(0); |
| return MV_OK; |
| } |
| if (portType == MV_PORT_TYPE_SGMII) { |
| if (mvBoardPhyNegotiationTypeGet(port) == XSMI) { |
| /* |
| * writing to the xsmi registers is not done directly |
| * it's done through a certain a window, so it requires having the |
| * window obtained, otherwise the writes would go to waste, |
| * obtaining the window is done through selecting the NSS. |
| */ |
| mvNetComplexNssSelect(1); |
| initSgmiiMode(port, SGMII_1G_1G_MODE); |
| mvNetComplexNssSelect(0); |
| return MV_OK; |
| } |
| } |
| #endif /* CONFIG_MV_ETH_10G */ |
| return MV_NOT_SUPPORTED; |
| } |
| |
| /*********************************************************** |
| * Init the PHY of the board * |
| ***********************************************************/ |
| void mvBoardEgigaPhyInit(void) |
| { |
| |
| /* Prepare HAL data information */ |
| mvSysEthPhyInit(); |
| #if defined(CONFIG_MV_ETH_10G) && defined(CONFIG_MV_XSMI) |
| mvSysEth10gPhyInit(); |
| #endif |
| |
| #if defined(MV_ETH_NETA) |
| int i; |
| MV_STATUS status; |
| MV_U32 phyAddr; |
| #ifdef MV_INCLUDE_SWITCH |
| MV_U16 switchDeviceID; |
| #endif |
| |
| for (i = 0; i < mvCtrlEthMaxPortGet(); i++) { |
| if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, i)) |
| continue; |
| if (MV_FALSE == mvBoardIsGbEPortConnected(i)) |
| continue; |
| phyAddr = mvBoardPhyAddrGet(i); |
| if (phyAddr != -1) { |
| /* writing the PHY address before PHY init */ |
| mvNetaPhyAddrSet(i, phyAddr); |
| /* Initiaze 10G PHYs */ |
| status = mvBoard10GPhyInit(i); |
| if (status == MV_OK) |
| continue; |
| if ((status != MV_OK) && (status != MV_NOT_SUPPORTED)) { |
| mvCtrlPwrClckSet(ETH_GIG_UNIT_ID, i, MV_FALSE); |
| mvOsOutput("PHY error - shutdown port%d\n", i); |
| } else if (MV_ERROR == mvEthPhyInit(i, MV_FALSE)) { |
| mvNetaPhyAddrPollingDisable(i); |
| mvCtrlPwrClckSet(ETH_GIG_UNIT_ID, i, MV_FALSE); |
| mvOsOutput("PHY error - shutdown port%d\n", i); |
| } else if (mvBoardIsPortInMii(i)) { |
| /* if port is MII the speed is les the 1Gbps need too change the phy advertisment */ |
| mvEthPhyAdvertiseSet(phyAddr, MV_PHY_ADVERTISE_100_FULL); |
| /* after PHY advertisment change must reset PHY is needed*/ |
| status = mvEthPhyReset(phyAddr, 1000); |
| if (status != MV_OK) |
| mvOsPrintf("mvEthPhyReset(port=%d) failed: status=0x%x\n", i, status); |
| } |
| } else { |
| /* Inband PHY control - disable PHY polling */ |
| mvNetaPhyAddrPollingDisable(i); |
| } |
| } |
| |
| #ifdef MV_INCLUDE_SWITCH |
| switchDeviceID = mvEthSwitchGetDeviceID(); |
| if (mvBoardIsSwitchConnected()) { |
| switchDeviceID >>= QD_REG_SWITCH_ID_PRODUCT_NUM_OFFSET; |
| for (i = 0; i < mvCtrlEthMaxPortGet(); i++) { |
| /*force the switch connected eth port link up and disable auto-neg, bit 15 must set to 1*/ |
| if (mvBoardSwitchConnectedPortGet(i) != -1) |
| MV_REG_WRITE((NETA_GMAC_AN_CTRL_REG(i) + INTER_REGS_BASE), |
| (NETA_FORCE_LINK_PASS_MASK | NETA_SET_GMII_SPEED_1000_MASK | |
| NETA_SET_FLOW_CONTROL_MASK | NETA_FLOW_CONTROL_ADVERTISE_MASK | |
| NETA_SET_FULL_DUPLEX_MASK | BIT15)/*0x9342*/); |
| } |
| |
| /*now only E6172 switch works for NETA, so here no other switch initialization is called*/ |
| if (switchDeviceID == MV_E6172_PRODUCT_NUM) |
| mvEthE6172SwitchBasicInit(0); |
| if (switchDeviceID == MV_E6176_PRODUCT_NUM) |
| mvEthE6171SwitchBasicInit(0); |
| } |
| #endif |
| |
| #elif defined (MV88F66XX) /* Avanta-LP: dynamic PPv2 configuration */ |
| MV_U32 ethComplex = mvBoardEthComplexConfigGet(); |
| char *eeeEnable = NULL; |
| MV_BOOL mv_eeeEnable = MV_FALSE; |
| |
| eeeEnable = getenv("eeeEnable"); |
| if (eeeEnable && ((strcmp(eeeEnable, "yes") == 0) || (strcmp(eeeEnable, "Yes") == 0))) |
| mv_eeeEnable = MV_TRUE; |
| |
| /* Init PHYs according to eth. complex configuration */ |
| if (ethComplex & (MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0 | MV_ETHCOMP_GE_MAC0_2_RGMII0 | |
| MV_ETHCOMP_GE_MAC0_2_COMPHY_1 | MV_ETHCOMP_GE_MAC0_2_COMPHY_2 | |
| MV_ETHCOMP_GE_MAC0_2_COMPHY_3 | MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3 | |
| MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES | |
| MV_ETHCOMP_GE_MAC1_2_RGMII0 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES_SFP | |
| MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY)) |
| mvAlpBoardEgigaPhyInit(mv_eeeEnable); |
| |
| if (mvBoardIsInternalSwitchConnected() == MV_TRUE) { |
| mvAlpBoardSwitchBasicInit(mvBoardSwitchPortsMaskGet(0)); |
| mvEthInternalQuadGEPhyBasicInit(mv_eeeEnable); |
| } |
| |
| /* Close unnecessary internal phys */ |
| if(!(ethComplex & (MV_ETHCOMP_SW_P0_2_GE_PHY_P0 | MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0))) |
| mvBoardPhyShutDown(0x0); |
| /* Shutdown GE-PHY#1: |
| * 1. RGMII-1 enabled & GE-PHY#1 disabled (both use same SMI address = 0x1) |
| - set NO external SMI (to avoid mismatch when accessing SMI address 0x1) |
| - shutdown GE-PHY#1 (CPU SMI access) |
| - restore external SMI to CPU control */ |
| if((!(ethComplex & MV_ETHCOMP_SW_P1_2_GE_PHY_P1)) && (ethComplex & MV_ETHCOMP_GE_MAC1_2_RGMII1)) { |
| mvCtrlSmiMasterSet(NO_SMI_CTRL); |
| mvBoardPhyShutDown(0x1); |
| udelay(30); |
| mvCtrlSmiMasterSet(CPU_SMI_CTRL); |
| } |
| /* 2. RGMII-1/GE-PHY#1/PON Serdes is not connected |
| - shutdown GE-PHY#1 (CPU SMI access) */ |
| if(!(ethComplex & (MV_ETHCOMP_SW_P1_2_GE_PHY_P1 | MV_ETHCOMP_GE_MAC1_2_RGMII1 | MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES))) |
| mvBoardPhyShutDown(0x1); |
| if(!(ethComplex & MV_ETHCOMP_SW_P2_2_GE_PHY_P2)) |
| mvBoardPhyShutDown(0x2); |
| if(!(ethComplex & (MV_ETHCOMP_SW_P3_2_GE_PHY_P3 | MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3))) |
| mvBoardPhyShutDown(0x3); |
| |
| mvBoardLedMatrixInit(); |
| |
| /* Disable external SMI control: |
| * If NO external RGMII/PHY are connected to CPU MACs */ |
| if (!(mvBoardEthComplexConfigGet() & (MV_ETHCOMP_GE_MAC0_2_RGMII0 | |
| MV_ETHCOMP_SW_P4_2_RGMII0_EXT_PHY | |
| MV_ETHCOMP_GE_MAC1_2_RGMII1 | |
| MV_ETHCOMP_GE_MAC1_2_RGMII0 | |
| MV_ETHCOMP_GE_MAC1_2_PON_ETH_SERDES))) |
| mvCtrlSmiMasterSet(NO_SMI_CTRL); |
| |
| #elif defined(MV88F672X) /* Armada-375: static PPv2 configuration */ |
| MV_U32 ethComplex = mvBoardEthComplexConfigGet(); |
| |
| /* Set external CPU SMI control */ |
| mvCtrlSmiMasterSet(CPU_SMI_CTRL); |
| |
| /* Init PHY connected to MAC0 */ |
| if (ethComplex & (MV_ETHCOMP_GE_MAC0_2_RGMII0 | MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0)) |
| mvEthPhyInit(0, MV_FALSE); |
| |
| /* Init PHY connected to MAC1 */ |
| if (ethComplex & (MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3 | MV_ETHCOMP_GE_MAC1_2_RGMII1)) |
| mvEthPhyInit(1, MV_FALSE); |
| |
| /* Shutdown GE-PHYs: |
| * - disable external CPU SMI control |
| * (avoid mismatch with equal SMI addresses between internal PHY and external RGMII PHY) |
| * - shutdown GE-PHY (CPU SMI access) |
| * - enable external CPU SMI control |
| */ |
| mvCtrlSmiMasterSet(NO_SMI_CTRL); |
| |
| if(!(ethComplex & MV_ETHCOMP_GE_MAC0_2_GE_PHY_P0)) |
| mvBoardPhyShutDown(0x0); |
| |
| /* Internal GE-PHY#1,2 are not used - close unnecessary internal phys */ |
| mvBoardPhyShutDown(0x1); |
| mvBoardPhyShutDown(0x2); |
| |
| if(!(ethComplex & MV_ETHCOMP_GE_MAC1_2_GE_PHY_P3)) |
| mvBoardPhyShutDown(0x3); |
| |
| /* Restore external CPU SMI control */ |
| udelay(30); |
| mvCtrlSmiMasterSet(CPU_SMI_CTRL); |
| |
| mvBoardLedMatrixInit(); |
| #endif |
| } |