Merge branch 'master' of git://git.denx.de/u-boot-blackfin
[platform/kernel/u-boot.git] / cpu / mpc8xxx / ddr / ctrl_regs.c
index 490e3dc..03f9c43 100644 (file)
@@ -1,9 +1,10 @@
 /*
- * Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * Version 2 as published by the Free Software Foundation.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
  */
 
 /*
@@ -188,12 +189,13 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr)
         * The DDR3 spec has not tXARD,
         * we use the tXP instead of it.
         * tXP=max(3nCK, 7.5ns) for DDR3.
-        * we use the tXP=6
         * spec has not the tAXPD, we use
         * tAXPD=8, need design to confirm.
         */
-       act_pd_exit_mclk = 6;
-       pre_pd_exit_mclk = 6;
+       int tXP = max((get_memory_clk_period_ps() * 3), 7500); /* unit=ps */
+       act_pd_exit_mclk = picos_to_mclk(tXP);
+       /* Mode register MR0[A12] is '1' - fast exit */
+       pre_pd_exit_mclk = act_pd_exit_mclk;
        taxpd_mclk = 8;
        tmrd_mclk = 4;
 #else /* CONFIG_FSL_DDR2 */
@@ -575,18 +577,22 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 }
 
 /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr)
+static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+                               const memctl_options_t *popts)
 {
        unsigned short esdmode2 = 0;    /* Extended SDRAM mode 2 */
        unsigned short esdmode3 = 0;    /* Extended SDRAM mode 3 */
 
 #if defined(CONFIG_FSL_DDR3)
-       unsigned int rtt_wr = 2;        /* 120 ohm Rtt_WR */
+       unsigned int rtt_wr = 0;        /* Rtt_WR - dynamic ODT off */
        unsigned int srt = 0;   /* self-refresh temerature, normal range */
        unsigned int asr = 0;   /* auto self-refresh disable */
        unsigned int cwl = compute_cas_write_latency() - 5;
        unsigned int pasr = 0;  /* partial array self refresh disable */
 
+       if (popts->rtt_override)
+               rtt_wr = popts->rtt_wr_override_value;
+
        esdmode2 = (0
                | ((rtt_wr & 0x3) << 9)
                | ((srt & 0x1) << 7)
@@ -675,12 +681,12 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
        esdmode = (0
                | ((qoff & 0x1) << 12)
                | ((tdqs_en & 0x1) << 11)
-               | ((rtt & 0x4) << 9)   /* rtt field is split */
+               | ((rtt & 0x4) << 7)   /* rtt field is split */
                | ((wrlvl_en & 0x1) << 7)
-               | ((rtt & 0x2) << 6)   /* rtt field is split */
-               | ((dic & 0x2) << 5)   /* DIC field is split */
+               | ((rtt & 0x2) << 5)   /* rtt field is split */
+               | ((dic & 0x2) << 4)   /* DIC field is split */
                | ((al & 0x3) << 3)
-               | ((rtt & 0x1) << 2)   /* rtt field is split */
+               | ((rtt & 0x1) << 2)  /* rtt field is split */
                | ((dic & 0x1) << 1)   /* DIC field is split */
                | ((dll_en & 0x1) << 0)
                );
@@ -929,7 +935,8 @@ static void set_ddr_init_ext_addr(fsl_ddr_cfg_regs_t *ddr)
 }
 
 /* DDR SDRAM Timing Configuration 4 (TIMING_CFG_4) */
-static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr)
+static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr,
+                               const memctl_options_t *popts)
 {
        unsigned int rwt = 0; /* Read-to-write turnaround for same CS */
        unsigned int wrt = 0; /* Write-to-read turnaround for same CS */
@@ -938,9 +945,15 @@ static void set_timing_cfg_4(fsl_ddr_cfg_regs_t *ddr)
        unsigned int dll_lock = 0; /* DDR SDRAM DLL Lock Time */
 
 #if defined(CONFIG_FSL_DDR3)
-       /* We need set BL/2 + 4 for BC4 or OTF */
-       rrt = 4;        /* BL/2 + 4 clocks */
-       wwt = 4;        /* BL/2 + 4 clocks */
+       if (popts->burst_length == DDR_BL8) {
+               /* We set BL/2 for fixed BL8 */
+               rrt = 0;        /* BL/2 clocks */
+               wwt = 0;        /* BL/2 clocks */
+       } else {
+               /* We need to set BL/2 + 2 to BC4 and OTF */
+               rrt = 2;        /* BL/2 + 2 clocks */
+               wwt = 2;        /* BL/2 + 2 clocks */
+       }
        dll_lock = 1;   /* tDLLK = 512 clocks from spec */
 #endif
        ddr->timing_cfg_4 = (0
@@ -1001,8 +1014,8 @@ static void set_ddr_zq_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int zq_en)
 }
 
 /* DDR Write Leveling Control (DDR_WRLVL_CNTL) */
