Merge branch 'master' of git://git.denx.de/u-boot-i2c
[platform/kernel/u-boot.git] / board / freescale / corenet_ds / ddr.c
1 /*
2  * Copyright 2009-2010 Freescale Semiconductor, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * Version 2 as published by the Free Software Foundation.
7  */
8
9 #include <common.h>
10 #include <i2c.h>
11 #include <hwconfig.h>
12 #include <asm/mmu.h>
13 #include <asm/fsl_ddr_sdram.h>
14 #include <asm/fsl_ddr_dimm_params.h>
15 #include <asm/fsl_law.h>
16
17 DECLARE_GLOBAL_DATA_PTR;
18
19 extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
20                                    unsigned int ctrl_num);
21
22
23 /*
24  * Fixed sdram init -- doesn't use serial presence detect.
25  */
26 extern fixed_ddr_parm_t fixed_ddr_parm_0[];
27 #if (CONFIG_NUM_DDR_CONTROLLERS == 2)
28 extern fixed_ddr_parm_t fixed_ddr_parm_1[];
29 #endif
30
31 phys_size_t fixed_sdram(void)
32 {
33         int i;
34         sys_info_t sysinfo;
35         char buf[32];
36         fsl_ddr_cfg_regs_t ddr_cfg_regs;
37         phys_size_t ddr_size;
38         unsigned int lawbar1_target_id;
39
40         get_sys_info(&sysinfo);
41         printf("Configuring DDR for %s MT/s data rate\n",
42                                 strmhz(buf, sysinfo.freqDDRBus));
43
44         for (i = 0; fixed_ddr_parm_0[i].max_freq > 0; i++) {
45                 if ((sysinfo.freqDDRBus > fixed_ddr_parm_0[i].min_freq) &&
46                    (sysinfo.freqDDRBus <= fixed_ddr_parm_0[i].max_freq)) {
47                         memcpy(&ddr_cfg_regs,
48                                 fixed_ddr_parm_0[i].ddr_settings,
49                                 sizeof(ddr_cfg_regs));
50                         break;
51                 }
52         }
53
54         if (fixed_ddr_parm_0[i].max_freq == 0)
55                 panic("Unsupported DDR data rate %s MT/s data rate\n",
56                         strmhz(buf, sysinfo.freqDDRBus));
57
58         ddr_size = (phys_size_t) CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
59         fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 0);
60
61 #if (CONFIG_NUM_DDR_CONTROLLERS == 2)
62         memcpy(&ddr_cfg_regs,
63                 fixed_ddr_parm_1[i].ddr_settings,
64                 sizeof(ddr_cfg_regs));
65         fsl_ddr_set_memctl_regs(&ddr_cfg_regs, 1);
66 #endif
67
68         /*
69          * setup laws for DDR. If not interleaving, presuming half memory on
70          * DDR1 and the other half on DDR2
71          */
72         if (fixed_ddr_parm_0[i].ddr_settings->cs[0].config & 0x20000000) {
73                 if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
74                                  ddr_size,
75                                  LAW_TRGT_IF_DDR_INTRLV) < 0) {
76                         printf("ERROR setting Local Access Windows for DDR\n");
77                         return 0;
78                 }
79         } else {
80 #if (CONFIG_NUM_DDR_CONTROLLERS == 2)
81                 /* We require both controllers have identical DIMMs */
82                 lawbar1_target_id = LAW_TRGT_IF_DDR_1;
83                 if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
84                                  ddr_size / 2,
85                                  lawbar1_target_id) < 0) {
86                         printf("ERROR setting Local Access Windows for DDR\n");
87                         return 0;
88                 }
89                 lawbar1_target_id = LAW_TRGT_IF_DDR_2;
90                 if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE + ddr_size / 2,
91                                  ddr_size / 2,
92                                  lawbar1_target_id) < 0) {
93                         printf("ERROR setting Local Access Windows for DDR\n");
94                         return 0;
95                 }
96 #else
97                 lawbar1_target_id = LAW_TRGT_IF_DDR_1;
98                 if (set_ddr_laws(CONFIG_SYS_DDR_SDRAM_BASE,
99                                  ddr_size,
100                                  lawbar1_target_id) < 0) {
101                         printf("ERROR setting Local Access Windows for DDR\n");
102                         return 0;
103                 }
104 #endif
105         }
106         return ddr_size;
107 }
108
109 static void get_spd(ddr3_spd_eeprom_t *spd, unsigned char i2c_address)
110 {
111         int ret;
112
113         ret = i2c_read(i2c_address, 0, 1, (uchar *)spd, sizeof(ddr3_spd_eeprom_t));
114         if (ret) {
115                 debug("DDR: failed to read SPD from address %u\n", i2c_address);
116                 memset(spd, 0, sizeof(ddr3_spd_eeprom_t));
117         }
118 }
119
120 unsigned int fsl_ddr_get_mem_data_rate(void)
121 {
122         return get_ddr_freq(0);
123 }
124
125 void fsl_ddr_get_spd(ddr3_spd_eeprom_t *ctrl_dimms_spd,
126                       unsigned int ctrl_num)
127 {
128         unsigned int i;
129         unsigned int i2c_address = 0;
130
131         for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
132                 if (ctrl_num == 0 && i == 0)
133                         i2c_address = SPD_EEPROM_ADDRESS1;
134                 else if (ctrl_num == 1 && i == 0)
135                         i2c_address = SPD_EEPROM_ADDRESS2;
136
137                 get_spd(&(ctrl_dimms_spd[i]), i2c_address);
138         }
139 }
140
141 typedef struct {
142         u32 datarate_mhz_low;
143         u32 datarate_mhz_high;
144         u32 n_ranks;
145         u32 clk_adjust;
146         u32 cpo;
147         u32 write_data_delay;
148         u32 force_2T;
149 } board_specific_parameters_t;
150
151 /* ranges for parameters:
152  *  wr_data_delay = 0-6
153  *  clk adjust = 0-8
154  *  cpo 2-0x1E (30)
155  */
156
157
158 /* XXX: these values need to be checked for all interleaving modes.  */
159 /* XXX: No reliable dual-rank 800 MHz setting has been found.  It may
160  *      seem reliable, but errors will appear when memory intensive
161  *      program is run. */
162 /* XXX: Single rank at 800 MHz is OK.  */
163 const board_specific_parameters_t board_specific_parameters[][30] = {
164         {
165         /*      memory controller 0                     */
166         /*        lo|  hi|  num|  clk| cpo|wrdata|2T    */
167         /*       mhz| mhz|ranks|adjst|    | delay|      */
168                 {  0, 333,    4,    6,   7,    3,  0},
169                 {334, 400,    4,    6,   9,    3,  0},
170                 {401, 549,    4,    6,  11,    3,  0},
171                 {550, 680,    4,    1,  10,    5,  0},
172                 {681, 850,    4,    1,  12,    5,  0},
173                 {851, 1050,   4,    1,  12,    5,  0},
174                 {1051, 1250,  4,    1,  15,    4,  0},
175                 {1251, 1350,  4,    1,  15,    4,  0},
176                 {  0, 333,    2,    6,   7,    3,  0},
177                 {334, 400,    2,    6,   9,    3,  0},
178                 {401, 549,    2,    6,  11,    3,  0},
179                 {550, 680,    2,    1,  10,    5,  0},
180                 {681, 850,    2,    1,  12,    5,  0},
181                 {851, 1050,   2,    1,  12,    5,  0},
182                 {1051, 1250,  2,    1,  15,    4,  0},
183                 {1251, 1350,  2,    1,  15,    4,  0},
184                 {  0, 333,    1,    6,   7,    3,  0},
185                 {334, 400,    1,    6,   9,    3,  0},
186                 {401, 549,    1,    6,  11,    3,  0},
187                 {550, 680,    1,    1,  10,    5,  0},
188                 {681, 850,    1,    1,  12,    5,  0}
189         },
190
191         {
192         /*      memory controller 1                     */
193         /*        lo|  hi|  num|  clk| cpo|wrdata|2T    */
194         /*       mhz| mhz|ranks|adjst|    | delay|      */
195                 {  0, 333,    4,    6,   7,    3,  0},
196                 {334, 400,    4,    6,   9,    3,  0},
197                 {401, 549,    4,    6,  11,    3,  0},
198                 {550, 680,    4,    1,  10,    5,  0},
199                 {681, 850,    4,    1,  12,    5,  0},
200                 {851, 1050,   4,    1,  12,    5,  0},
201                 {1051, 1250,  4,    1,  15,    4,  0},
202                 {1251, 1350,  4,    1,  15,    4,  0},
203                 {  0, 333,    2,     6,  7,    3,  0},
204                 {334, 400,    2,     6,  9,    3,  0},
205                 {401, 549,    2,     6, 11,    3,  0},
206                 {550, 680,    2,     1, 11,    6,  0},
207                 {681, 850,    2,     1, 13,    6,  0},
208                 {851, 1050,   2,     1, 13,    6,  0},
209                 {1051, 1250,  2,     1, 15,    4,  0},
210                 {1251, 1350,  2,     1, 15,    4,  0},
211                 {  0, 333,    1,     6,  7,    3,  0},
212                 {334, 400,    1,     6,  9,    3,  0},
213                 {401, 549,    1,     6, 11,    3,  0},
214                 {550, 680,    1,     1, 11,    6,  0},
215                 {681, 850,    1,     1, 13,    6,  0}
216         }
217 };
218
219 void fsl_ddr_board_options(memctl_options_t *popts,
220                                 dimm_params_t *pdimm,
221                                 unsigned int ctrl_num)
222 {
223         const board_specific_parameters_t *pbsp =
224                                 &(board_specific_parameters[ctrl_num][0]);
225         u32 num_params = sizeof(board_specific_parameters[ctrl_num]) /
226                                 sizeof(board_specific_parameters[0][0]);
227         u32 i;
228         ulong ddr_freq;
229
230         /* set odt_rd_cfg and odt_wr_cfg. If the there is only one dimm in
231          * that controller, set odt_wr_cfg to 4 for CS0, and 0 to CS1. If
232          * there are two dimms in the controller, set odt_rd_cfg to 3 and
233          * odt_wr_cfg to 3 for the even CS, 0 for the odd CS.
234          */
235         for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
236                 if (i&1) {      /* odd CS */
237                         popts->cs_local_opts[i].odt_rd_cfg = 0;
238                         popts->cs_local_opts[i].odt_wr_cfg = 1;
239                 } else {        /* even CS */
240                         if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
241                                 popts->cs_local_opts[i].odt_rd_cfg = 0;
242                                 popts->cs_local_opts[i].odt_wr_cfg = 1;
243                         } else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) {
244                         popts->cs_local_opts[i].odt_rd_cfg = 3;
245                         popts->cs_local_opts[i].odt_wr_cfg = 3;
246                         }
247                 }
248         }
249
250         /* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
251          * freqency and n_banks specified in board_specific_parameters table.
252          */
253         ddr_freq = get_ddr_freq(0) / 1000000;
254         for (i = 0; i < num_params; i++) {
255                 if (ddr_freq >= pbsp->datarate_mhz_low &&
256                     ddr_freq <= pbsp->datarate_mhz_high &&
257                     pdimm->n_ranks == pbsp->n_ranks) {
258                         popts->cpo_override = 0xff; /* force auto CPO calibration */
259                         popts->write_data_delay = 2;
260                         popts->clk_adjust = 5; /* Force value to be 5/8 clock cycle */
261                         popts->twoT_en = pbsp->force_2T;
262                 }
263                 pbsp++;
264         }
265
266         /*
267          * Factors to consider for half-strength driver enable:
268          *      - number of DIMMs installed
269          */
270         popts->half_strength_driver_enable = 0;
271         /*
272          * Write leveling override
273          */
274         popts->wrlvl_override = 1;
275         popts->wrlvl_sample = 0xa;
276         popts->wrlvl_start = 0x7;
277         /*
278          * Rtt and Rtt_WR override
279          */
280         popts->rtt_override = 1;
281         popts->rtt_override_value = DDR3_RTT_120_OHM;
282         popts->rtt_wr_override_value = 0; /* Rtt_WR= dynamic ODT off */
283
284         /* Enable ZQ calibration */
285         popts->zq_en = 1;
286 }
287
288 phys_size_t initdram(int board_type)
289 {
290         phys_size_t dram_size;
291         int use_spd = 0;
292
293         puts("Initializing....");
294
295 #ifdef CONFIG_DDR_SPD
296         /* if hwconfig is not enabled, or "sdram" is not defined, use spd */
297         if (hwconfig_sub("fsl_ddr", "sdram")) {
298                 if (hwconfig_subarg_cmp("fsl_ddr", "sdram", "spd"))
299                         use_spd = 1;
300                 else if (hwconfig_subarg_cmp("fsl_ddr", "sdram", "fixed"))
301                         use_spd = 0;
302                 else
303                         use_spd = 1;
304         } else
305                 use_spd = 1;
306 #endif
307
308         if (use_spd) {
309                 puts("using SPD\n");
310                 dram_size = fsl_ddr_sdram();
311         } else {
312                 puts("using fixed parameters\n");
313                 dram_size = fixed_sdram();
314         }
315
316         dram_size = setup_ddr_tlbs(dram_size / 0x100000);
317         dram_size *= 0x100000;
318
319         puts("    DDR: ");
320         return dram_size;
321 }