/******************************************************************************* * mvPciLocalDevNumGet - Get PCI interface local device number. * * DESCRIPTION: * This function gets the local device number of a given PCI interface. * * INPUT: * pciIf - PCI interface number. * * OUTPUT: * None. * * RETURN: * Local device number. 0xffffffff on Error * *******************************************************************************/ MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF); #else return 0xFFFFFFFF; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF); #else return 0xFFFFFFFF; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf); } return 0; }
/******************************************************************************* * 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; }
/******************************************************************************* * mvPciLocalBusNumSet - Set PCI interface local bus number. * * DESCRIPTION: * This function sets given PCI interface its local bus number. * Note: In case the PCI interface is PCI-X, the information is read-only. * * INPUT: * pciIf - PCI interface number. * busNum - Bus number. * * OUTPUT: * None. * * RETURN: * MV_NOT_ALLOWED in case PCI interface is PCI-X. * MV_BAD_PARAM on bad parameters , * otherwise MV_OK * *******************************************************************************/ MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF, busNum); #else return MV_OK; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF, busNum); #else return MV_OK; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf); } return MV_FAIL; }
/******************************************************************************* * mvPciIfTypeGet - * * DESCRIPTION: * * INPUT: * * OUTPUT: * None. * * RETURN: * *******************************************************************************/ MV_U32 mvPciRealIfNumGet(MV_U32 pciIf) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) return (pciIf - MV_PCI_START_IF); else if (PCI_IF_TYPE_PEX == pciIfType) return (pciIf - MV_PEX_START_IF); else mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __func__, pciIf); return 0xffffffff; }
/******************************************************************************* * mvPciInit - Initialize PCI interfaces * * DESCRIPTION: * * INPUT: * None * * OUTPUT: * None * * RETURN: * MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM * *******************************************************************************/ MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) MV_PCI_MOD pciMod; if (PCI_IF_MODE_HOST == pciIfmode) { pciMod = MV_PCI_MOD_HOST; } else if (PCI_IF_MODE_DEVICE == pciIfmode) { pciMod = MV_PCI_MOD_DEVICE; } else { mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n", __func__, pciIf, pciIfmode); return MV_FAIL; } return mvPciInit(pciIf - MV_PCI_START_IF, pciMod); #else return MV_OK; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) MV_PEX_TYPE pexType; if (PCI_IF_MODE_HOST == pciIfmode) { pexType = MV_PEX_ROOT_COMPLEX; } else if (PCI_IF_MODE_DEVICE == pciIfmode) { pexType = MV_PEX_END_POINT; } else { mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" " end point\n", __func__, pciIf, pciIfmode); return MV_FAIL; } return mvSysPexInit(pciIf - MV_PEX_START_IF, pexType); #else return MV_OK; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __func__, pciIf); } return MV_FAIL; }
/******************************************************************************* * mvPciConfigWrite - Write to configuration space * * DESCRIPTION: * This function performs a 32 bit write to PCI configuration space. * It supports both type 0 and type 1 of Configuration Transactions * (local and over bridge). In order to write to local bus segment, use * bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers * will result configuration transaction of type 1 (over bridge). * * INPUT: * pciIf - PCI interface number. * bus - PCI segment bus number. * dev - PCI device number. * func - Function number. * regOffs - Register offset. * data - 32bit data. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK * *******************************************************************************/ MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func, MV_U32 regOff, MV_U32 data) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciConfigWrite(pciIf - MV_PCI_START_IF, bus, dev, func, regOff, data); #else return MV_OK; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexConfigWrite(pciIf - MV_PEX_START_IF, bus, dev, func, regOff, data); #else return MV_OK; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf); } return MV_FAIL; }
/******************************************************************************* * mvPciMasterEnable - Enable/disale PCI interface master transactions. * * DESCRIPTION: * This function performs read modified write to PCI command status * (offset 0x4) to set/reset bit 2. After this bit is set, the PCI * master is allowed to gain ownership on the bus, otherwise it is * incapable to do so. * * INPUT: * pciIf - PCI interface number. * enable - Enable/disable parameter. * * OUTPUT: * None. * * RETURN: * MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK * *******************************************************************************/ MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciMasterEnable(pciIf - MV_PCI_START_IF, enable); #else return MV_OK; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexMasterEnable(pciIf - MV_PEX_START_IF, enable); #else return MV_OK; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __func__, pciIf); } return MV_FAIL; }
/******************************************************************************* * mvPciConfigRead - Read from configuration space * * DESCRIPTION: * This function performs a 32 bit read from PCI configuration space. * It supports both type 0 and type 1 of Configuration Transactions * (local and over bridge). In order to read from local bus segment, use * bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers * will result configuration transaction of type 1 (over bridge). * * INPUT: * pciIf - PCI interface number. * bus - PCI segment bus number. * dev - PCI device number. * func - Function number. * regOffs - Register offset. * * OUTPUT: * None. * * RETURN: * 32bit register data, 0xffffffff on error * *******************************************************************************/ MV_U32 mvPciIfConfigRead(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func, MV_U32 regOff) { PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf); if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType) { #if defined(MV_INCLUDE_PCI) return mvPciConfigRead(pciIf - MV_PCI_START_IF, bus, dev, func, regOff); #else return 0xffffffff; #endif } else if (PCI_IF_TYPE_PEX == pciIfType) { #if defined(MV_INCLUDE_PEX) return mvPexConfigRead(pciIf - MV_PEX_START_IF, bus, dev, func, regOff); #else return 0xffffffff; #endif } else { mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __func__, pciIf); } return 0; }
static MV_STATUS pciDetectDevice(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func, MV_PCI_DEVICE *pPciAgent) { MV_U32 pciData; /* MV_U32 detectedBar=0; */ /* barIndex,MV_U32 tmpBaseHigh,tmpBaseLow; */ /* no Parameters checking ! because it is static function and it is assumed that all parameters were checked in the calling function */ /* Try read the PCI Vendor ID and Device ID */ /* We will scan only ourselves and the PCI slots that exist on the board, because we may have a case that we have one slot that has a Cardbus connector, and because CardBus answers all IDsels we want to scan only this slot and ourseleves. */ if (PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) { MV_U32 localBus,localDev, firstSlotDevNum,slotsNum; slotsNum = mvBoardPciSlotsNumGet(mvPciRealIfNumGet(pciIf)); firstSlotDevNum= mvBoardFirstPciSlotDevNumGet(mvPciRealIfNumGet(pciIf)); localDev = mvPciIfLocalDevNumGet(pciIf); localBus = mvPciIfLocalBusNumGet(pciIf); if (bus == localBus) { if (!(((dev >= firstSlotDevNum) && (dev < firstSlotDevNum + slotsNum))|| (dev == localDev))) { return MV_ERROR; } } } pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID); if (PCI_ERROR_CODE == pciData) { /* no device exist */ return MV_ERROR; } /* we are here ! means a device is detected */ /* fill basic information */ pPciAgent->busNumber=bus; pPciAgent->deviceNum=dev; pPciAgent->function=func; /* Fill the PCI Vendor ID and Device ID */ pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS; pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS; /* Read Status and command */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_STATUS_AND_COMMAND); /* Fill related Status and Command information*/ if (pciData & PSCR_TAR_FAST_BB) { pPciAgent->isFastB2BCapable = MV_TRUE; } else { pPciAgent->isFastB2BCapable = MV_FALSE; } if (pciData & PSCR_CAP_LIST) { pPciAgent->isCapListSupport=MV_TRUE; } else { pPciAgent->isCapListSupport=MV_FALSE; } if (pciData & PSCR_66MHZ_EN) { pPciAgent->is66MHZCapable=MV_TRUE; } else { pPciAgent->is66MHZCapable=MV_FALSE; } /* Read Class Code and Revision */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_CLASS_CODE_AND_REVISION_ID); pPciAgent->baseClassCode = (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS; pPciAgent->subClassCode = (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS; pPciAgent->progIf = (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS; pPciAgent->revisionID = (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS; /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE); pPciAgent->pciCacheLine= (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS; pPciAgent->pciLatencyTimer= (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS; switch (pciData & PBHTLTCLR_HEADER_MASK) { case PBHTLTCLR_HEADER_STANDARD: pPciAgent->pciHeader=MV_PCI_STANDARD; break; case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE: pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE; break; } if (pciData & PBHTLTCLR_MULTI_FUNC) { pPciAgent->isMultiFunction=MV_TRUE; } else { pPciAgent->isMultiFunction=MV_FALSE; } if (pciData & PBHTLTCLR_BISTCAP) { pPciAgent->isBISTCapable=MV_TRUE; } else { pPciAgent->isBISTCapable=MV_FALSE; } /* read this device pci bars */ pciDetectDeviceBars(pciIf, bus,dev,func, pPciAgent); /* check if we are bridge*/ if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&& (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE)) { /* Read P2P_BUSSES_NUM */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_BUSSES_NUM); pPciAgent->p2pPrimBusNum = (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS; pPciAgent->p2pSecBusNum = (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS; pPciAgent->p2pSubBusNum = (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS; pPciAgent->p2pSecLatencyTimer = (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS; /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_IO_BASE_LIMIT_SEC_STATUS); pPciAgent->p2pSecStatus = (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS; pPciAgent->p2pIObase = (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS; /* clear low address (should be zero)*/ pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK; pPciAgent->p2pIOLimit = (pciData & PIBLSS_IO_LIMIT_MASK); /* fill low address with 0xfff */ pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK; switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS) { case PIBLSS_ADD_CAP_16BIT: pPciAgent->bIO32 = MV_FALSE; break; case PIBLSS_ADD_CAP_32BIT: pPciAgent->bIO32 = MV_TRUE; /* Read P2P_IO_BASE_LIMIT_UPPER_16 */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_IO_BASE_LIMIT_UPPER_16); pPciAgent->p2pIObase |= (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS; pPciAgent->p2pIOLimit |= (pciData & PRBU_IO_UPP_LIMIT_MASK); break; } /* Read P2P_MEM_BASE_LIMIT */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_MEM_BASE_LIMIT); pPciAgent->p2pMemBase = (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS; /* clear low address */ pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK; pPciAgent->p2pMemLimit = (pciData & PMBL_MEM_LIMIT_MASK); /* add 0xfffff */ pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK; /* Read P2P_PREF_MEM_BASE_LIMIT */ pciData = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_PREF_MEM_BASE_LIMIT); pPciAgent->p2pPrefMemBase = (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS; /* get high address only */ pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK; pPciAgent->p2pPrefMemLimit = (pciData & PRMBL_PREF_MEM_LIMIT_MASK); /* add 0xfffff */ pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK; switch (pciData & PRMBL_ADD_CAP_MASK) { case PRMBL_ADD_CAP_32BIT: pPciAgent->bPrefMem64 = MV_FALSE; /* Read P2P_PREF_BASE_UPPER_32 */ pPciAgent->p2pPrefBaseUpper32Bits = 0; /* Read P2P_PREF_LIMIT_UPPER_32 */ pPciAgent->p2pPrefLimitUpper32Bits = 0; break; case PRMBL_ADD_CAP_64BIT: pPciAgent->bPrefMem64 = MV_TRUE; /* Read P2P_PREF_BASE_UPPER_32 */ pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_PREF_BASE_UPPER_32); /* Read P2P_PREF_LIMIT_UPPER_32 */ pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf, bus,dev,func, P2P_PREF_LIMIT_UPPER_32); break; } }