Add copy command to FSL DDR interactive
authorJames Yang <James.Yang@freescale.com>
Fri, 4 Jan 2013 08:14:02 +0000 (08:14 +0000)
committerAndy Fleming <afleming@freescale.com>
Wed, 30 Jan 2013 17:25:13 +0000 (11:25 -0600)
Add copy command which allows copying of DIMM/controller settings.
This saves tedious retyping of parameters for each identical DIMM
or controller.

Signed-off-by: James Yang <James.Yang@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
doc/README.fsl-ddr

index 0474acc30a58b7ceaed132566a883fd5b18d0795..e5ee7754640c6023920f1583fea6a62b03f2820e 100644 (file)
@@ -1445,6 +1445,7 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo)
                "recompute  reload SPD and options to default and recompute regs\n"
                "edit       modify spd, parameter, or option\n"
                "compute    recompute registers from current next_step to end\n"
+               "copy       copy parameters\n"
                "next_step  shows current next_step\n"
                "help       this message\n"
                "go         program the memory controller and continue with u-boot\n"
@@ -1477,6 +1478,132 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo)
                        continue;
                }
 
+               if (strcmp(argv[0], "copy") == 0) {
+                       unsigned int error = 0;
+                       unsigned int step_mask = 0;
+                       unsigned int src_ctlr_mask = 0;
+                       unsigned int src_dimm_mask = 0;
+                       unsigned int dimm_number_required = 0;
+                       unsigned int src_ctlr_num = 0;
+                       unsigned int src_dimm_num = 0;
+                       unsigned int dst_ctlr_num = -1;
+                       unsigned int dst_dimm_num = -1;
+                       unsigned int i, num_dest_parms;
+
+                       if (argc == 1) {
+                               printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n");
+                               continue;
+                       }
+
+                       error = fsl_ddr_parse_interactive_cmd(
+                               argv, argc,
+                               &step_mask,
+                               &src_ctlr_mask,
+                               &src_dimm_mask,
+                               &dimm_number_required
+                       );
+
+                       /* XXX: only dimm_number_required and step_mask will
+                          be used by this function.  Parse the controller and
+                          DIMM number separately because it is easier.  */
+
+                       if (error)
+                               continue;
+
+                       /* parse source destination controller / DIMM */
+
+                       num_dest_parms = dimm_number_required ? 2 : 1;
+
+                       for (i = 0; i < argc; i++) {
+                               if (argv[i][0] == 'c') {
+                                       char c = argv[i][1];
+                                       if (isdigit(c)) {
+                                               src_ctlr_num = (c - '0');
+                                               break;
+                                       }
+                               }
+                       }
+
+                       for (i = 0; i < argc; i++) {
+                               if (argv[i][0] == 'd') {
+                                       char c = argv[i][1];
+                                       if (isdigit(c)) {
+                                               src_dimm_num = (c - '0');
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /* parse destination controller / DIMM */
+
+                       for (i = argc - 1; i >= argc - num_dest_parms; i--) {
+                               if (argv[i][0] == 'c') {
+                                       char c = argv[i][1];
+                                       if (isdigit(c)) {
+                                               dst_ctlr_num = (c - '0');
+                                               break;
+                                       }
+                               }
+                       }
+
+                       for (i = argc - 1; i >= argc - num_dest_parms; i--) {
+                               if (argv[i][0] == 'd') {
+                                       char c = argv[i][1];
+                                       if (isdigit(c)) {
+                                               dst_dimm_num = (c - '0');
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /* TODO: validate inputs */
+
+                       debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n",
+                               src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask);
+
+
+                       switch (step_mask) {
+
+                       case STEP_GET_SPD:
+                               memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]),
+                                       &(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]),
+                                       sizeof(pinfo->spd_installed_dimms[0][0]));
+                               break;
+
+                       case STEP_COMPUTE_DIMM_PARMS:
+                               memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]),
+                                       &(pinfo->dimm_params[src_ctlr_num][src_dimm_num]),
+                                       sizeof(pinfo->dimm_params[0][0]));
+                               break;
+
+                       case STEP_COMPUTE_COMMON_PARMS:
+                               memcpy(&(pinfo->common_timing_params[dst_ctlr_num]),
+                                       &(pinfo->common_timing_params[src_ctlr_num]),
+                                       sizeof(pinfo->common_timing_params[0]));
+                               break;
+
+                       case STEP_GATHER_OPTS:
+                               memcpy(&(pinfo->memctl_opts[dst_ctlr_num]),
+                                       &(pinfo->memctl_opts[src_ctlr_num]),
+                                       sizeof(pinfo->memctl_opts[0]));
+                               break;
+
+                       /* someday be able to have addresses to copy addresses... */
+
+                       case STEP_COMPUTE_REGS:
+                               memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]),
+                                       &(pinfo->fsl_ddr_config_reg[src_ctlr_num]),
+                                       sizeof(pinfo->memctl_opts[0]));
+                               break;
+
+                       default:
+                               printf("unexpected step_mask value\n");
+                       }
+
+                       continue;
+
+               }
+
                if (strcmp(argv[0], "edit") == 0) {
                        unsigned int error = 0;
                        unsigned int step_mask = 0;
index 59583b3fcdef722c0bbea9498d47ad4ae5ebb885..b2a7c0fab4e2aaf85b46b0bdb41d6e92b17cf9d8 100644 (file)
@@ -279,6 +279,7 @@ The example flow of using interactive debugging is
 type command "compute" to calculate the parameters from the default
 type command "print" with arguments to show SPD, options, registers
 type command "edit" with arguments to change any if desired
+type command "copy" with arguments to copy controller/dimm settings
 type command "go" to continue calculation and enable DDR controller
 type command "reset" to reset the board
 type command "recompute" to reload SPD and start over
@@ -313,6 +314,10 @@ edit <c#> <d#> <spd|dimmparms|commonparms|opts|addresses|regs> <element> <value>
                          byte number if the object is SPD
        <value>         - decimal or heximal (prefixed with 0x) numbers
 
+copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>
+       same as for "edit" command
+       DIMM numbers ignored for commonparms, opts, and regs
+
 reset
        no arguement    - reset the board