Example #1
0
MV_STATUS mvPexBarGet(MV_U32 pexIf,
								MV_U32 barNum,
								MV_PEX_BAR *pAddrWin)
{
	/* check parameters */
	if(pexIf >= mvCtrlPexMaxIfGet())
	{
		mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
		return MV_BAD_PARAM;
	}

	if(barNum >= PEX_MAX_BARS)
	{
		mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
		return MV_BAD_PARAM;
	}

	/* read base low */
	pAddrWin->addrWin.baseLow = 
		MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));


	if (PEX_INTER_REGS_BAR == barNum)
	{
		pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
	}
	else
	{
		pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
	}


	/* read base high */
	pAddrWin->addrWin.baseHigh = 
		MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));


	/* Read bar size */
	if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
	{
		pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));

		/* check if enable or not */
		if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
		{
			pAddrWin->enable = MV_TRUE;
		}
		else
		{
			pAddrWin->enable = MV_FALSE;
		}
			
		/* now get the size */
		pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
		pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;

		pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
											   PXBCR_BAR_SIZE_ALIGNMENT);

	}
/*******************************************************************************
* mvPexIfEnable
*
* DESCRIPTION:
*	This function Enables PCI Express interface.
*
* INPUT:
*	pexIf		-  PEX interface number.
*	pexType		-  MV_PEX_ROOT_COMPLEX - root complex device
*			   MV_PEX_END_POINT - end point device
* OUTPUT:
*	None.
*
* RETURN:
*	None.
*
*******************************************************************************/
MV_VOID mvPexIfEnable(MV_U32 pexIf, MV_PEX_TYPE pexType)
{
	MV_U32 regVal;

/* NOTE: this was asked by CV, bit is reserved in the spec, but causing problems, disabling for now. */
	/* MV_REG_BIT_SET(PEX_CTRL_REG(pexIf), PXCR_AUTO_SPEED_CTRL_MASK); */

	/* Set pex mode incase S@R not exist */
	if (pexType == MV_PEX_END_POINT) {
		MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf), PXCR_DEV_TYPE_CTRL_MASK);
		/* Change pex mode in capability reg */
		MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_CAPABILITY_REG), BIT22);
		MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_CAPABILITY_REG), BIT20);

		regVal = MV_REG_READ(PEX_CAPABILITIES_REG(pexIf));
		regVal |= 0x00F00000;
		regVal &= ~(BIT23 | BIT22 | BIT21);
		MV_REG_WRITE(PEX_CAPABILITIES_REG(pexIf), regVal);
	} else {
		regVal = MV_REG_READ(PEX_CAPABILITIES_REG(pexIf));
		regVal |= 0x00F00000;
		regVal &= ~(BIT23 | BIT21 | BIT20);
		MV_REG_WRITE(PEX_CAPABILITIES_REG(pexIf), regVal);

		MV_REG_BIT_SET(PEX_CTRL_REG(pexIf), PXCR_DEV_TYPE_CTRL_MASK);
	}
	return;
}
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;
}
Example #4
0
/*******************************************************************************
* mvCpuIfEnablePex - Enable PCI Express.
*
* DESCRIPTION:
*	This function enables PCI Express access to the device address
*	space.
*
* INPUT:
*	pexIf - The PCI-E interface to enable.
*
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
MV_VOID mvCpuIfEnablePex(MV_U32 pexIf)
{
	MV_U32 reg;

	if (mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf) == MV_TRUE) {
		if (pexIf == 0) {
			reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0, PEX_LINK_CAPABILITY_REG));
			reg &= ~PXLC_MAX_LNK_SPEED_MASK;
			reg |= (0x1 << PXLC_MAX_LNK_SPEED_OFFS);
			MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(0, PEX_LINK_CAPABILITY_REG), reg);
		}

		/* CPU config register Pex enable */
		MV_REG_BIT_SET(CPU_CTRL_STAT_REG, CCSR_PCI_ACCESS_MASK(pexIf));
	}
}
Example #5
0
MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
{
	/* Set pex mode incase S@R not exist */
	if( pexType == MV_PEX_END_POINT)
	{
		MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
		/* Change pex mode in capability reg */
		MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
		MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);

	}
	else
	{	
		MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
	}

	/* CPU config register Pex enable */
	MV_REG_BIT_SET(CPU_CTRL_STAT_REG,(CCSR_PCI_ACCESS_MASK(pexIf)));
}
/*******************************************************************************
* mvPexMasterEnable - Enable/disale PEX interface master transactions.
*
* DESCRIPTION:
*       This function performs read modified write to PEX command status
*       (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
*       master is allowed to gain ownership on the bus, otherwise it is
*       incapable to do so.
*
* INPUT:
*       pexIf  - PEX interface number.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
*
*******************************************************************************/
MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
{
	MV_U32 pexCommandStatus;

	/* Parameter checking   */
	if (pexIf >= pexHalData[pexIf].maxPexIf) {
		mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
		return MV_ERROR;
	}

	pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));

	if (MV_TRUE == enable)
		pexCommandStatus |= PXSAC_MASTER_EN;
	else
		pexCommandStatus &= ~PXSAC_MASTER_EN;

	MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), pexCommandStatus);

	return MV_OK;
}
/*******************************************************************************
* mvPexActiveStateLinkPMEnable
*
* DESCRIPTION:
*	Enable Active Link State Power Management
*
* INPUT:
*	pexIf		- PEX interface number.
*	enable		- MV_TRUE to enable ASPM, MV_FALSE to disable.
*
* OUTPUT:
*	None
*
* RETURN:
*	MV_OK on success , MV_ERROR otherwise
*
*******************************************************************************/
MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
{
	MV_U32 reg;

	if (pexIf >= pexHalData[pexIf].maxPexIf) {
		mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
		return MV_ERROR;
	}

	reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
	if (enable == MV_TRUE)
		reg |= PXPMER_L1_ASPM_EN_MASK;
	MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);

	/* Enable / Disable L0/1 entry */
	reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
	      & ~PXLCSR_ASPM_CNT_MASK;
	if (enable == MV_TRUE)
		reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
	MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);

	return MV_OK;
}
Example #8
0
/*******************************************************************************
* mvPexModeGet - Get Pex Mode
*
* DESCRIPTION:
*
* INPUT:
*       pexIf   - PEX interface number.
*
* OUTPUT:
*       pexMode - Pex mode structure
*
* RETURN:
*       MV_OK on success , MV_ERROR otherwise
*
*******************************************************************************/
MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
{
	MV_U32 pexData;

	/* Parameter checking   */
	if (PEX_DEFAULT_IF != pexIf)
	{
		if (pexIf >= mvCtrlPexMaxIfGet())
		{
			mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
			return MV_ERROR;
		}
	}

	pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));

	switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
	{
	case PXCR_DEV_TYPE_CTRL_CMPLX:
		pexMode->pexType = MV_PEX_ROOT_COMPLEX;
		break;
	case PXCR_DEV_TYPE_CTRL_POINT:
		pexMode->pexType = MV_PEX_END_POINT;
		break;

	}

    /* Check if we have link */
    if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
    {
        pexMode->pexLinkUp = MV_FALSE;
        
        /* If there is no link, the auto negotiation data is worthless */
        pexMode->pexWidth  = MV_PEX_WITDH_INVALID;
    }   
    else
    {
        pexMode->pexLinkUp = MV_TRUE;

        /* We have link. The link width is now valid */
        pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
        pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >> 
                             PXLCSR_NEG_LNK_WDTH_OFFS);
    }

    return MV_OK;
}
Example #9
0
/*******************************************************************************
* mvPexModeGet - Get Pex Mode
*
* DESCRIPTION:
*
* INPUT:
*       pexIf   - PEX interface number.
*
* OUTPUT:
*       pexMode - Pex mode structure
*
* RETURN:
*       MV_OK on success , MV_ERROR otherwise
*
*******************************************************************************/
MV_U32 mvPexModeGet(MV_U32 pexIf, MV_PEX_MODE *pexMode)
{
	MV_U32 pexData;

	if (pexIf >= MV_PEX_MAX_IF)
		return MV_BAD_PARAM;
#if 0 /* maen - disabled because there is a conflict with SysPexInit
	sysPexInit need pexMode, however pexHalData[pexIf].maxPexIf is needed in mvPexModeGe */
      */
	/* Parameter checking   */
	if (PEX_DEFAULT_IF != pexIf) {
		if (pexIf >= pexHalData[pexIf].maxPexIf) {
			mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n", pexIf);
			return MV_ERROR;
		}
	}
#endif

	pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));

	switch (pexData & PXCR_DEV_TYPE_CTRL_MASK) {
	case PXCR_DEV_TYPE_CTRL_CMPLX:
		pexMode->pexType = MV_PEX_ROOT_COMPLEX;
		break;
	case PXCR_DEV_TYPE_CTRL_POINT:
		pexMode->pexType = MV_PEX_END_POINT;
		break;

	}

	/* Check if we have link */
	if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN) {
		pexMode->pexLinkUp = MV_FALSE;

		/* If there is no link, the auto negotiation data is worthless */
		pexMode->pexWidth = MV_PEX_WITDH_INVALID;
	} else {
		pexMode->pexLinkUp = MV_TRUE;

		/* We have link. The link width is now valid */
		pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
		pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >> PXLCSR_NEG_LNK_WDTH_OFFS);
	}

	return MV_OK;
}
Example #10
0
/*******************************************************************************
* mvPexModeGet - Get Pex Mode
*
* DESCRIPTION:
*
* INPUT:
*       pexIf   - PEX interface number.
*
* OUTPUT:
*       pexMode - Pex mode structure
*
* RETURN:
*       MV_OK on success , MV_ERROR otherwise
*
*******************************************************************************/
MV_U32 mvPexModeGet(MV_U32 pexIf, MV_PEX_MODE *pexMode)
{
	MV_U32 pexData;

	if (pexIf >= MV_PEX_MAX_IF)
		return MV_BAD_PARAM;

	
	pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));

	switch (pexData & PXCR_DEV_TYPE_CTRL_MASK) {
	case PXCR_DEV_TYPE_CTRL_CMPLX:
		pexMode->pexType = MV_PEX_ROOT_COMPLEX;
		break;
	case PXCR_DEV_TYPE_CTRL_POINT:
		pexMode->pexType = MV_PEX_END_POINT;
		break;

	}

	/* Check if we have link */
