uboot/board/tqc/tqm85xx/sdram.c
<<
>>
Prefs
   1
   2/*
   3 * (C) Copyright 2005
   4 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   5 *
   6 * See file CREDITS for list of people who contributed to this
   7 * project.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation; either version 2 of
  12 * the License, or (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22 * MA 02111-1307 USA
  23 */
  24
  25#include <common.h>
  26#include <asm/processor.h>
  27#include <asm/immap_85xx.h>
  28#include <asm/processor.h>
  29#include <asm/mmu.h>
  30
  31struct sdram_conf_s {
  32        unsigned long size;
  33        unsigned long reg;
  34#ifdef CONFIG_TQM8548
  35        unsigned long refresh;
  36#endif /* CONFIG_TQM8548 */
  37};
  38
  39typedef struct sdram_conf_s sdram_conf_t;
  40
  41#ifdef CONFIG_TQM8548
  42#ifdef CONFIG_TQM8548_AG
  43sdram_conf_t ddr_cs_conf[] = {
  44        {(1024 << 20), 0x80044202, 0x0002D000}, /* 1024MB, 14x10(4)     */
  45        { (512 << 20), 0x80044102, 0x0001A000}, /*  512MB, 13x10(4)     */
  46        { (256 << 20), 0x80040102, 0x00014000}, /*  256MB, 13x10(4)     */
  47        { (128 << 20), 0x80040101, 0x0000C000}, /*  128MB, 13x9(4)      */
  48};
  49#else /* !CONFIG_TQM8548_AG */
  50sdram_conf_t ddr_cs_conf[] = {
  51        {(512 << 20), 0x80044102, 0x0001A000},  /* 512MB, 13x10(4)      */
  52        {(256 << 20), 0x80040102, 0x00014000},  /* 256MB, 13x10(4)      */
  53        {(128 << 20), 0x80040101, 0x0000C000},  /* 128MB, 13x9(4)       */
  54};
  55#endif /* CONFIG_TQM8548_AG */
  56#else /* !CONFIG_TQM8548 */
  57sdram_conf_t ddr_cs_conf[] = {
  58        {(512 << 20), 0x80000202},      /* 512MB, 14x10(4)      */
  59        {(256 << 20), 0x80000102},      /* 256MB, 13x10(4)      */
  60        {(128 << 20), 0x80000101},      /* 128MB, 13x9(4)       */
  61        {( 64 << 20), 0x80000001},      /*  64MB, 12x9(4)       */
  62};
  63#endif /* CONFIG_TQM8548 */
  64
  65#define N_DDR_CS_CONF (sizeof(ddr_cs_conf) / sizeof(ddr_cs_conf[0]))
  66
  67int cas_latency (void);
  68
  69/*
  70 * Autodetect onboard DDR SDRAM on 85xx platforms
  71 *
  72 * NOTE: Some of the hardcoded values are hardware dependant,
  73 *       so this should be extended for other future boards
  74 *       using this routine!
  75 */
  76long int sdram_setup (int casl)
  77{
  78        int i;
  79        volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
  80#ifdef CONFIG_TQM8548
  81        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  82#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
  83        volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
  84#endif
  85#else /* !CONFIG_TQM8548 */
  86        unsigned long cfg_ddr_timing1;
  87        unsigned long cfg_ddr_mode;
  88#endif /* CONFIG_TQM8548 */
  89
  90        /*
  91         * Disable memory controller.
  92         */
  93        ddr->cs0_config = 0;
  94        ddr->sdram_cfg = 0;
  95
  96#ifdef CONFIG_TQM8548
  97        /* Timing and refresh settings for DDR2-533 and below */
  98
  99        ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
 100        ddr->cs0_config = ddr_cs_conf[0].reg;
 101        ddr->timing_cfg_3 = 0x00020000;
 102
 103        /* TIMING CFG 1, 533MHz
 104         * PRETOACT: 4 Clocks
 105         * ACTTOPRE: 12 Clocks
 106         * ACTTORW:  4 Clocks
 107         * CASLAT:   4 Clocks
 108         * REFREC:   EXT_REFREC:REFREC 53 Clocks
 109         * WRREC:    4 Clocks
 110         * ACTTOACT: 3 Clocks
 111         * WRTORD:   2 Clocks
 112         */
 113        ddr->timing_cfg_1 = 0x4C47D432;
 114
 115        /* TIMING CFG 2, 533MHz
 116         * ADD_LAT:       3 Clocks
 117         * CPO:           READLAT + 1
 118         * WR_LAT:        3 Clocks
 119         * RD_TO_PRE:     2 Clocks
 120         * WR_DATA_DELAY: 1/2 Clock
 121         * CKE_PLS:       3 Clock
 122         * FOUR_ACT:      14 Clocks
 123         */
 124        ddr->timing_cfg_2 = 0x331848CE;
 125
 126        /* DDR SDRAM Mode, 533MHz
 127         * MRS:          Extended Mode Register
 128         * OUT:          Outputs enabled
 129         * RDQS:         no
 130         * DQS:          enabled
 131         * OCD:          default state
 132         * RTT:          75 Ohms
 133         * Posted CAS:   3 Clocks
 134         * ODS:          reduced strength
 135         * DLL:          enabled
 136         * MR:           Mode Register
 137         * PD:           fast exit
 138         * WR:           4 Clocks
 139         * DLL:          no DLL reset
 140         * TM:           normal
 141         * CAS latency:  4 Clocks
 142         * BT:           sequential
 143         * Burst length: 4
 144         */
 145        ddr->sdram_mode = 0x439E0642;
 146
 147        /* DDR SDRAM Interval, 533MHz
 148         * REFINT:  1040 Clocks
 149         * BSTOPRE: 256
 150         */
 151        ddr->sdram_interval = (1040 << 16) | 0x100;
 152
 153        /*
 154         * Workaround for erratum DDR19 according to MPC8548 Device Errata
 155         * document, Rev. 1: DDR IO receiver must be set to an acceptable
 156         * bias point by modifying a hidden register.
 157         */
 158        if (SVR_REV (get_svr ()) < 0x21)
 159                gur->ddrioovcr = 0x90000000;    /* enable, VSEL 1.8V */
 160
 161        /* DDR SDRAM CFG 2
 162         * FRC_SR:      normal mode
 163         * SR_IE:       no self-refresh interrupt
 164         * DLL_RST_DIS: don't care, leave at reset value
 165         * DQS_CFG:     differential DQS signals
 166         * ODT_CFG:     assert ODT to internal IOs only during reads to DRAM
 167         * LVWx_CFG:    don't care, leave at reset value
 168         * NUM_PR:      1 refresh will be issued at a time
 169         * DM_CFG:      don't care, leave at reset value
 170         * D_INIT:      no data initialization
 171         */
 172        ddr->sdram_cfg_2 = 0x04401000;
 173
 174        /* DDR SDRAM MODE 2
 175         * MRS: Extended Mode Register 2
 176         */
 177        ddr->sdram_mode_2 = 0x8000C000;
 178
 179        /* DDR SDRAM CLK CNTL
 180         * CLK_ADJUST: 1/2 Clock 0x02000000
 181         * CLK_ADJUST: 5/8 Clock 0x02800000
 182         */
 183        ddr->sdram_clk_cntl = 0x02800000;
 184
 185        /* wait for clock stabilization */
 186        asm ("sync;isync;msync");
 187        udelay (1000);
 188
 189#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
 190        /*
 191         * Workaround for erratum DDR20 according to MPC8548 Device Errata
 192         * document, Rev. 1: "CKE signal may not function correctly after
 193         * assertion of HRESET"
 194         */
 195
 196        /* 1. Configure DDR register as is done in normal DDR configuration.
 197         *    Do not set DDR_SDRAM_CFG[MEM_EN].
 198         *
 199         * 2. Set reserved bit EEBACR[3] at offset 0x1000
 200         */
 201        ecm->eebacr |= 0x10000000;
 202
 203        /*
 204         * 3. Before DDR_SDRAM_CFG[MEM_EN] is set, write DDR_SDRAM_CFG_2[D_INIT]
 205         *
 206         * DDR_SDRAM_CFG_2:
 207         * FRC_SR:      normal mode
 208         * SR_IE:       no self-refresh interrupt
 209         * DLL_RST_DIS: don't care, leave at reset value
 210         * DQS_CFG:     differential DQS signals
 211         * ODT_CFG:     assert ODT to internal IOs only during reads to DRAM
 212         * LVWx_CFG:    don't care, leave at reset value
 213         * NUM_PR:      1 refresh will be issued at a time
 214         * DM_CFG:      don't care, leave at reset value
 215         * D_INIT:      enable data initialization
 216         */
 217        ddr->sdram_cfg_2 |= 0x00000010;
 218
 219        /*
 220         * 4. Before DDR_SDRAM_CFG[MEM_EN] set, write D3[21] to disable data
 221         *    training
 222         */
 223        ddr->debug_3 |= 0x00000400;
 224
 225        /*
 226         * 5. Wait 200 micro-seconds
 227         */
 228        udelay (200);
 229
 230        /*
 231         * 6. Set DDR_SDRAM_CFG[MEM_EN]
 232         *
 233         * BTW, initialize DDR_SDRAM_CFG:
 234         * MEM_EN:       enabled
 235         * SREN:         don't care, leave at reset value
 236         * ECC_EN:       no error report
 237         * RD_EN:        no registered DIMMs
 238         * SDRAM_TYPE:   DDR2
 239         * DYN_PWR:      no power management
 240         * 32_BE:        don't care, leave at reset value
 241         * 8_BE:         4 beat burst
 242         * NCAP:         don't care, leave at reset value
 243         * 2T_EN:        1T Timing
 244         * BA_INTLV_CTL: no interleaving
 245         * x32_EN:       x16 organization
 246         * PCHB8:        MA[10] for auto-precharge
 247         * HSE:          half strength for single and 2-layer stacks
 248         *               (full strength for 3- and 4-layer stacks not
 249         *               yet considered)
 250         * MEM_HALT:     no halt
 251         * BI:           automatic initialization
 252         */
 253        ddr->sdram_cfg = 0x83000008;
 254
 255        /*
 256         * 7. Poll DDR_SDRAM_CFG_2[D_INIT] until it is cleared by hardware
 257         */
 258        asm ("sync;isync;msync");
 259        while (ddr->sdram_cfg_2 & 0x00000010)
 260                asm ("eieio");
 261
 262        /*
 263         * 8. Clear D3[21] to re-enable data training
 264         */
 265        ddr->debug_3 &= ~0x00000400;
 266
 267        /*
 268         * 9. Set D2(21) to force data training to run
 269         */
 270        ddr->debug_2 |= 0x00000400;
 271
 272        /*
 273         * 10. Poll on D2[21] until it is cleared by hardware
 274         */
 275        asm ("sync;isync;msync");
 276        while (ddr->debug_2 & 0x00000400)
 277                asm ("eieio");
 278
 279        /*
 280         * 11. Clear reserved bit EEBACR[3] at offset 0x1000
 281         */
 282        ecm->eebacr &= ~0x10000000;
 283
 284#else /* !(CONFIG_TQM8548_AG || CONFIG_TQM8548_BE) */
 285
 286        /* DDR SDRAM CLK CNTL
 287         * MEM_EN:       enabled
 288         * SREN:         don't care, leave at reset value
 289         * ECC_EN:       no error report
 290         * RD_EN:        no register DIMMs
 291         * SDRAM_TYPE:   DDR2
 292         * DYN_PWR:      no power management
 293         * 32_BE:        don't care, leave at reset value
 294         * 8_BE:         4 beat burst
 295         * NCAP:         don't care, leave at reset value
 296         * 2T_EN:        1T Timing
 297         * BA_INTLV_CTL: no interleaving
 298         * x32_EN:       x16 organization
 299         * PCHB8:        MA[10] for auto-precharge
 300         * HSE:          half strength for single and 2-layer stacks
 301         * (full strength for 3- and 4-layer stacks no yet considered)
 302         * MEM_HALT:     no halt
 303         * BI:           automatic initialization
 304         */
 305        ddr->sdram_cfg = 0x83000008;
 306
 307#endif /* CONFIG_TQM8548_AG || CONFIG_TQM8548_BE */
 308
 309        asm ("sync; isync; msync");
 310        udelay (1000);
 311#else /* !CONFIG_TQM8548 */
 312        switch (casl) {
 313        case 20:
 314                cfg_ddr_timing1 = 0x47405331 | (3 << 16);
 315                cfg_ddr_mode = 0x40020002 | (2 << 4);
 316                break;
 317
 318        case 25:
 319                cfg_ddr_timing1 = 0x47405331 | (4 << 16);
 320                cfg_ddr_mode = 0x40020002 | (6 << 4);
 321                break;
 322
 323        case 30:
 324        default:
 325                cfg_ddr_timing1 = 0x47405331 | (5 << 16);
 326                cfg_ddr_mode = 0x40020002 | (3 << 4);
 327                break;
 328        }
 329
 330        ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
 331        ddr->cs0_config = ddr_cs_conf[0].reg;
 332        ddr->timing_cfg_1 = cfg_ddr_timing1;
 333        ddr->timing_cfg_2 = 0x00000800;         /* P9-45,may need tuning */
 334        ddr->sdram_mode = cfg_ddr_mode;
 335        ddr->sdram_interval = 0x05160100;       /* autocharge,no open page */
 336        ddr->err_disable = 0x0000000D;
 337
 338        asm ("sync; isync; msync");
 339        udelay (1000);
 340
 341        ddr->sdram_cfg = 0xc2000000;            /* unbuffered,no DYN_PWR */
 342        asm ("sync; isync; msync");
 343        udelay (1000);
 344#endif /* CONFIG_TQM8548 */
 345
 346        for (i = 0; i < N_DDR_CS_CONF; i++) {
 347                ddr->cs0_config = ddr_cs_conf[i].reg;
 348
 349                if (get_ram_size (0, ddr_cs_conf[i].size) ==
 350                    ddr_cs_conf[i].size) {
 351                        /*
 352                         * size detected -> set Chip Select Bounds Register
 353                         */
 354                        ddr->cs0_bnds = (ddr_cs_conf[i].size - 1) >> 24;
 355
 356                        break;
 357                }
 358        }
 359
 360#ifdef CONFIG_TQM8548
 361        if (i < N_DDR_CS_CONF) {
 362                /* Adjust refresh rate for DDR2 */
 363
 364                ddr->timing_cfg_3 = ddr_cs_conf[i].refresh & 0x00070000;
 365
 366                ddr->timing_cfg_1 = (ddr->timing_cfg_1 & 0xFFFF0FFF) |
 367                    (ddr_cs_conf[i].refresh & 0x0000F000);
 368
 369                return ddr_cs_conf[i].size;
 370        }
 371#endif /* CONFIG_TQM8548 */
 372
 373        /* return size if detected, else return 0 */
 374        return (i < N_DDR_CS_CONF) ? ddr_cs_conf[i].size : 0;
 375}
 376
 377phys_size_t initdram (int board_type)
 378{
 379        long dram_size = 0;
 380        int casl;
 381
 382#if defined(CONFIG_DDR_DLL)
 383        /*
 384         * This DLL-Override only used on TQM8540 and TQM8560
 385         */
 386        {
 387                volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 388                int i, x;
 389
 390                x = 10;
 391
 392                /*
 393                 * Work around to stabilize DDR DLL
 394                 */
 395                gur->ddrdllcr = 0x81000000;
 396                asm ("sync; isync; msync");
 397                udelay (200);
 398                while (gur->ddrdllcr != 0x81000100) {
 399                        gur->devdisr = gur->devdisr | 0x00010000;
 400                        asm ("sync; isync; msync");
 401                        for (i = 0; i < x; i++)
 402                                ;
 403                        gur->devdisr = gur->devdisr & 0xfff7ffff;
 404                        asm ("sync; isync; msync");
 405                        x++;
 406                }
 407        }
 408#endif
 409
 410        casl = cas_latency ();
 411        dram_size = sdram_setup (casl);
 412        if ((dram_size == 0) && (casl != CONFIG_DDR_DEFAULT_CL)) {
 413                /*
 414                 * Try again with default CAS latency
 415                 */
 416                printf ("Problem with CAS lantency, using default CL %d/10!\n",
 417                        CONFIG_DDR_DEFAULT_CL);
 418                dram_size = sdram_setup (CONFIG_DDR_DEFAULT_CL);
 419                puts ("       ");
 420        }
 421
 422        return dram_size;
 423}
 424
 425#if defined(CONFIG_SYS_DRAM_TEST)
 426int testdram (void)
 427{
 428        uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
 429        uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
 430        uint *p;
 431
 432        printf ("SDRAM test phase 1:\n");
 433        for (p = pstart; p < pend; p++)
 434                *p = 0xaaaaaaaa;
 435
 436        for (p = pstart; p < pend; p++) {
 437                if (*p != 0xaaaaaaaa) {
 438                        printf ("SDRAM test fails at: %08x\n", (uint) p);
 439                        return 1;
 440                }
 441        }
 442
 443        printf ("SDRAM test phase 2:\n");
 444        for (p = pstart; p < pend; p++)
 445                *p = 0x55555555;
 446
 447        for (p = pstart; p < pend; p++) {
 448                if (*p != 0x55555555) {
 449                        printf ("SDRAM test fails at: %08x\n", (uint) p);
 450                        return 1;
 451                }
 452        }
 453
 454        printf ("SDRAM test passed.\n");
 455        return 0;
 456}
 457#endif
 458