MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin, 
                                MV_DEC_WIN_PARAMS *pWinParam)
{
	MV_U32 baseToReg=0, sizeToReg=0;
    
	/* BaseLow[31:16] => base register [31:16]		*/
	baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;

	/* Write to address decode Base Address Register	*/
	pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
	pWinParam->baseAddr |= baseToReg;

	/* Get size register value according to window size	*/
	sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
	
	/* Size parameter validity check.			*/
	if (-1 == sizeToReg)
	{
        	mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
		return MV_BAD_PARAM;
	}
    	pWinParam->size = sizeToReg;

    	pWinParam->attrib   = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
    	pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;

    	return MV_OK;
}
Exemplo n.º 2
0
/*******************************************************************************
* mvCtrlAddrDecToParams - Get address decode register format values
*
* DESCRIPTION:
*       This function returns the given address window information in the 
*       format of address decode base and size registers.
*
* INPUT:
*       pAddrDecWin - Target window data structure.
*
* OUTPUT:
*       pWinParam   - Address decode window parameters.
*
* RETURN:
*       MV_BAD_PARAM if base address is invalid parameter or target is 
*       unknown.
*
*******************************************************************************/
MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin, 
                                MV_DEC_WIN_PARAMS *pWinParam)
{
	MV_TARGET_ATTRIB targetAttrib;
	MV_U32 size;        /* Holds BAR size              */
    /* 2) Initialize Size register                                          */
    /* 2.1 Get address decode size register value to given size             */
    size = ctrlSizeToReg(pAddrDecWin->addrWin.size, BAR_SIZE_ALIGNMENT);   
    /* Size parameter validity check.                                       */
    if (-1 == size)
	{
		DB(mvOsPrintf("mvCtrlAddrDecToParams: ERR. addrDecSizeToReg failed.\n"));
        return MV_BAD_PARAM;
	}

    /* Write the size register value */
    pWinParam->size = size;   
    /* Base address */
    pWinParam->baseAddr = pAddrDecWin->addrWin.baseLow;
	/* attrib and targetId */
	mvCtrlAttribGet(pAddrDecWin->target, &targetAttrib);
	pWinParam->attrib = targetAttrib.attrib;
	pWinParam->targetId = targetAttrib.targetId;
    return MV_OK;

}
/*******************************************************************************
* mvCtrlAddrDecToReg - Get address decode register format values
*
* DESCRIPTION:
*
* INPUT:
*
* OUTPUT:
*
* RETURN:
*
*******************************************************************************/
MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
{

	MV_U32 baseToReg=0 , sizeToReg=0;
    
	/* BaseLow[31:16] => base register [31:16]		*/
	baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;

	/* Write to address decode Base Address Register	*/
	pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
	pAddrDecRegs->baseReg |= baseToReg;

	/* Get size register value according to window size	*/
	sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
	
	/* Size parameter validity check.			*/
	if (-1 == sizeToReg)
	{
		return MV_BAD_PARAM;
	}

	/* set size */
	pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
	pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);

	return MV_OK;
}
Exemplo n.º 4
0
/*******************************************************************************
* mvPciTargetWinSet - Set PCI to peripheral target address window BAR
*
* DESCRIPTION:
*       This function sets an address window from PCI to a peripheral 
*       target (e.g. SDRAM bank0, PCI_MEM0), also known as BARs. 
*       A new PCI BAR window is set for specified target address window.
*       If address decode window parameter structure enables the window, 
*       the routine will also enable the target window, allowing PCI to access
*       the target window.
*
* INPUT:
*       pciIf       - PCI interface number.
*       bar         - BAR to be accessed by slave.
*       pAddrBarWin - PCI target window information data structure.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_OK if PCI BAR target window was set correctly, MV_BAD_PARAM on bad params 
*       MV_ERROR otherwise 
*       (e.g. address window overlapps with other active PCI target window).
*
*******************************************************************************/
MV_STATUS mvPciTargetWinSet(MV_U32 pciIf,
							MV_PCI_BAR bar, 
                            MV_PCI_BAR_WIN *pAddrBarWin)
{
	MV_U32 pciData;
	MV_U32 sizeToReg;
	MV_U32 size;
	MV_U32 baseLow;
	MV_U32 baseHigh;
	MV_U32 localBus;
	MV_U32 localDev;
	PCI_BAR_REG_INFO barRegInfo;

	size     = pAddrBarWin->addrWin.size;
	baseLow  = pAddrBarWin->addrWin.baseLow;
	baseHigh = pAddrBarWin->addrWin.baseHigh;

	/* Parameter checking   */
	if(pciIf >= mvCtrlPciMaxIfGet())
	{
		mvOsPrintf("mvPciTargetWinSet: ERR. Invalid PCI interface %d\n", pciIf);
		return MV_BAD_PARAM;
	}

	if(bar >= PCI_MAX_BARS )
	{
		mvOsPrintf("mvPciTargetWinSet: ERR. Illigal PCI BAR %d\n", bar);
		return MV_BAD_PARAM;
	}


	/* if the address windows is disabled , we only disable the appropriare
	pci bar and ignore other settings */

	if (MV_FALSE == pAddrBarWin->enable)
	{
        MV_REG_BIT_SET(PCI_BASE_ADDR_ENABLE_REG(pciIf), BARER_ENABLE(bar));
		return MV_OK;
	}

	if (0 == pAddrBarWin->addrWin.size)
	{
        mvOsPrintf("mvPciTargetWinSet: ERR. Target %d can't be zero!\n",bar);
        return MV_BAD_PARAM;
	}

	/* Check if the window complies with PCI spec							*/
	if (MV_TRUE != pciWinIsValid(baseLow, size))
	{
        mvOsPrintf("mvPciTargetWinSet: ERR. Target %d window invalid\n", bar);
		return MV_BAD_PARAM;
	}

    /* 2) Check if the requested window overlaps with current windows		*/
	if(MV_TRUE == pciWinOverlapDetect(pciIf, bar, &pAddrBarWin->addrWin))
	{
		mvOsPrintf("mvPciTargetWinSet: ERR. Overlap detected for target %d\n",
																		bar);
		return MV_BAD_PARAM;
	}

	/* Get size register value according to window size						*/
	sizeToReg = ctrlSizeToReg(size, PBBLR_BASE_ALIGNMET);

	/* Size parameter validity check.                                   */
	if (-1 == sizeToReg)
	{
		mvOsPrintf("mvPciTargetWinSet: ERR. Target BAR %d size invalid.\n",bar);
		return MV_BAD_PARAM;
	}

	localBus = mvPciLocalBusNumGet(pciIf);
	localDev = mvPciLocalDevNumGet(pciIf);
	
	/* Get BAR register information */
	pciBarRegInfoGet(pciIf, bar, &barRegInfo);
	
	/* Internal register space size have no size register. Do not perform	*/
	/* size register assigment for this slave target					 	*/
	if (0 != barRegInfo.sizeRegOffs)
	{    
		/* Update size register */
		MV_REG_WRITE(barRegInfo.sizeRegOffs, (sizeToReg << BAR_SIZE_OFFS));
	}
	
	/* Read current address */
	pciData = mvPciConfigRead(pciIf, localBus, localDev, barRegInfo.funcNum, 
													barRegInfo.baseLowRegOffs);

	/* Clear current address */
	pciData &= ~PBBLR_BASE_MASK;
	pciData |= (baseLow & PBBLR_BASE_MASK);
		
	/* Write new address */
	mvPciConfigWrite(pciIf, localBus, localDev, barRegInfo.funcNum,
											barRegInfo.baseLowRegOffs, pciData);

	/* Skip base high settings if the BAR has only base low (32-bit)		*/
	if (0 != barRegInfo.baseHighRegOffs)
	{
		mvPciConfigWrite(pciIf, localBus, localDev, barRegInfo.funcNum, 
										barRegInfo.baseHighRegOffs, baseHigh);	
	}

	/* Enable/disable the BAR */
    if (MV_TRUE == pAddrBarWin->enable)
    {
        MV_REG_BIT_RESET(PCI_BASE_ADDR_ENABLE_REG(pciIf), BARER_ENABLE(bar));
    }
	else
	{
        MV_REG_BIT_SET(PCI_BASE_ADDR_ENABLE_REG(pciIf), BARER_ENABLE(bar));
	}

	return MV_OK;
}
Exemplo n.º 5
0
/*******************************************************************************
* mvPexInit - Initialize PEX interfaces
*
* DESCRIPTION:
*
* This function is responsible of intialization of the Pex Interface , It 
* configure the Pex Bars and Windows in the following manner:
*
*  Assumptions : 
*				Bar0 is always internal registers bar
*			    Bar1 is always the DRAM bar
*				Bar2 is always the Device bar
*
*  1) Sets the Internal registers bar base by obtaining the base from
*	  the CPU Interface
*  2) Sets the DRAM bar base and size by getting the base and size from
*     the CPU Interface when the size is the sum of all enabled DRAM 
*	  chip selects and the base is the base of CS0 .
*  3) Sets the Device bar base and size by getting these values from the 
*     CPU Interface when the base is the base of the lowest base of the
*     Device chip selects, and the 
*
*
* INPUT:
*
*       pexIf   -  PEX interface number.
*
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
*
*******************************************************************************/
MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
{
	MV_U32 	       		bar;
	MV_U32		   	winNum;
	MV_PEX_BAR	  	pexBar;
	MV_PEX_DEC_WIN 		pexWin;
	MV_CPU_DEC_WIN 		addrDecWin;
	MV_TARGET 		target;
	MV_U32			pexCurrWin=0;
	MV_U32			status;
	/* default and exapntion rom 
	are always configured */

#ifndef MV_DISABLE_PEX_DEVICE_BAR
	MV_U32		   	winIndex;
	MV_U32 		    	maxBase=0, sizeOfMaxBase=0;
	MV_U32			pexStartWindow;
#endif

	/* Parameter checking   */
	if(pexIf >= mvCtrlPexMaxIfGet())
	{
		mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
		return MV_BAD_PARAM;
	}
	
	/* Enabled CPU access to PCI-Express */
	mvCpuIfEnablePex(pexIf, pexType);

    /* Start with bars */
	/* First disable all PEX bars*/
	for (bar = 0; bar < PEX_MAX_BARS; bar++)
    {
		if (PEX_INTER_REGS_BAR != bar)
		{
			if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
			{
				mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
				return MV_ERROR;
			}
			
		}

	}

	/* and disable all PEX target windows  */
	for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
    {
		if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
		{
			mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
					   winNum);
			return MV_ERROR;

		}
	}

	/* Now, go through all bars*/



