]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
Add CFG_USE_OSCCLK option to handle OCSM clock mode problem on MBX8xx
authorwdenk <wdenk>
Sun, 16 Dec 2001 00:16:58 +0000 (00:16 +0000)
committerwdenk <wdenk>
Sun, 16 Dec 2001 00:16:58 +0000 (00:16 +0000)
(Based on email by Erik Theisen, 07 Dec 2001).

CHANGELOG
README
board/mbx8xx/mbx8xx.c

index 5c6c889048600236dccc8e915e38d816b9d012fe..1d7ab4d47ce886ea8582071f5d1302fadbd2abf2 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,9 @@ To do:
 Modifications for 1.1.3:
 ======================================================================
 
+* Add CFG_USE_OSCCLK option to handle OCSM clock mode problem on MBX8xx
+  (Based on email by Erik Theisen, 07 Dec 2001).
+
 * Fix ethernet package corruption on EVB64260 board
   Patch by Rich Ireland, 10 Dec 2001
 
diff --git a/README b/README
index 059a1ebae4c1d3ac7ac39e4f8a638c7911c6e72a..d920e9c939c1a16118f8cbe6642397c75f0c0f0b 100644 (file)
--- a/README
+++ b/README
@@ -1048,6 +1048,10 @@ Low Level (hardware related) configuration options:
                enable SPI microcode relocation patch (MPC8xx);
                define relocation offset in DPRAM [SCC4]
 
+- CFG_USE_OSCCLK:
+                Use OSCM clock mode on MBX8xx board. Be careful,
+                wrong setting might damage your board. Read
+                doc/README.MBX before setting this variable!
 
 Building the Software:
 ======================
@@ -1112,6 +1116,16 @@ Note: for some board special configuration names may exist; check  if
       make TQM860L_FEC_80MHz_config
         - will configure for a TQM860L at 80 MHz with FEC for ethernet
 
+      make TQM823L_LCD_config
+        - will configure for a TQM823L with PPCBoot console on LCD
+
+      make TQM823L_LCD_80MHz_config
+        - will configure for a TQM823L at 80 MHz with PPCBoot console on LCD
+
+      etc.
+
+
+
 Finally, type "make all", and you should  get  some  working  PPCBoot
 images ready for downlod to / installation on your system:
 
index efe4f97e4d6d4c5b14fff30fc13538c7ddad1ad7..a3f0aae310655c9638d660d51cf94f3f0a446602 100644 (file)
@@ -22,7 +22,7 @@
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
 
 /* ------------------------------------------------------------------------- */
 