/*	if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN) { */

	if ((MV_REG_READ(PEX_DBG_STATUS_REG(pexIf)) & 0x7f) != 0x7E) {

		pexMode->pexLinkUp = MV_FALSE;

		/* If there is no link, the auto negotiation data is worthless */
		pexMode->pexWidth = MV_PEX_WITDH_INVALID;
	}
	else { /* We have Link negotiation started */
			pexMode->pexLinkUp = MV_TRUE;
		/* We have link. The link width is now valid */
		pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
		pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >> PXLCSR_NEG_LNK_WDTH_OFFS);
		pexMode->pexGen = ((pexData & PXLCSR_NEG_LNK_GEN_MASK) >> PXLCSR_NEG_LNK_GEN_OFFS);
	}

	return MV_OK;
}
Example #11
0
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;
}
Example #12
0
MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
                        MV_U32 regOff)
{
#endif
	MV_U32 pexData = 0;
	MV_U32	localDev,localBus;

	/* Parameter checking   */
	if (PEX_DEFAULT_IF != pexIf)
	{
		if (pexIf >= mvCtrlPexMaxIfGet())
		{
			mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
			return 0xFFFFFFFF;
		}
	}

	if (dev >= MAX_PEX_DEVICES)
	{
		DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
		return 0xFFFFFFFF;
	}
	
	if (func >= MAX_PEX_FUNCS)
	{
		DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
		return 0xFFFFFFFF;
	}
	
	if (bus >= MAX_PEX_BUSSES)
	{
		DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
		return MV_ERROR;
	}
    	     
    DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
                   pexIf, bus, dev, func, regOff));
	
	localDev = mvPexLocalDevNumGet(pexIf);
	localBus = mvPexLocalBusNumGet(pexIf);
                                     
    /* Speed up the process. In case on no link, return MV_ERROR */
    if ((dev != localDev) || (bus != localBus))
    {
        pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));

        if ((pexData & PXSR_DL_DOWN))
        {
            return MV_ERROR;
        }
    }

    /* in PCI Express we have only one device number */
	/* and this number is the first number we encounter 
	else that the localDev*/
	/* spec pex define return on config read/write on any device */
	if (bus == localBus)
	{
		if (localDev == 0)
		{
			/* if local dev is 0 then the first number we encounter 
			after 0 is 1 */
			if ((dev != 1)&&(dev != localDev))
			{
				return MV_ERROR;
			}	
		}
		else
		{
			/* if local dev is not 0 then the first number we encounter 
			is 0 */
	
			if ((dev != 0)&&(dev != localDev))
			{
				return MV_ERROR;
			}
		}
		if(func != 0 ) /* i.e bridge */
		{
			return MV_ERROR;
		}
	}
    
    
	/* Creating PEX address to be passed */
	pexData = (bus << PXCAR_BUS_NUM_OFFS);
	pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
	pexData |= (func << PXCAR_FUNC_NUM_OFFS);
	pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
	/* extended register space */
	pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> 
				PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);

	pexData |= PXCAR_CONFIG_EN; 
	
	/* Write the address to the PEX configuration address register */
	MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);

	DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
    
	
	/* In order to let the PEX controller absorbed the address of the read 	*/
	/* transaction we perform a validity check that the address was written */
	if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
	{
		return MV_ERROR;
	}

	/* cleaning Master Abort */
	MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND), 
				   PXSAC_MABORT);
