uboot/board/etx094/etx094.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 <mpc8xx.h>
  26
  27DECLARE_GLOBAL_DATA_PTR;
  28
  29/* ------------------------------------------------------------------------- */
  30
  31static long int dram_size (long int, long int *, long int);
  32static void read_hw_vers (void);
  33
  34/* ------------------------------------------------------------------------- */
  35
  36#define _NOT_USED_      0xFFFFFFFF
  37
  38const uint sdram_table[] = {
  39
  40        /* single read   (offset 0x00 in upm ram) */
  41
  42        0xEECEFC24, 0x100DFC24, 0xE02FBC04, 0x01AA7C04,
  43        0x1FB5FC00, 0xFFFFFC05, _NOT_USED_, _NOT_USED_,
  44
  45        /* burst read    (offset 0x08 in upm ram) */
  46
  47        0xEECEFC24, 0x100DFC24, 0xE0FFBC04, 0x10FF7C04,
  48        0xF0FFFC00, 0xF0FFFC00, 0xF0FFFC00, 0xFFFFFC00,
  49        0xFFFFFC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  50        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  51
  52        /* single write  (offset 0x18 in upm ram) */
  53
  54        0xEECEFC24, 0x100DFC24, 0xE02BBC04, 0x01A27C00,
  55        0xEFAAFC04, 0x1FB5FC05, _NOT_USED_, _NOT_USED_,
  56
  57        /* burst write   (offset 0x20 in upm ram) */
  58
  59        0xEECEFC24, 0x103DFC24, 0xE0FBBC00, 0x10F77C00,
  60        0xF0FFFC00, 0xF0FFFC00, 0xF0FFFC04, 0xFFFFFC05,
  61
  62        /* init part1      (offset 0x28 in upm ram) */
  63
  64        0xEFFAFC3C, 0x1FF4FC34, 0xEFFCBC34, 0x1FFC3C34,
  65        0xFFFC3C35, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  66
  67        /* refresh   (offset 0x30 in upm ram) */
  68
  69        0xEFFEBC0C, 0x1FFD7C04, 0xFFFFFC04, 0xFFFFFC05,
  70
  71        /* init part2     (offset 0x34 in upm ram) */
  72
  73        0xFFFEBC04, 0xEFFC3CB4, 0x1FFC3C34, 0xFFFC3C34,
  74        0xFFFC3C34, 0xEFE83CB4, 0x1FB57C35, _NOT_USED_,
  75
  76        /* exception     (offset 0x3C in upm ram) */
  77
  78        0xFFFFFC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
  79
  80};
  81
  82/* ------------------------------------------------------------------------- */
  83
  84
  85/*
  86 * Check Board Identity:
  87 *
  88 * Test ETX ID string (ETX_xxx...)
  89 *
  90 * Return 1 always.
  91 */
  92
  93int checkboard (void)
  94{
  95        char *s = getenv ("serial#");
  96        char *e;
  97
  98        puts ("Board: ");
  99
 100#ifdef SB_ETX094
 101        gd->board_type = 0; /* 0 = 2SDRAM-Device */
 102#else
 103        gd->board_type = 1; /* 1 = 1SDRAM-Device */
 104#endif
 105
 106        if (!s || strncmp (s, "ETX_", 4)) {
 107                puts ("### No HW ID - assuming ETX_094\n");
 108                read_hw_vers ();
 109                return (0);
 110        }
 111
 112        for (e = s; *e; ++e) {
 113                if (*e == ' ')
 114                        break;
 115        }
 116
 117        for (; s < e; ++s) {
 118                putc (*s);
 119        }
 120        putc ('\n');
 121
 122        read_hw_vers ();
 123        return (0);
 124}
 125
 126/* ------------------------------------------------------------------------- */
 127
 128phys_size_t initdram (int board_type)
 129{
 130        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 131        volatile memctl8xx_t *memctl = &immap->im_memctl;
 132        long int size_b0, size_b1, size8, size9;
 133
 134        upmconfig (UPMA, (uint *) sdram_table,
 135                           sizeof (sdram_table) / sizeof (uint));
 136
 137        /*
 138         * Preliminary prescaler for refresh (depends on number of
 139         * banks): This value is selected for four cycles every 62.4 us
 140         * with two SDRAM banks or four cycles every 31.2 us with one
 141         * bank. It will be adjusted after memory sizing.
 142         */
 143        memctl->memc_mptpr = CONFIG_SYS_MPTPR_1BK_4K;   /* MPTPR_PTP_DIV32 0x0200 */
 144
 145        /* A3(SDRAM)=0      => Bursttype = Sequential
 146         * A2-A0(SDRAM)=010 => Burst length = 4
 147         * A4-A6(SDRAM)=010 => CasLat=2
 148         */
 149        memctl->memc_mar = 0x00000088;
 150
 151        /*
 152         * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
 153         * preliminary addresses - these have to be modified after the
 154         * SDRAM size has been determined.
 155         */
 156        memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
 157        memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;
 158
 159        if (board_type == 0) {  /* "L" type boards have only one bank SDRAM */
 160                memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM;
 161                memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM;
 162        }
 163
 164        memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE));      /* no refresh yet */
 165
 166        udelay (200);
 167
 168        /* perform SDRAM initializsation sequence */
 169
 170        memctl->memc_mcr = 0x80004128;  /* SDRAM bank 0 (CS2) - Init Part 1 */
 171        memctl->memc_mcr = 0x80004734;  /* SDRAM bank 0 (CS2) - Init Part 2 */
 172        udelay (1);
 173
 174        if (board_type == 0) {          /* "L" type boards have only one bank SDRAM */
 175                memctl->memc_mcr = 0x80006128;  /* SDRAM bank 1 (CS3) - Init Part 1 */
 176                memctl->memc_mcr = 0x80006734;  /* SDRAM bank 1 (CS3) - Init Part 2 */
 177                udelay (1);
 178        }
 179
 180        memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
 181
 182        udelay (1000);
 183
 184        /*
 185         * Check Bank 0 Memory Size for re-configuration
 186         *
 187         * try 8 column mode
 188         */
 189        size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE2_PRELIM,
 190                                           SDRAM_MAX_SIZE);
 191
 192        udelay (1000);
 193
 194        /*
 195         * try 9 column mode
 196         */
 197        size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE2_PRELIM,
 198                                           SDRAM_MAX_SIZE);
 199
 200        if (size8 < size9) {            /* leave configuration at 9 columns */
 201                size_b0 = size9;
 202/*      debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);  */
 203        } else {                                        /* back to 8 columns            */
 204                size_b0 = size8;
 205                memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
 206                udelay (500);
 207/*      debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);  */
 208        }
 209
 210        if (board_type == 0) {          /* "L" type boards have only one bank SDRAM */
 211                /*
 212                 * Check Bank 1 Memory Size
 213                 * use current column settings
 214                 * [9 column SDRAM may also be used in 8 column mode,
 215                 *  but then only half the real size will be used.]
 216                 */
 217                size_b1 =
 218                                dram_size (memctl->memc_mamr, (long *) SDRAM_BASE3_PRELIM,
 219                                                   SDRAM_MAX_SIZE);
 220/*      debug ("SDRAM Bank 1: %ld MB\n", size8 >> 20);  */
 221        } else {
 222                size_b1 = 0;
 223        }
 224
 225        udelay (1000);
 226
 227        /*
 228         * Adjust refresh rate depending on SDRAM type, both banks
 229         * For types > 128 MBit leave it at the current (fast) rate
 230         */
 231        if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) {
 232                /* reduce to 15.6 us (62.4 us / quad) */
 233                memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;   /*DIV16 */
 234                udelay (1000);
 235        }
 236
 237        /*
 238         * Final mapping: map bigger bank first
 239         */
 240        if (size_b1 > size_b0) {        /* SDRAM Bank 1 is bigger - map first   */
 241
 242                memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 243                memctl->memc_br3 =
 244                        (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 245
 246                if (size_b0 > 0) {
 247                        /*
 248                         * Position Bank 0 immediately above Bank 1
 249                         */
 250                        memctl->memc_or2 =
 251                                ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 252                        memctl->memc_br2 =
 253                                ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
 254                                + size_b1;
 255                } else {
 256                        unsigned long reg;
 257
 258                        /*
 259                         * No bank 0
 260                         *
 261                         * invalidate bank
 262                         */
 263                        memctl->memc_br2 = 0;
 264
 265                        /* adjust refresh rate depending on SDRAM type, one bank */
 266                        reg = memctl->memc_mptpr;
 267                        reg >>= 1;      /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
 268                        memctl->memc_mptpr = reg;
 269                }
 270
 271        } else {                        /* SDRAM Bank 0 is bigger - map first   */
 272
 273                memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 274                memctl->memc_br2 =
 275                                (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 276
 277                if (size_b1 > 0) {
 278                        /*
 279                         * Position Bank 1 immediately above Bank 0
 280                         */
 281                        memctl->memc_or3 =
 282                                        ((-size_b1) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 283                        memctl->memc_br3 =
 284                                        ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
 285                                        + size_b0;
 286                } else {
 287                        unsigned long reg;
 288
 289                        /*
 290                         * No bank 1
 291                         *
 292                         * invalidate bank
 293                         */
 294                        memctl->memc_br3 = 0;
 295
 296                        /* adjust refresh rate depending on SDRAM type, one bank */
 297                        reg = memctl->memc_mptpr;
 298                        reg >>= 1;      /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
 299                        memctl->memc_mptpr = reg;
 300                }
 301        }
 302
 303        udelay (10000);
 304
 305        return (size_b0 + size_b1);
 306}
 307
 308/* ------------------------------------------------------------------------- */
 309
 310/*
 311 * Check memory range for valid RAM. A simple memory test determines
 312 * the actually available RAM size between addresses `base' and
 313 * `base + maxsize'. Some (not all) hardware errors are detected:
 314 * - short between address lines
 315 * - short between data lines
 316 */
 317
 318static long int dram_size (long int mamr_value, long int *base,
 319                                                   long int maxsize)
 320{
 321        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 322        volatile memctl8xx_t *memctl = &immap->im_memctl;
 323
 324        memctl->memc_mamr = mamr_value;
 325
 326        return (get_ram_size(base, maxsize));
 327}
 328
 329/* ------------------------------------------------------------------------- */
 330
 331/* HW-ID Table (Bits: 2^9;2^7;2^5) */
 332#define HW_ID_0 0x0000
 333#define HW_ID_1 0x0020
 334#define HW_ID_2 0x0080
 335#define HW_ID_3 0x00a0
 336#define HW_ID_4 0x0200
 337#define HW_ID_5 0x0220
 338#define HW_ID_6 0x0280
 339#define HW_ID_7 0x02a0
 340
 341void read_hw_vers ()
 342{
 343        unsigned short rd_msk = 0x02A0;
 344
 345        /* HW-ID pin-definition */
 346        volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
 347
 348        immr->im_ioport.iop_pddir &= ~(rd_msk);
 349        immr->im_ioport.iop_pdpar &= ~(rd_msk);
 350
 351        /* debug printf("State of PD: %x\n",immr->im_ioport.iop_pddat); */
 352
 353        /* Check the HW-ID */
 354        printf ("HW-Version: ");
 355        switch (immr->im_ioport.iop_pddat & rd_msk) {
 356        case HW_ID_0:
 357                printf ("V0.1 - V0.3 / W97238-Q3162-A1-1-2\n");
 358                break;
 359        case HW_ID_1:
 360                printf ("V0.9 / W50037-Q1-D6-1\n");
 361                break;
 362        case HW_ID_2:
 363                printf ("NOT USED - assuming ID#2\n");
 364                break;
 365        case HW_ID_3:
 366                printf ("NOT USED - assuming ID#3\n");
 367                break;
 368        case HW_ID_4:
 369                printf ("NOT USED - assuming ID#4\n");
 370                break;
 371        case HW_ID_5:
 372                printf ("NOT USED - assuming ID#5\n");
 373                break;
 374        case HW_ID_6:
 375                printf ("NOT USED - assuming ID#6\n");
 376                break;
 377        case HW_ID_7:
 378                printf ("NOT USED - assuming ID#7\n");
 379                break;
 380        default:
 381                printf ("###Error###\n");
 382                break;
 383        }
 384}
 385
 386/* ------------------------------------------------------------------------- */
 387