예제 #1
0
/*******************************************************************************
* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
*
* DESCRIPTION:
*       This function enable/disable a CPU address decode window.
*       if parameter 'enable' == MV_TRUE the routine will enable the
*       window, thus enabling CPU accesses (before enabling the window it is
*       tested for overlapping). Otherwise, the window will be disabled.
*
* INPUT:
*       winNum - Peripheral winNum enumerator.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_ERROR if protection window number was wrong, or the window
*       overlapps other winNum window.
*
*******************************************************************************/
MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
{

	/* Parameter checking   */
	if (winNum >= MAX_AHB_TO_MBUS_WINS)
	{
		mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
		return MV_NOT_SUPPORTED;
	}

	/* Internal registers bar can't be disable or enabled */
	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
	{
		return (enable ? MV_OK : MV_ERROR);
	}

    if (enable == MV_TRUE)
    {
		/* enable the window */
		MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
    }
    else
    {   /* Disable address decode winNum window                             */
		MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
    }

	return MV_OK;
}
예제 #2
0
MV_VOID mvAhbToMbusCpuWinCopy(MV_VOID)
{
    MV_U32 winNum;

    for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ ) 
    {
	    if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	    {
		MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(1, winNum),
		    MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(0, winNum)));
		MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(1, winNum),
		    MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(0, winNum)));
		/* We have remap register only for win [7..0] */
		if (winNum != MAX_AHB_TO_MBUS_REMAP_WINS)
		{
		    MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(1, winNum), 
			MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(0, winNum)));
		    MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(1, winNum),
			MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(0, winNum)));
		}
	    }
	    else
	    {
		MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG(1),
		    MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG(0)));
	    }
    }
}
예제 #3
0
/*******************************************************************************
* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
*
* DESCRIPTION:
*		Get the CPU peripheral winNum address window.
*
* INPUT:
*       winNum - Peripheral winNum enumerator
*
* OUTPUT:
*       pAddrDecWin - CPU winNum window information data structure.
*
* RETURN:
*       MV_OK if winNum exist, MV_ERROR otherwise.
*
*******************************************************************************/
MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
{
	MV_DEC_REGS decRegs;
	MV_TARGET_ATTRIB targetAttrib;
	MV_U32 sizeRegVal;

	/* Parameter checking   */
	if (winNum >= MAX_AHB_TO_MBUS_WINS) {
		mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
		return MV_NOT_SUPPORTED;
	}

	/* Internal register space size have no size register */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
		decRegs.ctrlReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
	else
		decRegs.ctrlReg = 0;

	/* Read base and size   */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
	else
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);

	pAddrDecWin->addrWin.baseHigh = 0;
	pAddrDecWin->addrWin.baseLow = decRegs.baseReg & ATMWBR_BASE_MASK;
	sizeRegVal = (decRegs.ctrlReg & ATMWCR_WIN_SIZE_MASK) >> ATMWCR_WIN_SIZE_OFFS;
	pAddrDecWin->addrWin.size = (sizeRegVal + 1) * ATMWCR_WIN_SIZE_ALIGNMENT;

	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN) {
		pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
		pAddrDecWin->target = INTER_REGS;
		pAddrDecWin->enable = MV_TRUE;

		return MV_OK;
	}

	if (decRegs.ctrlReg & ATMWCR_WIN_ENABLE)
		pAddrDecWin->enable = MV_TRUE;
	else
		pAddrDecWin->enable = MV_FALSE;

	if (-1 == pAddrDecWin->addrWin.size)
		return MV_ERROR;

	/* attrib and targetId */
	targetAttrib.attrib = (decRegs.ctrlReg & ATMWCR_WIN_ATTR_MASK) >> ATMWCR_WIN_ATTR_OFFS;
	targetAttrib.targetId = (decRegs.ctrlReg & ATMWCR_WIN_TARGET_MASK) >> ATMWCR_WIN_TARGET_OFFS;

	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);

	return MV_OK;
}
예제 #4
0
/*******************************************************************************
* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
*
* DESCRIPTION:
*       After a CPU address hits one of PCI address decode windows there is an
*       option to remap the address to a different one. For example, CPU
*       executes a read from PCI winNum window address 0x1200.0000. This
*       can be modified so the address on the PCI bus would be 0x1400.0000
*       Using the PCI address remap mechanism.
*
* INPUT:
*       winNum      - Peripheral winNum enumerator. Must be a PCI winNum.
*       pAddrDecWin - CPU winNum window information data structure.
*                     Note that caller has to fill in the base field only. The
*                     size field is ignored.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
*
*******************************************************************************/
MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
{
	MV_U32 baseAddr;
	AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
	MV_U32 effectiveBaseAddress = 0, baseAddrValue = 0, windowSizeValue = 0;

	/* Get registers offsets of given winNum                */
	if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
		return 0xffffffff;

	/* 1) Set address remap low */
	baseAddr = pAddrWin->baseLow;

	/* Check base address aligment                                  */
	/*
	   if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
	   {
	   mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
	   baseAddr);
	   return MV_ERROR;
	   }
	 */

	/* BaseLow[31:16] => base register [31:16]              */
	baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;

	MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
	MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);

	baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
	windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));

	baseAddrValue &= ATMWBR_BASE_MASK;
	windowSizeValue &= ATMWCR_WIN_SIZE_MASK;

	/* Start calculating the effective Base Address */
	effectiveBaseAddress = baseAddrValue;

	/* The effective base address will be combined from the chopped (if any)
	   remap value (according to the size value and remap mechanism) and the
	   window's base address */
	effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
	/* If the effectiveBaseAddress exceed the window boundaries return an
	   invalid value. */

	if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff))) {
		mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
		return 0xffffffff;
	}

	return effectiveBaseAddress;
}
/*
 * Straight forward function what returns _only_ the index of the
 * memory window according to provided SoC target.
 */
