/******************************************************************************* * mvPciSlaveEnable - Enable/disale PCI interface slave transactions. * * DESCRIPTION: * This function performs read modified write to PCI command status * (offset 0x4) to set/reset bit 0 and 1. After those bits are set, * the PCI slave is allowed to respond to PCI IO space access (bit 0) * and PCI memory space access (bit 1). * * INPUT: * pciIf - PCI interface number. * dev - PCI device number. * enable - Enable/disable parameter. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK * *******************************************************************************/ MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev, enable); #else return MV_OK; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev, enable); #else return MV_OK; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf); } return MV_FAIL; }
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 mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType) { MV_PEX_MODE pexMode; MV_U32 regVal; MV_U32 status; /* 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 */ if ((mvCtrlModelGet() != MV_1281_DEV_ID) && (mvCtrlModelGet() != MV_6281_DEV_ID) && (mvCtrlModelGet() != MV_6192_DEV_ID) && (mvCtrlModelGet() != MV_6190_DEV_ID) && (mvCtrlModelGet() != MV_6180_DEV_ID) && (mvCtrlModelGet() != MV_6183_DEV_ID) && (mvCtrlModelGet() != MV_6183L_DEV_ID) && (mvCtrlModelGet() != MV_78100_DEV_ID) && (mvCtrlModelGet() != MV_78200_DEV_ID) && (mvCtrlModelGet() != MV_76100_DEV_ID) && (mvCtrlModelGet() != MV_78XX0_DEV_ID)) { /* Read current value of TXAMP */ MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */ regVal = MV_REG_READ(0x41b00); /* 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(0x41b00, 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 (mvCtrlModelGet() == MV_1281_DEV_ID) { MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */ regVal = MV_REG_READ(0x41b00); /* Extract the data */ regVal |= (BIT0 | BIT3); regVal &= ~0x80000000; /* Set "write" command */ MV_REG_WRITE(0x41b00, 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( 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 */ mvPexPowerDown(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); } /* 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; }
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) && (ctrlModel != MV_6710_DEV_ID) && (ctrlModel != MV_78130_DEV_ID) && (ctrlModel != MV_78160_DEV_ID) && (ctrlModel != MV_78230_DEV_ID) && (ctrlModel != MV_78260_DEV_ID) && (ctrlModel != MV_78460_DEV_ID) && (ctrlModel != MV_78000_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)) { regVal = MV_REG_READ(0x100e4); /* This register currently doesn't appear in the FS */ regVal |= 0x3 << 25; MV_REG_WRITE(0x100e4, regVal); 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); if (ctrlModel == MV_6710_DEV_ID) { /* PEX capability */ regVal = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CAPABILITY_REG)) & 0xF; if (regVal == 0x2) { /* KW40 set to Gen 2.0 - conf_auto_speed_change */ /* when bit is set, link will issue link speed change to the max link speed possible */ regVal = MV_REG_READ(PEX_CTRL_REG(pexIf)) | (1<<10); MV_REG_WRITE(PEX_CTRL_REG(pexIf), regVal); } } } else { /* TODO: 14/12/10 - requested by CV to support EP Compliance */ MV_REG_WRITE(PEX_DBG_CTRL_REG(pexIf), 0x0F62F0C0); MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), (0x80C2 << 16)); regVal = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf)) & 0xFFFF; MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), (0xC2 << 16) | regVal | (1 << 2)); MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), (0x8080 << 16)); regVal = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf)) & 0xFFFF; MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), (0x80 << 16) | regVal | (0x2 << 1)); } mvSysPexCpuIfEnable(pexIf); /* now wait 1ms to be sure the link is valid */ mvOsDelay(100); /* 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 0 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); #endif #ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT mvPexVrtBrgInit(pexIf); #endif return MV_OK; }