/******************************************************************************/
/*                       Internal registers bar                               */
/******************************************************************************/
	bar = PEX_INTER_REGS_BAR;

	/* we only open the bar , no need to open windows for this bar */

	/* first get the CS attribute from the CPU Interface */
	if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
	{
		mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
		return MV_ERROR;
	}

	pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
	pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
	pexBar.addrWin.size = addrDecWin.addrWin.size;
	pexBar.enable = MV_TRUE;

	if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
	{
		mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
		return MV_ERROR;
	}
	
/******************************************************************************/
/*                                DRAM bar                                    */
/******************************************************************************/

	bar = PEX_DRAM_BAR;

	pexBar.addrWin.size = 0;
	
	for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
	{

		status = mvCpuIfTargetWinGet(target,&addrDecWin);

		if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
		{
			continue;
		}

		/* first get attributes from CPU If */
		if (MV_OK != status)
		{
			mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
			return MV_ERROR;
		}
		if (addrDecWin.enable == MV_TRUE)
		{				
			/* the base is the base of DRAM CS0 always */
			if (SDRAM_CS0 == target )
			{
				pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
				pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;

			}

			/* increment the bar size to be the sum of the size of all
			DRAM chips selecs */
			pexBar.addrWin.size += addrDecWin.addrWin.size;

			/* set a Pex window for this target ! 
			DRAM CS always will have a Pex Window , and is not a 
			part of the priority table */
			pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
			pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
			pexWin.addrWin.size = addrDecWin.addrWin.size;
			
			/* we disable the windows at first because we are not
			sure that it is witihin bar boundries */
			pexWin.enable =MV_FALSE;
			pexWin.target = target;
			pexWin.targetBar = bar;

			if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
			{
				mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
				return MV_ERROR;
			}
		}
	}

	/* check if the size of the bar is illeggal */
	if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
	{
		/* try to get a good size */
		pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
												 PXBCR_BAR_SIZE_ALIGNMENT);
	}
    
	/* check if the size and base are valid */
	if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
	{
		mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
		mvOsPrintf("it will be disabled\n");
		mvOsPrintf("please check Pex and CPU windows configuration\n");
	}
	else
	{
		pexBar.enable = MV_TRUE;
        
		/* configure the bar */
		if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
		{
			mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
			return MV_ERROR;
		}
	
		/* after the bar was configured then we enable the Pex windows*/
		for (winNum = 0;winNum < pexCurrWin ;winNum++)
		{
			if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
			{
				mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
				return MV_ERROR;
			}
	
		}
	}

