X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=arch%2Fpowerpc%2Fcpu%2Fmpc8xxx%2Fddr%2Finteractive.c;h=46257c9529ef924dc0c92827d0591a8231d18f48;hb=951c6baaf44c7fd4335b75fb92840d4e42c94927;hp=d7d66ef4917826cae369509095323ea0eab582f0;hpb=6f5e1dc531d6b4a975e39054fdf7c737cbb4d8e9;p=karo-tx-uboot.git diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c index d7d66ef491..46257c9529 100644 --- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c +++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2010-2012 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 @@ -452,6 +452,8 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, CTRL_OPTIONS(rcw_override), CTRL_OPTIONS(rcw_1), CTRL_OPTIONS(rcw_2), + CTRL_OPTIONS(ddr_cdr1), + CTRL_OPTIONS(ddr_cdr2), CTRL_OPTIONS(tCKE_clock_pulse_width_ps), CTRL_OPTIONS(tFAW_window_four_activates_ps), CTRL_OPTIONS(trwt_override), @@ -518,6 +520,8 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) CFG_REGS(timing_cfg_5), CFG_REGS(ddr_zq_cntl), CFG_REGS(ddr_wrlvl_cntl), + CFG_REGS(ddr_wrlvl_cntl_2), + CFG_REGS(ddr_wrlvl_cntl_3), CFG_REGS(ddr_sr_cntr), CFG_REGS(ddr_sdram_rcw_1), CFG_REGS(ddr_sdram_rcw_2), @@ -525,6 +529,7 @@ static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) CFG_REGS(ddr_cdr2), CFG_REGS(err_disable), CFG_REGS(err_int_en), + CFG_REGS(ddr_eor), }; static const unsigned int n_opts = ARRAY_SIZE(options); @@ -584,6 +589,8 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, CFG_REGS(timing_cfg_5), CFG_REGS(ddr_zq_cntl), CFG_REGS(ddr_wrlvl_cntl), + CFG_REGS(ddr_wrlvl_cntl_2), + CFG_REGS(ddr_wrlvl_cntl_3), CFG_REGS(ddr_sr_cntr), CFG_REGS(ddr_sdram_rcw_1), CFG_REGS(ddr_sdram_rcw_2), @@ -593,7 +600,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, CFG_REGS(err_int_en), CFG_REGS(ddr_sdram_rcw_2), CFG_REGS(ddr_sdram_rcw_2), - + CFG_REGS(ddr_eor), }; static const unsigned int n_opts = ARRAY_SIZE(options); @@ -689,6 +696,8 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS(rcw_override), CTRL_OPTIONS(rcw_1), CTRL_OPTIONS(rcw_2), + CTRL_OPTIONS_HEX(ddr_cdr1), + CTRL_OPTIONS_HEX(ddr_cdr2), CTRL_OPTIONS(tCKE_clock_pulse_width_ps), CTRL_OPTIONS(tFAW_window_four_activates_ps), CTRL_OPTIONS(trwt_override), @@ -1047,7 +1056,7 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) /* General Section: Bytes 0-59 */ -#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, y); +#define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); #define PRINT_NNXXS(n0, n1, x0, x1, s) \ printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); @@ -1121,11 +1130,21 @@ void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) "therm_sensor SDRAM Thermal Sensor"); PRINT_NXS(33, spd->device_type, "device_type SDRAM Device Type"); - - printf("%-3d-%3d: ", 34, 59); /* Reserved, General Section */ - - for (i = 34; i <= 59; i++) - printf("%02x ", spd->res_34_59[i - 34]); + PRINT_NXS(34, spd->fine_tCK_min, + "fine_tCK_min Fine offset for tCKmin"); + PRINT_NXS(35, spd->fine_tAA_min, + "fine_tAA_min Fine offset for tAAmin"); + PRINT_NXS(36, spd->fine_tRCD_min, + "fine_tRCD_min Fine offset for tRCDmin"); + PRINT_NXS(37, spd->fine_tRP_min, + "fine_tRP_min Fine offset for tRPmin"); + PRINT_NXS(38, spd->fine_tRC_min, + "fine_tRC_min Fine offset for tRCmin"); + + printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ + + for (i = 39; i <= 59; i++) + printf("%02x ", spd->res_39_59[i - 39]); puts("\n"); @@ -1350,15 +1369,15 @@ struct data_strings { #define DATA_OPTIONS(name, step, dimm) {#name, step, dimm} -unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) -{ - unsigned long long ddrsize; - const char *prompt = "FSL DDR>"; - unsigned int len; - char buffer[CONFIG_SYS_CBSIZE]; - char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ - int argc; - unsigned int next_step = STEP_GET_SPD; +static unsigned int fsl_ddr_parse_interactive_cmd( + char **argv, + int argc, + unsigned int *pstep_mask, + unsigned int *pctlr_mask, + unsigned int *pdimm_mask, + unsigned int *pdimm_number_required + ) { + static const struct data_strings options[] = { DATA_OPTIONS(spd, STEP_GET_SPD, 1), DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1), @@ -1368,6 +1387,69 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0), }; static const unsigned int n_opts = ARRAY_SIZE(options); + + unsigned int i, j; + unsigned int error = 0; + + for (i = 1; i < argc; i++) { + unsigned int matched = 0; + + for (j = 0; j < n_opts; j++) { + if (strcmp(options[j].data_name, argv[i]) != 0) + continue; + *pstep_mask |= options[j].step_mask; + *pdimm_number_required = + options[j].dimm_number_required; + matched = 1; + break; + } + + if (matched) + continue; + + if (argv[i][0] == 'c') { + char c = argv[i][1]; + if (isdigit(c)) + *pctlr_mask |= 1 << (c - '0'); + continue; + } + + if (argv[i][0] == 'd') { + char c = argv[i][1]; + if (isdigit(c)) + *pdimm_mask |= 1 << (c - '0'); + continue; + } + + printf("unknown arg %s\n", argv[i]); + *pstep_mask = 0; + error = 1; + break; + } + + return error; +} + +int fsl_ddr_interactive_env_var_exists(void) +{ + char buffer[CONFIG_SYS_CBSIZE]; + + if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0) + return 1; + + return 0; +} + +unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set) +{ + unsigned long long ddrsize; + const char *prompt = "FSL DDR>"; + char buffer[CONFIG_SYS_CBSIZE]; + char buffer2[CONFIG_SYS_CBSIZE]; + char *p = NULL; + char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ + int argc; + unsigned int next_step = STEP_GET_SPD; const char *usage = { "commands:\n" "print print SPD and intermediate computed data\n" @@ -1375,21 +1457,45 @@ 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" }; + if (var_is_set) { + if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) { + p = buffer2; + } else { + var_is_set = 0; + } + } + /* * 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); + if (var_is_set) { + char *pend = strchr(p, ';'); + if (pend) { + /* found command separator, copy sub-command */ + *pend = '\0'; + strcpy(buffer, p); + p = pend + 1; + } else { + /* separator not found, copy whole string */ + strcpy(buffer, p); + p = NULL; + var_is_set = 0; + } + } else { + /* + * No need to worry for buffer overflow here in + * this function; readline() maxes out at CFG_CBSIZE + */ + readline_into_buffer(prompt, buffer, 0); + } argc = parse_line(buffer, argv); if (argc == 0) continue; @@ -1407,64 +1513,160 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) continue; } - if (strcmp(argv[0], "edit") == 0) { - unsigned int i, j; + if (strcmp(argv[0], "copy") == 0) { 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 src_ctlr_mask = 0; + unsigned int src_dimm_mask = 0; unsigned int dimm_number_required = 0; - unsigned int ctrl_num; - unsigned int dimm_num; - unsigned int matched = 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) { - /* Only the element and value must be last */ - printf("edit " - " \n"); - printf("for spd, specify byte number for " - "element\n"); + printf("copy \n"); continue; } - for (i = 1; i < argc - 2; i++) { - for (j = 0; j < n_opts; j++) { - if (strcmp(options[j].data_name, - argv[i]) != 0) - continue; - step_mask |= options[j].step_mask; - dimm_number_required = - options[j].dimm_number_required; - matched = 1; - break; + 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; + } } + } - if (matched) - continue; + /* 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)) - ctlr_mask |= 1 << (c - '0'); - continue; + 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)) - dimm_mask |= 1 << (c - '0'); - continue; + 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; - printf("unknown arg %s\n", argv[i]); - step_mask = 0; - error = 1; + 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; + 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 " + " \n"); + printf("for spd, specify byte number for " + "element\n"); + continue; } + error = fsl_ddr_parse_interactive_cmd( + argv, argc - 2, + &step_mask, + &ctlr_mask, + &dimm_mask, + &dimm_number_required + ); if (error) continue; @@ -1588,6 +1790,7 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) * doesn't return */ do_reset(NULL, 0, 0, NULL); + printf("Reset didn't work\n"); } if (strcmp(argv[0], "recompute") == 0) { @@ -1610,12 +1813,11 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) } if (strcmp(argv[0], "print") == 0) { - unsigned int i, j; unsigned int error = 0; unsigned int step_mask = 0; unsigned int ctlr_mask = 0; unsigned int dimm_mask = 0; - unsigned int matched = 0; + unsigned int dimm_number_required = 0; if (argc == 1) { printf("print [c] [d] [spd] [dimmparms] " @@ -1623,38 +1825,13 @@ unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo) continue; } - for (i = 1; i < argc; i++) { - for (j = 0; j < n_opts; j++) { - if (strcmp(options[j].data_name, - argv[i]) != 0) - continue; - step_mask |= options[j].step_mask; - matched = 1; - break; - } - - if (matched) - continue; - - if (argv[i][0] == 'c') { - char c = argv[i][1]; - if (isdigit(c)) - ctlr_mask |= 1 << (c - '0'); - continue; - } - - if (argv[i][0] == 'd') { - char c = argv[i][1]; - if (isdigit(c)) - dimm_mask |= 1 << (c - '0'); - continue; - } - - printf("unknown arg %s\n", argv[i]); - step_mask = 0; - error = 1; - break; - } + error = fsl_ddr_parse_interactive_cmd( + argv, argc, + &step_mask, + &ctlr_mask, + &dimm_mask, + &dimm_number_required + ); if (error) continue;