Exemplo n.º 1
0
/***********************************************************************
 *
 * Function: sdr_sdram_setup
 *
 * Purpose: Setup SDRAM
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *     clk : Base SDRAM controller clock rate
 *     lp  : Low power SDRAM flag
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
void sdr_sdram_setup(UNS_32 clk, int lp)
{
	volatile UNS_32 tmp32;
	UNS_32 tmp;

	/* Enables SDR clocking mode, (7*0.25nS) HCLK delay
	   Tests of HCLK delay have shown that voltage and frequency are
	   not driving factors for it's timing. Over testing, a working
	   value of 3 to 27 (average) appears to work and not effect other
	   operation. For this value, a hardcoded value of 7 is used. */
    CLKPWR->clkpwr_sdramclk_ctrl = CLKPWR_SDRCLK_HCLK_DLY(7);

	/* Setup slew rates */
#ifdef SDRAM_USE_SLOW_SLEW
	CLKPWR->clkpwr_sdramclk_ctrl |= (CLKPWR_SDRCLK_SLOWSLEW_CLK |
		CLKPWR_SDRCLK_SLOWSLEW | CLKPWR_SDRCLK_SLOWSLEW_DAT);

#else
	CLKPWR->clkpwr_sdramclk_ctrl &= ~(CLKPWR_SDRCLK_SLOWSLEW_CLK |
		CLKPWR_SDRCLK_SLOWSLEW | CLKPWR_SDRCLK_SLOWSLEW_DAT);
#endif

	tmp = sdram_find_config();
	if (!tmp)
	{
		/* Nothing matches, exit, DRAM won't work */
		return;
	}

	/* Setup address mapping, its ok to use low power SDRAM mode with
	   standard SDRAM devices */
	EMC->emcdynamicconfig0 = (tmp << 7) | EMC_DYN_DEV_LP_SDR_SDRAM;

	/* Setup CAS and RAS latencies */
	EMC->emcdynamicrascas0 =
		EMC_SET_CAS_IN_HALF_CYCLES(SDRAM_CAS_LATENCY) |
		EMC_SET_RAS_IN_CYCLES(SDRAM_RAS_LATENCY);

#ifdef USE_DUAL_SDRAM_DEVICES
	/* DYCS1 chip select */
	EMC->emcdynamicconfig1 = (tmp << 7) | EMC_DYN_DEV_LP_SDR_SDRAM;
	EMC->emcdynamicrascas1 =
		EMC_SET_CAS_IN_HALF_CYCLES(SDRAM_CAS_LATENCY) |
		EMC_SET_RAS_IN_CYCLES(SDRAM_RAS_LATENCY);
#endif

	/* Setup SDRAM read strategy */
	EMC->emcdynamicreadconfig = (EMC_SDR_CLK_NODLY_CMD_DEL |
	    EMC_SDR_READCAP_POS_POL);

	/* Setup SDRAM timing for current HCLK clock settings */
	sdram_adjust_timing(clk);

	/* Enable clocks and delay for at least 100uS to stabilize */
	tmp = (EMC_DYN_CLK_ALWAYS_ON | EMC_DYN_CLKEN_ALWAYS_ON |
		EMC_DYN_DIS_INV_MEMCLK);
	EMC->emcdynamiccontrol = (tmp | EMC_DYN_NOP_MODE);
	timer_wait_us(TIMER_CNTR0, 100);

	/* Issue a precharge all command */
	EMC->emcdynamiccontrol = (tmp | EMC_DYN_PALL_MODE);
	EMC->emcdynamicrefresh = EMC_DYN_REFRESH_IVAL(4);
	timer_wait_us(TIMER_CNTR0, 10);

	/* Fast dynamic refresh for at least a few SDRAM clock cycles */
	timer_wait_us(TIMER_CNTR0, 10);

	/* Normal refresh timing */
	EMC->emcdynamicrefresh =
		EMC_DYN_REFRESH_IVAL(clk / SDRAM_RFSH_INTERVAL);

	/* Issue load mode command and normal mode word */
	EMC->emcdynamiccontrol = (tmp | EMC_DYN_CMD_MODE);
	tmp32 = * (volatile UNS_32 *) (EMC_DYCS0_BASE +
		(SDRAM_MODE_WORD << modeshift));
#ifdef ENABLE_DEBUG
		modeaddr = EMC_DYCS0_BASE + (SDRAM_MODE_WORD << modeshift);
#endif
	timer_wait_us(TIMER_CNTR0, 1);

	/* Only mobile (low power) SDRAMs use the extended mode word */
	if (lp)
	{
		tmp32 = * (volatile UNS_32 *) (EMC_DYCS0_BASE +
			SDRAM_EXT_MODE_BB + (SDRAM_EXT_MODE_WORD << modeshift));
#ifdef ENABLE_DEBUG
		extmodeaddr = EMC_DYCS0_BASE + SDRAM_EXT_MODE_BB +
			(SDRAM_EXT_MODE_WORD << modeshift);
#endif
		timer_wait_us(TIMER_CNTR0, 1);
	}