#if 0
	/* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration   */
	/* This guideline is relevant for all devices except of the following devices:
	   88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
	   88F6183 A0 and above, 88F6183L  */
	if ( ( (dev != localDev) || (bus != localBus) ) && 
		(
		!(MV_5281_DEV_ID == mvCtrlModelGet())&&
		!((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
		!(MV_1281_DEV_ID == mvCtrlModelGet())&&
		!(MV_6183_DEV_ID == mvCtrlModelGet())&&
		!(MV_6183L_DEV_ID == mvCtrlModelGet())&&
		!(MV_6281_DEV_ID == mvCtrlModelGet())&&
		!(MV_6192_DEV_ID == mvCtrlModelGet())&&
		!(MV_6190_DEV_ID == mvCtrlModelGet())&&
        !(MV_6180_DEV_ID == mvCtrlModelGet())&& 
		!(MV_78XX0_DEV_ID == mvCtrlModelGet()) 
		))
	{

		/* PCI-Express configuration read work-around */

		/* we will use one of the Punit (AHBToMbus) windows to access the xbar 
		and read the data from there */
		/*
		Need to configure the 2 free Punit (AHB to MBus bridge) 
		address decoding windows:
		Configure the flash Window to handle Configuration space requests 
		for PEX0/1:
		1.    write 0x7931/0x7941 to the flash window and the size, 
		      79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
		2.    write base to flash window 
		
		Configuration transactions from the CPU should write/read the data 
		to/from address of the form:
		addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
		addr[27:24] = extended register number
		addr[23:16] = bus number
		addr[15:11] = device number
		addr[10:8]   = function number
		addr[7:0]     = register number
		*/

		#include "ctrlEnv/sys/mvAhbToMbus.h"
		{
			MV_U32 winNum;
			MV_AHB_TO_MBUS_DEC_WIN originWin;
			MV_U32 pciAddr=0;
			MV_U32 remapLow=0,remapHigh=0;

			/* 
			We will use DEV_CS2\Flash window for this workarround 
			*/
            
			winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);

			/* save remap values if exist */
			if ((1 == winNum)||(0 == winNum))
			{
				remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
				remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));

			}
			

			/* save the original window values */
			mvAhbToMbusWinGet(winNum,&originWin);

			if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
			{
				/* set the window as xbar window */
				if (pexIf)
				{
					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), 
					(0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
				}
				else
				{
					MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), 
					(0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
				}

				MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
							 originWin.addrWin.baseLow);

				/*pciAddr = originWin.addrWin.baseLow;*/
				pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
					(MV_U32)originWin.addrWin.baseLow);
			
			}
