15614e71bSYork Sun /* 234e026f9SYork Sun * Copyright 2010-2014 Freescale Semiconductor, Inc. 35614e71bSYork Sun * 45614e71bSYork Sun * SPDX-License-Identifier: GPL-2.0+ 55614e71bSYork Sun */ 65614e71bSYork Sun 75614e71bSYork Sun /* 85614e71bSYork Sun * Generic driver for Freescale DDR/DDR2/DDR3 memory controller. 95614e71bSYork Sun * Based on code from spd_sdram.c 105614e71bSYork Sun * Author: James Yang [at freescale.com] 115614e71bSYork Sun * York Sun [at freescale.com] 125614e71bSYork Sun */ 135614e71bSYork Sun 145614e71bSYork Sun #include <common.h> 1518d66533SSimon Glass #include <cli.h> 165614e71bSYork Sun #include <linux/ctype.h> 175614e71bSYork Sun #include <asm/types.h> 185614e71bSYork Sun #include <asm/io.h> 195614e71bSYork Sun 205614e71bSYork Sun #include <fsl_ddr_sdram.h> 215614e71bSYork Sun #include <fsl_ddr.h> 225614e71bSYork Sun 235614e71bSYork Sun /* Option parameter Structures */ 245614e71bSYork Sun struct options_string { 255614e71bSYork Sun const char *option_name; 265614e71bSYork Sun size_t offset; 275614e71bSYork Sun unsigned int size; 285614e71bSYork Sun const char printhex; 295614e71bSYork Sun }; 305614e71bSYork Sun 315614e71bSYork Sun static unsigned int picos_to_mhz(unsigned int picos) 325614e71bSYork Sun { 335614e71bSYork Sun return 1000000 / picos; 345614e71bSYork Sun } 355614e71bSYork Sun 365614e71bSYork Sun static void print_option_table(const struct options_string *table, 375614e71bSYork Sun int table_size, 385614e71bSYork Sun const void *base) 395614e71bSYork Sun { 405614e71bSYork Sun unsigned int i; 415614e71bSYork Sun unsigned int *ptr; 425614e71bSYork Sun unsigned long long *ptr_l; 435614e71bSYork Sun 445614e71bSYork Sun for (i = 0; i < table_size; i++) { 455614e71bSYork Sun switch (table[i].size) { 465614e71bSYork Sun case 4: 475614e71bSYork Sun ptr = (unsigned int *) (base + table[i].offset); 485614e71bSYork Sun if (table[i].printhex) { 495614e71bSYork Sun printf("%s = 0x%08X\n", 505614e71bSYork Sun table[i].option_name, *ptr); 515614e71bSYork Sun } else { 525614e71bSYork Sun printf("%s = %u\n", 535614e71bSYork Sun table[i].option_name, *ptr); 545614e71bSYork Sun } 555614e71bSYork Sun break; 565614e71bSYork Sun case 8: 575614e71bSYork Sun ptr_l = (unsigned long long *) (base + table[i].offset); 585614e71bSYork Sun printf("%s = %llu\n", 595614e71bSYork Sun table[i].option_name, *ptr_l); 605614e71bSYork Sun break; 615614e71bSYork Sun default: 625614e71bSYork Sun printf("Unrecognized size!\n"); 635614e71bSYork Sun break; 645614e71bSYork Sun } 655614e71bSYork Sun } 665614e71bSYork Sun } 675614e71bSYork Sun 685614e71bSYork Sun static int handle_option_table(const struct options_string *table, 695614e71bSYork Sun int table_size, 705614e71bSYork Sun void *base, 715614e71bSYork Sun const char *opt, 725614e71bSYork Sun const char *val) 735614e71bSYork Sun { 745614e71bSYork Sun unsigned int i; 755614e71bSYork Sun unsigned int value, *ptr; 765614e71bSYork Sun unsigned long long value_l, *ptr_l; 775614e71bSYork Sun 785614e71bSYork Sun for (i = 0; i < table_size; i++) { 795614e71bSYork Sun if (strcmp(table[i].option_name, opt) != 0) 805614e71bSYork Sun continue; 815614e71bSYork Sun switch (table[i].size) { 825614e71bSYork Sun case 4: 835614e71bSYork Sun value = simple_strtoul(val, NULL, 0); 845614e71bSYork Sun ptr = base + table[i].offset; 855614e71bSYork Sun *ptr = value; 865614e71bSYork Sun break; 875614e71bSYork Sun case 8: 885614e71bSYork Sun value_l = simple_strtoull(val, NULL, 0); 895614e71bSYork Sun ptr_l = base + table[i].offset; 905614e71bSYork Sun *ptr_l = value_l; 915614e71bSYork Sun break; 925614e71bSYork Sun default: 935614e71bSYork Sun printf("Unrecognized size!\n"); 945614e71bSYork Sun break; 955614e71bSYork Sun } 965614e71bSYork Sun return 1; 975614e71bSYork Sun } 985614e71bSYork Sun 995614e71bSYork Sun return 0; 1005614e71bSYork Sun } 1015614e71bSYork Sun 1025614e71bSYork Sun static void fsl_ddr_generic_edit(void *pdata, 1035614e71bSYork Sun void *pend, 1045614e71bSYork Sun unsigned int element_size, 1055614e71bSYork Sun unsigned int element_num, 1065614e71bSYork Sun unsigned int value) 1075614e71bSYork Sun { 1085614e71bSYork Sun char *pcdata = (char *)pdata; /* BIG ENDIAN ONLY */ 1095614e71bSYork Sun 1105614e71bSYork Sun pcdata += element_num * element_size; 1115614e71bSYork Sun if ((pcdata + element_size) > (char *) pend) { 1125614e71bSYork Sun printf("trying to write past end of data\n"); 1135614e71bSYork Sun return; 1145614e71bSYork Sun } 1155614e71bSYork Sun 1165614e71bSYork Sun switch (element_size) { 1175614e71bSYork Sun case 1: 1185614e71bSYork Sun __raw_writeb(value, pcdata); 1195614e71bSYork Sun break; 1205614e71bSYork Sun case 2: 1215614e71bSYork Sun __raw_writew(value, pcdata); 1225614e71bSYork Sun break; 1235614e71bSYork Sun case 4: 1245614e71bSYork Sun __raw_writel(value, pcdata); 1255614e71bSYork Sun break; 1265614e71bSYork Sun default: 1275614e71bSYork Sun printf("unexpected element size %u\n", element_size); 1285614e71bSYork Sun break; 1295614e71bSYork Sun } 1305614e71bSYork Sun } 1315614e71bSYork Sun 1325614e71bSYork Sun static void fsl_ddr_spd_edit(fsl_ddr_info_t *pinfo, 1335614e71bSYork Sun unsigned int ctrl_num, 1345614e71bSYork Sun unsigned int dimm_num, 1355614e71bSYork Sun unsigned int element_num, 1365614e71bSYork Sun unsigned int value) 1375614e71bSYork Sun { 1385614e71bSYork Sun generic_spd_eeprom_t *pspd; 1395614e71bSYork Sun 1405614e71bSYork Sun pspd = &(pinfo->spd_installed_dimms[ctrl_num][dimm_num]); 1415614e71bSYork Sun fsl_ddr_generic_edit(pspd, pspd + 1, 1, element_num, value); 1425614e71bSYork Sun } 1435614e71bSYork Sun 1445614e71bSYork Sun #define COMMON_TIMING(x) {#x, offsetof(common_timing_params_t, x), \ 1455614e71bSYork Sun sizeof((common_timing_params_t *)0)->x, 0} 1465614e71bSYork Sun 1475614e71bSYork Sun static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo, 1485614e71bSYork Sun unsigned int ctrl_num, 1495614e71bSYork Sun const char *optname_str, 1505614e71bSYork Sun const char *value_str) 1515614e71bSYork Sun { 1525614e71bSYork Sun common_timing_params_t *p = &pinfo->common_timing_params[ctrl_num]; 1535614e71bSYork Sun 1545614e71bSYork Sun static const struct options_string options[] = { 1555614e71bSYork Sun COMMON_TIMING(tckmin_x_ps), 1565614e71bSYork Sun COMMON_TIMING(tckmax_ps), 15734e026f9SYork Sun COMMON_TIMING(taamin_ps), 1585614e71bSYork Sun COMMON_TIMING(trcd_ps), 1595614e71bSYork Sun COMMON_TIMING(trp_ps), 1605614e71bSYork Sun COMMON_TIMING(tras_ps), 16134e026f9SYork Sun 16234e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 16334e026f9SYork Sun COMMON_TIMING(trfc1_ps), 16434e026f9SYork Sun COMMON_TIMING(trfc2_ps), 16534e026f9SYork Sun COMMON_TIMING(trfc4_ps), 16634e026f9SYork Sun COMMON_TIMING(trrds_ps), 16734e026f9SYork Sun COMMON_TIMING(trrdl_ps), 16834e026f9SYork Sun COMMON_TIMING(tccdl_ps), 16934e026f9SYork Sun #else 1705614e71bSYork Sun COMMON_TIMING(twtr_ps), 1715614e71bSYork Sun COMMON_TIMING(trfc_ps), 1725614e71bSYork Sun COMMON_TIMING(trrd_ps), 17334e026f9SYork Sun COMMON_TIMING(trtp_ps), 17434e026f9SYork Sun #endif 17534e026f9SYork Sun COMMON_TIMING(twr_ps), 1765614e71bSYork Sun COMMON_TIMING(trc_ps), 1775614e71bSYork Sun COMMON_TIMING(refresh_rate_ps), 17834e026f9SYork Sun COMMON_TIMING(extended_op_srt), 17934e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 1805614e71bSYork Sun COMMON_TIMING(tis_ps), 1815614e71bSYork Sun COMMON_TIMING(tih_ps), 1825614e71bSYork Sun COMMON_TIMING(tds_ps), 1835614e71bSYork Sun COMMON_TIMING(tdh_ps), 1845614e71bSYork Sun COMMON_TIMING(tdqsq_max_ps), 1855614e71bSYork Sun COMMON_TIMING(tqhs_ps), 18634e026f9SYork Sun #endif 1875614e71bSYork Sun COMMON_TIMING(ndimms_present), 18834e026f9SYork Sun COMMON_TIMING(lowest_common_spd_caslat), 1895614e71bSYork Sun COMMON_TIMING(highest_common_derated_caslat), 1905614e71bSYork Sun COMMON_TIMING(additive_latency), 1915614e71bSYork Sun COMMON_TIMING(all_dimms_burst_lengths_bitmask), 1925614e71bSYork Sun COMMON_TIMING(all_dimms_registered), 1935614e71bSYork Sun COMMON_TIMING(all_dimms_unbuffered), 1945614e71bSYork Sun COMMON_TIMING(all_dimms_ecc_capable), 1955614e71bSYork Sun COMMON_TIMING(total_mem), 1965614e71bSYork Sun COMMON_TIMING(base_address), 1975614e71bSYork Sun }; 1985614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 1995614e71bSYork Sun 2005614e71bSYork Sun if (handle_option_table(options, n_opts, p, optname_str, value_str)) 2015614e71bSYork Sun return; 2025614e71bSYork Sun 2035614e71bSYork Sun printf("Error: couldn't find option string %s\n", optname_str); 2045614e71bSYork Sun } 2055614e71bSYork Sun 2065614e71bSYork Sun #define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \ 2075614e71bSYork Sun sizeof((dimm_params_t *)0)->x, 0} 2085614e71bSYork Sun 2095614e71bSYork Sun static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo, 2105614e71bSYork Sun unsigned int ctrl_num, 2115614e71bSYork Sun unsigned int dimm_num, 2125614e71bSYork Sun const char *optname_str, 2135614e71bSYork Sun const char *value_str) 2145614e71bSYork Sun { 2155614e71bSYork Sun dimm_params_t *p = &(pinfo->dimm_params[ctrl_num][dimm_num]); 2165614e71bSYork Sun 2175614e71bSYork Sun static const struct options_string options[] = { 2185614e71bSYork Sun DIMM_PARM(n_ranks), 2195614e71bSYork Sun DIMM_PARM(data_width), 2205614e71bSYork Sun DIMM_PARM(primary_sdram_width), 2215614e71bSYork Sun DIMM_PARM(ec_sdram_width), 2225614e71bSYork Sun DIMM_PARM(registered_dimm), 2235614e71bSYork Sun DIMM_PARM(device_width), 2245614e71bSYork Sun 2255614e71bSYork Sun DIMM_PARM(n_row_addr), 2265614e71bSYork Sun DIMM_PARM(n_col_addr), 2275614e71bSYork Sun DIMM_PARM(edc_config), 22834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 22934e026f9SYork Sun DIMM_PARM(bank_addr_bits), 23034e026f9SYork Sun DIMM_PARM(bank_group_bits), 23134e026f9SYork Sun #else 2325614e71bSYork Sun DIMM_PARM(n_banks_per_sdram_device), 23334e026f9SYork Sun #endif 2345614e71bSYork Sun DIMM_PARM(burst_lengths_bitmask), 2355614e71bSYork Sun DIMM_PARM(row_density), 2365614e71bSYork Sun 2375614e71bSYork Sun DIMM_PARM(tckmin_x_ps), 2385614e71bSYork Sun DIMM_PARM(tckmin_x_minus_1_ps), 2395614e71bSYork Sun DIMM_PARM(tckmin_x_minus_2_ps), 2405614e71bSYork Sun DIMM_PARM(tckmax_ps), 2415614e71bSYork Sun 2425614e71bSYork Sun DIMM_PARM(caslat_x), 2435614e71bSYork Sun DIMM_PARM(caslat_x_minus_1), 2445614e71bSYork Sun DIMM_PARM(caslat_x_minus_2), 2455614e71bSYork Sun 2465614e71bSYork Sun DIMM_PARM(caslat_lowest_derated), 2475614e71bSYork Sun 2485614e71bSYork Sun DIMM_PARM(trcd_ps), 2495614e71bSYork Sun DIMM_PARM(trp_ps), 2505614e71bSYork Sun DIMM_PARM(tras_ps), 25134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 25234e026f9SYork Sun DIMM_PARM(trfc1_ps), 25334e026f9SYork Sun DIMM_PARM(trfc2_ps), 25434e026f9SYork Sun DIMM_PARM(trfc4_ps), 25534e026f9SYork Sun DIMM_PARM(trrds_ps), 25634e026f9SYork Sun DIMM_PARM(trrdl_ps), 25734e026f9SYork Sun DIMM_PARM(tccdl_ps), 25834e026f9SYork Sun #else 2595614e71bSYork Sun DIMM_PARM(twr_ps), 2605614e71bSYork Sun DIMM_PARM(twtr_ps), 2615614e71bSYork Sun DIMM_PARM(trfc_ps), 2625614e71bSYork Sun DIMM_PARM(trrd_ps), 26334e026f9SYork Sun DIMM_PARM(trtp_ps), 26434e026f9SYork Sun #endif 2655614e71bSYork Sun DIMM_PARM(trc_ps), 2665614e71bSYork Sun DIMM_PARM(refresh_rate_ps), 26734e026f9SYork Sun DIMM_PARM(extended_op_srt), 2685614e71bSYork Sun 26934e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 2705614e71bSYork Sun DIMM_PARM(tis_ps), 2715614e71bSYork Sun DIMM_PARM(tih_ps), 2725614e71bSYork Sun DIMM_PARM(tds_ps), 2735614e71bSYork Sun DIMM_PARM(tdh_ps), 2745614e71bSYork Sun DIMM_PARM(tdqsq_max_ps), 2755614e71bSYork Sun DIMM_PARM(tqhs_ps), 27634e026f9SYork Sun #endif 2775614e71bSYork Sun 2785614e71bSYork Sun DIMM_PARM(rank_density), 2795614e71bSYork Sun DIMM_PARM(capacity), 2805614e71bSYork Sun DIMM_PARM(base_address), 2815614e71bSYork Sun }; 2825614e71bSYork Sun 2835614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 2845614e71bSYork Sun 2855614e71bSYork Sun if (handle_option_table(options, n_opts, p, optname_str, value_str)) 2865614e71bSYork Sun return; 2875614e71bSYork Sun 2885614e71bSYork Sun printf("couldn't find option string %s\n", optname_str); 2895614e71bSYork Sun } 2905614e71bSYork Sun 2915614e71bSYork Sun static void print_dimm_parameters(const dimm_params_t *pdimm) 2925614e71bSYork Sun { 2935614e71bSYork Sun static const struct options_string options[] = { 2945614e71bSYork Sun DIMM_PARM(n_ranks), 2955614e71bSYork Sun DIMM_PARM(data_width), 2965614e71bSYork Sun DIMM_PARM(primary_sdram_width), 2975614e71bSYork Sun DIMM_PARM(ec_sdram_width), 2985614e71bSYork Sun DIMM_PARM(registered_dimm), 2995614e71bSYork Sun DIMM_PARM(device_width), 3005614e71bSYork Sun 3015614e71bSYork Sun DIMM_PARM(n_row_addr), 3025614e71bSYork Sun DIMM_PARM(n_col_addr), 3035614e71bSYork Sun DIMM_PARM(edc_config), 30434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 30534e026f9SYork Sun DIMM_PARM(bank_addr_bits), 30634e026f9SYork Sun DIMM_PARM(bank_group_bits), 30734e026f9SYork Sun #else 3085614e71bSYork Sun DIMM_PARM(n_banks_per_sdram_device), 30934e026f9SYork Sun #endif 3105614e71bSYork Sun 3115614e71bSYork Sun DIMM_PARM(tckmin_x_ps), 3125614e71bSYork Sun DIMM_PARM(tckmin_x_minus_1_ps), 3135614e71bSYork Sun DIMM_PARM(tckmin_x_minus_2_ps), 3145614e71bSYork Sun DIMM_PARM(tckmax_ps), 3155614e71bSYork Sun 3165614e71bSYork Sun DIMM_PARM(caslat_x), 3175614e71bSYork Sun DIMM_PARM(taa_ps), 3185614e71bSYork Sun DIMM_PARM(caslat_x_minus_1), 3195614e71bSYork Sun DIMM_PARM(caslat_x_minus_2), 3205614e71bSYork Sun DIMM_PARM(caslat_lowest_derated), 3215614e71bSYork Sun 3225614e71bSYork Sun DIMM_PARM(trcd_ps), 3235614e71bSYork Sun DIMM_PARM(trp_ps), 3245614e71bSYork Sun DIMM_PARM(tras_ps), 32534e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 32634e026f9SYork Sun DIMM_PARM(trfc1_ps), 32734e026f9SYork Sun DIMM_PARM(trfc2_ps), 32834e026f9SYork Sun DIMM_PARM(trfc4_ps), 32934e026f9SYork Sun DIMM_PARM(trrds_ps), 33034e026f9SYork Sun DIMM_PARM(trrdl_ps), 33134e026f9SYork Sun DIMM_PARM(tccdl_ps), 33234e026f9SYork Sun #else 3335614e71bSYork Sun DIMM_PARM(twr_ps), 3345614e71bSYork Sun DIMM_PARM(twtr_ps), 3355614e71bSYork Sun DIMM_PARM(trfc_ps), 3365614e71bSYork Sun DIMM_PARM(trrd_ps), 33734e026f9SYork Sun DIMM_PARM(trtp_ps), 33834e026f9SYork Sun #endif 3395614e71bSYork Sun DIMM_PARM(trc_ps), 3405614e71bSYork Sun DIMM_PARM(refresh_rate_ps), 3415614e71bSYork Sun 34234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 3435614e71bSYork Sun DIMM_PARM(tis_ps), 3445614e71bSYork Sun DIMM_PARM(tih_ps), 3455614e71bSYork Sun DIMM_PARM(tds_ps), 3465614e71bSYork Sun DIMM_PARM(tdh_ps), 3475614e71bSYork Sun DIMM_PARM(tdqsq_max_ps), 3485614e71bSYork Sun DIMM_PARM(tqhs_ps), 34934e026f9SYork Sun #endif 3505614e71bSYork Sun }; 3515614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 3525614e71bSYork Sun 3535614e71bSYork Sun if (pdimm->n_ranks == 0) { 3545614e71bSYork Sun printf("DIMM not present\n"); 3555614e71bSYork Sun return; 3565614e71bSYork Sun } 3575614e71bSYork Sun printf("DIMM organization parameters:\n"); 3585614e71bSYork Sun printf("module part name = %s\n", pdimm->mpart); 3595614e71bSYork Sun printf("rank_density = %llu bytes (%llu megabytes)\n", 3605614e71bSYork Sun pdimm->rank_density, pdimm->rank_density / 0x100000); 3615614e71bSYork Sun printf("capacity = %llu bytes (%llu megabytes)\n", 3625614e71bSYork Sun pdimm->capacity, pdimm->capacity / 0x100000); 3635614e71bSYork Sun printf("burst_lengths_bitmask = %02X\n", 3645614e71bSYork Sun pdimm->burst_lengths_bitmask); 3655614e71bSYork Sun printf("base_addresss = %llu (%08llX %08llX)\n", 3665614e71bSYork Sun pdimm->base_address, 3675614e71bSYork Sun (pdimm->base_address >> 32), 3685614e71bSYork Sun pdimm->base_address & 0xFFFFFFFF); 3695614e71bSYork Sun print_option_table(options, n_opts, pdimm); 3705614e71bSYork Sun } 3715614e71bSYork Sun 3725614e71bSYork Sun static void print_lowest_common_dimm_parameters( 3735614e71bSYork Sun const common_timing_params_t *plcd_dimm_params) 3745614e71bSYork Sun { 3755614e71bSYork Sun static const struct options_string options[] = { 37634e026f9SYork Sun COMMON_TIMING(taamin_ps), 3775614e71bSYork Sun COMMON_TIMING(trcd_ps), 3785614e71bSYork Sun COMMON_TIMING(trp_ps), 3795614e71bSYork Sun COMMON_TIMING(tras_ps), 38034e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 38134e026f9SYork Sun COMMON_TIMING(trfc1_ps), 38234e026f9SYork Sun COMMON_TIMING(trfc2_ps), 38334e026f9SYork Sun COMMON_TIMING(trfc4_ps), 38434e026f9SYork Sun COMMON_TIMING(trrds_ps), 38534e026f9SYork Sun COMMON_TIMING(trrdl_ps), 38634e026f9SYork Sun COMMON_TIMING(tccdl_ps), 38734e026f9SYork Sun #else 3885614e71bSYork Sun COMMON_TIMING(twtr_ps), 3895614e71bSYork Sun COMMON_TIMING(trfc_ps), 3905614e71bSYork Sun COMMON_TIMING(trrd_ps), 39134e026f9SYork Sun COMMON_TIMING(trtp_ps), 39234e026f9SYork Sun #endif 39334e026f9SYork Sun COMMON_TIMING(twr_ps), 3945614e71bSYork Sun COMMON_TIMING(trc_ps), 3955614e71bSYork Sun COMMON_TIMING(refresh_rate_ps), 39634e026f9SYork Sun COMMON_TIMING(extended_op_srt), 39734e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2) 3985614e71bSYork Sun COMMON_TIMING(tis_ps), 39934e026f9SYork Sun COMMON_TIMING(tih_ps), 4005614e71bSYork Sun COMMON_TIMING(tds_ps), 4015614e71bSYork Sun COMMON_TIMING(tdh_ps), 4025614e71bSYork Sun COMMON_TIMING(tdqsq_max_ps), 4035614e71bSYork Sun COMMON_TIMING(tqhs_ps), 40434e026f9SYork Sun #endif 40534e026f9SYork Sun COMMON_TIMING(lowest_common_spd_caslat), 4065614e71bSYork Sun COMMON_TIMING(highest_common_derated_caslat), 4075614e71bSYork Sun COMMON_TIMING(additive_latency), 4085614e71bSYork Sun COMMON_TIMING(ndimms_present), 4095614e71bSYork Sun COMMON_TIMING(all_dimms_registered), 4105614e71bSYork Sun COMMON_TIMING(all_dimms_unbuffered), 4115614e71bSYork Sun COMMON_TIMING(all_dimms_ecc_capable), 4125614e71bSYork Sun }; 4135614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 4145614e71bSYork Sun 4155614e71bSYork Sun /* Clock frequencies */ 4165614e71bSYork Sun printf("tckmin_x_ps = %u (%u MHz)\n", 4175614e71bSYork Sun plcd_dimm_params->tckmin_x_ps, 4185614e71bSYork Sun picos_to_mhz(plcd_dimm_params->tckmin_x_ps)); 4195614e71bSYork Sun printf("tckmax_ps = %u (%u MHz)\n", 4205614e71bSYork Sun plcd_dimm_params->tckmax_ps, 4215614e71bSYork Sun picos_to_mhz(plcd_dimm_params->tckmax_ps)); 4225614e71bSYork Sun printf("all_dimms_burst_lengths_bitmask = %02X\n", 4235614e71bSYork Sun plcd_dimm_params->all_dimms_burst_lengths_bitmask); 4245614e71bSYork Sun 4255614e71bSYork Sun print_option_table(options, n_opts, plcd_dimm_params); 4265614e71bSYork Sun 4275614e71bSYork Sun printf("total_mem = %llu (%llu megabytes)\n", 4285614e71bSYork Sun plcd_dimm_params->total_mem, 4295614e71bSYork Sun plcd_dimm_params->total_mem / 0x100000); 4305614e71bSYork Sun printf("base_address = %llu (%llu megabytes)\n", 4315614e71bSYork Sun plcd_dimm_params->base_address, 4325614e71bSYork Sun plcd_dimm_params->base_address / 0x100000); 4335614e71bSYork Sun } 4345614e71bSYork Sun 4355614e71bSYork Sun #define CTRL_OPTIONS(x) {#x, offsetof(memctl_options_t, x), \ 4365614e71bSYork Sun sizeof((memctl_options_t *)0)->x, 0} 4375614e71bSYork Sun #define CTRL_OPTIONS_CS(x, y) {"cs" #x "_" #y, \ 4385614e71bSYork Sun offsetof(memctl_options_t, cs_local_opts[x].y), \ 4395614e71bSYork Sun sizeof((memctl_options_t *)0)->cs_local_opts[x].y, 0} 4405614e71bSYork Sun 4415614e71bSYork Sun static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, 4425614e71bSYork Sun unsigned int ctl_num, 4435614e71bSYork Sun const char *optname_str, 4445614e71bSYork Sun const char *value_str) 4455614e71bSYork Sun { 4465614e71bSYork Sun memctl_options_t *p = &(pinfo->memctl_opts[ctl_num]); 4475614e71bSYork Sun /* 4485614e71bSYork Sun * This array all on the stack and *computed* each time this 4495614e71bSYork Sun * function is rung. 4505614e71bSYork Sun */ 4515614e71bSYork Sun static const struct options_string options[] = { 4525614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rd_cfg), 4535614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_wr_cfg), 4545614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 4555614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rd_cfg), 4565614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_wr_cfg), 4575614e71bSYork Sun #endif 4585614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 4595614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rd_cfg), 4605614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_wr_cfg), 4615614e71bSYork Sun #endif 4625614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 4635614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rd_cfg), 4645614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_wr_cfg), 4655614e71bSYork Sun #endif 4665614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 4675614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rtt_norm), 4685614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rtt_wr), 4695614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 4705614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rtt_norm), 4715614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rtt_wr), 4725614e71bSYork Sun #endif 4735614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 4745614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rtt_norm), 4755614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rtt_wr), 4765614e71bSYork Sun #endif 4775614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 4785614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rtt_norm), 4795614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rtt_wr), 4805614e71bSYork Sun #endif 4815614e71bSYork Sun #endif 4825614e71bSYork Sun CTRL_OPTIONS(memctl_interleaving), 4835614e71bSYork Sun CTRL_OPTIONS(memctl_interleaving_mode), 4845614e71bSYork Sun CTRL_OPTIONS(ba_intlv_ctl), 4855614e71bSYork Sun CTRL_OPTIONS(ecc_mode), 4865614e71bSYork Sun CTRL_OPTIONS(ecc_init_using_memctl), 4875614e71bSYork Sun CTRL_OPTIONS(dqs_config), 4885614e71bSYork Sun CTRL_OPTIONS(self_refresh_in_sleep), 4895614e71bSYork Sun CTRL_OPTIONS(dynamic_power), 4905614e71bSYork Sun CTRL_OPTIONS(data_bus_width), 4915614e71bSYork Sun CTRL_OPTIONS(burst_length), 4925614e71bSYork Sun CTRL_OPTIONS(cas_latency_override), 4935614e71bSYork Sun CTRL_OPTIONS(cas_latency_override_value), 4945614e71bSYork Sun CTRL_OPTIONS(use_derated_caslat), 4955614e71bSYork Sun CTRL_OPTIONS(additive_latency_override), 4965614e71bSYork Sun CTRL_OPTIONS(additive_latency_override_value), 4975614e71bSYork Sun CTRL_OPTIONS(clk_adjust), 4985614e71bSYork Sun CTRL_OPTIONS(cpo_override), 4995614e71bSYork Sun CTRL_OPTIONS(write_data_delay), 5005614e71bSYork Sun CTRL_OPTIONS(half_strength_driver_enable), 5015614e71bSYork Sun 5025614e71bSYork Sun /* 5035614e71bSYork Sun * These can probably be changed to 2T_EN and 3T_EN 5045614e71bSYork Sun * (using a leading numerical character) without problem 5055614e71bSYork Sun */ 5065614e71bSYork Sun CTRL_OPTIONS(twot_en), 5075614e71bSYork Sun CTRL_OPTIONS(threet_en), 5085614e71bSYork Sun CTRL_OPTIONS(ap_en), 5095614e71bSYork Sun CTRL_OPTIONS(x4_en), 5105614e71bSYork Sun CTRL_OPTIONS(bstopre), 5115614e71bSYork Sun CTRL_OPTIONS(wrlvl_override), 5125614e71bSYork Sun CTRL_OPTIONS(wrlvl_sample), 5135614e71bSYork Sun CTRL_OPTIONS(wrlvl_start), 514*ef87cab6SYork Sun CTRL_OPTIONS(cswl_override), 5155614e71bSYork Sun CTRL_OPTIONS(rcw_override), 5165614e71bSYork Sun CTRL_OPTIONS(rcw_1), 5175614e71bSYork Sun CTRL_OPTIONS(rcw_2), 5185614e71bSYork Sun CTRL_OPTIONS(ddr_cdr1), 5195614e71bSYork Sun CTRL_OPTIONS(ddr_cdr2), 5205614e71bSYork Sun CTRL_OPTIONS(tcke_clock_pulse_width_ps), 5215614e71bSYork Sun CTRL_OPTIONS(tfaw_window_four_activates_ps), 5225614e71bSYork Sun CTRL_OPTIONS(trwt_override), 5235614e71bSYork Sun CTRL_OPTIONS(trwt), 52434e026f9SYork Sun CTRL_OPTIONS(rtt_override), 52534e026f9SYork Sun CTRL_OPTIONS(rtt_override_value), 52634e026f9SYork Sun CTRL_OPTIONS(rtt_wr_override_value), 5275614e71bSYork Sun }; 5285614e71bSYork Sun 5295614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 5305614e71bSYork Sun 5315614e71bSYork Sun if (handle_option_table(options, n_opts, p, 5325614e71bSYork Sun optname_str, value_str)) 5335614e71bSYork Sun return; 5345614e71bSYork Sun 5355614e71bSYork Sun printf("couldn't find option string %s\n", optname_str); 5365614e71bSYork Sun } 5375614e71bSYork Sun 5385614e71bSYork Sun #define CFG_REGS(x) {#x, offsetof(fsl_ddr_cfg_regs_t, x), \ 5395614e71bSYork Sun sizeof((fsl_ddr_cfg_regs_t *)0)->x, 1} 5405614e71bSYork Sun #define CFG_REGS_CS(x, y) {"cs" #x "_" #y, \ 5415614e71bSYork Sun offsetof(fsl_ddr_cfg_regs_t, cs[x].y), \ 5425614e71bSYork Sun sizeof((fsl_ddr_cfg_regs_t *)0)->cs[x].y, 1} 5435614e71bSYork Sun 5445614e71bSYork Sun static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr) 5455614e71bSYork Sun { 5465614e71bSYork Sun unsigned int i; 5475614e71bSYork Sun static const struct options_string options[] = { 5485614e71bSYork Sun CFG_REGS_CS(0, bnds), 5495614e71bSYork Sun CFG_REGS_CS(0, config), 5505614e71bSYork Sun CFG_REGS_CS(0, config_2), 5515614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 5525614e71bSYork Sun CFG_REGS_CS(1, bnds), 5535614e71bSYork Sun CFG_REGS_CS(1, config), 5545614e71bSYork Sun CFG_REGS_CS(1, config_2), 5555614e71bSYork Sun #endif 5565614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 5575614e71bSYork Sun CFG_REGS_CS(2, bnds), 5585614e71bSYork Sun CFG_REGS_CS(2, config), 5595614e71bSYork Sun CFG_REGS_CS(2, config_2), 5605614e71bSYork Sun #endif 5615614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 5625614e71bSYork Sun CFG_REGS_CS(3, bnds), 5635614e71bSYork Sun CFG_REGS_CS(3, config), 5645614e71bSYork Sun CFG_REGS_CS(3, config_2), 5655614e71bSYork Sun #endif 5665614e71bSYork Sun CFG_REGS(timing_cfg_3), 5675614e71bSYork Sun CFG_REGS(timing_cfg_0), 5685614e71bSYork Sun CFG_REGS(timing_cfg_1), 5695614e71bSYork Sun CFG_REGS(timing_cfg_2), 5705614e71bSYork Sun CFG_REGS(ddr_sdram_cfg), 5715614e71bSYork Sun CFG_REGS(ddr_sdram_cfg_2), 57234e026f9SYork Sun CFG_REGS(ddr_sdram_cfg_3), 5735614e71bSYork Sun CFG_REGS(ddr_sdram_mode), 5745614e71bSYork Sun CFG_REGS(ddr_sdram_mode_2), 5755614e71bSYork Sun CFG_REGS(ddr_sdram_mode_3), 5765614e71bSYork Sun CFG_REGS(ddr_sdram_mode_4), 5775614e71bSYork Sun CFG_REGS(ddr_sdram_mode_5), 5785614e71bSYork Sun CFG_REGS(ddr_sdram_mode_6), 5795614e71bSYork Sun CFG_REGS(ddr_sdram_mode_7), 5805614e71bSYork Sun CFG_REGS(ddr_sdram_mode_8), 58134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 58234e026f9SYork Sun CFG_REGS(ddr_sdram_mode_9), 58334e026f9SYork Sun CFG_REGS(ddr_sdram_mode_10), 58434e026f9SYork Sun CFG_REGS(ddr_sdram_mode_11), 58534e026f9SYork Sun CFG_REGS(ddr_sdram_mode_12), 58634e026f9SYork Sun CFG_REGS(ddr_sdram_mode_13), 58734e026f9SYork Sun CFG_REGS(ddr_sdram_mode_14), 58834e026f9SYork Sun CFG_REGS(ddr_sdram_mode_15), 58934e026f9SYork Sun CFG_REGS(ddr_sdram_mode_16), 59034e026f9SYork Sun #endif 5915614e71bSYork Sun CFG_REGS(ddr_sdram_interval), 5925614e71bSYork Sun CFG_REGS(ddr_data_init), 5935614e71bSYork Sun CFG_REGS(ddr_sdram_clk_cntl), 5945614e71bSYork Sun CFG_REGS(ddr_init_addr), 5955614e71bSYork Sun CFG_REGS(ddr_init_ext_addr), 5965614e71bSYork Sun CFG_REGS(timing_cfg_4), 5975614e71bSYork Sun CFG_REGS(timing_cfg_5), 59834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 59934e026f9SYork Sun CFG_REGS(timing_cfg_6), 60034e026f9SYork Sun CFG_REGS(timing_cfg_7), 60134e026f9SYork Sun CFG_REGS(timing_cfg_8), 60234e026f9SYork Sun CFG_REGS(timing_cfg_9), 60334e026f9SYork Sun #endif 6045614e71bSYork Sun CFG_REGS(ddr_zq_cntl), 6055614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl), 6065614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl_2), 6075614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl_3), 6085614e71bSYork Sun CFG_REGS(ddr_sr_cntr), 6095614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_1), 6105614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_2), 6115614e71bSYork Sun CFG_REGS(ddr_cdr1), 6125614e71bSYork Sun CFG_REGS(ddr_cdr2), 61334e026f9SYork Sun CFG_REGS(dq_map_0), 61434e026f9SYork Sun CFG_REGS(dq_map_1), 61534e026f9SYork Sun CFG_REGS(dq_map_2), 61634e026f9SYork Sun CFG_REGS(dq_map_3), 6175614e71bSYork Sun CFG_REGS(err_disable), 6185614e71bSYork Sun CFG_REGS(err_int_en), 6195614e71bSYork Sun CFG_REGS(ddr_eor), 6205614e71bSYork Sun }; 6215614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 6225614e71bSYork Sun 6235614e71bSYork Sun print_option_table(options, n_opts, ddr); 6245614e71bSYork Sun 6255614e71bSYork Sun for (i = 0; i < 32; i++) 6265614e71bSYork Sun printf("debug_%02d = 0x%08X\n", i+1, ddr->debug[i]); 6275614e71bSYork Sun } 6285614e71bSYork Sun 6295614e71bSYork Sun static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, 6305614e71bSYork Sun unsigned int ctrl_num, 6315614e71bSYork Sun const char *regname, 6325614e71bSYork Sun const char *value_str) 6335614e71bSYork Sun { 6345614e71bSYork Sun unsigned int i; 6355614e71bSYork Sun fsl_ddr_cfg_regs_t *ddr; 6365614e71bSYork Sun char buf[20]; 6375614e71bSYork Sun static const struct options_string options[] = { 6385614e71bSYork Sun CFG_REGS_CS(0, bnds), 6395614e71bSYork Sun CFG_REGS_CS(0, config), 6405614e71bSYork Sun CFG_REGS_CS(0, config_2), 6415614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 6425614e71bSYork Sun CFG_REGS_CS(1, bnds), 6435614e71bSYork Sun CFG_REGS_CS(1, config), 6445614e71bSYork Sun CFG_REGS_CS(1, config_2), 6455614e71bSYork Sun #endif 6465614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 6475614e71bSYork Sun CFG_REGS_CS(2, bnds), 6485614e71bSYork Sun CFG_REGS_CS(2, config), 6495614e71bSYork Sun CFG_REGS_CS(2, config_2), 6505614e71bSYork Sun #endif 6515614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) 6525614e71bSYork Sun CFG_REGS_CS(3, bnds), 6535614e71bSYork Sun CFG_REGS_CS(3, config), 6545614e71bSYork Sun CFG_REGS_CS(3, config_2), 6555614e71bSYork Sun #endif 6565614e71bSYork Sun CFG_REGS(timing_cfg_3), 6575614e71bSYork Sun CFG_REGS(timing_cfg_0), 6585614e71bSYork Sun CFG_REGS(timing_cfg_1), 6595614e71bSYork Sun CFG_REGS(timing_cfg_2), 6605614e71bSYork Sun CFG_REGS(ddr_sdram_cfg), 6615614e71bSYork Sun CFG_REGS(ddr_sdram_cfg_2), 66234e026f9SYork Sun CFG_REGS(ddr_sdram_cfg_3), 6635614e71bSYork Sun CFG_REGS(ddr_sdram_mode), 6645614e71bSYork Sun CFG_REGS(ddr_sdram_mode_2), 6655614e71bSYork Sun CFG_REGS(ddr_sdram_mode_3), 6665614e71bSYork Sun CFG_REGS(ddr_sdram_mode_4), 6675614e71bSYork Sun CFG_REGS(ddr_sdram_mode_5), 6685614e71bSYork Sun CFG_REGS(ddr_sdram_mode_6), 6695614e71bSYork Sun CFG_REGS(ddr_sdram_mode_7), 6705614e71bSYork Sun CFG_REGS(ddr_sdram_mode_8), 67134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 67234e026f9SYork Sun CFG_REGS(ddr_sdram_mode_9), 67334e026f9SYork Sun CFG_REGS(ddr_sdram_mode_10), 67434e026f9SYork Sun CFG_REGS(ddr_sdram_mode_11), 67534e026f9SYork Sun CFG_REGS(ddr_sdram_mode_12), 67634e026f9SYork Sun CFG_REGS(ddr_sdram_mode_13), 67734e026f9SYork Sun CFG_REGS(ddr_sdram_mode_14), 67834e026f9SYork Sun CFG_REGS(ddr_sdram_mode_15), 67934e026f9SYork Sun CFG_REGS(ddr_sdram_mode_16), 68034e026f9SYork Sun #endif 6815614e71bSYork Sun CFG_REGS(ddr_sdram_interval), 6825614e71bSYork Sun CFG_REGS(ddr_data_init), 6835614e71bSYork Sun CFG_REGS(ddr_sdram_clk_cntl), 6845614e71bSYork Sun CFG_REGS(ddr_init_addr), 6855614e71bSYork Sun CFG_REGS(ddr_init_ext_addr), 6865614e71bSYork Sun CFG_REGS(timing_cfg_4), 6875614e71bSYork Sun CFG_REGS(timing_cfg_5), 68834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 68934e026f9SYork Sun CFG_REGS(timing_cfg_6), 69034e026f9SYork Sun CFG_REGS(timing_cfg_7), 69134e026f9SYork Sun CFG_REGS(timing_cfg_8), 69234e026f9SYork Sun CFG_REGS(timing_cfg_9), 69334e026f9SYork Sun #endif 6945614e71bSYork Sun CFG_REGS(ddr_zq_cntl), 6955614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl), 6965614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl_2), 6975614e71bSYork Sun CFG_REGS(ddr_wrlvl_cntl_3), 6985614e71bSYork Sun CFG_REGS(ddr_sr_cntr), 6995614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_1), 7005614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_2), 7015614e71bSYork Sun CFG_REGS(ddr_cdr1), 7025614e71bSYork Sun CFG_REGS(ddr_cdr2), 70334e026f9SYork Sun CFG_REGS(dq_map_0), 70434e026f9SYork Sun CFG_REGS(dq_map_1), 70534e026f9SYork Sun CFG_REGS(dq_map_2), 70634e026f9SYork Sun CFG_REGS(dq_map_3), 7075614e71bSYork Sun CFG_REGS(err_disable), 7085614e71bSYork Sun CFG_REGS(err_int_en), 7095614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_2), 7105614e71bSYork Sun CFG_REGS(ddr_sdram_rcw_2), 7115614e71bSYork Sun CFG_REGS(ddr_eor), 7125614e71bSYork Sun }; 7135614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 7145614e71bSYork Sun 7155614e71bSYork Sun debug("fsl_ddr_regs_edit: ctrl_num = %u, " 7165614e71bSYork Sun "regname = %s, value = %s\n", 7175614e71bSYork Sun ctrl_num, regname, value_str); 7185614e71bSYork Sun if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS) 7195614e71bSYork Sun return; 7205614e71bSYork Sun 7215614e71bSYork Sun ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]); 7225614e71bSYork Sun 7235614e71bSYork Sun if (handle_option_table(options, n_opts, ddr, regname, value_str)) 7245614e71bSYork Sun return; 7255614e71bSYork Sun 7265614e71bSYork Sun for (i = 0; i < 32; i++) { 7275614e71bSYork Sun unsigned int value = simple_strtoul(value_str, NULL, 0); 7285614e71bSYork Sun sprintf(buf, "debug_%u", i + 1); 7295614e71bSYork Sun if (strcmp(buf, regname) == 0) { 7305614e71bSYork Sun ddr->debug[i] = value; 7315614e71bSYork Sun return; 7325614e71bSYork Sun } 7335614e71bSYork Sun } 7345614e71bSYork Sun printf("Error: couldn't find register string %s\n", regname); 7355614e71bSYork Sun } 7365614e71bSYork Sun 7375614e71bSYork Sun #define CTRL_OPTIONS_HEX(x) {#x, offsetof(memctl_options_t, x), \ 7385614e71bSYork Sun sizeof((memctl_options_t *)0)->x, 1} 7395614e71bSYork Sun 7405614e71bSYork Sun static void print_memctl_options(const memctl_options_t *popts) 7415614e71bSYork Sun { 7425614e71bSYork Sun static const struct options_string options[] = { 7435614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rd_cfg), 7445614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_wr_cfg), 7455614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 7465614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rd_cfg), 7475614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_wr_cfg), 7485614e71bSYork Sun #endif 7495614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 7505614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rd_cfg), 7515614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_wr_cfg), 7525614e71bSYork Sun #endif 7535614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) 7545614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rd_cfg), 7555614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_wr_cfg), 7565614e71bSYork Sun #endif 7575614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR3) 7585614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rtt_norm), 7595614e71bSYork Sun CTRL_OPTIONS_CS(0, odt_rtt_wr), 7605614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1) 7615614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rtt_norm), 7625614e71bSYork Sun CTRL_OPTIONS_CS(1, odt_rtt_wr), 7635614e71bSYork Sun #endif 7645614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2) 7655614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rtt_norm), 7665614e71bSYork Sun CTRL_OPTIONS_CS(2, odt_rtt_wr), 7675614e71bSYork Sun #endif 7685614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3) 7695614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rtt_norm), 7705614e71bSYork Sun CTRL_OPTIONS_CS(3, odt_rtt_wr), 7715614e71bSYork Sun #endif 7725614e71bSYork Sun #endif 7735614e71bSYork Sun CTRL_OPTIONS(memctl_interleaving), 7745614e71bSYork Sun CTRL_OPTIONS(memctl_interleaving_mode), 7755614e71bSYork Sun CTRL_OPTIONS_HEX(ba_intlv_ctl), 7765614e71bSYork Sun CTRL_OPTIONS(ecc_mode), 7775614e71bSYork Sun CTRL_OPTIONS(ecc_init_using_memctl), 7785614e71bSYork Sun CTRL_OPTIONS(dqs_config), 7795614e71bSYork Sun CTRL_OPTIONS(self_refresh_in_sleep), 7805614e71bSYork Sun CTRL_OPTIONS(dynamic_power), 7815614e71bSYork Sun CTRL_OPTIONS(data_bus_width), 7825614e71bSYork Sun CTRL_OPTIONS(burst_length), 7835614e71bSYork Sun CTRL_OPTIONS(cas_latency_override), 7845614e71bSYork Sun CTRL_OPTIONS(cas_latency_override_value), 7855614e71bSYork Sun CTRL_OPTIONS(use_derated_caslat), 7865614e71bSYork Sun CTRL_OPTIONS(additive_latency_override), 7875614e71bSYork Sun CTRL_OPTIONS(additive_latency_override_value), 7885614e71bSYork Sun CTRL_OPTIONS(clk_adjust), 7895614e71bSYork Sun CTRL_OPTIONS(cpo_override), 7905614e71bSYork Sun CTRL_OPTIONS(write_data_delay), 7915614e71bSYork Sun CTRL_OPTIONS(half_strength_driver_enable), 7925614e71bSYork Sun /* 7935614e71bSYork Sun * These can probably be changed to 2T_EN and 3T_EN 7945614e71bSYork Sun * (using a leading numerical character) without problem 7955614e71bSYork Sun */ 7965614e71bSYork Sun CTRL_OPTIONS(twot_en), 7975614e71bSYork Sun CTRL_OPTIONS(threet_en), 7985614e71bSYork Sun CTRL_OPTIONS(registered_dimm_en), 7995614e71bSYork Sun CTRL_OPTIONS(ap_en), 8005614e71bSYork Sun CTRL_OPTIONS(x4_en), 8015614e71bSYork Sun CTRL_OPTIONS(bstopre), 8025614e71bSYork Sun CTRL_OPTIONS(wrlvl_override), 8035614e71bSYork Sun CTRL_OPTIONS(wrlvl_sample), 8045614e71bSYork Sun CTRL_OPTIONS(wrlvl_start), 805*ef87cab6SYork Sun CTRL_OPTIONS_HEX(cswl_override), 8065614e71bSYork Sun CTRL_OPTIONS(rcw_override), 8075614e71bSYork Sun CTRL_OPTIONS(rcw_1), 8085614e71bSYork Sun CTRL_OPTIONS(rcw_2), 8095614e71bSYork Sun CTRL_OPTIONS_HEX(ddr_cdr1), 8105614e71bSYork Sun CTRL_OPTIONS_HEX(ddr_cdr2), 8115614e71bSYork Sun CTRL_OPTIONS(tcke_clock_pulse_width_ps), 8125614e71bSYork Sun CTRL_OPTIONS(tfaw_window_four_activates_ps), 8135614e71bSYork Sun CTRL_OPTIONS(trwt_override), 8145614e71bSYork Sun CTRL_OPTIONS(trwt), 81534e026f9SYork Sun CTRL_OPTIONS(rtt_override), 81634e026f9SYork Sun CTRL_OPTIONS(rtt_override_value), 81734e026f9SYork Sun CTRL_OPTIONS(rtt_wr_override_value), 8185614e71bSYork Sun }; 8195614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 8205614e71bSYork Sun 8215614e71bSYork Sun print_option_table(options, n_opts, popts); 8225614e71bSYork Sun } 8235614e71bSYork Sun 8245614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR1 8255614e71bSYork Sun void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd) 8265614e71bSYork Sun { 8275614e71bSYork Sun unsigned int i; 8285614e71bSYork Sun 8295614e71bSYork Sun printf("%-3d : %02x %s\n", 0, spd->info_size, 8305614e71bSYork Sun " spd->info_size, * 0 # bytes written into serial memory *"); 8315614e71bSYork Sun printf("%-3d : %02x %s\n", 1, spd->chip_size, 8325614e71bSYork Sun " spd->chip_size, * 1 Total # bytes of SPD memory device *"); 8335614e71bSYork Sun printf("%-3d : %02x %s\n", 2, spd->mem_type, 8345614e71bSYork Sun " spd->mem_type, * 2 Fundamental memory type *"); 8355614e71bSYork Sun printf("%-3d : %02x %s\n", 3, spd->nrow_addr, 8365614e71bSYork Sun " spd->nrow_addr, * 3 # of Row Addresses on this assembly *"); 8375614e71bSYork Sun printf("%-3d : %02x %s\n", 4, spd->ncol_addr, 8385614e71bSYork Sun " spd->ncol_addr, * 4 # of Column Addrs on this assembly *"); 8395614e71bSYork Sun printf("%-3d : %02x %s\n", 5, spd->nrows, 8405614e71bSYork Sun " spd->nrows * 5 # of DIMM Banks *"); 8415614e71bSYork Sun printf("%-3d : %02x %s\n", 6, spd->dataw_lsb, 8425614e71bSYork Sun " spd->dataw_lsb, * 6 Data Width lsb of this assembly *"); 8435614e71bSYork Sun printf("%-3d : %02x %s\n", 7, spd->dataw_msb, 8445614e71bSYork Sun " spd->dataw_msb, * 7 Data Width msb of this assembly *"); 8455614e71bSYork Sun printf("%-3d : %02x %s\n", 8, spd->voltage, 8465614e71bSYork Sun " spd->voltage, * 8 Voltage intf std of this assembly *"); 8475614e71bSYork Sun printf("%-3d : %02x %s\n", 9, spd->clk_cycle, 8485614e71bSYork Sun " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *"); 8495614e71bSYork Sun printf("%-3d : %02x %s\n", 10, spd->clk_access, 8505614e71bSYork Sun " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *"); 8515614e71bSYork Sun printf("%-3d : %02x %s\n", 11, spd->config, 8525614e71bSYork Sun " spd->config, * 11 DIMM Configuration type *"); 8535614e71bSYork Sun printf("%-3d : %02x %s\n", 12, spd->refresh, 8545614e71bSYork Sun " spd->refresh, * 12 Refresh Rate/Type *"); 8555614e71bSYork Sun printf("%-3d : %02x %s\n", 13, spd->primw, 8565614e71bSYork Sun " spd->primw, * 13 Primary SDRAM Width *"); 8575614e71bSYork Sun printf("%-3d : %02x %s\n", 14, spd->ecw, 8585614e71bSYork Sun " spd->ecw, * 14 Error Checking SDRAM width *"); 8595614e71bSYork Sun printf("%-3d : %02x %s\n", 15, spd->min_delay, 8605614e71bSYork Sun " spd->min_delay, * 15 Back to Back Random Access *"); 8615614e71bSYork Sun printf("%-3d : %02x %s\n", 16, spd->burstl, 8625614e71bSYork Sun " spd->burstl, * 16 Burst Lengths Supported *"); 8635614e71bSYork Sun printf("%-3d : %02x %s\n", 17, spd->nbanks, 8645614e71bSYork Sun " spd->nbanks, * 17 # of Banks on Each SDRAM Device *"); 8655614e71bSYork Sun printf("%-3d : %02x %s\n", 18, spd->cas_lat, 8665614e71bSYork Sun " spd->cas_lat, * 18 CAS# Latencies Supported *"); 8675614e71bSYork Sun printf("%-3d : %02x %s\n", 19, spd->cs_lat, 8685614e71bSYork Sun " spd->cs_lat, * 19 Chip Select Latency *"); 8695614e71bSYork Sun printf("%-3d : %02x %s\n", 20, spd->write_lat, 8705614e71bSYork Sun " spd->write_lat, * 20 Write Latency/Recovery *"); 8715614e71bSYork Sun printf("%-3d : %02x %s\n", 21, spd->mod_attr, 8725614e71bSYork Sun " spd->mod_attr, * 21 SDRAM Module Attributes *"); 8735614e71bSYork Sun printf("%-3d : %02x %s\n", 22, spd->dev_attr, 8745614e71bSYork Sun " spd->dev_attr, * 22 SDRAM Device Attributes *"); 8755614e71bSYork Sun printf("%-3d : %02x %s\n", 23, spd->clk_cycle2, 8765614e71bSYork Sun " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *"); 8775614e71bSYork Sun printf("%-3d : %02x %s\n", 24, spd->clk_access2, 8785614e71bSYork Sun " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *"); 8795614e71bSYork Sun printf("%-3d : %02x %s\n", 25, spd->clk_cycle3, 8805614e71bSYork Sun " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *"); 8815614e71bSYork Sun printf("%-3d : %02x %s\n", 26, spd->clk_access3, 8825614e71bSYork Sun " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *"); 8835614e71bSYork Sun printf("%-3d : %02x %s\n", 27, spd->trp, 8845614e71bSYork Sun " spd->trp, * 27 Min Row Precharge Time (tRP)*"); 8855614e71bSYork Sun printf("%-3d : %02x %s\n", 28, spd->trrd, 8865614e71bSYork Sun " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *"); 8875614e71bSYork Sun printf("%-3d : %02x %s\n", 29, spd->trcd, 8885614e71bSYork Sun " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *"); 8895614e71bSYork Sun printf("%-3d : %02x %s\n", 30, spd->tras, 8905614e71bSYork Sun " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *"); 8915614e71bSYork Sun printf("%-3d : %02x %s\n", 31, spd->bank_dens, 8925614e71bSYork Sun " spd->bank_dens, * 31 Density of each bank on module *"); 8935614e71bSYork Sun printf("%-3d : %02x %s\n", 32, spd->ca_setup, 8945614e71bSYork Sun " spd->ca_setup, * 32 Cmd + Addr signal input setup time *"); 8955614e71bSYork Sun printf("%-3d : %02x %s\n", 33, spd->ca_hold, 8965614e71bSYork Sun " spd->ca_hold, * 33 Cmd and Addr signal input hold time *"); 8975614e71bSYork Sun printf("%-3d : %02x %s\n", 34, spd->data_setup, 8985614e71bSYork Sun " spd->data_setup, * 34 Data signal input setup time *"); 8995614e71bSYork Sun printf("%-3d : %02x %s\n", 35, spd->data_hold, 9005614e71bSYork Sun " spd->data_hold, * 35 Data signal input hold time *"); 9015614e71bSYork Sun printf("%-3d : %02x %s\n", 36, spd->res_36_40[0], 9025614e71bSYork Sun " spd->res_36_40[0], * 36 Reserved / tWR *"); 9035614e71bSYork Sun printf("%-3d : %02x %s\n", 37, spd->res_36_40[1], 9045614e71bSYork Sun " spd->res_36_40[1], * 37 Reserved / tWTR *"); 9055614e71bSYork Sun printf("%-3d : %02x %s\n", 38, spd->res_36_40[2], 9065614e71bSYork Sun " spd->res_36_40[2], * 38 Reserved / tRTP *"); 9075614e71bSYork Sun printf("%-3d : %02x %s\n", 39, spd->res_36_40[3], 9085614e71bSYork Sun " spd->res_36_40[3], * 39 Reserved / mem_probe *"); 9095614e71bSYork Sun printf("%-3d : %02x %s\n", 40, spd->res_36_40[4], 9105614e71bSYork Sun " spd->res_36_40[4], * 40 Reserved / trc,trfc extensions *"); 9115614e71bSYork Sun printf("%-3d : %02x %s\n", 41, spd->trc, 9125614e71bSYork Sun " spd->trc, * 41 Min Active to Auto refresh time tRC *"); 9135614e71bSYork Sun printf("%-3d : %02x %s\n", 42, spd->trfc, 9145614e71bSYork Sun " spd->trfc, * 42 Min Auto to Active period tRFC *"); 9155614e71bSYork Sun printf("%-3d : %02x %s\n", 43, spd->tckmax, 9165614e71bSYork Sun " spd->tckmax, * 43 Max device cycle time tCKmax *"); 9175614e71bSYork Sun printf("%-3d : %02x %s\n", 44, spd->tdqsq, 9185614e71bSYork Sun " spd->tdqsq, * 44 Max DQS to DQ skew *"); 9195614e71bSYork Sun printf("%-3d : %02x %s\n", 45, spd->tqhs, 9205614e71bSYork Sun " spd->tqhs, * 45 Max Read DataHold skew tQHS *"); 9215614e71bSYork Sun printf("%-3d : %02x %s\n", 46, spd->res_46, 9225614e71bSYork Sun " spd->res_46, * 46 Reserved/ PLL Relock time *"); 9235614e71bSYork Sun printf("%-3d : %02x %s\n", 47, spd->dimm_height, 9245614e71bSYork Sun " spd->dimm_height * 47 SDRAM DIMM Height *"); 9255614e71bSYork Sun 9265614e71bSYork Sun printf("%-3d-%3d: ", 48, 61); 9275614e71bSYork Sun 9285614e71bSYork Sun for (i = 0; i < 14; i++) 9295614e71bSYork Sun printf("%02x", spd->res_48_61[i]); 9305614e71bSYork Sun 9315614e71bSYork Sun printf(" * 48-61 IDD in SPD and Reserved space *\n"); 9325614e71bSYork Sun 9335614e71bSYork Sun printf("%-3d : %02x %s\n", 62, spd->spd_rev, 9345614e71bSYork Sun " spd->spd_rev, * 62 SPD Data Revision Code *"); 9355614e71bSYork Sun printf("%-3d : %02x %s\n", 63, spd->cksum, 9365614e71bSYork Sun " spd->cksum, * 63 Checksum for bytes 0-62 *"); 9375614e71bSYork Sun printf("%-3d-%3d: ", 64, 71); 9385614e71bSYork Sun 9395614e71bSYork Sun for (i = 0; i < 8; i++) 9405614e71bSYork Sun printf("%02x", spd->mid[i]); 9415614e71bSYork Sun 9425614e71bSYork Sun printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n"); 9435614e71bSYork Sun printf("%-3d : %02x %s\n", 72, spd->mloc, 9445614e71bSYork Sun " spd->mloc, * 72 Manufacturing Location *"); 9455614e71bSYork Sun 9465614e71bSYork Sun printf("%-3d-%3d: >>", 73, 90); 9475614e71bSYork Sun 9485614e71bSYork Sun for (i = 0; i < 18; i++) 9495614e71bSYork Sun printf("%c", spd->mpart[i]); 9505614e71bSYork Sun 9515614e71bSYork Sun printf("<<* 73 Manufacturer's Part Number *\n"); 9525614e71bSYork Sun 9535614e71bSYork Sun printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1], 9545614e71bSYork Sun "* 91 Revision Code *"); 9555614e71bSYork Sun printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1], 9565614e71bSYork Sun "* 93 Manufacturing Date *"); 9575614e71bSYork Sun printf("%-3d-%3d: ", 95, 98); 9585614e71bSYork Sun 9595614e71bSYork Sun for (i = 0; i < 4; i++) 9605614e71bSYork Sun printf("%02x", spd->sernum[i]); 9615614e71bSYork Sun 9625614e71bSYork Sun printf("* 95 Assembly Serial Number *\n"); 9635614e71bSYork Sun 9645614e71bSYork Sun printf("%-3d-%3d: ", 99, 127); 9655614e71bSYork Sun 9665614e71bSYork Sun for (i = 0; i < 27; i++) 9675614e71bSYork Sun printf("%02x", spd->mspec[i]); 9685614e71bSYork Sun 9695614e71bSYork Sun printf("* 99 Manufacturer Specific Data *\n"); 9705614e71bSYork Sun } 9715614e71bSYork Sun #endif 9725614e71bSYork Sun 9735614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR2 9745614e71bSYork Sun void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd) 9755614e71bSYork Sun { 9765614e71bSYork Sun unsigned int i; 9775614e71bSYork Sun 9785614e71bSYork Sun printf("%-3d : %02x %s\n", 0, spd->info_size, 9795614e71bSYork Sun " spd->info_size, * 0 # bytes written into serial memory *"); 9805614e71bSYork Sun printf("%-3d : %02x %s\n", 1, spd->chip_size, 9815614e71bSYork Sun " spd->chip_size, * 1 Total # bytes of SPD memory device *"); 9825614e71bSYork Sun printf("%-3d : %02x %s\n", 2, spd->mem_type, 9835614e71bSYork Sun " spd->mem_type, * 2 Fundamental memory type *"); 9845614e71bSYork Sun printf("%-3d : %02x %s\n", 3, spd->nrow_addr, 9855614e71bSYork Sun " spd->nrow_addr, * 3 # of Row Addresses on this assembly *"); 9865614e71bSYork Sun printf("%-3d : %02x %s\n", 4, spd->ncol_addr, 9875614e71bSYork Sun " spd->ncol_addr, * 4 # of Column Addrs on this assembly *"); 9885614e71bSYork Sun printf("%-3d : %02x %s\n", 5, spd->mod_ranks, 9895614e71bSYork Sun " spd->mod_ranks * 5 # of Module Rows on this assembly *"); 9905614e71bSYork Sun printf("%-3d : %02x %s\n", 6, spd->dataw, 9915614e71bSYork Sun " spd->dataw, * 6 Data Width of this assembly *"); 9925614e71bSYork Sun printf("%-3d : %02x %s\n", 7, spd->res_7, 9935614e71bSYork Sun " spd->res_7, * 7 Reserved *"); 9945614e71bSYork Sun printf("%-3d : %02x %s\n", 8, spd->voltage, 9955614e71bSYork Sun " spd->voltage, * 8 Voltage intf std of this assembly *"); 9965614e71bSYork Sun printf("%-3d : %02x %s\n", 9, spd->clk_cycle, 9975614e71bSYork Sun " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *"); 9985614e71bSYork Sun printf("%-3d : %02x %s\n", 10, spd->clk_access, 9995614e71bSYork Sun " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *"); 10005614e71bSYork Sun printf("%-3d : %02x %s\n", 11, spd->config, 10015614e71bSYork Sun " spd->config, * 11 DIMM Configuration type *"); 10025614e71bSYork Sun printf("%-3d : %02x %s\n", 12, spd->refresh, 10035614e71bSYork Sun " spd->refresh, * 12 Refresh Rate/Type *"); 10045614e71bSYork Sun printf("%-3d : %02x %s\n", 13, spd->primw, 10055614e71bSYork Sun " spd->primw, * 13 Primary SDRAM Width *"); 10065614e71bSYork Sun printf("%-3d : %02x %s\n", 14, spd->ecw, 10075614e71bSYork Sun " spd->ecw, * 14 Error Checking SDRAM width *"); 10085614e71bSYork Sun printf("%-3d : %02x %s\n", 15, spd->res_15, 10095614e71bSYork Sun " spd->res_15, * 15 Reserved *"); 10105614e71bSYork Sun printf("%-3d : %02x %s\n", 16, spd->burstl, 10115614e71bSYork Sun " spd->burstl, * 16 Burst Lengths Supported *"); 10125614e71bSYork Sun printf("%-3d : %02x %s\n", 17, spd->nbanks, 10135614e71bSYork Sun " spd->nbanks, * 17 # of Banks on Each SDRAM Device *"); 10145614e71bSYork Sun printf("%-3d : %02x %s\n", 18, spd->cas_lat, 10155614e71bSYork Sun " spd->cas_lat, * 18 CAS# Latencies Supported *"); 10165614e71bSYork Sun printf("%-3d : %02x %s\n", 19, spd->mech_char, 10175614e71bSYork Sun " spd->mech_char, * 19 Mechanical Characteristics *"); 10185614e71bSYork Sun printf("%-3d : %02x %s\n", 20, spd->dimm_type, 10195614e71bSYork Sun " spd->dimm_type, * 20 DIMM type *"); 10205614e71bSYork Sun printf("%-3d : %02x %s\n", 21, spd->mod_attr, 10215614e71bSYork Sun " spd->mod_attr, * 21 SDRAM Module Attributes *"); 10225614e71bSYork Sun printf("%-3d : %02x %s\n", 22, spd->dev_attr, 10235614e71bSYork Sun " spd->dev_attr, * 22 SDRAM Device Attributes *"); 10245614e71bSYork Sun printf("%-3d : %02x %s\n", 23, spd->clk_cycle2, 10255614e71bSYork Sun " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *"); 10265614e71bSYork Sun printf("%-3d : %02x %s\n", 24, spd->clk_access2, 10275614e71bSYork Sun " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *"); 10285614e71bSYork Sun printf("%-3d : %02x %s\n", 25, spd->clk_cycle3, 10295614e71bSYork Sun " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *"); 10305614e71bSYork Sun printf("%-3d : %02x %s\n", 26, spd->clk_access3, 10315614e71bSYork Sun " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *"); 10325614e71bSYork Sun printf("%-3d : %02x %s\n", 27, spd->trp, 10335614e71bSYork Sun " spd->trp, * 27 Min Row Precharge Time (tRP)*"); 10345614e71bSYork Sun printf("%-3d : %02x %s\n", 28, spd->trrd, 10355614e71bSYork Sun " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *"); 10365614e71bSYork Sun printf("%-3d : %02x %s\n", 29, spd->trcd, 10375614e71bSYork Sun " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *"); 10385614e71bSYork Sun printf("%-3d : %02x %s\n", 30, spd->tras, 10395614e71bSYork Sun " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *"); 10405614e71bSYork Sun printf("%-3d : %02x %s\n", 31, spd->rank_dens, 10415614e71bSYork Sun " spd->rank_dens, * 31 Density of each rank on module *"); 10425614e71bSYork Sun printf("%-3d : %02x %s\n", 32, spd->ca_setup, 10435614e71bSYork Sun " spd->ca_setup, * 32 Cmd + Addr signal input setup time *"); 10445614e71bSYork Sun printf("%-3d : %02x %s\n", 33, spd->ca_hold, 10455614e71bSYork Sun " spd->ca_hold, * 33 Cmd and Addr signal input hold time *"); 10465614e71bSYork Sun printf("%-3d : %02x %s\n", 34, spd->data_setup, 10475614e71bSYork Sun " spd->data_setup, * 34 Data signal input setup time *"); 10485614e71bSYork Sun printf("%-3d : %02x %s\n", 35, spd->data_hold, 10495614e71bSYork Sun " spd->data_hold, * 35 Data signal input hold time *"); 10505614e71bSYork Sun printf("%-3d : %02x %s\n", 36, spd->twr, 10515614e71bSYork Sun " spd->twr, * 36 Write Recovery time tWR *"); 10525614e71bSYork Sun printf("%-3d : %02x %s\n", 37, spd->twtr, 10535614e71bSYork Sun " spd->twtr, * 37 Int write to read delay tWTR *"); 10545614e71bSYork Sun printf("%-3d : %02x %s\n", 38, spd->trtp, 10555614e71bSYork Sun " spd->trtp, * 38 Int read to precharge delay tRTP *"); 10565614e71bSYork Sun printf("%-3d : %02x %s\n", 39, spd->mem_probe, 10575614e71bSYork Sun " spd->mem_probe, * 39 Mem analysis probe characteristics *"); 10585614e71bSYork Sun printf("%-3d : %02x %s\n", 40, spd->trctrfc_ext, 10595614e71bSYork Sun " spd->trctrfc_ext, * 40 Extensions to trc and trfc *"); 10605614e71bSYork Sun printf("%-3d : %02x %s\n", 41, spd->trc, 10615614e71bSYork Sun " spd->trc, * 41 Min Active to Auto refresh time tRC *"); 10625614e71bSYork Sun printf("%-3d : %02x %s\n", 42, spd->trfc, 10635614e71bSYork Sun " spd->trfc, * 42 Min Auto to Active period tRFC *"); 10645614e71bSYork Sun printf("%-3d : %02x %s\n", 43, spd->tckmax, 10655614e71bSYork Sun " spd->tckmax, * 43 Max device cycle time tCKmax *"); 10665614e71bSYork Sun printf("%-3d : %02x %s\n", 44, spd->tdqsq, 10675614e71bSYork Sun " spd->tdqsq, * 44 Max DQS to DQ skew *"); 10685614e71bSYork Sun printf("%-3d : %02x %s\n", 45, spd->tqhs, 10695614e71bSYork Sun " spd->tqhs, * 45 Max Read DataHold skew tQHS *"); 10705614e71bSYork Sun printf("%-3d : %02x %s\n", 46, spd->pll_relock, 10715614e71bSYork Sun " spd->pll_relock, * 46 PLL Relock time *"); 10725614e71bSYork Sun printf("%-3d : %02x %s\n", 47, spd->t_casemax, 10735614e71bSYork Sun " spd->t_casemax, * 47 t_casemax *"); 10745614e71bSYork Sun printf("%-3d : %02x %s\n", 48, spd->psi_ta_dram, 10755614e71bSYork Sun " spd->psi_ta_dram, * 48 Thermal Resistance of DRAM Package " 10765614e71bSYork Sun "from Top (Case) to Ambient (Psi T-A DRAM) *"); 10775614e71bSYork Sun printf("%-3d : %02x %s\n", 49, spd->dt0_mode, 10785614e71bSYork Sun " spd->dt0_mode, * 49 DRAM Case Temperature Rise from " 10795614e71bSYork Sun "Ambient due to Activate-Precharge/Mode Bits " 10805614e71bSYork Sun "(DT0/Mode Bits) *)"); 10815614e71bSYork Sun printf("%-3d : %02x %s\n", 50, spd->dt2n_dt2q, 10825614e71bSYork Sun " spd->dt2n_dt2q, * 50 DRAM Case Temperature Rise from " 10835614e71bSYork Sun "Ambient due to Precharge/Quiet Standby " 10845614e71bSYork Sun "(DT2N/DT2Q) *"); 10855614e71bSYork Sun printf("%-3d : %02x %s\n", 51, spd->dt2p, 10865614e71bSYork Sun " spd->dt2p, * 51 DRAM Case Temperature Rise from " 10875614e71bSYork Sun "Ambient due to Precharge Power-Down (DT2P) *"); 10885614e71bSYork Sun printf("%-3d : %02x %s\n", 52, spd->dt3n, 10895614e71bSYork Sun " spd->dt3n, * 52 DRAM Case Temperature Rise from " 10905614e71bSYork Sun "Ambient due to Active Standby (DT3N) *"); 10915614e71bSYork Sun printf("%-3d : %02x %s\n", 53, spd->dt3pfast, 10925614e71bSYork Sun " spd->dt3pfast, * 53 DRAM Case Temperature Rise from " 10935614e71bSYork Sun "Ambient due to Active Power-Down with Fast PDN Exit " 10945614e71bSYork Sun "(DT3Pfast) *"); 10955614e71bSYork Sun printf("%-3d : %02x %s\n", 54, spd->dt3pslow, 10965614e71bSYork Sun " spd->dt3pslow, * 54 DRAM Case Temperature Rise from " 10975614e71bSYork Sun "Ambient due to Active Power-Down with Slow PDN Exit " 10985614e71bSYork Sun "(DT3Pslow) *"); 10995614e71bSYork Sun printf("%-3d : %02x %s\n", 55, spd->dt4r_dt4r4w, 11005614e71bSYork Sun " spd->dt4r_dt4r4w, * 55 DRAM Case Temperature Rise from " 11015614e71bSYork Sun "Ambient due to Page Open Burst Read/DT4R4W Mode Bit " 11025614e71bSYork Sun "(DT4R/DT4R4W Mode Bit) *"); 11035614e71bSYork Sun printf("%-3d : %02x %s\n", 56, spd->dt5b, 11045614e71bSYork Sun " spd->dt5b, * 56 DRAM Case Temperature Rise from " 11055614e71bSYork Sun "Ambient due to Burst Refresh (DT5B) *"); 11065614e71bSYork Sun printf("%-3d : %02x %s\n", 57, spd->dt7, 11075614e71bSYork Sun " spd->dt7, * 57 DRAM Case Temperature Rise from " 11085614e71bSYork Sun "Ambient due to Bank Interleave Reads with " 11095614e71bSYork Sun "Auto-Precharge (DT7) *"); 11105614e71bSYork Sun printf("%-3d : %02x %s\n", 58, spd->psi_ta_pll, 11115614e71bSYork Sun " spd->psi_ta_pll, * 58 Thermal Resistance of PLL Package form" 11125614e71bSYork Sun " Top (Case) to Ambient (Psi T-A PLL) *"); 11135614e71bSYork Sun printf("%-3d : %02x %s\n", 59, spd->psi_ta_reg, 11145614e71bSYork Sun " spd->psi_ta_reg, * 59 Thermal Reisitance of Register Package" 11155614e71bSYork Sun " from Top (Case) to Ambient (Psi T-A Register) *"); 11165614e71bSYork Sun printf("%-3d : %02x %s\n", 60, spd->dtpllactive, 11175614e71bSYork Sun " spd->dtpllactive, * 60 PLL Case Temperature Rise from " 11185614e71bSYork Sun "Ambient due to PLL Active (DT PLL Active) *"); 11195614e71bSYork Sun printf("%-3d : %02x %s\n", 61, spd->dtregact, 11205614e71bSYork Sun " spd->dtregact, " 11215614e71bSYork Sun "* 61 Register Case Temperature Rise from Ambient due to " 11225614e71bSYork Sun "Register Active/Mode Bit (DT Register Active/Mode Bit) *"); 11235614e71bSYork Sun printf("%-3d : %02x %s\n", 62, spd->spd_rev, 11245614e71bSYork Sun " spd->spd_rev, * 62 SPD Data Revision Code *"); 11255614e71bSYork Sun printf("%-3d : %02x %s\n", 63, spd->cksum, 11265614e71bSYork Sun " spd->cksum, * 63 Checksum for bytes 0-62 *"); 11275614e71bSYork Sun 11285614e71bSYork Sun printf("%-3d-%3d: ", 64, 71); 11295614e71bSYork Sun 11305614e71bSYork Sun for (i = 0; i < 8; i++) 11315614e71bSYork Sun printf("%02x", spd->mid[i]); 11325614e71bSYork Sun 11335614e71bSYork Sun printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n"); 11345614e71bSYork Sun 11355614e71bSYork Sun printf("%-3d : %02x %s\n", 72, spd->mloc, 11365614e71bSYork Sun " spd->mloc, * 72 Manufacturing Location *"); 11375614e71bSYork Sun 11385614e71bSYork Sun printf("%-3d-%3d: >>", 73, 90); 11395614e71bSYork Sun for (i = 0; i < 18; i++) 11405614e71bSYork Sun printf("%c", spd->mpart[i]); 11415614e71bSYork Sun 11425614e71bSYork Sun 11435614e71bSYork Sun printf("<<* 73 Manufacturer's Part Number *\n"); 11445614e71bSYork Sun 11455614e71bSYork Sun printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1], 11465614e71bSYork Sun "* 91 Revision Code *"); 11475614e71bSYork Sun printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1], 11485614e71bSYork Sun "* 93 Manufacturing Date *"); 11495614e71bSYork Sun printf("%-3d-%3d: ", 95, 98); 11505614e71bSYork Sun 11515614e71bSYork Sun for (i = 0; i < 4; i++) 11525614e71bSYork Sun printf("%02x", spd->sernum[i]); 11535614e71bSYork Sun 11545614e71bSYork Sun printf("* 95 Assembly Serial Number *\n"); 11555614e71bSYork Sun 11565614e71bSYork Sun printf("%-3d-%3d: ", 99, 127); 11575614e71bSYork Sun for (i = 0; i < 27; i++) 11585614e71bSYork Sun printf("%02x", spd->mspec[i]); 11595614e71bSYork Sun 11605614e71bSYork Sun 11615614e71bSYork Sun printf("* 99 Manufacturer Specific Data *\n"); 11625614e71bSYork Sun } 11635614e71bSYork Sun #endif 11645614e71bSYork Sun 11655614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR3 11665614e71bSYork Sun void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd) 11675614e71bSYork Sun { 11685614e71bSYork Sun unsigned int i; 11695614e71bSYork Sun 11705614e71bSYork Sun /* General Section: Bytes 0-59 */ 11715614e71bSYork Sun 11725614e71bSYork Sun #define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); 11735614e71bSYork Sun #define PRINT_NNXXS(n0, n1, x0, x1, s) \ 11745614e71bSYork Sun printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); 11755614e71bSYork Sun 11765614e71bSYork Sun PRINT_NXS(0, spd->info_size_crc, 11775614e71bSYork Sun "info_size_crc bytes written into serial memory, " 11785614e71bSYork Sun "CRC coverage"); 11795614e71bSYork Sun PRINT_NXS(1, spd->spd_rev, 11805614e71bSYork Sun "spd_rev SPD Revision"); 11815614e71bSYork Sun PRINT_NXS(2, spd->mem_type, 11825614e71bSYork Sun "mem_type Key Byte / DRAM Device Type"); 11835614e71bSYork Sun PRINT_NXS(3, spd->module_type, 11845614e71bSYork Sun "module_type Key Byte / Module Type"); 11855614e71bSYork Sun PRINT_NXS(4, spd->density_banks, 11865614e71bSYork Sun "density_banks SDRAM Density and Banks"); 11875614e71bSYork Sun PRINT_NXS(5, spd->addressing, 11885614e71bSYork Sun "addressing SDRAM Addressing"); 11895614e71bSYork Sun PRINT_NXS(6, spd->module_vdd, 11905614e71bSYork Sun "module_vdd Module Nominal Voltage, VDD"); 11915614e71bSYork Sun PRINT_NXS(7, spd->organization, 11925614e71bSYork Sun "organization Module Organization"); 11935614e71bSYork Sun PRINT_NXS(8, spd->bus_width, 11945614e71bSYork Sun "bus_width Module Memory Bus Width"); 11955614e71bSYork Sun PRINT_NXS(9, spd->ftb_div, 11965614e71bSYork Sun "ftb_div Fine Timebase (FTB) Dividend / Divisor"); 11975614e71bSYork Sun PRINT_NXS(10, spd->mtb_dividend, 11985614e71bSYork Sun "mtb_dividend Medium Timebase (MTB) Dividend"); 11995614e71bSYork Sun PRINT_NXS(11, spd->mtb_divisor, 12005614e71bSYork Sun "mtb_divisor Medium Timebase (MTB) Divisor"); 12015614e71bSYork Sun PRINT_NXS(12, spd->tck_min, 12025614e71bSYork Sun "tck_min SDRAM Minimum Cycle Time"); 12035614e71bSYork Sun PRINT_NXS(13, spd->res_13, 12045614e71bSYork Sun "res_13 Reserved"); 12055614e71bSYork Sun PRINT_NXS(14, spd->caslat_lsb, 12065614e71bSYork Sun "caslat_lsb CAS Latencies Supported, LSB"); 12075614e71bSYork Sun PRINT_NXS(15, spd->caslat_msb, 12085614e71bSYork Sun "caslat_msb CAS Latencies Supported, MSB"); 12095614e71bSYork Sun PRINT_NXS(16, spd->taa_min, 12105614e71bSYork Sun "taa_min Min CAS Latency Time"); 12115614e71bSYork Sun PRINT_NXS(17, spd->twr_min, 12125614e71bSYork Sun "twr_min Min Write REcovery Time"); 12135614e71bSYork Sun PRINT_NXS(18, spd->trcd_min, 12145614e71bSYork Sun "trcd_min Min RAS# to CAS# Delay Time"); 12155614e71bSYork Sun PRINT_NXS(19, spd->trrd_min, 12165614e71bSYork Sun "trrd_min Min Row Active to Row Active Delay Time"); 12175614e71bSYork Sun PRINT_NXS(20, spd->trp_min, 12185614e71bSYork Sun "trp_min Min Row Precharge Delay Time"); 12195614e71bSYork Sun PRINT_NXS(21, spd->tras_trc_ext, 12205614e71bSYork Sun "tras_trc_ext Upper Nibbles for tRAS and tRC"); 12215614e71bSYork Sun PRINT_NXS(22, spd->tras_min_lsb, 12225614e71bSYork Sun "tras_min_lsb Min Active to Precharge Delay Time, LSB"); 12235614e71bSYork Sun PRINT_NXS(23, spd->trc_min_lsb, 12245614e71bSYork Sun "trc_min_lsb Min Active to Active/Refresh Delay Time, LSB"); 12255614e71bSYork Sun PRINT_NXS(24, spd->trfc_min_lsb, 12265614e71bSYork Sun "trfc_min_lsb Min Refresh Recovery Delay Time LSB"); 12275614e71bSYork Sun PRINT_NXS(25, spd->trfc_min_msb, 12285614e71bSYork Sun "trfc_min_msb Min Refresh Recovery Delay Time MSB"); 12295614e71bSYork Sun PRINT_NXS(26, spd->twtr_min, 12305614e71bSYork Sun "twtr_min Min Internal Write to Read Command Delay Time"); 12315614e71bSYork Sun PRINT_NXS(27, spd->trtp_min, 12325614e71bSYork Sun "trtp_min " 12335614e71bSYork Sun "Min Internal Read to Precharge Command Delay Time"); 12345614e71bSYork Sun PRINT_NXS(28, spd->tfaw_msb, 12355614e71bSYork Sun "tfaw_msb Upper Nibble for tFAW"); 12365614e71bSYork Sun PRINT_NXS(29, spd->tfaw_min, 12375614e71bSYork Sun "tfaw_min Min Four Activate Window Delay Time"); 12385614e71bSYork Sun PRINT_NXS(30, spd->opt_features, 12395614e71bSYork Sun "opt_features SDRAM Optional Features"); 12405614e71bSYork Sun PRINT_NXS(31, spd->therm_ref_opt, 12415614e71bSYork Sun "therm_ref_opt SDRAM Thermal and Refresh Opts"); 12425614e71bSYork Sun PRINT_NXS(32, spd->therm_sensor, 12435614e71bSYork Sun "therm_sensor SDRAM Thermal Sensor"); 12445614e71bSYork Sun PRINT_NXS(33, spd->device_type, 12455614e71bSYork Sun "device_type SDRAM Device Type"); 12465614e71bSYork Sun PRINT_NXS(34, spd->fine_tck_min, 12475614e71bSYork Sun "fine_tck_min Fine offset for tCKmin"); 12485614e71bSYork Sun PRINT_NXS(35, spd->fine_taa_min, 12495614e71bSYork Sun "fine_taa_min Fine offset for tAAmin"); 12505614e71bSYork Sun PRINT_NXS(36, spd->fine_trcd_min, 12515614e71bSYork Sun "fine_trcd_min Fine offset for tRCDmin"); 12525614e71bSYork Sun PRINT_NXS(37, spd->fine_trp_min, 12535614e71bSYork Sun "fine_trp_min Fine offset for tRPmin"); 12545614e71bSYork Sun PRINT_NXS(38, spd->fine_trc_min, 12555614e71bSYork Sun "fine_trc_min Fine offset for tRCmin"); 12565614e71bSYork Sun 12575614e71bSYork Sun printf("%-3d-%3d: ", 39, 59); /* Reserved, General Section */ 12585614e71bSYork Sun 12595614e71bSYork Sun for (i = 39; i <= 59; i++) 12605614e71bSYork Sun printf("%02x ", spd->res_39_59[i - 39]); 12615614e71bSYork Sun 12625614e71bSYork Sun puts("\n"); 12635614e71bSYork Sun 12645614e71bSYork Sun switch (spd->module_type) { 12655614e71bSYork Sun case 0x02: /* UDIMM */ 12665614e71bSYork Sun case 0x03: /* SO-DIMM */ 12675614e71bSYork Sun case 0x04: /* Micro-DIMM */ 12685614e71bSYork Sun case 0x06: /* Mini-UDIMM */ 12695614e71bSYork Sun PRINT_NXS(60, spd->mod_section.unbuffered.mod_height, 12705614e71bSYork Sun "mod_height (Unbuffered) Module Nominal Height"); 12715614e71bSYork Sun PRINT_NXS(61, spd->mod_section.unbuffered.mod_thickness, 12725614e71bSYork Sun "mod_thickness (Unbuffered) Module Maximum Thickness"); 12735614e71bSYork Sun PRINT_NXS(62, spd->mod_section.unbuffered.ref_raw_card, 12745614e71bSYork Sun "ref_raw_card (Unbuffered) Reference Raw Card Used"); 12755614e71bSYork Sun PRINT_NXS(63, spd->mod_section.unbuffered.addr_mapping, 12765614e71bSYork Sun "addr_mapping (Unbuffered) Address mapping from " 12775614e71bSYork Sun "Edge Connector to DRAM"); 12785614e71bSYork Sun break; 12795614e71bSYork Sun case 0x01: /* RDIMM */ 12805614e71bSYork Sun case 0x05: /* Mini-RDIMM */ 12815614e71bSYork Sun PRINT_NXS(60, spd->mod_section.registered.mod_height, 12825614e71bSYork Sun "mod_height (Registered) Module Nominal Height"); 12835614e71bSYork Sun PRINT_NXS(61, spd->mod_section.registered.mod_thickness, 12845614e71bSYork Sun "mod_thickness (Registered) Module Maximum Thickness"); 12855614e71bSYork Sun PRINT_NXS(62, spd->mod_section.registered.ref_raw_card, 12865614e71bSYork Sun "ref_raw_card (Registered) Reference Raw Card Used"); 12875614e71bSYork Sun PRINT_NXS(63, spd->mod_section.registered.modu_attr, 12885614e71bSYork Sun "modu_attr (Registered) DIMM Module Attributes"); 12895614e71bSYork Sun PRINT_NXS(64, spd->mod_section.registered.thermal, 12905614e71bSYork Sun "thermal (Registered) Thermal Heat " 12915614e71bSYork Sun "Spreader Solution"); 12925614e71bSYork Sun PRINT_NXS(65, spd->mod_section.registered.reg_id_lo, 12935614e71bSYork Sun "reg_id_lo (Registered) Register Manufacturer ID " 12945614e71bSYork Sun "Code, LSB"); 12955614e71bSYork Sun PRINT_NXS(66, spd->mod_section.registered.reg_id_hi, 12965614e71bSYork Sun "reg_id_hi (Registered) Register Manufacturer ID " 12975614e71bSYork Sun "Code, MSB"); 12985614e71bSYork Sun PRINT_NXS(67, spd->mod_section.registered.reg_rev, 12995614e71bSYork Sun "reg_rev (Registered) Register " 13005614e71bSYork Sun "Revision Number"); 13015614e71bSYork Sun PRINT_NXS(68, spd->mod_section.registered.reg_type, 13025614e71bSYork Sun "reg_type (Registered) Register Type"); 13035614e71bSYork Sun for (i = 69; i <= 76; i++) { 13045614e71bSYork Sun printf("%-3d : %02x rcw[%d]\n", i, 13055614e71bSYork Sun spd->mod_section.registered.rcw[i-69], i-69); 13065614e71bSYork Sun } 13075614e71bSYork Sun break; 13085614e71bSYork Sun default: 13095614e71bSYork Sun /* Module-specific Section, Unsupported Module Type */ 13105614e71bSYork Sun printf("%-3d-%3d: ", 60, 116); 13115614e71bSYork Sun 13125614e71bSYork Sun for (i = 60; i <= 116; i++) 13135614e71bSYork Sun printf("%02x", spd->mod_section.uc[i - 60]); 13145614e71bSYork Sun 13155614e71bSYork Sun break; 13165614e71bSYork Sun } 13175614e71bSYork Sun 13185614e71bSYork Sun /* Unique Module ID: Bytes 117-125 */ 13195614e71bSYork Sun PRINT_NXS(117, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106"); 13205614e71bSYork Sun PRINT_NXS(118, spd->mmid_msb, "Module MfgID Code MSB - JEP-106"); 13215614e71bSYork Sun PRINT_NXS(119, spd->mloc, "Mfg Location"); 13225614e71bSYork Sun PRINT_NNXXS(120, 121, spd->mdate[0], spd->mdate[1], "Mfg Date"); 13235614e71bSYork Sun 13245614e71bSYork Sun printf("%-3d-%3d: ", 122, 125); 13255614e71bSYork Sun 13265614e71bSYork Sun for (i = 122; i <= 125; i++) 13275614e71bSYork Sun printf("%02x ", spd->sernum[i - 122]); 13285614e71bSYork Sun printf(" Module Serial Number\n"); 13295614e71bSYork Sun 13305614e71bSYork Sun /* CRC: Bytes 126-127 */ 13315614e71bSYork Sun PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC"); 13325614e71bSYork Sun 13335614e71bSYork Sun /* Other Manufacturer Fields and User Space: Bytes 128-255 */ 13345614e71bSYork Sun printf("%-3d-%3d: ", 128, 145); 13355614e71bSYork Sun for (i = 128; i <= 145; i++) 13365614e71bSYork Sun printf("%02x ", spd->mpart[i - 128]); 13375614e71bSYork Sun printf(" Mfg's Module Part Number\n"); 13385614e71bSYork Sun 13395614e71bSYork Sun PRINT_NNXXS(146, 147, spd->mrev[0], spd->mrev[1], 13405614e71bSYork Sun "Module Revision code"); 13415614e71bSYork Sun 13425614e71bSYork Sun PRINT_NXS(148, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106"); 13435614e71bSYork Sun PRINT_NXS(149, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106"); 13445614e71bSYork Sun 13455614e71bSYork Sun printf("%-3d-%3d: ", 150, 175); 13465614e71bSYork Sun for (i = 150; i <= 175; i++) 13475614e71bSYork Sun printf("%02x ", spd->msd[i - 150]); 13485614e71bSYork Sun printf(" Mfg's Specific Data\n"); 13495614e71bSYork Sun 13505614e71bSYork Sun printf("%-3d-%3d: ", 176, 255); 13515614e71bSYork Sun for (i = 176; i <= 255; i++) 13525614e71bSYork Sun printf("%02x", spd->cust[i - 176]); 13535614e71bSYork Sun printf(" Mfg's Specific Data\n"); 13545614e71bSYork Sun 13555614e71bSYork Sun } 13565614e71bSYork Sun #endif 13575614e71bSYork Sun 135834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4 135934e026f9SYork Sun void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd) 136034e026f9SYork Sun { 136134e026f9SYork Sun unsigned int i; 136234e026f9SYork Sun 136334e026f9SYork Sun /* General Section: Bytes 0-127 */ 136434e026f9SYork Sun 136534e026f9SYork Sun #define PRINT_NXS(x, y, z...) printf("%-3d : %02x " z "\n", x, (u8)y); 136634e026f9SYork Sun #define PRINT_NNXXS(n0, n1, x0, x1, s) \ 136734e026f9SYork Sun printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1); 136834e026f9SYork Sun 136934e026f9SYork Sun PRINT_NXS(0, spd->info_size_crc, 137034e026f9SYork Sun "info_size_crc bytes written into serial memory, CRC coverage"); 137134e026f9SYork Sun PRINT_NXS(1, spd->spd_rev, 137234e026f9SYork Sun "spd_rev SPD Revision"); 137334e026f9SYork Sun PRINT_NXS(2, spd->mem_type, 137434e026f9SYork Sun "mem_type Key Byte / DRAM Device Type"); 137534e026f9SYork Sun PRINT_NXS(3, spd->module_type, 137634e026f9SYork Sun "module_type Key Byte / Module Type"); 137734e026f9SYork Sun PRINT_NXS(4, spd->density_banks, 137834e026f9SYork Sun "density_banks SDRAM Density and Banks"); 137934e026f9SYork Sun PRINT_NXS(5, spd->addressing, 138034e026f9SYork Sun "addressing SDRAM Addressing"); 138134e026f9SYork Sun PRINT_NXS(6, spd->package_type, 138234e026f9SYork Sun "package_type Package type"); 138334e026f9SYork Sun PRINT_NXS(7, spd->opt_feature, 138434e026f9SYork Sun "opt_feature Optional features"); 138534e026f9SYork Sun PRINT_NXS(8, spd->thermal_ref, 138634e026f9SYork Sun "thermal_ref Thermal and Refresh options"); 138734e026f9SYork Sun PRINT_NXS(9, spd->oth_opt_features, 138834e026f9SYork Sun "oth_opt_features Other SDRAM optional features"); 138934e026f9SYork Sun PRINT_NXS(10, spd->res_10, 139034e026f9SYork Sun "res_10 Reserved"); 139134e026f9SYork Sun PRINT_NXS(11, spd->module_vdd, 139234e026f9SYork Sun "module_vdd Module Nominal Voltage, VDD"); 139334e026f9SYork Sun PRINT_NXS(12, spd->organization, 139434e026f9SYork Sun "organization Module Organization"); 139534e026f9SYork Sun PRINT_NXS(13, spd->bus_width, 139634e026f9SYork Sun "bus_width Module Memory Bus Width"); 139734e026f9SYork Sun PRINT_NXS(14, spd->therm_sensor, 139834e026f9SYork Sun "therm_sensor Module Thermal Sensor"); 139934e026f9SYork Sun PRINT_NXS(15, spd->ext_type, 140034e026f9SYork Sun "ext_type Extended module type"); 140134e026f9SYork Sun PRINT_NXS(16, spd->res_16, 140234e026f9SYork Sun "res_16 Reserved"); 140334e026f9SYork Sun PRINT_NXS(17, spd->timebases, 140434e026f9SYork Sun "timebases MTb and FTB"); 140534e026f9SYork Sun PRINT_NXS(18, spd->tck_min, 140634e026f9SYork Sun "tck_min tCKAVGmin"); 140734e026f9SYork Sun PRINT_NXS(19, spd->tck_max, 140834e026f9SYork Sun "tck_max TCKAVGmax"); 140934e026f9SYork Sun PRINT_NXS(20, spd->caslat_b1, 141034e026f9SYork Sun "caslat_b1 CAS latencies, 1st byte"); 141134e026f9SYork Sun PRINT_NXS(21, spd->caslat_b2, 141234e026f9SYork Sun "caslat_b2 CAS latencies, 2nd byte"); 141334e026f9SYork Sun PRINT_NXS(22, spd->caslat_b3, 141434e026f9SYork Sun "caslat_b3 CAS latencies, 3rd byte "); 141534e026f9SYork Sun PRINT_NXS(23, spd->caslat_b4, 141634e026f9SYork Sun "caslat_b4 CAS latencies, 4th byte"); 141734e026f9SYork Sun PRINT_NXS(24, spd->taa_min, 141834e026f9SYork Sun "taa_min Min CAS Latency Time"); 141934e026f9SYork Sun PRINT_NXS(25, spd->trcd_min, 142034e026f9SYork Sun "trcd_min Min RAS# to CAS# Delay Time"); 142134e026f9SYork Sun PRINT_NXS(26, spd->trp_min, 142234e026f9SYork Sun "trp_min Min Row Precharge Delay Time"); 142334e026f9SYork Sun PRINT_NXS(27, spd->tras_trc_ext, 142434e026f9SYork Sun "tras_trc_ext Upper Nibbles for tRAS and tRC"); 142534e026f9SYork Sun PRINT_NXS(28, spd->tras_min_lsb, 142634e026f9SYork Sun "tras_min_lsb tRASmin, lsb"); 142734e026f9SYork Sun PRINT_NXS(29, spd->trc_min_lsb, 142834e026f9SYork Sun "trc_min_lsb tRCmin, lsb"); 142934e026f9SYork Sun PRINT_NXS(30, spd->trfc1_min_lsb, 143034e026f9SYork Sun "trfc1_min_lsb Min Refresh Recovery Delay Time, LSB"); 143134e026f9SYork Sun PRINT_NXS(31, spd->trfc1_min_msb, 143234e026f9SYork Sun "trfc1_min_msb Min Refresh Recovery Delay Time, MSB "); 143334e026f9SYork Sun PRINT_NXS(32, spd->trfc2_min_lsb, 143434e026f9SYork Sun "trfc2_min_lsb Min Refresh Recovery Delay Time, LSB"); 143534e026f9SYork Sun PRINT_NXS(33, spd->trfc2_min_msb, 143634e026f9SYork Sun "trfc2_min_msb Min Refresh Recovery Delay Time, MSB"); 143734e026f9SYork Sun PRINT_NXS(34, spd->trfc4_min_lsb, 143834e026f9SYork Sun "trfc4_min_lsb Min Refresh Recovery Delay Time, LSB"); 143934e026f9SYork Sun PRINT_NXS(35, spd->trfc4_min_msb, 144034e026f9SYork Sun "trfc4_min_msb Min Refresh Recovery Delay Time, MSB"); 144134e026f9SYork Sun PRINT_NXS(36, spd->tfaw_msb, 144234e026f9SYork Sun "tfaw_msb Upper Nibble for tFAW"); 144334e026f9SYork Sun PRINT_NXS(37, spd->tfaw_min, 144434e026f9SYork Sun "tfaw_min tFAW, lsb"); 144534e026f9SYork Sun PRINT_NXS(38, spd->trrds_min, 144634e026f9SYork Sun "trrds_min tRRD_Smin, MTB"); 144734e026f9SYork Sun PRINT_NXS(39, spd->trrdl_min, 144834e026f9SYork Sun "trrdl_min tRRD_Lmin, MTB"); 144934e026f9SYork Sun PRINT_NXS(40, spd->tccdl_min, 145034e026f9SYork Sun "tccdl_min tCCS_Lmin, MTB"); 145134e026f9SYork Sun 145234e026f9SYork Sun printf("%-3d-%3d: ", 41, 59); /* Reserved, General Section */ 145334e026f9SYork Sun for (i = 41; i <= 59; i++) 145434e026f9SYork Sun printf("%02x ", spd->res_41[i - 41]); 145534e026f9SYork Sun 145634e026f9SYork Sun puts("\n"); 145734e026f9SYork Sun printf("%-3d-%3d: ", 60, 77); 145834e026f9SYork Sun for (i = 60; i <= 77; i++) 145934e026f9SYork Sun printf("%02x ", spd->mapping[i - 60]); 146034e026f9SYork Sun puts(" mapping[] Connector to SDRAM bit map\n"); 146134e026f9SYork Sun 146234e026f9SYork Sun PRINT_NXS(117, spd->fine_tccdl_min, 146334e026f9SYork Sun "fine_tccdl_min Fine offset for tCCD_Lmin"); 146434e026f9SYork Sun PRINT_NXS(118, spd->fine_trrdl_min, 146534e026f9SYork Sun "fine_trrdl_min Fine offset for tRRD_Lmin"); 146634e026f9SYork Sun PRINT_NXS(119, spd->fine_trrds_min, 146734e026f9SYork Sun "fine_trrds_min Fine offset for tRRD_Smin"); 146834e026f9SYork Sun PRINT_NXS(120, spd->fine_trc_min, 146934e026f9SYork Sun "fine_trc_min Fine offset for tRCmin"); 147034e026f9SYork Sun PRINT_NXS(121, spd->fine_trp_min, 147134e026f9SYork Sun "fine_trp_min Fine offset for tRPmin"); 147234e026f9SYork Sun PRINT_NXS(122, spd->fine_trcd_min, 147334e026f9SYork Sun "fine_trcd_min Fine offset for tRCDmin"); 147434e026f9SYork Sun PRINT_NXS(123, spd->fine_taa_min, 147534e026f9SYork Sun "fine_taa_min Fine offset for tAAmin"); 147634e026f9SYork Sun PRINT_NXS(124, spd->fine_tck_max, 147734e026f9SYork Sun "fine_tck_max Fine offset for tCKAVGmax"); 147834e026f9SYork Sun PRINT_NXS(125, spd->fine_tck_min, 147934e026f9SYork Sun "fine_tck_min Fine offset for tCKAVGmin"); 148034e026f9SYork Sun 148134e026f9SYork Sun /* CRC: Bytes 126-127 */ 148234e026f9SYork Sun PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], " SPD CRC"); 148334e026f9SYork Sun 148434e026f9SYork Sun switch (spd->module_type) { 148534e026f9SYork Sun case 0x02: /* UDIMM */ 148634e026f9SYork Sun case 0x03: /* SO-DIMM */ 148734e026f9SYork Sun PRINT_NXS(128, spd->mod_section.unbuffered.mod_height, 148834e026f9SYork Sun "mod_height (Unbuffered) Module Nominal Height"); 148934e026f9SYork Sun PRINT_NXS(129, spd->mod_section.unbuffered.mod_thickness, 149034e026f9SYork Sun "mod_thickness (Unbuffered) Module Maximum Thickness"); 149134e026f9SYork Sun PRINT_NXS(130, spd->mod_section.unbuffered.ref_raw_card, 149234e026f9SYork Sun "ref_raw_card (Unbuffered) Reference Raw Card Used"); 149334e026f9SYork Sun PRINT_NXS(131, spd->mod_section.unbuffered.addr_mapping, 149434e026f9SYork Sun "addr_mapping (Unbuffered) Address mapping from Edge Connector to DRAM"); 149534e026f9SYork Sun PRINT_NNXXS(254, 255, spd->mod_section.unbuffered.crc[0], 149634e026f9SYork Sun spd->mod_section.unbuffered.crc[1], " Module CRC"); 149734e026f9SYork Sun break; 149834e026f9SYork Sun case 0x01: /* RDIMM */ 149934e026f9SYork Sun PRINT_NXS(128, spd->mod_section.registered.mod_height, 150034e026f9SYork Sun "mod_height (Registered) Module Nominal Height"); 150134e026f9SYork Sun PRINT_NXS(129, spd->mod_section.registered.mod_thickness, 150234e026f9SYork Sun "mod_thickness (Registered) Module Maximum Thickness"); 150334e026f9SYork Sun PRINT_NXS(130, spd->mod_section.registered.ref_raw_card, 150434e026f9SYork Sun "ref_raw_card (Registered) Reference Raw Card Used"); 150534e026f9SYork Sun PRINT_NXS(131, spd->mod_section.registered.modu_attr, 150634e026f9SYork Sun "modu_attr (Registered) DIMM Module Attributes"); 150734e026f9SYork Sun PRINT_NXS(132, spd->mod_section.registered.thermal, 150834e026f9SYork Sun "thermal (Registered) Thermal Heat Spreader Solution"); 150934e026f9SYork Sun PRINT_NXS(133, spd->mod_section.registered.reg_id_lo, 151034e026f9SYork Sun "reg_id_lo (Registered) Register Manufacturer ID Code, LSB"); 151134e026f9SYork Sun PRINT_NXS(134, spd->mod_section.registered.reg_id_hi, 151234e026f9SYork Sun "reg_id_hi (Registered) Register Manufacturer ID Code, MSB"); 151334e026f9SYork Sun PRINT_NXS(135, spd->mod_section.registered.reg_rev, 151434e026f9SYork Sun "reg_rev (Registered) Register Revision Number"); 151534e026f9SYork Sun PRINT_NXS(136, spd->mod_section.registered.reg_map, 151634e026f9SYork Sun "reg_map (Registered) Address mapping"); 151734e026f9SYork Sun PRINT_NNXXS(254, 255, spd->mod_section.registered.crc[0], 151834e026f9SYork Sun spd->mod_section.registered.crc[1], " Module CRC"); 151934e026f9SYork Sun break; 152034e026f9SYork Sun case 0x04: /* LRDIMM */ 152134e026f9SYork Sun PRINT_NXS(128, spd->mod_section.loadreduced.mod_height, 152234e026f9SYork Sun "mod_height (Loadreduced) Module Nominal Height"); 152334e026f9SYork Sun PRINT_NXS(129, spd->mod_section.loadreduced.mod_thickness, 152434e026f9SYork Sun "mod_thickness (Loadreduced) Module Maximum Thickness"); 152534e026f9SYork Sun PRINT_NXS(130, spd->mod_section.loadreduced.ref_raw_card, 152634e026f9SYork Sun "ref_raw_card (Loadreduced) Reference Raw Card Used"); 152734e026f9SYork Sun PRINT_NXS(131, spd->mod_section.loadreduced.modu_attr, 152834e026f9SYork Sun "modu_attr (Loadreduced) DIMM Module Attributes"); 152934e026f9SYork Sun PRINT_NXS(132, spd->mod_section.loadreduced.thermal, 153034e026f9SYork Sun "thermal (Loadreduced) Thermal Heat Spreader Solution"); 153134e026f9SYork Sun PRINT_NXS(133, spd->mod_section.loadreduced.reg_id_lo, 153234e026f9SYork Sun "reg_id_lo (Loadreduced) Register Manufacturer ID Code, LSB"); 153334e026f9SYork Sun PRINT_NXS(134, spd->mod_section.loadreduced.reg_id_hi, 153434e026f9SYork Sun "reg_id_hi (Loadreduced) Register Manufacturer ID Code, MSB"); 153534e026f9SYork Sun PRINT_NXS(135, spd->mod_section.loadreduced.reg_rev, 153634e026f9SYork Sun "reg_rev (Loadreduced) Register Revision Number"); 153734e026f9SYork Sun PRINT_NXS(136, spd->mod_section.loadreduced.reg_map, 153834e026f9SYork Sun "reg_map (Loadreduced) Address mapping"); 153934e026f9SYork Sun PRINT_NXS(137, spd->mod_section.loadreduced.reg_drv, 154034e026f9SYork Sun "reg_drv (Loadreduced) Reg output drive strength"); 154134e026f9SYork Sun PRINT_NXS(138, spd->mod_section.loadreduced.reg_drv_ck, 154234e026f9SYork Sun "reg_drv_ck (Loadreduced) Reg output drive strength for CK"); 154334e026f9SYork Sun PRINT_NXS(139, spd->mod_section.loadreduced.data_buf_rev, 154434e026f9SYork Sun "data_buf_rev (Loadreduced) Data Buffer Revision Numbe"); 154534e026f9SYork Sun PRINT_NXS(140, spd->mod_section.loadreduced.vrefqe_r0, 154634e026f9SYork Sun "vrefqe_r0 (Loadreduced) DRAM VrefDQ for Package Rank 0"); 154734e026f9SYork Sun PRINT_NXS(141, spd->mod_section.loadreduced.vrefqe_r1, 154834e026f9SYork Sun "vrefqe_r1 (Loadreduced) DRAM VrefDQ for Package Rank 1"); 154934e026f9SYork Sun PRINT_NXS(142, spd->mod_section.loadreduced.vrefqe_r2, 155034e026f9SYork Sun "vrefqe_r2 (Loadreduced) DRAM VrefDQ for Package Rank 2"); 155134e026f9SYork Sun PRINT_NXS(143, spd->mod_section.loadreduced.vrefqe_r3, 155234e026f9SYork Sun "vrefqe_r3 (Loadreduced) DRAM VrefDQ for Package Rank 3"); 155334e026f9SYork Sun PRINT_NXS(144, spd->mod_section.loadreduced.data_intf, 155434e026f9SYork Sun "data_intf (Loadreduced) Data Buffer VrefDQ for DRAM Interface"); 155534e026f9SYork Sun PRINT_NXS(145, spd->mod_section.loadreduced.data_drv_1866, 155634e026f9SYork Sun "data_drv_1866 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); 155734e026f9SYork Sun PRINT_NXS(146, spd->mod_section.loadreduced.data_drv_2400, 155834e026f9SYork Sun "data_drv_2400 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); 155934e026f9SYork Sun PRINT_NXS(147, spd->mod_section.loadreduced.data_drv_3200, 156034e026f9SYork Sun "data_drv_3200 (Loadreduced) Data Buffer MDQ Drive Strength and RTT"); 156134e026f9SYork Sun PRINT_NXS(148, spd->mod_section.loadreduced.dram_drv, 156234e026f9SYork Sun "dram_drv (Loadreduced) DRAM Drive Strength"); 156334e026f9SYork Sun PRINT_NXS(149, spd->mod_section.loadreduced.dram_odt_1866, 156434e026f9SYork Sun "dram_odt_1866 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); 156534e026f9SYork Sun PRINT_NXS(150, spd->mod_section.loadreduced.dram_odt_2400, 156634e026f9SYork Sun "dram_odt_2400 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); 156734e026f9SYork Sun PRINT_NXS(151, spd->mod_section.loadreduced.dram_odt_3200, 156834e026f9SYork Sun "dram_odt_3200 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)"); 156934e026f9SYork Sun PRINT_NXS(152, spd->mod_section.loadreduced.dram_odt_park_1866, 157034e026f9SYork Sun "dram_odt_park_1866 (Loadreduced) DRAM ODT (RTT_PARK)"); 157134e026f9SYork Sun PRINT_NXS(153, spd->mod_section.loadreduced.dram_odt_park_2400, 157234e026f9SYork Sun "dram_odt_park_2400 (Loadreduced) DRAM ODT (RTT_PARK)"); 157334e026f9SYork Sun PRINT_NXS(154, spd->mod_section.loadreduced.dram_odt_park_3200, 157434e026f9SYork Sun "dram_odt_park_3200 (Loadreduced) DRAM ODT (RTT_PARK)"); 157534e026f9SYork Sun PRINT_NNXXS(254, 255, spd->mod_section.loadreduced.crc[0], 157634e026f9SYork Sun spd->mod_section.loadreduced.crc[1], 157734e026f9SYork Sun " Module CRC"); 157834e026f9SYork Sun break; 157934e026f9SYork Sun default: 158034e026f9SYork Sun /* Module-specific Section, Unsupported Module Type */ 158134e026f9SYork Sun printf("%-3d-%3d: ", 128, 255); 158234e026f9SYork Sun 158334e026f9SYork Sun for (i = 128; i <= 255; i++) 1584353527d5SYork Sun printf("%02x", spd->mod_section.uc[i - 128]); 158534e026f9SYork Sun 158634e026f9SYork Sun break; 158734e026f9SYork Sun } 158834e026f9SYork Sun 158934e026f9SYork Sun /* Unique Module ID: Bytes 320-383 */ 159034e026f9SYork Sun PRINT_NXS(320, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106"); 159134e026f9SYork Sun PRINT_NXS(321, spd->mmid_msb, "Module MfgID Code MSB - JEP-106"); 159234e026f9SYork Sun PRINT_NXS(322, spd->mloc, "Mfg Location"); 159334e026f9SYork Sun PRINT_NNXXS(323, 324, spd->mdate[0], spd->mdate[1], "Mfg Date"); 159434e026f9SYork Sun 159534e026f9SYork Sun printf("%-3d-%3d: ", 325, 328); 159634e026f9SYork Sun 159734e026f9SYork Sun for (i = 325; i <= 328; i++) 159834e026f9SYork Sun printf("%02x ", spd->sernum[i - 325]); 159934e026f9SYork Sun printf(" Module Serial Number\n"); 160034e026f9SYork Sun 160134e026f9SYork Sun printf("%-3d-%3d: ", 329, 348); 160234e026f9SYork Sun for (i = 329; i <= 348; i++) 160334e026f9SYork Sun printf("%02x ", spd->mpart[i - 329]); 160434e026f9SYork Sun printf(" Mfg's Module Part Number\n"); 160534e026f9SYork Sun 160634e026f9SYork Sun PRINT_NXS(349, spd->mrev, "Module Revision code"); 160734e026f9SYork Sun PRINT_NXS(350, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106"); 160834e026f9SYork Sun PRINT_NXS(351, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106"); 160934e026f9SYork Sun PRINT_NXS(352, spd->stepping, "DRAM stepping"); 161034e026f9SYork Sun 161134e026f9SYork Sun printf("%-3d-%3d: ", 353, 381); 161234e026f9SYork Sun for (i = 353; i <= 381; i++) 161334e026f9SYork Sun printf("%02x ", spd->msd[i - 353]); 161434e026f9SYork Sun printf(" Mfg's Specific Data\n"); 161534e026f9SYork Sun } 161634e026f9SYork Sun #endif 161734e026f9SYork Sun 16185614e71bSYork Sun static inline void generic_spd_dump(const generic_spd_eeprom_t *spd) 16195614e71bSYork Sun { 16205614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1) 16215614e71bSYork Sun ddr1_spd_dump(spd); 16225614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2) 16235614e71bSYork Sun ddr2_spd_dump(spd); 16245614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3) 16255614e71bSYork Sun ddr3_spd_dump(spd); 162634e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR4) 162734e026f9SYork Sun ddr4_spd_dump(spd); 16285614e71bSYork Sun #endif 16295614e71bSYork Sun } 16305614e71bSYork Sun 16315614e71bSYork Sun static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, 16325614e71bSYork Sun unsigned int ctrl_mask, 16335614e71bSYork Sun unsigned int dimm_mask, 16345614e71bSYork Sun unsigned int do_mask) 16355614e71bSYork Sun { 16365614e71bSYork Sun unsigned int i, j, retval; 16375614e71bSYork Sun 16385614e71bSYork Sun /* STEP 1: DIMM SPD data */ 16395614e71bSYork Sun if (do_mask & STEP_GET_SPD) { 16405614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 16415614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 16425614e71bSYork Sun continue; 16435614e71bSYork Sun 16445614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 16455614e71bSYork Sun if (!(dimm_mask & (1 << j))) 16465614e71bSYork Sun continue; 16475614e71bSYork Sun 16485614e71bSYork Sun printf("SPD info: Controller=%u " 16495614e71bSYork Sun "DIMM=%u\n", i, j); 16505614e71bSYork Sun generic_spd_dump( 16515614e71bSYork Sun &(pinfo->spd_installed_dimms[i][j])); 16525614e71bSYork Sun printf("\n"); 16535614e71bSYork Sun } 16545614e71bSYork Sun printf("\n"); 16555614e71bSYork Sun } 16565614e71bSYork Sun printf("\n"); 16575614e71bSYork Sun } 16585614e71bSYork Sun 16595614e71bSYork Sun /* STEP 2: DIMM Parameters */ 16605614e71bSYork Sun if (do_mask & STEP_COMPUTE_DIMM_PARMS) { 16615614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 16625614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 16635614e71bSYork Sun continue; 16645614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 16655614e71bSYork Sun if (!(dimm_mask & (1 << j))) 16665614e71bSYork Sun continue; 16675614e71bSYork Sun printf("DIMM parameters: Controller=%u " 16685614e71bSYork Sun "DIMM=%u\n", i, j); 16695614e71bSYork Sun print_dimm_parameters( 16705614e71bSYork Sun &(pinfo->dimm_params[i][j])); 16715614e71bSYork Sun printf("\n"); 16725614e71bSYork Sun } 16735614e71bSYork Sun printf("\n"); 16745614e71bSYork Sun } 16755614e71bSYork Sun printf("\n"); 16765614e71bSYork Sun } 16775614e71bSYork Sun 16785614e71bSYork Sun /* STEP 3: Common Parameters */ 16795614e71bSYork Sun if (do_mask & STEP_COMPUTE_COMMON_PARMS) { 16805614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 16815614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 16825614e71bSYork Sun continue; 16835614e71bSYork Sun printf("\"lowest common\" DIMM parameters: " 16845614e71bSYork Sun "Controller=%u\n", i); 16855614e71bSYork Sun print_lowest_common_dimm_parameters( 16865614e71bSYork Sun &pinfo->common_timing_params[i]); 16875614e71bSYork Sun printf("\n"); 16885614e71bSYork Sun } 16895614e71bSYork Sun printf("\n"); 16905614e71bSYork Sun } 16915614e71bSYork Sun 16925614e71bSYork Sun /* STEP 4: User Configuration Options */ 16935614e71bSYork Sun if (do_mask & STEP_GATHER_OPTS) { 16945614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 16955614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 16965614e71bSYork Sun continue; 16975614e71bSYork Sun printf("User Config Options: Controller=%u\n", i); 16985614e71bSYork Sun print_memctl_options(&pinfo->memctl_opts[i]); 16995614e71bSYork Sun printf("\n"); 17005614e71bSYork Sun } 17015614e71bSYork Sun printf("\n"); 17025614e71bSYork Sun } 17035614e71bSYork Sun 17045614e71bSYork Sun /* STEP 5: Address assignment */ 17055614e71bSYork Sun if (do_mask & STEP_ASSIGN_ADDRESSES) { 17065614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 17075614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 17085614e71bSYork Sun continue; 17095614e71bSYork Sun for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { 17105614e71bSYork Sun printf("Address Assignment: Controller=%u " 17115614e71bSYork Sun "DIMM=%u\n", i, j); 17125614e71bSYork Sun printf("Don't have this functionality yet\n"); 17135614e71bSYork Sun } 17145614e71bSYork Sun printf("\n"); 17155614e71bSYork Sun } 17165614e71bSYork Sun printf("\n"); 17175614e71bSYork Sun } 17185614e71bSYork Sun 17195614e71bSYork Sun /* STEP 6: computed controller register values */ 17205614e71bSYork Sun if (do_mask & STEP_COMPUTE_REGS) { 17215614e71bSYork Sun for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { 17225614e71bSYork Sun if (!(ctrl_mask & (1 << i))) 17235614e71bSYork Sun continue; 17245614e71bSYork Sun printf("Computed Register Values: Controller=%u\n", i); 17255614e71bSYork Sun print_fsl_memctl_config_regs( 17265614e71bSYork Sun &pinfo->fsl_ddr_config_reg[i]); 17275614e71bSYork Sun retval = check_fsl_memctl_config_regs( 17285614e71bSYork Sun &pinfo->fsl_ddr_config_reg[i]); 17295614e71bSYork Sun if (retval) { 17305614e71bSYork Sun printf("check_fsl_memctl_config_regs " 17315614e71bSYork Sun "result = %u\n", retval); 17325614e71bSYork Sun } 17335614e71bSYork Sun printf("\n"); 17345614e71bSYork Sun } 17355614e71bSYork Sun printf("\n"); 17365614e71bSYork Sun } 17375614e71bSYork Sun } 17385614e71bSYork Sun 17395614e71bSYork Sun struct data_strings { 17405614e71bSYork Sun const char *data_name; 17415614e71bSYork Sun unsigned int step_mask; 17425614e71bSYork Sun unsigned int dimm_number_required; 17435614e71bSYork Sun }; 17445614e71bSYork Sun 17455614e71bSYork Sun #define DATA_OPTIONS(name, step, dimm) {#name, step, dimm} 17465614e71bSYork Sun 17475614e71bSYork Sun static unsigned int fsl_ddr_parse_interactive_cmd( 17485614e71bSYork Sun char **argv, 17495614e71bSYork Sun int argc, 17505614e71bSYork Sun unsigned int *pstep_mask, 17515614e71bSYork Sun unsigned int *pctlr_mask, 17525614e71bSYork Sun unsigned int *pdimm_mask, 17535614e71bSYork Sun unsigned int *pdimm_number_required 17545614e71bSYork Sun ) { 17555614e71bSYork Sun 17565614e71bSYork Sun static const struct data_strings options[] = { 17575614e71bSYork Sun DATA_OPTIONS(spd, STEP_GET_SPD, 1), 17585614e71bSYork Sun DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1), 17595614e71bSYork Sun DATA_OPTIONS(commonparms, STEP_COMPUTE_COMMON_PARMS, 0), 17605614e71bSYork Sun DATA_OPTIONS(opts, STEP_GATHER_OPTS, 0), 17615614e71bSYork Sun DATA_OPTIONS(addresses, STEP_ASSIGN_ADDRESSES, 0), 17625614e71bSYork Sun DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0), 17635614e71bSYork Sun }; 17645614e71bSYork Sun static const unsigned int n_opts = ARRAY_SIZE(options); 17655614e71bSYork Sun 17665614e71bSYork Sun unsigned int i, j; 17675614e71bSYork Sun unsigned int error = 0; 17685614e71bSYork Sun 17695614e71bSYork Sun for (i = 1; i < argc; i++) { 17705614e71bSYork Sun unsigned int matched = 0; 17715614e71bSYork Sun 17725614e71bSYork Sun for (j = 0; j < n_opts; j++) { 17735614e71bSYork Sun if (strcmp(options[j].data_name, argv[i]) != 0) 17745614e71bSYork Sun continue; 17755614e71bSYork Sun *pstep_mask |= options[j].step_mask; 17765614e71bSYork Sun *pdimm_number_required = 17775614e71bSYork Sun options[j].dimm_number_required; 17785614e71bSYork Sun matched = 1; 17795614e71bSYork Sun break; 17805614e71bSYork Sun } 17815614e71bSYork Sun 17825614e71bSYork Sun if (matched) 17835614e71bSYork Sun continue; 17845614e71bSYork Sun 17855614e71bSYork Sun if (argv[i][0] == 'c') { 17865614e71bSYork Sun char c = argv[i][1]; 17875614e71bSYork Sun if (isdigit(c)) 17885614e71bSYork Sun *pctlr_mask |= 1 << (c - '0'); 17895614e71bSYork Sun continue; 17905614e71bSYork Sun } 17915614e71bSYork Sun 17925614e71bSYork Sun if (argv[i][0] == 'd') { 17935614e71bSYork Sun char c = argv[i][1]; 17945614e71bSYork Sun if (isdigit(c)) 17955614e71bSYork Sun *pdimm_mask |= 1 << (c - '0'); 17965614e71bSYork Sun continue; 17975614e71bSYork Sun } 17985614e71bSYork Sun 17995614e71bSYork Sun printf("unknown arg %s\n", argv[i]); 18005614e71bSYork Sun *pstep_mask = 0; 18015614e71bSYork Sun error = 1; 18025614e71bSYork Sun break; 18035614e71bSYork Sun } 18045614e71bSYork Sun 18055614e71bSYork Sun return error; 18065614e71bSYork Sun } 18075614e71bSYork Sun 18085614e71bSYork Sun int fsl_ddr_interactive_env_var_exists(void) 18095614e71bSYork Sun { 18105614e71bSYork Sun char buffer[CONFIG_SYS_CBSIZE]; 18115614e71bSYork Sun 18125614e71bSYork Sun if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0) 18135614e71bSYork Sun return 1; 18145614e71bSYork Sun 18155614e71bSYork Sun return 0; 18165614e71bSYork Sun } 18175614e71bSYork Sun 18185614e71bSYork Sun unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set) 18195614e71bSYork Sun { 18205614e71bSYork Sun unsigned long long ddrsize; 18215614e71bSYork Sun const char *prompt = "FSL DDR>"; 18225614e71bSYork Sun char buffer[CONFIG_SYS_CBSIZE]; 18235614e71bSYork Sun char buffer2[CONFIG_SYS_CBSIZE]; 18245614e71bSYork Sun char *p = NULL; 18255614e71bSYork Sun char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */ 18265614e71bSYork Sun int argc; 18275614e71bSYork Sun unsigned int next_step = STEP_GET_SPD; 18285614e71bSYork Sun const char *usage = { 18295614e71bSYork Sun "commands:\n" 18305614e71bSYork Sun "print print SPD and intermediate computed data\n" 18315614e71bSYork Sun "reset reboot machine\n" 18325614e71bSYork Sun "recompute reload SPD and options to default and recompute regs\n" 18335614e71bSYork Sun "edit modify spd, parameter, or option\n" 18345614e71bSYork Sun "compute recompute registers from current next_step to end\n" 18355614e71bSYork Sun "copy copy parameters\n" 18365614e71bSYork Sun "next_step shows current next_step\n" 18375614e71bSYork Sun "help this message\n" 18385614e71bSYork Sun "go program the memory controller and continue with u-boot\n" 18395614e71bSYork Sun }; 18405614e71bSYork Sun 18415614e71bSYork Sun if (var_is_set) { 18425614e71bSYork Sun if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) { 18435614e71bSYork Sun p = buffer2; 18445614e71bSYork Sun } else { 18455614e71bSYork Sun var_is_set = 0; 18465614e71bSYork Sun } 18475614e71bSYork Sun } 18485614e71bSYork Sun 18495614e71bSYork Sun /* 18505614e71bSYork Sun * The strategy for next_step is that it points to the next 18515614e71bSYork Sun * step in the computation process that needs to be done. 18525614e71bSYork Sun */ 18535614e71bSYork Sun while (1) { 18545614e71bSYork Sun if (var_is_set) { 18555614e71bSYork Sun char *pend = strchr(p, ';'); 18565614e71bSYork Sun if (pend) { 18575614e71bSYork Sun /* found command separator, copy sub-command */ 18585614e71bSYork Sun *pend = '\0'; 18595614e71bSYork Sun strcpy(buffer, p); 18605614e71bSYork Sun p = pend + 1; 18615614e71bSYork Sun } else { 18625614e71bSYork Sun /* separator not found, copy whole string */ 18635614e71bSYork Sun strcpy(buffer, p); 18645614e71bSYork Sun p = NULL; 18655614e71bSYork Sun var_is_set = 0; 18665614e71bSYork Sun } 18675614e71bSYork Sun } else { 18685614e71bSYork Sun /* 18695614e71bSYork Sun * No need to worry for buffer overflow here in 1870e1bf824dSSimon Glass * this function; cli_readline() maxes out at 1871e1bf824dSSimon Glass * CFG_CBSIZE 18725614e71bSYork Sun */ 1873e1bf824dSSimon Glass cli_readline_into_buffer(prompt, buffer, 0); 18745614e71bSYork Sun } 1875e1bf824dSSimon Glass argc = cli_simple_parse_line(buffer, argv); 18765614e71bSYork Sun if (argc == 0) 18775614e71bSYork Sun continue; 18785614e71bSYork Sun 18795614e71bSYork Sun 18805614e71bSYork Sun if (strcmp(argv[0], "help") == 0) { 18815614e71bSYork Sun puts(usage); 18825614e71bSYork Sun continue; 18835614e71bSYork Sun } 18845614e71bSYork Sun 18855614e71bSYork Sun if (strcmp(argv[0], "next_step") == 0) { 18865614e71bSYork Sun printf("next_step = 0x%02X (%s)\n", 18875614e71bSYork Sun next_step, 18885614e71bSYork Sun step_to_string(next_step)); 18895614e71bSYork Sun continue; 18905614e71bSYork Sun } 18915614e71bSYork Sun 18925614e71bSYork Sun if (strcmp(argv[0], "copy") == 0) { 18935614e71bSYork Sun unsigned int error = 0; 18945614e71bSYork Sun unsigned int step_mask = 0; 18955614e71bSYork Sun unsigned int src_ctlr_mask = 0; 18965614e71bSYork Sun unsigned int src_dimm_mask = 0; 18975614e71bSYork Sun unsigned int dimm_number_required = 0; 18985614e71bSYork Sun unsigned int src_ctlr_num = 0; 18995614e71bSYork Sun unsigned int src_dimm_num = 0; 19005614e71bSYork Sun unsigned int dst_ctlr_num = -1; 19015614e71bSYork Sun unsigned int dst_dimm_num = -1; 19025614e71bSYork Sun unsigned int i, num_dest_parms; 19035614e71bSYork Sun 19045614e71bSYork Sun if (argc == 1) { 19055614e71bSYork Sun printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n"); 19065614e71bSYork Sun continue; 19075614e71bSYork Sun } 19085614e71bSYork Sun 19095614e71bSYork Sun error = fsl_ddr_parse_interactive_cmd( 19105614e71bSYork Sun argv, argc, 19115614e71bSYork Sun &step_mask, 19125614e71bSYork Sun &src_ctlr_mask, 19135614e71bSYork Sun &src_dimm_mask, 19145614e71bSYork Sun &dimm_number_required 19155614e71bSYork Sun ); 19165614e71bSYork Sun 19175614e71bSYork Sun /* XXX: only dimm_number_required and step_mask will 19185614e71bSYork Sun be used by this function. Parse the controller and 19195614e71bSYork Sun DIMM number separately because it is easier. */ 19205614e71bSYork Sun 19215614e71bSYork Sun if (error) 19225614e71bSYork Sun continue; 19235614e71bSYork Sun 19245614e71bSYork Sun /* parse source destination controller / DIMM */ 19255614e71bSYork Sun 19265614e71bSYork Sun num_dest_parms = dimm_number_required ? 2 : 1; 19275614e71bSYork Sun 19285614e71bSYork Sun for (i = 0; i < argc; i++) { 19295614e71bSYork Sun if (argv[i][0] == 'c') { 19305614e71bSYork Sun char c = argv[i][1]; 19315614e71bSYork Sun if (isdigit(c)) { 19325614e71bSYork Sun src_ctlr_num = (c - '0'); 19335614e71bSYork Sun break; 19345614e71bSYork Sun } 19355614e71bSYork Sun } 19365614e71bSYork Sun } 19375614e71bSYork Sun 19385614e71bSYork Sun for (i = 0; i < argc; i++) { 19395614e71bSYork Sun if (argv[i][0] == 'd') { 19405614e71bSYork Sun char c = argv[i][1]; 19415614e71bSYork Sun if (isdigit(c)) { 19425614e71bSYork Sun src_dimm_num = (c - '0'); 19435614e71bSYork Sun break; 19445614e71bSYork Sun } 19455614e71bSYork Sun } 19465614e71bSYork Sun } 19475614e71bSYork Sun 19485614e71bSYork Sun /* parse destination controller / DIMM */ 19495614e71bSYork Sun 19505614e71bSYork Sun for (i = argc - 1; i >= argc - num_dest_parms; i--) { 19515614e71bSYork Sun if (argv[i][0] == 'c') { 19525614e71bSYork Sun char c = argv[i][1]; 19535614e71bSYork Sun if (isdigit(c)) { 19545614e71bSYork Sun dst_ctlr_num = (c - '0'); 19555614e71bSYork Sun break; 19565614e71bSYork Sun } 19575614e71bSYork Sun } 19585614e71bSYork Sun } 19595614e71bSYork Sun 19605614e71bSYork Sun for (i = argc - 1; i >= argc - num_dest_parms; i--) { 19615614e71bSYork Sun if (argv[i][0] == 'd') { 19625614e71bSYork Sun char c = argv[i][1]; 19635614e71bSYork Sun if (isdigit(c)) { 19645614e71bSYork Sun dst_dimm_num = (c - '0'); 19655614e71bSYork Sun break; 19665614e71bSYork Sun } 19675614e71bSYork Sun } 19685614e71bSYork Sun } 19695614e71bSYork Sun 19705614e71bSYork Sun /* TODO: validate inputs */ 19715614e71bSYork Sun 19725614e71bSYork Sun debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n", 19735614e71bSYork Sun src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask); 19745614e71bSYork Sun 19755614e71bSYork Sun 19765614e71bSYork Sun switch (step_mask) { 19775614e71bSYork Sun 19785614e71bSYork Sun case STEP_GET_SPD: 19795614e71bSYork Sun memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]), 19805614e71bSYork Sun &(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]), 19815614e71bSYork Sun sizeof(pinfo->spd_installed_dimms[0][0])); 19825614e71bSYork Sun break; 19835614e71bSYork Sun 19845614e71bSYork Sun case STEP_COMPUTE_DIMM_PARMS: 19855614e71bSYork Sun memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]), 19865614e71bSYork Sun &(pinfo->dimm_params[src_ctlr_num][src_dimm_num]), 19875614e71bSYork Sun sizeof(pinfo->dimm_params[0][0])); 19885614e71bSYork Sun break; 19895614e71bSYork Sun 19905614e71bSYork Sun case STEP_COMPUTE_COMMON_PARMS: 19915614e71bSYork Sun memcpy(&(pinfo->common_timing_params[dst_ctlr_num]), 19925614e71bSYork Sun &(pinfo->common_timing_params[src_ctlr_num]), 19935614e71bSYork Sun sizeof(pinfo->common_timing_params[0])); 19945614e71bSYork Sun break; 19955614e71bSYork Sun 19965614e71bSYork Sun case STEP_GATHER_OPTS: 19975614e71bSYork Sun memcpy(&(pinfo->memctl_opts[dst_ctlr_num]), 19985614e71bSYork Sun &(pinfo->memctl_opts[src_ctlr_num]), 19995614e71bSYork Sun sizeof(pinfo->memctl_opts[0])); 20005614e71bSYork Sun break; 20015614e71bSYork Sun 20025614e71bSYork Sun /* someday be able to have addresses to copy addresses... */ 20035614e71bSYork Sun 20045614e71bSYork Sun case STEP_COMPUTE_REGS: 20055614e71bSYork Sun memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]), 20065614e71bSYork Sun &(pinfo->fsl_ddr_config_reg[src_ctlr_num]), 20075614e71bSYork Sun sizeof(pinfo->memctl_opts[0])); 20085614e71bSYork Sun break; 20095614e71bSYork Sun 20105614e71bSYork Sun default: 20115614e71bSYork Sun printf("unexpected step_mask value\n"); 20125614e71bSYork Sun } 20135614e71bSYork Sun 20145614e71bSYork Sun continue; 20155614e71bSYork Sun 20165614e71bSYork Sun } 20175614e71bSYork Sun 20185614e71bSYork Sun if (strcmp(argv[0], "edit") == 0) { 20195614e71bSYork Sun unsigned int error = 0; 20205614e71bSYork Sun unsigned int step_mask = 0; 20215614e71bSYork Sun unsigned int ctlr_mask = 0; 20225614e71bSYork Sun unsigned int dimm_mask = 0; 20235614e71bSYork Sun char *p_element = NULL; 20245614e71bSYork Sun char *p_value = NULL; 20255614e71bSYork Sun unsigned int dimm_number_required = 0; 20265614e71bSYork Sun unsigned int ctrl_num; 20275614e71bSYork Sun unsigned int dimm_num; 20285614e71bSYork Sun 20295614e71bSYork Sun if (argc == 1) { 20305614e71bSYork Sun /* Only the element and value must be last */ 20315614e71bSYork Sun printf("edit <c#> <d#> " 20325614e71bSYork Sun "<spd|dimmparms|commonparms|opts|" 20335614e71bSYork Sun "addresses|regs> <element> <value>\n"); 20345614e71bSYork Sun printf("for spd, specify byte number for " 20355614e71bSYork Sun "element\n"); 20365614e71bSYork Sun continue; 20375614e71bSYork Sun } 20385614e71bSYork Sun 20395614e71bSYork Sun error = fsl_ddr_parse_interactive_cmd( 20405614e71bSYork Sun argv, argc - 2, 20415614e71bSYork Sun &step_mask, 20425614e71bSYork Sun &ctlr_mask, 20435614e71bSYork Sun &dimm_mask, 20445614e71bSYork Sun &dimm_number_required 20455614e71bSYork Sun ); 20465614e71bSYork Sun 20475614e71bSYork Sun if (error) 20485614e71bSYork Sun continue; 20495614e71bSYork Sun 20505614e71bSYork Sun 20515614e71bSYork Sun /* Check arguments */ 20525614e71bSYork Sun 20535614e71bSYork Sun /* ERROR: If no steps were found */ 20545614e71bSYork Sun if (step_mask == 0) { 20555614e71bSYork Sun printf("Error: No valid steps were specified " 20565614e71bSYork Sun "in argument.\n"); 20575614e71bSYork Sun continue; 20585614e71bSYork Sun } 20595614e71bSYork Sun 20605614e71bSYork Sun /* ERROR: If multiple steps were found */ 20615614e71bSYork Sun if (step_mask & (step_mask - 1)) { 20625614e71bSYork Sun printf("Error: Multiple steps specified in " 20635614e71bSYork Sun "argument.\n"); 20645614e71bSYork Sun continue; 20655614e71bSYork Sun } 20665614e71bSYork Sun 20675614e71bSYork Sun /* ERROR: Controller not specified */ 20685614e71bSYork Sun if (ctlr_mask == 0) { 20695614e71bSYork Sun printf("Error: controller number not " 20705614e71bSYork Sun "specified or no element and " 20715614e71bSYork Sun "value specified\n"); 20725614e71bSYork Sun continue; 20735614e71bSYork Sun } 20745614e71bSYork Sun 20755614e71bSYork Sun if (ctlr_mask & (ctlr_mask - 1)) { 20765614e71bSYork Sun printf("Error: multiple controllers " 20775614e71bSYork Sun "specified, %X\n", ctlr_mask); 20785614e71bSYork Sun continue; 20795614e71bSYork Sun } 20805614e71bSYork Sun 20815614e71bSYork Sun /* ERROR: DIMM number not specified */ 20825614e71bSYork Sun if (dimm_number_required && dimm_mask == 0) { 20835614e71bSYork Sun printf("Error: DIMM number number not " 20845614e71bSYork Sun "specified or no element and " 20855614e71bSYork Sun "value specified\n"); 20865614e71bSYork Sun continue; 20875614e71bSYork Sun } 20885614e71bSYork Sun 20895614e71bSYork Sun if (dimm_mask & (dimm_mask - 1)) { 20905614e71bSYork Sun printf("Error: multipled DIMMs specified\n"); 20915614e71bSYork Sun continue; 20925614e71bSYork Sun } 20935614e71bSYork Sun 20945614e71bSYork Sun p_element = argv[argc - 2]; 20955614e71bSYork Sun p_value = argv[argc - 1]; 20965614e71bSYork Sun 20975614e71bSYork Sun ctrl_num = __ilog2(ctlr_mask); 20985614e71bSYork Sun dimm_num = __ilog2(dimm_mask); 20995614e71bSYork Sun 21005614e71bSYork Sun switch (step_mask) { 21015614e71bSYork Sun case STEP_GET_SPD: 21025614e71bSYork Sun { 21035614e71bSYork Sun unsigned int element_num; 21045614e71bSYork Sun unsigned int value; 21055614e71bSYork Sun 21065614e71bSYork Sun element_num = simple_strtoul(p_element, 21075614e71bSYork Sun NULL, 0); 21085614e71bSYork Sun value = simple_strtoul(p_value, 21095614e71bSYork Sun NULL, 0); 21105614e71bSYork Sun fsl_ddr_spd_edit(pinfo, 21115614e71bSYork Sun ctrl_num, 21125614e71bSYork Sun dimm_num, 21135614e71bSYork Sun element_num, 21145614e71bSYork Sun value); 21155614e71bSYork Sun next_step = STEP_COMPUTE_DIMM_PARMS; 21165614e71bSYork Sun } 21175614e71bSYork Sun break; 21185614e71bSYork Sun 21195614e71bSYork Sun case STEP_COMPUTE_DIMM_PARMS: 21205614e71bSYork Sun fsl_ddr_dimm_parameters_edit( 21215614e71bSYork Sun pinfo, ctrl_num, dimm_num, 21225614e71bSYork Sun p_element, p_value); 21235614e71bSYork Sun next_step = STEP_COMPUTE_COMMON_PARMS; 21245614e71bSYork Sun break; 21255614e71bSYork Sun 21265614e71bSYork Sun case STEP_COMPUTE_COMMON_PARMS: 21275614e71bSYork Sun lowest_common_dimm_parameters_edit(pinfo, 21285614e71bSYork Sun ctrl_num, p_element, p_value); 21295614e71bSYork Sun next_step = STEP_GATHER_OPTS; 21305614e71bSYork Sun break; 21315614e71bSYork Sun 21325614e71bSYork Sun case STEP_GATHER_OPTS: 21335614e71bSYork Sun fsl_ddr_options_edit(pinfo, ctrl_num, 21345614e71bSYork Sun p_element, p_value); 21355614e71bSYork Sun next_step = STEP_ASSIGN_ADDRESSES; 21365614e71bSYork Sun break; 21375614e71bSYork Sun 21385614e71bSYork Sun case STEP_ASSIGN_ADDRESSES: 21395614e71bSYork Sun printf("editing of address assignment " 21405614e71bSYork Sun "not yet implemented\n"); 21415614e71bSYork Sun break; 21425614e71bSYork Sun 21435614e71bSYork Sun case STEP_COMPUTE_REGS: 21445614e71bSYork Sun { 21455614e71bSYork Sun fsl_ddr_regs_edit(pinfo, 21465614e71bSYork Sun ctrl_num, 21475614e71bSYork Sun p_element, 21485614e71bSYork Sun p_value); 21495614e71bSYork Sun next_step = STEP_PROGRAM_REGS; 21505614e71bSYork Sun } 21515614e71bSYork Sun break; 21525614e71bSYork Sun 21535614e71bSYork Sun default: 21545614e71bSYork Sun printf("programming error\n"); 21555614e71bSYork Sun while (1) 21565614e71bSYork Sun ; 21575614e71bSYork Sun break; 21585614e71bSYork Sun } 21595614e71bSYork Sun continue; 21605614e71bSYork Sun } 21615614e71bSYork Sun 21625614e71bSYork Sun if (strcmp(argv[0], "reset") == 0) { 21635614e71bSYork Sun /* 21645614e71bSYork Sun * Reboot machine. 21655614e71bSYork Sun * Args don't seem to matter because this 21665614e71bSYork Sun * doesn't return 21675614e71bSYork Sun */ 21685614e71bSYork Sun do_reset(NULL, 0, 0, NULL); 21695614e71bSYork Sun printf("Reset didn't work\n"); 21705614e71bSYork Sun } 21715614e71bSYork Sun 21725614e71bSYork Sun if (strcmp(argv[0], "recompute") == 0) { 21735614e71bSYork Sun /* 21745614e71bSYork Sun * Recalculate everything, starting with 21755614e71bSYork Sun * loading SPD EEPROM from DIMMs 21765614e71bSYork Sun */ 21775614e71bSYork Sun next_step = STEP_GET_SPD; 21785614e71bSYork Sun ddrsize = fsl_ddr_compute(pinfo, next_step, 0); 21795614e71bSYork Sun continue; 21805614e71bSYork Sun } 21815614e71bSYork Sun 21825614e71bSYork Sun if (strcmp(argv[0], "compute") == 0) { 21835614e71bSYork Sun /* 21845614e71bSYork Sun * Compute rest of steps starting at 21855614e71bSYork Sun * the current next_step/ 21865614e71bSYork Sun */ 21875614e71bSYork Sun ddrsize = fsl_ddr_compute(pinfo, next_step, 0); 21885614e71bSYork Sun continue; 21895614e71bSYork Sun } 21905614e71bSYork Sun 21915614e71bSYork Sun if (strcmp(argv[0], "print") == 0) { 21925614e71bSYork Sun unsigned int error = 0; 21935614e71bSYork Sun unsigned int step_mask = 0; 21945614e71bSYork Sun unsigned int ctlr_mask = 0; 21955614e71bSYork Sun unsigned int dimm_mask = 0; 21965614e71bSYork Sun unsigned int dimm_number_required = 0; 21975614e71bSYork Sun 21985614e71bSYork Sun if (argc == 1) { 21995614e71bSYork Sun printf("print [c<n>] [d<n>] [spd] [dimmparms] " 22005614e71bSYork Sun "[commonparms] [opts] [addresses] [regs]\n"); 22015614e71bSYork Sun continue; 22025614e71bSYork Sun } 22035614e71bSYork Sun 22045614e71bSYork Sun error = fsl_ddr_parse_interactive_cmd( 22055614e71bSYork Sun argv, argc, 22065614e71bSYork Sun &step_mask, 22075614e71bSYork Sun &ctlr_mask, 22085614e71bSYork Sun &dimm_mask, 22095614e71bSYork Sun &dimm_number_required 22105614e71bSYork Sun ); 22115614e71bSYork Sun 22125614e71bSYork Sun if (error) 22135614e71bSYork Sun continue; 22145614e71bSYork Sun 22155614e71bSYork Sun /* If no particular controller was found, print all */ 22165614e71bSYork Sun if (ctlr_mask == 0) 22175614e71bSYork Sun ctlr_mask = 0xFF; 22185614e71bSYork Sun 22195614e71bSYork Sun /* If no particular dimm was found, print all dimms. */ 22205614e71bSYork Sun if (dimm_mask == 0) 22215614e71bSYork Sun dimm_mask = 0xFF; 22225614e71bSYork Sun 22235614e71bSYork Sun /* If no steps were found, print all steps. */ 22245614e71bSYork Sun if (step_mask == 0) 22255614e71bSYork Sun step_mask = STEP_ALL; 22265614e71bSYork Sun 22275614e71bSYork Sun fsl_ddr_printinfo(pinfo, ctlr_mask, 22285614e71bSYork Sun dimm_mask, step_mask); 22295614e71bSYork Sun continue; 22305614e71bSYork Sun } 22315614e71bSYork Sun 22325614e71bSYork Sun if (strcmp(argv[0], "go") == 0) { 22335614e71bSYork Sun if (next_step) 22345614e71bSYork Sun ddrsize = fsl_ddr_compute(pinfo, next_step, 0); 22355614e71bSYork Sun break; 22365614e71bSYork Sun } 22375614e71bSYork Sun 22385614e71bSYork Sun printf("unknown command %s\n", argv[0]); 22395614e71bSYork Sun } 22405614e71bSYork Sun 22415614e71bSYork Sun debug("end of memory = %llu\n", (u64)ddrsize); 22425614e71bSYork Sun 22435614e71bSYork Sun return ddrsize; 22445614e71bSYork Sun } 2245