Exemple #1
0
/*******************************************************************************
* mvXorTargetWinEnable - Enable/disable a Xor address decode window
*
* DESCRIPTION:
*       This function enable/disable a XOR address decode window.
*       if parameter 'enable' == MV_TRUE the routine will enable the 
*       window, thus enabling XOR accesses (before enabling the window it is 
*       tested for overlapping). Otherwise, the window will be disabled.
*
* INPUT:
*       winNum - Decode window number.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
*
*******************************************************************************/
MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
{
	MV_XOR_DEC_WIN  addrDecWin;
    MV_U32          chan;
    
	/* Parameter checking   */               
    if (winNum >= XOR_MAX_ADDR_DEC_WIN)
    {
        DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
        return MV_ERROR;
    }

	if (enable == MV_TRUE) 
	{
		/* Get current window */
	    if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
		{
			DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
			return MV_ERROR;
		}

		/* Check for overlapping */
	    if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
		{
			/* Overlap detected	*/
			DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
			return MV_ERROR;
		}

		/* No Overlap. Enable address decode target window */
		for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
		{
		    MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
						   XEXWCR_WIN_EN_MASK(winNum));
		}

	}
	else
	{
		/* Disable address decode target window */

		for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
		{
		    MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
							 XEXWCR_WIN_EN_MASK(winNum));
		}

	}

	return MV_OK;                  
}
Exemple #2
0
/* Audio SPDIF PlayBack related*/
MV_VOID mvSPDIFPlaybackCtrlSet(int unit, MV_SPDIF_PLAYBACK_CTRL *ctrl)
{
	if (ctrl->blockStartInternally)
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_BLOCK_START_MASK);
	}
	else
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_BLOCK_START_MASK);
	}

	if (ctrl->validityFromMemory)
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_EN_MEM_VALIDITY_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_EN_MEM_VALIDITY_MASK);
	}

	if (ctrl->userBitsFromMemory)
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_MEM_USR_EN_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_MEM_USR_EN_MASK);
	}

	if (ctrl->underrunData)
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_UNDERRUN_DATA_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_UNDERRUN_DATA_MASK);
	}

	if (ctrl->validity)
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_REG_VALIDITY_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_REG_VALIDITY_MASK);
	}

	if (ctrl->nonPcm)
	{
		MV_REG_BIT_SET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_NONPCM_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_SPDIF_PLAY_CTRL_REG(unit),ASPCR_SPDIF_PB_NONPCM_MASK);
	}
}
/*******************************************************************************
* mvPp2WinEnable - Enable/disable a ETH to target address window
*
* DESCRIPTION:
*       This function enable/disable a ETH to target address window.
*       According to parameter 'enable' the routine will enable the
*       window, thus enabling ETH accesses (before enabling the window it is
*       tested for overlapping). Otherwise, the window will be disabled.
*
* INPUT:
*       winNum - ETH to target address decode window number.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_ERROR if decode window number was wrong or enabled window overlapps.
*
*******************************************************************************/
MV_STATUS mvPp2WinEnable(MV_U32 dummy/*backward compability*/, MV_U32 winNum, MV_BOOL enable)
{
	/* Parameter checking   */
	if (winNum >= ETH_MAX_DECODE_WIN) {
		mvOsPrintf("mvPp2TargetWinEnable:ERR. Invalid winNum%d\n", winNum);
		return MV_ERROR;
	}

	if (enable)
		MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG, (1 << winNum));
	else
		/* Disable address decode target window                             */
		MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG, (1 << winNum));

	return MV_OK;
}
Exemple #4
0
/*******************************************************************************
* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
*
* DESCRIPTION:
*       This function sets the maximum number of cycles that the arbiter 
*       waits for a PCI master to respond to its grant assertion. If a 
*       PCI agent fails to respond within this time, the PCI arbiter aborts 
*       the transaction and performs a new arbitration cycle.
*       NOTE: Value must be greater than '1' for conventional PCI and 
*       greater than '5' for PCI-X.
*
* INPUT:
*       pciIf      - PCI interface number.
*       pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
*                    master detection is disabled.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
*
*******************************************************************************/
MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
{
	MV_U32 pciArbiterCtrl;
	MV_U32 pciMode;

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

	/* Checking PCI mode and if pClkCycles is legal value */
	pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
	pciMode &= PMR_PCI_MODE_MASK;

	if (PMR_PCI_MODE_CONV == pciMode)
	{
		if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN) 
			return MV_ERROR;
	}
	else
	{
		if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN) 
			return MV_ERROR;
	}

	pClkCycles <<= PACR_BROKEN_VAL_OFFS;

	/* Reading Arbiter Control register */
	pciArbiterCtrl  = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
	pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
	pciArbiterCtrl |= pClkCycles;

	/* Arbiter must be disabled before changing broken detection */
	MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE); 

	/* writing new value ( if th earbiter was enabled before the change 	*/
	/* here it will be reenabled 											*/

	MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);

	return MV_OK;
}
Exemple #5
0
/*******************************************************************************
* mvTsuWinEnable
*
* DESCRIPTION:
*       This function enable/disable a TSU to target address window.
*       According to parameter 'enable' the routine will enable the
*       window, thus enabling TSU accesses (before enabling the window it is
*       tested for overlapping). Otherwise, the window will be disabled.
*
* INPUT:
*       winNum - TSU to target address decode window number.
*       enable - Enable / disable parameter.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_ERROR if decode window number was wrong or enabled window overlapps.
*
*******************************************************************************/
MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
{
	MV_TSU_DEC_WIN addrDecWin;

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

	if(enable == MV_TRUE)
	{
		/* First check for overlap with other enabled windows   */
		/* Get current window.					*/
		if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
		{
			mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
			return MV_ERROR;
		}
		/* Check for overlapping.	*/
		if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
		{
			/* No Overlap. Enable address decode target window   */
			MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
				       TSU_WIN_CTRL_EN_MASK);
		}
		else
		{
			/* Overlap detected */
			mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
			return MV_ERROR;
		}
	}
	else
	{
		/* Disable address decode target window */
		MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
				 TSU_WIN_CTRL_EN_MASK);
	}
	return MV_OK;
}
/*******************************************************************************
* mvDmaTransfer - Transfer data from source to destination
*
* DESCRIPTION:
*       This function initiates IDMA channel, according to function parameters,
*       in order to perform DMA transaction.
*       This routine supports both chain and none chained DMA modes.
*       To use the function in chain mode just set phyNextDesc parameter with
*       chain second descriptor address (the first one is given in other
*       function paarameters). Otherwise (none chain mode) set it to NULL.
*       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 IDMA 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.
*       3) In case of chain mode, the API does not align the user descriptor
*          chain. Instead, the user must make sure the descriptor chain is
*          aligned according to IDMA rquirements.
*       4) Parameters validity. For example, does size parameter exceeds
*          maximum byte count of descriptor mode (16M or 64K).
*
* INPUT:
*       chan          - DMA channel number. See MV_DMA_CHANNEL enumerator.
*       phySrc        - Physical source address.
*       phyDst        - Physical destination address.
*       size          - The total number of bytes to transfer.
*       *pPhyNextDesc - Physical address pointer to 2nd descriptor in chain.
*                       In case of none chain mode set it to NULL.
*
* OUTPUT:
*       None.
*
* RETURS:
*       MV_OK.
*
*******************************************************************************/
MV_STATUS mvDmaTransfer(MV_U32 chan, MV_U32 phySrc, MV_U32 phyDst, MV_U32 size, MV_U32 phyNextDescPtr)
{
	/* Set byte count register                      */
	MV_REG_WRITE(IDMA_BYTE_COUNT_REG(chan), size);
	/* Set source address register          */
	MV_REG_WRITE(IDMA_SRC_ADDR_REG(chan), phySrc);
	/* Set destination address register     */
	MV_REG_WRITE(IDMA_DST_ADDR_REG(chan), phyDst);
	/* UnLock the Source address in dma operation */
	MV_REG_BIT_RESET(IDMA_CTRL_LOW_REG(chan), ICCLR_SRC_HOLD);

	if (0 != phyNextDescPtr) {	/* Chain mode. Set next descriptor register     */
		MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(chan), phyNextDescPtr);
	}

	/* Start DMA    */
	MV_REG_BIT_SET(IDMA_CTRL_LOW_REG(chan), ICCLR_CHAN_ENABLE);

	return MV_OK;
}
/******************************************************************************
* mvEthCompSwP1ToSgmiiConfig
*
* DESCRIPTION:
*	Configure ethernet complex for Switch port1 to SGMII output.
*
* INPUT:
*	ethCompCfg - Ethernet complex configuration bitmap.
*
* OUTPUT:
*	None.
*
* RETURN:
*	MV_OK on success,
*	MV_ERROR otherwise.
*******************************************************************************/
MV_STATUS mvEthCompSwP1ToSgmiiConfig(MV_U32 ethCompCfg)
{
	MV_U32 reg;

	if (!(ethCompCfg & (ESC_OPT_SGMII | ESC_OPT_SGMII_2_5)))
		return MV_OK;

	/* 3.10. Switch P1 to LP_SERDES_PHY, using TBI
	 * 3.10.2. Ethernet-Complex configuration:
	 * 3.10.2.1. Configure Switch 125Mhz clock source: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwFi125ClkSrc to LpSERDES (0x2).
	 */
	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));
	reg &= ~ETHCC_SW_FI_125_CLK_MASK;

	/* 3.10.2.2. Connect Switch ports 1 to PCS-0: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwitchPort123Source to PCS (0x0)
	 */
	reg &= ~ETHCC_SW_PORT_123_SRC_MASK;
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	/* Initialize Serdes. */
	mvEthCompSerdesConfig(ethCompCfg);

	/* 3.10.4. Reset de-assertion:
	 * 3.10.4.1. De-assert all PCSs reset: set registers PCS_0_Control,
	 * PCS_1_Control PCS_2_Control and PCS_3_Control, fields PCS<i>_Port_Reset to 0x0.
	 */
	MV_REG_BIT_RESET(MV_ETHCOMP_PCS_CTRL_REG(0), PCSCTRL_PORT_RESET_MASK);

	/* 3.10.5. PCS-0 configurations:
	 * OPEN: This section was never tried on our test-plan. We should ramp
	 * up this test!!! The following sections are written based on section. (QSGMII)
	 * 3.10.5.1. Enable PCS ports: set Regunit PCS0Control register, fields
	 * Pcs0PortActive and Pcs0En to active (0x1)
	 */
	MV_REG_BIT_SET(MV_ETHCOMP_PCS_CTRL_REG(0), PCSCTRL_PORT_ACTIVE_MASK);
	MV_REG_BIT_SET(MV_ETHCOMP_PCS_CTRL_REG(0), PCSCTRL_PORT_EN_MASK);

	return MV_OK;
}
Exemple #8
0
static void mv_init_timer(void)
{
	/*
	 * Setup clocksource free running timer (no interrupt on reload)
	 */
 	MV_REG_WRITE(CNTMR_VAL_REG(CLOCKSOURCE), 0xffffffff);
	MV_REG_WRITE(CNTMR_RELOAD_REG(CLOCKSOURCE), 0xffffffff);
	MV_REG_BIT_RESET(BRIDGE_INT_MASK_REG, BRIDGE_INT_TIMER(CLOCKSOURCE));
	MV_REG_BIT_SET(CNTMR_CTRL_REG, TIMER_RELOAD_EN(CLOCKSOURCE) |
				  TIMER_EN(CLOCKSOURCE));

	kw_clkevt.cpumask = cpumask_of(0);

	/*
	 * Register clocksource
	 */
	kw_clksrc.mult =
		clocksource_hz2mult(mvBoardTclkGet(), kw_clksrc.shift);

	clocksource_register(&kw_clksrc);

	/*
	 * Connect and enable tick handler
	 */
	setup_irq(IRQ_BRIDGE, &kw_timer_irq);

	/*
	 * Register clockevent
	 */
	kw_clkevt.mult =
		div_sc(mvBoardTclkGet(), NSEC_PER_SEC, kw_clkevt.shift);
	kw_clkevt.max_delta_ns =
		clockevent_delta2ns(0xfffffffe, &kw_clkevt);
	kw_clkevt.min_delta_ns =
		clockevent_delta2ns(1, &kw_clkevt);

	/*
	 * Setup clockevent timer (interrupt-driven.)
	 */
	clockevents_register_device(&kw_clkevt);
}
Exemple #9
0
/* Audio I2S PlayBack related*/
MV_STATUS mvI2SPlaybackCtrlSet(int unit, MV_I2S_PLAYBACK_CTRL *ctrl)
{
	MV_U32 reg = MV_REG_READ(MV_AUDIO_I2S_PLAY_CTRL_REG(unit)) &
				~(AIPCR_I2S_PB_JUSTF_MASK|AIPCR_I2S_PB_SAMPLE_SIZE_MASK);

	if (ctrl->sampleSize > SAMPLE_16BIT)
	{
		mvOsPrintf("mvI2SPlaybackCtrlSet: illigal sample size\n");
		return MV_FAIL;
	}

	reg |= ctrl->sampleSize << AIPCR_I2S_PB_SAMPLE_SIZE_OFFS;

	if (ctrl->sendLastFrame)
	{
		MV_REG_BIT_SET(MV_AUDIO_I2S_PLAY_CTRL_REG(unit),AIPCR_I2S_SEND_LAST_FRM_MASK);
	}
	else
	{
		MV_REG_BIT_RESET(MV_AUDIO_I2S_PLAY_CTRL_REG(unit),AIPCR_I2S_SEND_LAST_FRM_MASK);
	}


	switch (ctrl->justification)
	{
	case I2S_JUSTIFIED:
	case LEFT_JUSTIFIED:
	case RIGHT_JUSTIFIED:
		reg |= ctrl->justification << AIPCR_I2S_PB_JUSTF_OFFS;
		break;
	default:
		mvOsPrintf("mvI2SPlaybackCtrlSet: illigal Justification value\n");
		return MV_FAIL;

	}

	MV_REG_WRITE(MV_AUDIO_I2S_PLAY_CTRL_REG(unit), reg);
	return MV_OK;

}
Exemple #10
0
/*******************************************************************************
* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
*
* DESCRIPTION: 
*		This function enable/Disable SDRAM address decode window.
*
* INPUT:
*	    target - System target. Use only SDRAM targets.
*
* OUTPUT:
*		None.
*
* RETURN:
*		MV_ERROR in case function parameter are invalid, MV_OK otherewise.
*
*******************************************************************************/
MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
{
	MV_DRAM_DEC_WIN 	addrDecWin;

	/* Check parameters */
	if (!MV_TARGET_IS_DRAM(target))
	{
		mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
		return MV_ERROR;
	}

	if (enable == MV_TRUE) 
	{   /* First check for overlap with other enabled windows				*/
		if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
		{
			mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n", 
                                                                        target);
			return MV_ERROR;
		}
		/* Check for overlapping */
		if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
		{
			/* No Overlap. Enable address decode winNum window              */
			MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
		}
		else
		{   /* Overlap detected	*/
			mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
                                                                        target);
			return MV_ERROR;
		}
	}
	else
	{   /* Disable address decode winNum window                             */
		MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
	}

	return MV_OK;
}
Exemple #11
0
/*******************************************************************************
* mvDmaWinEnable - Enable/disable a DMA to target address window
*
* DESCRIPTION:
*       This function enable/disable a DMA to target address window.
*       According to parameter 'enable' the routine will enable the 
*       window, thus enabling DMA accesses (before enabling the window it is 
*       tested for overlapping). Otherwise, the window will be disabled.
*
* INPUT:
*       winNum - IDMA to target address decode window number.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_ERROR if decode window number was wrong or enabled window overlapps.
*
*******************************************************************************/
MV_STATUS mvDmaWinEnable(MV_U32 winNum,MV_BOOL enable)
{
	MV_DMA_DEC_WIN addrDecWin;
    
	/* Parameter checking   */
	if (winNum >= IDMA_MAX_ADDR_DEC_WIN)
	{
		mvOsPrintf("mvDmaWinEnable:ERR. Invalid winNum%d\n",winNum);
		return MV_ERROR;
	}

	if (enable == MV_TRUE) 
	{   /* First check for overlap with other enabled windows				*/
		/* Get current window */
		if (MV_OK != mvDmaWinGet(winNum, &addrDecWin))
		{
			mvOsPrintf("mvDmaWinEnable:ERR. targetWinGet fail\n");
			return MV_ERROR;
		}
		/* Check for overlapping */
		if (MV_FALSE == dmaWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
		{
			/* No Overlap. Enable address decode target window              */
			MV_REG_BIT_RESET(IDMA_BASE_ADDR_ENABLE_REG, IBAER_ENABLE(winNum));
		}
		else
		{   /* Overlap detected	*/
			mvOsPrintf("mvDmaWinEnable:ERR. Overlap detected\n");
			return MV_ERROR;
		}
	}
	else
	{   /* Disable address decode target window                             */
		MV_REG_BIT_SET(IDMA_BASE_ADDR_ENABLE_REG, IBAER_ENABLE(winNum));
	}
	return MV_OK;
}
Exemple #12
0
MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
{
	MV_TDM_DEC_WIN addrDecWin;

	if (MV_TRUE == enable)
	{
		if (winNum >= TDM_MBUS_MAX_WIN)
		{
			mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
			return MV_ERROR;
		}	
		
		/* First check for overlap with other enabled windows				*/
		/* Get current window */
		if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
		{
			mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
			return MV_ERROR;
		}
		/* Check for overlapping */
		if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
		{
			/* No Overlap. Enable address decode target window */
			MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
		}
		else
		{   /* Overlap detected	*/
			mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
			return MV_ERROR;
		}
	}
	else
	{
		MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);	
	}
	return MV_OK;
}
Exemple #13
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;
}
Exemple #14
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;
}
Exemple #15
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 #16
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;
}
Exemple #17
0
/*******************************************************************************
* mvPexTargetWinEnable - Enable/disable a PEX BAR window
*
* DESCRIPTION:
*       This function enable/disable a PEX BAR window.
*       if parameter 'enable' == MV_TRUE the routine will enable the 
*       window, thus enabling PEX accesses for that BAR (before enabling the 
*       window it is tested for overlapping). Otherwise, the window will 
*       be disabled.
*
* INPUT:
*       pexIf  - PEX interface number.
*       bar    - BAR to be accessed by slave.
*       enable - Enable/disable parameter.
*
* OUTPUT:
*       None.
*
* RETURN:
*       MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
*
*******************************************************************************/
MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
{
	PEX_WIN_REG_INFO winRegInfo;
	MV_PEX_DEC_WIN addrDecWin;

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

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

	}


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


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

	if (MV_FALSE == enable)
	{

		/* this is not relevant to default and expantion rom
		windows */
		if (winRegInfo.sizeRegOffs)
		{
			if ((MV_PEX_WIN_DEFAULT != winNum)&&
				(MV_PEX_WIN_EXP_ROM != winNum))
			{
				MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
			}
		}

	}
	else
	{
		if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
		{
			mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
			return MV_ERROR;
		}

		/* Check if the requested window overlaps with current windows	*/
		if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
		{
			mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
			return MV_BAD_PARAM;
		}

		if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
		{
			mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
					   winNum);
			return MV_BAD_PARAM;
		}


		/* this is not relevant to default and expantion rom
		windows */
		if (winRegInfo.sizeRegOffs)
		{
			if ((MV_PEX_WIN_DEFAULT != winNum)&&
				(MV_PEX_WIN_EXP_ROM != winNum))
			{
				MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
			}
		}


	}

	return MV_OK;

}
/******************************************************************************
* mvEthCompSwToQsgmiiPhyConfig
*
* DESCRIPTION:
*	Configure ethernet complex for Switch ports 1-3 to QSGMII output.
*
* INPUT:
*	ethCompCfg - Ethernet complex configuration bitmap.
*
* OUTPUT:
*	None.
*
* RETURN:
*	MV_OK on success,
*	MV_ERROR otherwise.
*******************************************************************************/
MV_STATUS mvEthCompSwToQsgmiiPhyConfig(MV_U32 ethCompCfg)
{
	MV_U32 reg;
	MV_U32 i;

	if (!(ethCompCfg & ESC_OPT_QSGMII))
		return MV_OK;

	/* 3.8. Switch P1-4 to LP_SERDES_PHY, using QSGMII (10Mbps/ 100Mbps/ 1000Mbps) */
	/* 3.8.2. Ethernet-Complex configuration :
	 * 3.8.2.1. Configure Switch 125Mhz clock source: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwFi125ClkSrc to QSGMII (0x0).
	 */
	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));
	reg &= ~ETHCC_SW_FI_125_CLK_MASK;

	/* 3.8.2.2. Connect Switch ports 1,2 & 3 to PCS-0,1 & 2: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwitchPort123Source to PCS (0x0)
	 */
	reg &= ~ETHCC_SW_PORT_123_SRC_MASK;

	/* 3.8.2.3. Connect Switch ports 0 to PCS-3: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwitchPort123Source to PCS (0x0).
	 */
	reg &= ~ETHCC_SW_PORT_0_SRC_MASK;
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	/* Initialize Serdes. */
	mvEthCompSerdesConfig(ethCompCfg);

	/* 3.8.4. Reset de-assertion:
	 * 3.8.4.1. De-assert QSGMII reset: set Regunit QSGMII Control 1
	 * register, field QsgmiiRstn to 0x1.
	 */
	MV_REG_BIT_SET(MV_ETHCOMP_QSGMII_CONTROL_REG(1), QSGCTRL_RESETN_MASK);

	/* 3.8.4.2. De-assert all PCSs reset: set registers PCS_0_Control,
	 * PCS_1_Control PCS_2_Control and PCS_3_Control, fields PCS<i>_Port_Reset to 0x0.
	 */
	for (i = 0; i < 4; i++)
		MV_REG_BIT_RESET(MV_ETHCOMP_PCS_CTRL_REG(i), PCSCTRL_PORT_RESET_MASK);

	/* 3.8.5. PCS configurations (for PCSs 01,2 & 3):
	 * 3.8.5.1. Enable PCS ports: set Regunit PCS<i>Control register,
	 * fields Pcs<i>PortActive and Pcs<i>En to active (0x1)
	 */
	for (i = 0; i < 4; i++) {
		reg = MV_REG_READ(MV_ETHCOMP_PCS_CTRL_REG(i));
		reg |= ((0x1 << PCSCTRL_PORT_ACTIVE_OFFSET) |
			(0x1 << PCSCTRL_PORT_ANEG_AN_OFFSET) |
			(0x1 << PCSCTRL_PORT_RESTART_AN_OFFSET) |
			(0x1 << PCSCTRL_PORT_ADV_PAUSE_OFFSET) |
			(0x1 << PCSCTRL_PORT_ADV_ASM_PAUSE_OFFSET) |
			(0x1 << PCSCTRL_PORT_ANEG_DUPLEX_AN_OFFSET) |
			(0x1 << PCSCTRL_PORT_FC_AN_OFFSET) | (0x1 << PCSCTRL_PORT_SPEED_AN_OFFSET));
		MV_REG_WRITE(MV_ETHCOMP_PCS_CTRL_REG(i), reg);
	}

	/* Enable PCS */
	for (i = 0; i < 4; i++)
		MV_REG_BIT_SET(MV_ETHCOMP_PCS_CTRL_REG(i), PCSCTRL_PORT_EN_MASK);

	return MV_OK;
}
/******************************************************************************
* mvEthCompSataConfig
*
* DESCRIPTION:
*	Configure ethernet complex for sata port output.
*
* INPUT:
*	ethCompCfg - Ethernet complex configuration bitmap.
*
* OUTPUT:
*	None.
*
* RETURN:
*	MV_OK on success,
*	MV_ERROR otherwise.
*******************************************************************************/
MV_STATUS mvEthCompSataConfig(MV_U32 ethCompCfg)
{
	MV_U32 reg;
	MV_U32 tmp;
	MV_U16 serdesReg;

	if (!(ethCompCfg & ESC_OPT_SATA))
		return MV_OK;

	/* 3.8.3. LP_SERDES_PHY initialization:
	 * 3.8.3.1. Set LP_SERDES to reset: set Regunit Software Reset Control
	 * register to Reset (0x1).
	 */
	MV_REG_BIT_SET(SOFT_RESET_CTRL_REG, SRC_LPSRDSSWRSTN_MASK);

	/* 3.8.3.2. De-assert LP_SERDES reset: set Regunit Software Reset
	 * Control register to 0x0.
	 */
	MV_REG_BIT_RESET(SOFT_RESET_CTRL_REG, SRC_LPSRDSSWRSTN_MASK);

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));

	/* 3.8.2.4. Connect LP_SERDES_PHY to required source: set Regunit
	 * Ethernet_Complex_Control_0 register, field "LpphyMode" to "lpphyMode".
	 */
	tmp = 0x1;

	reg &= ~ETHCC_LPPHYMODE_MASK;
	reg |= (tmp << ETHCC_LPPHYMODE_OFFSET);
	reg |= ETHCC_LP_SERDES_DATA_SWAP_TX_MASK | ETHCC_LP_SERDES_DATA_SWAP_RX_MASK;
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	mvEthCompSetSerdesDefaults();

	/* 3.8.3.3. Power up LP_SERDES: set Gunit Serdes Configuration
	 * (SERDESCFG) register, fields "PU_TX", "PU_RX, "PU_PLL" (bits 1,2,3)
	 * to Enable (0x1)
	 */
	reg = MV_REG_READ(MV_SATACOMP_SERDESCFG_REG);
	reg &= ~SERDES_CFG_PU_TX_MASK;
	reg &= ~SERDES_CFG_PU_RX_MASK;
	reg &= ~SERDES_CFG_PU_PLL_MASK;
	MV_REG_WRITE(MV_SATACOMP_SERDESCFG_REG, reg);

	/* 3.8.3.4. Configuring the LP_SERDES to Reference clock 25M, and
	 * PHY_MODE to SERDES APB3 Reg 0x1. Access to LP_SERDES registers is
	 * done by accessing Gunit0, base address
	 * (0xE00 + (Serdes Reg Address << 2)) 0xE00 + 0x1<<2 = 0x4 + 0xE00 = 0xE04.
	 * Configure to -0xF88.
	 */
	mvEthCompSerdesRegWrite(0x1, 0xF801);

	/* 3.8.3.5. Configyre LP_SERED data rate, by setting Gunit Serdes
	 * Configuration (SERDESCFG) register, fields "PIN_PHY_GEN_TX" and
	 * "PIN_PHY_GEN_RX" to 5Gbps (0xA).
	 */
	tmp = 0x1;

	reg = MV_REG_READ(MV_SATACOMP_SERDESCFG_REG);
	reg &= ~SERDES_CFG_PHY_GEN_RX_MASK;
	reg |= (tmp << SERDES_CFG_PHY_GEN_RX_OFFSET);
	reg &= ~SERDES_CFG_PHY_GEN_TX_MASK;
	reg |= (tmp << SERDES_CFG_PHY_GEN_TX_OFFSET);
	MV_REG_WRITE(MV_SATACOMP_SERDESCFG_REG, reg);

	/* Set PHY Gen Tx & Rx to 0xA, Same as in reg MV_ETHCOMP_SERDESCFG_REG
	 ** Bit[9] - Dig_test_bus_en.
	 */
	mvEthCompSerdesRegWrite(0x26, 0x111);

	/* 3.8.3.6. Configuring the LP_SERDES to 10 bit interface, by setting
	 * its internal register 0x23[11:10] to 0x1. Access to LP_SERDES
	 * registers is done by accessing Gunit0, base address
	 * (0xE00 + (Serdes Reg Address << 2)) = 0xE00 + 0x23<<2 =  0xE00 + 0x8c = 0xE8c.
	 */
	serdesReg = mvEthCompSerdesRegRead(0x23);
	serdesReg &= ~(0x3 << 10);

	if ((ethCompCfg & ESC_OPT_SATA) || (ethCompCfg & ESC_OPT_QSGMII))
		serdesReg |= (0x1 << 10);

	mvEthCompSerdesRegWrite(0x23, serdesReg);

	/* 3.8.3.7. Wait for LP_SERDES pin "PLL_READY" to be 0x1. This pin is
	 * reflected in Gunit Serdes Status (SERDESSTS) register, bit[2].
	 */
	do {
		reg = MV_REG_READ(MV_SATACOMP_SERDESSTS_REG);
	} while ((reg & (1 << 2)) == 0);

	/* 3.8.3.8. Set PIN_RX_INIT to 1b1 for at least 16 TXDCLK cycles. Set
	 * Gunit Serdes Configuration (SERDESCFG) register, field "PIN_RX_INIT"
	 * to Enable (0x1).
	 */
	MV_REG_BIT_SET(MV_SATACOMP_SERDESCFG_REG, SERDES_CFG_RX_INIT_MASK);
	mvOsSleep(10);

	/* 3.8.3.9. Wait for LP_SERDES pin "PIN_RX_INIT_DONE" to be 0x1. This
	 * pin is reflected in Gunit Serdes Status (SERDESSTS) register, bit[0].
	 */
	do {
		reg = MV_REG_READ(MV_SATACOMP_SERDESSTS_REG);
	} while ((reg & 0x1) == 0);

	/* 3.8.3.10. Set PIN_RX_INIT back to 0x0. Set Gunit Serdes Configuration
	 * (SERDESCFG) register; field "PIN_RX_INIT" to Enable (0x0).
	 */
	MV_REG_BIT_RESET(MV_SATACOMP_SERDESCFG_REG, SERDES_CFG_RX_INIT_MASK);

	return MV_OK;
}
/******************************************************************************
* mvEthCompMac2SwitchConfig
*
* DESCRIPTION:
*	Configure ethernet complex for MAC0/1 to switch ports 5/6 mode.
*
* INPUT:
*	ethCompCfg - Ethernet complex configuration bitmap.
*	muxCfgOnly - MV_TRUE: Configure only the ethernet complex mux'es and
*		     skip other switch reset configurations.
*
* OUTPUT:
*	None.
*
* RETURN:
*	MV_OK on success,
*	MV_ERROR otherwise.
*******************************************************************************/
MV_STATUS mvEthCompMac2SwitchConfig(MV_U32 ethCompCfg, MV_BOOL muxCfgOnly)
{
	MV_U32 reg, portEnabled = 0;

	if (!(ethCompCfg & (ESC_OPT_MAC0_2_SW_P4 | ESC_OPT_MAC1_2_SW_P5)))
		return MV_OK;

	/* GbE-MAC-0 to Switch P4 (1000Mbps)    */
	/* GbE-MAC-1 to Switch P5 (1000Mbps)    */

	if (muxCfgOnly == MV_FALSE) {
		/* Set switch phy address */
		reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(1));
		reg &= ~ETHCC_SWTCH_ADDR_MASK;
		if (ethCompCfg & ESC_OPT_MAC0_2_SW_P4)
			reg |= (mvBoardPhyAddrGet(0) << ETHCC_SWTCH_ADDR_OFFSET);
		else
			reg |= (mvBoardPhyAddrGet(1) << ETHCC_SWTCH_ADDR_OFFSET);
		MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(1), reg);

		/*
		 * 3.1.2. Switch power-on configurations:
		 * 3.1.2.1. Activate Switch ports 1-6 (1 bit per port): set Regunit
		 * Ethernet_Complex_Control_2 register, field SwitchPortState, to 0x7E.
		 */
		reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(2));
		reg &= ~ETHCC_SW_PRT_STATE_MASK;

		if (ethCompCfg & ESC_OPT_RGMIIA_SW_P5)
			portEnabled |= BIT5;
		if (ethCompCfg & ESC_OPT_RGMIIA_SW_P6)
			portEnabled |= BIT6;
		if (ethCompCfg & ESC_OPT_MAC0_2_SW_P4)
			portEnabled |= BIT4;
		if (ethCompCfg & ESC_OPT_MAC1_2_SW_P5)
			portEnabled |= BIT5;
		if (ethCompCfg & ESC_OPT_GEPHY_SW_P0)
			portEnabled |= BIT0;
		if (ethCompCfg & ESC_OPT_GEPHY_SW_P5)
			portEnabled |= BIT5;
		if (ethCompCfg & ESC_OPT_FE3PHY)
			portEnabled |= BIT1 | BIT2 | BIT3;
		if (ethCompCfg & ESC_OPT_QSGMII)
			portEnabled |= BIT0 | BIT1 | BIT2 | BIT3;
		portEnabled |= BIT4 | BIT5;

		reg |= (portEnabled << ETHCC_SW_PRT_STATE_OFFSET);	/* 0x7E */
		MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(2), reg);

		/* 3.1.3. Ethernet-Complex configuration:
		 * 3.1.3.1. Configure Switch 125Mhz clock source: set
		 * Regunit Ethernet_Complex_Control_0 register, field SwFi125ClkSrc to
		 * MiscPLL (0x1).
		 */
		MV_REG_BIT_RESET(MV_ETHCOMP_CTRL_REG(0), ETHCC_SW_FI_125_CLK_MASK);
		MV_REG_BIT_SET(MV_ETHCOMP_CTRL_REG(0), (1 << ETHCC_SW_FI_125_CLK_OFFSET));
	}

	/* 3.1.3.2. Configure G-0 connection: set Regunit
	 * Ethernet_Complex_Control_0 register, field Gport0Source to
	 * "SwitchPort6" (0x1).
	 */
	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));
	if (ethCompCfg & ESC_OPT_MAC0_2_SW_P4) {
		reg &= ~ETHCC_GPORT_0_SRC_MASK;
		reg |= (0x1 << ETHCC_GPORT_0_SRC_OFFSET);
	}

	/* 3.2.3.2. Configure G-1 connection: set Regunit
	 * Ethernet_Complex_Control_0 register, field Gport1Source to
	 * SwitchPort5" (0x1).
	 */
	if (ethCompCfg & ESC_OPT_MAC1_2_SW_P5) {
		reg &= ~ETHCC_GPORT_1_SRC_MASK;
		reg |= (0x1 << ETHCC_GPORT_1_SRC_OFFSET);
	}
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	/* 3.2.3.3. Configure Switch P5 connection: set Regunit
	 * Ethernet_Complex_Control_0 register, field SwitchPort5Source to
	 * "Gport1" (0x1).
	 */
	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));
	reg &= ~ETHCC_SW_PORT_5_SRC_MASK;
	if (ethCompCfg & ESC_OPT_MAC1_2_SW_P5)
		reg |= (0x1 << ETHCC_SW_PORT_5_SRC_OFFSET);
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	/* 3.1.4.2. Wait for Switch, Switch Global Status Register, field
	 * EEInt to be set to 0x1.
	 */
	mvOsDelay(100);

	return MV_OK;
}
/******************************************************************************
* mvEthCompSerdesConfig
*
* DESCRIPTION:
*	Initialize serdes according to require PHY mode.
*
* INPUT:
*	ethCompCfg - Ethernet complex configuration bitmap.
*
* OUTPUT:
*	None.
*
* RETURN:
*	MV_OK on success,
*	MV_ERROR otherwise.
*******************************************************************************/
static MV_STATUS mvEthCompSerdesConfig(MV_U32 ethCompCfg)
{
	MV_U32 reg;
	MV_U32 tmp;
	MV_U16 serdesReg;

	reg = MV_REG_READ(MV_ETHCOMP_CTRL_REG(0));

	/* 3.8.2.4. Connect LP_SERDES_PHY to required source: set Regunit
	 * Ethernet_Complex_Control_0 register, field "LpphyMode" to "lpphyMode".
	 */
	if (ethCompCfg & (ESC_OPT_SGMII | ESC_OPT_SGMII_2_5))
		tmp = 0x0;
	else if (ethCompCfg & ESC_OPT_QSGMII)
		tmp = 0x2;
	else if (ethCompCfg & ESC_OPT_SATA)
		tmp = 0x1;
	else
		tmp = 0x3;

	reg &= ~ETHCC_LPPHYMODE_MASK;
	reg |= (tmp << ETHCC_LPPHYMODE_OFFSET);
	MV_REG_WRITE(MV_ETHCOMP_CTRL_REG(0), reg);

	/* 3.8.2.5. Change signal detect indication polarity: set Regunit
	 * QSGMII Control 1 register, field "QsgmiiInvSigdet" to 0x1.
	 */
	if (ethCompCfg & ESC_OPT_QSGMII) {
		reg = MV_REG_READ(MV_ETHCOMP_QSGMII_CONTROL_REG(1));
		reg &= ~QSGCTRL_INV_SIG_DET_MASK;
		reg |= (0x1 << QSGCTRL_INV_SIG_DET_OFFSET);
		MV_REG_WRITE(MV_ETHCOMP_QSGMII_CONTROL_REG(1), reg);
	}

	/* 3.8.3. LP_SERDES_PHY initialization:
	 * 3.8.3.1. Set LP_SERDES to reset: set Regunit Software Reset Control
	 * register to Reset (0x1).
	 */
	MV_REG_BIT_SET(SOFT_RESET_CTRL_REG, SRC_LPSRDSSWRSTN_MASK);

	/* 3.8.3.2. De-assert LP_SERDES reset: set Regunit Software Reset
	 * Control register to 0x0.
	 */
	MV_REG_BIT_RESET(SOFT_RESET_CTRL_REG, SRC_LPSRDSSWRSTN_MASK);

	mvEthCompSetSerdesDefaults();
	if (ethCompCfg & ESC_OPT_QSGMII) {
		mvEthCompSerdesRegWrite(0x25, 0x0);
		mvEthCompSerdesRegWrite(0x24, mvEthCompSerdesRegRead(0x24) | 0x8000);
		mvEthCompSerdesRegWrite(0xD, 0x0BE0);
		mvEthCompSerdesRegWrite(0xE, 0x5055);
	} else if (ethCompCfg & ESC_OPT_SGMII_2_5) {
		mvEthCompSerdesRegWrite(0xD, 0x0BEF);
		mvEthCompSerdesRegWrite(0xE, 0x9055);
	} else if (ethCompCfg & ESC_OPT_SGMII) {
		mvEthCompSerdesRegWrite(0xD, 0x0430);
		mvEthCompSerdesRegWrite(0xE, 0x0080);
	}

	/* 3.8.3.3. Power up LP_SERDES: set Gunit Serdes Configuration
	 * (SERDESCFG) register, fields "PU_TX", "PU_RX, "PU_PLL" (bits 1,2,3)
	 * to Enable (0x1)
	 */
	reg = MV_REG_READ(MV_ETHCOMP_SERDESCFG_REG);
	reg &= ~SERDES_CFG_PU_TX_MASK;
	reg &= ~SERDES_CFG_PU_RX_MASK;
	reg &= ~SERDES_CFG_PU_PLL_MASK;
	MV_REG_WRITE(MV_ETHCOMP_SERDESCFG_REG, reg);

	/* 3.8.3.4. Configuring the LP_SERDES to Reference clock 25M, and
	 * PHY_MODE to SERDES APB3 Reg 0x1. Access to LP_SERDES registers is
	 * done by accessing Gunit0, base address
	 * (0xE00 + (Serdes Reg Address << 2)) 0xE00 + 0x1<<2 = 0x4 + 0xE00 = 0xE04.
	 * Configure to -0xF88.
	 */
	mvEthCompSerdesRegWrite(0x1, 0xF880);	/* Was 0xF881 */

	/* 3.8.3.5. Configyre LP_SERED data rate, by setting Gunit Serdes
	 * Configuration (SERDESCFG) register, fields "PIN_PHY_GEN_TX" and
	 * "PIN_PHY_GEN_RX" to 5Gbps (0xA).
	 */
	tmp = 0x4;
	if (ethCompCfg & ESC_OPT_QSGMII)
		tmp = 0xA;
	if (ethCompCfg & ESC_OPT_SATA)
		tmp = 0x1;

	reg = MV_REG_READ(MV_ETHCOMP_SERDESCFG_REG);
	reg &= ~SERDES_CFG_PHY_GEN_RX_MASK;
	reg |= (tmp << SERDES_CFG_PHY_GEN_RX_OFFSET);
	reg &= ~SERDES_CFG_PHY_GEN_TX_MASK;
	reg |= (tmp << SERDES_CFG_PHY_GEN_TX_OFFSET);
	MV_REG_WRITE(MV_ETHCOMP_SERDESCFG_REG, reg);

	/* Set PHY Gen Tx & Rx to 0xA, Same as in reg MV_ETHCOMP_SERDESCFG_REG
	 ** Bit[9] - Dig_test_bus_en.
	 */
	if (ethCompCfg & ESC_OPT_QSGMII)
		mvEthCompSerdesRegWrite(0x26, 0x3AA);

	if (ethCompCfg & ESC_OPT_SGMII)
		mvEthCompSerdesRegWrite(0x26, 0x144);

	if (ethCompCfg & ESC_OPT_SGMII_2_5)
		mvEthCompSerdesRegWrite(0x26, 0x8166);

	if (ethCompCfg & ESC_OPT_SATA)
		mvEthCompSerdesRegWrite(0x26, 0x111);

	/* 3.8.3.6. Configuring the LP_SERDES to 10 bit interface, by setting
	 * its internal register 0x23[11:10] to 0x1. Access to LP_SERDES
	 * registers is done by accessing Gunit0, base address
	 * (0xE00 + (Serdes Reg Address << 2)) = 0xE00 + 0x23<<2 =  0xE00 + 0x8c = 0xE8c.
	 */
	serdesReg = mvEthCompSerdesRegRead(0x23);
	serdesReg &= ~(0x3 << 10);

	if ((ethCompCfg & ESC_OPT_SATA) || (ethCompCfg & ESC_OPT_QSGMII))
		serdesReg |= (0x1 << 10);

/* 	serdesReg |= (0x1 << 10); */
/* 	serdesReg |= (0x1 << 12); */
/* 	serdesReg |= (0x1 << 13); // Analog loopback. */
	mvEthCompSerdesRegWrite(0x23, serdesReg);

#if 0
	serdesReg = mvEthCompSerdesRegRead(0x51);
	serdesReg |= (0x1 << 9);
	mvEthCompSerdesRegWrite(0x51, serdesReg);
#endif

	/* 3.8.3.7. Wait for LP_SERDES pin "PLL_READY" to be 0x1. This pin is
	 * reflected in Gunit Serdes Status (SERDESSTS) register, bit[2].
	 */
	do {
		reg = MV_REG_READ(MV_ETHCOMP_SERDESSTS_REG);
	} while ((reg & (1 << 2)) == 0);

	/* 3.8.3.8. Set PIN_RX_INIT to 1b1 for at least 16 TXDCLK cycles. Set
	 * Gunit Serdes Configuration (SERDESCFG) register, field "PIN_RX_INIT"
	 * to Enable (0x1).
	 */
	MV_REG_BIT_SET(MV_ETHCOMP_SERDESCFG_REG, SERDES_CFG_RX_INIT_MASK);
	mvOsSleep(10);

	/* 3.8.3.9. Wait for LP_SERDES pin "PIN_RX_INIT_DONE" to be 0x1. This
	 * pin is reflected in Gunit Serdes Status (SERDESSTS) register, bit[0].
	 */
	do {
		reg = MV_REG_READ(MV_ETHCOMP_SERDESSTS_REG);
	} while ((reg & 0x1) == 0);

	/* 3.8.3.10. Set PIN_RX_INIT back to 0x0. Set Gunit Serdes Configuration
	 * (SERDESCFG) register; field "PIN_RX_INIT" to Enable (0x0).
	 */
	MV_REG_BIT_RESET(MV_ETHCOMP_SERDESCFG_REG, SERDES_CFG_RX_INIT_MASK);

	return MV_OK;
}
Exemple #22
0
/* Audio Recording*/
MV_STATUS mvAudioRecordControlSet(int unit, MV_AUDIO_RECORD_CTRL *ctrl)
{
	MV_U32 reg;

	if (ctrl->monoChannel > AUDIO_REC_RIGHT_MONO)
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal monoChannel %x\n",
				   ctrl->monoChannel );

		return MV_FAIL;
	}

	if ((ctrl->burst != AUDIO_32BYTE_BURST) &&
		(ctrl->burst != AUDIO_128BYTE_BURST))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal burst %x\n",
				   ctrl->burst );

		return MV_FAIL;

	}

	if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,bufferPhyBase is not"\
				   "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN );

		return MV_FAIL;
	}

	if  ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))||
		(ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))||
		 (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX))
		 )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error, bufferSize smaller"\
				   "\nthan or not multiple of 0x%x bytes or larger than"\
				   "\n 0x%x",
				   audioBurstBytesNumGet(ctrl->burst),
				   AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX));

		return MV_FAIL;
	}


	reg = MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit));
	reg &= ~(ARCR_RECORD_BURST_SIZE_MASK|ARCR_RECORDED_MONO_CHNL_MASK|
			 ARCR_RECORD_SAMPLE_SIZE_MASK);
	switch (ctrl->sampleSize)
	{
	case SAMPLE_16BIT:
	case SAMPLE_16BIT_NON_COMPACT:
	case SAMPLE_20BIT:
	case SAMPLE_24BIT:
	case SAMPLE_32BIT:
		reg |= ctrl->sampleSize << ARCR_RECORD_SAMPLE_SIZE_OFFS;
        break;
	default:
        mvOsPrintf("mvAudioRecordControlSet: Error ,illegal sampleSize %x\n",
				   ctrl->sampleSize );

		return MV_FAIL;
	}

	reg |= ctrl->burst << ARCR_RECORD_BURST_SIZE_OFFS;
	reg |= ctrl->monoChannel << ARCR_RECORDED_MONO_CHNL_OFFS;
	MV_REG_WRITE(MV_AUDIO_RECORD_CTRL_REG(unit), reg);

	if (ctrl->mono)
	{
		MV_REG_BIT_SET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}
	else
	{
		MV_REG_BIT_RESET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}