Example #13
0
/*******************************************************************************
* mvPexConfigRead - Read from configuration space
*
* DESCRIPTION:
*       This function performs a 32 bit read from PEX 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 mvPexLocalBusNumGet(). Other bus numbers
*       will result configuration transaction of type 1 (over bridge).
*
* INPUT:
*       pexIf   - PEX interface number.
*       bus     - PEX segment bus number.
*       dev     - PEX device number.
*       func    - Function number.
*       regOffs - Register offset.
*
* OUTPUT:
*       None.
*
* RETURN:
*       32bit register data, 0xffffffff on error
*
*******************************************************************************/
MV_U32 mvPexConfigRead(MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func, MV_U32 regOff)
{
	MV_U32 pexData = 0;
	MV_U32 localDev, localBus;

	if (pexIf >= MV_PEX_MAX_IF)
		return 0xFFFFFFFF;

	/* Parameter checking   */
	if (PEX_DEFAULT_IF != pexIf) {
		if (pexIf >= pexHalData[pexIf].maxPexIf) {
			mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n", pexIf);
			return 0xFFFFFFFF;
		}
	}

	if (dev >= MAX_PEX_DEVICES) {
		DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
		return 0xFFFFFFFF;
	}

	if (func >= MAX_PEX_FUNCS) {
		DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
		return 0xFFFFFFFF;
	}

	if (bus >= MAX_PEX_BUSSES) {
		DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
		return 0xFFFFFFFF;
	}

	DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
		      pexIf, bus, dev, func, regOff));

	localDev = mvPexLocalDevNumGet(pexIf);
	localBus = mvPexLocalBusNumGet(pexIf);

	/* Speed up the process. In case on no link, return MV_ERROR */
	if ((dev != localDev) || (bus != localBus)) {
		pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));

		if ((pexData & PXSR_DL_DOWN))
			return 0xFFFFFFFF;
	}

	/* in PCI Express we have only one device number */
	/* and this number is the first number we encounter
	   else that the localDev */
	/* spec pex define return on config read/write on any device */
	if (bus == localBus) {
		if (localDev == 0) {
			/* if local dev is 0 then the first number we encounter
			   after 0 is 1 */
			if ((dev != 1) && (dev != localDev))
				return 0xFFFFFFFF;
		} else {
			/* if local dev is not 0 then the first number we encounter
			   is 0 */

			if ((dev != 0) && (dev != localDev))
				return 0xFFFFFFFF;
		}
	}
	/* Creating PEX address to be passed */
	pexData = (bus << PXCAR_BUS_NUM_OFFS);
	pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
	pexData |= (func << PXCAR_FUNC_NUM_OFFS);
	pexData |= (regOff & PXCAR_REG_NUM_MASK);	/* lgacy register space */
	/* extended register space */
	pexData |= (((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
		     PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);

	pexData |= PXCAR_CONFIG_EN;

	/* Write the address to the PEX configuration address register */
	MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
	DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ", pexData));

	/* In order to let the PEX controller absorbed the address of the read  */
	/* transaction we perform a validity check that the address was written */
	if (pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
		return MV_ERROR;

	/* cleaning Master Abort */
	MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), PXSAC_MABORT);
		/* Read the Data returned in the PEX Data register */
		pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));

	DB(mvOsPrintf("mvPexConfigRead: got : %x \n", pexData));

	return pexData;

}
Example #14
0
/*******************************************************************************
*  mvPexBarSet - Set PEX bar address and size 
*
* DESCRIPTION:
*
* INPUT:
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
*
*******************************************************************************/
MV_STATUS mvPexBarSet(MV_U32 pexIf,
						MV_U32 barNum,
						MV_PEX_BAR *pAddrWin)
{
	MV_U32 regBaseLow;
	MV_U32 regSize,sizeToReg;


	/* check parameters */
	if(pexIf >= mvCtrlPexMaxIfGet())
	{
		mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
		return MV_BAD_PARAM;
	}

	if(barNum >= PEX_MAX_BARS)
	{
		mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
		return MV_BAD_PARAM;
	}
	

	if (pAddrWin->addrWin.size == 0)
	{
		mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
		return MV_BAD_PARAM;
	}


	/* Check if the window complies with PEX spec							*/
	if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
								 pAddrWin->addrWin.size))
	{
        mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
		return MV_BAD_PARAM;
	}

    /* 2) Check if the requested bar overlaps with current bars		*/
    if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
	{
        mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
		return MV_BAD_PARAM;
	}

	/* Get size register value according to window size						*/
	sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
	
	/* Read bar size */
	if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
	{
		regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));

		/* Size parameter validity check.                                   */
		if (-1 == sizeToReg)
		{
			mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
			return MV_BAD_PARAM;
		}
	
		regSize &= ~PXBCR_BAR_SIZE_MASK;
		regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
	
		MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);

	}

	/* set size */



	/* Read base address low */
	regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
												   PEX_MV_BAR_BASE(barNum)));

	/* clear current base */
	if (PEX_INTER_REGS_BAR == barNum)
	{
		regBaseLow &= ~PXBIR_BASE_MASK;
        regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
	}
	else
	{
		regBaseLow &= ~PXBR_BASE_MASK;
		regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
	}

	/* if we had a previous value that contain the bar type (MeM\IO), we want to
	restore it */
	regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;



	/* write base low */
    MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
				regBaseLow);

	if (pAddrWin->addrWin.baseHigh != 0)
	{
		/* Read base address high */
		MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
								 pAddrWin->addrWin.baseHigh);

	}

	/* lastly enable the Bar */
	if (pAddrWin->enable == MV_TRUE)
	{
		if (PEX_INTER_REGS_BAR != barNum) /* internal registers 
												are enabled always */
		{
			MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
		}
	}
	else if (MV_FALSE == pAddrWin->enable)
	{
		if (PEX_INTER_REGS_BAR != barNum) /* internal registers 
												are enabled always */
		{
			MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
		}

	}



	return MV_OK;
}
/*******************************************************************************
* mvCtrlHighSpeedSerdesPhyConfig
*
* DESCRIPTION: This is the main function which configure the
*              PU sequence of the ser-des
*
* INPUT:
*       None.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_OK   - success
*       MV_ERROR - failure
*******************************************************************************/
MV_STATUS mvCtrlHighSpeedSerdesPhyConfig(MV_VOID)
{
    MV_U32      serdesLaneNum, pexUnit;
    MV_U32      uiReg;
    MV_BIN_SERDES_UNIT_INDX     serdesLaneCfg;
    MV_U32	regAddr[16][11], regVal[16][11]; /* addr/value for each line @ every setup step */
    MV_U8	maxSerdesLanes;
    MV_U32	tmp;
    MV_U32	tempReg, tempPexReg;
    MV_U32	pexIf=0;
	MV_U32  first_busno, next_busno;
    MV_U32	addr;
	MV_TWSI_ADDR slave;
	MV_U32  boardId = mvBoardIdIndexGet(mvBoardIdGet());
    maxSerdesLanes = mvCtrlSerdesMaxLanesGet();

    if (maxSerdesLanes == 0)
        return MV_OK;

	/*Set MPP1 for twsi access */
	uiReg = (MV_REG_READ(MPP_CONTROL_REG(1))  & 0x00FFFFFF) | 0x22000000;
	MV_REG_WRITE(MPP_CONTROL_REG(1), uiReg);

	/* TWSI init */
	slave.type = ADDR7_BIT;
	slave.address = 0;
	mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);


	mvUartInit();

	/* update board configuration (serdes lane topology and speed), if needed */
	mvBoardUpdateBoardTopologyConfig(boardId);

	/* Initialize board configuration database */
	boardLaneConfig[0] = SERDES_UNIT_PEX;		/* SerDes 0 is alwyas PCIe0*/
	boardLaneConfig[1] = boardTopologyConfig[boardId].serdesTopology.lane1;
	boardLaneConfig[2] = boardTopologyConfig[boardId].serdesTopology.lane2;
	boardLaneConfig[3] = boardTopologyConfig[boardId].serdesTopology.lane3;

    memset(regAddr, 0, sizeof(regAddr));
    memset(regVal,  0, sizeof(regVal));


    /* Check if DRAM is already initialized  */
    if (MV_REG_READ(REG_BOOTROM_ROUTINE_ADDR) & (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
        DEBUG_INIT_S("High speed PHY - Version: ");
        DEBUG_INIT_S(SERDES_VERION);
        DEBUG_INIT_S(" - 2nd boot - Skip \n");
        return MV_OK;
    }
    DEBUG_INIT_S("High speed PHY - Version: ");
    DEBUG_INIT_S(SERDES_VERION);
    DEBUG_INIT_S(" (COM-PHY-V20) \n");
	DEBUG_INIT_FULL_C("SERDES 0=",boardLaneConfig[0],2);
	DEBUG_INIT_FULL_C("SERDES 1=",boardLaneConfig[1],2);
	DEBUG_INIT_FULL_C("SERDES 2=",boardLaneConfig[2],2);
	DEBUG_INIT_FULL_C("SERDES 3=",boardLaneConfig[3],2);

    /*------------------------------------------*/
    /* STEP - 1.5 Power Down PLL, RX, TX all phys */
    /*------------------------------------------*/

    for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++)
    {
      uiReg=MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum));
	  uiReg &= ~PIN_TX_IDLE_MASK;
      uiReg &= ~(PHY_POWER_UP_PLL_MASK | PHY_POWER_UP_RX_MASK | PHY_POWER_UP_TX_MASK);
      MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg);
    }

    mvOsUDelay(10000);

    /*--------------------------------------------------------*/
    /* STEP - 2 Reset PHY and PIPE (Zx: Un-reset, Ax: Reset)*/
    /*--------------------------------------------------------*/
	for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++)
	{
#ifndef CONFIG_ALP_A375_ZX_REV
			resetPhyAndPipe(serdesLaneNum, MV_TRUE);
#else
			resetPhyAndPipe(serdesLaneNum, MV_FALSE);
#endif
	}


    /*--------------------------------*/
    /* STEP - 2 Common PHYs Selectors */
    /*--------------------------------*/

    MV_REG_WRITE(COMMON_PHY_SELECTOR_REG, GetLaneSelectorConfig());

    /*--------------------------------*/
    /* STEP - 3 Configuration 1       */
    /*--------------------------------*/

	for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) {
		serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum);
		if(serdesLaneCfg >= SERDES_LAST_UNIT){
			return MV_ERROR;
		}
		uiReg = MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum));
		switch(serdesLaneCfg){
			case SERDES_UNIT_USB3:
#ifndef CONFIG_ALP_A375_ZX_REV
				A375_A0_COMMON_PHY_CONFIG(uiReg);
#endif
				uiReg |= PHY_MODE_MASK;	/* PHY Mode = USB */
				uiReg |= PIPE_SELECT_MASK ;	/* Select USB3_PEX */
				break;
			case SERDES_UNIT_PEX:
				uiReg |= PIPE_SELECT_MASK ;	/* Select USB3_PEX */
#ifndef CONFIG_ALP_A375_ZX_REV
					uiReg &= ~(PHY_MODE_MASK);	/* PHY Mode = PEX */
					A375_A0_COMMON_PHY_CONFIG(uiReg);
#endif
				break;
			case SERDES_UNIT_SGMII:
			case SERDES_UNIT_SATA:
#ifndef CONFIG_ALP_A375_ZX_REV
					A375_A0_COMMON_PHY_CONFIG(uiReg);
#endif
				uiReg &= ~(PIPE_SELECT_MASK);	/* Select SATA_SGMII */
				uiReg |= POWER_UP_IVREF_MASK;  /* Power UP IVREF = Power Up */
				break;
			case SERDES_UNIT_UNCONNECTED:
			default:
			break;
		}

		/* Serdes speed config */
		tmp = getSerdesSpeedConfig(boardId, serdesLaneCfg);
		uiReg &= ~(GEN_RX_MASK); /* SERDES RX Speed config */
		uiReg |= tmp<<GEN_RX_OFFS;
		uiReg &= ~(GEN_TX_MASK); /* SERDES TX Speed config */
		uiReg |= tmp<<GEN_TX_OFFS;
		MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg);
	}

