Ejemplo n.º 1
0
/*******************************************************************************
* ddr3NewTipEccScrub - Scrub the DRAM
*
* DESCRIPTION:
*
* INPUT:
*
* OUTPUT:
*       None.
*
* RETURN:
*
*******************************************************************************/
MV_VOID	ddr3NewTipEccScrub()
{
	MV_U32 cs_c,max_cs;
	MV_U32 uiCsEna = 0;
    mvPrintf("DDR Training Sequence - Start scrubbing \n");

	max_cs = mvHwsDdr3TipMaxCSGet();
	for (cs_c = 0; cs_c < max_cs; cs_c++)
		uiCsEna |= 1 << cs_c;

	mvSysXorInit(max_cs, uiCsEna, 0x80000000, 0);

	mvXorMemInit(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
    /* wait for previous transfer completion */
    while (mvXorStateGet(0) != MV_IDLE);

	mvXorMemInit(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
    /* wait for previous transfer completion */
    while (mvXorStateGet(0) != MV_IDLE);

    /* Return XOR State */
    mvSysXorFinish();

    mvPrintf("DDR Training Sequence - End scrubbing \n");
}
Ejemplo n.º 2
0
void xor_waiton_eng(int chan)
{
    int timeout = 0;
    if(!xor_channel[chan].chan_active)
	return;
    
    while(!(MV_REG_READ(XOR_CAUSE_REG) & XOR_CAUSE_DONE_MASK(chan))) 
    {
	if(timeout > XOR_TIMEOUT)
	    goto timeout; 
	timeout++;
    }

    timeout = 0;
    while(mvXorStateGet(chan) != MV_IDLE)
    {
	if(timeout > XOR_TIMEOUT)
	    goto timeout; 
	timeout++;
    }
    /* Clear int */
    MV_REG_WRITE(XOR_CAUSE_REG, ~(XOR_CAUSE_DONE_MASK(chan)));
    xor_channel[chan].chan_active = 0;

timeout:
    if(timeout > XOR_TIMEOUT)
    {
	printk("ERR: XOR eng got timedout!!\n");
	BUG();
    }
    return;

}
Ejemplo n.º 3
0
void inline free_channel(struct xor_channel_t *channel)
{
	if(mvXorStateGet(channel->chan_num) != MV_IDLE){
		printk("ERR: %s XOR chan %d is not idle",__FUNCTION__, channel->chan_num);
		BUG();
	}
    up(&channel->sema);
}
Ejemplo n.º 4
0
/*******************************************************************************
* mvXorMemInit -
*
* DESCRIPTION:
*
*
* INPUT:
*       None.
*
* OUTPUT:
*       None.
*
* RETURN:
*
*
*******************************************************************************/
MV_STATUS mvXorMemInit(MV_U32 chan, MV_U32 startPtr, MV_U32 blockSize, MV_U32 initValHigh, MV_U32 initValLow)
{
	MV_U32 temp;

	/* Parameter checking   */
	if (chan >= MV_XOR_MAX_CHAN) {
		mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan);
		return MV_BAD_PARAM;
	}
	if (MV_ACTIVE == mvXorStateGet(chan)) {
		mvOsPrintf("%s: ERR. Channel is already active\n", __func__);
		return MV_BUSY;
	}
	if ((blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) {
		mvOsPrintf("%s: ERR. Block size must be between %d to %ul\n",
			   __func__, XEXBSR_BLOCK_SIZE_MIN_VALUE, XEXBSR_BLOCK_SIZE_MAX_VALUE);
		return MV_BAD_PARAM;
	}

	/* set the operation mode to Memory Init */
	temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	temp &= ~XEXCR_OPERATION_MODE_MASK;
	temp |= XEXCR_OPERATION_MODE_MEM_INIT;
	MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);

	/* update the startPtr field in XOR Engine [0..1] Destination Pointer
	   Register (XExDPR0) */
	MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), startPtr);

	/* update the BlockSize field in the XOR Engine[0..1] Block Size
	   Registers (XExBSR) */
	MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), blockSize);

	/* update the field InitValL in the XOR Engine Initial Value Register
	   Low (XEIVRL) */
	MV_REG_WRITE(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), initValLow);

	/* update the field InitValH in the XOR Engine Initial Value Register
	   High (XEIVRH) */
	MV_REG_WRITE(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), initValHigh);

	/* start transfer */
	MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);

	return MV_OK;
}
Ejemplo n.º 5
0
int allocate_channel(void)
{
    int chan;
    for(chan = 0; chan < XOR_MAX_CHANNELS; chan++)
    {        
        if(down_trylock(&xor_channel[chan].sema))
        {
            DPRINTK("XOR engine %d is busy\n", chan);
            continue;
        }
	if(mvXorStateGet(chan) != MV_IDLE) {
		printk("ERR: %s XOR chan %d is not idle",__FUNCTION__, chan);
	}
        return chan;
    }
    DPRINTK("XOR engines are busy, return\n");
    return -1;
}
Ejemplo n.º 6
0
/*******************************************************************************
* mvXorCommandSet - Set command of XOR channel
*
* DESCRIPTION:
*       XOR channel can be started, idle, paused and restarted.
*       Paused can be set only if channel is active.
*       Start can be set only if channel is idle or paused.
*       Restart can be set only if channel is paused.
*       Stop can be set only if channel is active.
*
* INPUT:
*       chan     - The channel number
*       command  - The command type (start, stop, restart, pause)
*
* OUTPUT:
*       None.
*
* RETURN:
*       GT_OK on success , GT_BAD_PARAM on erroneous parameter, MV_ERROR on
*       undefind XOR engine mode
*
*******************************************************************************/
GT_STATUS mvXorCommandSet(GT_U32 chan, MV_COMMAND command)
{
	MV_STATE state;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN) {
		DB(mvPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan));
		return GT_BAD_PARAM;
	}

	/* get the current state */
	state = mvXorStateGet(chan);

	/* command is start and current state is idle */
	if ((command == MV_START) && (state == MV_IDLE)) {
		MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);
		return GT_OK;
	}
	/* command is stop and current state is active */
	else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
		MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTOP_MASK);
		return GT_OK;
	}
	/* command is paused and current state is active */
	else if (((MV_STATE)command == MV_PAUSED) && (state == MV_ACTIVE)) {
		MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XEPAUSE_MASK);
		return GT_OK;
	}
	/* command is restart and current state is paused */
	else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
		MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XERESTART_MASK);
		return GT_OK;
	}

	/* command is stop and current state is active */
	else if ((command == MV_STOP) && (state == MV_IDLE))
		return GT_OK;

	/* illegal command */
	DB(mvPrintf("%s: ERR. Illegal command\n", __func__));

	return GT_BAD_PARAM;
}
Ejemplo n.º 7
0
/*******************************************************************************
* mvXorMemInit -
*
* DESCRIPTION:
*
*
* INPUT:
*       None.
*
* OUTPUT:
*       None.
*
* RETURN:
*
*
*******************************************************************************/
GT_STATUS mvXorMemInit(GT_U32 chan, GT_U32 startPtr, GT_U32 blockSize, GT_U32 initValHigh, GT_U32 initValLow)
{
	GT_U32 temp;

	/* Parameter checking   */
	if (chan >= MV_XOR_MAX_CHAN) {
		return GT_BAD_PARAM;
	}
	if (MV_ACTIVE == mvXorStateGet(chan)) {
		return GT_BUSY;
	}
	if ((blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) || (blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) {
		return GT_BAD_PARAM;
	}

	/* set the operation mode to Memory Init */
	temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	temp &= ~XEXCR_OPERATION_MODE_MASK;
	temp |= XEXCR_OPERATION_MODE_MEM_INIT;
	MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);

	/* update the startPtr field in XOR Engine [0..1] Destination Pointer
	   Register (XExDPR0) */
	MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), startPtr);

	/* update the BlockSize field in the XOR Engine[0..1] Block Size
	   Registers (XExBSR) */
	MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), blockSize);

	/* update the field InitValL in the XOR Engine Initial Value Register
	   Low (XEIVRL) */
	MV_REG_WRITE(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), initValLow);

	/* update the field InitValH in the XOR Engine Initial Value Register
	   High (XEIVRH) */
	MV_REG_WRITE(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), initValHigh);

	/* start transfer */
	MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);

	return GT_OK;
}
Ejemplo n.º 8
0
/*******************************************************************************
* mvXorTransfer - Transfer data from source to destination on one of
*                 three modes (XOR,CRC32,DMA)
*
* DESCRIPTION:
*       This function initiates XOR channel, according to function parameters,
*       in order to perform XOR or CRC32 or DMA transaction.
*       To gain maximum performance the user is asked to keep the following
*       restrictions:
*       1) Selected engine is available (not busy).
*       1) This module does not take into consideration CPU MMU issues.
*          In order for the XOR engine to access the appropreate source
*          and destination, address parameters must be given in system
*          physical mode.
*       2) This API does not take care of cache coherency issues. The source,
*          destination and in case of chain the descriptor list are assumed
*          to be cache coherent.
*       4) Parameters validity. For example, does size parameter exceeds
*          maximum byte count of descriptor mode (16M or 64K).
*
* INPUT:
*       chan          - XOR channel number. See MV_XOR_CHANNEL enumerator.
*       xorType       - One of three: XOR, CRC32 and DMA operations.
*       xorChainPtr   - address of chain pointer
*
* OUTPUT:
*       None.
*
* RETURS:
*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
*
*******************************************************************************/
MV_STATUS mvXorTransfer(MV_U32 chan, MV_XOR_TYPE xorType, MV_U32 xorChainPtr)
{
	MV_U32 temp;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN) {
		DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan));
		return MV_BAD_PARAM;
	}
	if (MV_ACTIVE == mvXorStateGet(chan)) {
		DB(mvOsPrintf("%s: ERR. Channel is already active\n", __func__));
		return MV_BUSY;
	}
	if (0x0 == xorChainPtr) {
		DB(mvOsPrintf("%s: ERR. xorChainPtr is NULL pointer\n", __func__));
		return MV_BAD_PARAM;
	}

	/* read configuration register and mask the operation mode field */
	temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	temp &= ~XEXCR_OPERATION_MODE_MASK;

	switch (xorType) {
	case MV_XOR:
		if (0 != (xorChainPtr & XEXDPR_DST_PTR_XOR_MASK)) {
			DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [5:0] must "
				      "be cleared)\n", __func__));
			return MV_BAD_PARAM;
		}
		/* set the operation mode to XOR */
		temp |= XEXCR_OPERATION_MODE_XOR;
		break;

	case MV_DMA:
		if (0 != (xorChainPtr & XEXDPR_DST_PTR_DMA_MASK)) {
			DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must "
				      "be cleared)\n", __func__));
			return MV_BAD_PARAM;
		}
		/* set the operation mode to DMA */
		temp |= XEXCR_OPERATION_MODE_DMA;
		break;

	case MV_CRC32:
		if (0 != (xorChainPtr & XEXDPR_DST_PTR_CRC_MASK)) {
			DB(mvOsPrintf("%s: ERR. Invalid chain pointer (bits [4:0] must "
				      "be cleared)\n", __func__));
			return MV_BAD_PARAM;
		}
		/* set the operation mode to CRC32 */
		temp |= XEXCR_OPERATION_MODE_CRC;
		break;

	default:
		return MV_BAD_PARAM;
	}

	/* write the operation mode to the register */
	MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
	/* update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
	   Pointer Register (XExNDPR) */
	MV_REG_WRITE(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xorChainPtr);

	/* start transfer */
	MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);

	return MV_OK;
}
Ejemplo n.º 9
0
/*******************************************************************************
* mvXorEccClean - .
*
* DESCRIPTION:
*
*
* INPUT:
*       destPtr -
*
* OUTPUT:
*       None.
*
* RETURN:
*
*******************************************************************************/
MV_STATUS mvXorEccClean(MV_U32 chan, MV_XOR_ECC *pXorEccConfig)
{
	MV_U32 tClkCycles;
	MV_U32 temp;

	/* Parameter checking   */
	if (chan >= MV_XOR_MAX_CHAN) {
		DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __func__, chan));
		return MV_BAD_PARAM;
	}
	if (NULL == pXorEccConfig) {
		DB(mvOsPrintf("%s: ERR. pXorEccConfig is NULL pointer\n", __func__));
		return MV_BAD_PTR;
	}
	if (MV_ACTIVE == mvXorStateGet(chan)) {
		DB(mvOsPrintf("%s: ERR. Channel is already active\n", __func__));
		return MV_BUSY;
	}
	if ((pXorEccConfig->sectorSize < XETMCR_SECTION_SIZE_MIN_VALUE) ||
	    (pXorEccConfig->sectorSize > XETMCR_SECTION_SIZE_MAX_VALUE)) {
		DB(mvOsPrintf("%s: ERR. sectorSize must be between %d to %d\n",
			      __func__, XETMCR_SECTION_SIZE_MIN_VALUE, XETMCR_SECTION_SIZE_MAX_VALUE));
		return MV_BAD_PARAM;
	}
	if ((pXorEccConfig->blockSize < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
	    (pXorEccConfig->blockSize > XEXBSR_BLOCK_SIZE_MAX_VALUE)) {
		DB(mvOsPrintf("%s: ERR. Block size must be between %d to %ul\n",
			      __func__, XEXBSR_BLOCK_SIZE_MIN_VALUE, XEXBSR_BLOCK_SIZE_MAX_VALUE));
		return MV_BAD_PARAM;
	}
	if (0x0 == pXorEccConfig->destPtr) {
		DB(mvOsPrintf("%s: ERR. destPtr is NULL pointer\n", __func__));
		return MV_BAD_PARAM;
	}

	/* set the operation mode to ECC */
	temp = MV_REG_READ(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	temp &= ~XEXCR_OPERATION_MODE_MASK;
	temp |= XEXCR_OPERATION_MODE_ECC;
	MV_REG_WRITE(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);

	/* update the TimerEn bit in the XOR Engine Timer Mode
	   Control Register (XETMCR) */
	if (pXorEccConfig->periodicEnable)
		MV_REG_BIT_SET(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), XETMCR_TIMER_EN_MASK);
	else
		MV_REG_BIT_RESET(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), XETMCR_TIMER_EN_MASK);

	/* update the SectionSizeCtrl bit in the XOR Engine Timer Mode Control
	   Register (XETMCR) */
	temp = MV_REG_READ(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)));
	temp &= ~XETMCR_SECTION_SIZE_CTRL_MASK;
	temp |= (pXorEccConfig->sectorSize << XETMCR_SECTION_SIZE_CTRL_OFFS);
	MV_REG_WRITE(XOR_TIMER_MODE_CTRL_REG(XOR_UNIT(chan)), temp);

	/* update the DstPtr field in the XOR Engine [0..1] Destination Pointer
	   Register (XExDPR0) */
	MV_REG_WRITE(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), pXorEccConfig->destPtr);

	/* update the BlockSize field in the XOR Engine[0..1] Block Size
	   Registers (XExBSR) */
	MV_REG_WRITE(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)), pXorEccConfig->blockSize);

	/* update the XOR Engine Timer Mode Initial Value Register (XETMIVR) */
	tClkCycles = pXorEccConfig->tClkTicks;
	MV_REG_WRITE(XOR_TIMER_MODE_INIT_VAL_REG(XOR_UNIT(chan)), tClkCycles);

	/* start transfer */
	MV_REG_BIT_SET(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)), XEXACTR_XESTART_MASK);

	return MV_OK;
}