#ifdef USE_DUAL_SDRAM_DEVICES
	/* Configuration for other chip select */
	tmp32 = * (volatile UNS_32 *) (EMC_DYCS1_BASE +
		(SDRAM_MODE_WORD << modeshift));
	timer_wait_us(TIMER_CNTR0, 1);

	if (lp)
	{
		tmp32 = * (volatile UNS_32 *) (EMC_DYCS1_BASE +
			SDRAM_EXT_MODE_BB + (SDRAM_EXT_MODE_WORD << modeshift));
		timer_wait_us(TIMER_CNTR0, 1);
	}
#endif

	/* Normal SDRAM mode */
	EMC->emcdynamiccontrol = EMC_DYN_NORMAL_MODE |
		EMC_DYN_DIS_INV_MEMCLK | EMC_DYN_DIS_MEMCLK_IN_SFRSH;
	timer_wait_us(TIMER_CNTR0, 1);
}
Exemplo n.º 2
0
/***********************************************************************
 *
 * Function: ddr_if_init
 *
 * Purpose: Sets up DDR interface and initial calibration
 *
 * Processing:
 *     See function.
 *
 * Parameters:
 *    cfg: Dynamic configuration value
 *
 * Outputs: None
 *
 * Returns: Nothing
 *
 * Notes: None
 *
 **********************************************************************/
static void ddr_if_init(UNS_32 cfg)
{
	UNS_32 tmp, ringosccount;
	int idx;

	/* Use nominal rate for DDR clocking */
	tmp = CLKPWR->clkpwr_hclk_div & ~(0x3 << 0x7);
	CLKPWR->clkpwr_hclk_div = tmp | CLKPWR_HCLKDIV_DDRCLK_NORM;

	/* Resync DDR clocks */
	ddr_clock_resync(cfg);

	/* Enable calibration logic with low calibration sensitivity and
	   a guessed first DQSIN delay value. This is just temporary and
	   is used for the next step. */
	CLKPWR->clkpwr_sdramclk_ctrl |= CLKPWR_SDRCLK_USE_CAL |
		CLKPWR_SDRCLK_SENS_FACT(7) | CLKPWR_SDRCLK_DQS_DLY(0xF);

	/* Force calibration 10 times and save the average value */
	ringosccount = 0;
	for (idx = 0; idx < 10; idx++)
	{
		CLKPWR->clkpwr_sdramclk_ctrl |= CLKPWR_SDRCLK_DO_CAL;
		CLKPWR->clkpwr_sdramclk_ctrl &= ~CLKPWR_SDRCLK_DO_CAL;
		timer_wait_ms(TIMER_CNTR0, 25);
		ringosccount += CLKPWR->clkpwr_ddr_lap_count;
	}

	/* use the average for the nominal ring oscillator value */
	CLKPWR->clkpwr_ddr_lap_nom = ringosccount / 10;

	/* Enable automatic RTC tick calibration, but keep calibration off
	   for now until uncalibrated DQS delay is found. */
	CLKPWR->clkpwr_sdramclk_ctrl |= CLKPWR_SDRCLK_CAL_ON_RTC;
	CLKPWR->clkpwr_sdramclk_ctrl &= ~CLKPWR_SDRCLK_USE_CAL;

	/* Setup CAS and RAS latencies */
	EMC->emcdynamicrascas0 =
		EMC_SET_CAS_IN_HALF_CYCLES(SDRAM_CAS_LATENCY) |
		EMC_SET_RAS_IN_CYCLES(SDRAM_RAS_LATENCY);

#ifdef USE_DUAL_SDRAM_DEVICES
	EMC->emcdynamicrascas1 =
		EMC_SET_CAS_IN_HALF_CYCLES(SDRAM_CAS_LATENCY) |
		EMC_SET_RAS_IN_CYCLES(SDRAM_RAS_LATENCY);
#endif

	/* Setup DDR read strategy */
	EMC->emcdynamicreadconfig = (EMC_SDR_CLK_NODLY_CMD_DEL |
	    EMC_SDR_READCAP_POS_POL | EMC_DDR_CLK_NODLY_CMD_DEL);

	/* Setup slew rates */
#ifdef SDRAM_USE_SLOW_SLEW
	CLKPWR->clkpwr_sdramclk_ctrl |= (CLKPWR_SDRCLK_SLOWSLEW_CLK |
		CLKPWR_SDRCLK_SLOWSLEW | CLKPWR_SDRCLK_SLOWSLEW_DAT);

#else
	CLKPWR->clkpwr_sdramclk_ctrl &= ~(CLKPWR_SDRCLK_SLOWSLEW_CLK |
		CLKPWR_SDRCLK_SLOWSLEW | CLKPWR_SDRCLK_SLOWSLEW_DAT);
#endif
}