MV_STATUS mvAhbToMbusWinNumByTargetGet(MV_TARGET target, MV_U32 *pWinNum)
{
	MV_TARGET_ATTRIB targetAttribs;
	MV_U32 winNum, ctrlReg, targetId;

	if (pWinNum == NULL) {
		mvOsPrintf("%s: Error: pWinNum is NULL\n", __func__);
		return MV_FAIL;
	}

	if (target >= MAX_TARGETS) {
		mvOsPrintf("%s: Error: target %d is illegal\n", __func__, target);
		return MV_FAIL;
	}

	if (target == INTER_REGS) {
		*pWinNum = MV_AHB_TO_MBUS_INTREG_WIN;
		return MV_OK;
	}

	if (mvCtrlAttribGet(target, &targetAttribs) != MV_OK) {
		mvOsPrintf("%s: Error: mvCtrlAttribGet(target = %d) failed\n",
			   __func__, target);
		return MV_FAIL;
	}

	for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++) {
		if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
			continue;

		ctrlReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
		targetId = (ctrlReg & ATMWCR_WIN_TARGET_MASK) >> ATMWCR_WIN_TARGET_OFFS;

		if (targetId == targetAttribs.targetId) {
			*pWinNum = winNum;
			return MV_OK;
		}

	}

	return MV_FAIL;
}
예제 #6
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);
			
			}
예제 #7
0
/*******************************************************************************
* mvCpuIfInit - Initialize Controller CPU interface
*
* DESCRIPTION:
*       This function initialize Controller CPU interface:
*       1. Set CPU interface configuration registers.
*       2. Set CPU master Pizza arbiter control according to static
*          configuration described in configuration file.
*       3. Opens CPU address decode windows. DRAM windows are assumed to be
*		   already set (auto detection).
*
* INPUT:
*       None.
*
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
{
    MV_U32 regVal;
    MV_TARGET target;
    MV_ADDR_WIN addrWin;
    int ii;

    if (cpuAddrWinMap == NULL)
    {
        DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
        return MV_ERROR;
    }

    /* Set ARM Configuration register */
    regVal  = MV_REG_READ(CPU_CONFIG_REG);
    regVal &= ~CPU_CONFIG_DEFAULT_MASK;
    /* regVal |= CPU_CONFIG_DEFAULT; Note: not needed */
    MV_REG_WRITE(CPU_CONFIG_REG,regVal);


    /* First disable all CPU target windows  */
    for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
    {
        if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
        {
            continue;
        }

#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
        /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
        if (MV_TARGET_IS_PCI(target))
        {
            continue;
        }
#endif

#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
        /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
        if (MV_TARGET_IS_PEX(target))
        {
            continue;
        }
#endif
#if defined(MV_RUN_FROM_FLASH)
        /* Don't disable the boot device.                               */
        if (target == DEV_BOOCS)
        {
            continue;
        }
#endif /* MV_RUN_FROM_FLASH */
        mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
    }

    /* TODO */
    for (ii = 0; ii < 8; ii++)
        MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(ii), 0);