#ifndef MV_AUDIO_SKIP_WIN_DECODING
	if(mvAudioReplaceAddrWin(unit, MV_AUDIO_RECORD_WIN_NUM, ctrl->bufferPhyBase,
				ctrl->bufferSize) != MV_OK)
	{
		mvOsPrintf("mvAudioRecordControlSet: Failed to replace address decoding window.\n");
		return MV_FAIL;
	}
#endif

    	/* Set the interrupt byte count.                            */
    	reg = ctrl->intByteCount & ARBCI_BYTE_COUNT_MASK;
    	MV_REG_WRITE(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit), reg);

	MV_REG_WRITE(MV_AUDIO_RECORD_START_ADDR_REG(unit), ctrl->bufferPhyBase);
	MV_REG_WRITE(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit),
				 AUDIO_SIZE_TO_REG(ctrl->bufferSize));

	return MV_OK;
}
Exemple #23
0
/*******************************************************************************
* mvCpuIfEnablePex - Enable PCI Express.
*
* DESCRIPTION:
*	This function enables PCI Express access to the device address
*	space.
*
* INPUT:
*	None.
* OUTPUT:
*       None.
*
* RETURN:
*       None.
*
*******************************************************************************/
MV_VOID mvCpuIfEnablePex(void)
{
    /* CPU config register Pex enable */
    MV_REG_BIT_RESET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
}
Exemple #24
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;
}
Exemple #25
0
/* Audio Recording*/
MV_STATUS mvAudioRecordControlSet(int unit, MV_AUDIO_RECORD_CTRL *ctrl)
{
	MV_AUDIO_DEC_WIN audioWin;
	MV_CPU_DEC_WIN  cpuWin;
	MV_ADDR_WIN   bufAddrWin;
	MV_U32 target;
	MV_U32 reg;

	if (ctrl->monoChannel > AUDIO_REC_RIGHT_MONO)
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal monoChannel %x\n",
				   ctrl->monoChannel );

		return MV_FAIL;
	}

	if ((ctrl->burst != AUDIO_32BYTE_BURST) &&
		(ctrl->burst != AUDIO_128BYTE_BURST))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,illegal burst %x\n",
				   ctrl->burst );

		return MV_FAIL;

	}

	if (ctrl->bufferPhyBase & (MV_AUDIO_BUFFER_MIN_ALIGN - 1))
	{
		mvOsPrintf("mvAudioRecordControlSet: Error ,bufferPhyBase is not"\
				   "\n aligned to 0x%x bytes\n",MV_AUDIO_BUFFER_MIN_ALIGN );

		return MV_FAIL;
	}

	if  ((ctrl->bufferSize <= audioBurstBytesNumGet(ctrl->burst))||
		(ctrl->bufferSize & (audioBurstBytesNumGet(ctrl->burst) - 1))||
		 (ctrl->bufferSize > AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX))
		 )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error, bufferSize smaller"\
				   "\nthan or not multiple of 0x%x bytes or larger than"\
				   "\n 0x%x",
				   audioBurstBytesNumGet(ctrl->burst),
				   AUDIO_REG_TO_SIZE(APBBCR_SIZE_MAX));

		return MV_FAIL;
	}


	reg = MV_REG_READ(MV_AUDIO_RECORD_CTRL_REG(unit));
	reg &= ~(ARCR_RECORD_BURST_SIZE_MASK|ARCR_RECORDED_MONO_CHNL_MASK|
			 ARCR_RECORD_SAMPLE_SIZE_MASK);
	switch (ctrl->sampleSize)
	{
	case SAMPLE_16BIT:
	case SAMPLE_16BIT_NON_COMPACT:
	case SAMPLE_20BIT:
	case SAMPLE_24BIT:
	case SAMPLE_32BIT:
		reg |= ctrl->sampleSize << ARCR_RECORD_SAMPLE_SIZE_OFFS;
        break;
	default:
        mvOsPrintf("mvAudioRecordControlSet: Error ,illegal sampleSize %x\n",
				   ctrl->sampleSize );

		return MV_FAIL;
	}

	reg |= ctrl->burst << ARCR_RECORD_BURST_SIZE_OFFS;
	reg |= ctrl->monoChannel << ARCR_RECORDED_MONO_CHNL_OFFS;
	MV_REG_WRITE(MV_AUDIO_RECORD_CTRL_REG(unit), reg);

	if (ctrl->mono)
	{
		MV_REG_BIT_SET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}
	else
	{
		MV_REG_BIT_RESET (MV_AUDIO_RECORD_CTRL_REG(unit), 
				ARCR_RECORD_MONO_MASK);
	}

	/* Get the details of the Record address window*/
	if( mvAudioWinGet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK )
	{
		mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n",
				   MV_AUDIO_RECORD_WIN_NUM);
		return MV_FAIL;
	}

	bufAddrWin.baseHigh = 0;
	bufAddrWin.baseLow = ctrl->bufferPhyBase;
	bufAddrWin.size = ctrl->bufferSize;

	/* If Record window is not enabled or buffer address is not within window boundries
	   then try to set a new value to the Record window by
	   Geting the target of where the buffer exist, if the buffer is within the window
	   of the new target then set the Record window to that target
	   else return Fail
    */

	if((audioWin.enable != MV_TRUE) ||
	  (MV_TRUE != ctrlWinWithinWinTest(&bufAddrWin, &audioWin.addrWin)))
	{
		/* Get the target of the buffer that user require*/
		target = mvCpuIfTargetOfBaseAddressGet(ctrl->bufferPhyBase);
		if (MAX_TARGETS == target)
		{
			mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on address 0x%x\n",
					   ctrl->bufferPhyBase);
			return MV_FAIL;
		}

		/* Get the window details of this target*/
		if (MV_OK != mvCpuIfTargetWinGet(target, &cpuWin))
		{
			mvOsPrintf("mvAudioRecordControlSet: Error calling mvCpuIfTargetWinGet on target %d\n",
					   target);
			return MV_FAIL;

		}

		/* if the address window of the target is enabled and te user buffer is within
		   that target address window then set the palyback\recording window to the
		   target window

		*/
		if((cpuWin.enable == MV_TRUE) &&
		  (MV_TRUE == ctrlWinWithinWinTest(&bufAddrWin, &cpuWin.addrWin)))
		{

			audioWin.addrWin.baseHigh = cpuWin.addrWin.baseHigh;
			audioWin.addrWin.baseLow = cpuWin.addrWin.baseLow;
			audioWin.addrWin.size = cpuWin.addrWin.size;
			audioWin.enable = cpuWin.enable;
			audioWin.target = target;

			if( mvAudioWinSet( MV_AUDIO_RECORD_WIN_NUM, &audioWin ) != MV_OK )
			{
				mvOsPrintf("mvAudioRecordControlSet: Error calling mvAudioWinGet on win %d\n",
						   MV_AUDIO_RECORD_WIN_NUM);
				return MV_FAIL;
			}

		}
		else
		{
			mvOsPrintf("mvAudioRecordControlSet: Error buffer is not within a valid target\n");
			return MV_FAIL;

		}
	}

    	/* Set the interrupt byte count.                            */
    	reg = ctrl->intByteCount & ARBCI_BYTE_COUNT_MASK;
    	MV_REG_WRITE(MV_AUDIO_RECORD_BYTE_CNTR_INT_REG(unit), reg);

	MV_REG_WRITE(MV_AUDIO_RECORD_START_ADDR_REG(unit), ctrl->bufferPhyBase);
	MV_REG_WRITE(MV_AUDIO_RECORD_BUFF_SIZE_REG(unit),
				 AUDIO_SIZE_TO_REG(ctrl->bufferSize));

	return MV_OK;
}
Exemple #26
0
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
	     void *din, unsigned long flags)
{
	MV_STATUS ret;
	MV_U8* pdout = (MV_U8*)dout;
	MV_U8* pdin = (MV_U8*)din;
	int tmp_bitlen = bitlen;
#if 0
	unsigned int tmpdout, tmpdin;
	int tm, isread = 0;

	debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
	      slave->bus, slave->cs, dout, din, bitlen);