/******************************************************************************/
/*                              DEVICE bar                                    */
/******************************************************************************/

/* Open the Device BAR for non linux only */
#ifndef MV_DISABLE_PEX_DEVICE_BAR 

	/* then device  bar*/
	bar = PEX_DEVICE_BAR;

	/* save the starting window */
	pexStartWindow = pexCurrWin;
	pexBar.addrWin.size = 0;
	pexBar.addrWin.baseLow = 0xffffffff;
	pexBar.addrWin.baseHigh = 0;
	maxBase = 0;

	for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
	{
		status = mvCpuIfTargetWinGet(target,&addrDecWin);

		if (MV_NO_SUCH == status)
		{
			continue;
		}

		if (MV_OK != status)
		{
			mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
			return MV_ERROR;
		}

		if (addrDecWin.enable == MV_TRUE)
		{				
			/* get the minimum base */
			if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
			{
				pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
			}

			/* get the maximum base */
			if (addrDecWin.addrWin.baseLow > maxBase)
			{
				maxBase = addrDecWin.addrWin.baseLow;
				sizeOfMaxBase = addrDecWin.addrWin.size;
			}

			/* search in the priority table for this target */
			for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
				 winIndex++)
			{
				if (pexDevBarPrioTable[winIndex] != target)
				{
					continue;
				}
				else if (pexDevBarPrioTable[winIndex] == target)
				{
					/*found it */

					/* if the index of this target in the prio table is valid 
					then we set the Pex window for this target, a valid index is 
					an index that is lower than the number of the windows that
					was not configured yet */

					/* we subtract 2 always because the default and expantion
					rom windows are always configured */
					if ( pexCurrWin  < PEX_MAX_TARGET_WIN - 2)
					{
						/* set a Pex window for this target !  */
						pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
						pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
						pexWin.addrWin.size = addrDecWin.addrWin.size;
						
						/* we disable the windows at first because we are not
						sure that it is witihin bar boundries */
						pexWin.enable = MV_FALSE;
						pexWin.target = target;
						pexWin.targetBar = bar;

						if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
													   &pexWin))
						{
							mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
							return MV_ERROR;
						}
					}
				}
			}
		}
	}

	pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
	pexBar.enable = MV_TRUE;

	/* check if the size of the bar is illegal */
	if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
	{
		/* try to get a good size */
		pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
												 PXBCR_BAR_SIZE_ALIGNMENT);
	}

	/* check if the size and base are valid */
	if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
	{
		mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
		mvOsPrintf("it will be disabled\n");
		mvOsPrintf("please check Pex and CPU windows configuration\n");
	}
	else
	{
		if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
		{
			mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
			return MV_ERROR;
		}

		/* now enable the windows */
		for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
		{
			if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
			{
				mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
						   winNum);
				return MV_ERROR;
			}
		}
	}

