From 18ba012b9b919a7c264dc6299f954d7f53d06605 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Wed, 24 Feb 2010 19:45:39 +0100 Subject: edb93xx: Fix SDRAM initialization edb93xx: Fix SDRAM initialization by issuing a precharge all command before forcing the precharge and select mode register update mode before programming the mode registers. Write to the SDRAM banks in order to force a precharge, reading causes the edb93xx boards to hang Signed-off-by: Matthias Kaehlcke --- board/edb93xx/sdram_cfg.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/board/edb93xx/sdram_cfg.c b/board/edb93xx/sdram_cfg.c index 6155f0eb459..440ad11fcb0 100644 --- a/board/edb93xx/sdram_cfg.c +++ b/board/edb93xx/sdram_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Matthias Kaehlcke + * Copyright (C) 2009, 2010 Matthias Kaehlcke * * Copyright (C) 2006 Dominic Rath * @@ -30,9 +30,9 @@ (SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank | SDRAM_MODE_REG_VAL)) #define PRECHARGE_BANK(bank) (*(volatile uint32_t *) \ - (SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank)) + (SDRAM_BASE_ADDR | SDRAM_BANK_SEL_##bank)) = 0 -static void force_precharge(void); +static void precharge_all_banks(void); static void setup_refresh_timer(void); static void program_mode_registers(void); @@ -47,7 +47,7 @@ void sdram_cfg(void) early_udelay(200); - force_precharge(); + precharge_all_banks(); setup_refresh_timer(); @@ -57,19 +57,37 @@ void sdram_cfg(void) writel(GLCONFIG_CKE, &sdram->glconfig); } -static void force_precharge(void) +static void precharge_all_banks(void) { + struct sdram_regs *sdram = (struct sdram_regs *)SDRAM_BASE; + + /* Issue PRECHARGE ALL commands */ + writel(GLCONFIG_INIT | GLCONFIG_CKE, &sdram->glconfig); + /* - * Errata most EP93xx revisions say that PRECHARGE ALL isn't always - * issued. + * Errata of most EP93xx revisions say that PRECHARGE ALL isn't always + * issued * - * Do a read from each bank to make sure they're precharged + * Cirrus proposes a workaround which consists in performing a read from + * each bank to force the precharge. This causes some boards to hang. + * Writing to the SDRAM banks instead of reading has the same + * side-effect (the SDRAM controller issues the necessary precharges), + * but is known to work on all supported boards */ PRECHARGE_BANK(0); + +#if (CONFIG_NR_DRAM_BANKS >= 2) PRECHARGE_BANK(1); +#endif + +#if (CONFIG_NR_DRAM_BANKS >= 3) PRECHARGE_BANK(2); +#endif + +#if (CONFIG_NR_DRAM_BANKS == 4) PRECHARGE_BANK(3); +#endif } static void setup_refresh_timer(void) @@ -101,6 +119,11 @@ static void setup_refresh_timer(void) static void program_mode_registers(void) { + struct sdram_regs *sdram = (struct sdram_regs *)SDRAM_BASE; + + /* Select mode register update mode */ + writel(GLCONFIG_MRS | GLCONFIG_CKE, &sdram->glconfig); + /* * The mode registers are programmed by performing a read from each * SDRAM bank. The value of the address that is read defines the value -- cgit v1.2.3