blob: 2885906e875c6498136f9c6be35c9d1d38193655 [file] [log] [blame]
Kumar Gala124b0822008-08-26 15:01:29 -05001/*
York Sune8dc17b2012-08-17 08:22:39 +00002 * Copyright 2008-2012 Freescale Semiconductor, Inc.
Kumar Gala124b0822008-08-26 15:01:29 -05003 *
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/*
10 * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
11 * Based on code from spd_sdram.c
12 * Author: James Yang [at freescale.com]
13 */
14
15#include <common.h>
Kumar Galac68e86c2011-01-31 22:18:47 -060016#include <i2c.h>
Kumar Gala124b0822008-08-26 15:01:29 -050017#include <asm/fsl_ddr_sdram.h>
York Sune8dc17b2012-08-17 08:22:39 +000018#include <asm/fsl_law.h>
Kumar Gala124b0822008-08-26 15:01:29 -050019
20#include "ddr.h"
21
York Sune8dc17b2012-08-17 08:22:39 +000022void fsl_ddr_set_lawbar(
Kumar Gala124b0822008-08-26 15:01:29 -050023 const common_timing_params_t *memctl_common_params,
24 unsigned int memctl_interleaved,
25 unsigned int ctrl_num);
York Sune8dc17b2012-08-17 08:22:39 +000026void fsl_ddr_set_intl3r(const unsigned int granule_size);
Kumar Gala124b0822008-08-26 15:01:29 -050027
28/* processor specific function */
29extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
30 unsigned int ctrl_num);
31
Kumar Galac68e86c2011-01-31 22:18:47 -060032#if defined(SPD_EEPROM_ADDRESS) || \
33 defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \
34 defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4)
35#if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
36u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
37 [0][0] = SPD_EEPROM_ADDRESS,
38};
York Sun92b46ac2011-08-26 11:32:41 -070039#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
Kumar Galac68e86c2011-01-31 22:18:47 -060040u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
41 [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
York Sun92b46ac2011-08-26 11:32:41 -070042 [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */
43};
44#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
45u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
46 [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
Kumar Galac68e86c2011-01-31 22:18:47 -060047 [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */
48};
York Sun92b46ac2011-08-26 11:32:41 -070049#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
Kumar Galac68e86c2011-01-31 22:18:47 -060050u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
51 [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
52 [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */
53 [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */
54 [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */
55};
York Sune8dc17b2012-08-17 08:22:39 +000056#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
57u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
58 [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
59 [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */
60 [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */
61};
62#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
63u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = {
64 [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */
65 [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */
66 [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */
67 [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */
68 [2][0] = SPD_EEPROM_ADDRESS5, /* controller 3 */
69 [2][1] = SPD_EEPROM_ADDRESS6, /* controller 3 */
70};
71
Kumar Galac68e86c2011-01-31 22:18:47 -060072#endif
73
74static void __get_spd(generic_spd_eeprom_t *spd, u8 i2c_address)
75{
76 int ret = i2c_read(i2c_address, 0, 1, (uchar *)spd,
77 sizeof(generic_spd_eeprom_t));
78
79 if (ret) {
80 printf("DDR: failed to read SPD from address %u\n", i2c_address);
81 memset(spd, 0, sizeof(generic_spd_eeprom_t));
82 }
83}
84
85__attribute__((weak, alias("__get_spd")))
86void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address);
87
88void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
89 unsigned int ctrl_num)
90{
91 unsigned int i;
92 unsigned int i2c_address = 0;
93
94 if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) {
95 printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num);
96 return;
97 }
98
99 for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
100 i2c_address = spd_i2c_addr[ctrl_num][i];
101 get_spd(&(ctrl_dimms_spd[i]), i2c_address);
102 }
103}
104#else
105void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
106 unsigned int ctrl_num)
107{
108}
109#endif /* SPD_EEPROM_ADDRESSx */
Kumar Gala124b0822008-08-26 15:01:29 -0500110
111/*
112 * ASSUMPTIONS:
113 * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller
114 * - Same memory data bus width on all controllers
115 *
116 * NOTES:
117 *
118 * The memory controller and associated documentation use confusing
119 * terminology when referring to the orgranization of DRAM.
120 *
121 * Here is a terminology translation table:
122 *
123 * memory controller/documention |industry |this code |signals
124 * -------------------------------|-----------|-----------|-----------------
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200125 * physical bank/bank |rank |rank |chip select (CS)
126 * logical bank/sub-bank |bank |bank |bank address (BA)
127 * page/row |row |page |row address
128 * ??? |column |column |column address
Kumar Gala124b0822008-08-26 15:01:29 -0500129 *
130 * The naming confusion is further exacerbated by the descriptions of the
131 * memory controller interleaving feature, where accesses are interleaved
132 * _BETWEEN_ two seperate memory controllers. This is configured only in
133 * CS0_CONFIG[INTLV_CTL] of each memory controller.
134 *
135 * memory controller documentation | number of chip selects
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200136 * | per memory controller supported
Kumar Gala124b0822008-08-26 15:01:29 -0500137 * --------------------------------|-----------------------------------------
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200138 * cache line interleaving | 1 (CS0 only)
139 * page interleaving | 1 (CS0 only)
140 * bank interleaving | 1 (CS0 only)
141 * superbank interleraving | depends on bank (chip select)
142 * | interleraving [rank interleaving]
143 * | mode used on every memory controller
Kumar Gala124b0822008-08-26 15:01:29 -0500144 *
145 * Even further confusing is the existence of the interleaving feature
146 * _WITHIN_ each memory controller. The feature is referred to in
147 * documentation as chip select interleaving or bank interleaving,
148 * although it is configured in the DDR_SDRAM_CFG field.
149 *
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200150 * Name of field | documentation name | this code
Kumar Gala124b0822008-08-26 15:01:29 -0500151 * -----------------------------|-----------------------|------------------
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200152 * DDR_SDRAM_CFG[BA_INTLV_CTL] | Bank (chip select) | rank interleaving
153 * | interleaving
Kumar Gala124b0822008-08-26 15:01:29 -0500154 */
155
Kumar Gala124b0822008-08-26 15:01:29 -0500156const char *step_string_tbl[] = {
157 "STEP_GET_SPD",
158 "STEP_COMPUTE_DIMM_PARMS",
159 "STEP_COMPUTE_COMMON_PARMS",
160 "STEP_GATHER_OPTS",
161 "STEP_ASSIGN_ADDRESSES",
162 "STEP_COMPUTE_REGS",
163 "STEP_PROGRAM_REGS",
164 "STEP_ALL"
165};
166
167const char * step_to_string(unsigned int step) {
168
169 unsigned int s = __ilog2(step);
170
171 if ((1 << s) != step)
172 return step_string_tbl[7];
173
174 return step_string_tbl[s];
175}
Kumar Gala124b0822008-08-26 15:01:29 -0500176
York Sune8dc17b2012-08-17 08:22:39 +0000177unsigned long long step_assign_addresses(fsl_ddr_info_t *pinfo,
178 unsigned int dbw_cap_adj[])
Kumar Gala124b0822008-08-26 15:01:29 -0500179{
180 int i, j;
York Sune8dc17b2012-08-17 08:22:39 +0000181 unsigned long long total_mem, current_mem_base, total_ctlr_mem;
182 unsigned long long rank_density, ctlr_density = 0;
Kumar Gala124b0822008-08-26 15:01:29 -0500183
184 /*
185 * If a reduced data width is requested, but the SPD
186 * specifies a physically wider device, adjust the
187 * computed dimm capacities accordingly before
188 * assigning addresses.
189 */
190 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
191 unsigned int found = 0;
192
193 switch (pinfo->memctl_opts[i].data_bus_width) {
194 case 2:
195 /* 16-bit */
York Sundd803dd2011-05-27 07:25:51 +0800196 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
197 unsigned int dw;
198 if (!pinfo->dimm_params[i][j].n_ranks)
199 continue;
200 dw = pinfo->dimm_params[i][j].primary_sdram_width;
201 if ((dw == 72 || dw == 64)) {
202 dbw_cap_adj[i] = 2;
203 break;
204 } else if ((dw == 40 || dw == 32)) {
205 dbw_cap_adj[i] = 1;
206 break;
207 }
208 }
Kumar Gala124b0822008-08-26 15:01:29 -0500209 break;
210
211 case 1:
212 /* 32-bit */
213 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
214 unsigned int dw;
215 dw = pinfo->dimm_params[i][j].data_width;
216 if (pinfo->dimm_params[i][j].n_ranks
217 && (dw == 72 || dw == 64)) {
218 /*
219 * FIXME: can't really do it
220 * like this because this just
221 * further reduces the memory
222 */
223 found = 1;
224 break;
225 }
226 }
227 if (found) {
228 dbw_cap_adj[i] = 1;
229 }
230 break;
231
232 case 0:
233 /* 64-bit */
234 break;
235
236 default:
237 printf("unexpected data bus width "
238 "specified controller %u\n", i);
239 return 1;
240 }
York Sune8dc17b2012-08-17 08:22:39 +0000241 debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]);
Kumar Gala124b0822008-08-26 15:01:29 -0500242 }
243
York Sune8dc17b2012-08-17 08:22:39 +0000244 current_mem_base = 0ull;
245 total_mem = 0;
246 if (pinfo->memctl_opts[0].memctl_interleaving) {
247 rank_density = pinfo->dimm_params[0][0].rank_density >>
248 dbw_cap_adj[0];
249 switch (pinfo->memctl_opts[0].ba_intlv_ctl &
250 FSL_DDR_CS0_CS1_CS2_CS3) {
251 case FSL_DDR_CS0_CS1_CS2_CS3:
252 ctlr_density = 4 * rank_density;
253 break;
254 case FSL_DDR_CS0_CS1:
255 case FSL_DDR_CS0_CS1_AND_CS2_CS3:
256 ctlr_density = 2 * rank_density;
257 break;
258 case FSL_DDR_CS2_CS3:
259 default:
260 ctlr_density = rank_density;
261 break;
262 }
263 debug("rank density is 0x%llx, ctlr density is 0x%llx\n",
264 rank_density, ctlr_density);
Kumar Gala124b0822008-08-26 15:01:29 -0500265 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
York Sune8dc17b2012-08-17 08:22:39 +0000266 if (pinfo->memctl_opts[i].memctl_interleaving) {
267 switch (pinfo->memctl_opts[i].memctl_interleaving_mode) {
268 case FSL_DDR_CACHE_LINE_INTERLEAVING:
269 case FSL_DDR_PAGE_INTERLEAVING:
270 case FSL_DDR_BANK_INTERLEAVING:
271 case FSL_DDR_SUPERBANK_INTERLEAVING:
272 total_ctlr_mem = 2 * ctlr_density;
273 break;
274 case FSL_DDR_3WAY_1KB_INTERLEAVING:
275 case FSL_DDR_3WAY_4KB_INTERLEAVING:
276 case FSL_DDR_3WAY_8KB_INTERLEAVING:
277 total_ctlr_mem = 3 * ctlr_density;
278 break;
279 case FSL_DDR_4WAY_1KB_INTERLEAVING:
280 case FSL_DDR_4WAY_4KB_INTERLEAVING:
281 case FSL_DDR_4WAY_8KB_INTERLEAVING:
282 total_ctlr_mem = 4 * ctlr_density;
283 break;
284 default:
285 panic("Unknown interleaving mode");
286 }
287 pinfo->common_timing_params[i].base_address =
288 current_mem_base;
289 pinfo->common_timing_params[i].total_mem =
290 total_ctlr_mem;
291 total_mem = current_mem_base + total_ctlr_mem;
292 debug("ctrl %d base 0x%llx\n", i, current_mem_base);
293 debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
294 } else {
295 /* when 3rd controller not interleaved */
296 current_mem_base = total_mem;
297 total_ctlr_mem = 0;
298 pinfo->common_timing_params[i].base_address =
299 current_mem_base;
300 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
301 unsigned long long cap =
302 pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i];
303 pinfo->dimm_params[i][j].base_address =
304 current_mem_base;
305 debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base);
306 current_mem_base += cap;
307 total_ctlr_mem += cap;
308 }
309 debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
310 pinfo->common_timing_params[i].total_mem =
311 total_ctlr_mem;
312 total_mem += total_ctlr_mem;
Kumar Gala124b0822008-08-26 15:01:29 -0500313 }
314 }
315 } else {
316 /*
317 * Simple linear assignment if memory
318 * controllers are not interleaved.
319 */
Kumar Gala124b0822008-08-26 15:01:29 -0500320 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
York Sune8dc17b2012-08-17 08:22:39 +0000321 total_ctlr_mem = 0;
Kumar Gala124b0822008-08-26 15:01:29 -0500322 pinfo->common_timing_params[i].base_address =
York Sune8dc17b2012-08-17 08:22:39 +0000323 current_mem_base;
Kumar Gala124b0822008-08-26 15:01:29 -0500324 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
325 /* Compute DIMM base addresses. */
326 unsigned long long cap =
York Sune8dc17b2012-08-17 08:22:39 +0000327 pinfo->dimm_params[i][j].capacity >> dbw_cap_adj[i];
Kumar Gala124b0822008-08-26 15:01:29 -0500328 pinfo->dimm_params[i][j].base_address =
York Sune8dc17b2012-08-17 08:22:39 +0000329 current_mem_base;
330 debug("ctrl %d dimm %d base 0x%llx\n", i, j, current_mem_base);
331 current_mem_base += cap;
332 total_ctlr_mem += cap;
Kumar Gala124b0822008-08-26 15:01:29 -0500333 }
York Sune8dc17b2012-08-17 08:22:39 +0000334 debug("ctrl %d total 0x%llx\n", i, total_ctlr_mem);
Kumar Gala124b0822008-08-26 15:01:29 -0500335 pinfo->common_timing_params[i].total_mem =
York Sune8dc17b2012-08-17 08:22:39 +0000336 total_ctlr_mem;
337 total_mem += total_ctlr_mem;
Kumar Gala124b0822008-08-26 15:01:29 -0500338 }
339 }
York Sune8dc17b2012-08-17 08:22:39 +0000340 debug("Total mem by %s is 0x%llx\n", __func__, total_mem);
Kumar Gala124b0822008-08-26 15:01:29 -0500341
York Sune8dc17b2012-08-17 08:22:39 +0000342 return total_mem;
Kumar Gala124b0822008-08-26 15:01:29 -0500343}
344
Kumar Gala68ef4bd2009-06-11 23:42:35 -0500345unsigned long long
Haiying Wang80ad4012010-12-01 10:35:31 -0500346fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
347 unsigned int size_only)
Kumar Gala124b0822008-08-26 15:01:29 -0500348{
349 unsigned int i, j;
Kumar Gala68ef4bd2009-06-11 23:42:35 -0500350 unsigned long long total_mem = 0;
Kumar Gala124b0822008-08-26 15:01:29 -0500351
352 fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
353 common_timing_params_t *timing_params = pinfo->common_timing_params;
354
355 /* data bus width capacity adjust shift amount */
356 unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
357
358 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
359 dbw_capacity_adjust[i] = 0;
360 }
361
362 debug("starting at step %u (%s)\n",
363 start_step, step_to_string(start_step));
364
365 switch (start_step) {
366 case STEP_GET_SPD:
York Sune73cc042011-06-07 09:42:16 +0800367#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
Kumar Gala124b0822008-08-26 15:01:29 -0500368 /* STEP 1: Gather all DIMM SPD data */
369 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
370 fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i);
371 }
372
373 case STEP_COMPUTE_DIMM_PARMS:
374 /* STEP 2: Compute DIMM parameters from SPD data */
375
376 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
377 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
378 unsigned int retval;
379 generic_spd_eeprom_t *spd =
380 &(pinfo->spd_installed_dimms[i][j]);
381 dimm_params_t *pdimm =
Wolfgang Denk9dbbd7b2008-09-13 02:23:05 +0200382 &(pinfo->dimm_params[i][j]);
Kumar Gala124b0822008-08-26 15:01:29 -0500383
384 retval = compute_dimm_parameters(spd, pdimm, i);
York Sun09d8aa82011-06-07 09:42:17 +0800385#ifdef CONFIG_SYS_DDR_RAW_TIMING
York Sun11dd8842012-08-17 08:22:42 +0000386 if (!i && !j && retval) {
York Sune8dc17b2012-08-17 08:22:39 +0000387 printf("SPD error on controller %d! "
388 "Trying fallback to raw timing "
389 "calculation\n", i);
York Sun09d8aa82011-06-07 09:42:17 +0800390 fsl_ddr_get_dimm_params(pdimm, i, j);
391 }
392#else
Kumar Gala124b0822008-08-26 15:01:29 -0500393 if (retval == 2) {
394 printf("Error: compute_dimm_parameters"
395 " non-zero returned FATAL value "
396 "for memctl=%u dimm=%u\n", i, j);
397 return 0;
398 }
York Sun09d8aa82011-06-07 09:42:17 +0800399#endif
Kumar Gala124b0822008-08-26 15:01:29 -0500400 if (retval) {
401 debug("Warning: compute_dimm_parameters"
402 " non-zero return value for memctl=%u "
403 "dimm=%u\n", i, j);
404 }
405 }
406 }
407
Shaohui Xie24009042012-06-28 23:36:38 +0000408#elif defined(CONFIG_SYS_DDR_RAW_TIMING)
York Sune73cc042011-06-07 09:42:16 +0800409 case STEP_COMPUTE_DIMM_PARMS:
410 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
411 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
412 dimm_params_t *pdimm =
413 &(pinfo->dimm_params[i][j]);
414 fsl_ddr_get_dimm_params(pdimm, i, j);
415 }
416 }
417 debug("Filling dimm parameters from board specific file\n");
418#endif
Kumar Gala124b0822008-08-26 15:01:29 -0500419 case STEP_COMPUTE_COMMON_PARMS:
420 /*
421 * STEP 3: Compute a common set of timing parameters
422 * suitable for all of the DIMMs on each memory controller
423 */
424 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
425 debug("Computing lowest common DIMM"
426 " parameters for memctl=%u\n", i);
427 compute_lowest_common_dimm_parameters(
428 pinfo->dimm_params[i],
429 &timing_params[i],
430 CONFIG_DIMM_SLOTS_PER_CTLR);
431 }
432
433 case STEP_GATHER_OPTS:
434 /* STEP 4: Gather configuration requirements from user */
435 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
436 debug("Reloading memory controller "
437 "configuration options for memctl=%u\n", i);
438 /*
439 * This "reloads" the memory controller options
440 * to defaults. If the user "edits" an option,
441 * next_step points to the step after this,
442 * which is currently STEP_ASSIGN_ADDRESSES.
443 */
444 populate_memctl_options(
445 timing_params[i].all_DIMMs_registered,
Haiying Wangfa440362008-10-03 12:36:55 -0400446 &pinfo->memctl_opts[i],
447 pinfo->dimm_params[i], i);
Kumar Gala124b0822008-08-26 15:01:29 -0500448 }
Kumar Gala124b0822008-08-26 15:01:29 -0500449 case STEP_ASSIGN_ADDRESSES:
450 /* STEP 5: Assign addresses to chip selects */
York Sune8dc17b2012-08-17 08:22:39 +0000451 check_interleaving_options(pinfo);
452 total_mem = step_assign_addresses(pinfo, dbw_capacity_adjust);
Kumar Gala124b0822008-08-26 15:01:29 -0500453
454 case STEP_COMPUTE_REGS:
455 /* STEP 6: compute controller register values */
York Sune8dc17b2012-08-17 08:22:39 +0000456 debug("FSL Memory ctrl register computation\n");
Kumar Gala124b0822008-08-26 15:01:29 -0500457 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
458 if (timing_params[i].ndimms_present == 0) {
459 memset(&ddr_reg[i], 0,
460 sizeof(fsl_ddr_cfg_regs_t));
461 continue;
462 }
463
464 compute_fsl_memctl_config_regs(
465 &pinfo->memctl_opts[i],
466 &ddr_reg[i], &timing_params[i],
467 pinfo->dimm_params[i],
Haiying Wang80ad4012010-12-01 10:35:31 -0500468 dbw_capacity_adjust[i],
469 size_only);
Kumar Gala124b0822008-08-26 15:01:29 -0500470 }
471
472 default:
473 break;
474 }
475
York Sune8dc17b2012-08-17 08:22:39 +0000476 {
Kumar Gala124b0822008-08-26 15:01:29 -0500477 /*
478 * Compute the amount of memory available just by
479 * looking for the highest valid CSn_BNDS value.
480 * This allows us to also experiment with using
481 * only CS0 when using dual-rank DIMMs.
482 */
483 unsigned int max_end = 0;
484
485 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
486 for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) {
487 fsl_ddr_cfg_regs_t *reg = &ddr_reg[i];
488 if (reg->cs[j].config & 0x80000000) {
489 unsigned int end;
490 end = reg->cs[j].bnds & 0xFFF;
491 if (end > max_end) {
492 max_end = end;
493 }
494 }
495 }
496 }
497
Kumar Gala124b0822008-08-26 15:01:29 -0500498 total_mem = 1 + (((unsigned long long)max_end << 24ULL)
499 | 0xFFFFFFULL);
500 }
501
502 return total_mem;
503}
504
505/*
506 * fsl_ddr_sdram() -- this is the main function to be called by
507 * initdram() in the board file.
508 *
509 * It returns amount of memory configured in bytes.
510 */
511phys_size_t fsl_ddr_sdram(void)
512{
513 unsigned int i;
York Sune8dc17b2012-08-17 08:22:39 +0000514 unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
Kumar Gala68ef4bd2009-06-11 23:42:35 -0500515 unsigned long long total_memory;
Kumar Gala124b0822008-08-26 15:01:29 -0500516 fsl_ddr_info_t info;
517
518 /* Reset info structure. */
519 memset(&info, 0, sizeof(fsl_ddr_info_t));
520
521 /* Compute it once normally. */
York Sunbd495cf2011-09-16 13:21:35 -0700522#ifdef CONFIG_FSL_DDR_INTERACTIVE
523 if (getenv("ddr_interactive"))
524 total_memory = fsl_ddr_interactive(&info);
525 else
526#endif
527 total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0);
Kumar Gala124b0822008-08-26 15:01:29 -0500528
York Sun016095d2012-10-08 07:44:24 +0000529 /* setup 3-way interleaving before enabling DDRC */
530 switch (info.memctl_opts[0].memctl_interleaving_mode) {
531 case FSL_DDR_3WAY_1KB_INTERLEAVING:
532 case FSL_DDR_3WAY_4KB_INTERLEAVING:
533 case FSL_DDR_3WAY_8KB_INTERLEAVING:
534 fsl_ddr_set_intl3r(info.memctl_opts[0].memctl_interleaving_mode);
535 break;
536 default:
537 break;
538 }
539
Kumar Gala124b0822008-08-26 15:01:29 -0500540 /* Program configuration registers. */
541 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
542 debug("Programming controller %u\n", i);
543 if (info.common_timing_params[i].ndimms_present == 0) {
544 debug("No dimms present on controller %u; "
545 "skipping programming\n", i);
546 continue;
547 }
548
549 fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
550 }
551
York Sune8dc17b2012-08-17 08:22:39 +0000552 /* program LAWs */
553 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
554 if (info.memctl_opts[i].memctl_interleaving) {
555 switch (info.memctl_opts[i].memctl_interleaving_mode) {
556 case FSL_DDR_CACHE_LINE_INTERLEAVING:
557 case FSL_DDR_PAGE_INTERLEAVING:
558 case FSL_DDR_BANK_INTERLEAVING:
559 case FSL_DDR_SUPERBANK_INTERLEAVING:
560 if (i == 0) {
561 law_memctl = LAW_TRGT_IF_DDR_INTRLV;
562 fsl_ddr_set_lawbar(&info.common_timing_params[i],
563 law_memctl, i);
564 } else if (i == 2) {
565 law_memctl = LAW_TRGT_IF_DDR_INTLV_34;
566 fsl_ddr_set_lawbar(&info.common_timing_params[i],
567 law_memctl, i);
568 }
569 break;
570 case FSL_DDR_3WAY_1KB_INTERLEAVING:
571 case FSL_DDR_3WAY_4KB_INTERLEAVING:
572 case FSL_DDR_3WAY_8KB_INTERLEAVING:
573 law_memctl = LAW_TRGT_IF_DDR_INTLV_123;
574 if (i == 0) {
York Sune8dc17b2012-08-17 08:22:39 +0000575 fsl_ddr_set_lawbar(&info.common_timing_params[i],
576 law_memctl, i);
577 }
578 break;
579 case FSL_DDR_4WAY_1KB_INTERLEAVING:
580 case FSL_DDR_4WAY_4KB_INTERLEAVING:
581 case FSL_DDR_4WAY_8KB_INTERLEAVING:
582 law_memctl = LAW_TRGT_IF_DDR_INTLV_1234;
583 if (i == 0)
584 fsl_ddr_set_lawbar(&info.common_timing_params[i],
585 law_memctl, i);
586 /* place holder for future 4-way interleaving */
587 break;
588 default:
589 break;
590 }
591 } else {
592 switch (i) {
593 case 0:
594 law_memctl = LAW_TRGT_IF_DDR_1;
595 break;
596 case 1:
597 law_memctl = LAW_TRGT_IF_DDR_2;
598 break;
599 case 2:
600 law_memctl = LAW_TRGT_IF_DDR_3;
601 break;
602 case 3:
603 law_memctl = LAW_TRGT_IF_DDR_4;
604 break;
605 default:
606 break;
607 }
Kumar Gala124b0822008-08-26 15:01:29 -0500608 fsl_ddr_set_lawbar(&info.common_timing_params[i],
York Sune8dc17b2012-08-17 08:22:39 +0000609 law_memctl, i);
Kumar Gala124b0822008-08-26 15:01:29 -0500610 }
611 }
612
York Sune8dc17b2012-08-17 08:22:39 +0000613 debug("total_memory by %s = %llu\n", __func__, total_memory);
Kumar Gala68ef4bd2009-06-11 23:42:35 -0500614
615#if !defined(CONFIG_PHYS_64BIT)
616 /* Check for 4G or more. Bad. */
617 if (total_memory >= (1ull << 32)) {
618 printf("Detected %lld MB of memory\n", total_memory >> 20);
Becky Bruce2d8ecac2010-12-17 17:17:59 -0600619 printf(" This U-Boot only supports < 4G of DDR\n");
620 printf(" You could rebuild it with CONFIG_PHYS_64BIT\n");
621 printf(" "); /* re-align to match init_func_ram print */
Kumar Gala68ef4bd2009-06-11 23:42:35 -0500622 total_memory = CONFIG_MAX_MEM_MAPPED;
623 }
624#endif
Kumar Gala124b0822008-08-26 15:01:29 -0500625
626 return total_memory;
627}
Haiying Wang80ad4012010-12-01 10:35:31 -0500628
629/*
630 * fsl_ddr_sdram_size() - This function only returns the size of the total
631 * memory without setting ddr control registers.
632 */
633phys_size_t
634fsl_ddr_sdram_size(void)
635{
636 fsl_ddr_info_t info;
637 unsigned long long total_memory = 0;
638
639 memset(&info, 0 , sizeof(fsl_ddr_info_t));
640
641 /* Compute it once normally. */
642 total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1);
643
644 return total_memory;
645}