#ifndef CONFIG_ALP_A375_ZX_REV
	/*------------------------------------------*/
	/*	STEP - 3.5 Unreset PHY and PIPE(only Ax)*/
	/*------------------------------------------*/
		for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) {
			resetPhyAndPipe(serdesLaneNum, MV_FALSE);
		}
#endif

    /*----------------------------------------*/
    /* STEP - 4 COMPHY register configuration */
    /*----------------------------------------*/
    for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) {
        serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum);
        if(serdesLaneCfg >= SERDES_LAST_UNIT){
            return MV_ERROR;
        }
        switch(serdesLaneCfg){
            case SERDES_UNIT_PEX:
                MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x25); /* Enable soft_reset*/
                MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC60); /* PHY Mode = PEX */
#ifndef CONFIG_ALP_A375_ZX_REV
					MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6017); /* REFCLK SEL =0x0 (100Mhz) */
					MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */
					MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */
					A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum);
#else
					MV_REG_WRITE(KVCO_CALOBRATION_CONTROL_REG(serdesLaneNum),0x40); /* use_max_pll_rate=0x0, ext_force_cal_done=0x0 */
#endif
                MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x24); /* Release soft_reset */
            break;
            case SERDES_UNIT_USB3:
                MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x21); /* Enable soft_reset*/
				MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFCA0); /* PHY Mode = USB3 */
