Sequential accesses to non-existent memory must be synchronized,
authorWolfgang Denk <wd@pollux.denx.de>
Mon, 6 Nov 2006 16:06:36 +0000 (17:06 +0100)
committerWolfgang Denk <wd@denx.de>
Mon, 6 Nov 2006 16:06:36 +0000 (17:06 +0100)
at least on G2 cores.

This fixes get_ram_size() problems on MPC5200 Rev. B boards.

board/mcc200/mcc200.c
common/memsize.c
include/common.h

index 71a691b5dbf1fb171b62ad823b603aeef65d8dbb..8b475c690d9d24affb9d3e33930720a130482f23 100644 (file)
@@ -27,6 +27,7 @@
 #include <common.h>
 #include <mpc5xxx.h>
 #include <pci.h>
+#include <asm/processor.h>
 
 /* Two MT48LC8M32B2 for 32 MB */
 /* #include "mt48lc8m32b2-6-7.h" */
@@ -98,6 +99,7 @@ long int initdram (int board_type)
 {
        ulong dramsize = 0;
        ulong dramsize2 = 0;
+       uint svr, pvr;
 #ifndef CFG_RAMBOOT
        ulong test1, test2;
 
@@ -192,6 +194,23 @@ long int initdram (int board_type)
 
 #endif /* CFG_RAMBOOT */
 
+       /*
+        * On MPC5200B we need to set the special configuration delay in the
+        * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
+        * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
+        *
+        * "The SDelay should be written to a value of 0x00000004. It is
+        * required to account for changes caused by normal wafer processing
+        * parameters."
+        */
+       svr = get_svr();
+       pvr = get_pvr();
+       if ((SVR_MJREV(svr) >= 2) && (PVR_MAJ(pvr) == 1) && 
+           (PVR_MIN(pvr) == 4)) {
+               *(vu_long *)MPC5XXX_SDRAM_SDELAY = 0x04;
+               __asm__ volatile ("sync");
+       }
+
        return dramsize + dramsize2;
 }
 
index dbc812dfc51e65cd351cc1af069714a5f76e5734..6c275c9b25feec5189d2717f8dd35c46d6eb88da 100644 (file)
  * MA 02111-1307 USA
  */
 
+#include <config.h>
+#ifdef __PPC__
+/*
+ * At least on G2 PowerPC cores, sequential accesses to non-existent
+ * memory must be synchronized.
+ */
+# include <asm/io.h>   /* for sync() */
+#else
+# define sync()                /* nothing */
+#endif
 
 /*
  * Check memory range for valid RAM. A simple memory test determines
@@ -38,20 +48,27 @@ long get_ram_size(volatile long *base, long maxsize)
 
        for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
                addr = base + cnt;      /* pointer arith! */
+               sync ();
                save[i++] = *addr;
+               sync ();
                *addr = ~cnt;
        }
 
        addr = base;
+       sync ();
        save[i] = *addr;
+       sync ();
        *addr = 0;
 
+       sync ();
        if ((val = *addr) != 0) {
                /* Restore the original data before leaving the function.
                 */
+               sync ();
                *addr = save[i];
                for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
                        addr  = base + cnt;
+                       sync ();
                        *addr = save[--i];
                }
                return (0);
index 349d5cf726bdc833937267b97a57e2eba19c6fa9..ac78d1c001cf690d70528b4bffcd8782df3b971a 100644 (file)
@@ -270,7 +270,7 @@ int misc_init_r   (void);
 void   jumptable_init(void);
 
 /* common/memsize.c */
-int    get_ram_size  (volatile long *, long);
+long   get_ram_size  (volatile long *, long);
 
 /* $(BOARD)/$(BOARD).c */
 void   reset_phy     (void);