From: James Yang <[EMAIL PROTECTED]>

Provide a mechanism to allow interactive configuration of DDR params.  This
is useful when trying to test various DDR settings to determine optimal
configuration values for a given board.

---
 cpu/mpc8xxx/Makefile              |    1 +
 cpu/mpc8xxx/fsl_ddr_interactive.c | 1281 +++++++++++++++++++++++++++++++++++++
 cpu/mpc8xxx/fsl_ddr_sdram.c       |   10 +
 cpu/mpc8xxx/fsl_ddr_sdram.h       |    3 +
 4 files changed, 1295 insertions(+), 0 deletions(-)
 create mode 100644 cpu/mpc8xxx/fsl_ddr_interactive.c

diff --git a/cpu/mpc8xxx/Makefile b/cpu/mpc8xxx/Makefile
index 30f81ff..0ceac5b 100644
--- a/cpu/mpc8xxx/Makefile
+++ b/cpu/mpc8xxx/Makefile
@@ -10,6 +10,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)libmpc8xxx.a
 
+COBJS-$(CONFIG_FSL_DDR_INTERACTIVE)    += fsl_ddr_interactive.o
 COBJS-$(CONFIG_FSL_DDR1)       += fsl_ddr_sdram.o
 COBJS-$(CONFIG_FSL_DDR1)       += fsl_ddr1.o
 