-static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
-                              unsigned int wrlvl_en)
+static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr, unsigned int wrlvl_en,
+                               const memctl_options_t *popts)
 {
        /*
         * First DQS pulse rising edge after margining mode
@@ -1029,8 +1042,9 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
                /* tWL_DQSEN min = 25 nCK, we set it 32 */
                wrlvl_dqsen = 0x5;
                /*
-                * Write leveling sample time at least need 14 clocks
-                * due to tWLO = 9, we set it 15 clocks
+                * Write leveling sample time at least need 6 clocks
+                * higher than tWLO to allow enough time for progagation
+                * delay and sampling the prime data bits.
                 */
                wrlvl_smpl = 0xf;
                /*
@@ -1043,9 +1057,16 @@ static void set_ddr_wrlvl_cntl(fsl_ddr_cfg_regs_t *ddr,
                 * Write leveling start time
                 * The value use for the DQS_ADJUST for the first sample
                 * when write leveling is enabled.
-                * we set it 1 clock delay
                 */
                wrlvl_start = 0x8;
+               /*
+                * Override the write leveling sample and start time
+                * according to specific board
+                */
+               if (popts->wrlvl_override) {
+                       wrlvl_smpl = popts->wrlvl_sample;
+                       wrlvl_start = popts->wrlvl_start;
+               }
        }
 
        ddr->ddr_wrlvl_cntl = (0
@@ -1066,28 +1087,6 @@ static void set_ddr_sr_cntr(fsl_ddr_cfg_regs_t *ddr, unsigned int sr_it)
        ddr->ddr_sr_cntr = (sr_it & 0xF) << 16;
 }
 
-/* DDR Pre-Drive Conditioning Control (DDR_PD_CNTL) */
-static void set_ddr_pd_cntl(fsl_ddr_cfg_regs_t *ddr)
-{
-       /* Termination value during pre-drive conditioning */
-       unsigned int tvpd = 0;
-       unsigned int pd_en = 0;         /* Pre-Drive Conditioning Enable */
-       unsigned int pdar = 0;          /* Pre-Drive After Read */
-       unsigned int pdaw = 0;          /* Pre-Drive After Write */
-       unsigned int pd_on = 0;         /* Pre-Drive Conditioning On */
-       unsigned int pd_off = 0;        /* Pre-Drive Conditioning Off */
-
-       ddr->ddr_pd_cntl = (0
-                           | ((pd_en & 0x1) << 31)
-                           | ((tvpd & 0x7) << 28)
-                           | ((pdar & 0x7F) << 20)
-                           | ((pdaw & 0x7F) << 12)
-                           | ((pd_on & 0x1F) << 6)
-                           | ((pd_off & 0x1F) << 0)
-                           );
-}
-
-
 /* DDR SDRAM Register Control Word 1 (DDR_SDRAM_RCW_1) */
 static void set_ddr_sdram_rcw_1(fsl_ddr_cfg_regs_t *ddr)
 {
@@ -1199,15 +1198,17 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 
        /* Chip Select Memory Bounds (CSn_BNDS) */
        for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
-               phys_size_t sa = 0;
-               phys_size_t ea = 0;
+               unsigned long long ea = 0, sa = 0;
 
                if (popts->ba_intlv_ctl && (i > 0) &&
                        ((popts->ba_intlv_ctl & 0x60) != FSL_DDR_CS2_CS3 )) {
                        /* Don't set up boundaries for other CS
                         * other than CS0, if bank interleaving
                         * is enabled and not CS2+CS3 interleaved.
+                        * But we need to set the ODT_RD_CFG and
+                        * ODT_WR_CFG for CS1_CONFIG here.
                         */
+                       set_csn_config(i, ddr, popts, dimm_params);
                        break;
                }
 
@@ -1344,19 +1345,18 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
        set_ddr_sdram_cfg_2(ddr, popts);
        set_ddr_sdram_mode(ddr, popts, common_dimm,
                                cas_latency, additive_latency);
-       set_ddr_sdram_mode_2(ddr);
+       set_ddr_sdram_mode_2(ddr, popts);
        set_ddr_sdram_interval(ddr, popts, common_dimm);
        set_ddr_data_init(ddr);
        set_ddr_sdram_clk_cntl(ddr, popts);
        set_ddr_init_addr(ddr);
        set_ddr_init_ext_addr(ddr);
-       set_timing_cfg_4(ddr);
+       set_timing_cfg_4(ddr, popts);
        set_timing_cfg_5(ddr);
 
        set_ddr_zq_cntl(ddr, zq_en);
-       set_ddr_wrlvl_cntl(ddr, wrlvl_en);
+       set_ddr_wrlvl_cntl(ddr, wrlvl_en, popts);
 
-       set_ddr_pd_cntl(ddr);
        set_ddr_sr_cntr(ddr, sr_it);
 
        set_ddr_sdram_rcw_1(ddr);