-static const uint sdram_table_40[] =
-{
-    /* DRAM - single read. (offset 0 in upm RAM)
-     */
-  0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
-  0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* DRAM - burst read. (offset 8 in upm RAM)
-     */
-  0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
-  0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
-  0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* DRAM - single write. (offset 18 in upm RAM)
-     */
-  0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* DRAM - burst write. (offset 20 in upm RAM)
-     */
-  0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
-  0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
-  0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* refresh  (offset 30 in upm RAM)
-     */
-  0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
-  0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* exception. (offset 3c in upm RAM)
-     */
-  0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+static const uint sdram_table_40[] = {
+       /* DRAM - single read. (offset 0 in upm RAM)
+        */
+       0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x30AF0C00,
+       0xF1BF4805, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* DRAM - burst read. (offset 8 in upm RAM)
+        */
+       0xCFAFC004, 0x0FAFC404, 0x0CAF0C04, 0x03AF0C08,
+       0x0CAF0C04, 0x03AF0C08, 0x0CAF0C04, 0x03AF0C08,
+       0x0CAF0C04, 0x30AF0C00, 0xF3BF4805, 0xFFFFC005,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* DRAM - single write. (offset 18 in upm RAM)
+        */
+       0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x33FF4804,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* DRAM - burst write. (offset 20 in upm RAM)
+        */
+       0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+       0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+       0x0CFF0C00, 0x33FF4804, 0xFFFFC005, 0xFFFFC005,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* refresh  (offset 30 in upm RAM)
+        */
+       0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+       0x3FFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* exception. (offset 3c in upm RAM)
+        */
+       0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
 };
 
-static const uint sdram_table_50[] =
-{
-    /* DRAM - single read. (offset 0 in upm RAM)
-     */
-  0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
-  0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
-
-    /* DRAM - burst read. (offset 8 in upm RAM)
-     */
-  0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x00AF0C04,
-  0x07AF0C08, 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C04,
-  0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08, 0x0CAF0C04,
-  0x10AF0C04, 0xF0AFC000, 0xF3FF4805, 0xFFFFC005,
-
-    /* DRAM - single write. (offset 18 in upm RAM)
-     */
-  0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
-  0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* DRAM - burst write. (offset 20 in upm RAM)
-     */
-  0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
-  0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
-  0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* refresh  (offset 30 in upm RAM)
-     */
-  0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
-  0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
-  0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
-
-    /* exception. (offset 3c in upm RAM)
-     */
-  0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
+static const uint sdram_table_50[] = {
+       /* DRAM - single read. (offset 0 in upm RAM)
+        */
+       0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x10AF0C04,
+       0xF0AF0C00, 0xF3BF4805, 0xFFFFC005, 0xFFFFC005,
+
+       /* DRAM - burst read. (offset 8 in upm RAM)
+        */
+       0xCFAFC004, 0x0FAFC404, 0x0CAF8C04, 0x00AF0C04,
+       0x07AF0C08, 0x0CAF0C04, 0x01AF0C04, 0x0FAF0C04,
+       0x0CAF0C04, 0x01AF0C04, 0x0FAF0C08, 0x0CAF0C04,
+       0x10AF0C04, 0xF0AFC000, 0xF3FF4805, 0xFFFFC005,
+
+       /* DRAM - single write. (offset 18 in upm RAM)
+        */
+       0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x13FF4804,
+       0xFFFFC004, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* DRAM - burst write. (offset 20 in upm RAM)
+        */
+       0xCFFF0004, 0x0FFF0404, 0x0CFF0C00, 0x03FF0C0C,
+       0x0CFF0C00, 0x03FF0C0C, 0x0CFF0C00, 0x03FF0C0C,
+       0x0CFF0C00, 0x13FF4804, 0xFFFFC004, 0xFFFFC005,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* refresh  (offset 30 in upm RAM)
+        */
+       0xFCFFC004, 0xC0FFC004, 0x01FFC004, 0x0FFFC004,
+       0x1FFFC004, 0xFFFFC004, 0xFFFFC005, 0xFFFFC005,
+       0xFFFFC005, 0xFFFFC005, 0xFFFFC005, 0xFFFFC005,
+
+       /* exception. (offset 3c in upm RAM)
+        */
+       0xFFFFC007, 0xFFFFC007, 0xFFFFC007, 0xFFFFC007,
 };
 
 /* ------------------------------------------------------------------------- */
@@ -119,123 +117,122 @@ static const uint sdram_table_50[] =
 static unsigned int get_reffreq(void);
 static unsigned int board_get_cpufreq(void);
 
-void mbx_init(void)
+void mbx_init (void)
 {
-    volatile immap_t *immr = (immap_t *)CFG_IMMR;
-    volatile memctl8xx_t *memctl = &immr->im_memctl;
-    ulong speed, refclock, plprcr, sccr;
-    ulong br0_32 = memctl->memc_br0 & 0x400;
-
-    /* real-time clock status and control register */
-    immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
-    immr->im_sit.sit_rtcsc = 0x00C3;
-
-    /* SIEL and SIMASK Registers (see MBX PRG 2-3) */
-    immr->im_siu_conf.sc_simask = 0x00000000;
-    immr->im_siu_conf.sc_siel = 0xAAAA0000;
-    immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
-
-    /*
-     * Prepare access to i2c bus. The MBX offers 3 devices on the i2c
-     * bus:
-     * 1. Vital Product Data (contains clock speeds, mac-address etc,
-     *    see vpd.h)
-     * 2. RAM Specs (see dimm.h)
-     * 2. DIMM Specs (see dimm.h)
-     */
-    vpd_init();
-
-    /* system clock and reset control register */
-    immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
-    sccr = immr->im_clkrst.car_sccr;
-    sccr &= SCCR_MASK;
-    sccr |= CFG_SCCR;
-    immr->im_clkrst.car_sccr = sccr;
-
-    speed = board_get_cpufreq();
-    refclock = get_reffreq();
+       volatile immap_t *immr = (immap_t *) CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immr->im_memctl;
+       ulong speed, refclock, plprcr, sccr;
+       ulong br0_32 = memctl->memc_br0 & 0x400;
+
+       /* real-time clock status and control register */
+       immr->im_sitk.sitk_rtcsck = KAPWR_KEY;
+       immr->im_sit.sit_rtcsc = 0x00C3;
+
+       /* SIEL and SIMASK Registers (see MBX PRG 2-3) */
+       immr->im_siu_conf.sc_simask = 0x00000000;
+       immr->im_siu_conf.sc_siel = 0xAAAA0000;
+       immr->im_siu_conf.sc_tesr = 0xFFFFFFFF;
+
+       /*
+        * Prepare access to i2c bus. The MBX offers 3 devices on the i2c bus:
+        * 1. Vital Product Data (contains clock speeds, MAC address etc, see vpd.h)
+        * 2. RAM  Specs (see dimm.h)
+        * 2. DIMM Specs (see dimm.h)
+        */
+       vpd_init ();
+
+       /* system clock and reset control register */
+       immr->im_clkrstk.cark_sccrk = KAPWR_KEY;
+       sccr = immr->im_clkrst.car_sccr;
+       sccr &= SCCR_MASK;
+       sccr |= CFG_SCCR;
+       immr->im_clkrst.car_sccr = sccr;
+
+       speed = board_get_cpufreq ();
+       refclock = get_reffreq ();
 
 #if ((CFG_PLPRCR & PLPRCR_MF_MSK) != 0)
-    plprcr = CFG_PLPRCR;
+       plprcr = CFG_PLPRCR;
 #else
-    plprcr = immr->im_clkrst.car_plprcr;
-    plprcr &= PLPRCR_MF_MSK;               /* isolate MF field     */
-    plprcr |= CFG_PLPRCR;                  /* reset control bits   */
+       plprcr = immr->im_clkrst.car_plprcr;
+       plprcr &= PLPRCR_MF_MSK;        /* isolate MF field */
+       plprcr |= CFG_PLPRCR;           /* reset control bits   */
 #endif
-#if 1  /* XXX - Just what was this for??? email etheisen@mindspring.com */
-    plprcr |= ((speed + refclock / 2) / refclock - 1) << 20;
+
+#ifdef CFG_USE_OSCCLK                  /* See doc/README.MBX ! */
+       plprcr |= ((speed + refclock / 2) / refclock - 1) << 20;
 #endif
-    immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
-    immr->im_clkrst.car_plprcr = plprcr;
-
-    /*
-     * preliminary setup of memory controller:
-     * - map Flash, otherwise configuration/status
-     *    registers won't be accessible when read
-     *    by board_init_f.
-     * - map NVRAM and configuation/status registers.
-     * - map pci registers.
-     * - DON'T map ram yet, this is done in initdram().
-     */
-    switch(speed / 1000000)
-    {
-    case 40:
-       memctl->memc_br0 = 0xfe000000 | br0_32 | 1;
-       memctl->memc_or0 = 0xff800930;
-       memctl->memc_or4 = CFG_NVRAM_OR   | 0x920;
-       memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
-       break;
-    case 50:
-       memctl->memc_br0 = 0xfe000000 | br0_32 | 1;
-       memctl->memc_or0 = 0xff800940;
-       memctl->memc_or4 = CFG_NVRAM_OR   | 0x930;
-       memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
-       break;
-    default:
-       hang();
-       break;
-    }
-    memctl->memc_or5 = CFG_PCIMEM_OR;
-    memctl->memc_br5 = CFG_PCIMEM_BASE | 0x001;
-    memctl->memc_or6 = CFG_PCIBRIDGE_OR;
-    memctl->memc_br6 = CFG_PCIBRIDGE_BASE | 0x001;
+
+       immr->im_clkrstk.cark_plprcrk = KAPWR_KEY;
+       immr->im_clkrst.car_plprcr = plprcr;
+
+       /*
+        * preliminary setup of memory controller:
+        * - map Flash, otherwise configuration/status
+        *    registers won't be accessible when read
+        *    by board_init_f.
+        * - map NVRAM and configuation/status registers.
+        * - map pci registers.
+        * - DON'T map ram yet, this is done in initdram().
+        */
+       switch (speed / 1000000) {
+       case 40:
+               memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+               memctl->memc_or0 = 0xFF800930;
+               memctl->memc_or4 = CFG_NVRAM_OR | 0x920;
+               memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+               break;
+       case 50:
+               memctl->memc_br0 = 0xFE000000 | br0_32 | 1;
+               memctl->memc_or0 = 0xFF800940;
+               memctl->memc_or4 = CFG_NVRAM_OR | 0x930;
+               memctl->memc_br4 = CFG_NVRAM_BASE | 0x401;
+               break;
+       default:
+               hang ();
+               break;
+       }
+       memctl->memc_or5 = CFG_PCIMEM_OR;
+       memctl->memc_br5 = CFG_PCIMEM_BASE | 0x001;
+       memctl->memc_or6 = CFG_PCIBRIDGE_OR;
+       memctl->memc_br6 = CFG_PCIBRIDGE_BASE | 0x001;
 }
 
-void board_serial_init(void)
+void board_serial_init (void)
 {
-    MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
+       MBX_CSR1 &= ~(CSR1_COM1EN | CSR1_XCVRDIS);
 }
 
-void board_ether_init(void)
+void board_ether_init (void)
 {
-    MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
-    MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS ;
+       MBX_CSR1 &= ~(CSR1_EAEN | CSR1_ELEN);
+       MBX_CSR1 |= CSR1_ETEN | CSR1_TPEN | CSR1_FDDIS;
 }
 
-static unsigned int board_get_cpufreq(void)
+static unsigned int board_get_cpufreq (void)
 {
-    vpd_packet_t *packet;
+       vpd_packet_t *packet;
 
-    packet = vpd_find_packet(VPD_PID_ICS);
-    return *((ulong*)packet->data);
+       packet = vpd_find_packet (VPD_PID_ICS);
+       return *((ulong *) packet->data);
 }
 
-static unsigned int get_reffreq(void)
+static unsigned int get_reffreq (void)
 {
-    vpd_packet_t *packet;
+       vpd_packet_t *packet;
 
-    packet = vpd_find_packet(VPD_PID_RCS);
-    return *((ulong*)packet->data);
+       packet = vpd_find_packet (VPD_PID_RCS);
+       return *((ulong *) packet->data);
 }
 
-void board_get_enetaddr (uchar *addr)
+void board_get_enetaddr (uchar * addr)
 {
-    int i;
-    vpd_packet_t *packet;
+       int i;
+       vpd_packet_t *packet;
 
-    packet = vpd_find_packet(VPD_PID_EA);
-    for (i=0; i<6; i++)
-      addr[i] = packet->data[i];
+       packet = vpd_find_packet (VPD_PID_EA);
+       for (i = 0; i < 6; i++)
+               addr[i] = packet->data[i];
 }
 
 /*
@@ -244,127 +241,121 @@ void board_get_enetaddr (uchar *addr)
 
 int checkboard (void)
 {
-    vpd_packet_t *packet;
-    int i;
-
-    packet = vpd_find_packet(VPD_PID_PID);
-    for (i=0; i<packet->size; i++) {
-       serial_putc (packet->data[i]);
-    }
-    packet = vpd_find_packet(VPD_PID_MT);
-    for (i=0; i<packet->size; i++) {
-       serial_putc (packet->data[i]);
-    }
-    serial_putc ('(');
-    packet = vpd_find_packet(VPD_PID_FAN);
-    for (i=0; i<packet->size; i++) {
-       serial_putc (packet->data[i]);
-    }
-    serial_putc (')');
-
-    if (!(MBX_CSR2 & SR2_BATGD))
-      printf("\n         *** Warning: Low Battery Status - On-Board Battery ***");
-    if (!(MBX_CSR2 & SR2_NVBATGD))
-      printf("\n         *** Warning: Low Battery Status - NVRAM Battery ***");
-
-    serial_putc ('\n');
-
-    return (1);
+       vpd_packet_t *packet;
+       int i;
+       const char *const fmt =
+               "\n      *** Warning: Low Battery Status - %s Battery ***");
+
+       packet = vpd_find_packet (VPD_PID_PID);
+       for (i = 0; i < packet->size; i++) {
+               serial_putc (packet->data[i]);
+       }
+       packet = vpd_find_packet (VPD_PID_MT);
+       for (i = 0; i < packet->size; i++) {
+               serial_putc (packet->data[i]);
+       }
+       serial_putc ('(');
+       packet = vpd_find_packet (VPD_PID_FAN);
+       for (i = 0; i < packet->size; i++) {
+               serial_putc (packet->data[i]);
+       }
+       serial_putc (')');
+
+       if (!(MBX_CSR2 & SR2_BATGD))
+               printf (fmt, "On-Board");
+       if (!(MBX_CSR2 & SR2_NVBATGD))
+               printf (fmt, "NVRAM");
+
+       serial_putc ('\n');
+
+       return (1);
 }
 
 /* ------------------------------------------------------------------------- */
 
-static ulong get_ramsize(dimm_t *dimm)
+static ulong get_ramsize (dimm_t * dimm)
 {
-    ulong size = 0;
+       ulong size = 0;
 
-    if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3 || dimm->fmt == 4 )
-    {
-       size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
-         ((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
-    }
+       if (dimm->fmt == 1 || dimm->fmt == 2 || dimm->fmt == 3
+               || dimm->fmt == 4) {
+               size = (1 << (dimm->n_row + dimm->n_col)) * dimm->n_banks *
+                       ((dimm->data_w_hi << 8 | dimm->data_w_lo) / 8);
+       }
 
-    return size;
+       return size;
 }
 
 long int initdram (int board_type)
 {
-    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
-    volatile memctl8xx_t *memctl = &immap->im_memctl;
-    unsigned long ram_sz = 0;
-    unsigned long dimm_sz = 0;
-    dimm_t vpd_dimm, vpd_dram;
-    unsigned int speed = board_get_cpufreq() / 1000000;
-
-    if (vpd_read(0xa2, (uchar*)&vpd_dimm, sizeof(vpd_dimm), 0) > 0)
-    {
-       dimm_sz = get_ramsize(&vpd_dimm);
-    }
-    if (vpd_read(0xa6, (uchar*)&vpd_dram, sizeof(vpd_dram), 0) > 0)
-    {
-       ram_sz = get_ramsize(&vpd_dram);
-    }
-
-    /*
-     * Only initialize memory controller when running from FLASH.
-     * When running from RAM, don't touch it.
-     */
-    if ((ulong)initdram & 0xff000000)
-    {
-       ulong dimm_bank;
-       ulong br0_32 = memctl->memc_br0 & 0x400;
-
-       switch(speed)
-       {
-       case 40:
-           upmconfig(UPMA, (uint *)sdram_table_40,
-                     sizeof(sdram_table_40) / sizeof(uint));
-           memctl->memc_mptpr = 0x0200;
-           memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
-           memctl->memc_or7 = 0xff800930;
-           memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
-           break;
-       case 50:
-           upmconfig(UPMA, (uint *)sdram_table_50,
-                     sizeof(sdram_table_50) / sizeof(uint));
-           memctl->memc_mptpr = 0x0200;
-           memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
-           memctl->memc_or7 = 0xff800940;
-           memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
-           break;
-       default:
-           hang();
-           break;
+       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+       unsigned long ram_sz = 0;
+       unsigned long dimm_sz = 0;
+       dimm_t vpd_dimm, vpd_dram;
+       unsigned int speed = board_get_cpufreq () / 1000000;
+
+       if (vpd_read (0xa2, (uchar *) & vpd_dimm, sizeof (vpd_dimm), 0) > 0) {
+               dimm_sz = get_ramsize (&vpd_dimm);
        }
-
-       /* now map ram and dimm, largest one first */
-       dimm_bank = dimm_sz / 2;
-       if (!dimm_sz)
-       {
-           memctl->memc_or1 = ~(ram_sz - 1)   | 0x400;
-           memctl->memc_br1 = CFG_SDRAM_BASE  | 0x81;
-           memctl->memc_br2 = 0;
-           memctl->memc_br3 = 0;
-       }
-       else if (ram_sz > dimm_bank)
-       {
-           memctl->memc_or1 = ~(ram_sz - 1)   | 0x400;
-           memctl->memc_br1 = CFG_SDRAM_BASE  | 0x81;
-           memctl->memc_or2 = ~(dimm_bank - 1)          | 0x400;
-           memctl->memc_br2 = (CFG_SDRAM_BASE + ram_sz) | 0x81;
-           memctl->memc_or3 = ~(dimm_bank - 1)                      | 0x400;
-           memctl->memc_br3 = (CFG_SDRAM_BASE + ram_sz + dimm_bank) | 0x81;
+       if (vpd_read (0xa6, (uchar *) & vpd_dram, sizeof (vpd_dram), 0) > 0) {
+               ram_sz = get_ramsize (&vpd_dram);
        }
-       else
-       {
-           memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
-           memctl->memc_br2 = CFG_SDRAM_BASE   | 0x81;
-           memctl->memc_or3 = ~(dimm_bank - 1)             | 0x400;
-           memctl->memc_br3 = (CFG_SDRAM_BASE + dimm_bank) | 0x81;
-           memctl->memc_or1 = ~(ram_sz - 1)              | 0x400;
-           memctl->memc_br1 = (CFG_SDRAM_BASE + dimm_sz) | 0x81;
+
+       /*
+        * Only initialize memory controller when running from FLASH.
+        * When running from RAM, don't touch it.
+        */
+       if ((ulong) initdram & 0xff000000) {
+               ulong dimm_bank;
+               ulong br0_32 = memctl->memc_br0 & 0x400;
+
+               switch (speed) {
+               case 40:
+                       upmconfig (UPMA, (uint *) sdram_table_40,
+                                          sizeof (sdram_table_40) / sizeof (uint));
+                       memctl->memc_mptpr = 0x0200;
+                       memctl->memc_mamr = dimm_sz ? 0x06801000 : 0x13801000;
+                       memctl->memc_or7 = 0xff800930;
+                       memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+                       break;
+               case 50:
+                       upmconfig (UPMA, (uint *) sdram_table_50,
+                                          sizeof (sdram_table_50) / sizeof (uint));
+                       memctl->memc_mptpr = 0x0200;
+                       memctl->memc_mamr = dimm_sz ? 0x08801000 : 0x1880100;
+                       memctl->memc_or7 = 0xff800940;
+                       memctl->memc_br7 = 0xfc000000 | (br0_32 ^ br0_32) | 1;
+                       break;
+               default:
+                       hang ();
+                       break;
+               }
+
+               /* now map ram and dimm, largest one first */
+               dimm_bank = dimm_sz / 2;
+               if (!dimm_sz) {
+                       memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+                       memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+                       memctl->memc_br2 = 0;
+                       memctl->memc_br3 = 0;
+               } else if (ram_sz > dimm_bank) {
+                       memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+                       memctl->memc_br1 = CFG_SDRAM_BASE | 0x81;
+                       memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+                       memctl->memc_br2 = (CFG_SDRAM_BASE + ram_sz) | 0x81;
+                       memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+                       memctl->memc_br3 = (CFG_SDRAM_BASE + ram_sz + dimm_bank) \
+                                                                    | 0x81;
+               } else {
+                       memctl->memc_or2 = ~(dimm_bank - 1) | 0x400;
+                       memctl->memc_br2 = CFG_SDRAM_BASE | 0x81;
+                       memctl->memc_or3 = ~(dimm_bank - 1) | 0x400;
+                       memctl->memc_br3 = (CFG_SDRAM_BASE + dimm_bank) | 0x81;
+                       memctl->memc_or1 = ~(ram_sz - 1) | 0x400;
+                       memctl->memc_br1 = (CFG_SDRAM_BASE + dimm_sz) | 0x81;
+               }
        }
-    }
 
-    return ram_sz + dimm_sz;
+       return ram_sz + dimm_sz;
 }