/*********************************************************************** * * Function: dqsin_ddr_mod * * Purpose: Adjusts non-calibrated DQSIN delay and cal sensitivity * * Processing: * See function. * * Parameters: * ddl : New DQSIN delay value * * Outputs: None * * Returns: Nothing * * Notes: None * **********************************************************************/ static void dqsin_ddr_mod(UNS_32 ddl) { UNS_32 tmp; /* Adjust calibration sensitivity with DQS delay */ tmp = CLKPWR->clkpwr_sdramclk_ctrl & ~(CLKPWR_SDRCLK_SENS_FACT(7) | CLKPWR_SDRCLK_DQS_DLY(0x1F)); CLKPWR->clkpwr_sdramclk_ctrl = tmp | CLKPWR_SDRCLK_DQS_DLY(ddl) | CLKPWR_SDRCLK_SENS_FACT(dqs2calsen[ddl]); }
/*********************************************************************** * * 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 }