I've been trying to study how the ARM bootloader works, but initialization of SDRAM is still somewhat a mystery to me. For example AT91 Bootstrap uses following function for initialization. I think I understand most of the steps, but why step #7 (8 auto-refresh cycles) is needed?
int sdramc_initialize(struct sdramc_register *sdramc_config,
unsigned int sdram_address)
{
unsigned int i;
/* Step#1 SDRAM feature must be in the configuration register */
sdramc_writel(SDRAMC_CR, sdramc_config->cr);
/* Step#2 For mobile SDRAM, temperature-compensated self refresh(TCSR),... */
/* Step#3 The SDRAM memory type must be set in the Memory Device Register */
sdramc_writel(SDRAMC_MDR, sdramc_config->mdr);
/* Step#4 The minimum pause of 200 us is provided to precede any single toggle */
for (i = 0; i < 1000; i++) ;
/* Step#5 A NOP command is issued to the SDRAM devices */
sdramc_writel(SDRAMC_MR, AT91C_SDRAMC_MODE_NOP);
writel(0x00000000, sdram_address);
/* Step#6 An All Banks Precharge command is issued to the SDRAM devices */
sdramc_writel(SDRAMC_MR, AT91C_SDRAMC_MODE_PRECHARGE);
writel(0x00000000, sdram_address);
for (i = 0; i < 10000; i++) ;
/* Step#7 Eight auto-refresh cycles are provided */
for (i = 0; i < 8; i++) {
sdramc_writel(SDRAMC_MR, AT91C_SDRAMC_MODE_AUTO_REFRESH);
writel(0x00000001 + i, sdram_address + 4 + 4 * i);
}
/* Step#8 A Mode Register set (MRS) cyscle is issued to program the SDRAM parameters(TCSR, PASR, DS) */
sdramc_writel(SDRAMC_MR, AT91C_SDRAMC_MODE_LOAD_MODE);
writel(0xcafedede, sdram_address + 0x24);
/* Step#9 For mobile SDRAM initialization, an Extended Mode Register set cycle is issued to ... */
/* Step#10 The application must go into Normal Mode, setting Mode to 0 in the Mode Register
and perform a write access at any location in the SDRAM. */
sdramc_writel(SDRAMC_MR, AT91C_SDRAMC_MODE_NORMAL); // Set Normal mode
writel(0x00000000, sdram_address); // Perform Normal mode
/* Step#11 Write the refresh rate into the count field in the SDRAMC Refresh Timer Rgister. */
sdramc_writel(SDRAMC_TR, sdramc_config->tr);
return 0;
}