#if defined(MV_RUN_FROM_FLASH)
    /* Resize the bootcs windows before other windows, because this     */
    /* window is enabled and will cause an overlap if not resized.      */
    target = DEV_BOOCS;

    if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
    {
        DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
        return MV_ERROR;
    }

    addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
    addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
    if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
    {
        DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
                      cpuAddrWinMap[target].winNum));
    }

#endif /* MV_RUN_FROM_FLASH */

    /* Go through all targets in user table until table terminator			*/
    for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
    {

#if defined(MV_RUN_FROM_FLASH)
        if (target == DEV_BOOCS)
        {
            continue;
        }
#endif /* MV_RUN_FROM_FLASH */

        /* if DRAM auto sizing is used do not initialized DRAM target windows, 	*/
        /* assuming this already has been done earlier.							*/
#ifdef	MV_DRAM_AUTO_SIZE
        if (MV_TARGET_IS_DRAM(target))
        {
            continue;
        }
#endif

#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
        /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
        if (MV_TARGET_IS_PCI(target))
        {
            continue;
        }
#endif

#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
        /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
        if (MV_TARGET_IS_PEX(target))
        {
            continue;
        }
#endif
        /* If the target attribute is the same as the boot device attribute */
        /* then it's stays disable */
        if (MV_TARGET_IS_AS_BOOT(target))
        {
            continue;
        }

        if((0 == cpuAddrWinMap[target].addrWin.size) ||
                (DIS == cpuAddrWinMap[target].enable))

        {
            if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
            {
                DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
                return MV_ERROR;
            }

        }
        else
        {
            if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
            {
                DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
                return MV_ERROR;
            }

            addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
            addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
            if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
            {
                DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
                              cpuAddrWinMap[target].winNum));
            }


        }
    }

#ifdef MV_INCLUDE_PEX
    mvCpuIfEnablePex();
#endif

#ifdef MV_INCLUDE_PMU
    mvCpuIfEnablePmu();
#endif
    return MV_OK;


}
예제 #8
0
/*******************************************************************************
* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
*
* DESCRIPTION:
*		Get the CPU peripheral winNum address window.
*
* INPUT:
*       winNum - Peripheral winNum enumerator
*
* OUTPUT:
*       pAddrDecWin - CPU winNum window information data structure.
*
* RETURN:
*       MV_OK if winNum exist, MV_ERROR otherwise.
*
*******************************************************************************/
MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
{
	MV_DEC_REGS decRegs;
	MV_TARGET_ATTRIB targetAttrib;


	/* Parameter checking   */
	if (winNum >= MAX_AHB_TO_MBUS_WINS)
	{
		mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
		return MV_NOT_SUPPORTED;
	}


	/* Internal register space size have no size register*/
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		decRegs.sizeReg =  MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
	}
	else
	{
		decRegs.sizeReg = 0;
	}


	/* Read base and size	*/
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
	}
	else
	{
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
	}



	if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
	{
		mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
		return MV_ERROR;
	}

	if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
	{
        pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
		pAddrDecWin->target = INTER_REGS;
		pAddrDecWin->enable = MV_TRUE;

		return MV_OK;
	}


	if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
	{
		pAddrDecWin->enable = MV_TRUE;
	}
	else
	{
		pAddrDecWin->enable = MV_FALSE;

	}



	if (-1 == pAddrDecWin->addrWin.size)
	{
		return MV_ERROR;
	}

	/* attrib and targetId */
	targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
													ATMWCR_WIN_ATTR_OFFS;
	targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
													ATMWCR_WIN_TARGET_OFFS;

	pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);

	return MV_OK;
}
예제 #9
0
/*******************************************************************************
* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
*
* DESCRIPTION:
*       This function sets
*       address window, also known as address decode window.
*       A new address decode window is set for specified winNum address window.
*       If address decode window parameter structure enables the window,
*       the routine will also enable the winNum window, allowing CPU to access
*       the winNum window.
*
* INPUT:
*       winNum      - Windows number.
*       pAddrDecWin - CPU winNum window data structure.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
*       address window overlapps with other active CPU winNum window or
*		trying to assign 36bit base address while CPU does not support that.
*       The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
*
*******************************************************************************/
MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
{
	MV_TARGET_ATTRIB targetAttribs;
	MV_DEC_REGS decRegs;

	/* Parameter checking   */
	if (winNum >= MAX_AHB_TO_MBUS_WINS)
	{
		mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
		return MV_NOT_SUPPORTED;
	}


	/* read base register*/
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
	}
	else
	{
		decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
	}

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

	/* read control register*/
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
	}

	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
	{
		mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
		return MV_ERROR;
	}

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

	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);

	/* set attributes */
	decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
	decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
	/* set target ID */
	decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
	decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;

