uboot/board/ip860/ip860.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#include <common.h>
  25#include <commproc.h>
  26#include <mpc8xx.h>
  27
  28/* ------------------------------------------------------------------------- */
  29
  30static long int dram_size (long int, long int *, long int);
  31unsigned long ip860_get_dram_size(void);
  32unsigned long ip860_get_clk_freq (void);
  33/* ------------------------------------------------------------------------- */
  34
  35#define _NOT_USED_      0xFFFFFFFF
  36
  37const uint sdram_table[] = {
  38        /*
  39         * Single Read. (Offset 0 in UPMA RAM)
  40         */
  41        0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
  42        0x1ff77c47,                                     /* last */
  43        /*
  44         * SDRAM Initialization (offset 5 in UPMA RAM)
  45         *
  46         * This is no UPM entry point. The following definition uses
  47         * the remaining space to establish an initialization
  48         * sequence, which is executed by a RUN command.
  49         *
  50         */
  51        0x1ff77c34, 0xefeabc34, 0x1fb57c35,     /* last */
  52        /*
  53         * Burst Read. (Offset 8 in UPMA RAM)
  54         */
  55        0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
  56        0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
  57        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  58        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  59        /*
  60         * Single Write. (Offset 18 in UPMA RAM)
  61         */
  62        0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
  63        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  64        /*
  65         * Burst Write. (Offset 20 in UPMA RAM)
  66         */
  67        0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
  68        0xf0affc00, 0xe1bbbc04, 0x1ff77c47,     /* last */
  69        _NOT_USED_,
  70        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  71        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  72        /*
  73         * Refresh  (Offset 30 in UPMA RAM)
  74         */
  75        0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
  76        0xfffffc84, 0xfffffc07,         /* last */
  77        _NOT_USED_, _NOT_USED_,
  78        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  79        /*
  80         * Exception. (Offset 3c in UPMA RAM)
  81         */
  82        0x7ffffc07,                                     /* last */
  83        _NOT_USED_, _NOT_USED_, _NOT_USED_,
  84};
  85
  86
  87/* ------------------------------------------------------------------------- */
  88int board_early_init_f(void)
  89{
  90    volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR;
  91    volatile memctl8xx_t *memctl = &immap->im_memctl;
  92
  93/* init BCSR chipselect line for ip860_get_clk_freq() and ip860_get_dram_size() */
  94    memctl->memc_or4 = CONFIG_SYS_OR4;
  95    memctl->memc_br4 = CONFIG_SYS_BR4;
  96
  97    return 0;
  98}
  99
 100
 101/* ------------------------------------------------------------------------- */
 102
 103/*
 104 * Check Board Identity:
 105 *
 106 * Test ID string (IP860...)
 107 */
 108
 109int checkboard (void)
 110{
 111        unsigned char *s, *e;
 112        unsigned char buf[64];
 113        int i;
 114
 115        puts ("Board: ");
 116
 117        i = getenv_f("serial#", (char *)buf, sizeof (buf));
 118        s = (i > 0) ? buf : NULL;
 119
 120        if (!s || strncmp ((char *)s, "IP860", 5)) {
 121                puts ("### No HW ID - assuming IP860");
 122        } else {
 123                for (e = s; *e; ++e) {
 124                        if (*e == ' ')
 125                                break;
 126                }
 127
 128                for (; s < e; ++s) {
 129                        putc (*s);
 130                }
 131        }
 132
 133        putc ('\n');
 134
 135        return (0);
 136}
 137
 138/* ------------------------------------------------------------------------- */
 139
 140phys_size_t initdram (int board_type)
 141{
 142        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 143        volatile memctl8xx_t *memctl = &immap->im_memctl;
 144        long int size;
 145        ulong refresh_val;
 146
 147        upmconfig (UPMA, (uint *) sdram_table,
 148                           sizeof (sdram_table) / sizeof (uint));
 149
 150        /*
 151         * Preliminary prescaler for refresh
 152         */
 153        if (ip860_get_clk_freq() == 50000000)
 154        {
 155                memctl->memc_mptpr = 0x0400;
 156                refresh_val = 0xC3000000;
 157        }
 158        else
 159        {
 160                memctl->memc_mptpr = 0x0200;
 161                refresh_val = 0x9C000000;
 162        }
 163
 164
 165        memctl->memc_mar = 0x00000088;
 166
 167        /*
 168         * Map controller banks 2 to the SDRAM address
 169         */
 170        memctl->memc_or2 = CONFIG_SYS_OR2;
 171        memctl->memc_br2 = CONFIG_SYS_BR2;
 172
 173        /* IP860 boards have only one bank SDRAM */
 174
 175
 176        udelay (200);
 177
 178        /* perform SDRAM initializsation sequence */
 179
 180        memctl->memc_mamr = 0x00804114 | refresh_val;
 181        memctl->memc_mcr  = 0x80004105; /* run precharge pattern from loc 5 */
 182        udelay(1);
 183        memctl->memc_mamr = 0x00804118 | refresh_val;
 184        memctl->memc_mcr  = 0x80004130; /* run refresh pattern 8 times */
 185
 186
 187        udelay (1000);
 188
 189        /*
 190         * Check SDRAM Memory Size
 191         */
 192        if (ip860_get_dram_size() == 16)
 193                size = dram_size (refresh_val | 0x00804114, SDRAM_BASE, SDRAM_MAX_SIZE);
 194        else
 195                size = dram_size (refresh_val | 0x00906114, SDRAM_BASE, SDRAM_MAX_SIZE);
 196
 197        udelay (1000);
 198
 199        memctl->memc_or2 = ((-size) & 0xFFFF0000) | SDRAM_TIMING;
 200        memctl->memc_br2 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 201
 202        udelay (10000);
 203
 204        /*
 205         * Also, map other memory to correct position
 206         */
 207
 208#if (defined(CONFIG_SYS_OR1) && defined(CONFIG_SYS_BR1_PRELIM))
 209        memctl->memc_or1 = CONFIG_SYS_OR1;
 210        memctl->memc_br1 = CONFIG_SYS_BR1;
 211#endif
 212
 213#if defined(CONFIG_SYS_OR3) && defined(CONFIG_SYS_BR3)
 214        memctl->memc_or3 = CONFIG_SYS_OR3;
 215        memctl->memc_br3 = CONFIG_SYS_BR3;
 216#endif
 217
 218#if defined(CONFIG_SYS_OR4) && defined(CONFIG_SYS_BR4)
 219        memctl->memc_or4 = CONFIG_SYS_OR4;
 220        memctl->memc_br4 = CONFIG_SYS_BR4;
 221#endif
 222
 223#if defined(CONFIG_SYS_OR5) && defined(CONFIG_SYS_BR5)
 224        memctl->memc_or5 = CONFIG_SYS_OR5;
 225        memctl->memc_br5 = CONFIG_SYS_BR5;
 226#endif
 227
 228#if defined(CONFIG_SYS_OR6) && defined(CONFIG_SYS_BR6)
 229        memctl->memc_or6 = CONFIG_SYS_OR6;
 230        memctl->memc_br6 = CONFIG_SYS_BR6;
 231#endif
 232
 233#if defined(CONFIG_SYS_OR7) && defined(CONFIG_SYS_BR7)
 234        memctl->memc_or7 = CONFIG_SYS_OR7;
 235        memctl->memc_br7 = CONFIG_SYS_BR7;
 236#endif
 237
 238        return (size);
 239}
 240
 241/* ------------------------------------------------------------------------- */
 242
 243/*
 244 * Check memory range for valid RAM. A simple memory test determines
 245 * the actually available RAM size between addresses `base' and
 246 * `base + maxsize'. Some (not all) hardware errors are detected:
 247 * - short between address lines
 248 * - short between data lines
 249 */
 250
 251static long int dram_size (long int mamr_value, long int *base,
 252                                                   long int maxsize)
 253{
 254        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 255        volatile memctl8xx_t *memctl = &immap->im_memctl;
 256
 257        memctl->memc_mamr = mamr_value;
 258
 259        return (get_ram_size(base, maxsize));
 260}
 261
 262/* ------------------------------------------------------------------------- */
 263
 264void reset_phy (void)
 265{
 266        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 267        ulong mask = PB_ENET_RESET | PB_ENET_JABD;
 268        ulong reg;
 269
 270        /* Make sure PHY is not in low-power mode */
 271        immr->im_cpm.cp_pbpar &= ~(mask);       /* GPIO */
 272        immr->im_cpm.cp_pbodr &= ~(mask);       /* active output */
 273
 274        /* Set  JABD low  (no JABber Disable),
 275         * and RESET high (Reset PHY)
 276         */
 277        reg = immr->im_cpm.cp_pbdat;
 278        reg = (reg & ~PB_ENET_JABD) | PB_ENET_RESET;
 279        immr->im_cpm.cp_pbdat = reg;
 280
 281        /* now drive outputs */
 282        immr->im_cpm.cp_pbdir |= mask;  /* output */
 283        udelay (1000);
 284        /*
 285           * Release RESET signal
 286         */
 287        immr->im_cpm.cp_pbdat &= ~(PB_ENET_RESET);
 288        udelay (1000);
 289}
 290
 291/* ------------------------------------------------------------------------- */
 292
 293unsigned long ip860_get_clk_freq(void)
 294{
 295        volatile ip860_bcsr_t   *bcsr   = (ip860_bcsr_t *)BCSR_BASE;
 296        ulong temp;
 297        uchar sysclk;
 298
 299        if ((bcsr->bd_status & 0x80) == 0x80)   /* bd_rev valid ? */
 300                sysclk = (bcsr->bd_rev & 0x18) >> 3;
 301        else
 302                sysclk = 0x00;
 303
 304        switch (sysclk)
 305        {
 306                case 0x00:
 307                        temp = 50000000;
 308                        break;
 309
 310                case 0x01:
 311                        temp = 80000000;
 312                        break;
 313
 314                default:
 315                        temp = 50000000;
 316                        break;
 317        }
 318
 319        return (temp);
 320
 321}
 322
 323
 324/* ------------------------------------------------------------------------- */
 325
 326unsigned long ip860_get_dram_size(void)
 327{
 328        volatile ip860_bcsr_t   *bcsr   = (ip860_bcsr_t *)BCSR_BASE;
 329        ulong temp;
 330        uchar dram_size;
 331
 332        if ((bcsr->bd_status & 0x80) == 0x80)   /* bd_rev valid ? */
 333                dram_size = (bcsr->bd_rev & 0xE0) >> 5;
 334        else
 335                dram_size = 0x00;       /* default is 16 MB */
 336
 337        switch (dram_size)
 338        {
 339                case 0x00:
 340                        temp = 16;
 341                        break;
 342
 343                case 0x01:
 344                        temp = 32;
 345                        break;
 346
 347                default:
 348                        temp = 16;
 349                        break;
 350        }
 351
 352        return (temp);
 353
 354}
 355
 356/* ------------------------------------------------------------------------- */
 357