#ifndef CONFIG_ALP_A375_ZX_REV
					MV_REG_WRITE(LANE_CONFIGURATION_4_REG(serdesLaneNum),0x13); /* Ref_Clk =100Mhz */
					MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6017); /* REFCLK SEL =0x0 (100Mhz) */
					MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */
					MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */
					A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum);
#else
					MV_REG_WRITE(KVCO_CALOBRATION_CONTROL_REG(serdesLaneNum),0x40); /* use_max_pll_rate=0x0, ext_force_cal_done=0x0 */
					MV_REG_WRITE(GENERETION_2_SETTINGS_1_REG(serdesLaneNum),0x149); /* Mulitiple frequency setup */
#endif
                MV_REG_WRITE(RESET_AND_CLOCK_CONTROL_REG(serdesLaneNum),0x20); /* Release soft_reset */
                break;
            case SERDES_UNIT_SATA:
                MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC01); /* PHY Mode = SATA */
				MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6417); /* REFCLK SEL =0x1 (25Mhz) */
#ifndef CONFIG_ALP_A375_ZX_REV
					MV_REG_WRITE(INTERFACE_REG1_REG(serdesLaneNum),0x1400); /* PHY_Gen_Max = 5G */
					MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x400); /* SEL_Bits = 20-Bit */
					MV_REG_WRITE(DIGITAL_RESERVED0_REG(serdesLaneNum),0xE); /* Reg_sq_de_glitch_en */
					A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum);
