Merge branch 'evk1100-prep'
[oweals/u-boot.git] / board / tqc / tqm85xx / sdram.c
index 783b2809e7786c6a04e8911f82c5414bbe47bf81..6d73a88ab0f7aaf4903c15cfd9f87e177a782362 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * (C) Copyright 2005
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
@@ -38,11 +39,20 @@ struct sdram_conf_s {
 typedef struct sdram_conf_s sdram_conf_t;
 
 #ifdef CONFIG_TQM8548
+#ifdef CONFIG_TQM8548_AG
+sdram_conf_t ddr_cs_conf[] = {
+       {(1024 << 20), 0x80044202, 0x0002D000}, /* 1024MB, 14x10(4)     */
+       { (512 << 20), 0x80044102, 0x0001A000}, /*  512MB, 13x10(4)     */
+       { (256 << 20), 0x80040102, 0x00014000}, /*  256MB, 13x10(4)     */
+       { (128 << 20), 0x80040101, 0x0000C000}, /*  128MB, 13x9(4)      */
+};
+#else /* !CONFIG_TQM8548_AG */
 sdram_conf_t ddr_cs_conf[] = {
        {(512 << 20), 0x80044102, 0x0001A000},  /* 512MB, 13x10(4)      */
        {(256 << 20), 0x80040102, 0x00014000},  /* 256MB, 13x10(4)      */
        {(128 << 20), 0x80040101, 0x0000C000},  /* 128MB, 13x9(4)       */
 };
+#endif /* CONFIG_TQM8548_AG */
 #else /* !CONFIG_TQM8548 */
 sdram_conf_t ddr_cs_conf[] = {
        {(512 << 20), 0x80000202},      /* 512MB, 14x10(4)      */
@@ -69,6 +79,9 @@ long int sdram_setup (int casl)
        volatile ccsr_ddr_t *ddr = (void *)(CONFIG_SYS_MPC85xx_DDR_ADDR);
 #ifdef CONFIG_TQM8548
        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
+       volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
+#endif
 #else /* !CONFIG_TQM8548 */
        unsigned long cfg_ddr_timing1;
        unsigned long cfg_ddr_mode;
@@ -81,21 +94,23 @@ long int sdram_setup (int casl)
        ddr->sdram_cfg = 0;
 
 #ifdef CONFIG_TQM8548
+       /* Timing and refresh settings for DDR2-533 and below */
+
        ddr->cs0_bnds = (ddr_cs_conf[0].size - 1) >> 24;
        ddr->cs0_config = ddr_cs_conf[0].reg;
-       ddr->timing_cfg_3 = 0x00010000;
+       ddr->timing_cfg_3 = 0x00020000;
 
        /* TIMING CFG 1, 533MHz
         * PRETOACT: 4 Clocks
         * ACTTOPRE: 12 Clocks
         * ACTTORW:  4 Clocks
         * CASLAT:   4 Clocks
-        * REFREC:   34 Clocks
+        * REFREC:   EXT_REFREC:REFREC 53 Clocks
         * WRREC:    4 Clocks
         * ACTTOACT: 3 Clocks
         * WRTORD:   2 Clocks
         */
-       ddr->timing_cfg_1 = 0x4C47A432;
+       ddr->timing_cfg_1 = 0x4C47D432;
 
        /* TIMING CFG 2, 533MHz
         * ADD_LAT:       3 Clocks
@@ -103,10 +118,10 @@ long int sdram_setup (int casl)
         * WR_LAT:        3 Clocks
         * RD_TO_PRE:     2 Clocks
         * WR_DATA_DELAY: 1/2 Clock
-        * CKE_PLS:       1 Clock
-        * FOUR_ACT:      13 Clocks
+        * CKE_PLS:       3 Clock
+        * FOUR_ACT:      14 Clocks
         */
-       ddr->timing_cfg_2 = 0x3318484D;
+       ddr->timing_cfg_2 = 0x331848CE;
 
        /* DDR SDRAM Mode, 533MHz
         * MRS:          Extended Mode Register
@@ -136,13 +151,12 @@ long int sdram_setup (int casl)
        ddr->sdram_interval = (1040 << 16) | 0x100;
 
        /*
-        * workaround for erratum DD10 of MPC8458 family below rev. 2.0:
-        * DDR IO receiver must be set to an acceptable bias point by modifying
-        * a hidden register.
+        * Workaround for erratum DDR19 according to MPC8548 Device Errata
+        * document, Rev. 1: DDR IO receiver must be set to an acceptable
+        * bias point by modifying a hidden register.
         */
-       if (SVR_REV (get_svr ()) < 0x20) {
+       if (SVR_REV (get_svr ()) < 0x21)
                gur->ddrioovcr = 0x90000000;    /* enable, VSEL 1.8V */
-       }
 
        /* DDR SDRAM CFG 2
         * FRC_SR:      normal mode
@@ -170,7 +184,104 @@ long int sdram_setup (int casl)
 
        /* wait for clock stabilization */
        asm ("sync;isync;msync");
-       udelay(1000);
+       udelay (1000);
+
+#if defined(CONFIG_TQM8548_AG) || defined(CONFIG_TQM8548_BE)
+       /*
+        * Workaround for erratum DDR20 according to MPC8548 Device Errata
+        * document, Rev. 1: "CKE signal may not function correctly after
+        * assertion of HRESET"
+        */
+
+       /* 1. Configure DDR register as is done in normal DDR configuration.
+        *    Do not set DDR_SDRAM_CFG[MEM_EN].
+        *
+        * 2. Set reserved bit EEBACR[3] at offset 0x1000
+        */
+       ecm->eebacr |= 0x10000000;
+
+       /*
+        * 3. Before DDR_SDRAM_CFG[MEM_EN] is set, write DDR_SDRAM_CFG_2[D_INIT]
+        *
+        * DDR_SDRAM_CFG_2:
+        * FRC_SR:      normal mode
+        * SR_IE:       no self-refresh interrupt
+        * DLL_RST_DIS: don't care, leave at reset value
+        * DQS_CFG:     differential DQS signals
+        * ODT_CFG:     assert ODT to internal IOs only during reads to DRAM
+        * LVWx_CFG:    don't care, leave at reset value
+        * NUM_PR:      1 refresh will be issued at a time
+        * DM_CFG:      don't care, leave at reset value
+        * D_INIT:      enable data initialization
+        */
+       ddr->sdram_cfg_2 |= 0x00000010;
+
+       /*
+        * 4. Before DDR_SDRAM_CFG[MEM_EN] set, write D3[21] to disable data
+        *    training
+        */
+       ddr->debug_3 |= 0x00000400;
+
+       /*
+        * 5. Wait 200 micro-seconds
+        */
+       udelay (200);
+
+       /*
+        * 6. Set DDR_SDRAM_CFG[MEM_EN]
+        *
+        * BTW, initialize DDR_SDRAM_CFG:
+        * MEM_EN:       enabled
+        * SREN:         don't care, leave at reset value
+        * ECC_EN:       no error report
+        * RD_EN:        no registered DIMMs
+        * SDRAM_TYPE:   DDR2
+        * DYN_PWR:      no power management
+        * 32_BE:        don't care, leave at reset value
+        * 8_BE:         4 beat burst
+        * NCAP:         don't care, leave at reset value
+        * 2T_EN:        1T Timing
+        * BA_INTLV_CTL: no interleaving
+        * x32_EN:       x16 organization
+        * PCHB8:        MA[10] for auto-precharge
+        * HSE:          half strength for single and 2-layer stacks
+        *               (full strength for 3- and 4-layer stacks not
+        *               yet considered)
+        * MEM_HALT:     no halt
+        * BI:           automatic initialization
+        */
+       ddr->sdram_cfg = 0x83000008;
+
+       /*
+        * 7. Poll DDR_SDRAM_CFG_2[D_INIT] until it is cleared by hardware
+        */
+       asm ("sync;isync;msync");
+       while (ddr->sdram_cfg_2 & 0x00000010)
+               asm ("eieio");
+
+       /*
+        * 8. Clear D3[21] to re-enable data training
+        */
+       ddr->debug_3 &= ~0x00000400;
+
+       /*
+        * 9. Set D2(21) to force data training to run
+        */
+       ddr->debug_2 |= 0x00000400;
+
+       /*
+        * 10. Poll on D2[21] until it is cleared by hardware
+        */
+       asm ("sync;isync;msync");
+       while (ddr->debug_2 & 0x00000400)
+               asm ("eieio");
+
+       /*
+        * 11. Clear reserved bit EEBACR[3] at offset 0x1000
+        */
+       ecm->eebacr &= ~0x10000000;
+
+#else /* !(CONFIG_TQM8548_AG || CONFIG_TQM8548_BE) */
 
        /* DDR SDRAM CLK CNTL
         * MEM_EN:       enabled
@@ -192,9 +303,11 @@ long int sdram_setup (int casl)
         * BI:           automatic initialization
         */
        ddr->sdram_cfg = 0x83000008;
-       asm ("sync; isync; msync");
-       udelay(1000);
 
+#endif /* CONFIG_TQM8548_AG || CONFIG_TQM8548_BE */
+
+       asm ("sync; isync; msync");
+       udelay (1000);
 #else /* !CONFIG_TQM8548 */
        switch (casl) {
        case 20: