[U-Boot] [PATCH 2/2] edb93xx sdram: fix initialization

Matthias Kaehlcke matthias at kaehlcke.net
Tue Feb 16 20:24:58 CET 2010


Hi Alessandro,

El Sat, Feb 13, 2010 at 12:01:34AM +0100 Alessandro Rubini ha dit:

> I'm sorry I can't test before wednesday as I'll be offline.
> 
> I am doubtful, as usually precharge is done before setting mode, but
> your chips are clearly different from mine, I now expect that no
> sequence works for both of them.

i found some more information about the precharge workaround: Cirrus
added it to the RedBoot of v1.4.3 of its BSP, but commented in the
most recent version (v1.4.5) after people started complaining that
it causes their boards to hang
(http://arm.cirrus.com/forum/viewtopic.php?t=48&highlight=precharge&sid=e13913b8baa37aabbb6c73a911935080)

conclusion: their workaround doesn't seem to work :/

please test the below patch on your board when you get a chance. it
should be pretty much the same sequence that worked for you, i just
removed the *workaround* that makes my boards hang and restructured
the code a little

---

diff --git a/board/edb93xx/sdram_cfg.c b/board/edb93xx/sdram_cfg.c
index 6155f0e..9c0fa9a 100644
--- a/board/edb93xx/sdram_cfg.c
+++ b/board/edb93xx/sdram_cfg.c
@@ -29,10 +29,7 @@
 #define PROGRAM_MODE_REG(bank)		(*(volatile uint32_t *)		\
 		(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))
-
-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 +44,7 @@ void sdram_cfg(void)
 
 	early_udelay(200);
 
-	force_precharge();
+	precharge_all_banks();
 
 	setup_refresh_timer();
 
@@ -57,19 +54,25 @@ 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
+	 *
+	 * Cirrus proposes a workaround consisting in performing a read from
+	 * each bank to force the precharge. Unfortunately this causes the board
+	 * to hang. Cirrus added this workaround to the RedBoot bootloader they
+	 * deliver, but had to remove it one version later after problems were
+	 * reported
 	 *
-	 * Do a read from each bank to make sure they're precharged
+	 * Thus it seems the only workaround currently available is hope ...
 	 */
-
-	PRECHARGE_BANK(0);
-	PRECHARGE_BANK(1);
-	PRECHARGE_BANK(2);
-	PRECHARGE_BANK(3);
 }
 
 static void setup_refresh_timer(void)
@@ -101,6 +104,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

-- 
Matthias Kaehlcke
Embedded Linux Developer
Barcelona

             "The only important thing Windows does better
            than Debian is implementing the win32 platform"
                                                                 .''`.
    using free software / Debian GNU/Linux | http://debian.org  : :'  :
                                                                `. `'`
gpg --keyserver pgp.mit.edu --recv-keys 47D8E5D4                  `-


More information about the U-Boot mailing list