#endif

	//printf("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
	  //    slave->bus, slave->cs, dout, din, bitlen);

	if (flags & SPI_XFER_BEGIN)
		spi_cs_activate(slave);

#if 0
	MV_STATUS ret;
	MV_U32 bytesLeft = buffSize;
	MV_U16* txPtr = (MV_U16*)pTxBuff;


	/* Check that the buffer pointer and the buffer size are 16bit aligned */
	if (((bitlen & 1) == 0) && ((dout & 1) == 0))
	{
	/* Verify that the SPI mode is in 16bit mode */
	MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);

	/* TX/RX as long we have complete 16bit chunks */
	while (bitlen >= MV_SPI_16_BIT_CHUNK_SIZE)
	{
        /* Transmitted and wait for the transfer to be completed */
		if ((ret = mvSpi16bitDataTxRx(*dout, *din)) != MV_OK)
			return ret;

		/* increment the pointers */
		txPtr++;
		bitlen -= MV_SPI_16_BIT_CHUNK_SIZE;
	}
    }
    else
    {
#endif
	
	/* Verify that the SPI mode is in 8bit mode */
	MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG(0), MV_SPI_BYTE_LENGTH_MASK);

	/* TX/RX in 8bit chanks */
	
	while (tmp_bitlen > 0)
	{
		/* Transmitted and wait for the transfer to be completed */
		if ((ret = mvSpi8bitDataTxRx(0,*pdout, pdin)) != MV_OK)
			return ret;
		
		/* increment the pointers */
		//printf("in=[0x%x]",*pdin);
		if (pdin)
			pdin++;
		//printf("out=[0x%x]",*pdout);
		if (pdout)
			pdout++;

		tmp_bitlen-=8;
	}

