MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType, MV_PEX_HAL_DATA *halData) { MV_PEX_MODE pexMode; MV_U32 regVal; MV_U32 status; mvOsMemcpy(&pexHalData[pexIf], halData, sizeof(MV_PEX_HAL_DATA)); if (mvPexModeGet(pexIf, &pexMode) != MV_OK) { mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n", pexMode.pexType); return MV_ERROR; } if (pexMode.pexLinkUp == MV_FALSE) { /* interface detected no Link. */ return MV_NO_SUCH; } /* Check that required PEX type is the one set in reset time */ if (pexType != pexMode.pexType) { /* No Link. Shut down the Phy */ mvPexPhyPowerDown(pexIf); mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n", pexType, pexMode.pexType); return MV_ERROR; } if (MV_PEX_ROOT_COMPLEX == pexType) { mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf)); mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf)); /* Local device master Enable */ mvPexMasterEnable(pexIf, MV_TRUE); /* Local device slave Enable */ mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf), mvPexLocalDevNumGet(pexIf), MV_TRUE); /* Interrupt disable */ status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND)); status |= PXSAC_INT_DIS; MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status); } else { regVal = MV_REG_READ(PEX_DBG_CTRL_REG(pexIf)); regVal &= ~(BIT16 | BIT19); MV_REG_WRITE(PEX_DBG_CTRL_REG(pexIf), regVal); } return MV_OK; }
MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType, MV_PEX_HAL_DATA *halData) { MV_PEX_MODE pexMode; MV_U32 regVal; MV_U32 status; MV_U16 ctrlModel, phyRegVal; mvOsMemcpy(&pexHalData[pexIf], halData, sizeof(MV_PEX_HAL_DATA)); /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */ /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */ /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */ ctrlModel = pexHalData[pexIf].ctrlModel; if ((ctrlModel != MV_1281_DEV_ID) && (ctrlModel != MV_6281_DEV_ID) && (ctrlModel != MV_6282_DEV_ID) && (ctrlModel != MV_6280_DEV_ID) && (ctrlModel != MV_6192_DEV_ID) && (ctrlModel != MV_6190_DEV_ID) && (ctrlModel != MV_6180_DEV_ID) && (ctrlModel != MV_6183_DEV_ID) && (ctrlModel != MV_6183L_DEV_ID) && (ctrlModel != MV_78100_DEV_ID) && (ctrlModel != MV_78200_DEV_ID) && (ctrlModel != MV_76100_DEV_ID) && (ctrlModel != MV_6323_DEV_ID) && (ctrlModel != MV_6322_DEV_ID) && (ctrlModel != MV_6321_DEV_ID) && (ctrlModel != MV_78XX0_DEV_ID) && (ctrlModel != MV_6510_DEV_ID) && (ctrlModel != MV_6530_DEV_ID) && (ctrlModel != MV_6550_DEV_ID) && (ctrlModel != MV_6560_DEV_ID)) { /* Read current value of TXAMP */ MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), 0x80820000); /* Write the read command */ regVal = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf)); /* Extract the data */ /* Prepare new data for write */ regVal &= ~0x7; /* Clear bits [2:0] */ regVal |= 0x4; /* Set the new value */ regVal &= ~0x80000000; /* Set "write" command */ MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regVal); /* Write the write command */ } else { /* Implement 1.0V termination GL for 88F1281 device only */ /* BIT0 - Common mode feedback */ /* BIT3 - TxBuf, extra drive for 1.0V termination */ if (ctrlModel == MV_1281_DEV_ID) { MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), 0x80860000); /* Write the read command */ regVal = MV_REG_READ(0x41b00); /* Extract the data */ regVal |= (BIT0 | BIT3); regVal &= ~0x80000000; /* Set "write" command */ MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regVal); /* Write the write command */ MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */ regVal = MV_REG_READ(0x31b00); /* Extract the data */ regVal |= (BIT0 | BIT3); regVal &= ~0x80000000; /* Set "write" command */ MV_REG_WRITE(0x31b00, regVal); /* Write the write command */ } } if ((ctrlModel == MV_6281_DEV_ID) || (ctrlModel == MV_6282_DEV_ID) || (ctrlModel == MV_6280_DEV_ID) || (ctrlModel == MV_6192_DEV_ID) || (ctrlModel == MV_6190_DEV_ID) || (ctrlModel == MV_6180_DEV_ID)) { regVal = MV_REG_READ(0x100e4); /* This register currently doesn't appear in the FS */ regVal |= 0x3 << 25; MV_REG_WRITE(0x100e4, regVal); } if (ctrlModel == MV_6282_DEV_ID) { mvPexPhyRegRead(pexIf, 0x92, &phyRegVal); phyRegVal &= ~(0x80F0); phyRegVal |= 0x8080; mvPexPhyRegWrite(pexIf, 0x92, phyRegVal); } else if ((ctrlModel == MV_6510_DEV_ID) || (ctrlModel == MV_6530_DEV_ID) || (ctrlModel == MV_6550_DEV_ID) || (ctrlModel == MV_6560_DEV_ID)) { mvPexPhyRegRead(pexIf, 0x92, &phyRegVal); phyRegVal &= ~(0x80F0); phyRegVal |= 0x8080; mvPexPhyRegWrite(pexIf, 0x92, phyRegVal); } if (mvPexModeGet(pexIf, &pexMode) != MV_OK) { mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n", pexMode.pexType); return MV_ERROR; } /* Check that required PEX type is the one set in reset time */ if (pexType != pexMode.pexType) { /* No Link. Shut down the Phy */ mvPexPhyPowerDown(pexIf); mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n", pexType, pexMode.pexType); return MV_ERROR; } if (MV_PEX_ROOT_COMPLEX == pexType) { mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf)); mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf)); /* Local device master Enable */ mvPexMasterEnable(pexIf, MV_TRUE); /* Local device slave Enable */ mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf), mvPexLocalDevNumGet(pexIf), MV_TRUE); /* Interrupt disable */ status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND)); status |= PXSAC_INT_DIS; MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status); } mvSysPexCpuIfEnable(pexIf); /* now wait 500 ms to be sure the link is valid (spec compliant) */ mvOsDelay(500); /* Check if we have link */ if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN) { mvOsPrintf("PEX%d interface detected no Link.\n", pexIf); return MV_NO_SUCH; } if (MV_PEX_WITDH_X1 == pexMode.pexWidth) mvOsPrintf("PEX%d interface detected Link X1\n", pexIf); else mvOsPrintf("PEX%d interface detected Link X4\n", pexIf); #ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT mvPexVrtBrgInit(pexIf); #endif return MV_OK; }