#endif

	return mvPexHalInit(pexIf, pexType);

}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/*******************************************************************************
* mvDramIfWinSet - Set DRAM interface address decode window
*
* DESCRIPTION: 
*       This function sets DRAM interface address decode window.
*
* INPUT:
*	    target      - System target. Use only SDRAM targets.
*       pAddrDecWin - SDRAM address window structure.
*
* OUTPUT:
*       None
*
* RETURN:
*       MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
*       otherwise.
*******************************************************************************/
MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
{
	MV_U32 baseReg=0,sizeReg=0;
	MV_U32 baseToReg=0 , sizeToReg=0;

    /* Check parameters */
	if (!MV_TARGET_IS_DRAM(target))
	{
		mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
		return MV_BAD_PARAM;
	}

    /* Check if the requested window overlaps with current enabled windows	*/
    if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
	{
        mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
		return MV_BAD_PARAM;
	}

	/* check if address is aligned to the size */
	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
	{
		mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
				   "\nAddress 0x%08x is unaligned to size 0x%x.\n",
                   target, 
				   pAddrDecWin->addrWin.baseLow,
				   pAddrDecWin->addrWin.size);
		return MV_ERROR;
	}

	/* read base register*/
	baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));

	/* read size register */
	sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));

	/* BaseLow[31:16] => base register [31:16]		*/
	baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;

	/* Write to address decode Base Address Register                  */
	baseReg &= ~SCBAR_BASE_MASK;
	baseReg |= baseToReg;

	/* Translate the given window size to register format			*/
	sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);

	/* Size parameter validity check.                                   */
	if (-1 == sizeToReg)
	{
		mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
		return MV_BAD_PARAM;
	}

	/* set size */
	sizeReg &= ~SCSR_SIZE_MASK;
	/* Size is located at upper 16 bits */
	sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);

	/* enable/Disable */
	if (MV_TRUE == pAddrDecWin->enable)
	{
		sizeReg |= SCSR_WIN_EN;
	}
	else
	{
		sizeReg &= ~SCSR_WIN_EN;
	}

	/* 3) Write to address decode Base Address Register                   */
	MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);

	/* Write to address decode Size Register                        	*/
	MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
	
	return MV_OK;
}
Exemplo n.º 8
0
/*******************************************************************************
* mvDramIfDetect - Prepare DRAM interface configuration values.
*
* DESCRIPTION:
*       This function implements the full DRAM detection and timing 
*       configuration for best system performance.
*       Since this routine runs from a ROM device (Boot Flash), its stack 
*       resides on RAM, that might be the system DRAM. Changing DRAM 
*       configuration values while keeping vital data in DRAM is risky. That
*       is why the function does not preform the configuration setting but 
*       prepare those in predefined 32bit registers (in this case IDMA 
*       registers are used) for other routine to perform the settings.
*       The function will call for board DRAM SPD information for each DRAM 
*       chip select. The function will then analyze those SPD parameters of 
*       all DRAM banks in order to decide on DRAM configuration compatible 
*       for all DRAM banks.
*       The function will set the CPU DRAM address decode registers.
*       Note: This routine prepares values that will overide configuration of
*       mvDramBasicAsmInit().
*       
* INPUT:
*       forcedCl - Forced CAL Latency. If equal to zero, do not force.
*
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
{
	MV_U32 retVal = MV_OK;	/* return value */
	MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
	MV_U32  busClk, size, base = 0, i, temp, deviceW, dimmW;
	MV_U8	minCas;
	MV_DRAM_DEC_WIN dramDecWin;

	dramDecWin.addrWin.baseHigh = 0;

	busClk = mvBoardSysClkGet();
	
	if (0 == busClk)
	{
		mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
		return MV_ERROR;
	}
	
	/* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
	for(i= SDRAM_CS1; i <= SDRAM_CS3; i++)
		mvCpuIfTargetWinEnable(i, MV_FALSE);

	/* we will use bank 0 as the representative of the all the DRAM banks,  */
	/* since bank 0 must exist.                                             */	
	for(i = 0; i < MV_DRAM_MAX_CS; i++)
	{ 
		/* if Bank exist */
		if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
		{
			/* check it isn't SDRAM */
			if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
			{
				mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
				return MV_ERROR;
			}
			/* All banks must support registry in order to activate it */
			if(bankInfo[i].registeredAddrAndControlInputs != 
			   bankInfo[0].registeredAddrAndControlInputs)
			{
				mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
				return MV_ERROR;
			}

			/* Init the CPU window decode */
			/* Note that the size in Bank info is in MB units 			*/
			/* Note that the Dimm width might be different then the device DRAM width */
			temp = MV_REG_READ(SDRAM_CONFIG_REG);
			
			deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
			dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
			size = ((bankInfo[i].size << 20) / (dimmW/deviceW)); 

			/* We can not change DRAM window settings while excecuting  	*/
			/* code from it. That is why we skip the DRAM CS[0], saving     */
			/* it to the ROM configuration routine							*/
			if(i == SDRAM_CS0)
			{
				MV_U32 sizeToReg;
				
				/* Translate the given window size to register format		*/
				sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);

				/* Size parameter validity check.                           */
				if (-1 == sizeToReg)
				{
					mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
							   ,i);
					return MV_BAD_PARAM;
				}
                
				/* Size is located at upper 16 bits */
				sizeToReg <<= SCSR_SIZE_OFFS;

				/* enable it */
				sizeToReg |= SCSR_WIN_EN;

				MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
			}
			else
			{
				dramDecWin.addrWin.baseLow = base;
				dramDecWin.addrWin.size = size;
				dramDecWin.enable = MV_TRUE;
				
				if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
				{
					mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", 
							   SDRAM_CS0 + i);
					return MV_ERROR;
				}
			}
			
			base += size;

			/* update the suportedCasLatencies mask */
			bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;

		}
		else
		{
			if( i == 0 ) /* bank 0 doesn't exist */
			{
				mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
				return MV_ERROR;
			}
			else
			{
				DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
				bankInfo[i].size = 0;     /* Mark this bank as non exist */
			}
		}
	}

	/* calculate minimum CAS */
	minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
	if (0 == minCas) 
	{
		mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
				   (busClk / 1000000));

		if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
		{
			minCas = DDR2_CL_4; /* Continue with this CAS */
			mvOsPrintf("Set default CAS latency 4\n");
		}
		else
		{
			minCas = DDR1_CL_3; /* Continue with this CAS */
			mvOsPrintf("Set default CAS latency 3\n");
		}
	}

	/* calc SDRAM_CONFIG_REG  and save it to temp register */
	temp = sdramConfigRegCalc(&bankInfo[0], busClk);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG1, temp);

	/* calc SDRAM_MODE_REG  and save it to temp register */ 
	temp = sdramModeRegCalc(minCas);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG2, temp);

	/* calc SDRAM_EXTENDED_MODE_REG  and save it to temp register */ 
	temp = sdramExtModeRegCalc(&bankInfo[0]);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG10, temp);

/* calc D_UNIT_CONTROL_LOW  and save it to temp register */
	temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas); 
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG3, temp); 

	/* calc SDRAM_ADDR_CTRL_REG  and save it to temp register */
	temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG4, temp);

	/* calc SDRAM_TIMING_CTRL_LOW_REG  and save it to temp register */
	temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG5, temp);

	/* calc SDRAM_TIMING_CTRL_HIGH_REG  and save it to temp register */
	temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
	if(-1 == temp)
	{
		mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
		return MV_ERROR;
	}
	MV_REG_WRITE(DRAM_BUF_REG6, temp);

	/* Config DDR2 On Die Termination (ODT) registers */
	if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
	{
		sdramDDr2OdtConfig(bankInfo);
	}
	
	/* Note that DDR SDRAM Address/Control and Data pad calibration     */
	/* settings is done in mvSdramIfConfig.s                            */

	return retVal;
}