#if 0
    }
#endif
	
#if 0
/*
	 * handle data in 8-bit chunks
	 * TBD: 2byte xfer mode to be enabled
	 */
	writel(((readl(&spireg->cfg) & ~KWSPI_XFERLEN_MASK) |
		KWSPI_XFERLEN_1BYTE), &spireg->cfg);

	while (bitlen > 4) {
		debug("loopstart bitlen %d\n", bitlen);
		tmpdout = 0;

		/* Shift data so it's msb-justified */
		if (dout)
			tmpdout = *(u32 *) dout & 0x0ff;

		writel(~KWSPI_SMEMRDIRQ, &spireg->irq_cause);
		writel(tmpdout, &spireg->dout);	/* Write the data out */
		debug("*** spi_xfer: ... %08x written, bitlen %d\n",
		      tmpdout, bitlen);

		/*
		 * Wait for SPI transmit to get out
		 * or time out (1 second = 1000 ms)
		 * The NE event must be read and cleared first
		 */
		for (tm = 0, isread = 0; tm < KWSPI_TIMEOUT; ++tm) {
			if (readl(&spireg->irq_cause) & KWSPI_SMEMRDIRQ) {
				isread = 1;
				tmpdin = readl(&spireg->din);
				debug
					("spi_xfer: din %08x..%08x read\n",
					din, tmpdin);

				if (din) {
					*((u8 *) din) = (u8) tmpdin;
					din += 1;
				}
				if (dout)
					dout += 1;
				bitlen -= 8;
			}
			if (isread)
				break;
		}
		if (tm >= KWSPI_TIMEOUT)
			printf("*** spi_xfer: Time out during SPI transfer\n");

		debug("loopend bitlen %d\n", bitlen);
	}



