blob: ebf3ed6f388fc38c3a591555fb5bb565a349d847 [file] [log] [blame]
York Sun6f5e1dc2011-09-16 13:21:35 -07001/*
York Sun73b53962012-08-17 08:22:37 +00002 * Copyright 2010-2012 Freescale Semiconductor, Inc.
York Sun6f5e1dc2011-09-16 13:21:35 -07003 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
York Sun6f5e1dc2011-09-16 13:21:35 -07005 */
6
7/*
8 * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
9 * Based on code from spd_sdram.c
10 * Author: James Yang [at freescale.com]
11 * York Sun [at freescale.com]
12 */
13
14#include <common.h>
15#include <linux/ctype.h>
16#include <asm/types.h>
York Sun5614e712013-09-30 09:22:09 -070017#include <asm/io.h>
York Sun6f5e1dc2011-09-16 13:21:35 -070018
York Sun5614e712013-09-30 09:22:09 -070019#include <fsl_ddr_sdram.h>
20#include <fsl_ddr.h>
York Sun6f5e1dc2011-09-16 13:21:35 -070021
22/* Option parameter Structures */
23struct options_string {
24 const char *option_name;
25 size_t offset;
26 unsigned int size;
27 const char printhex;
28};
29
30static unsigned int picos_to_mhz(unsigned int picos)
31{
32 return 1000000 / picos;
33}
34
35static void print_option_table(const struct options_string *table,
36 int table_size,
37 const void *base)
38{
39 unsigned int i;
40 unsigned int *ptr;
41 unsigned long long *ptr_l;
42
43 for (i = 0; i < table_size; i++) {
44 switch (table[i].size) {
45 case 4:
46 ptr = (unsigned int *) (base + table[i].offset);
47 if (table[i].printhex) {
48 printf("%s = 0x%08X\n",
49 table[i].option_name, *ptr);
50 } else {
51 printf("%s = %u\n",
52 table[i].option_name, *ptr);
53 }
54 break;
55 case 8:
56 ptr_l = (unsigned long long *) (base + table[i].offset);
57 printf("%s = %llu\n",
58 table[i].option_name, *ptr_l);
59 break;
60 default:
61 printf("Unrecognized size!\n");
62 break;
63 }
64 }
65}
66
67static int handle_option_table(const struct options_string *table,
68 int table_size,
69 void *base,
70 const char *opt,
71 const char *val)
72{
73 unsigned int i;
74 unsigned int value, *ptr;
75 unsigned long long value_l, *ptr_l;
76
77 for (i = 0; i < table_size; i++) {
78 if (strcmp(table[i].option_name, opt) != 0)
79 continue;
80 switch (table[i].size) {
81 case 4:
82 value = simple_strtoul(val, NULL, 0);
83 ptr = base + table[i].offset;
84 *ptr = value;
85 break;
86 case 8:
87 value_l = simple_strtoull(val, NULL, 0);
88 ptr_l = base + table[i].offset;
89 *ptr_l = value_l;
90 break;
91 default:
92 printf("Unrecognized size!\n");
93 break;
94 }
95 return 1;
96 }
97
98 return 0;
99}
100
101static void fsl_ddr_generic_edit(void *pdata,
102 void *pend,
103 unsigned int element_size,
104 unsigned int element_num,
105 unsigned int value)
106{
107 char *pcdata = (char *)pdata; /* BIG ENDIAN ONLY */
108
109 pcdata += element_num * element_size;
110 if ((pcdata + element_size) > (char *) pend) {
111 printf("trying to write past end of data\n");
112 return;
113 }
114
115 switch (element_size) {
116 case 1:
117 __raw_writeb(value, pcdata);
118 break;
119 case 2:
120 __raw_writew(value, pcdata);
121 break;
122 case 4:
123 __raw_writel(value, pcdata);
124 break;
125 default:
126 printf("unexpected element size %u\n", element_size);
127 break;
128 }
129}
130
131static void fsl_ddr_spd_edit(fsl_ddr_info_t *pinfo,
132 unsigned int ctrl_num,
133 unsigned int dimm_num,
134 unsigned int element_num,
135 unsigned int value)
136{
137 generic_spd_eeprom_t *pspd;
138
139 pspd = &(pinfo->spd_installed_dimms[ctrl_num][dimm_num]);
140 fsl_ddr_generic_edit(pspd, pspd + 1, 1, element_num, value);
141}
142
143#define COMMON_TIMING(x) {#x, offsetof(common_timing_params_t, x), \
144 sizeof((common_timing_params_t *)0)->x, 0}
145
146static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
147 unsigned int ctrl_num,
148 const char *optname_str,
149 const char *value_str)
150{
151 common_timing_params_t *p = &pinfo->common_timing_params[ctrl_num];
152
153 static const struct options_string options[] = {
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530154 COMMON_TIMING(tckmin_x_ps),
155 COMMON_TIMING(tckmax_ps),
156 COMMON_TIMING(tckmax_max_ps),
157 COMMON_TIMING(trcd_ps),
158 COMMON_TIMING(trp_ps),
159 COMMON_TIMING(tras_ps),
160 COMMON_TIMING(twr_ps),
161 COMMON_TIMING(twtr_ps),
162 COMMON_TIMING(trfc_ps),
163 COMMON_TIMING(trrd_ps),
164 COMMON_TIMING(trc_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700165 COMMON_TIMING(refresh_rate_ps),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530166 COMMON_TIMING(tis_ps),
167 COMMON_TIMING(tih_ps),
168 COMMON_TIMING(tds_ps),
169 COMMON_TIMING(tdh_ps),
170 COMMON_TIMING(trtp_ps),
171 COMMON_TIMING(tdqsq_max_ps),
172 COMMON_TIMING(tqhs_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700173 COMMON_TIMING(ndimms_present),
174 COMMON_TIMING(lowest_common_SPD_caslat),
175 COMMON_TIMING(highest_common_derated_caslat),
176 COMMON_TIMING(additive_latency),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530177 COMMON_TIMING(all_dimms_burst_lengths_bitmask),
178 COMMON_TIMING(all_dimms_registered),
179 COMMON_TIMING(all_dimms_unbuffered),
180 COMMON_TIMING(all_dimms_ecc_capable),
York Sun6f5e1dc2011-09-16 13:21:35 -0700181 COMMON_TIMING(total_mem),
182 COMMON_TIMING(base_address),
183 };
184 static const unsigned int n_opts = ARRAY_SIZE(options);
185
186 if (handle_option_table(options, n_opts, p, optname_str, value_str))
187 return;
188
189 printf("Error: couldn't find option string %s\n", optname_str);
190}
191
192#define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \
193 sizeof((dimm_params_t *)0)->x, 0}
194
195static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
196 unsigned int ctrl_num,
197 unsigned int dimm_num,
198 const char *optname_str,
199 const char *value_str)
200{
201 dimm_params_t *p = &(pinfo->dimm_params[ctrl_num][dimm_num]);
202
203 static const struct options_string options[] = {
204 DIMM_PARM(n_ranks),
205 DIMM_PARM(data_width),
206 DIMM_PARM(primary_sdram_width),
207 DIMM_PARM(ec_sdram_width),
208 DIMM_PARM(registered_dimm),
York Sunb61e0612013-06-25 11:37:47 -0700209 DIMM_PARM(device_width),
York Sun6f5e1dc2011-09-16 13:21:35 -0700210
211 DIMM_PARM(n_row_addr),
212 DIMM_PARM(n_col_addr),
213 DIMM_PARM(edc_config),
214 DIMM_PARM(n_banks_per_sdram_device),
215 DIMM_PARM(burst_lengths_bitmask),
216 DIMM_PARM(row_density),
217
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530218 DIMM_PARM(tckmin_x_ps),
219 DIMM_PARM(tckmin_x_minus_1_ps),
220 DIMM_PARM(tckmin_x_minus_2_ps),
221 DIMM_PARM(tckmax_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700222
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530223 DIMM_PARM(caslat_x),
224 DIMM_PARM(caslat_x_minus_1),
225 DIMM_PARM(caslat_x_minus_2),
York Sun6f5e1dc2011-09-16 13:21:35 -0700226
227 DIMM_PARM(caslat_lowest_derated),
228
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530229 DIMM_PARM(trcd_ps),
230 DIMM_PARM(trp_ps),
231 DIMM_PARM(tras_ps),
232 DIMM_PARM(twr_ps),
233 DIMM_PARM(twtr_ps),
234 DIMM_PARM(trfc_ps),
235 DIMM_PARM(trrd_ps),
236 DIMM_PARM(trc_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700237 DIMM_PARM(refresh_rate_ps),
238
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530239 DIMM_PARM(tis_ps),
240 DIMM_PARM(tih_ps),
241 DIMM_PARM(tds_ps),
242 DIMM_PARM(tdh_ps),
243 DIMM_PARM(trtp_ps),
244 DIMM_PARM(tdqsq_max_ps),
245 DIMM_PARM(tqhs_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700246
247 DIMM_PARM(rank_density),
248 DIMM_PARM(capacity),
249 DIMM_PARM(base_address),
250 };
251
252 static const unsigned int n_opts = ARRAY_SIZE(options);
253
254 if (handle_option_table(options, n_opts, p, optname_str, value_str))
255 return;
256
257 printf("couldn't find option string %s\n", optname_str);
258}
259
260static void print_dimm_parameters(const dimm_params_t *pdimm)
261{
262 static const struct options_string options[] = {
263 DIMM_PARM(n_ranks),
264 DIMM_PARM(data_width),
265 DIMM_PARM(primary_sdram_width),
266 DIMM_PARM(ec_sdram_width),
267 DIMM_PARM(registered_dimm),
York Sunb61e0612013-06-25 11:37:47 -0700268 DIMM_PARM(device_width),
York Sun6f5e1dc2011-09-16 13:21:35 -0700269
270 DIMM_PARM(n_row_addr),
271 DIMM_PARM(n_col_addr),
272 DIMM_PARM(edc_config),
273 DIMM_PARM(n_banks_per_sdram_device),
274
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530275 DIMM_PARM(tckmin_x_ps),
276 DIMM_PARM(tckmin_x_minus_1_ps),
277 DIMM_PARM(tckmin_x_minus_2_ps),
278 DIMM_PARM(tckmax_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700279
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530280 DIMM_PARM(caslat_x),
281 DIMM_PARM(taa_ps),
282 DIMM_PARM(caslat_x_minus_1),
283 DIMM_PARM(caslat_x_minus_2),
York Sun6f5e1dc2011-09-16 13:21:35 -0700284 DIMM_PARM(caslat_lowest_derated),
285
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530286 DIMM_PARM(trcd_ps),
287 DIMM_PARM(trp_ps),
288 DIMM_PARM(tras_ps),
289 DIMM_PARM(twr_ps),
290 DIMM_PARM(twtr_ps),
291 DIMM_PARM(trfc_ps),
292 DIMM_PARM(trrd_ps),
293 DIMM_PARM(trc_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700294 DIMM_PARM(refresh_rate_ps),
295
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530296 DIMM_PARM(tis_ps),
297 DIMM_PARM(tih_ps),
298 DIMM_PARM(tds_ps),
299 DIMM_PARM(tdh_ps),
300 DIMM_PARM(trtp_ps),
301 DIMM_PARM(tdqsq_max_ps),
302 DIMM_PARM(tqhs_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700303 };
304 static const unsigned int n_opts = ARRAY_SIZE(options);
305
306 if (pdimm->n_ranks == 0) {
307 printf("DIMM not present\n");
308 return;
309 }
310 printf("DIMM organization parameters:\n");
311 printf("module part name = %s\n", pdimm->mpart);
312 printf("rank_density = %llu bytes (%llu megabytes)\n",
313 pdimm->rank_density, pdimm->rank_density / 0x100000);
314 printf("capacity = %llu bytes (%llu megabytes)\n",
315 pdimm->capacity, pdimm->capacity / 0x100000);
316 printf("burst_lengths_bitmask = %02X\n",
317 pdimm->burst_lengths_bitmask);
318 printf("base_addresss = %llu (%08llX %08llX)\n",
319 pdimm->base_address,
320 (pdimm->base_address >> 32),
321 pdimm->base_address & 0xFFFFFFFF);
322 print_option_table(options, n_opts, pdimm);
323}
324
325static void print_lowest_common_dimm_parameters(
326 const common_timing_params_t *plcd_dimm_params)
327{
328 static const struct options_string options[] = {
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530329 COMMON_TIMING(tckmax_max_ps),
330 COMMON_TIMING(trcd_ps),
331 COMMON_TIMING(trp_ps),
332 COMMON_TIMING(tras_ps),
333 COMMON_TIMING(twr_ps),
334 COMMON_TIMING(twtr_ps),
335 COMMON_TIMING(trfc_ps),
336 COMMON_TIMING(trrd_ps),
337 COMMON_TIMING(trc_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700338 COMMON_TIMING(refresh_rate_ps),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530339 COMMON_TIMING(tis_ps),
340 COMMON_TIMING(tds_ps),
341 COMMON_TIMING(tdh_ps),
342 COMMON_TIMING(trtp_ps),
343 COMMON_TIMING(tdqsq_max_ps),
344 COMMON_TIMING(tqhs_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700345 COMMON_TIMING(lowest_common_SPD_caslat),
346 COMMON_TIMING(highest_common_derated_caslat),
347 COMMON_TIMING(additive_latency),
348 COMMON_TIMING(ndimms_present),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530349 COMMON_TIMING(all_dimms_registered),
350 COMMON_TIMING(all_dimms_unbuffered),
351 COMMON_TIMING(all_dimms_ecc_capable),
York Sun6f5e1dc2011-09-16 13:21:35 -0700352 };
353 static const unsigned int n_opts = ARRAY_SIZE(options);
354
355 /* Clock frequencies */
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530356 printf("tckmin_x_ps = %u (%u MHz)\n",
357 plcd_dimm_params->tckmin_x_ps,
358 picos_to_mhz(plcd_dimm_params->tckmin_x_ps));
359 printf("tckmax_ps = %u (%u MHz)\n",
360 plcd_dimm_params->tckmax_ps,
361 picos_to_mhz(plcd_dimm_params->tckmax_ps));
362 printf("all_dimms_burst_lengths_bitmask = %02X\n",
363 plcd_dimm_params->all_dimms_burst_lengths_bitmask);
York Sun6f5e1dc2011-09-16 13:21:35 -0700364
365 print_option_table(options, n_opts, plcd_dimm_params);
366
367 printf("total_mem = %llu (%llu megabytes)\n",
368 plcd_dimm_params->total_mem,
369 plcd_dimm_params->total_mem / 0x100000);
370 printf("base_address = %llu (%llu megabytes)\n",
371 plcd_dimm_params->base_address,
372 plcd_dimm_params->base_address / 0x100000);
373}
374
375#define CTRL_OPTIONS(x) {#x, offsetof(memctl_options_t, x), \
376 sizeof((memctl_options_t *)0)->x, 0}
377#define CTRL_OPTIONS_CS(x, y) {"cs" #x "_" #y, \
378 offsetof(memctl_options_t, cs_local_opts[x].y), \
379 sizeof((memctl_options_t *)0)->cs_local_opts[x].y, 0}
380
381static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
382 unsigned int ctl_num,
383 const char *optname_str,
384 const char *value_str)
385{
386 memctl_options_t *p = &(pinfo->memctl_opts[ctl_num]);
387 /*
388 * This array all on the stack and *computed* each time this
389 * function is rung.
390 */
391 static const struct options_string options[] = {
392 CTRL_OPTIONS_CS(0, odt_rd_cfg),
393 CTRL_OPTIONS_CS(0, odt_wr_cfg),
394#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
395 CTRL_OPTIONS_CS(1, odt_rd_cfg),
396 CTRL_OPTIONS_CS(1, odt_wr_cfg),
397#endif
398#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
399 CTRL_OPTIONS_CS(2, odt_rd_cfg),
400 CTRL_OPTIONS_CS(2, odt_wr_cfg),
401#endif
402#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
403 CTRL_OPTIONS_CS(3, odt_rd_cfg),
404 CTRL_OPTIONS_CS(3, odt_wr_cfg),
405#endif
York Sun5614e712013-09-30 09:22:09 -0700406#if defined(CONFIG_SYS_FSL_DDR3)
York Sun6f5e1dc2011-09-16 13:21:35 -0700407 CTRL_OPTIONS_CS(0, odt_rtt_norm),
408 CTRL_OPTIONS_CS(0, odt_rtt_wr),
409#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
410 CTRL_OPTIONS_CS(1, odt_rtt_norm),
411 CTRL_OPTIONS_CS(1, odt_rtt_wr),
412#endif
413#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
414 CTRL_OPTIONS_CS(2, odt_rtt_norm),
415 CTRL_OPTIONS_CS(2, odt_rtt_wr),
416#endif
417#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
418 CTRL_OPTIONS_CS(3, odt_rtt_norm),
419 CTRL_OPTIONS_CS(3, odt_rtt_wr),
420#endif
421#endif
422 CTRL_OPTIONS(memctl_interleaving),
423 CTRL_OPTIONS(memctl_interleaving_mode),
424 CTRL_OPTIONS(ba_intlv_ctl),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530425 CTRL_OPTIONS(ecc_mode),
426 CTRL_OPTIONS(ecc_init_using_memctl),
427 CTRL_OPTIONS(dqs_config),
York Sun6f5e1dc2011-09-16 13:21:35 -0700428 CTRL_OPTIONS(self_refresh_in_sleep),
429 CTRL_OPTIONS(dynamic_power),
430 CTRL_OPTIONS(data_bus_width),
431 CTRL_OPTIONS(burst_length),
432 CTRL_OPTIONS(cas_latency_override),
433 CTRL_OPTIONS(cas_latency_override_value),
434 CTRL_OPTIONS(use_derated_caslat),
435 CTRL_OPTIONS(additive_latency_override),
436 CTRL_OPTIONS(additive_latency_override_value),
437 CTRL_OPTIONS(clk_adjust),
438 CTRL_OPTIONS(cpo_override),
439 CTRL_OPTIONS(write_data_delay),
440 CTRL_OPTIONS(half_strength_driver_enable),
441
442 /*
443 * These can probably be changed to 2T_EN and 3T_EN
444 * (using a leading numerical character) without problem
445 */
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530446 CTRL_OPTIONS(twot_en),
447 CTRL_OPTIONS(threet_en),
York Sun6f5e1dc2011-09-16 13:21:35 -0700448 CTRL_OPTIONS(ap_en),
York Sunb61e0612013-06-25 11:37:47 -0700449 CTRL_OPTIONS(x4_en),
York Sun6f5e1dc2011-09-16 13:21:35 -0700450 CTRL_OPTIONS(bstopre),
451 CTRL_OPTIONS(wrlvl_override),
452 CTRL_OPTIONS(wrlvl_sample),
453 CTRL_OPTIONS(wrlvl_start),
454 CTRL_OPTIONS(rcw_override),
455 CTRL_OPTIONS(rcw_1),
456 CTRL_OPTIONS(rcw_2),
York Sun57495e42012-10-08 07:44:22 +0000457 CTRL_OPTIONS(ddr_cdr1),
458 CTRL_OPTIONS(ddr_cdr2),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530459 CTRL_OPTIONS(tcke_clock_pulse_width_ps),
460 CTRL_OPTIONS(tfaw_window_four_activates_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700461 CTRL_OPTIONS(trwt_override),
462 CTRL_OPTIONS(trwt),
463 };
464
465 static const unsigned int n_opts = ARRAY_SIZE(options);
466
467 if (handle_option_table(options, n_opts, p,
468 optname_str, value_str))
469 return;
470
471 printf("couldn't find option string %s\n", optname_str);
472}
473
474#define CFG_REGS(x) {#x, offsetof(fsl_ddr_cfg_regs_t, x), \
475 sizeof((fsl_ddr_cfg_regs_t *)0)->x, 1}
476#define CFG_REGS_CS(x, y) {"cs" #x "_" #y, \
477 offsetof(fsl_ddr_cfg_regs_t, cs[x].y), \
478 sizeof((fsl_ddr_cfg_regs_t *)0)->cs[x].y, 1}
479
480static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
481{
482 unsigned int i;
483 static const struct options_string options[] = {
484 CFG_REGS_CS(0, bnds),
485 CFG_REGS_CS(0, config),
486 CFG_REGS_CS(0, config_2),
487#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
488 CFG_REGS_CS(1, bnds),
489 CFG_REGS_CS(1, config),
490 CFG_REGS_CS(1, config_2),
491#endif
492#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
493 CFG_REGS_CS(2, bnds),
494 CFG_REGS_CS(2, config),
495 CFG_REGS_CS(2, config_2),
496#endif
497#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
498 CFG_REGS_CS(3, bnds),
499 CFG_REGS_CS(3, config),
500 CFG_REGS_CS(3, config_2),
501#endif
502 CFG_REGS(timing_cfg_3),
503 CFG_REGS(timing_cfg_0),
504 CFG_REGS(timing_cfg_1),
505 CFG_REGS(timing_cfg_2),
506 CFG_REGS(ddr_sdram_cfg),
507 CFG_REGS(ddr_sdram_cfg_2),
508 CFG_REGS(ddr_sdram_mode),
509 CFG_REGS(ddr_sdram_mode_2),
510 CFG_REGS(ddr_sdram_mode_3),
511 CFG_REGS(ddr_sdram_mode_4),
512 CFG_REGS(ddr_sdram_mode_5),
513 CFG_REGS(ddr_sdram_mode_6),
514 CFG_REGS(ddr_sdram_mode_7),
515 CFG_REGS(ddr_sdram_mode_8),
516 CFG_REGS(ddr_sdram_interval),
517 CFG_REGS(ddr_data_init),
518 CFG_REGS(ddr_sdram_clk_cntl),
519 CFG_REGS(ddr_init_addr),
520 CFG_REGS(ddr_init_ext_addr),
521 CFG_REGS(timing_cfg_4),
522 CFG_REGS(timing_cfg_5),
523 CFG_REGS(ddr_zq_cntl),
524 CFG_REGS(ddr_wrlvl_cntl),
York Sun57495e42012-10-08 07:44:22 +0000525 CFG_REGS(ddr_wrlvl_cntl_2),
526 CFG_REGS(ddr_wrlvl_cntl_3),
York Sun6f5e1dc2011-09-16 13:21:35 -0700527 CFG_REGS(ddr_sr_cntr),
528 CFG_REGS(ddr_sdram_rcw_1),
529 CFG_REGS(ddr_sdram_rcw_2),
530 CFG_REGS(ddr_cdr1),
531 CFG_REGS(ddr_cdr2),
532 CFG_REGS(err_disable),
533 CFG_REGS(err_int_en),
York Sun57495e42012-10-08 07:44:22 +0000534 CFG_REGS(ddr_eor),
York Sun6f5e1dc2011-09-16 13:21:35 -0700535 };
536 static const unsigned int n_opts = ARRAY_SIZE(options);
537
538 print_option_table(options, n_opts, ddr);
539
540 for (i = 0; i < 32; i++)
541 printf("debug_%02d = 0x%08X\n", i+1, ddr->debug[i]);
542}
543
544static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
545 unsigned int ctrl_num,
546 const char *regname,
547 const char *value_str)
548{
549 unsigned int i;
550 fsl_ddr_cfg_regs_t *ddr;
551 char buf[20];
552 static const struct options_string options[] = {
553 CFG_REGS_CS(0, bnds),
554 CFG_REGS_CS(0, config),
555 CFG_REGS_CS(0, config_2),
556#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
557 CFG_REGS_CS(1, bnds),
558 CFG_REGS_CS(1, config),
559 CFG_REGS_CS(1, config_2),
560#endif
561#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
562 CFG_REGS_CS(2, bnds),
563 CFG_REGS_CS(2, config),
564 CFG_REGS_CS(2, config_2),
565#endif
566#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
567 CFG_REGS_CS(3, bnds),
568 CFG_REGS_CS(3, config),
569 CFG_REGS_CS(3, config_2),
570#endif
571 CFG_REGS(timing_cfg_3),
572 CFG_REGS(timing_cfg_0),
573 CFG_REGS(timing_cfg_1),
574 CFG_REGS(timing_cfg_2),
575 CFG_REGS(ddr_sdram_cfg),
576 CFG_REGS(ddr_sdram_cfg_2),
577 CFG_REGS(ddr_sdram_mode),
578 CFG_REGS(ddr_sdram_mode_2),
579 CFG_REGS(ddr_sdram_mode_3),
580 CFG_REGS(ddr_sdram_mode_4),
581 CFG_REGS(ddr_sdram_mode_5),
582 CFG_REGS(ddr_sdram_mode_6),
583 CFG_REGS(ddr_sdram_mode_7),
584 CFG_REGS(ddr_sdram_mode_8),
585 CFG_REGS(ddr_sdram_interval),
586 CFG_REGS(ddr_data_init),
587 CFG_REGS(ddr_sdram_clk_cntl),
588 CFG_REGS(ddr_init_addr),
589 CFG_REGS(ddr_init_ext_addr),
590 CFG_REGS(timing_cfg_4),
591 CFG_REGS(timing_cfg_5),
592 CFG_REGS(ddr_zq_cntl),
593 CFG_REGS(ddr_wrlvl_cntl),
York Sun57495e42012-10-08 07:44:22 +0000594 CFG_REGS(ddr_wrlvl_cntl_2),
595 CFG_REGS(ddr_wrlvl_cntl_3),
York Sun6f5e1dc2011-09-16 13:21:35 -0700596 CFG_REGS(ddr_sr_cntr),
597 CFG_REGS(ddr_sdram_rcw_1),
598 CFG_REGS(ddr_sdram_rcw_2),
599 CFG_REGS(ddr_cdr1),
600 CFG_REGS(ddr_cdr2),
601 CFG_REGS(err_disable),
602 CFG_REGS(err_int_en),
603 CFG_REGS(ddr_sdram_rcw_2),
604 CFG_REGS(ddr_sdram_rcw_2),
York Sun57495e42012-10-08 07:44:22 +0000605 CFG_REGS(ddr_eor),
York Sun6f5e1dc2011-09-16 13:21:35 -0700606 };
607 static const unsigned int n_opts = ARRAY_SIZE(options);
608
609 debug("fsl_ddr_regs_edit: ctrl_num = %u, "
610 "regname = %s, value = %s\n",
611 ctrl_num, regname, value_str);
612 if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS)
613 return;
614
615 ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]);
616
617 if (handle_option_table(options, n_opts, ddr, regname, value_str))
618 return;
619
620 for (i = 0; i < 32; i++) {
621 unsigned int value = simple_strtoul(value_str, NULL, 0);
622 sprintf(buf, "debug_%u", i + 1);
623 if (strcmp(buf, regname) == 0) {
624 ddr->debug[i] = value;
625 return;
626 }
627 }
628 printf("Error: couldn't find register string %s\n", regname);
629}
630
631#define CTRL_OPTIONS_HEX(x) {#x, offsetof(memctl_options_t, x), \
632 sizeof((memctl_options_t *)0)->x, 1}
633
634static void print_memctl_options(const memctl_options_t *popts)
635{
636 static const struct options_string options[] = {
637 CTRL_OPTIONS_CS(0, odt_rd_cfg),
638 CTRL_OPTIONS_CS(0, odt_wr_cfg),
639#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
640 CTRL_OPTIONS_CS(1, odt_rd_cfg),
641 CTRL_OPTIONS_CS(1, odt_wr_cfg),
642#endif
643#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
644 CTRL_OPTIONS_CS(2, odt_rd_cfg),
645 CTRL_OPTIONS_CS(2, odt_wr_cfg),
646#endif
647#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
648 CTRL_OPTIONS_CS(3, odt_rd_cfg),
649 CTRL_OPTIONS_CS(3, odt_wr_cfg),
650#endif
York Sun5614e712013-09-30 09:22:09 -0700651#if defined(CONFIG_SYS_FSL_DDR3)
York Sun6f5e1dc2011-09-16 13:21:35 -0700652 CTRL_OPTIONS_CS(0, odt_rtt_norm),
653 CTRL_OPTIONS_CS(0, odt_rtt_wr),
654#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
655 CTRL_OPTIONS_CS(1, odt_rtt_norm),
656 CTRL_OPTIONS_CS(1, odt_rtt_wr),
657#endif
658#if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
659 CTRL_OPTIONS_CS(2, odt_rtt_norm),
660 CTRL_OPTIONS_CS(2, odt_rtt_wr),
661#endif
662#if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
663 CTRL_OPTIONS_CS(3, odt_rtt_norm),
664 CTRL_OPTIONS_CS(3, odt_rtt_wr),
665#endif
666#endif
667 CTRL_OPTIONS(memctl_interleaving),
668 CTRL_OPTIONS(memctl_interleaving_mode),
669 CTRL_OPTIONS_HEX(ba_intlv_ctl),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530670 CTRL_OPTIONS(ecc_mode),
671 CTRL_OPTIONS(ecc_init_using_memctl),
672 CTRL_OPTIONS(dqs_config),
York Sun6f5e1dc2011-09-16 13:21:35 -0700673 CTRL_OPTIONS(self_refresh_in_sleep),
674 CTRL_OPTIONS(dynamic_power),
675 CTRL_OPTIONS(data_bus_width),
676 CTRL_OPTIONS(burst_length),
677 CTRL_OPTIONS(cas_latency_override),
678 CTRL_OPTIONS(cas_latency_override_value),
679 CTRL_OPTIONS(use_derated_caslat),
680 CTRL_OPTIONS(additive_latency_override),
681 CTRL_OPTIONS(additive_latency_override_value),
682 CTRL_OPTIONS(clk_adjust),
683 CTRL_OPTIONS(cpo_override),
684 CTRL_OPTIONS(write_data_delay),
685 CTRL_OPTIONS(half_strength_driver_enable),
686 /*
687 * These can probably be changed to 2T_EN and 3T_EN
688 * (using a leading numerical character) without problem
689 */
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530690 CTRL_OPTIONS(twot_en),
691 CTRL_OPTIONS(threet_en),
York Sun6f5e1dc2011-09-16 13:21:35 -0700692 CTRL_OPTIONS(registered_dimm_en),
693 CTRL_OPTIONS(ap_en),
York Sunb61e0612013-06-25 11:37:47 -0700694 CTRL_OPTIONS(x4_en),
York Sun6f5e1dc2011-09-16 13:21:35 -0700695 CTRL_OPTIONS(bstopre),
696 CTRL_OPTIONS(wrlvl_override),
697 CTRL_OPTIONS(wrlvl_sample),
698 CTRL_OPTIONS(wrlvl_start),
699 CTRL_OPTIONS(rcw_override),
700 CTRL_OPTIONS(rcw_1),
701 CTRL_OPTIONS(rcw_2),
York Sun57495e42012-10-08 07:44:22 +0000702 CTRL_OPTIONS_HEX(ddr_cdr1),
703 CTRL_OPTIONS_HEX(ddr_cdr2),
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530704 CTRL_OPTIONS(tcke_clock_pulse_width_ps),
705 CTRL_OPTIONS(tfaw_window_four_activates_ps),
York Sun6f5e1dc2011-09-16 13:21:35 -0700706 CTRL_OPTIONS(trwt_override),
707 CTRL_OPTIONS(trwt),
708 };
709 static const unsigned int n_opts = ARRAY_SIZE(options);
710
711 print_option_table(options, n_opts, popts);
712}
713
York Sun5614e712013-09-30 09:22:09 -0700714#ifdef CONFIG_SYS_FSL_DDR1
York Sun6f5e1dc2011-09-16 13:21:35 -0700715void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd)
716{
717 unsigned int i;
718
719 printf("%-3d : %02x %s\n", 0, spd->info_size,
720 " spd->info_size, * 0 # bytes written into serial memory *");
721 printf("%-3d : %02x %s\n", 1, spd->chip_size,
722 " spd->chip_size, * 1 Total # bytes of SPD memory device *");
723 printf("%-3d : %02x %s\n", 2, spd->mem_type,
724 " spd->mem_type, * 2 Fundamental memory type *");
725 printf("%-3d : %02x %s\n", 3, spd->nrow_addr,
726 " spd->nrow_addr, * 3 # of Row Addresses on this assembly *");
727 printf("%-3d : %02x %s\n", 4, spd->ncol_addr,
728 " spd->ncol_addr, * 4 # of Column Addrs on this assembly *");
729 printf("%-3d : %02x %s\n", 5, spd->nrows,
730 " spd->nrows * 5 # of DIMM Banks *");
731 printf("%-3d : %02x %s\n", 6, spd->dataw_lsb,
732 " spd->dataw_lsb, * 6 Data Width lsb of this assembly *");
733 printf("%-3d : %02x %s\n", 7, spd->dataw_msb,
734 " spd->dataw_msb, * 7 Data Width msb of this assembly *");
735 printf("%-3d : %02x %s\n", 8, spd->voltage,
736 " spd->voltage, * 8 Voltage intf std of this assembly *");
737 printf("%-3d : %02x %s\n", 9, spd->clk_cycle,
738 " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *");
739 printf("%-3d : %02x %s\n", 10, spd->clk_access,
740 " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *");
741 printf("%-3d : %02x %s\n", 11, spd->config,
742 " spd->config, * 11 DIMM Configuration type *");
743 printf("%-3d : %02x %s\n", 12, spd->refresh,
744 " spd->refresh, * 12 Refresh Rate/Type *");
745 printf("%-3d : %02x %s\n", 13, spd->primw,
746 " spd->primw, * 13 Primary SDRAM Width *");
747 printf("%-3d : %02x %s\n", 14, spd->ecw,
748 " spd->ecw, * 14 Error Checking SDRAM width *");
749 printf("%-3d : %02x %s\n", 15, spd->min_delay,
750 " spd->min_delay, * 15 Back to Back Random Access *");
751 printf("%-3d : %02x %s\n", 16, spd->burstl,
752 " spd->burstl, * 16 Burst Lengths Supported *");
753 printf("%-3d : %02x %s\n", 17, spd->nbanks,
754 " spd->nbanks, * 17 # of Banks on Each SDRAM Device *");
755 printf("%-3d : %02x %s\n", 18, spd->cas_lat,
756 " spd->cas_lat, * 18 CAS# Latencies Supported *");
757 printf("%-3d : %02x %s\n", 19, spd->cs_lat,
758 " spd->cs_lat, * 19 Chip Select Latency *");
759 printf("%-3d : %02x %s\n", 20, spd->write_lat,
760 " spd->write_lat, * 20 Write Latency/Recovery *");
761 printf("%-3d : %02x %s\n", 21, spd->mod_attr,
762 " spd->mod_attr, * 21 SDRAM Module Attributes *");
763 printf("%-3d : %02x %s\n", 22, spd->dev_attr,
764 " spd->dev_attr, * 22 SDRAM Device Attributes *");
765 printf("%-3d : %02x %s\n", 23, spd->clk_cycle2,
766 " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *");
767 printf("%-3d : %02x %s\n", 24, spd->clk_access2,
768 " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
769 printf("%-3d : %02x %s\n", 25, spd->clk_cycle3,
770 " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *");
771 printf("%-3d : %02x %s\n", 26, spd->clk_access3,
772 " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
773 printf("%-3d : %02x %s\n", 27, spd->trp,
774 " spd->trp, * 27 Min Row Precharge Time (tRP)*");
775 printf("%-3d : %02x %s\n", 28, spd->trrd,
776 " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *");
777 printf("%-3d : %02x %s\n", 29, spd->trcd,
778 " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *");
779 printf("%-3d : %02x %s\n", 30, spd->tras,
780 " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *");
781 printf("%-3d : %02x %s\n", 31, spd->bank_dens,
782 " spd->bank_dens, * 31 Density of each bank on module *");
783 printf("%-3d : %02x %s\n", 32, spd->ca_setup,
784 " spd->ca_setup, * 32 Cmd + Addr signal input setup time *");
785 printf("%-3d : %02x %s\n", 33, spd->ca_hold,
786 " spd->ca_hold, * 33 Cmd and Addr signal input hold time *");
787 printf("%-3d : %02x %s\n", 34, spd->data_setup,
788 " spd->data_setup, * 34 Data signal input setup time *");
789 printf("%-3d : %02x %s\n", 35, spd->data_hold,
790 " spd->data_hold, * 35 Data signal input hold time *");
791 printf("%-3d : %02x %s\n", 36, spd->res_36_40[0],
792 " spd->res_36_40[0], * 36 Reserved / tWR *");
793 printf("%-3d : %02x %s\n", 37, spd->res_36_40[1],
794 " spd->res_36_40[1], * 37 Reserved / tWTR *");
795 printf("%-3d : %02x %s\n", 38, spd->res_36_40[2],
796 " spd->res_36_40[2], * 38 Reserved / tRTP *");
797 printf("%-3d : %02x %s\n", 39, spd->res_36_40[3],
798 " spd->res_36_40[3], * 39 Reserved / mem_probe *");
799 printf("%-3d : %02x %s\n", 40, spd->res_36_40[4],
800 " spd->res_36_40[4], * 40 Reserved / trc,trfc extensions *");
801 printf("%-3d : %02x %s\n", 41, spd->trc,
802 " spd->trc, * 41 Min Active to Auto refresh time tRC *");
803 printf("%-3d : %02x %s\n", 42, spd->trfc,
804 " spd->trfc, * 42 Min Auto to Active period tRFC *");
805 printf("%-3d : %02x %s\n", 43, spd->tckmax,
806 " spd->tckmax, * 43 Max device cycle time tCKmax *");
807 printf("%-3d : %02x %s\n", 44, spd->tdqsq,
808 " spd->tdqsq, * 44 Max DQS to DQ skew *");
809 printf("%-3d : %02x %s\n", 45, spd->tqhs,
810 " spd->tqhs, * 45 Max Read DataHold skew tQHS *");
811 printf("%-3d : %02x %s\n", 46, spd->res_46,
812 " spd->res_46, * 46 Reserved/ PLL Relock time *");
813 printf("%-3d : %02x %s\n", 47, spd->dimm_height,
814 " spd->dimm_height * 47 SDRAM DIMM Height *");
815
816 printf("%-3d-%3d: ", 48, 61);
817
818 for (i = 0; i < 14; i++)
819 printf("%02x", spd->res_48_61[i]);
820
821 printf(" * 48-61 IDD in SPD and Reserved space *\n");
822
823 printf("%-3d : %02x %s\n", 62, spd->spd_rev,
824 " spd->spd_rev, * 62 SPD Data Revision Code *");
825 printf("%-3d : %02x %s\n", 63, spd->cksum,
826 " spd->cksum, * 63 Checksum for bytes 0-62 *");
827 printf("%-3d-%3d: ", 64, 71);
828
829 for (i = 0; i < 8; i++)
830 printf("%02x", spd->mid[i]);
831
832 printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
833 printf("%-3d : %02x %s\n", 72, spd->mloc,
834 " spd->mloc, * 72 Manufacturing Location *");
835
836 printf("%-3d-%3d: >>", 73, 90);
837
838 for (i = 0; i < 18; i++)
839 printf("%c", spd->mpart[i]);
840
841 printf("<<* 73 Manufacturer's Part Number *\n");
842
843 printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1],
844 "* 91 Revision Code *");
845 printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1],
846 "* 93 Manufacturing Date *");
847 printf("%-3d-%3d: ", 95, 98);
848
849 for (i = 0; i < 4; i++)
850 printf("%02x", spd->sernum[i]);
851
852 printf("* 95 Assembly Serial Number *\n");
853
854 printf("%-3d-%3d: ", 99, 127);
855
856 for (i = 0; i < 27; i++)
857 printf("%02x", spd->mspec[i]);
858
859 printf("* 99 Manufacturer Specific Data *\n");
860}
861#endif
862
York Sun5614e712013-09-30 09:22:09 -0700863#ifdef CONFIG_SYS_FSL_DDR2
York Sun6f5e1dc2011-09-16 13:21:35 -0700864void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd)
865{
866 unsigned int i;
867
868 printf("%-3d : %02x %s\n", 0, spd->info_size,
869 " spd->info_size, * 0 # bytes written into serial memory *");
870 printf("%-3d : %02x %s\n", 1, spd->chip_size,
871 " spd->chip_size, * 1 Total # bytes of SPD memory device *");
872 printf("%-3d : %02x %s\n", 2, spd->mem_type,
873 " spd->mem_type, * 2 Fundamental memory type *");
874 printf("%-3d : %02x %s\n", 3, spd->nrow_addr,
875 " spd->nrow_addr, * 3 # of Row Addresses on this assembly *");
876 printf("%-3d : %02x %s\n", 4, spd->ncol_addr,
877 " spd->ncol_addr, * 4 # of Column Addrs on this assembly *");
878 printf("%-3d : %02x %s\n", 5, spd->mod_ranks,
879 " spd->mod_ranks * 5 # of Module Rows on this assembly *");
880 printf("%-3d : %02x %s\n", 6, spd->dataw,
881 " spd->dataw, * 6 Data Width of this assembly *");
882 printf("%-3d : %02x %s\n", 7, spd->res_7,
883 " spd->res_7, * 7 Reserved *");
884 printf("%-3d : %02x %s\n", 8, spd->voltage,
885 " spd->voltage, * 8 Voltage intf std of this assembly *");
886 printf("%-3d : %02x %s\n", 9, spd->clk_cycle,
887 " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *");
888 printf("%-3d : %02x %s\n", 10, spd->clk_access,
889 " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *");
890 printf("%-3d : %02x %s\n", 11, spd->config,
891 " spd->config, * 11 DIMM Configuration type *");
892 printf("%-3d : %02x %s\n", 12, spd->refresh,
893 " spd->refresh, * 12 Refresh Rate/Type *");
894 printf("%-3d : %02x %s\n", 13, spd->primw,
895 " spd->primw, * 13 Primary SDRAM Width *");
896 printf("%-3d : %02x %s\n", 14, spd->ecw,
897 " spd->ecw, * 14 Error Checking SDRAM width *");
898 printf("%-3d : %02x %s\n", 15, spd->res_15,
899 " spd->res_15, * 15 Reserved *");
900 printf("%-3d : %02x %s\n", 16, spd->burstl,
901 " spd->burstl, * 16 Burst Lengths Supported *");
902 printf("%-3d : %02x %s\n", 17, spd->nbanks,
903 " spd->nbanks, * 17 # of Banks on Each SDRAM Device *");
904 printf("%-3d : %02x %s\n", 18, spd->cas_lat,
905 " spd->cas_lat, * 18 CAS# Latencies Supported *");
906 printf("%-3d : %02x %s\n", 19, spd->mech_char,
907 " spd->mech_char, * 19 Mechanical Characteristics *");
908 printf("%-3d : %02x %s\n", 20, spd->dimm_type,
909 " spd->dimm_type, * 20 DIMM type *");
910 printf("%-3d : %02x %s\n", 21, spd->mod_attr,
911 " spd->mod_attr, * 21 SDRAM Module Attributes *");
912 printf("%-3d : %02x %s\n", 22, spd->dev_attr,
913 " spd->dev_attr, * 22 SDRAM Device Attributes *");
914 printf("%-3d : %02x %s\n", 23, spd->clk_cycle2,
915 " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *");
916 printf("%-3d : %02x %s\n", 24, spd->clk_access2,
917 " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
918 printf("%-3d : %02x %s\n", 25, spd->clk_cycle3,
919 " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *");
920 printf("%-3d : %02x %s\n", 26, spd->clk_access3,
921 " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
922 printf("%-3d : %02x %s\n", 27, spd->trp,
923 " spd->trp, * 27 Min Row Precharge Time (tRP)*");
924 printf("%-3d : %02x %s\n", 28, spd->trrd,
925 " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *");
926 printf("%-3d : %02x %s\n", 29, spd->trcd,
927 " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *");
928 printf("%-3d : %02x %s\n", 30, spd->tras,
929 " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *");
930 printf("%-3d : %02x %s\n", 31, spd->rank_dens,
931 " spd->rank_dens, * 31 Density of each rank on module *");
932 printf("%-3d : %02x %s\n", 32, spd->ca_setup,
933 " spd->ca_setup, * 32 Cmd + Addr signal input setup time *");
934 printf("%-3d : %02x %s\n", 33, spd->ca_hold,
935 " spd->ca_hold, * 33 Cmd and Addr signal input hold time *");
936 printf("%-3d : %02x %s\n", 34, spd->data_setup,
937 " spd->data_setup, * 34 Data signal input setup time *");
938 printf("%-3d : %02x %s\n", 35, spd->data_hold,
939 " spd->data_hold, * 35 Data signal input hold time *");
940 printf("%-3d : %02x %s\n", 36, spd->twr,
941 " spd->twr, * 36 Write Recovery time tWR *");
942 printf("%-3d : %02x %s\n", 37, spd->twtr,
943 " spd->twtr, * 37 Int write to read delay tWTR *");
944 printf("%-3d : %02x %s\n", 38, spd->trtp,
945 " spd->trtp, * 38 Int read to precharge delay tRTP *");
946 printf("%-3d : %02x %s\n", 39, spd->mem_probe,
947 " spd->mem_probe, * 39 Mem analysis probe characteristics *");
948 printf("%-3d : %02x %s\n", 40, spd->trctrfc_ext,
949 " spd->trctrfc_ext, * 40 Extensions to trc and trfc *");
950 printf("%-3d : %02x %s\n", 41, spd->trc,
951 " spd->trc, * 41 Min Active to Auto refresh time tRC *");
952 printf("%-3d : %02x %s\n", 42, spd->trfc,
953 " spd->trfc, * 42 Min Auto to Active period tRFC *");
954 printf("%-3d : %02x %s\n", 43, spd->tckmax,
955 " spd->tckmax, * 43 Max device cycle time tCKmax *");
956 printf("%-3d : %02x %s\n", 44, spd->tdqsq,
957 " spd->tdqsq, * 44 Max DQS to DQ skew *");
958 printf("%-3d : %02x %s\n", 45, spd->tqhs,
959 " spd->tqhs, * 45 Max Read DataHold skew tQHS *");
960 printf("%-3d : %02x %s\n", 46, spd->pll_relock,
961 " spd->pll_relock, * 46 PLL Relock time *");
Priyanka Jain0dd38a32013-09-25 10:41:19 +0530962 printf("%-3d : %02x %s\n", 47, spd->t_casemax,
963 " spd->t_casemax, * 47 t_casemax *");
964 printf("%-3d : %02x %s\n", 48, spd->psi_ta_dram,
965 " spd->psi_ta_dram, * 48 Thermal Resistance of DRAM Package "
York Sun6f5e1dc2011-09-16 13:21:35 -0700966 "from Top (Case) to Ambient (Psi T-A DRAM) *");
967 printf("%-3d : %02x %s\n", 49, spd->dt0_mode,
968 " spd->dt0_mode, * 49 DRAM Case Temperature Rise from "
969 "Ambient due to Activate-Precharge/Mode Bits "
970 "(DT0/Mode Bits) *)");
971 printf("%-3d : %02x %s\n", 50, spd->dt2n_dt2q,
972 " spd->dt2n_dt2q, * 50 DRAM Case Temperature Rise from "
973 "Ambient due to Precharge/Quiet Standby "
974 "(DT2N/DT2Q) *");
975 printf("%-3d : %02x %s\n", 51, spd->dt2p,
976 " spd->dt2p, * 51 DRAM Case Temperature Rise from "
977 "Ambient due to Precharge Power-Down (DT2P) *");
978 printf("%-3d : %02x %s\n", 52, spd->dt3n,
979 " spd->dt3n, * 52 DRAM Case Temperature Rise from "
980 "Ambient due to Active Standby (DT3N) *");
981 printf("%-3d : %02x %s\n", 53, spd->dt3pfast,
982 " spd->dt3pfast, * 53 DRAM Case Temperature Rise from "
983 "Ambient due to Active Power-Down with Fast PDN Exit "
984 "(DT3Pfast) *");
985 printf("%-3d : %02x %s\n", 54, spd->dt3pslow,
986 " spd->dt3pslow, * 54 DRAM Case Temperature Rise from "
987 "Ambient due to Active Power-Down with Slow PDN Exit "
988 "(DT3Pslow) *");
989 printf("%-3d : %02x %s\n", 55, spd->dt4r_dt4r4w,
990 " spd->dt4r_dt4r4w, * 55 DRAM Case Temperature Rise from "
991 "Ambient due to Page Open Burst Read/DT4R4W Mode Bit "
992 "(DT4R/DT4R4W Mode Bit) *");
993 printf("%-3d : %02x %s\n", 56, spd->dt5b,
994 " spd->dt5b, * 56 DRAM Case Temperature Rise from "
995 "Ambient due to Burst Refresh (DT5B) *");
996 printf("%-3d : %02x %s\n", 57, spd->dt7,
997 " spd->dt7, * 57 DRAM Case Temperature Rise from "
998 "Ambient due to Bank Interleave Reads with "
999 "Auto-Precharge (DT7) *");
Priyanka Jain0dd38a32013-09-25 10:41:19 +05301000 printf("%-3d : %02x %s\n", 58, spd->psi_ta_pll,
1001 " spd->psi_ta_pll, * 58 Thermal Resistance of PLL Package form"
York Sun6f5e1dc2011-09-16 13:21:35 -07001002 " Top (Case) to Ambient (Psi T-A PLL) *");
Priyanka Jain0dd38a32013-09-25 10:41:19 +05301003 printf("%-3d : %02x %s\n", 59, spd->psi_ta_reg,
1004 " spd->psi_ta_reg, * 59 Thermal Reisitance of Register Package"
York Sun6f5e1dc2011-09-16 13:21:35 -07001005 " from Top (Case) to Ambient (Psi T-A Register) *");
1006 printf("%-3d : %02x %s\n", 60, spd->dtpllactive,
1007 " spd->dtpllactive, * 60 PLL Case Temperature Rise from "
1008 "Ambient due to PLL Active (DT PLL Active) *");
1009 printf("%-3d : %02x %s\n", 61, spd->dtregact,
1010 " spd->dtregact, "
1011 "* 61 Register Case Temperature Rise from Ambient due to "
1012 "Register Active/Mode Bit (DT Register Active/Mode Bit) *");
1013 printf("%-3d : %02x %s\n", 62, spd->spd_rev,
1014 " spd->spd_rev, * 62 SPD Data Revision Code *");
1015 printf("%-3d : %02x %s\n", 63, spd->cksum,
1016 " spd->cksum, * 63 Checksum for bytes 0-62 *");
1017
1018 printf("%-3d-%3d: ", 64, 71);
1019
1020 for (i = 0; i < 8; i++)
1021 printf("%02x", spd->mid[i]);
1022
1023 printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
1024
1025 printf("%-3d : %02x %s\n", 72, spd->mloc,
1026 " spd->mloc, * 72 Manufacturing Location *");
1027
1028 printf("%-3d-%3d: >>", 73, 90);
1029 for (i = 0; i < 18; i++)
1030 printf("%c", spd->mpart[i]);
1031
1032
1033 printf("<<* 73 Manufacturer's Part Number *\n");
1034
1035 printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1],
1036 "* 91 Revision Code *");
1037 printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1],
1038 "* 93 Manufacturing Date *");
1039 printf("%-3d-%3d: ", 95, 98);
1040
1041 for (i = 0; i < 4; i++)
1042 printf("%02x", spd->sernum[i]);
1043
1044 printf("* 95 Assembly Serial Number *\n");
1045
1046 printf("%-3d-%3d: ", 99, 127);
1047 for (i = 0; i < 27; i++)
1048 printf("%02x", spd->mspec[i]);
1049
1050
1051 printf("* 99 Manufacturer Specific Data *\n");
1052}
1053#endif
1054
York Sun5614e712013-09-30 09:22:09 -07001055#ifdef CONFIG_SYS_FSL_DDR3
York Sun6f5e1dc2011-09-16 13:21:35 -07001056void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd)
1057{
1058 unsigned int i;
1059
1060 /* General Section: Bytes 0-59 */
1061
York Sun1d083ff2012-08-17 08:22:43 +00001062#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y);
York Sun6f5e1dc2011-09-16 13:21:35 -07001063#define PRINT_NNXXS(n0, n1, x0, x1, s) \
1064 printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1);
1065
1066 PRINT_NXS(0, spd->info_size_crc,
1067 "info_size_crc bytes written into serial memory, "
1068 "CRC coverage");
1069 PRINT_NXS(1, spd->spd_rev,
1070 "spd_rev SPD Revision");
1071 PRINT_NXS(2, spd->mem_type,
1072 "mem_type Key Byte / DRAM Device Type");
1073 PRINT_NXS(3, spd->module_type,
1074 "module_type Key Byte / Module Type");
1075 PRINT_NXS(4, spd->density_banks,
1076 "density_banks SDRAM Density and Banks");
1077 PRINT_NXS(5, spd->addressing,
1078 "addressing SDRAM Addressing");
1079 PRINT_NXS(6, spd->module_vdd,
1080 "module_vdd Module Nominal Voltage, VDD");
1081 PRINT_NXS(7, spd->organization,
1082 "organization Module Organization");
1083 PRINT_NXS(8, spd->bus_width,
1084 "bus_width Module Memory Bus Width");
1085 PRINT_NXS(9, spd->ftb_div,
1086 "ftb_div Fine Timebase (FTB) Dividend / Divisor");
1087 PRINT_NXS(10, spd->mtb_dividend,
1088 "mtb_dividend Medium Timebase (MTB) Dividend");
1089 PRINT_NXS(11, spd->mtb_divisor,
1090 "mtb_divisor Medium Timebase (MTB) Divisor");
Priyanka Jain0dd38a32013-09-25 10:41:19 +05301091 PRINT_NXS(12, spd->tck_min,
1092 "tck_min SDRAM Minimum Cycle Time");
York Sun6f5e1dc2011-09-16 13:21:35 -07001093 PRINT_NXS(13, spd->res_13,
1094 "res_13 Reserved");
1095 PRINT_NXS(14, spd->caslat_lsb,
1096 "caslat_lsb CAS Latencies Supported, LSB");
1097 PRINT_NXS(15, spd->caslat_msb,
1098 "caslat_msb CAS Latencies Supported, MSB");
Priyanka Jain0dd38a32013-09-25 10:41:19 +05301099 PRINT_NXS(16, spd->taa_min,
1100 "taa_min Min CAS Latency Time");
1101 PRINT_NXS(17, spd->twr_min,
1102 "twr_min Min Write REcovery Time");
1103 PRINT_NXS(18, spd->trcd_min,
1104 "trcd_min Min RAS# to CAS# Delay Time");
1105 PRINT_NXS(19, spd->trrd_min,
1106 "trrd_min Min Row Active to Row Active Delay Time");
1107 PRINT_NXS(20, spd->trp_min,
1108 "trp_min Min Row Precharge Delay Time");
1109 PRINT_NXS(21, spd->tras_trc_ext,
1110 "tras_trc_ext Upper Nibbles for tRAS and tRC");
1111 PRINT_NXS(22, spd->tras_min_lsb,
1112 "tras_min_lsb Min Active to Precharge Delay Time, LSB");
1113 PRINT_NXS(23, spd->trc_min_lsb,
1114 "trc_min_lsb Min Active to Active/Refresh Delay Time, LSB");
1115 PRINT_NXS(24, spd->trfc_min_lsb,
1116 "trfc_min_lsb Min Refresh Recovery Delay Time LSB");
1117 PRINT_NXS(25, spd->trfc_min_msb,
1118 "trfc_min_msb Min Refresh Recovery Delay Time MSB");
1119 PRINT_NXS(26, spd->twtr_min,
1120 "twtr_min Min Internal Write to Read Command Delay Time");
1121 PRINT_NXS(27, spd->trtp_min,
1122 "trtp_min "
1123 "Min Internal Read to Precharge Command Delay Time");
1124 PRINT_NXS(28, spd->tfaw_msb,
1125 "tfaw_msb Upper Nibble for tFAW");
1126 PRINT_NXS(29, spd->tfaw_min,
1127 "tfaw_min Min Four Activate Window Delay Time");
York Sun6f5e1dc2011-09-16 13:21:35 -07001128 PRINT_NXS(30, spd->opt_features,
1129 "opt_features SDRAM Optional Features");
1130 PRINT_NXS(31, spd->therm_ref_opt,
1131 "therm_ref_opt SDRAM Thermal and Refresh Opts");
1132 PRINT_NXS(32, spd->therm_sensor,
1133 "therm_sensor SDRAM Thermal Sensor");
1134 PRINT_NXS(33, spd->device_type,
1135 "device_type SDRAM Device Type");
Priyanka Jain0dd38a32013-09-25 10:41:19 +05301136 PRINT_NXS(34, spd->fine_tck_min,
1137 "fine_tck_min Fine offset for tCKmin");
1138 PRINT_NXS(35, spd->fine_taa_min,
1139 "fine_taa_min Fine offset for tAAmin");
1140 PRINT_NXS(36, spd->fine_trcd_min,
1141 "fine_trcd_min Fine offset for tRCDmin");
1142 PRINT_NXS(37, spd->fine_trp_min,
1143 "fine_trp_min Fine offset for tRPmin");
1144 PRINT_NXS(38, spd->fine_trc_min,
1145 "fine_trc_min Fine offset for tRCmin");
York Sun6f5e1dc2011-09-16 13:21:35 -07001146
York Sun73b53962012-08-17 08:22:37 +00001147 printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */
York Sun6f5e1dc2011-09-16 13:21:35 -07001148
York Sun73b53962012-08-17 08:22:37 +00001149 for (i = 39; i <= 59; i++)
1150 printf("%02x ", spd->res_39_59[i - 39]);
York Sun6f5e1dc2011-09-16 13:21:35 -07001151
1152 puts("\n");
1153
1154 switch (spd->module_type) {
1155 case 0x02: /* UDIMM */
1156 case 0x03: /* SO-DIMM */
1157 case 0x04: /* Micro-DIMM */
1158 case 0x06: /* Mini-UDIMM */
1159 PRINT_NXS(60, spd->mod_section.unbuffered.mod_height,
1160 "mod_height (Unbuffered) Module Nominal Height");
1161 PRINT_NXS(61, spd->mod_section.unbuffered.mod_thickness,
1162 "mod_thickness (Unbuffered) Module Maximum Thickness");
1163 PRINT_NXS(62, spd->mod_section.unbuffered.ref_raw_card,
1164 "ref_raw_card (Unbuffered) Reference Raw Card Used");
1165 PRINT_NXS(63, spd->mod_section.unbuffered.addr_mapping,
1166 "addr_mapping (Unbuffered) Address mapping from "
1167 "Edge Connector to DRAM");
1168 break;
1169 case 0x01: /* RDIMM */
1170 case 0x05: /* Mini-RDIMM */
1171 PRINT_NXS(60, spd->mod_section.registered.mod_height,
1172 "mod_height (Registered) Module Nominal Height");
1173 PRINT_NXS(61, spd->mod_section.registered.mod_thickness,
1174 "mod_thickness (Registered) Module Maximum Thickness");
1175 PRINT_NXS(62, spd->mod_section.registered.ref_raw_card,
1176 "ref_raw_card (Registered) Reference Raw Card Used");
1177 PRINT_NXS(63, spd->mod_section.registered.modu_attr,
1178 "modu_attr (Registered) DIMM Module Attributes");
1179 PRINT_NXS(64, spd->mod_section.registered.thermal,
1180 "thermal (Registered) Thermal Heat "
1181 "Spreader Solution");
1182 PRINT_NXS(65, spd->mod_section.registered.reg_id_lo,
1183 "reg_id_lo (Registered) Register Manufacturer ID "
1184 "Code, LSB");
1185 PRINT_NXS(66, spd->mod_section.registered.reg_id_hi,
1186 "reg_id_hi (Registered) Register Manufacturer ID "
1187 "Code, MSB");
1188 PRINT_NXS(67, spd->mod_section.registered.reg_rev,
1189 "reg_rev (Registered) Register "
1190 "Revision Number");
1191 PRINT_NXS(68, spd->mod_section.registered.reg_type,
1192 "reg_type (Registered) Register Type");
1193 for (i = 69; i <= 76; i++) {
1194 printf("%-3d : %02x rcw[%d]\n", i,
1195 spd->mod_section.registered.rcw[i-69], i-69);
1196 }
1197 break;
1198 default:
1199 /* Module-specific Section, Unsupported Module Type */
1200 printf("%-3d-%3d: ", 60, 116);
1201
1202 for (i = 60; i <= 116; i++)
1203 printf("%02x", spd->mod_section.uc[i - 60]);
1204
1205 break;
1206 }
1207
1208 /* Unique Module ID: Bytes 117-125 */
1209 PRINT_NXS(117, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106");
1210 PRINT_NXS(118, spd->mmid_msb, "Module MfgID Code MSB - JEP-106");
1211 PRINT_NXS(119, spd->mloc, "Mfg Location");
1212 PRINT_NNXXS(120, 121, spd->mdate[0], spd->mdate[1], "Mfg Date");
1213
1214 printf("%-3d-%3d: ", 122, 125);
1215
1216 for (i = 122; i <= 125; i++)
1217 printf("%02x ", spd->sernum[i - 122]);
1218 printf(" Module Serial Number\n");
1219
1220 /* CRC: Bytes 126-127 */
1221 PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC");
1222
1223 /* Other Manufacturer Fields and User Space: Bytes 128-255 */
1224 printf("%-3d-%3d: ", 128, 145);
1225 for (i = 128; i <= 145; i++)
1226 printf("%02x ", spd->mpart[i - 128]);
1227 printf(" Mfg's Module Part Number\n");
1228
1229 PRINT_NNXXS(146, 147, spd->mrev[0], spd->mrev[1],
1230 "Module Revision code");
1231
1232 PRINT_NXS(148, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106");
1233 PRINT_NXS(149, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106");
1234
1235 printf("%-3d-%3d: ", 150, 175);
1236 for (i = 150; i <= 175; i++)
1237 printf("%02x ", spd->msd[i - 150]);
1238 printf(" Mfg's Specific Data\n");
1239
1240 printf("%-3d-%3d: ", 176, 255);
1241 for (i = 176; i <= 255; i++)
1242 printf("%02x", spd->cust[i - 176]);
1243 printf(" Mfg's Specific Data\n");
1244
1245}
1246#endif
1247
1248static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
1249{
York Sun5614e712013-09-30 09:22:09 -07001250#if defined(CONFIG_SYS_FSL_DDR1)
York Sun6f5e1dc2011-09-16 13:21:35 -07001251 ddr1_spd_dump(spd);
York Sun5614e712013-09-30 09:22:09 -07001252#elif defined(CONFIG_SYS_FSL_DDR2)
York Sun6f5e1dc2011-09-16 13:21:35 -07001253 ddr2_spd_dump(spd);
York Sun5614e712013-09-30 09:22:09 -07001254#elif defined(CONFIG_SYS_FSL_DDR3)
York Sun6f5e1dc2011-09-16 13:21:35 -07001255 ddr3_spd_dump(spd);
1256#endif
1257}
1258
1259static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo,
1260 unsigned int ctrl_mask,
1261 unsigned int dimm_mask,
1262 unsigned int do_mask)
1263{
1264 unsigned int i, j, retval;
1265
1266 /* STEP 1: DIMM SPD data */
1267 if (do_mask & STEP_GET_SPD) {
1268 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1269 if (!(ctrl_mask & (1 << i)))
1270 continue;
1271
1272 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
1273 if (!(dimm_mask & (1 << j)))
1274 continue;
1275
1276 printf("SPD info: Controller=%u "
1277 "DIMM=%u\n", i, j);
1278 generic_spd_dump(
1279 &(pinfo->spd_installed_dimms[i][j]));
1280 printf("\n");
1281 }
1282 printf("\n");
1283 }
1284 printf("\n");
1285 }
1286
1287 /* STEP 2: DIMM Parameters */
1288 if (do_mask & STEP_COMPUTE_DIMM_PARMS) {
1289 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1290 if (!(ctrl_mask & (1 << i)))
1291 continue;
1292 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
1293 if (!(dimm_mask & (1 << j)))
1294 continue;
1295 printf("DIMM parameters: Controller=%u "
1296 "DIMM=%u\n", i, j);
1297 print_dimm_parameters(
1298 &(pinfo->dimm_params[i][j]));
1299 printf("\n");
1300 }
1301 printf("\n");
1302 }
1303 printf("\n");
1304 }
1305
1306 /* STEP 3: Common Parameters */
1307 if (do_mask & STEP_COMPUTE_COMMON_PARMS) {
1308 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1309 if (!(ctrl_mask & (1 << i)))
1310 continue;
1311 printf("\"lowest common\" DIMM parameters: "
1312 "Controller=%u\n", i);
1313 print_lowest_common_dimm_parameters(
1314 &pinfo->common_timing_params[i]);
1315 printf("\n");
1316 }
1317 printf("\n");
1318 }
1319
1320 /* STEP 4: User Configuration Options */
1321 if (do_mask & STEP_GATHER_OPTS) {
1322 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1323 if (!(ctrl_mask & (1 << i)))
1324 continue;
1325 printf("User Config Options: Controller=%u\n", i);
1326 print_memctl_options(&pinfo->memctl_opts[i]);
1327 printf("\n");
1328 }
1329 printf("\n");
1330 }
1331
1332 /* STEP 5: Address assignment */
1333 if (do_mask & STEP_ASSIGN_ADDRESSES) {
1334 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1335 if (!(ctrl_mask & (1 << i)))
1336 continue;
1337 for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
1338 printf("Address Assignment: Controller=%u "
1339 "DIMM=%u\n", i, j);
1340 printf("Don't have this functionality yet\n");
1341 }
1342 printf("\n");
1343 }
1344 printf("\n");
1345 }
1346
1347 /* STEP 6: computed controller register values */
1348 if (do_mask & STEP_COMPUTE_REGS) {
1349 for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1350 if (!(ctrl_mask & (1 << i)))
1351 continue;
1352 printf("Computed Register Values: Controller=%u\n", i);
1353 print_fsl_memctl_config_regs(
1354 &pinfo->fsl_ddr_config_reg[i]);
1355 retval = check_fsl_memctl_config_regs(
1356 &pinfo->fsl_ddr_config_reg[i]);
1357 if (retval) {
1358 printf("check_fsl_memctl_config_regs "
1359 "result = %u\n", retval);
1360 }
1361 printf("\n");
1362 }
1363 printf("\n");
1364 }
1365}
1366
1367struct data_strings {
1368 const char *data_name;
1369 unsigned int step_mask;
1370 unsigned int dimm_number_required;
1371};
1372
1373#define DATA_OPTIONS(name, step, dimm) {#name, step, dimm}
1374
James Yangbf418932013-01-04 08:14:00 +00001375static unsigned int fsl_ddr_parse_interactive_cmd(
1376 char **argv,
1377 int argc,
1378 unsigned int *pstep_mask,
1379 unsigned int *pctlr_mask,
1380 unsigned int *pdimm_mask,
1381 unsigned int *pdimm_number_required
1382 ) {
1383
York Sun6f5e1dc2011-09-16 13:21:35 -07001384 static const struct data_strings options[] = {
1385 DATA_OPTIONS(spd, STEP_GET_SPD, 1),
1386 DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1),
1387 DATA_OPTIONS(commonparms, STEP_COMPUTE_COMMON_PARMS, 0),
1388 DATA_OPTIONS(opts, STEP_GATHER_OPTS, 0),
1389 DATA_OPTIONS(addresses, STEP_ASSIGN_ADDRESSES, 0),
1390 DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0),
1391 };
1392 static const unsigned int n_opts = ARRAY_SIZE(options);
James Yangbf418932013-01-04 08:14:00 +00001393
1394 unsigned int i, j;
1395 unsigned int error = 0;
James Yangbf418932013-01-04 08:14:00 +00001396
1397 for (i = 1; i < argc; i++) {
James Yang992f2fb2013-01-04 08:14:01 +00001398 unsigned int matched = 0;
1399
James Yangbf418932013-01-04 08:14:00 +00001400 for (j = 0; j < n_opts; j++) {
1401 if (strcmp(options[j].data_name, argv[i]) != 0)
1402 continue;
1403 *pstep_mask |= options[j].step_mask;
1404 *pdimm_number_required =
1405 options[j].dimm_number_required;
1406 matched = 1;
1407 break;
1408 }
1409
1410 if (matched)
1411 continue;
1412
1413 if (argv[i][0] == 'c') {
1414 char c = argv[i][1];
1415 if (isdigit(c))
1416 *pctlr_mask |= 1 << (c - '0');
1417 continue;
1418 }
1419
1420 if (argv[i][0] == 'd') {
1421 char c = argv[i][1];
1422 if (isdigit(c))
1423 *pdimm_mask |= 1 << (c - '0');
1424 continue;
1425 }
1426
1427 printf("unknown arg %s\n", argv[i]);
1428 *pstep_mask = 0;
1429 error = 1;
1430 break;
1431 }
1432
1433 return error;
1434}
1435
James Yange8ba6c52013-01-07 14:01:03 +00001436int fsl_ddr_interactive_env_var_exists(void)
1437{
1438 char buffer[CONFIG_SYS_CBSIZE];
1439
1440 if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0)
1441 return 1;
1442
1443 return 0;
1444}
1445
1446unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set)
James Yangbf418932013-01-04 08:14:00 +00001447{
1448 unsigned long long ddrsize;
1449 const char *prompt = "FSL DDR>";
1450 char buffer[CONFIG_SYS_CBSIZE];
James Yange8ba6c52013-01-07 14:01:03 +00001451 char buffer2[CONFIG_SYS_CBSIZE];
1452 char *p = NULL;
James Yangbf418932013-01-04 08:14:00 +00001453 char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
1454 int argc;
1455 unsigned int next_step = STEP_GET_SPD;
York Sun6f5e1dc2011-09-16 13:21:35 -07001456 const char *usage = {
1457 "commands:\n"
1458 "print print SPD and intermediate computed data\n"
1459 "reset reboot machine\n"
1460 "recompute reload SPD and options to default and recompute regs\n"
1461 "edit modify spd, parameter, or option\n"
1462 "compute recompute registers from current next_step to end\n"
James Yang5926ee32013-01-04 08:14:02 +00001463 "copy copy parameters\n"
York Sun6f5e1dc2011-09-16 13:21:35 -07001464 "next_step shows current next_step\n"
1465 "help this message\n"
1466 "go program the memory controller and continue with u-boot\n"
1467 };
1468
James Yange8ba6c52013-01-07 14:01:03 +00001469 if (var_is_set) {
1470 if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) {
1471 p = buffer2;
1472 } else {
1473 var_is_set = 0;
1474 }
1475 }
1476
York Sun6f5e1dc2011-09-16 13:21:35 -07001477 /*
1478 * The strategy for next_step is that it points to the next
1479 * step in the computation process that needs to be done.
1480 */
1481 while (1) {
James Yange8ba6c52013-01-07 14:01:03 +00001482 if (var_is_set) {
1483 char *pend = strchr(p, ';');
1484 if (pend) {
1485 /* found command separator, copy sub-command */
1486 *pend = '\0';
1487 strcpy(buffer, p);
1488 p = pend + 1;
1489 } else {
1490 /* separator not found, copy whole string */
1491 strcpy(buffer, p);
1492 p = NULL;
1493 var_is_set = 0;
1494 }
1495 } else {
1496 /*
1497 * No need to worry for buffer overflow here in
1498 * this function; readline() maxes out at CFG_CBSIZE
1499 */
1500 readline_into_buffer(prompt, buffer, 0);
1501 }
York Sun6f5e1dc2011-09-16 13:21:35 -07001502 argc = parse_line(buffer, argv);
1503 if (argc == 0)
1504 continue;
1505
1506
1507 if (strcmp(argv[0], "help") == 0) {
1508 puts(usage);
1509 continue;
1510 }
1511
1512 if (strcmp(argv[0], "next_step") == 0) {
1513 printf("next_step = 0x%02X (%s)\n",
1514 next_step,
1515 step_to_string(next_step));
1516 continue;
1517 }
1518
James Yang5926ee32013-01-04 08:14:02 +00001519 if (strcmp(argv[0], "copy") == 0) {
1520 unsigned int error = 0;
1521 unsigned int step_mask = 0;
1522 unsigned int src_ctlr_mask = 0;
1523 unsigned int src_dimm_mask = 0;
1524 unsigned int dimm_number_required = 0;
1525 unsigned int src_ctlr_num = 0;
1526 unsigned int src_dimm_num = 0;
1527 unsigned int dst_ctlr_num = -1;
1528 unsigned int dst_dimm_num = -1;
1529 unsigned int i, num_dest_parms;
1530
1531 if (argc == 1) {
1532 printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n");
1533 continue;
1534 }
1535
1536 error = fsl_ddr_parse_interactive_cmd(
1537 argv, argc,
1538 &step_mask,
1539 &src_ctlr_mask,
1540 &src_dimm_mask,
1541 &dimm_number_required
1542 );
1543
1544 /* XXX: only dimm_number_required and step_mask will
1545 be used by this function. Parse the controller and
1546 DIMM number separately because it is easier. */
1547
1548 if (error)
1549 continue;
1550
1551 /* parse source destination controller / DIMM */
1552
1553 num_dest_parms = dimm_number_required ? 2 : 1;
1554
1555 for (i = 0; i < argc; i++) {
1556 if (argv[i][0] == 'c') {
1557 char c = argv[i][1];
1558 if (isdigit(c)) {
1559 src_ctlr_num = (c - '0');
1560 break;
1561 }
1562 }
1563 }
1564
1565 for (i = 0; i < argc; i++) {
1566 if (argv[i][0] == 'd') {
1567 char c = argv[i][1];
1568 if (isdigit(c)) {
1569 src_dimm_num = (c - '0');
1570 break;
1571 }
1572 }
1573 }
1574
1575 /* parse destination controller / DIMM */
1576
1577 for (i = argc - 1; i >= argc - num_dest_parms; i--) {
1578 if (argv[i][0] == 'c') {
1579 char c = argv[i][1];
1580 if (isdigit(c)) {
1581 dst_ctlr_num = (c - '0');
1582 break;
1583 }
1584 }
1585 }
1586
1587 for (i = argc - 1; i >= argc - num_dest_parms; i--) {
1588 if (argv[i][0] == 'd') {
1589 char c = argv[i][1];
1590 if (isdigit(c)) {
1591 dst_dimm_num = (c - '0');
1592 break;
1593 }
1594 }
1595 }
1596
1597 /* TODO: validate inputs */
1598
1599 debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n",
1600 src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask);
1601
1602
1603 switch (step_mask) {
1604
1605 case STEP_GET_SPD:
1606 memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]),
1607 &(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]),
1608 sizeof(pinfo->spd_installed_dimms[0][0]));
1609 break;
1610
1611 case STEP_COMPUTE_DIMM_PARMS:
1612 memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]),
1613 &(pinfo->dimm_params[src_ctlr_num][src_dimm_num]),
1614 sizeof(pinfo->dimm_params[0][0]));
1615 break;
1616
1617 case STEP_COMPUTE_COMMON_PARMS:
1618 memcpy(&(pinfo->common_timing_params[dst_ctlr_num]),
1619 &(pinfo->common_timing_params[src_ctlr_num]),
1620 sizeof(pinfo->common_timing_params[0]));
1621 break;
1622
1623 case STEP_GATHER_OPTS:
1624 memcpy(&(pinfo->memctl_opts[dst_ctlr_num]),
1625 &(pinfo->memctl_opts[src_ctlr_num]),
1626 sizeof(pinfo->memctl_opts[0]));
1627 break;
1628
1629 /* someday be able to have addresses to copy addresses... */
1630
1631 case STEP_COMPUTE_REGS:
1632 memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]),
1633 &(pinfo->fsl_ddr_config_reg[src_ctlr_num]),
1634 sizeof(pinfo->memctl_opts[0]));
1635 break;
1636
1637 default:
1638 printf("unexpected step_mask value\n");
1639 }
1640
1641 continue;
1642
1643 }
1644
York Sun6f5e1dc2011-09-16 13:21:35 -07001645 if (strcmp(argv[0], "edit") == 0) {
York Sun6f5e1dc2011-09-16 13:21:35 -07001646 unsigned int error = 0;
1647 unsigned int step_mask = 0;
1648 unsigned int ctlr_mask = 0;
1649 unsigned int dimm_mask = 0;
1650 char *p_element = NULL;
1651 char *p_value = NULL;
1652 unsigned int dimm_number_required = 0;
1653 unsigned int ctrl_num;
1654 unsigned int dimm_num;
York Sun6f5e1dc2011-09-16 13:21:35 -07001655
1656 if (argc == 1) {
1657 /* Only the element and value must be last */
1658 printf("edit <c#> <d#> "
1659 "<spd|dimmparms|commonparms|opts|"
1660 "addresses|regs> <element> <value>\n");
1661 printf("for spd, specify byte number for "
1662 "element\n");
1663 continue;
1664 }
1665
James Yangbf418932013-01-04 08:14:00 +00001666 error = fsl_ddr_parse_interactive_cmd(
1667 argv, argc - 2,
1668 &step_mask,
1669 &ctlr_mask,
1670 &dimm_mask,
1671 &dimm_number_required
1672 );
York Sun6f5e1dc2011-09-16 13:21:35 -07001673
1674 if (error)
1675 continue;
1676
1677
1678 /* Check arguments */
1679
1680 /* ERROR: If no steps were found */
1681 if (step_mask == 0) {
1682 printf("Error: No valid steps were specified "
1683 "in argument.\n");
1684 continue;
1685 }
1686
1687 /* ERROR: If multiple steps were found */
1688 if (step_mask & (step_mask - 1)) {
1689 printf("Error: Multiple steps specified in "
1690 "argument.\n");
1691 continue;
1692 }
1693
1694 /* ERROR: Controller not specified */
1695 if (ctlr_mask == 0) {
1696 printf("Error: controller number not "
1697 "specified or no element and "
1698 "value specified\n");
1699 continue;
1700 }
1701
1702 if (ctlr_mask & (ctlr_mask - 1)) {
1703 printf("Error: multiple controllers "
1704 "specified, %X\n", ctlr_mask);
1705 continue;
1706 }
1707
1708 /* ERROR: DIMM number not specified */
1709 if (dimm_number_required && dimm_mask == 0) {
1710 printf("Error: DIMM number number not "
1711 "specified or no element and "
1712 "value specified\n");
1713 continue;
1714 }
1715
1716 if (dimm_mask & (dimm_mask - 1)) {
1717 printf("Error: multipled DIMMs specified\n");
1718 continue;
1719 }
1720
1721 p_element = argv[argc - 2];
1722 p_value = argv[argc - 1];
1723
1724 ctrl_num = __ilog2(ctlr_mask);
1725 dimm_num = __ilog2(dimm_mask);
1726
1727 switch (step_mask) {
1728 case STEP_GET_SPD:
1729 {
1730 unsigned int element_num;
1731 unsigned int value;
1732
1733 element_num = simple_strtoul(p_element,
1734 NULL, 0);
1735 value = simple_strtoul(p_value,
1736 NULL, 0);
1737 fsl_ddr_spd_edit(pinfo,
1738 ctrl_num,
1739 dimm_num,
1740 element_num,
1741 value);
1742 next_step = STEP_COMPUTE_DIMM_PARMS;
1743 }
1744 break;
1745
1746 case STEP_COMPUTE_DIMM_PARMS:
1747 fsl_ddr_dimm_parameters_edit(
1748 pinfo, ctrl_num, dimm_num,
1749 p_element, p_value);
1750 next_step = STEP_COMPUTE_COMMON_PARMS;
1751 break;
1752
1753 case STEP_COMPUTE_COMMON_PARMS:
1754 lowest_common_dimm_parameters_edit(pinfo,
1755 ctrl_num, p_element, p_value);
1756 next_step = STEP_GATHER_OPTS;
1757 break;
1758
1759 case STEP_GATHER_OPTS:
1760 fsl_ddr_options_edit(pinfo, ctrl_num,
1761 p_element, p_value);
1762 next_step = STEP_ASSIGN_ADDRESSES;
1763 break;
1764
1765 case STEP_ASSIGN_ADDRESSES:
1766 printf("editing of address assignment "
1767 "not yet implemented\n");
1768 break;
1769
1770 case STEP_COMPUTE_REGS:
1771 {
1772 fsl_ddr_regs_edit(pinfo,
1773 ctrl_num,
1774 p_element,
1775 p_value);
1776 next_step = STEP_PROGRAM_REGS;
1777 }
1778 break;
1779
1780 default:
1781 printf("programming error\n");
1782 while (1)
1783 ;
1784 break;
1785 }
1786 continue;
1787 }
1788
1789 if (strcmp(argv[0], "reset") == 0) {
1790 /*
1791 * Reboot machine.
1792 * Args don't seem to matter because this
1793 * doesn't return
1794 */
1795 do_reset(NULL, 0, 0, NULL);
York Sun57495e42012-10-08 07:44:22 +00001796 printf("Reset didn't work\n");
York Sun6f5e1dc2011-09-16 13:21:35 -07001797 }
1798
1799 if (strcmp(argv[0], "recompute") == 0) {
1800 /*
1801 * Recalculate everything, starting with
1802 * loading SPD EEPROM from DIMMs
1803 */
1804 next_step = STEP_GET_SPD;
1805 ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
1806 continue;
1807 }
1808
1809 if (strcmp(argv[0], "compute") == 0) {
1810 /*
1811 * Compute rest of steps starting at
1812 * the current next_step/
1813 */
1814 ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
1815 continue;
1816 }
1817
1818 if (strcmp(argv[0], "print") == 0) {
York Sun6f5e1dc2011-09-16 13:21:35 -07001819 unsigned int error = 0;
1820 unsigned int step_mask = 0;
1821 unsigned int ctlr_mask = 0;
1822 unsigned int dimm_mask = 0;
James Yangbf418932013-01-04 08:14:00 +00001823 unsigned int dimm_number_required = 0;
York Sun6f5e1dc2011-09-16 13:21:35 -07001824
1825 if (argc == 1) {
1826 printf("print [c<n>] [d<n>] [spd] [dimmparms] "
1827 "[commonparms] [opts] [addresses] [regs]\n");
1828 continue;
1829 }
1830
James Yangbf418932013-01-04 08:14:00 +00001831 error = fsl_ddr_parse_interactive_cmd(
1832 argv, argc,
1833 &step_mask,
1834 &ctlr_mask,
1835 &dimm_mask,
1836 &dimm_number_required
1837 );
York Sun6f5e1dc2011-09-16 13:21:35 -07001838
1839 if (error)
1840 continue;
1841
1842 /* If no particular controller was found, print all */
1843 if (ctlr_mask == 0)
1844 ctlr_mask = 0xFF;
1845
1846 /* If no particular dimm was found, print all dimms. */
1847 if (dimm_mask == 0)
1848 dimm_mask = 0xFF;
1849
1850 /* If no steps were found, print all steps. */
1851 if (step_mask == 0)
1852 step_mask = STEP_ALL;
1853
1854 fsl_ddr_printinfo(pinfo, ctlr_mask,
1855 dimm_mask, step_mask);
1856 continue;
1857 }
1858
1859 if (strcmp(argv[0], "go") == 0) {
1860 if (next_step)
1861 ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
1862 break;
1863 }
1864
1865 printf("unknown command %s\n", argv[0]);
1866 }
1867
1868 debug("end of memory = %llu\n", (u64)ddrsize);
1869
1870 return ddrsize;
1871}