#else
					MV_REG_WRITE(RESERVED_46_REG(serdesLaneNum),0xFF00);
#endif
                break;
            case SERDES_UNIT_SGMII:
                MV_REG_WRITE(POWER_AND_PLL_CONTROL_REG(serdesLaneNum),0xFC81); /* PHY Mode = SGMII */ /*moti need to change offset*/
                MV_REG_WRITE(DIGITAL_LOOPBACK_ENABLE_REG(serdesLaneNum),0x0); /* SEL_BITS = 0x0 (10-bits mode) */
				MV_REG_WRITE(MISCELLANEOUS_CONTROL0_REG(serdesLaneNum),0x6417); /* REFCLK SEL =0x1 (25Mhz) */
#ifndef CONFIG_ALP_A375_ZX_REV
					MV_REG_WRITE(DIGITAL_RESERVED0_REG(serdesLaneNum),0xE); /* Reg_sq_de_glitch_en */
					A375_A0_RESET_DFE_SEQUENCE(serdesLaneNum);
#else
                MV_REG_WRITE(RESERVED_46_REG(serdesLaneNum),0xFF00); /* Enable soft_reset*/
#endif
                MV_REG_WRITE(PHY_ISOLATION_MODE_CONTROL_REG(serdesLaneNum),0x166); /* Set PHY_GEN_TX/RX to 1.25Gbps */
                break;
	    case SERDES_UNIT_UNCONNECTED:
	    default:
			break;
        }
    }

    /*------------------------------------------*/
    /* STEP - 4.5 Power up PLL, RX, TX all phys */
    /*------------------------------------------*/

    for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++)
    {
      uiReg=MV_REG_READ(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum));
      uiReg |= (PHY_POWER_UP_PLL_MASK | PHY_POWER_UP_RX_MASK | PHY_POWER_UP_TX_MASK);
      MV_REG_WRITE(COMMON_PHY_CONFIGURATION1_REG(serdesLaneNum),uiReg);
    }

#ifndef CONFIG_ALP_A375_ZX_REV
	mvOsUDelay(5000);

    /*--------------------------------------------------------------------*/
    /* STEP - 4.6 (Only SGMII/SATA): WAIT for PHY Power up sequence to finish */
    /*--------------------------------------------------------------------*/
	for (serdesLaneNum = 0; serdesLaneNum < maxSerdesLanes; serdesLaneNum++) {
        serdesLaneCfg = mvGetSerdesLaneCfg(serdesLaneNum);
        if(serdesLaneCfg >= SERDES_LAST_UNIT){
            return MV_ERROR;
        }
        switch(serdesLaneCfg){
            case SERDES_UNIT_SATA:
			case SERDES_UNIT_SGMII:
                uiReg = MV_REG_READ(COMMON_PHY_STATUS1_REG(serdesLaneNum));
				if ((uiReg & 0x6) != 0x6) {
					DEBUG_INIT_S("Phy Power up did't finished\n");
					return MV_ERROR;
				}
	    case SERDES_UNIT_UNCONNECTED:
	    default:
			break;
        }
    }