#if !defined(MV_RUN_FROM_FLASH)
    /* To be on the safe side we disable the window before writing the  */
    /* new values.                                                      */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		mvAhbToMbusWinEnable(winNum,MV_FALSE);
	}
#endif

	/* 3) Write to address decode Base Address Register                   */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
	}
	else
	{
		MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
	}


	/* Internal register space have no size	*/
	/* register. Do not perform size register assigment for those targets 	*/
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
	{
		/* Write to address decode Size Register                        	*/
		MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
	}

    return MV_OK;
}
예제 #10
0
/*******************************************************************************
* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
*
* DESCRIPTION:
*       This function sets
*       address window, also known as address decode window.
*       A new address decode window is set for specified winNum address window.
*       If address decode window parameter structure enables the window,
*       the routine will also enable the winNum window, allowing CPU to access
*       the winNum window.
*
* INPUT:
*       winNum      - Windows number.
*       pAddrDecWin - CPU winNum window data structure.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
*       address window overlapps with other active CPU winNum window or
*		trying to assign 36bit base address while CPU does not support that.
*       The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
*
*******************************************************************************/
MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
{
	MV_TARGET_ATTRIB targetAttribs;
	MV_DEC_REGS decRegs;
	MV_U32 sizeToReg;

	/* Parameter checking   */
	if (winNum >= MAX_AHB_TO_MBUS_WINS) {
		mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
		return MV_NOT_SUPPORTED;
	}

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

	/* Size parameter validity check.                       */
	if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.size, ATMWCR_WIN_SIZE_ALIGNMENT)) {
		mvOsPrintf("mvAhbToMbusWinSet: Failed, size not aligned to 0x%x.\n", ATMWCR_WIN_SIZE_ALIGNMENT);
		return MV_BAD_PARAM;
	}

	/* Write to address decode Base Address Register        */
	decRegs.baseReg = (pAddrDecWin->addrWin.baseLow & ATMWBR_BASE_MASK);

	/* Get size register value according to window size     */
	sizeToReg = (pAddrDecWin->addrWin.size / ATMWCR_WIN_SIZE_ALIGNMENT) - 1;

	/* set size                                             */
	decRegs.ctrlReg = (sizeToReg << ATMWCR_WIN_SIZE_OFFS);

	/* enable\Disable */
	if (MV_TRUE == pAddrDecWin->enable)
		decRegs.ctrlReg |= ATMWCR_WIN_ENABLE;
	else
		decRegs.ctrlReg &= ~ATMWCR_WIN_ENABLE;

	mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);

	/* set attributes */
	decRegs.ctrlReg &= ~ATMWCR_WIN_ATTR_MASK;
	decRegs.ctrlReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
	/* set target ID */
	decRegs.ctrlReg &= ~ATMWCR_WIN_TARGET_MASK;
	decRegs.ctrlReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;

#if !defined(MV_RUN_FROM_FLASH)
	/* To be on the safe side we disable the window before writing the  */
	/* new values.                                                      */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
		mvAhbToMbusWinEnable(winNum, MV_FALSE);
#endif

	/* 3) Write to address decode Base Address Register                   */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
		MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
	else
		MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);

	/* Internal register space have no size */
	/* register. Do not perform size register assigment for those targets   */
	if (winNum != MV_AHB_TO_MBUS_INTREG_WIN) {
		/* Write to address decode Size Register                                */
		MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.ctrlReg);
	}

	return MV_OK;
}