#endif

	if (flags & SPI_XFER_END)
		spi_cs_deactivate(slave);

	return 0;
}
Exemple #27
0
MV_STATUS mvTdmInit(mv_tdm_params_t* tdmParams)
{
	MV_U8 ch, sample;
	MV_U32 pcmCtrlReg;
	
	MV_TRC_REC("->%s\n",__FUNCTION__);
	mvTdmShowProperties();

	/* Init TDM windows address decoding */
	if (mvTdmWinInit() != MV_OK)
	{
		return MV_ERROR;
	}

	/* Init globals */
	rxInt = txInt = 0;
	tdmEnable = 0;
	spiMode = mvBoardTdmSpiModeGet();
	tdmBandMode = tdmParams->bandMode;
	pcmFormat = tdmParams->pcmFormat;
	
	if((tdmParams->samplePeriod < MV_TDM_BASE_SAMPLE_PERIOD) || 
			(tdmParams->samplePeriod > MV_TDM_MAX_SAMPLE_PERIOD))
	{
		factor = 1; /* use base sample period(10ms) */
	}
	else
	{
		factor = (tdmParams->samplePeriod / MV_TDM_BASE_SAMPLE_PERIOD);
	}

	/* Set sample size for further TDM configuration */
	sample = (pcmFormat == MV_PCM_FORMAT_LINEAR ? 2 : 1);

	/* Allocate aggregated buffers for data transport */
	MV_TRC_REC("allocate %d bytes for aggregated buffer\n", MV_TDM_AGGR_BUFF_SIZE(pcmFormat, tdmBandMode, factor));
	rxAggrBuffVirt = (MV_U8*)mvOsIoCachedMalloc(NULL, MV_TDM_AGGR_BUFF_SIZE(pcmFormat, tdmBandMode, factor),
					&rxAggrBuffPhys,NULL);
	txAggrBuffVirt = (MV_U8*)mvOsIoCachedMalloc(NULL, MV_TDM_AGGR_BUFF_SIZE(pcmFormat, tdmBandMode, factor),
					&txAggrBuffPhys,NULL);
	if(!rxAggrBuffVirt || !txAggrBuffVirt)
	{
		mvOsPrintf("%s: error malloc failed\n",__FUNCTION__);
		return MV_NO_RESOURCE;
	}

	/* Config TDM */
	MV_REG_BIT_RESET(TDM_SPI_MUX_REG, 1);                 /* enable TDM/SPI interface */
	MV_REG_BIT_SET(TDM_MISC_REG, BIT0);           	      /* sw reset to TDM for 5181L-A1 & up */
	MV_REG_WRITE(INT_RESET_SELECT_REG,CLEAR_ON_ZERO);     /* int cause is not clear on read */
	MV_REG_WRITE(INT_EVENT_MASK_REG,0x3ffff);             /* all interrupt bits latched in status */
	MV_REG_WRITE(INT_STATUS_MASK_REG,0);                  /* disable interrupts */
	MV_REG_WRITE(INT_STATUS_REG,0);                       /* clear int status register */
	MV_REG_WRITE(PCM_CLK_RATE_DIV_REG, PCM_8192KHZ);      /* PCM PCLK freq */
	MV_REG_WRITE(DUMMY_RX_WRITE_DATA_REG,0);              /* Padding on Rx completion */
	MV_REG_BYTE_WRITE(SPI_GLOBAL_CTRL_REG, MV_REG_READ(SPI_GLOBAL_CTRL_REG) | SPI_GLOBAL_ENABLE);
	MV_REG_BYTE_WRITE(SPI_CLK_PRESCALAR_REG, SPI_CLK_8MHZ); /* SPI SCLK freq */
	MV_REG_WRITE(FRAME_TIMESLOT_REG, TIMESLOTS128_8192KHZ);     /* Number of timeslots (PCLK) */

	if(tdmBandMode == MV_NARROW_BAND)
	{
	  pcmCtrlReg = (CONFIG_PCM_CRTL | ((sample-1)<<PCM_SAMPLE_SIZE_OFFS));
	  MV_REG_WRITE(PCM_CTRL_REG, pcmCtrlReg); 		/* PCM configuration */
	  MV_REG_WRITE(TIMESLOT_CTRL_REG, CONFIG_TIMESLOT_CTRL);      /* channels rx/tx timeslots */
	}
	else /* MV_WIDE_BAND */
	{ 	  
	  pcmCtrlReg = (CONFIG_WB_PCM_CRTL | ((sample-1)<<PCM_SAMPLE_SIZE_OFFS));
	  MV_REG_WRITE(PCM_CTRL_REG, pcmCtrlReg);               	  	  /* PCM configuration - WB support */
	  MV_REG_WRITE(CH_DELAY_CTRL_REG(0), CONFIG_CH0_DELAY_CTRL_CONFIG); 	  /* CH0 delay control register */	
	  MV_REG_WRITE(CH_DELAY_CTRL_REG(1), CONFIG_CH1_DELAY_CTRL_CONFIG); 	  /* CH1 delay control register */
	  MV_REG_WRITE(CH_WB_DELAY_CTRL_REG(0), CONFIG_CH0_WB_DELAY_CTRL_CONFIG); /* CH0 WB delay control register */	
	  MV_REG_WRITE(CH_WB_DELAY_CTRL_REG(1), CONFIG_CH1_WB_DELAY_CTRL_CONFIG); /* CH1 WB delay control register */
	}

	/* Issue reset to codec(s) */
	MV_TRC_REC("reseting voice unit(s)\n");
	MV_REG_WRITE(MISC_CTRL_REG,0);
	mvOsDelay(1);
	MV_REG_WRITE(MISC_CTRL_REG,1);

	if(spiMode) 
	{
	  /* Configure TDM to work in daisy chain mode */
	  mvTdmDaisyChainModeSet();
	}
	
	/* Initialize all HW units */
	for(ch = 0 ; ch < MV_TDM_TOTAL_CHANNELS; ch++)
	{
	  if(mvTdmChInit(ch) != MV_OK)
	  {
		mvOsPrintf("mvTdmChInit(%d) failed !\n", ch);
		return MV_ERROR;
	  }
	}

	/* Enable SLIC/DAA interrupt detection(before pcm is active) */
	MV_REG_WRITE(INT_STATUS_MASK_REG, (MV_REG_READ(INT_STATUS_MASK_REG) | TDM_INT_SLIC)); 

	MV_TRC_REC("<-%s\n",__FUNCTION__);
	return MV_OK;
}