He estado tratando de estudiar cómo funciona el gestor de arranque ARM, pero la inicialización de SDRAM sigue siendo un misterio para mí. Por ejemplo, AT91 Bootstrap utiliza la siguiente función para la inicialización. Creo que entiendo la mayoría de los pasos, pero ¿por qué es necesario el paso # 7 (8 ciclos de actualización automática)?
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;
}