MV_STATUS mvCtrlAddrWinInfoGet(MV_UNIT_WIN_INFO *pAddrWinInfo, MV_ULONG physAddr)
{
	MV_CPU_DEC_WIN cpuAddrDecWin;
	MV_U32 i;
	MV_TARGET_ATTRIB targetAttrib;
	MV_STATUS status;

	for (i = 0; i < MAX_TARGETS; i++) {
		status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin);
		if (status != MV_OK)
			continue;

		if ((physAddr >= cpuAddrDecWin.addrWin.baseLow) &&
		    (physAddr < cpuAddrDecWin.addrWin.baseLow + cpuAddrDecWin.addrWin.size)) {
			/* Found */
			pAddrWinInfo->addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
			pAddrWinInfo->addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
			pAddrWinInfo->addrWin.size = cpuAddrDecWin.addrWin.size;

			if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) {
				mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCtrlAttribGet() failed.\n");
				return MV_ERROR;
			}
			pAddrWinInfo->attrib = targetAttrib.attrib;
			pAddrWinInfo->targetId = targetAttrib.targetId;
			return MV_OK;
		}
	}
	/* not found */
	return MV_NOT_FOUND;
}
/*******************************************************************************
* 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;

}
/*******************************************************************************
* mvAudioWinSet - Set AUDIO target address window
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) 
*       address window, also known as address decode window. 
*       After setting this target window, the AUDIO will be able to access the 
*       target within the address window. 
*
* INPUT:
*       winNum      - AUDIO target address decode window number.
*       pAddrDecWin - AUDIO target window data structure.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_ERROR if address window overlapps with other address decode windows.
*       MV_BAD_PARAM if base address is invalid parameter or target is 
*       unknown.
*
*******************************************************************************/
MV_STATUS mvAudioWinSet(int unit, MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
{
    MV_TARGET_ATTRIB    targetAttribs;
    MV_DEC_REGS         decRegs;

    /* Parameter checking   */
    if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
    {
        mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
        return MV_BAD_PARAM;
    }
    
    /* check if address is aligned to the size */
    if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
    {
		mvOsPrintf("mvAudioWinSet:Error setting AUDIO 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;
    }

    decRegs.baseReg = 0;
    decRegs.sizeReg = 0;

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

    mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
                                                                                                                         
    /* set attributes */
    decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
    decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);

    /* set target ID */
    decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
    decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);

    if (pAddrDecWin->enable == MV_TRUE)
    {
        decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
    }
    else
    {
        decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
    }

    MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(unit, winNum), decRegs.sizeReg);
    MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(unit, winNum), decRegs.baseReg);
    
    return MV_OK;
}
/*******************************************************************************
* mvCtrlAddrWinMapBuild
*
* DESCRIPTION:
*	Build the windows address decoding table, to be used for initializing
*	the unit's address decoding windows.
*
* INPUT:
*	pAddrWinMap: An array to hold the address decoding windows parameters.
*	len: Number of entries in pAddrWinMap.
*
* OUTPUT:
*	pAddrWinMap: Address window information.
*
* RETURN:
*	MV_BAD_PARAM: input array is smaller than needed to store all window
*	addresses.
*	MV_ERROR: Otherwise.
*
*******************************************************************************/
MV_STATUS mvCtrlAddrWinMapBuild(MV_UNIT_WIN_INFO *pAddrWinMap, MV_U32 len)
{
	MV_CPU_DEC_WIN cpuAddrDecWin;
	MV_U32 i;
	MV_TARGET_ATTRIB targetAttrib;
	MV_STATUS status;

	/* Check size of CPU address win table */
	if (len <= MAX_TARGETS) {
		mvOsPrintf("mvCtrlAddrWinMapBuild() - Table size too small.\n");
		return MV_BAD_PARAM;
	}

	/* Fill in the pAddrWinMap fields       */
	for (i = 0; i < MAX_TARGETS; i++) {
		status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin);
		if (status != MV_OK) {
			if (status == MV_NO_SUCH) {
				pAddrWinMap[i].enable = MV_FALSE;
				continue;
			} else {
				mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCpuIfTargetWinGet() failed.\n");
				return MV_ERROR;
			}
		}

		pAddrWinMap[i].addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
		pAddrWinMap[i].addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
		pAddrWinMap[i].addrWin.size = cpuAddrDecWin.addrWin.size;
		pAddrWinMap[i].enable = cpuAddrDecWin.enable;

		if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) {
			mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCtrlAttribGet() failed.\n");
			return MV_ERROR;
		}
		pAddrWinMap[i].attrib = targetAttrib.attrib;
		pAddrWinMap[i].targetId = targetAttrib.targetId;
	}
	pAddrWinMap[i].addrWin.baseLow = TBL_TERM;
	pAddrWinMap[i].addrWin.baseHigh = TBL_TERM;
	pAddrWinMap[i].addrWin.size = TBL_TERM;
	pAddrWinMap[i].enable = TBL_TERM;
	pAddrWinMap[i].attrib = TBL_TERM;
	pAddrWinMap[i].targetId = TBL_TERM;

	return MV_OK;
}
/*
 * 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;
}
Exemple #6
0
/*******************************************************************************
* mvDmaWinSet - Set DMA target address window
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) 
*       address window, also known as address decode window. 
*       After setting this target window, the DMA will be able to access the 
*       target within the address window. 
*
* INPUT:
*       winNum      - IDMA to target address decode window number.
*       pAddrDecWin - IDMA target window data structure.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_ERROR if address window overlapps with other address decode windows.
*       MV_BAD_PARAM if base address is invalid parameter or target is 
*       unknown.
*
*******************************************************************************/
MV_STATUS mvDmaWinSet(MV_U32 winNum, MV_DMA_DEC_WIN *pAddrDecWin)
{
	MV_TARGET_ATTRIB targetAttribs;
        MV_DEC_REGS decRegs;

    /* Parameter checking   */
    if (winNum >= IDMA_MAX_ADDR_DEC_WIN)
    {
		mvOsPrintf("mvDmaWinSet: ERR. Invalid win num %d\n",winNum);
        return MV_BAD_PARAM;
    }
    
    /* Check if the requested window overlapps with current windows         */
    if (MV_TRUE == dmaWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
   	{
        	mvOsPrintf("mvDmaWinSet: ERR. Window %d overlap\n", winNum);
		return MV_ERROR;
	}

	/* check if address is aligned to the size */
	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
	{
		mvOsPrintf("mvDmaWinSet: Error setting IDMA 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;
	}


	decRegs.baseReg = MV_REG_READ(IDMA_BASE_ADDR_REG(winNum));
	decRegs.sizeReg = MV_REG_READ(IDMA_SIZE_REG(winNum));

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

#if defined(MV_88F5182) || defined(MV_88F5181L)
    /* See BTS Nastore  #19.*/
    /* To access Tunit SRAM from IDMA use targetId = 0x5 */
    /* To access Tunit SRAM from the CPU use targetId = 0x9 */
    if(pAddrDecWin->target == CRYPT_ENG)
        targetAttribs.targetId = 5;
#endif /* defined(MV_88F5182) || defined(MV_88F5181L) */

	/* set attributes */
	decRegs.baseReg &= ~IDMA_WIN_ATTR_MASK;
	decRegs.baseReg |= targetAttribs.attrib << IDMA_WIN_ATTR_OFFS;
	/* set target ID */
	decRegs.baseReg &= ~IDMA_WIN_TARGET_MASK;
	decRegs.baseReg |= targetAttribs.targetId << IDMA_WIN_TARGET_OFFS;
	
	/* for the safe side we disable the window before writing the new
	values */
	mvDmaWinEnable(winNum,MV_FALSE);

	MV_REG_WRITE(IDMA_BASE_ADDR_REG(winNum), decRegs.baseReg);

	/* Write to address decode Size Register                             */
	MV_REG_WRITE(IDMA_SIZE_REG(winNum), decRegs.sizeReg);

	/* Enable address decode target window                               */
	if (pAddrDecWin->enable == MV_TRUE)
	{
    	mvDmaWinEnable(winNum, MV_TRUE);
	}
    
	return MV_OK;
}
Exemple #7
0
/*******************************************************************************
* mvTsuWinSet
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
*       address window, also known as address decode window.
*       After setting this target window, the TSU will be able to access the
*       target within the address window.
*
* INPUT:
*       winNum      - TSU to target address decode window number.
*       pAddrDecWin - TSU target window data structure.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_ERROR	- if address window overlapps with other address decode
*			windows.
*       MV_BAD_PARAM	- if base address is invalid parameter or target is
*			unknown.
*
*******************************************************************************/
MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
{
	MV_TARGET_ATTRIB    targetAttribs;
	MV_DEC_REGS         decRegs;

	/* Parameter checking   */
	if(winNum >= TSU_MAX_DECODE_WIN)
	{
		mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
		return MV_BAD_PARAM;
	}

	/* Check if the requested window overlapps with current windows     */
	if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
	{
		mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
		return MV_ERROR;
	}

	/* check if address is aligned to the size */
	if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
	{
		mvOsPrintf("mvTsuWinSet: Error setting TSU 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;
	}

	decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
	decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));

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

	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);

	/* set attributes */
	decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
	decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
	/* set target ID */
	decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
	decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;

	/* for the safe side we disable the window before writing the new */
	/* values */
	mvTsuWinEnable(winNum, MV_FALSE);
	MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);

	/* Write to address decode Size Register                            */
	MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);

	/* Enable address decode target window                              */
	if(pAddrDecWin->enable == MV_TRUE)
	{
		mvTsuWinEnable(winNum,MV_TRUE);
	}

	return MV_OK;
}
Exemple #8
0
/*******************************************************************************
* mvXorTargetWinSet - Set XOR target address window
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0) 
*       address window. After setting this target window, the XOR will be 
*       able to access the target within the address window. 
*
* INPUT:
*	    winNum - One of the possible XOR memory decode windows.
*       target - Peripheral target enumerator.
*       base   - Window base address.
*       size   - Window size.
*       enable - Window enable/disable.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
*
*******************************************************************************/
MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
{
    MV_DEC_REGS xorDecRegs;
	MV_TARGET_ATTRIB targetAttribs;
    MV_U32      chan;
    
    /* Parameter checking */
    if (winNum >= XOR_MAX_ADDR_DEC_WIN)
    {
		DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
        return MV_BAD_PARAM;
    }
    if (pAddrDecWin == NULL)
    {
        DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
        return MV_BAD_PTR;
    }                                         
    /* Check if the requested window overlaps with current windows */
    if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
    {
	DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
	return MV_ERROR;
    }                              

    xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
    xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));

    /* Get Base Address and size registers values */
    if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
    {
		DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
        return MV_BAD_PARAM;
	}
    

	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);

	/* set attributes */
	xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
	xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
	/* set target ID */
	xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
	xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;


    /* Write to address decode Base Address Register */
	MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
    
    /* Write to Size Register */
	MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
    
    for (chan = 0; chan < MV_XOR_MAX_CHAN; chan++)
    {
        if (pAddrDecWin->enable)
        {
            MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
                           XEXWCR_WIN_EN_MASK(winNum));
        }
        else
        {
            MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
                             XEXWCR_WIN_EN_MASK(winNum));
        }
    }
    return MV_OK;
}
Exemple #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;
}
Exemple #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;
}
Exemple #11
0
/*******************************************************************************
* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
*
* DESCRIPTION:
*
* INPUT:
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_OK if PEX BAR target window was set correctly, 
*		MV_BAD_PARAM on bad params 
*       MV_ERROR otherwise 
*       (e.g. address window overlapps with other active PEX target window).
*
*******************************************************************************/
MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum, 
                            MV_PEX_DEC_WIN *pAddrDecWin)
{

	MV_DEC_REGS decRegs;
	PEX_WIN_REG_INFO winRegInfo;
	MV_TARGET_ATTRIB targetAttribs;

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

	if (winNum >= PEX_MAX_TARGET_WIN)
	{
		mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
		return MV_BAD_PARAM;

	}

	/* get the pex Window registers offsets */
	pexWinRegInfoGet(pexIf,winNum,&winRegInfo);


	if (MV_TRUE == pAddrDecWin->enable)
	{

		/* 2) Check if the requested window overlaps with current windows  */
		if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
		{
			mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
			return MV_BAD_PARAM;
		}
	
		/* 2) Check if the requested window overlaps with current windows  */
		if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
		{
			mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
					   winNum);
			return MV_BAD_PARAM;
		}

	}



	/* read base register*/
	
	if (winRegInfo.baseLowRegOffs)
	{
		decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
	}
	else
	{
		decRegs.baseReg = 0;
	}

	if (winRegInfo.sizeRegOffs)
	{
		decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
	}
	else
	{
		decRegs.sizeReg =0;
	}
	
	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
	{
		mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
		return MV_ERROR;		
	}

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


	/* clear bit location */
	decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;

	/* set bar Mapping */
	if (pAddrDecWin->targetBar == 1)
	{
		decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
	}
	else if (pAddrDecWin->targetBar == 2)
	{
		decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
	}

	mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);

	/* set attributes */
	decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
	decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
	/* set target ID */
	decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
	decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;


	/* 3) Write to address decode Base Address Register                   */

	if (winRegInfo.baseLowRegOffs)
	{
		MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
	}

	/* write size reg */
	if (winRegInfo.sizeRegOffs)
	{
		if ((MV_PEX_WIN_DEFAULT == winNum)||
			(MV_PEX_WIN_EXP_ROM == winNum))
		{
			/* clear size because there is no size field*/
			decRegs.sizeReg &= ~PXWCR_SIZE_MASK;

			/* clear enable because there is no enable field*/
			decRegs.sizeReg &= ~PXWCR_WIN_EN;

		}

		MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
	}


    return MV_OK;

}
/*******************************************************************************
* mvCtrlAddrWinMapBuild
*
* DESCRIPTION:
*	Build the windows address decoding table, to be used for initializing
*	the unit's address decoding windows.
*
* INPUT:
*	pAddrWinMap: An array to hold the address decoding windows parameters.
*	len: Number of entries in pAddrWinMap.
*
* OUTPUT:
*	pAddrWinMap: Address window information.
*
* RETURN:
*	MV_BAD_PARAM: input array is smaller than needed to store all window
*	addresses.
*	MV_ERROR: Otherwise.
*
*******************************************************************************/
MV_STATUS mvCtrlAddrWinMapBuild(MV_UNIT_WIN_INFO *pAddrWinMap, MV_U32 len)
{
	MV_CPU_DEC_WIN cpuAddrDecWin;
	MV_U32 i, j;
	MV_TARGET_ATTRIB targetAttrib;
	MV_STATUS status;
	MV_U64 startAddr, endAddr;
	MV_UNIT_WIN_INFO ioDdrWin[MV_DRAM_MAX_CS];
	MV_U32 base;
	MV_U64 size;

	/* Check size of CPU address win table */
	if (len <= MAX_TARGETS) {
		mvOsPrintf("mvCtrlAddrWinMapBuild() - Table size too small.\n");
		return MV_BAD_PARAM;
	}

	/* Prepare an array of DRAM info */
	base = 0x0;
	j = 0;
	for (i = SDRAM_CS0; i <= SDRAM_CS3; i++) {
		status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin);
		if (status != MV_OK) {
			if (status == MV_NO_SUCH) {
				ioDdrWin[i].enable = MV_FALSE;
				continue;
			} else {
				mvOsPrintf("mvCtrlAddrWinMapBuild() - mvCpuIfTargetWinGet() failed.\n");
				return MV_ERROR;
			}
		}

		/* As all IO address decode windows support only 32-bit
		** addresses, limit the DRAM base / size to 4GB max.
		*/
		startAddr = (MV_U64)((((MV_U64)cpuAddrDecWin.addrWin.baseHigh << 32ll)) +
				(MV_U64)cpuAddrDecWin.addrWin.baseLow);
		endAddr = (MV_U64)(startAddr + (MV_U64)cpuAddrDecWin.addrWin.size) - 1;
		if (endAddr > 0xFFFFFFFFll) {
			if (startAddr <= 0xFFFFFFFFll)
				cpuAddrDecWin.addrWin.size = (0x100000000ll -
						cpuAddrDecWin.addrWin.baseLow);
			else
				cpuAddrDecWin.enable = MV_FALSE;
		}

		if (cpuAddrDecWin.enable == MV_FALSE)
			continue;

		/* If the endAddr passes minBase, then we need to split
		** this window to several windows up to minBase.
		** For example: minBase=0xE0000000, and CS0=2, CS1=2G,
		** Then we need to split the windwos as follows:
		** Win0: CS-0, 2GB (Base 0x0)
		** win1: CS-1, 1GB (Base 0x80000000)
		** Win2: CS-1, 0.5GB (Base 0xC0000000)
		*/
		if (endAddr > MV_DRAM_IO_RESERVE_BASE)
			/* Need to cut down this CS to IO reserve base
			** address.
			*/
			size = MV_DRAM_IO_RESERVE_BASE -
				cpuAddrDecWin.addrWin.baseLow;
		else
			size = cpuAddrDecWin.addrWin.size;

		if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) {
			mvOsPrintf("mvCtrlAddrWinMapBuild() - "
					"mvCtrlAttribGet() failed.\n");
			return MV_ERROR;
		}
		/* Now, spread the last CS into several windows, and make sure
		** that each of has a power-of-2 size.
		*/
		while (size != 0) {
			ioDdrWin[j].enable = MV_TRUE;
			ioDdrWin[j].attrib = targetAttrib.attrib;
			ioDdrWin[j].targetId = targetAttrib.targetId;
			ioDdrWin[j].addrWin.baseHigh = 0;
			if (MV_IS_POWER_OF_2(size))
				ioDdrWin[j].addrWin.size = size;
			else
				ioDdrWin[j].addrWin.size = (MV_U64)(1ll << (MV_U64)mvLog2(size));
			size -= ioDdrWin[j].addrWin.size;
			ioDdrWin[j].addrWin.baseLow = base;
			base += ioDdrWin[j].addrWin.size;
			j++;
		}
		/* Support only up to 4 DRAM address decode windows in the
		** units. */
		if (j == MV_DRAM_MAX_CS)
			break;
	}
	
	for (; j < MV_DRAM_MAX_CS; j++)
		ioDdrWin[j].enable = MV_FALSE;

	/* Fill in the pAddrWinMap fields       */
	for (i = 0; i < MAX_TARGETS; i++) {
		if (MV_TARGET_IS_DRAM(i)) {
			pAddrWinMap[i].addrWin.baseLow = ioDdrWin[i].addrWin.baseLow;
			pAddrWinMap[i].addrWin.baseHigh = ioDdrWin[i].addrWin.baseHigh;
			pAddrWinMap[i].addrWin.size = ioDdrWin[i].addrWin.size;
			pAddrWinMap[i].enable = ioDdrWin[i].enable;
			pAddrWinMap[i].attrib = ioDdrWin[i].attrib;
			pAddrWinMap[i].targetId = ioDdrWin[i].targetId;
		} else {
			status = mvCpuIfTargetWinGet(i, &cpuAddrDecWin);
			if (status != MV_OK) {
				if (status == MV_NO_SUCH) {
					pAddrWinMap[i].enable = MV_FALSE;
					continue;
				} else {
					mvOsPrintf("mvCtrlAddrWinMapBuild()"
					" - mvCpuIfTargetWinGet() failed.\n");
					return MV_ERROR;
				}
			}

			pAddrWinMap[i].addrWin.baseLow =
				cpuAddrDecWin.addrWin.baseLow;
			pAddrWinMap[i].addrWin.baseHigh =
				cpuAddrDecWin.addrWin.baseHigh;
			pAddrWinMap[i].addrWin.size =
				cpuAddrDecWin.addrWin.size;
			pAddrWinMap[i].enable = cpuAddrDecWin.enable;

			if (mvCtrlAttribGet(i, &targetAttrib) != MV_OK) {
				mvOsPrintf("mvCtrlAddrWinMapBuild() - "
						"mvCtrlAttribGet() failed.\n");
				return MV_ERROR;
			}
			pAddrWinMap[i].attrib = targetAttrib.attrib;
			pAddrWinMap[i].targetId = targetAttrib.targetId;
		}
	}
	pAddrWinMap[i].addrWin.baseLow = TBL_TERM;
	pAddrWinMap[i].addrWin.baseHigh = TBL_TERM;
	pAddrWinMap[i].addrWin.size = TBL_TERM;
	pAddrWinMap[i].enable = TBL_TERM;
	pAddrWinMap[i].attrib = TBL_TERM;
	pAddrWinMap[i].targetId = TBL_TERM;

	return MV_OK;
}
Exemple #13
0
* mvTdmWinSet - Set TDM target address window
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
*       address window, also known as address decode window.
*       After setting this target window, the TDM will be able to access the
*       target within the address window.
*
* INPUT:
*       winNum      - TDM to target address decode window number.
*       pAddrDecWin - TDM target window data structure.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_ERROR if address window overlapps with other address decode windows.
*       MV_BAD_PARAM if base address is invalid parameter or target is
*       unknown.
*
*******************************************************************************/

MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
{
	MV_TARGET_ATTRIB targetAttribs;
	MV_DEC_REGS decRegs;
	MV_U32 ctrlReg = 0;

    /* Parameter checking   */
    if (winNum >= TDM_MBUS_MAX_WIN)
    {
		mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
        return MV_BAD_PARAM;
    }
    
    /* Check if the requested window overlapps with current windows         */
    if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
   	{
       	mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
		return MV_ERROR;
	}

	/* check if address is aligned to the size */
	if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
	{
		mvOsPrintf("mvTdmWinSet: Error setting TDM 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;
	}

	decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
	decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >>  TDM_WIN_SIZE_OFFS;

	if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
	{
			mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
			return MV_ERROR;
	}
	
	mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
	
	/* for the safe side we disable the window before writing the new
	values */
	mvTdmWinEnable(winNum, MV_FALSE);

	ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
	ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
	ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);

	/* Write to address base and control registers  */
	MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
	MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);  
	/* Enable address decode target window  */
	if (pAddrDecWin->enable == MV_TRUE)
	{
		mvTdmWinEnable(winNum, MV_TRUE);
	}    
	return MV_OK;
}