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