#endif

    /*----------------------------------------*/
    /* STEP - 5 PEX Only                      */
    /*----------------------------------------*/
	for (pexUnit = 0; pexUnit < 4; pexUnit++) {
		if (boardLaneConfig[pexUnit] != SERDES_UNIT_PEX)
			continue;
		tmp = MV_REG_READ(PEX_CAPABILITIES_REG(pexUnit));
		DEBUG_RD_REG(PEX_CAPABILITIES_REG(pexUnit), tmp );
		tmp &= ~(0xf<<20);
		tmp |= (0x4<<20);
		MV_REG_WRITE(PEX_CAPABILITIES_REG(pexUnit),tmp);
		DEBUG_WR_REG(PEX_CAPABILITIES_REG(pexUnit),tmp);
	}

	tmp = MV_REG_READ(SOC_CTRL_REG);
	DEBUG_RD_REG(SOC_CTRL_REG, tmp);
	tmp &= ~(0x03);
    tmp |= 0x1<<PCIE0_ENABLE_OFFS;
	if (boardLaneConfig[1] == SERDES_UNIT_PEX)
		tmp |= 0x1<<PCIE1_ENABLE_OFFS;
	MV_REG_WRITE(SOC_CTRL_REG, tmp);
	DEBUG_WR_REG(SOC_CTRL_REG, tmp);

    /*----------------------------------------*/
    /* STEP - 6 PEX Only - support gen1/gen2  */
    /*----------------------------------------*/
	next_busno = 0;

	mvOsDelay(150);

    for (pexIf = 0; pexIf < 2; pexIf++)  // only pexIf 0 on
    {
		if (boardLaneConfig[pexIf] != SERDES_UNIT_PEX)
			continue;
      tmp = MV_REG_READ(PEX_DBG_STATUS_REG(pexIf));
      DEBUG_RD_REG(PEX_DBG_STATUS_REG(pexIf), tmp);
	  first_busno = next_busno;
      if ((tmp & 0x7f) == 0x7E) {
		  next_busno++;
		  tempPexReg = MV_REG_READ((PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CAPABILITY_REG)));
		  DEBUG_RD_REG((PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CAPABILITY_REG)),tempPexReg );
		  tempPexReg &= (0xF);
		  if (tempPexReg == 0x2) {
				tempReg = (MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG)) & 0xF0000) >> 16;
				DEBUG_RD_REG(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG),tempReg );

				/* check if the link established is GEN1 */
				if (tempReg == 0x1) {
					mvPexLocalBusNumSet(pexIf, first_busno);
					mvPexLocalDevNumSet(pexIf, 1);
					DEBUG_INIT_FULL_S("PEX: pexIf ");
					DEBUG_INIT_FULL_D(pexIf, 1);
					DEBUG_INIT_FULL_S(", link is Gen1, checking the EP capability \n");


					/* link is Gen1, check the EP capability */
					addr = mvPexConfigRead(pexIf, first_busno, 0, 0, 0x34) & 0xFF;
					DEBUG_INIT_FULL_C("mvPexConfigRead: return addr=0x%x", addr,4);
					if (addr == 0xff) {
						DEBUG_INIT_FULL_C("mvPexConfigRead: return 0xff -->PEX (%d): Detected No Link.", pexIf,1);
						continue;
					}
					while ((mvPexConfigRead(pexIf, first_busno, 0, 0, addr) & 0xFF) != 0x10) {
						addr = (mvPexConfigRead(pexIf, first_busno, 0, 0, addr) & 0xFF00) >> 8;
					}
					if ((mvPexConfigRead(pexIf, first_busno, 0, 0, addr + 0xC) & 0xF) >= 0x2) {
						tmp = MV_REG_READ(PEX_LINK_CTRL_STATUS2_REG(pexIf));
						DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp );
						tmp &=~(BIT0 | BIT1);
						tmp |= BIT1;
						MV_REG_WRITE(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp);
						DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pexIf),tmp);

						tmp = MV_REG_READ(PEX_CTRL_REG(pexIf));
						DEBUG_RD_REG(PEX_CTRL_REG(pexIf), tmp );
						tmp |= BIT10;
						MV_REG_WRITE(PEX_CTRL_REG(pexIf),tmp);
						DEBUG_WR_REG(PEX_CTRL_REG(pexIf),tmp);
						mvOsUDelay(10000);/* We need to wait 10ms before reading the PEX_DBG_STATUS_REG in order not to read the status of the former state*/

						DEBUG_INIT_FULL_S("PEX: pexIf ");
						DEBUG_INIT_FULL_D(pexIf, 1);
						DEBUG_INIT_FULL_S(", Link upgraded to Gen2 based on client cpabilities \n");
					} else {
						DEBUG_INIT_FULL_S("PEX: pexIf ");
						DEBUG_INIT_FULL_D(pexIf, 1);
						DEBUG_INIT_FULL_S(", remains Gen1\n");
					}
				}
		  }
Example #16
0
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;
}