diff --git a/cpu/mpc8xxx/fsl_ddr_interactive.c 
b/cpu/mpc8xxx/fsl_ddr_interactive.c
new file mode 100644
index 0000000..419deac
--- /dev/null
+++ b/cpu/mpc8xxx/fsl_ddr_interactive.c
@@ -0,0 +1,1281 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+/*
+ * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
+ * Based on code from spd_sdram.c
+ * Author: James Yang [at freescale.com]
+ */
+
+#include <common.h>
+#include <asm/types.h>
+
+#include "fsl_ddr_sdram.h"
+/*
+ * Option parameter Structures
+ */
+typedef struct {
+       const char *option_name;
+       unsigned long long *pointer;
+} options_strings_ulonglong_t;
+
+typedef struct {
+       const char *option_name;
+       unsigned int *pointer;
+} options_strings_uint_t;
+
+
+extern int do_reset(void *cmdtp, int flag, int argc, char *argv[]);
+
+/*
+ * interactive prompt
+ */
+
+static int is_a_num_char(const char c)
+{
+       return c >= '0' && c <= '9';
+}
+
+static unsigned int picos_to_mhz(unsigned int picos)
+{
+       return 1000000 / picos;
+}
+
+static int
+handle_uint_option_table(options_strings_uint_t *table,
+                        int table_size,
+                        const char *opt,
+                        const char *val)
+{
+       unsigned int i;
+       unsigned int value;
+
+       for (i = 0; i < table_size; i++) {
+               if (strcmp(table[i].option_name, opt) == 0) {
+                       value = simple_strtoul(val, NULL, 0);
+                       *table[i].pointer = value;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+
+static int
+handle_ull_option_table(options_strings_ulonglong_t *table,
+                       int table_size,
+                       const char *opt,
+                       const char *val)
+{
+       unsigned int i;
+       unsigned long long value;
+
+       for (i = 0; i < table_size; i++) {
+               if (strcmp(table[i].option_name, opt) == 0) {
+                       value = simple_strtoull(val, NULL, 0);
+                       *table[i].pointer = value;
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static void
+fsl_ddr_sdram_generic_edit(void *pdata,
+                          void *pend,
+                          unsigned int element_size,
+                          unsigned int element_num,
+                          unsigned int value)
+{
+       // XXX: BIG ENDIAN ONLY
+       char *pcdata = (char *)pdata;
+
+       pcdata += element_num * element_size;
+       if ((pcdata + element_size) > (char *) pend) {
+               debug("trying to write past end of data\n");
+               return;
+       }
+
+       switch (element_size) {
+       case 1:
+               asm volatile ("stb %0,0(%1)" : : "r" (value) , "b" (pcdata));
+               break;
+       case 2:
+               asm volatile ("sth %0,0(%1)" : : "r" (value) , "b" (pcdata));
+               break;
+       case 4:
+               asm volatile ("stw %0,0(%1)" : : "r" (value) , "b" (pcdata));
+               break;
+       default:
+               debug("unexpected element size %u\n", element_size);
+               break;
+       }
+}
+
+
+static void
+fsl_ddr_sdram_spd_edit(fsl_ddr_sdram_info_t *pinfo,
+                      unsigned int ctrl_num,
+                      unsigned int dimm_num,
+                      unsigned int element_num,
+                      unsigned int value)
+{
+       generic_spd_eeprom_t *pspd;
+
+       pspd = &(pinfo->spd_installed_dimms[ctrl_num][dimm_num]);
+       fsl_ddr_sdram_generic_edit(pspd, pspd + 1,
+                                  sizeof(char), element_num, value);
+}
+
+static void
+fsl_ddr_sdram_lowest_common_dimm_parameters_edit(fsl_ddr_sdram_info_t *pinfo,
+                                                unsigned int ctrl_num,
+                                                const char *optname_str,
+                                                const char * value_str)
+{
+       common_timing_params_t *p = &pinfo->common_timing_params[ctrl_num];
+
+       options_strings_uint_t options_uint[] = {
+               {"tCKmin_X_ps",                     &p->tCKmin_X_ps},
+               {"tCKmax_ps",                       &p->tCKmax_ps},
+               {"tCKmax_max_ps",                   &p->tCKmax_max_ps},
+               {"tRCD_ps",                         &p->tRCD_ps},
+               {"tRP_ps",                          &p->tRP_ps},
+               {"tRAS_ps",                         &p->tRAS_ps},
+               {"tWR_ps",                          &p->tWR_ps},
+               {"tWTR_ps",                         &p->tWTR_ps},
+               {"tRFC_ps",                         &p->tRFC_ps},
+               {"tRRD_ps",                         &p->tRRD_ps},
+               {"tRC_ps",                          &p->tRC_ps},
+               {"refresh_rate_ns",                 &p->refresh_rate_ns},
+               {"tIS_ps",                          &p->tIS_ps},
+               {"tIH_ps",                          &p->tIH_ps},
+               {"tDS_ps",                          &p->tDS_ps},
+               {"tDH_ps",                          &p->tDH_ps},
+               {"tRTP_ps",                         &p->tRTP_ps},
+               {"tDQSQ_max_ps",                    &p->tDQSQ_max_ps},
+               {"tQHS_ps",                         &p->tQHS_ps},
+               {"ndimms_present",                  &p->ndimms_present},
+               {"lowest_common_SPD_caslat",
+                       &p->lowest_common_SPD_caslat},
+               {"highest_common_derated_caslat",
+                       &p->highest_common_derated_caslat},
+               {"additive_latency",                &p->additive_latency},
+               {"all_DIMMs_burst_lengths_bitmask",
+                       &p->all_DIMMs_burst_lengths_bitmask},
+               {"all_DIMMs_registered",            &p->all_DIMMs_registered},
+               {"all_DIMMs_unbuffered",            &p->all_DIMMs_unbuffered},
+               {"all_DIMMs_ECC_capable",           &p->all_DIMMs_ECC_capable}
+       };
+
+       const unsigned int n_uint_opts = ARRAY_SIZE(options_uint);
+
+       options_strings_ulonglong_t options_ull[] = {
+               {"total_mem",    &p->total_mem},
+               {"base_address", &p->base_address}
+       };
+
+       const unsigned int n_ull_opts = ARRAY_SIZE(options_ull);
+
+       if (handle_uint_option_table(options_uint, n_uint_opts,
+                                    optname_str, value_str))
+               return;
+
+       if (handle_ull_option_table(options_ull, n_ull_opts,
+                                   optname_str, value_str))
+               return;
+
+       printf("Error: couldn't find option string %s\n", optname_str);
+}
+
+static void
+fsl_ddr_sdram_dimm_parameters_edit(fsl_ddr_sdram_info_t *pinfo,
+                                  unsigned int ctrl_num,
+                                  unsigned int dimm_num,
+                                  const char *optname_str,
+                                  const char *value_str)
+{
+       dimm_params_t *p = &(pinfo->dimm_params[ctrl_num][dimm_num]);
+
+       options_strings_uint_t options_uint[] = {
+               {"n_ranks",                  &p->n_ranks},
+               {"data_width",               &p->data_width},
+               {"primary_sdram_width",      &p->primary_sdram_width},
+               {"ec_sdram_width",           &p->ec_sdram_width},
+               {"registered_dimm",          &p->registered_dimm},
+
+               {"n_row_addr",               &p->n_row_addr},
+               {"n_col_addr",               &p->n_col_addr},
+               {"edc_config",               &p->edc_config},
+               {"n_banks_per_sdram_device", &p->n_banks_per_sdram_device},
+               {"burst_lengths_bitmask",    &p->burst_lengths_bitmask},
+               {"row_density",              &p->row_density},
+
+               {"tCKmin_X_ps",              &p->tCKmin_X_ps},
+               {"tCKmin_X_minus_1_ps",      &p->tCKmin_X_minus_1_ps},
+               {"tCKmin_X_minus_2_ps",      &p->tCKmin_X_minus_2_ps},
+               {"tCKmax_ps",                &p->tCKmax_ps},
+
+               {"caslat_X",                 &p->caslat_X},
+               {"caslat_X_minus_1",         &p->caslat_X_minus_1},
+               {"caslat_X_minus_2",         &p->caslat_X_minus_2},
+
+               {"caslat_lowest_derated",    &p->caslat_lowest_derated},
+
+               {"tRCD_ps",                  &p->tRCD_ps},
+               {"tRP_ps",                   &p->tRP_ps},
+               {"tRAS_ps",                  &p->tRAS_ps},
+               {"tWR_ps",                   &p->tWR_ps},
+               {"tWTR_ps",                  &p->tWTR_ps},
+               {"tRFC_ps",                  &p->tRFC_ps},
+               {"tRRD_ps",                  &p->tRRD_ps},
+               {"tRC_ps",                   &p->tRC_ps},
+               {"refresh_rate_ns",          &p->refresh_rate_ns},
+
+               {"tIS_ps",                   &p->tIS_ps},
+               {"tIH_ps",                   &p->tIH_ps},
+               {"tDS_ps",                   &p->tDS_ps},
+               {"tDH_ps",                   &p->tDH_ps},
+               {"tRTP_ps",                  &p->tRTP_ps},
+               {"tDQSQ_max_ps",             &p->tDQSQ_max_ps},
+               {"tQHS_ps",                  &p->tQHS_ps},
+       };
+
+       const unsigned int n_uint_opts = ARRAY_SIZE(options_uint);
+
+       options_strings_ulonglong_t options_ull[] = {
+               {"rank_density",  &p->rank_density},
+               {"dimm_capacity", &p->dimm_capacity},
+               {"base_address",  &p->base_address},
+       };
+
+       const unsigned int n_ull_opts = ARRAY_SIZE(options_ull);
+
+       if (handle_uint_option_table(options_uint, n_uint_opts,
+                                    optname_str, value_str))
+               return;
+
+       if (handle_ull_option_table(options_ull, n_ull_opts,
+                                   optname_str, value_str))
+               return;
+
+       printf("couldn't find option string %s\n", optname_str);
+}
+
+static void
+print_dimm_parameters(const dimm_params_t *pdimm)
+{
+       if (pdimm->n_ranks == 0) {
+               printf("DIMM not present\n");
+               return;
+       }
+
+       printf("DIMM organization parameters:\n");
+
+       printf("module part name = %s\n", pdimm->mpart);
+       printf("n_ranks = %u\n", pdimm->n_ranks);
+       printf("rank_density = %llu bytes (%llu megabytes)\n",
+              pdimm->rank_density, pdimm->rank_density / 0x100000);
+       printf("dimm_capacity = %llu bytes (%llu megabytes)\n",
+              pdimm->dimm_capacity, pdimm->dimm_capacity / 0x100000);
+       printf("data_width = %u\n", pdimm->data_width);
+       printf("primary_sdram_width = %u\n", pdimm->primary_sdram_width);
+       printf("ec_sdram_width = %u\n", pdimm->ec_sdram_width);
+       printf("registered_dimm = %u\n", pdimm->registered_dimm);
+
+       printf("SDRAM device parameters:\n");
+       printf("n_row_addr = %u\n", pdimm->n_row_addr);
+       printf("n_col_addr = %u\n", pdimm->n_col_addr);
+       printf("edc_config = %u\n", pdimm->edc_config);
+       printf("n_banks_per_sdram_device = %u\n",
+              pdimm->n_banks_per_sdram_device);
+       printf("burst_lengths_bitmask = %02X\n",
+              pdimm->burst_lengths_bitmask);
+
+       printf("base_addresss = %llu (%08llX %08llX)\n",
+              pdimm->base_address,
+              (pdimm->base_address >> 32),
+              pdimm->base_address & 0xFFFFFFFF);
+
+       printf("SDRAM clock periods:\n");
+       printf("tCKmin_X_ps = %u ps\n", pdimm->tCKmin_X_ps);
+       printf("tCKmin_X_minus_1_ps = %u ps\n", pdimm->tCKmin_X_minus_1_ps);
+       printf("tCKmin_X_minus_2_ps = %u ps\n", pdimm->tCKmin_X_minus_2_ps);
+       printf("tCKmax_ps = %u ps\n", pdimm->tCKmax_ps);
+
+       printf("SDRAM CAS latencies:\n");
+       printf("caslat_X = %u\n", pdimm->caslat_X);
+       printf("caslat_X_minus_1 = %u\n", pdimm->caslat_X_minus_1);
+       printf("caslat_X_minus_2 = %u\n", pdimm->caslat_X_minus_2);
+       printf("caslat_lowest_derated = %u\n", pdimm->caslat_lowest_derated);
+
+       printf("SDRAM timing parameters:\n");
+       printf("tRCD_ps = %u\n", pdimm->tRCD_ps);
+       printf("tRP_ps = %u\n",  pdimm->tRP_ps);
+       printf("tRAS_ps = %u\n", pdimm->tRAS_ps);
+       printf("tWR_ps = %u\n",  pdimm->tWR_ps);
+       printf("tWTR_ps = %u\n", pdimm->tWTR_ps);
+       printf("tRFC_ps = %u\n", pdimm->tRFC_ps);
+       printf("tRC_ps = %u\n",  pdimm->tRC_ps);
+       printf("tRRD_ps = %u\n", pdimm->tRRD_ps);
+       printf("refresh_rate_ns = %u\n", pdimm->refresh_rate_ns);
+
+       printf("SDRAM even more timing parameters:\n");
+       printf("tIS_ps = %u\n", pdimm->tIS_ps);
+       printf("tIH_ps = %u\n", pdimm->tIH_ps);
+       printf("tDS_ps = %u\n", pdimm->tDS_ps);
+       printf("tDH_ps = %u\n", pdimm->tDH_ps);
+       printf("tRTP_ps = %u\n", pdimm->tRTP_ps);
+       printf("tDQSQ_max_ps = %u\n", pdimm->tDQSQ_max_ps);
+       printf("tQHS_ps = %u\n", pdimm->tQHS_ps);
+}
+
+static void
+print_lowest_common_dimm_parameters(
+               const common_timing_params_t *plcd_dimm_params)
+{
+
+       /*
+        * Clock frequencies
+        */
+       printf("tCKmin_X_ps = %u (%u MHz)\n",
+              plcd_dimm_params->tCKmin_X_ps,
+              picos_to_mhz(plcd_dimm_params->tCKmin_X_ps));
+       printf("tCKmax_ps = %u (%u MHz)\n",
+              plcd_dimm_params->tCKmax_ps,
+              picos_to_mhz(plcd_dimm_params->tCKmax_ps));
+       printf("tCKmax_max_ps = %u\n", plcd_dimm_params->tCKmax_max_ps);
+
+       /*
+        * Basic timing parameters
+        */
+       printf("tRCD_ps = %u\n", plcd_dimm_params->tRCD_ps);
+       printf("tRP_ps = %u\n", plcd_dimm_params->tRP_ps);
+       printf("tRAS_ps = %u\n", plcd_dimm_params->tRAS_ps);
+
+       /* maximum = 63750 ps */
+       printf("tWR_ps = %u\n", plcd_dimm_params->tWR_ps);
+
+       /* maximum = 63750 ps */
+       printf("tWTR_ps = %u\n", plcd_dimm_params->tWTR_ps );
+
+       /* maximum = 255 ns + 256 ns + .75 ns = 511750 ps */
+       printf("tRFC_ps = %u\n", plcd_dimm_params->tRFC_ps);
+
+       /* maximum = 63750 ps */
+       printf("tRRD_ps = %u\n", plcd_dimm_params->tRRD_ps);
+
+       /* maximum = 254 ns + .75 ns = 254750 ps */
+       printf("tRC_ps = %u\n", plcd_dimm_params->tRC_ps);
+
+       printf("refresh_rate_ns = %u\n", plcd_dimm_params->refresh_rate_ns );
+
+       /* byte 32, spd->ca_setup */
+       printf("tIS_ps = %u\n", plcd_dimm_params->tIS_ps);
+       /* byte 33, spd->ca_hold */
+       printf("tIH_ps = %u\n", plcd_dimm_params->tIH_ps);
+       /* byte 34, spd->data_setup */
+       printf("tDS_ps = %u\n", plcd_dimm_params->tDS_ps);
+       /* byte 35, spd->data_hold */
+       printf("tDH_ps = %u\n", plcd_dimm_params->tDH_ps);
+       /* byte 38, spd->trtp */
+       printf("tRTP_ps = %u\n", plcd_dimm_params->tRTP_ps);
+       /* byte 44, spd->tdqsq */
+       printf("tDQSQ_max_ps = %u\n", plcd_dimm_params->tDQSQ_max_ps);
+       /* byte 45, spd->tqhs */
+       printf("tQHS_ps = %u\n", plcd_dimm_params->tQHS_ps );
+
+
+       printf("lowest_common_SPD_caslat = %u\n",
+              plcd_dimm_params->lowest_common_SPD_caslat);
+       printf("highest_common_derated_caslat = %u\n",
+              plcd_dimm_params->highest_common_derated_caslat);
+       printf("additive_latency = %u\n", plcd_dimm_params->additive_latency);
+
+       printf("ndimms_present = %u\n", plcd_dimm_params->ndimms_present);
+       printf("all_DIMMs_burst_lengths_bitmask = %02X\n",
+              plcd_dimm_params->all_DIMMs_burst_lengths_bitmask);
+       printf("all_DIMMs_registered = %u\n",
+              plcd_dimm_params->all_DIMMs_registered);
+       printf("all_DIMMs_unbuffered = %u\n",
+              plcd_dimm_params->all_DIMMs_unbuffered);
+       printf("all_DIMMs_ECC_capable = %u\n",
+              plcd_dimm_params->all_DIMMs_ECC_capable);
+
+       printf("total_mem = %llu (%llu megabytes)\n",
+              plcd_dimm_params->total_mem,
+              plcd_dimm_params->total_mem / 0x100000);
+       printf("base_address = %llu (%llu megabytes)\n",
+              plcd_dimm_params->base_address,
+              plcd_dimm_params->base_address / 0x100000);
+}
+
+static void
+fsl_ddr_sdram_options_edit(fsl_ddr_sdram_info_t *pinfo,
+                          unsigned int ctrl_num,
+                          const char *optname_str,
+                          const char *value_str)
+{
+
+       /*
+        * This array all on the stack and *computed* each time this
+        * function is rung.
+        */
+       options_strings_uint_t options[] = {
+               {"memctl_interleaving",
+                &pinfo->memctl_options[ctrl_num].memctl_interleaving},
+               {"memctl_interleaving_mode",
+                &pinfo->memctl_options[ctrl_num].memctl_interleaving_mode},
+               {"ba_intlv_ctl",
+                &pinfo->memctl_options[ctrl_num].ba_intlv_ctl},
+               {"ecc_mode", &pinfo->memctl_options[ctrl_num].ECC_mode},
+               {"ECC_mode", &pinfo->memctl_options[ctrl_num].ECC_mode},
+               {"self_refresh_in_sleep",
+                &pinfo->memctl_options[ctrl_num].self_refresh_in_sleep},
+               {"dynamic_power",
+                &pinfo->memctl_options[ctrl_num].dynamic_power},
+               {"data_bus_width",
+                &pinfo->memctl_options[ctrl_num].data_bus_width},
+               {"burst_length",
+                &pinfo->memctl_options[ctrl_num].burst_length},
+               {"cas_latency_override",
+                &pinfo->memctl_options[ctrl_num].cas_latency_override},
+               {"cas_latency_override_value",
+                &pinfo->memctl_options[ctrl_num].cas_latency_override_value},
+               {"use_derated_caslat",
+                &pinfo->memctl_options[ctrl_num].use_derated_caslat},
+               {"additive_latency_override",
+                &pinfo->memctl_options[ctrl_num].additive_latency_override},
+               {"additive_latency_override_value",
+                
&pinfo->memctl_options[ctrl_num].additive_latency_override_value},
+               {"clk_adjust", &pinfo->memctl_options[ctrl_num].clk_adjust},
+               {"cpo_override",
+                &pinfo->memctl_options[ctrl_num].cpo_override},
+               {"write_data_delay",
+                &pinfo->memctl_options[ctrl_num].write_data_delay},
+               {"half_strength_driver_enable",
+                &pinfo->memctl_options[ctrl_num].half_strength_driver_enable},
+
+               /*
+                * These can probably be changed to 2T_EN and 3T_EN
+                * (using a leading numerical character) without problem
+                */
+               {"twoT_en", &pinfo->memctl_options[ctrl_num].twoT_en},
+               {"threeT_en", &pinfo->memctl_options[ctrl_num].threeT_en},
+               {"bstopre", &pinfo->memctl_options[ctrl_num].bstopre},
+               {"tCKE_clock_pulse_width_ps",
+                &pinfo->memctl_options[ctrl_num].tCKE_clock_pulse_width_ps},
+               {"tFAW_window_four_activates_ps",
+                &pinfo->memctl_options[ctrl_num].tFAW_window_four_activates_ps}
+       };
+
+       const unsigned int nopts = ARRAY_SIZE(options);
+
+       if (handle_uint_option_table(options, nopts, optname_str, value_str))
+               return;
+
+       printf("couldn't find option string %s\n", optname_str);
+}
+
+static void
+print_fsl_memctl_config_regs(const fsl_memctl_config_regs_t *ddr)
+{
+       unsigned int i;
+
+       for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+               printf("cs%u_bnds           = %08X\n", i, ddr->cs[i].bnds);
+               printf("cs%u_config         = %08X\n", i, ddr->cs[i].config);
+               printf("cs%u_config_2       = %08X\n", i, ddr->cs[i].config_2);
+       }
+
+       printf("timing_cfg_3       = %08X\n", ddr->timing_cfg_3);
+       printf("timing_cfg_0       = %08X\n", ddr->timing_cfg_0);
+       printf("timing_cfg_1       = %08X\n", ddr->timing_cfg_1);
+       printf("timing_cfg_2       = %08X\n", ddr->timing_cfg_2);
+       printf("ddr_sdram_cfg      = %08X\n", ddr->ddr_sdram_cfg);
+       printf("ddr_sdram_cfg_2    = %08X\n", ddr->ddr_sdram_cfg_2);
+       printf("ddr_sdram_mode     = %08X\n", ddr->ddr_sdram_mode);
+       printf("ddr_sdram_mode_2   = %08X\n", ddr->ddr_sdram_mode_2);
+       printf("ddr_sdram_interval = %08X\n", ddr->ddr_sdram_interval);
+       printf("ddr_data_init      = %08X\n", ddr->ddr_data_init);
+       printf("ddr_sdram_clk_cntl = %08X\n", ddr->ddr_sdram_clk_cntl);
+       printf("ddr_init_addr      = %08X\n", ddr->ddr_init_addr);
+       printf("ddr_init_ext_addr  = %08X\n", ddr->ddr_init_ext_addr);
+       printf("timing_cfg_4       = %08X\n", ddr->timing_cfg_4);
+       printf("timing_cfg_5       = %08X\n", ddr->timing_cfg_5);
+       printf("ddr_zq_cntl        = %08X\n", ddr->ddr_zq_cntl);
+       printf("ddr_wrlvl_cntl     = %08X\n", ddr->ddr_wrlvl_cntl);
+       printf("ddr_pd_cntl        = %08X\n", ddr->ddr_pd_cntl);
+       printf("ddr_sr_cntr        = %08X\n", ddr->ddr_sr_cntr);
+       printf("ddr_sdram_rcw_1    = %08X\n", ddr->ddr_sdram_rcw_1);
+       printf("ddr_sdram_rcw_2    = %08X\n", ddr->ddr_sdram_rcw_2);
+}
+
+static void
+fsl_ddr_sdram_regs_edit(fsl_ddr_sdram_info_t *pinfo,
+                       unsigned int ctrl_num,
+                       const char *regname,
+                       unsigned int value)
+{
+       unsigned int i;
+       fsl_memctl_config_regs_t *ddr;
+       char buf[20];
+
+       debug("fsl_ddr_sdram_regs_edit: ctrl_num = %u, regname = %s, value = 
0x%08X\n",
+              ctrl_num, regname, value);
+       if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS) {
+               return;
+       }
+
+       /*
+        * FIXME: Change this into struct like the other editing functions
+        */
+       ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]);
+
+       for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+               sprintf(buf, "cs%u_bnds", i);
+               if (strcmp(buf, regname) == 0) {
+                       ddr->cs[i].bnds = value;
+                       return;
+               }
+
+               sprintf(buf, "cs%u_config", i);
+               if (strcmp(buf, regname) == 0) {
+                       ddr->cs[i].config = value;
+                       return;
+               }
+
+               sprintf(buf, "cs%u_config_2", i);
+               if (strcmp(buf, regname) == 0) {
+                       ddr->cs[i].config_2 = value;
+                       return;
+               }
+       }
+
+       if (strcmp("timing_cfg_3", regname) == 0) {
+               ddr->timing_cfg_3 = value;
+               return;
+       }
+
+       if (strcmp("timing_cfg_0", regname) == 0) {
+               ddr->timing_cfg_0 = value;
+               return;
+       }
+
+       if (strcmp("timing_cfg_1", regname) == 0) {
+               ddr->timing_cfg_1 = value;
+               return;
+       }
+
+       if (strcmp("timing_cfg_2", regname) == 0) {
+               ddr->timing_cfg_2 = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_cfg", regname) == 0) {
+               ddr->ddr_sdram_cfg = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_cfg_2", regname) == 0) {
+               ddr->ddr_sdram_cfg_2 = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_mode", regname) == 0) {
+               ddr->ddr_sdram_mode = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_mode_2", regname) == 0) {
+               ddr->ddr_sdram_mode_2 = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_interval", regname) == 0) {
+               ddr->ddr_sdram_interval = value;
+               return;
+       }
+
+       if (strcmp("ddr_data_init", regname) == 0) {
+               ddr->ddr_data_init = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_clk_cntl", regname) == 0) {
+               ddr->ddr_sdram_clk_cntl = value;
+               return;
+       }
+
+       if (strcmp("ddr_init_addr", regname) == 0) {
+               ddr->ddr_init_addr = value;
+               return;
+       }
+
+       if (strcmp("ddr_init_ext_addr", regname) == 0) {
+               ddr->ddr_init_ext_addr = value;
+               return;
+       }
+
+       if (strcmp("timing_cfg_4", regname) == 0) {
+               ddr->timing_cfg_4 = value;
+               return;
+       }
+
+       if (strcmp("timing_cfg_5", regname) == 0) {
+               ddr->timing_cfg_5 = value;
+               return;
+       }
+
+       if (strcmp("ddr_zq_cntl", regname) == 0) {
+               ddr->ddr_zq_cntl = value;
+               return;
+       }
+
+       if (strcmp("ddr_wrlvl_cntl", regname) == 0) {
+               ddr->ddr_wrlvl_cntl = value;
+               return;
+       }
+
+       if (strcmp("ddr_pd_cntl", regname) == 0) {
+               ddr->ddr_pd_cntl = value;
+               return;
+       }
+
+       if (strcmp("ddr_sr_cntr", regname) == 0) {
+               ddr->ddr_sr_cntr = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_rcw_1", regname) == 0) {
+               ddr->ddr_sdram_rcw_1 = value;
+               return;
+       }
+
+       if (strcmp("ddr_sdram_rcw_2", regname) == 0) {
+               ddr->ddr_sdram_rcw_2 = value;
+               return;
+       }
+}
+
+static const char *
+get_sdram_type(unsigned int sdram_type)
+{
+       switch (sdram_type) {
+       case 2:
+               return "DDR1";
+       case 3:
+               return "DDR2";
+       case 6:
+               return "LPDDR1";
+       case 7:
+               return "DDR3";
+       }
+
+       return "unknown SDRAM type";
+}
+
+static void
+print_memctl_options(const memctl_options_t *popts)
+{
+
+       /*
+        * Special configurations for chip select
+        */
+       printf("memctl_interleaving = %u\n", popts->memctl_interleaving );
+       printf("memctl_interleaving_mode = %u\n",
+              popts->memctl_interleaving_mode);
+       printf("ba_intlv_ctl = 0x%02X\n", popts->ba_intlv_ctl );
+
+       /*
+        * Operational mode parameters
+        */
+       /* 2 = DDR1, 3 = DDR2, 6 = LPDDR1, 7 = DDR3 */
+       printf("sdram_type = %u (%s)\n",
+              popts->sdram_type, get_sdram_type(popts->sdram_type));
+
+       printf("ECC_mode = %u\n", popts->ECC_mode );     /* Use ECC? */
+
+       /* Initialize ECC using memory controller? */
+       printf("ECC_init_using_memctl = %u\n", popts->ECC_init_using_memctl);
+
+       /* Use DQS? maybe only with DDR2? */
+       printf("DQS_config = %u\n", popts->DQS_config);
+
+       /* SREN - self-refresh during sleep */
+       printf("self_refresh_in_sleep = %u\n", popts->self_refresh_in_sleep);
+
+       /* DYN_PWR */
+       printf("dynamic_power = %u\n", popts->dynamic_power);
+
+       /* memory data width to use (16-bit, 32-bit, 64-bit) */
+       printf("data_bus_width = %u\n", popts->data_bus_width);
+
+       /* 4, 8 */
+       printf("burst_length = %u\n", popts->burst_length);
+
+       /*
+        * Global Timing Parameters
+        */
+       printf("cas_latency_override = %u\n", popts->cas_latency_override);
+       printf("cas_latency_override_value = %u\n",
+              popts->cas_latency_override_value);
+       printf("use_derated_caslat = %u\n", popts->use_derated_caslat);
+       printf("additive_latency_override = %u\n",
+              popts->additive_latency_override);
+       printf("additive_latency_override_value = %u\n",
+              popts->additive_latency_override_value);
+       printf("clk_adjust = %u\n", popts->clk_adjust);
+       printf("cpo_override = %u\n", popts->cpo_override);
+       /* DQS adjust */
+       printf("write_data_delay = %u\n", popts->write_data_delay);
+       printf("half_strength_driver_enable = %u\n",
+              popts->half_strength_driver_enable);
+       printf("twoT_en = %u\n", popts->twoT_en);
+       printf("threeT_en = %u\n", popts->threeT_en);
+       printf("bstopre = %u\n", popts->bstopre);
+       /* tCKE */
+       printf("tCKE_clock_pulse_width_ps = %u\n",
+              popts->tCKE_clock_pulse_width_ps);
+       /* tFAW --  FOUR_ACT */
+       printf("tFAW_window_four_activates_ps = %u\n",
+              popts->tFAW_window_four_activates_ps);
+}
+
+static __inline__ void
+generic_spd_dump(const generic_spd_eeprom_t *spd)
+{
+#if defined(CONFIG_FSL_DDR1)
+       ddr1_spd_dump(spd);
+#elif defined(CONFIG_FSL_DDR2)
+       ddr2_spd_dump(spd);
+#elif defined(CONFIG_FSL_DDR3)
+#error "Implement generic_spd_dump() for DDR3"
+#endif
+}
+
+static void
+fsl_ddr_sdram_printinfo(const fsl_ddr_sdram_info_t *pinfo,
+                       unsigned int ctrl_mask,
+                       unsigned int dimm_mask,
+                       unsigned int do_mask)
+{
+       unsigned int i;
+       unsigned int j;
+       unsigned int retval;
+
+       /*
+        * INFO 1:  DIMM SPD data
+        */
+       if (do_mask & STEP_GET_SPD) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               /*
+                                * FIXME: find a way to make this
+                                * generate more optimal powerpc code
+                                * (i.e. rlwimi.)
+                                */
+                               for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; 
j++) {
+                                       if (dimm_mask & (1 << j)) {
+                                               printf("SPD info:  
Controller=%u DIMM=%u\n", i, j);
+                                               
generic_spd_dump(&(pinfo->spd_installed_dimms[i][j]));
+                                               printf("\n");
+                                       }
+                               }
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       /*
+        * INFO 2:  DIMM Parameters
+        */
+       if (do_mask & STEP_COMPUTE_DIMM_PARMS) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; 
j++) {
+                                       if (dimm_mask & (1 << j)) {
+                                               printf("DIMM parameters:  
Controller=%u DIMM=%u\n", i, j);
+                                               
print_dimm_parameters(&(pinfo->dimm_params[i][j]));
+                                               printf("\n");
+                                       }
+                               }
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       /*
+        * INFO 3:  Common Parameters
+        */
+       if (do_mask & STEP_COMPUTE_COMMON_PARMS) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               printf("\"lowest common\" DIMM parameters:  
Controller=%u\n", i);
+                               
print_lowest_common_dimm_parameters(&pinfo->common_timing_params[i]);
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       /*
+        * STEP 4:  User Configuration Options
+        */
+       if (do_mask & STEP_GATHER_OPTS) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               printf("User Config Options: Controller=%u\n", 
i);
+                               print_memctl_options(&pinfo->memctl_options[i]);
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       /*
+        * STEP 5:  Address assignment
+        */
+       if (do_mask & STEP_ASSIGN_ADDRESSES) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; 
j++) {
+                                       printf("Address Assignment: 
Controller=%u DIMM=%u\n", i, j);
+                                       printf("Don't have this functionality 
yet\n");
+                               }
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       /*
+        * STEP 6:  computed controller register values
+        */
+       if (do_mask & STEP_COMPUTE_REGS) {
+               for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
+                       if (ctrl_mask & (1 << i)) {
+                               printf("Computed Register Values: 
Controller=%u\n", i);
+                               
print_fsl_memctl_config_regs(&pinfo->fsl_ddr_config_reg[i]);
+                               retval = 
check_fsl_memctl_config_regs(&pinfo->fsl_ddr_config_reg[i]);
+                               if (retval) {
+                                       printf("check_fsl_memctl_config_regs 
result = %u\n", retval);
+                               }
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+}
+
+
+
+
+phys_size_t
+fsl_ddr_interactive(fsl_ddr_sdram_info_t *pinfo)
+{
+       phys_size_t ddrsize;
+       const char *prompt = "FSL DDR>";
+       unsigned int len;
+       char buffer[CFG_CBSIZE];
+       char *argv[CFG_MAXARGS + 1];            /* NULL terminated */
+       int argc;
+       unsigned int next_step = STEP_GET_SPD;
+
+       /*
+        * The strategy for next_step is that it points to the next
+        * step in the computation process that needs to be done.
+        */
+       while (1) {
+               /*
+                * No need to worry for buffer overflow here in
+                * this function;  readline() maxes out at CFG_CBSIZE
+                */
+               len = readline_into_buffer(prompt,  buffer);
+               argc = parse_line(buffer, argv);
+               if (argc == 0) {
+                       continue;
+               }
+
+               if (strcmp(argv[0], "help") == 0) {
+
+                       /*
+                        * FIXME: For some reason printing this whole
+                        * thing causes the machine to freeze.
+                        * Splitting it into two printfs seems to make
+                        * it work Does printf() have limits on the
+                        * length of the string?
+                        */
+                       printf(
+       "commands:\n"
+       "print      print SPD and intermediate computed data\n"
+       "reset      reboot machine\n"
+       "recompute  reload SPD and options to default and recompute 
registers\n");
+                       printf(
+       "compute    recompute registers from current next_step to end\n"
+       "next_step  shows current next_step\n"
+       "help       this message\n"
+       "go         program the memory controller and continue with u-boot\n"
+              );
+                       continue;
+               }
+
+               if (strcmp(argv[0], "next_step") == 0) {
+                       printf("next_step = 0x%02X (%s)\n",
+                              next_step,
+                              step_to_string(__ilog2(next_step)));
+                       continue;
+               }
+
+               if (strcmp(argv[0], "edit") == 0) {
+                       unsigned int i;
+                       unsigned int error = 0;
+                       unsigned int step_mask = 0;
+                       unsigned int ctlr_mask = 0;
+                       unsigned int dimm_mask = 0;
+                       char *p_element = NULL;
+                       char *p_value = NULL;
+                       unsigned int dimm_number_required = 0;
+                       unsigned int ctrl_num;
+                       unsigned int dimm_num;
+
+                       if (argc == 1) {
+                               /*
+                                * Only the element and value must be last
+                                */
+                               printf("edit <c#> <d#> 
<spd|dimmparms|commonparms|opts|addresses|regs> <element> <value>\n");
+                               continue;
+                       }
+
+                       for (i = 1; i < argc - 2; i++) {
+                               if (strcmp(argv[i], "spd") == 0) {
+                                       step_mask |= STEP_GET_SPD;
+                                       dimm_number_required = 1;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "dimmparms") == 0) {
+                                       step_mask |= STEP_COMPUTE_DIMM_PARMS;
+                                       dimm_number_required = 1;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "commonparms") == 0) {
+                                       step_mask |= STEP_COMPUTE_COMMON_PARMS;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "opts") == 0) {
+                                       step_mask |= STEP_GATHER_OPTS;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "addresses") == 0) {
+                                       step_mask |= STEP_ASSIGN_ADDRESSES;
+                                       /*  FIXME: not done yet */
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "regs") == 0) {
+                                       step_mask |= STEP_COMPUTE_REGS;
+                                       continue;
+                               }
+
+                               if (argv[i][0] == 'c') {
+                                       char c = argv[i][1];
+                                       if (is_a_num_char(c)) {
+                                               ctlr_mask |= 1 << (c - '0');
+                                       }
+                                       continue;
+                               }
+
+                               if (argv[i][0] == 'd') {
+                                       char c = argv[i][1];
+                                       if (is_a_num_char(c)) {
+                                               dimm_mask |= 1 << (c - '0');
+                                       }
+                                       continue;
+                               }
+
+                               printf("unknown arg %s\n", argv[i]);
+                               step_mask = 0;
+                               error = 1;
+                               break;
+                       }
+
+
+                       if (error) {
+                               continue;
+                       }
+
+
+                       /*
+                        * Check arguments
+                        */
+
+                       /*
+                        * ERROR: If no steps were found
+                        */
+                       if (step_mask == 0) {
+                               printf("Error: No valid steps were specified in 
argument.\n");
+                               continue;
+                       }
+
+                       /*
+                        * ERROR: If multiple steps were found
+                        */
+                       if (step_mask & (step_mask - 1)) {
+                               printf("Error: Multiple steps specified in 
argument.\n");
+                               continue;
+                       }
+
+                       /*
+                        * ERROR: Controller not specified
+                        */
+                       if (ctlr_mask == 0) {
+                               printf("Error: controller number not specified 
or no element and value specified\n");
+                               continue;
+                       }
+
+                       if (ctlr_mask & (ctlr_mask - 1)) {
+                               printf("Error: multiple controllers specified, 
%X\n", ctlr_mask);
+                               continue;
+                       }
+
+                       /*
+                        * ERROR: DIMM number not specified
+                        */
+                       if (dimm_number_required && dimm_mask == 0) {
+                               printf("Error: DIMM number number not specified 
or no element and value specified\n");
+                               continue;
+                       }
+
+                       if (dimm_mask & (dimm_mask - 1)) {
+                               printf("Error: multipled DIMMs specified\n");
+                               continue;
+                       }
+
+                       p_element = argv[argc - 2];
+                       p_value = argv[argc - 1];
+
+                       ctrl_num = __ilog2(ctlr_mask);
+                       dimm_num = __ilog2(dimm_mask);
+
+                       switch (step_mask) {
+                       case STEP_GET_SPD:
+                               {
+                                       unsigned int element_num;
+                                       unsigned int value;
+
+                                       element_num = simple_strtoul(p_element,
+                                                                    NULL, 0);
+                                       value = simple_strtoul(p_value,
+                                                              NULL, 0);
+                                       fsl_ddr_sdram_spd_edit(pinfo,
+                                                              ctrl_num,
+                                                              dimm_num,
+                                                              element_num,
+                                                              value);
+                                       next_step = STEP_COMPUTE_DIMM_PARMS;
+                               }
+                               break;
+
+                       case STEP_COMPUTE_DIMM_PARMS:
+                               fsl_ddr_sdram_dimm_parameters_edit(
+                                                pinfo, ctrl_num, dimm_num,
+                                                p_element, p_value);
+                               next_step = STEP_COMPUTE_COMMON_PARMS;
+                               break;
+
+                       case STEP_COMPUTE_COMMON_PARMS:
+                               
fsl_ddr_sdram_lowest_common_dimm_parameters_edit(pinfo, ctrl_num, p_element, 
p_value);
+                               next_step = STEP_GATHER_OPTS;
+                               break;
+
+                       case STEP_GATHER_OPTS:
+                               fsl_ddr_sdram_options_edit(pinfo, ctrl_num,
+                                                          p_element, p_value);
+                               next_step = STEP_ASSIGN_ADDRESSES;
+                               break;
+
+                       case STEP_ASSIGN_ADDRESSES:
+                               printf("editing of address assignment not yet 
implemented\n");
+                               break;
+
+                       case STEP_COMPUTE_REGS:
+                               {
+                                       unsigned int value;
+
+                                       value = simple_strtoul(p_value,
+                                                              NULL, 0);
+                                       fsl_ddr_sdram_regs_edit(pinfo,
+                                                               ctrl_num,
+                                                               p_element,
+                                                               value);
+                                       next_step = STEP_PROGRAM_REGS;
+                               }
+                               break;
+
+                       default:
+                               printf("programming error\n");
+                               while (1);
+                               break;
+                       }
+                       continue;
+               }
+
+               if (strcmp(argv[0], "reset") == 0) {
+                       /*
+                        * Reboot machine.
+                        * Args don't seem to matter because this
+                        * doesn't return
+                        */
+                       do_reset(NULL, 0, 0, NULL);
+               }
+
+               if (strcmp(argv[0], "recompute") == 0) {
+                       /*
+                        * Recalculate everything, starting with
+                        * loading SPD EEPROM from DIMMs
+                        */
+                       next_step = STEP_GET_SPD;
+                       ddrsize = fsl_ddr_sdram_compute(pinfo, next_step);
+                       /*
+                        * FIXME: There some problems with this.
+                        * For exmaple, what happens if there is
+                        * an error inside fsl_ddr_sdram_compute?
+                        */
+                       continue;
+               }
+
+               if (strcmp(argv[0], "compute") == 0) {
+                       /*
+                        * Compute rest of steps starting at
+                        * the current next_step/
+                        */
+                       ddrsize = fsl_ddr_sdram_compute(pinfo, next_step);
+                       continue;
+               }
+
+               if (strcmp(argv[0], "print") == 0) {
+                       unsigned int i;
+                       unsigned int error = 0;
+                       unsigned int step_mask = 0;
+                       unsigned int ctlr_mask = 0;
+                       unsigned int dimm_mask = 0;
+
+                       if (argc == 1) {
+                               printf("print [c<n>] [d<n>] [spd] [dimmparms] 
[commonparms] [opts] [addresses] [regs]\n");
+                               continue;
+                       }
+
+                       for (i = 1; i < argc; i++) {
+                               if (strcmp(argv[i], "spd") == 0) {
+                                       step_mask |= STEP_GET_SPD;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "dimmparms") == 0) {
+                                       step_mask |= STEP_COMPUTE_DIMM_PARMS;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "commonparms") == 0) {
+                                       step_mask |= STEP_COMPUTE_COMMON_PARMS;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "opts") == 0) {
+                                       step_mask |= STEP_GATHER_OPTS;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "addresses") == 0) {
+                                       step_mask |= STEP_ASSIGN_ADDRESSES;
+                                       continue;
+                               }
+
+                               if (strcmp(argv[i], "regs") == 0) {
+                                       step_mask |= STEP_COMPUTE_REGS;
+                                       continue;
+                               }
+
+                               if (argv[i][0] == 'c') {
+                                       char c = argv[i][1];
+                                       if (c >= '0' && c <= '9') {
+                                               ctlr_mask |= 1 << (c - '0');
+                                       }
+                                       continue;
+                               }
+
+                               if (argv[i][0] == 'd') {
+                                       char c = argv[i][1];
+                                       if (c >= '0' && c <= '9') {
+                                               dimm_mask |= 1 << (c - '0');
+                                       }
+                                       continue;
+                               }
+
+                               printf("unknown arg %s\n", argv[i]);
+                               step_mask = 0;
+                               error = 1;
+                               break;
+                       }
+
+                       if (error) {
+                               continue;
+                       }
+
+                       /*
+                        * If no particular controller was found,
+                        * print all controllers.
+                        */
+                       if (ctlr_mask == 0) {
+                               ctlr_mask = 0xFF;
+                       }
+
+                       /*
+                        * If no particular dimm was found, print all dimms.
+                        */
+                       if (dimm_mask == 0) {
+                               dimm_mask = 0xFF;
+                       }
+
+                       /*
+                        * If no steps were found, print all steps.
+                        */
+                       if (step_mask == 0) {
+                               step_mask = STEP_ALL;
+                       }
+
+                       fsl_ddr_sdram_printinfo(pinfo, ctlr_mask,
+                                               dimm_mask, step_mask);
+                       continue;
+               }
+
+               if (strcmp(argv[0], "go") == 0) {
+                       if (next_step) {
+                               ddrsize = fsl_ddr_sdram_compute(pinfo,  
+                                                               next_step);
+                       }
+                       break;
+               }
+
+               printf("unknown command %s\n", argv[0]);
+       }
+
+       debug("end of memory = %llu\n", (u64)ddrsize);
+
+       return ddrsize;
+}
+
+
diff --git a/cpu/mpc8xxx/fsl_ddr_sdram.c b/cpu/mpc8xxx/fsl_ddr_sdram.c
index 72af6ac..457cff3 100644
--- a/cpu/mpc8xxx/fsl_ddr_sdram.c
+++ b/cpu/mpc8xxx/fsl_ddr_sdram.c
@@ -2370,6 +2370,16 @@ phys_size_t fsl_ddr_sdram(void)
         */
        total_memory = fsl_ddr_sdram_compute(&info, STEP_GET_SPD);
 
+#ifdef CONFIG_FSL_DDR_INTERACTIVE
+       /*
+        * The presence of the environment variable "ddrsetup"
+        * causes the interactive DDR setup prompt to appear.
+        */
+       if (getenv("ddrsetup")) {
+               total_memory = fsl_ddr_interactive(&info);
+       }
+#endif
+
        /*
         * Check for memory controller interleaving.
         */
diff --git a/cpu/mpc8xxx/fsl_ddr_sdram.h b/cpu/mpc8xxx/fsl_ddr_sdram.h
index 0ac44a7..4034e9c 100644
--- a/cpu/mpc8xxx/fsl_ddr_sdram.h
+++ b/cpu/mpc8xxx/fsl_ddr_sdram.h
@@ -54,6 +54,9 @@ typedef struct {
 
 
 extern phys_size_t
+fsl_ddr_interactive(fsl_ddr_sdram_info_t *pinfo);
+
+extern phys_size_t
 fsl_ddr_sdram_compute(fsl_ddr_sdram_info_t *pinfo,
                                  unsigned int start_step);
 
-- 
1.5.5.1


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
U-Boot-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/u-boot-users

Reply via email to