Beispiel #1
0
/*******************************************************************************
* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
*
* DESCRIPTION:
*       This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
*       address window, also known as address decode window.
*       A new address decode 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 CPU to access
*       the target window.
*
* INPUT:
*       target      - Peripheral target enumerator.
*       pAddrDecWin - CPU target window data structure.
*
* OUTPUT:
*       N/A
*
* RETURN:
*       MV_OK if CPU target window was set correctly, MV_ERROR in case of
*       address window overlapps with other active CPU target window or
*		trying to assign 36bit base address while CPU does not support that.
*       The function returns MV_NOT_SUPPORTED, if the target is unsupported.
*
*******************************************************************************/
MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
{
    MV_AHB_TO_MBUS_DEC_WIN decWin;
    MV_U32 existingWinNum;
    MV_DRAM_DEC_WIN addrDecWin;

    target = MV_CHANGE_BOOT_CS(target);

    /* Check parameters */
    if (target >= MAX_TARGETS)
    {
        mvOsPrintf("mvCpuIfTargetWinSet: target %d is illegal\n", target);
        return MV_ERROR;
    }

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

    if (MV_TARGET_IS_DRAM(target))
    {
        /* copy relevant data to MV_DRAM_DEC_WIN structure */
        addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
        addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
        addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
        addrDecWin.enable = pAddrDecWin->enable;


        if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
        {
            mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
            return MV_ERROR;
        }

    }
    else
    {
        /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
        decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
        decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
        decWin.addrWin.size = pAddrDecWin->addrWin.size;
        decWin.enable = pAddrDecWin->enable;
        decWin.target = target;

        existingWinNum = mvAhbToMbusWinTargetGet(target);

        /* check if there is already another Window configured
        for this target */
        if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
                (existingWinNum != pAddrDecWin->winNum))
        {
            /* if we want to enable the new winow number
            passed by the user , then the old one should
            be disabled */
            if (MV_TRUE == pAddrDecWin->enable)
            {
                /* be sure it is disabled */
                mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
            }
        }

        if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
        {
            mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
            return MV_ERROR;
        }

    }

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

	dramDecWin.addrWin.baseHigh = 0;

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

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

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

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

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

				/* enable it */
				sizeToReg |= SCSR_WIN_EN;

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

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

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

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

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

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

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

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

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

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

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

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

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

	return retVal;
}