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; }