/* * (C) Copyright 2003 * MuLogic B.V. * * (C) Copyright 2002 * Simple Network Magic Corporation, dnevil@snmc.com * * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ #include <common.h> #include <asm/u-boot.h> #include <commproc.h> #include "mpc8xx.h" /* ------------------------------------------------------------------------- */ static long int dram_size (long int, long int *, long int); /* ------------------------------------------------------------------------- */ const uint sdram_table[] = { /* * Single Read. (Offset 0 in UPMA RAM) */ 0x0f07cc04, 0x00adcc04, 0x00a74c00, 0x00bfcc04, 0x1fffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05, /* * Burst Read. (Offset 8 in UPMA RAM) */ 0x0ff7fc04, 0x0ffffc04, 0x00bdfc04, 0x00fffc00, 0x00fffc00, 0x00fffc00, 0x0ff77c00, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, /* * Single Write. (Offset 18 in UPMA RAM) */ 0x0f07cc04, 0x0fafcc00, 0x01ad0c04, 0x1ff74c07, 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05, /* * Burst Write. (Offset 20 in UPMA RAM) */ 0x0ff7fc04, 0x0ffffc00, 0x00bd7c00, 0x00fffc00, 0x00fffc00, 0x00fffc00, 0x0ffffc04, 0x0ff77c04, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, 0x1ffffc05, /* * Refresh (Offset 30 in UPMA RAM) */ 0xffffcc04, 0x1ff5cc84, 0xffffcc04, 0xffffcc04, 0xffffcc84, 0xffffcc05, 0xffffcc04, 0xffffcc04, 0xffffcc04, 0xffffcc04, 0xffffcc04, 0xffffcc04, /* * Exception. (Offset 3c in UPMA RAM) */ 0x1ff74c04, 0xffffcc07, 0xffffaa34, 0x1fb54a37 }; /* ------------------------------------------------------------------------- */ /* * Check Board Identity: * * Test ID string (QS850, QS823, ...) * * Always return 1 */ #if defined(CONFIG_QS850) #define BOARD_IDENTITY "QS850" #elif defined(CONFIG_QS823) #define BOARD_IDENTITY "QS823" #else #define BOARD_IDENTITY "QS???" #endif int checkboard (void) { char *s, *e; char buf[64]; int i; i = getenv_r("serial#", buf, sizeof(buf)); s = (i>0) ? buf : NULL; if (!s || strncmp(s, BOARD_IDENTITY, 5)) { puts ("### No HW ID - assuming " BOARD_IDENTITY); } else { for (e=s; *e; ++e) { if (*e == ' ') break; } for ( ; s<e; ++s) { putc (*s); } } putc ('\n'); return (0); } /* ------------------------------------------------------------------------- */ /* SDRAM Mode Register Definitions */ /* Set SDRAM Burst Length to 4 (010) */ /* See Motorola MPC850 User Manual, Page 13-14 */ #define SDRAM_BURST_LENGTH (2) /* Set Wrap Type to Sequential (0) */ /* See Motorola MPC850 User Manual, Page 13-14 */ #define SDRAM_WRAP_TYPE (0 << 3) /* Set /CAS Latentcy to 2 clocks */ #define SDRAM_CAS_LATENTCY (2 << 4) /* The Mode Register value must be shifted left by 2, since it is */ /* placed on the address bus, and the 2 LSBs are ignored for 32-bit accesses */ #define SDRAM_MODE_REG ((SDRAM_BURST_LENGTH|SDRAM_WRAP_TYPE|SDRAM_CAS_LATENTCY) << 2) #define UPMA_RUN(loops,index) (0x80002000 + (loops<<8) + index) /* Please note a value of zero = 16 loops */ #define REFRESH_INIT_LOOPS (0) phys_size_t initdram (int board_type) { volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; volatile memctl8xx_t *memctl = &immap->im_memctl; long int size; upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint)); /* * Prescaler for refresh */ memctl->memc_mptpr = CONFIG_SYS_MPTPR; /* * Map controller bank 1 to the SDRAM address */ memctl->memc_or1 = CONFIG_SYS_OR1; memctl->memc_br1 = CONFIG_SYS_BR1; udelay(1000); /* perform SDRAM initialization sequence */ memctl->memc_mamr = CONFIG_SYS_16M_MAMR; udelay(100); /* Program the SDRAM's Mode Register */ memctl->memc_mar = SDRAM_MODE_REG; /* Run the Prechard Pattern at 0x3C */ memctl->memc_mcr = UPMA_RUN(1,0x3c); udelay(1); /* Run the Refresh program residing at MAD index 0x30 */ /* This contains the CBR Refresh command with a loop */ /* The SDRAM must be refreshed at least 2 times */ /* Please note a value of zero = 16 loops */ memctl->memc_mcr = UPMA_RUN(REFRESH_INIT_LOOPS,0x30); udelay(1); /* Run the Exception program residing at MAD index 0x3E */ /* This contains the Write Mode Register command */ /* The Write Mode Register command uses the value written to MAR */ memctl->memc_mcr = UPMA_RUN(1,0x3e); udelay (1000); /* * Check for 32M SDRAM Memory Size */ size = dram_size(CONFIG_SYS_32M_MAMR|MAMR_PTAE, (long *)SDRAM_BASE, SDRAM_32M_MAX_SIZE); udelay (1000); /* * Check for 16M SDRAM Memory Size */ if (size != SDRAM_32M_MAX_SIZE) { size = dram_size(CONFIG_SYS_16M_MAMR|MAMR_PTAE, (long *)SDRAM_BASE, SDRAM_16M_MAX_SIZE); udelay (1000); } udelay(10000); return (size); } /* ------------------------------------------------------------------------- */ /* * Check memory range for valid RAM. A simple memory test determines * the actually available RAM size between addresses `base' and * `base + maxsize'. Some (not all) hardware errors are detected: * - short between address lines * - short between data lines */ static long int dram_size (long int mamr_value, long int *base, long int maxsize) { volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR; volatile memctl8xx_t *memctl = &immap->im_memctl; memctl->memc_mamr = mamr_value; return (get_ram_size(base, maxsize)); }