uboot/board/quantum/quantum.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24
  25#include <common.h>
  26#include <mpc8xx.h>
  27#include "fpga.h"
  28
  29/* ------------------------------------------------------------------------- */
  30
  31static long int dram_size (long int, long int *, long int);
  32unsigned long flash_init (void);
  33
  34/* ------------------------------------------------------------------------- */
  35
  36#define _NOT_USED_      0xFFFFCC25
  37
  38const uint sdram_table[] = {
  39        /*
  40         * Single Read. (Offset 00h in UPMA RAM)
  41         */
  42        0x0F03CC04, 0x00ACCC24, 0x1FF74C20, _NOT_USED_,
  43        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  44
  45        /*
  46         * Burst Read. (Offset 08h in UPMA RAM)
  47         */
  48        0x0F03CC04, 0x00ACCC24, 0x00FFCC20, 0x00FFCC20,
  49        0x01FFCC20, 0x1FF74C20, _NOT_USED_, _NOT_USED_,
  50        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  51        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  52
  53        /*
  54         * Single Write. (Offset 18h in UPMA RAM)
  55         */
  56        0x0F03CC02, 0x00AC0C24, 0x1FF74C25, _NOT_USED_,
  57        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  58
  59        /*
  60         * Burst Write. (Offset 20h in UPMA RAM)
  61         */
  62        0x0F03CC00, 0x00AC0C20, 0x00FFFC20, 0x00FFFC22,
  63        0x01FFFC24, 0x1FF74C25, _NOT_USED_, _NOT_USED_,
  64        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  65        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  66
  67        /*
  68         * Refresh. (Offset 30h in UPMA RAM)
  69         * (Initialization code at 0x36)
  70         */
  71        0x0FF0CC24, 0xFFFFCC24, _NOT_USED_, _NOT_USED_,
  72        _NOT_USED_, _NOT_USED_, 0xEFFB8C34, 0x0FF74C34,
  73        0x0FFACCB4, 0x0FF5CC34, 0x0FFCC34, 0x0FFFCCB4,
  74
  75        /*
  76         * Exception. (Offset 3Ch in UPMA RAM)
  77         */
  78        0x0FEA8C34, 0x1FB54C34, 0xFFFFCC34, _NOT_USED_
  79};
  80
  81/* ------------------------------------------------------------------------- */
  82
  83
  84/*
  85 * Check Board Identity:
  86 */
  87
  88int checkboard (void)
  89{
  90        char *s = getenv ("serial#");
  91
  92        puts ("Board QUANTUM, Serial No: ");
  93
  94        for (; s && *s; ++s) {
  95                if (*s == ' ')
  96                        break;
  97                putc (*s);
  98        }
  99        putc ('\n');
 100        return (0);             /* success */
 101}
 102
 103/* ------------------------------------------------------------------------- */
 104
 105phys_size_t initdram (int board_type)
 106{
 107        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 108        volatile memctl8xx_t *memctl = &immap->im_memctl;
 109        long int size9;
 110
 111        upmconfig (UPMA, (uint *) sdram_table,
 112                   sizeof (sdram_table) / sizeof (uint));
 113
 114        /* Refresh clock prescalar */
 115        memctl->memc_mptpr = CONFIG_SYS_MPTPR;
 116
 117        memctl->memc_mar = 0x00000088;
 118
 119        /* Map controller banks 1 to the SDRAM bank */
 120        memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM;
 121        memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM;
 122
 123        memctl->memc_mamr = CONFIG_SYS_MAMR_9COL & (~(MAMR_PTAE));      /* no refresh yet */
 124
 125        udelay (200);
 126
 127        /* perform SDRAM initializsation sequence */
 128
 129        memctl->memc_mcr = 0x80002136;  /* SDRAM bank 0 */
 130        udelay (1);
 131
 132        memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
 133
 134        udelay (1000);
 135
 136        /* Check Bank 0 Memory Size,
 137         * 9 column mode
 138         */
 139        size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE_PRELIM,
 140                           SDRAM_MAX_SIZE);
 141        /*
 142         * Final mapping:
 143         */
 144        memctl->memc_or1 = ((-size9) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 145        udelay (1000);
 146
 147        return (size9);
 148}
 149
 150/* ------------------------------------------------------------------------- */
 151
 152/*
 153 * Check memory range for valid RAM. A simple memory test determines
 154 * the actually available RAM size between addresses `base' and
 155 * `base + maxsize'. Some (not all) hardware errors are detected:
 156 * - short between address lines
 157 * - short between data lines
 158 */
 159
 160static long int dram_size (long int mamr_value, long int *base,
 161                           long int maxsize)
 162{
 163        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 164        volatile memctl8xx_t *memctl = &immap->im_memctl;
 165        volatile ulong *addr;
 166        ulong cnt, val, size;
 167        ulong save[32];         /* to make test non-destructive */
 168        unsigned char i = 0;
 169
 170        memctl->memc_mamr = mamr_value;
 171
 172        for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
 173                addr = (volatile ulong *)(base + cnt);  /* pointer arith! */
 174
 175                save[i++] = *addr;
 176                *addr = ~cnt;
 177        }
 178
 179        /* write 0 to base address */
 180        addr = (volatile ulong *)base;
 181        save[i] = *addr;
 182        *addr = 0;
 183
 184        /* check at base address */
 185        if ((val = *addr) != 0) {
 186                /* Restore the original data before leaving the function.
 187                 */
 188                *addr = save[i];
 189                for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
 190                        addr = (volatile ulong *) base + cnt;
 191                        *addr = save[--i];
 192                }
 193                return (0);
 194        }
 195
 196        for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
 197                addr = (volatile ulong *)(base + cnt);  /* pointer arith! */
 198
 199                val = *addr;
 200                *addr = save[--i];
 201
 202                if (val != (~cnt)) {
 203                        size = cnt * sizeof (long);
 204                        /* Restore the original data before returning
 205                         */
 206                        for (cnt <<= 1; cnt <= maxsize / sizeof (long);
 207                             cnt <<= 1) {
 208                                addr = (volatile ulong *) base + cnt;
 209                                *addr = save[--i];
 210                        }
 211                        return (size);
 212                }
 213        }
 214        return (maxsize);
 215}
 216
 217/*
 218 * Miscellaneous intialization
 219 */
 220int misc_init_r (void)
 221{
 222        char *fpga_data_str = getenv ("fpgadata");
 223        char *fpga_size_str = getenv ("fpgasize");
 224        void *fpga_data;
 225        int fpga_size;
 226        int status;
 227        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 228        volatile memctl8xx_t *memctl = &immap->im_memctl;
 229        int flash_size;
 230
 231        /* Remap FLASH according to real size */
 232        flash_size = flash_init ();
 233        memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-flash_size & 0xFFFF8000);
 234        memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
 235
 236        if (fpga_data_str && fpga_size_str) {
 237                fpga_data = (void *) simple_strtoul (fpga_data_str, NULL, 16);
 238                fpga_size = simple_strtoul (fpga_size_str, NULL, 10);
 239
 240                status = fpga_boot (fpga_data, fpga_size);
 241                if (status != 0) {
 242                        printf ("\nFPGA: Booting failed ");
 243                        switch (status) {
 244                        case ERROR_FPGA_PRG_INIT_LOW:
 245                                printf ("(Timeout: INIT not low after asserting PROGRAM*)\n ");
 246                                break;
 247                        case ERROR_FPGA_PRG_INIT_HIGH:
 248                                printf ("(Timeout: INIT not high after deasserting PROGRAM*)\n ");
 249                                break;
 250                        case ERROR_FPGA_PRG_DONE:
 251                                printf ("(Timeout: DONE not high after programming FPGA)\n ");
 252                                break;
 253                        }
 254                }
 255        }
 256        return 0;
 257}
 258