xref: /rk3399_rockchip-uboot/drivers/ddr/fsl/interactive.c (revision 6b95be228024c7d15b9164b59187ef02333bb0c8)
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}
20866869f95SYork Sun #define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \
20966869f95SYork Sun 	sizeof((dimm_params_t *)0)->x, 1}
2105614e71bSYork Sun 
2115614e71bSYork Sun static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
2125614e71bSYork Sun 				   unsigned int ctrl_num,
2135614e71bSYork Sun 				   unsigned int dimm_num,
2145614e71bSYork Sun 				   const char *optname_str,
2155614e71bSYork Sun 				   const char *value_str)
2165614e71bSYork Sun {
2175614e71bSYork Sun 	dimm_params_t *p = &(pinfo->dimm_params[ctrl_num][dimm_num]);
2185614e71bSYork Sun 
2195614e71bSYork Sun 	static const struct options_string options[] = {
2205614e71bSYork Sun 		DIMM_PARM(n_ranks),
2215614e71bSYork Sun 		DIMM_PARM(data_width),
2225614e71bSYork Sun 		DIMM_PARM(primary_sdram_width),
2235614e71bSYork Sun 		DIMM_PARM(ec_sdram_width),
2245614e71bSYork Sun 		DIMM_PARM(registered_dimm),
22566869f95SYork Sun 		DIMM_PARM(mirrored_dimm),
2265614e71bSYork Sun 		DIMM_PARM(device_width),
2275614e71bSYork Sun 
2285614e71bSYork Sun 		DIMM_PARM(n_row_addr),
2295614e71bSYork Sun 		DIMM_PARM(n_col_addr),
2305614e71bSYork Sun 		DIMM_PARM(edc_config),
23134e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
23234e026f9SYork Sun 		DIMM_PARM(bank_addr_bits),
23334e026f9SYork Sun 		DIMM_PARM(bank_group_bits),
23434e026f9SYork Sun #else
2355614e71bSYork Sun 		DIMM_PARM(n_banks_per_sdram_device),
23634e026f9SYork Sun #endif
2375614e71bSYork Sun 		DIMM_PARM(burst_lengths_bitmask),
2385614e71bSYork Sun 		DIMM_PARM(row_density),
2395614e71bSYork Sun 
2405614e71bSYork Sun 		DIMM_PARM(tckmin_x_ps),
2415614e71bSYork Sun 		DIMM_PARM(tckmin_x_minus_1_ps),
2425614e71bSYork Sun 		DIMM_PARM(tckmin_x_minus_2_ps),
2435614e71bSYork Sun 		DIMM_PARM(tckmax_ps),
2445614e71bSYork Sun 
2455614e71bSYork Sun 		DIMM_PARM(caslat_x),
2465614e71bSYork Sun 		DIMM_PARM(caslat_x_minus_1),
2475614e71bSYork Sun 		DIMM_PARM(caslat_x_minus_2),
2485614e71bSYork Sun 
2495614e71bSYork Sun 		DIMM_PARM(caslat_lowest_derated),
2505614e71bSYork Sun 
2515614e71bSYork Sun 		DIMM_PARM(trcd_ps),
2525614e71bSYork Sun 		DIMM_PARM(trp_ps),
2535614e71bSYork Sun 		DIMM_PARM(tras_ps),
25434e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
25534e026f9SYork Sun 		DIMM_PARM(trfc1_ps),
25634e026f9SYork Sun 		DIMM_PARM(trfc2_ps),
25734e026f9SYork Sun 		DIMM_PARM(trfc4_ps),
25834e026f9SYork Sun 		DIMM_PARM(trrds_ps),
25934e026f9SYork Sun 		DIMM_PARM(trrdl_ps),
26034e026f9SYork Sun 		DIMM_PARM(tccdl_ps),
26134e026f9SYork Sun #else
2625614e71bSYork Sun 		DIMM_PARM(twr_ps),
2635614e71bSYork Sun 		DIMM_PARM(twtr_ps),
2645614e71bSYork Sun 		DIMM_PARM(trfc_ps),
2655614e71bSYork Sun 		DIMM_PARM(trrd_ps),
26634e026f9SYork Sun 		DIMM_PARM(trtp_ps),
26734e026f9SYork Sun #endif
2685614e71bSYork Sun 		DIMM_PARM(trc_ps),
2695614e71bSYork Sun 		DIMM_PARM(refresh_rate_ps),
27034e026f9SYork Sun 		DIMM_PARM(extended_op_srt),
2715614e71bSYork Sun 
27234e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
2735614e71bSYork Sun 		DIMM_PARM(tis_ps),
2745614e71bSYork Sun 		DIMM_PARM(tih_ps),
2755614e71bSYork Sun 		DIMM_PARM(tds_ps),
2765614e71bSYork Sun 		DIMM_PARM(tdh_ps),
2775614e71bSYork Sun 		DIMM_PARM(tdqsq_max_ps),
2785614e71bSYork Sun 		DIMM_PARM(tqhs_ps),
27934e026f9SYork Sun #endif
28066869f95SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
28166869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[0]),
28266869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[1]),
28366869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[2]),
28466869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[3]),
28566869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[4]),
28666869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[5]),
28766869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[6]),
28866869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[7]),
28966869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[8]),
29066869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[9]),
29166869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[10]),
29266869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[11]),
29366869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[12]),
29466869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[13]),
29566869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[14]),
29666869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[15]),
29766869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[16]),
29866869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[17]),
29966869f95SYork Sun 		DIMM_PARM(dq_mapping_ors),
30066869f95SYork Sun #endif
3015614e71bSYork Sun 		DIMM_PARM(rank_density),
3025614e71bSYork Sun 		DIMM_PARM(capacity),
3035614e71bSYork Sun 		DIMM_PARM(base_address),
3045614e71bSYork Sun 	};
3055614e71bSYork Sun 
3065614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
3075614e71bSYork Sun 
3085614e71bSYork Sun 	if (handle_option_table(options, n_opts, p, optname_str, value_str))
3095614e71bSYork Sun 		return;
3105614e71bSYork Sun 
3115614e71bSYork Sun 	printf("couldn't find option string %s\n", optname_str);
3125614e71bSYork Sun }
3135614e71bSYork Sun 
3145614e71bSYork Sun static void print_dimm_parameters(const dimm_params_t *pdimm)
3155614e71bSYork Sun {
3165614e71bSYork Sun 	static const struct options_string options[] = {
3175614e71bSYork Sun 		DIMM_PARM(n_ranks),
3185614e71bSYork Sun 		DIMM_PARM(data_width),
3195614e71bSYork Sun 		DIMM_PARM(primary_sdram_width),
3205614e71bSYork Sun 		DIMM_PARM(ec_sdram_width),
3215614e71bSYork Sun 		DIMM_PARM(registered_dimm),
32266869f95SYork Sun 		DIMM_PARM(mirrored_dimm),
3235614e71bSYork Sun 		DIMM_PARM(device_width),
3245614e71bSYork Sun 
3255614e71bSYork Sun 		DIMM_PARM(n_row_addr),
3265614e71bSYork Sun 		DIMM_PARM(n_col_addr),
3275614e71bSYork Sun 		DIMM_PARM(edc_config),
32834e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
32934e026f9SYork Sun 		DIMM_PARM(bank_addr_bits),
33034e026f9SYork Sun 		DIMM_PARM(bank_group_bits),
33134e026f9SYork Sun #else
3325614e71bSYork Sun 		DIMM_PARM(n_banks_per_sdram_device),
33334e026f9SYork Sun #endif
3345614e71bSYork Sun 
3355614e71bSYork Sun 		DIMM_PARM(tckmin_x_ps),
3365614e71bSYork Sun 		DIMM_PARM(tckmin_x_minus_1_ps),
3375614e71bSYork Sun 		DIMM_PARM(tckmin_x_minus_2_ps),
3385614e71bSYork Sun 		DIMM_PARM(tckmax_ps),
3395614e71bSYork Sun 
3405614e71bSYork Sun 		DIMM_PARM(caslat_x),
34166869f95SYork Sun 		DIMM_PARM_HEX(caslat_x),
3425614e71bSYork Sun 		DIMM_PARM(taa_ps),
3435614e71bSYork Sun 		DIMM_PARM(caslat_x_minus_1),
3445614e71bSYork Sun 		DIMM_PARM(caslat_x_minus_2),
3455614e71bSYork Sun 		DIMM_PARM(caslat_lowest_derated),
3465614e71bSYork Sun 
3475614e71bSYork Sun 		DIMM_PARM(trcd_ps),
3485614e71bSYork Sun 		DIMM_PARM(trp_ps),
3495614e71bSYork Sun 		DIMM_PARM(tras_ps),
35066869f95SYork Sun #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
35166869f95SYork Sun 		DIMM_PARM(tfaw_ps),
35266869f95SYork Sun #endif
35334e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
35434e026f9SYork Sun 		DIMM_PARM(trfc1_ps),
35534e026f9SYork Sun 		DIMM_PARM(trfc2_ps),
35634e026f9SYork Sun 		DIMM_PARM(trfc4_ps),
35734e026f9SYork Sun 		DIMM_PARM(trrds_ps),
35834e026f9SYork Sun 		DIMM_PARM(trrdl_ps),
35934e026f9SYork Sun 		DIMM_PARM(tccdl_ps),
36034e026f9SYork Sun #else
3615614e71bSYork Sun 		DIMM_PARM(twr_ps),
3625614e71bSYork Sun 		DIMM_PARM(twtr_ps),
3635614e71bSYork Sun 		DIMM_PARM(trfc_ps),
3645614e71bSYork Sun 		DIMM_PARM(trrd_ps),
36534e026f9SYork Sun 		DIMM_PARM(trtp_ps),
36634e026f9SYork Sun #endif
3675614e71bSYork Sun 		DIMM_PARM(trc_ps),
3685614e71bSYork Sun 		DIMM_PARM(refresh_rate_ps),
3695614e71bSYork Sun 
37034e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
3715614e71bSYork Sun 		DIMM_PARM(tis_ps),
3725614e71bSYork Sun 		DIMM_PARM(tih_ps),
3735614e71bSYork Sun 		DIMM_PARM(tds_ps),
3745614e71bSYork Sun 		DIMM_PARM(tdh_ps),
3755614e71bSYork Sun 		DIMM_PARM(tdqsq_max_ps),
3765614e71bSYork Sun 		DIMM_PARM(tqhs_ps),
37734e026f9SYork Sun #endif
37866869f95SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
37966869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[0]),
38066869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[1]),
38166869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[2]),
38266869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[3]),
38366869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[4]),
38466869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[5]),
38566869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[6]),
38666869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[7]),
38766869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[8]),
38866869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[9]),
38966869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[10]),
39066869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[11]),
39166869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[12]),
39266869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[13]),
39366869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[14]),
39466869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[15]),
39566869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[16]),
39666869f95SYork Sun 		DIMM_PARM_HEX(dq_mapping[17]),
39766869f95SYork Sun 		DIMM_PARM(dq_mapping_ors),
39866869f95SYork Sun #endif
3995614e71bSYork Sun 	};
4005614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
4015614e71bSYork Sun 
4025614e71bSYork Sun 	if (pdimm->n_ranks == 0) {
4035614e71bSYork Sun 		printf("DIMM not present\n");
4045614e71bSYork Sun 		return;
4055614e71bSYork Sun 	}
4065614e71bSYork Sun 	printf("DIMM organization parameters:\n");
4075614e71bSYork Sun 	printf("module part name = %s\n", pdimm->mpart);
4085614e71bSYork Sun 	printf("rank_density = %llu bytes (%llu megabytes)\n",
4095614e71bSYork Sun 	       pdimm->rank_density, pdimm->rank_density / 0x100000);
4105614e71bSYork Sun 	printf("capacity = %llu bytes (%llu megabytes)\n",
4115614e71bSYork Sun 	       pdimm->capacity, pdimm->capacity / 0x100000);
4125614e71bSYork Sun 	printf("burst_lengths_bitmask = %02X\n",
4135614e71bSYork Sun 	       pdimm->burst_lengths_bitmask);
4145614e71bSYork Sun 	printf("base_addresss = %llu (%08llX %08llX)\n",
4155614e71bSYork Sun 	       pdimm->base_address,
4165614e71bSYork Sun 	       (pdimm->base_address >> 32),
4175614e71bSYork Sun 	       pdimm->base_address & 0xFFFFFFFF);
4185614e71bSYork Sun 	print_option_table(options, n_opts, pdimm);
4195614e71bSYork Sun }
4205614e71bSYork Sun 
4215614e71bSYork Sun static void print_lowest_common_dimm_parameters(
4225614e71bSYork Sun 		const common_timing_params_t *plcd_dimm_params)
4235614e71bSYork Sun {
4245614e71bSYork Sun 	static const struct options_string options[] = {
42534e026f9SYork Sun 		COMMON_TIMING(taamin_ps),
4265614e71bSYork Sun 		COMMON_TIMING(trcd_ps),
4275614e71bSYork Sun 		COMMON_TIMING(trp_ps),
4285614e71bSYork Sun 		COMMON_TIMING(tras_ps),
42934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
43034e026f9SYork Sun 		COMMON_TIMING(trfc1_ps),
43134e026f9SYork Sun 		COMMON_TIMING(trfc2_ps),
43234e026f9SYork Sun 		COMMON_TIMING(trfc4_ps),
43334e026f9SYork Sun 		COMMON_TIMING(trrds_ps),
43434e026f9SYork Sun 		COMMON_TIMING(trrdl_ps),
43534e026f9SYork Sun 		COMMON_TIMING(tccdl_ps),
43634e026f9SYork Sun #else
4375614e71bSYork Sun 		COMMON_TIMING(twtr_ps),
4385614e71bSYork Sun 		COMMON_TIMING(trfc_ps),
4395614e71bSYork Sun 		COMMON_TIMING(trrd_ps),
44034e026f9SYork Sun 		COMMON_TIMING(trtp_ps),
44134e026f9SYork Sun #endif
44234e026f9SYork Sun 		COMMON_TIMING(twr_ps),
4435614e71bSYork Sun 		COMMON_TIMING(trc_ps),
4445614e71bSYork Sun 		COMMON_TIMING(refresh_rate_ps),
44534e026f9SYork Sun 		COMMON_TIMING(extended_op_srt),
44634e026f9SYork Sun #if defined(CONFIG_SYS_FSL_DDR1) || defined(CONFIG_SYS_FSL_DDR2)
4475614e71bSYork Sun 		COMMON_TIMING(tis_ps),
44834e026f9SYork Sun 		COMMON_TIMING(tih_ps),
4495614e71bSYork Sun 		COMMON_TIMING(tds_ps),
4505614e71bSYork Sun 		COMMON_TIMING(tdh_ps),
4515614e71bSYork Sun 		COMMON_TIMING(tdqsq_max_ps),
4525614e71bSYork Sun 		COMMON_TIMING(tqhs_ps),
45334e026f9SYork Sun #endif
45434e026f9SYork Sun 		COMMON_TIMING(lowest_common_spd_caslat),
4555614e71bSYork Sun 		COMMON_TIMING(highest_common_derated_caslat),
4565614e71bSYork Sun 		COMMON_TIMING(additive_latency),
4575614e71bSYork Sun 		COMMON_TIMING(ndimms_present),
4585614e71bSYork Sun 		COMMON_TIMING(all_dimms_registered),
4595614e71bSYork Sun 		COMMON_TIMING(all_dimms_unbuffered),
4605614e71bSYork Sun 		COMMON_TIMING(all_dimms_ecc_capable),
4615614e71bSYork Sun 	};
4625614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
4635614e71bSYork Sun 
4645614e71bSYork Sun 	/* Clock frequencies */
4655614e71bSYork Sun 	printf("tckmin_x_ps = %u (%u MHz)\n",
4665614e71bSYork Sun 	       plcd_dimm_params->tckmin_x_ps,
4675614e71bSYork Sun 	       picos_to_mhz(plcd_dimm_params->tckmin_x_ps));
4685614e71bSYork Sun 	printf("tckmax_ps = %u (%u MHz)\n",
4695614e71bSYork Sun 	       plcd_dimm_params->tckmax_ps,
4705614e71bSYork Sun 	       picos_to_mhz(plcd_dimm_params->tckmax_ps));
4715614e71bSYork Sun 	printf("all_dimms_burst_lengths_bitmask = %02X\n",
4725614e71bSYork Sun 	       plcd_dimm_params->all_dimms_burst_lengths_bitmask);
4735614e71bSYork Sun 
4745614e71bSYork Sun 	print_option_table(options, n_opts, plcd_dimm_params);
4755614e71bSYork Sun 
4765614e71bSYork Sun 	printf("total_mem = %llu (%llu megabytes)\n",
4775614e71bSYork Sun 	       plcd_dimm_params->total_mem,
4785614e71bSYork Sun 	       plcd_dimm_params->total_mem / 0x100000);
4795614e71bSYork Sun 	printf("base_address = %llu (%llu megabytes)\n",
4805614e71bSYork Sun 	       plcd_dimm_params->base_address,
4815614e71bSYork Sun 	       plcd_dimm_params->base_address / 0x100000);
4825614e71bSYork Sun }
4835614e71bSYork Sun 
4845614e71bSYork Sun #define CTRL_OPTIONS(x) {#x, offsetof(memctl_options_t, x), \
4855614e71bSYork Sun 	sizeof((memctl_options_t *)0)->x, 0}
4865614e71bSYork Sun #define CTRL_OPTIONS_CS(x, y) {"cs" #x "_" #y, \
4875614e71bSYork Sun 	offsetof(memctl_options_t, cs_local_opts[x].y), \
4885614e71bSYork Sun 	sizeof((memctl_options_t *)0)->cs_local_opts[x].y, 0}
4895614e71bSYork Sun 
4905614e71bSYork Sun static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
4915614e71bSYork Sun 			   unsigned int ctl_num,
4925614e71bSYork Sun 			   const char *optname_str,
4935614e71bSYork Sun 			   const char *value_str)
4945614e71bSYork Sun {
4955614e71bSYork Sun 	memctl_options_t *p = &(pinfo->memctl_opts[ctl_num]);
4965614e71bSYork Sun 	/*
4975614e71bSYork Sun 	 * This array all on the stack and *computed* each time this
4985614e71bSYork Sun 	 * function is rung.
4995614e71bSYork Sun 	 */
5005614e71bSYork Sun 	static const struct options_string options[] = {
5015614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rd_cfg),
5025614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_wr_cfg),
5035614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
5045614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rd_cfg),
5055614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_wr_cfg),
5065614e71bSYork Sun #endif
5075614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
5085614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rd_cfg),
5095614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_wr_cfg),
5105614e71bSYork Sun #endif
5115614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
5125614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rd_cfg),
5135614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_wr_cfg),
5145614e71bSYork Sun #endif
515*6b95be22SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
5165614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rtt_norm),
5175614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rtt_wr),
5185614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
5195614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rtt_norm),
5205614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rtt_wr),
5215614e71bSYork Sun #endif
5225614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
5235614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rtt_norm),
5245614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rtt_wr),
5255614e71bSYork Sun #endif
5265614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
5275614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rtt_norm),
5285614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rtt_wr),
5295614e71bSYork Sun #endif
5305614e71bSYork Sun #endif
5315614e71bSYork Sun 		CTRL_OPTIONS(memctl_interleaving),
5325614e71bSYork Sun 		CTRL_OPTIONS(memctl_interleaving_mode),
5335614e71bSYork Sun 		CTRL_OPTIONS(ba_intlv_ctl),
5345614e71bSYork Sun 		CTRL_OPTIONS(ecc_mode),
5355614e71bSYork Sun 		CTRL_OPTIONS(ecc_init_using_memctl),
5365614e71bSYork Sun 		CTRL_OPTIONS(dqs_config),
5375614e71bSYork Sun 		CTRL_OPTIONS(self_refresh_in_sleep),
5385614e71bSYork Sun 		CTRL_OPTIONS(dynamic_power),
5395614e71bSYork Sun 		CTRL_OPTIONS(data_bus_width),
5405614e71bSYork Sun 		CTRL_OPTIONS(burst_length),
5415614e71bSYork Sun 		CTRL_OPTIONS(cas_latency_override),
5425614e71bSYork Sun 		CTRL_OPTIONS(cas_latency_override_value),
5435614e71bSYork Sun 		CTRL_OPTIONS(use_derated_caslat),
5445614e71bSYork Sun 		CTRL_OPTIONS(additive_latency_override),
5455614e71bSYork Sun 		CTRL_OPTIONS(additive_latency_override_value),
5465614e71bSYork Sun 		CTRL_OPTIONS(clk_adjust),
5475614e71bSYork Sun 		CTRL_OPTIONS(cpo_override),
5485614e71bSYork Sun 		CTRL_OPTIONS(write_data_delay),
5495614e71bSYork Sun 		CTRL_OPTIONS(half_strength_driver_enable),
5505614e71bSYork Sun 
5515614e71bSYork Sun 		/*
5525614e71bSYork Sun 		 * These can probably be changed to 2T_EN and 3T_EN
5535614e71bSYork Sun 		 * (using a leading numerical character) without problem
5545614e71bSYork Sun 		 */
5555614e71bSYork Sun 		CTRL_OPTIONS(twot_en),
5565614e71bSYork Sun 		CTRL_OPTIONS(threet_en),
5575614e71bSYork Sun 		CTRL_OPTIONS(ap_en),
5585614e71bSYork Sun 		CTRL_OPTIONS(x4_en),
5595614e71bSYork Sun 		CTRL_OPTIONS(bstopre),
5605614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_override),
5615614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_sample),
5625614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_start),
563ef87cab6SYork Sun 		CTRL_OPTIONS(cswl_override),
5645614e71bSYork Sun 		CTRL_OPTIONS(rcw_override),
5655614e71bSYork Sun 		CTRL_OPTIONS(rcw_1),
5665614e71bSYork Sun 		CTRL_OPTIONS(rcw_2),
5675614e71bSYork Sun 		CTRL_OPTIONS(ddr_cdr1),
5685614e71bSYork Sun 		CTRL_OPTIONS(ddr_cdr2),
5695614e71bSYork Sun 		CTRL_OPTIONS(tfaw_window_four_activates_ps),
5705614e71bSYork Sun 		CTRL_OPTIONS(trwt_override),
5715614e71bSYork Sun 		CTRL_OPTIONS(trwt),
57234e026f9SYork Sun 		CTRL_OPTIONS(rtt_override),
57334e026f9SYork Sun 		CTRL_OPTIONS(rtt_override_value),
57434e026f9SYork Sun 		CTRL_OPTIONS(rtt_wr_override_value),
5755614e71bSYork Sun 	};
5765614e71bSYork Sun 
5775614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
5785614e71bSYork Sun 
5795614e71bSYork Sun 	if (handle_option_table(options, n_opts, p,
5805614e71bSYork Sun 					optname_str, value_str))
5815614e71bSYork Sun 		return;
5825614e71bSYork Sun 
5835614e71bSYork Sun 	printf("couldn't find option string %s\n", optname_str);
5845614e71bSYork Sun }
5855614e71bSYork Sun 
5865614e71bSYork Sun #define CFG_REGS(x) {#x, offsetof(fsl_ddr_cfg_regs_t, x), \
5875614e71bSYork Sun 	sizeof((fsl_ddr_cfg_regs_t *)0)->x, 1}
5885614e71bSYork Sun #define CFG_REGS_CS(x, y) {"cs" #x "_" #y, \
5895614e71bSYork Sun 	offsetof(fsl_ddr_cfg_regs_t, cs[x].y), \
5905614e71bSYork Sun 	sizeof((fsl_ddr_cfg_regs_t *)0)->cs[x].y, 1}
5915614e71bSYork Sun 
5925614e71bSYork Sun static void print_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
5935614e71bSYork Sun {
5945614e71bSYork Sun 	unsigned int i;
5955614e71bSYork Sun 	static const struct options_string options[] = {
5965614e71bSYork Sun 		CFG_REGS_CS(0, bnds),
5975614e71bSYork Sun 		CFG_REGS_CS(0, config),
5985614e71bSYork Sun 		CFG_REGS_CS(0, config_2),
5995614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
6005614e71bSYork Sun 		CFG_REGS_CS(1, bnds),
6015614e71bSYork Sun 		CFG_REGS_CS(1, config),
6025614e71bSYork Sun 		CFG_REGS_CS(1, config_2),
6035614e71bSYork Sun #endif
6045614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
6055614e71bSYork Sun 		CFG_REGS_CS(2, bnds),
6065614e71bSYork Sun 		CFG_REGS_CS(2, config),
6075614e71bSYork Sun 		CFG_REGS_CS(2, config_2),
6085614e71bSYork Sun #endif
6095614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
6105614e71bSYork Sun 		CFG_REGS_CS(3, bnds),
6115614e71bSYork Sun 		CFG_REGS_CS(3, config),
6125614e71bSYork Sun 		CFG_REGS_CS(3, config_2),
6135614e71bSYork Sun #endif
6145614e71bSYork Sun 		CFG_REGS(timing_cfg_3),
6155614e71bSYork Sun 		CFG_REGS(timing_cfg_0),
6165614e71bSYork Sun 		CFG_REGS(timing_cfg_1),
6175614e71bSYork Sun 		CFG_REGS(timing_cfg_2),
6185614e71bSYork Sun 		CFG_REGS(ddr_sdram_cfg),
6195614e71bSYork Sun 		CFG_REGS(ddr_sdram_cfg_2),
62034e026f9SYork Sun 		CFG_REGS(ddr_sdram_cfg_3),
6215614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode),
6225614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_2),
6235614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_3),
6245614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_4),
6255614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_5),
6265614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_6),
6275614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_7),
6285614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_8),
62934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
63034e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_9),
63134e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_10),
63234e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_11),
63334e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_12),
63434e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_13),
63534e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_14),
63634e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_15),
63734e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_16),
63834e026f9SYork Sun #endif
6395614e71bSYork Sun 		CFG_REGS(ddr_sdram_interval),
6405614e71bSYork Sun 		CFG_REGS(ddr_data_init),
6415614e71bSYork Sun 		CFG_REGS(ddr_sdram_clk_cntl),
6425614e71bSYork Sun 		CFG_REGS(ddr_init_addr),
6435614e71bSYork Sun 		CFG_REGS(ddr_init_ext_addr),
6445614e71bSYork Sun 		CFG_REGS(timing_cfg_4),
6455614e71bSYork Sun 		CFG_REGS(timing_cfg_5),
64634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
64734e026f9SYork Sun 		CFG_REGS(timing_cfg_6),
64834e026f9SYork Sun 		CFG_REGS(timing_cfg_7),
64934e026f9SYork Sun 		CFG_REGS(timing_cfg_8),
65034e026f9SYork Sun 		CFG_REGS(timing_cfg_9),
65134e026f9SYork Sun #endif
6525614e71bSYork Sun 		CFG_REGS(ddr_zq_cntl),
6535614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl),
6545614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl_2),
6555614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl_3),
6565614e71bSYork Sun 		CFG_REGS(ddr_sr_cntr),
6575614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_1),
6585614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_2),
6595614e71bSYork Sun 		CFG_REGS(ddr_cdr1),
6605614e71bSYork Sun 		CFG_REGS(ddr_cdr2),
66134e026f9SYork Sun 		CFG_REGS(dq_map_0),
66234e026f9SYork Sun 		CFG_REGS(dq_map_1),
66334e026f9SYork Sun 		CFG_REGS(dq_map_2),
66434e026f9SYork Sun 		CFG_REGS(dq_map_3),
6655614e71bSYork Sun 		CFG_REGS(err_disable),
6665614e71bSYork Sun 		CFG_REGS(err_int_en),
6675614e71bSYork Sun 		CFG_REGS(ddr_eor),
6685614e71bSYork Sun 	};
6695614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
6705614e71bSYork Sun 
6715614e71bSYork Sun 	print_option_table(options, n_opts, ddr);
6725614e71bSYork Sun 
6735614e71bSYork Sun 	for (i = 0; i < 32; i++)
6745614e71bSYork Sun 		printf("debug_%02d = 0x%08X\n", i+1, ddr->debug[i]);
6755614e71bSYork Sun }
6765614e71bSYork Sun 
6775614e71bSYork Sun static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo,
6785614e71bSYork Sun 			unsigned int ctrl_num,
6795614e71bSYork Sun 			const char *regname,
6805614e71bSYork Sun 			const char *value_str)
6815614e71bSYork Sun {
6825614e71bSYork Sun 	unsigned int i;
6835614e71bSYork Sun 	fsl_ddr_cfg_regs_t *ddr;
6845614e71bSYork Sun 	char buf[20];
6855614e71bSYork Sun 	static const struct options_string options[] = {
6865614e71bSYork Sun 		CFG_REGS_CS(0, bnds),
6875614e71bSYork Sun 		CFG_REGS_CS(0, config),
6885614e71bSYork Sun 		CFG_REGS_CS(0, config_2),
6895614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
6905614e71bSYork Sun 		CFG_REGS_CS(1, bnds),
6915614e71bSYork Sun 		CFG_REGS_CS(1, config),
6925614e71bSYork Sun 		CFG_REGS_CS(1, config_2),
6935614e71bSYork Sun #endif
6945614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
6955614e71bSYork Sun 		CFG_REGS_CS(2, bnds),
6965614e71bSYork Sun 		CFG_REGS_CS(2, config),
6975614e71bSYork Sun 		CFG_REGS_CS(2, config_2),
6985614e71bSYork Sun #endif
6995614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
7005614e71bSYork Sun 		CFG_REGS_CS(3, bnds),
7015614e71bSYork Sun 		CFG_REGS_CS(3, config),
7025614e71bSYork Sun 		CFG_REGS_CS(3, config_2),
7035614e71bSYork Sun #endif
7045614e71bSYork Sun 		CFG_REGS(timing_cfg_3),
7055614e71bSYork Sun 		CFG_REGS(timing_cfg_0),
7065614e71bSYork Sun 		CFG_REGS(timing_cfg_1),
7075614e71bSYork Sun 		CFG_REGS(timing_cfg_2),
7085614e71bSYork Sun 		CFG_REGS(ddr_sdram_cfg),
7095614e71bSYork Sun 		CFG_REGS(ddr_sdram_cfg_2),
71034e026f9SYork Sun 		CFG_REGS(ddr_sdram_cfg_3),
7115614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode),
7125614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_2),
7135614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_3),
7145614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_4),
7155614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_5),
7165614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_6),
7175614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_7),
7185614e71bSYork Sun 		CFG_REGS(ddr_sdram_mode_8),
71934e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
72034e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_9),
72134e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_10),
72234e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_11),
72334e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_12),
72434e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_13),
72534e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_14),
72634e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_15),
72734e026f9SYork Sun 		CFG_REGS(ddr_sdram_mode_16),
72834e026f9SYork Sun #endif
7295614e71bSYork Sun 		CFG_REGS(ddr_sdram_interval),
7305614e71bSYork Sun 		CFG_REGS(ddr_data_init),
7315614e71bSYork Sun 		CFG_REGS(ddr_sdram_clk_cntl),
7325614e71bSYork Sun 		CFG_REGS(ddr_init_addr),
7335614e71bSYork Sun 		CFG_REGS(ddr_init_ext_addr),
7345614e71bSYork Sun 		CFG_REGS(timing_cfg_4),
7355614e71bSYork Sun 		CFG_REGS(timing_cfg_5),
73634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
73734e026f9SYork Sun 		CFG_REGS(timing_cfg_6),
73834e026f9SYork Sun 		CFG_REGS(timing_cfg_7),
73934e026f9SYork Sun 		CFG_REGS(timing_cfg_8),
74034e026f9SYork Sun 		CFG_REGS(timing_cfg_9),
74134e026f9SYork Sun #endif
7425614e71bSYork Sun 		CFG_REGS(ddr_zq_cntl),
7435614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl),
7445614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl_2),
7455614e71bSYork Sun 		CFG_REGS(ddr_wrlvl_cntl_3),
7465614e71bSYork Sun 		CFG_REGS(ddr_sr_cntr),
7475614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_1),
7485614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_2),
7495614e71bSYork Sun 		CFG_REGS(ddr_cdr1),
7505614e71bSYork Sun 		CFG_REGS(ddr_cdr2),
75134e026f9SYork Sun 		CFG_REGS(dq_map_0),
75234e026f9SYork Sun 		CFG_REGS(dq_map_1),
75334e026f9SYork Sun 		CFG_REGS(dq_map_2),
75434e026f9SYork Sun 		CFG_REGS(dq_map_3),
7555614e71bSYork Sun 		CFG_REGS(err_disable),
7565614e71bSYork Sun 		CFG_REGS(err_int_en),
7575614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_2),
7585614e71bSYork Sun 		CFG_REGS(ddr_sdram_rcw_2),
7595614e71bSYork Sun 		CFG_REGS(ddr_eor),
7605614e71bSYork Sun 	};
7615614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
7625614e71bSYork Sun 
7635614e71bSYork Sun 	debug("fsl_ddr_regs_edit: ctrl_num = %u, "
7645614e71bSYork Sun 		"regname = %s, value = %s\n",
7655614e71bSYork Sun 		ctrl_num, regname, value_str);
7665614e71bSYork Sun 	if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS)
7675614e71bSYork Sun 		return;
7685614e71bSYork Sun 
7695614e71bSYork Sun 	ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]);
7705614e71bSYork Sun 
7715614e71bSYork Sun 	if (handle_option_table(options, n_opts, ddr, regname, value_str))
7725614e71bSYork Sun 		return;
7735614e71bSYork Sun 
7745614e71bSYork Sun 	for (i = 0; i < 32; i++) {
7755614e71bSYork Sun 		unsigned int value = simple_strtoul(value_str, NULL, 0);
7765614e71bSYork Sun 		sprintf(buf, "debug_%u", i + 1);
7775614e71bSYork Sun 		if (strcmp(buf, regname) == 0) {
7785614e71bSYork Sun 			ddr->debug[i] = value;
7795614e71bSYork Sun 			return;
7805614e71bSYork Sun 		}
7815614e71bSYork Sun 	}
7825614e71bSYork Sun 	printf("Error: couldn't find register string %s\n", regname);
7835614e71bSYork Sun }
7845614e71bSYork Sun 
7855614e71bSYork Sun #define CTRL_OPTIONS_HEX(x) {#x, offsetof(memctl_options_t, x), \
7865614e71bSYork Sun 	sizeof((memctl_options_t *)0)->x, 1}
7875614e71bSYork Sun 
7885614e71bSYork Sun static void print_memctl_options(const memctl_options_t *popts)
7895614e71bSYork Sun {
7905614e71bSYork Sun 	static const struct options_string options[] = {
7915614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rd_cfg),
7925614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_wr_cfg),
7935614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
7945614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rd_cfg),
7955614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_wr_cfg),
7965614e71bSYork Sun #endif
7975614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
7985614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rd_cfg),
7995614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_wr_cfg),
8005614e71bSYork Sun #endif
8015614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
8025614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rd_cfg),
8035614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_wr_cfg),
8045614e71bSYork Sun #endif
805*6b95be22SYork Sun #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
8065614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rtt_norm),
8075614e71bSYork Sun 		CTRL_OPTIONS_CS(0, odt_rtt_wr),
8085614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
8095614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rtt_norm),
8105614e71bSYork Sun 		CTRL_OPTIONS_CS(1, odt_rtt_wr),
8115614e71bSYork Sun #endif
8125614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 2)
8135614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rtt_norm),
8145614e71bSYork Sun 		CTRL_OPTIONS_CS(2, odt_rtt_wr),
8155614e71bSYork Sun #endif
8165614e71bSYork Sun #if (CONFIG_CHIP_SELECTS_PER_CTRL > 3)
8175614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rtt_norm),
8185614e71bSYork Sun 		CTRL_OPTIONS_CS(3, odt_rtt_wr),
8195614e71bSYork Sun #endif
8205614e71bSYork Sun #endif
8215614e71bSYork Sun 		CTRL_OPTIONS(memctl_interleaving),
8225614e71bSYork Sun 		CTRL_OPTIONS(memctl_interleaving_mode),
8235614e71bSYork Sun 		CTRL_OPTIONS_HEX(ba_intlv_ctl),
8245614e71bSYork Sun 		CTRL_OPTIONS(ecc_mode),
8255614e71bSYork Sun 		CTRL_OPTIONS(ecc_init_using_memctl),
8265614e71bSYork Sun 		CTRL_OPTIONS(dqs_config),
8275614e71bSYork Sun 		CTRL_OPTIONS(self_refresh_in_sleep),
8285614e71bSYork Sun 		CTRL_OPTIONS(dynamic_power),
8295614e71bSYork Sun 		CTRL_OPTIONS(data_bus_width),
8305614e71bSYork Sun 		CTRL_OPTIONS(burst_length),
8315614e71bSYork Sun 		CTRL_OPTIONS(cas_latency_override),
8325614e71bSYork Sun 		CTRL_OPTIONS(cas_latency_override_value),
8335614e71bSYork Sun 		CTRL_OPTIONS(use_derated_caslat),
8345614e71bSYork Sun 		CTRL_OPTIONS(additive_latency_override),
8355614e71bSYork Sun 		CTRL_OPTIONS(additive_latency_override_value),
8365614e71bSYork Sun 		CTRL_OPTIONS(clk_adjust),
8375614e71bSYork Sun 		CTRL_OPTIONS(cpo_override),
8385614e71bSYork Sun 		CTRL_OPTIONS(write_data_delay),
8395614e71bSYork Sun 		CTRL_OPTIONS(half_strength_driver_enable),
8405614e71bSYork Sun 		/*
8415614e71bSYork Sun 		 * These can probably be changed to 2T_EN and 3T_EN
8425614e71bSYork Sun 		 * (using a leading numerical character) without problem
8435614e71bSYork Sun 		 */
8445614e71bSYork Sun 		CTRL_OPTIONS(twot_en),
8455614e71bSYork Sun 		CTRL_OPTIONS(threet_en),
8465614e71bSYork Sun 		CTRL_OPTIONS(registered_dimm_en),
847*6b95be22SYork Sun 		CTRL_OPTIONS(mirrored_dimm),
8485614e71bSYork Sun 		CTRL_OPTIONS(ap_en),
8495614e71bSYork Sun 		CTRL_OPTIONS(x4_en),
8505614e71bSYork Sun 		CTRL_OPTIONS(bstopre),
8515614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_override),
8525614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_sample),
8535614e71bSYork Sun 		CTRL_OPTIONS(wrlvl_start),
854ef87cab6SYork Sun 		CTRL_OPTIONS_HEX(cswl_override),
8555614e71bSYork Sun 		CTRL_OPTIONS(rcw_override),
8565614e71bSYork Sun 		CTRL_OPTIONS(rcw_1),
8575614e71bSYork Sun 		CTRL_OPTIONS(rcw_2),
8585614e71bSYork Sun 		CTRL_OPTIONS_HEX(ddr_cdr1),
8595614e71bSYork Sun 		CTRL_OPTIONS_HEX(ddr_cdr2),
8605614e71bSYork Sun 		CTRL_OPTIONS(tfaw_window_four_activates_ps),
8615614e71bSYork Sun 		CTRL_OPTIONS(trwt_override),
8625614e71bSYork Sun 		CTRL_OPTIONS(trwt),
86334e026f9SYork Sun 		CTRL_OPTIONS(rtt_override),
86434e026f9SYork Sun 		CTRL_OPTIONS(rtt_override_value),
86534e026f9SYork Sun 		CTRL_OPTIONS(rtt_wr_override_value),
8665614e71bSYork Sun 	};
8675614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
8685614e71bSYork Sun 
8695614e71bSYork Sun 	print_option_table(options, n_opts, popts);
8705614e71bSYork Sun }
8715614e71bSYork Sun 
8725614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR1
8735614e71bSYork Sun void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd)
8745614e71bSYork Sun {
8755614e71bSYork Sun 	unsigned int i;
8765614e71bSYork Sun 
8775614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 0, spd->info_size,
8785614e71bSYork Sun 	       " spd->info_size,   *  0 # bytes written into serial memory *");
8795614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 1, spd->chip_size,
8805614e71bSYork Sun 	       " spd->chip_size,   *  1 Total # bytes of SPD memory device *");
8815614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 2, spd->mem_type,
8825614e71bSYork Sun 	       " spd->mem_type,    *  2 Fundamental memory type *");
8835614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 3, spd->nrow_addr,
8845614e71bSYork Sun 	       " spd->nrow_addr,   *  3 # of Row Addresses on this assembly *");
8855614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 4, spd->ncol_addr,
8865614e71bSYork Sun 	       " spd->ncol_addr,   *  4 # of Column Addrs on this assembly *");
8875614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 5, spd->nrows,
8885614e71bSYork Sun 	       " spd->nrows        *  5 # of DIMM Banks *");
8895614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 6, spd->dataw_lsb,
8905614e71bSYork Sun 	       " spd->dataw_lsb,   *  6 Data Width lsb of this assembly *");
8915614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 7, spd->dataw_msb,
8925614e71bSYork Sun 	       " spd->dataw_msb,   *  7 Data Width msb of this assembly *");
8935614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 8, spd->voltage,
8945614e71bSYork Sun 	       " spd->voltage,     *  8 Voltage intf std of this assembly *");
8955614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 9, spd->clk_cycle,
8965614e71bSYork Sun 	       " spd->clk_cycle,   *  9 SDRAM Cycle time at CL=X *");
8975614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 10, spd->clk_access,
8985614e71bSYork Sun 	       " spd->clk_access,  * 10 SDRAM Access from Clock at CL=X *");
8995614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 11, spd->config,
9005614e71bSYork Sun 	       " spd->config,      * 11 DIMM Configuration type *");
9015614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 12, spd->refresh,
9025614e71bSYork Sun 	       " spd->refresh,     * 12 Refresh Rate/Type *");
9035614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 13, spd->primw,
9045614e71bSYork Sun 	       " spd->primw,       * 13 Primary SDRAM Width *");
9055614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 14, spd->ecw,
9065614e71bSYork Sun 	       " spd->ecw,         * 14 Error Checking SDRAM width *");
9075614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 15, spd->min_delay,
9085614e71bSYork Sun 	       " spd->min_delay,   * 15 Back to Back Random Access *");
9095614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 16, spd->burstl,
9105614e71bSYork Sun 	       " spd->burstl,      * 16 Burst Lengths Supported *");
9115614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 17, spd->nbanks,
9125614e71bSYork Sun 	       " spd->nbanks,      * 17 # of Banks on Each SDRAM Device *");
9135614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 18, spd->cas_lat,
9145614e71bSYork Sun 	       " spd->cas_lat,     * 18 CAS# Latencies Supported *");
9155614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 19, spd->cs_lat,
9165614e71bSYork Sun 	       " spd->cs_lat,      * 19 Chip Select Latency *");
9175614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 20, spd->write_lat,
9185614e71bSYork Sun 	       " spd->write_lat,   * 20 Write Latency/Recovery *");
9195614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 21, spd->mod_attr,
9205614e71bSYork Sun 	       " spd->mod_attr,    * 21 SDRAM Module Attributes *");
9215614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 22, spd->dev_attr,
9225614e71bSYork Sun 	       " spd->dev_attr,    * 22 SDRAM Device Attributes *");
9235614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 23, spd->clk_cycle2,
9245614e71bSYork Sun 	       " spd->clk_cycle2,  * 23 Min SDRAM Cycle time at CL=X-1 *");
9255614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 24, spd->clk_access2,
9265614e71bSYork Sun 	       " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
9275614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 25, spd->clk_cycle3,
9285614e71bSYork Sun 	       " spd->clk_cycle3,  * 25 Min SDRAM Cycle time at CL=X-2 *");
9295614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 26, spd->clk_access3,
9305614e71bSYork Sun 	       " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
9315614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 27, spd->trp,
9325614e71bSYork Sun 	       " spd->trp,         * 27 Min Row Precharge Time (tRP)*");
9335614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 28, spd->trrd,
9345614e71bSYork Sun 	       " spd->trrd,        * 28 Min Row Active to Row Active (tRRD) *");
9355614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 29, spd->trcd,
9365614e71bSYork Sun 	       " spd->trcd,        * 29 Min RAS to CAS Delay (tRCD) *");
9375614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 30, spd->tras,
9385614e71bSYork Sun 	       " spd->tras,        * 30 Minimum RAS Pulse Width (tRAS) *");
9395614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 31, spd->bank_dens,
9405614e71bSYork Sun 	       " spd->bank_dens,   * 31 Density of each bank on module *");
9415614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 32, spd->ca_setup,
9425614e71bSYork Sun 	       " spd->ca_setup,    * 32 Cmd + Addr signal input setup time *");
9435614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 33, spd->ca_hold,
9445614e71bSYork Sun 	       " spd->ca_hold,     * 33 Cmd and Addr signal input hold time *");
9455614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 34, spd->data_setup,
9465614e71bSYork Sun 	       " spd->data_setup,  * 34 Data signal input setup time *");
9475614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 35, spd->data_hold,
9485614e71bSYork Sun 	       " spd->data_hold,   * 35 Data signal input hold time *");
9495614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 36, spd->res_36_40[0],
9505614e71bSYork Sun 	       " spd->res_36_40[0], * 36 Reserved / tWR *");
9515614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 37, spd->res_36_40[1],
9525614e71bSYork Sun 	       " spd->res_36_40[1], * 37 Reserved / tWTR *");
9535614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 38, spd->res_36_40[2],
9545614e71bSYork Sun 	       " spd->res_36_40[2], * 38 Reserved / tRTP *");
9555614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 39, spd->res_36_40[3],
9565614e71bSYork Sun 	       " spd->res_36_40[3], * 39 Reserved / mem_probe *");
9575614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 40, spd->res_36_40[4],
9585614e71bSYork Sun 	       " spd->res_36_40[4], * 40 Reserved / trc,trfc extensions *");
9595614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 41, spd->trc,
9605614e71bSYork Sun 	       " spd->trc,         * 41 Min Active to Auto refresh time tRC *");
9615614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 42, spd->trfc,
9625614e71bSYork Sun 	       " spd->trfc,        * 42 Min Auto to Active period tRFC *");
9635614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 43, spd->tckmax,
9645614e71bSYork Sun 	       " spd->tckmax,      * 43 Max device cycle time tCKmax *");
9655614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 44, spd->tdqsq,
9665614e71bSYork Sun 	       " spd->tdqsq,       * 44 Max DQS to DQ skew *");
9675614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 45, spd->tqhs,
9685614e71bSYork Sun 	       " spd->tqhs,        * 45 Max Read DataHold skew tQHS *");
9695614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 46, spd->res_46,
9705614e71bSYork Sun 	       " spd->res_46,  * 46 Reserved/ PLL Relock time *");
9715614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 47, spd->dimm_height,
9725614e71bSYork Sun 	       " spd->dimm_height  * 47 SDRAM DIMM Height *");
9735614e71bSYork Sun 
9745614e71bSYork Sun 	printf("%-3d-%3d: ",  48, 61);
9755614e71bSYork Sun 
9765614e71bSYork Sun 	for (i = 0; i < 14; i++)
9775614e71bSYork Sun 		printf("%02x", spd->res_48_61[i]);
9785614e71bSYork Sun 
9795614e71bSYork Sun 	printf(" * 48-61 IDD in SPD and Reserved space *\n");
9805614e71bSYork Sun 
9815614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 62, spd->spd_rev,
9825614e71bSYork Sun 	       " spd->spd_rev,     * 62 SPD Data Revision Code *");
9835614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 63, spd->cksum,
9845614e71bSYork Sun 	       " spd->cksum,       * 63 Checksum for bytes 0-62 *");
9855614e71bSYork Sun 	printf("%-3d-%3d: ",  64, 71);
9865614e71bSYork Sun 
9875614e71bSYork Sun 	for (i = 0; i < 8; i++)
9885614e71bSYork Sun 		printf("%02x", spd->mid[i]);
9895614e71bSYork Sun 
9905614e71bSYork Sun 	printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
9915614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 72, spd->mloc,
9925614e71bSYork Sun 	       " spd->mloc,        * 72 Manufacturing Location *");
9935614e71bSYork Sun 
9945614e71bSYork Sun 	printf("%-3d-%3d: >>",  73, 90);
9955614e71bSYork Sun 
9965614e71bSYork Sun 	for (i = 0; i < 18; i++)
9975614e71bSYork Sun 		printf("%c", spd->mpart[i]);
9985614e71bSYork Sun 
9995614e71bSYork Sun 	printf("<<* 73 Manufacturer's Part Number *\n");
10005614e71bSYork Sun 
10015614e71bSYork Sun 	printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1],
10025614e71bSYork Sun 	       "* 91 Revision Code *");
10035614e71bSYork Sun 	printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1],
10045614e71bSYork Sun 	       "* 93 Manufacturing Date *");
10055614e71bSYork Sun 	printf("%-3d-%3d: ", 95, 98);
10065614e71bSYork Sun 
10075614e71bSYork Sun 	for (i = 0; i < 4; i++)
10085614e71bSYork Sun 		printf("%02x", spd->sernum[i]);
10095614e71bSYork Sun 
10105614e71bSYork Sun 	printf("* 95 Assembly Serial Number *\n");
10115614e71bSYork Sun 
10125614e71bSYork Sun 	printf("%-3d-%3d: ", 99, 127);
10135614e71bSYork Sun 
10145614e71bSYork Sun 	for (i = 0; i < 27; i++)
10155614e71bSYork Sun 		printf("%02x", spd->mspec[i]);
10165614e71bSYork Sun 
10175614e71bSYork Sun 	printf("* 99 Manufacturer Specific Data *\n");
10185614e71bSYork Sun }
10195614e71bSYork Sun #endif
10205614e71bSYork Sun 
10215614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR2
10225614e71bSYork Sun void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd)
10235614e71bSYork Sun {
10245614e71bSYork Sun 	unsigned int i;
10255614e71bSYork Sun 
10265614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 0, spd->info_size,
10275614e71bSYork Sun 	       " spd->info_size,   *  0 # bytes written into serial memory *");
10285614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 1, spd->chip_size,
10295614e71bSYork Sun 	       " spd->chip_size,   *  1 Total # bytes of SPD memory device *");
10305614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 2, spd->mem_type,
10315614e71bSYork Sun 	       " spd->mem_type,    *  2 Fundamental memory type *");
10325614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 3, spd->nrow_addr,
10335614e71bSYork Sun 	       " spd->nrow_addr,   *  3 # of Row Addresses on this assembly *");
10345614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 4, spd->ncol_addr,
10355614e71bSYork Sun 	       " spd->ncol_addr,   *  4 # of Column Addrs on this assembly *");
10365614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 5, spd->mod_ranks,
10375614e71bSYork Sun 	       " spd->mod_ranks    *  5 # of Module Rows on this assembly *");
10385614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 6, spd->dataw,
10395614e71bSYork Sun 	       " spd->dataw,       *  6 Data Width of this assembly *");
10405614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 7, spd->res_7,
10415614e71bSYork Sun 	       " spd->res_7,       *  7 Reserved *");
10425614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 8, spd->voltage,
10435614e71bSYork Sun 	       " spd->voltage,     *  8 Voltage intf std of this assembly *");
10445614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 9, spd->clk_cycle,
10455614e71bSYork Sun 	       " spd->clk_cycle,   *  9 SDRAM Cycle time at CL=X *");
10465614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 10, spd->clk_access,
10475614e71bSYork Sun 	       " spd->clk_access,  * 10 SDRAM Access from Clock at CL=X *");
10485614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 11, spd->config,
10495614e71bSYork Sun 	       " spd->config,      * 11 DIMM Configuration type *");
10505614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 12, spd->refresh,
10515614e71bSYork Sun 	       " spd->refresh,     * 12 Refresh Rate/Type *");
10525614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 13, spd->primw,
10535614e71bSYork Sun 	       " spd->primw,       * 13 Primary SDRAM Width *");
10545614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 14, spd->ecw,
10555614e71bSYork Sun 	       " spd->ecw,         * 14 Error Checking SDRAM width *");
10565614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 15, spd->res_15,
10575614e71bSYork Sun 	       " spd->res_15,      * 15 Reserved *");
10585614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 16, spd->burstl,
10595614e71bSYork Sun 	       " spd->burstl,      * 16 Burst Lengths Supported *");
10605614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 17, spd->nbanks,
10615614e71bSYork Sun 	       " spd->nbanks,      * 17 # of Banks on Each SDRAM Device *");
10625614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 18, spd->cas_lat,
10635614e71bSYork Sun 	       " spd->cas_lat,     * 18 CAS# Latencies Supported *");
10645614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 19, spd->mech_char,
10655614e71bSYork Sun 	       " spd->mech_char,   * 19 Mechanical Characteristics *");
10665614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 20, spd->dimm_type,
10675614e71bSYork Sun 	       " spd->dimm_type,   * 20 DIMM type *");
10685614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 21, spd->mod_attr,
10695614e71bSYork Sun 	       " spd->mod_attr,    * 21 SDRAM Module Attributes *");
10705614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 22, spd->dev_attr,
10715614e71bSYork Sun 	       " spd->dev_attr,    * 22 SDRAM Device Attributes *");
10725614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 23, spd->clk_cycle2,
10735614e71bSYork Sun 	       " spd->clk_cycle2,  * 23 Min SDRAM Cycle time at CL=X-1 *");
10745614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 24, spd->clk_access2,
10755614e71bSYork Sun 	       " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
10765614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 25, spd->clk_cycle3,
10775614e71bSYork Sun 	       " spd->clk_cycle3,  * 25 Min SDRAM Cycle time at CL=X-2 *");
10785614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 26, spd->clk_access3,
10795614e71bSYork Sun 	       " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
10805614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 27, spd->trp,
10815614e71bSYork Sun 	       " spd->trp,         * 27 Min Row Precharge Time (tRP)*");
10825614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 28, spd->trrd,
10835614e71bSYork Sun 	       " spd->trrd,        * 28 Min Row Active to Row Active (tRRD) *");
10845614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 29, spd->trcd,
10855614e71bSYork Sun 	       " spd->trcd,        * 29 Min RAS to CAS Delay (tRCD) *");
10865614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 30, spd->tras,
10875614e71bSYork Sun 	       " spd->tras,        * 30 Minimum RAS Pulse Width (tRAS) *");
10885614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 31, spd->rank_dens,
10895614e71bSYork Sun 	       " spd->rank_dens,   * 31 Density of each rank on module *");
10905614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 32, spd->ca_setup,
10915614e71bSYork Sun 	       " spd->ca_setup,    * 32 Cmd + Addr signal input setup time *");
10925614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 33, spd->ca_hold,
10935614e71bSYork Sun 	       " spd->ca_hold,     * 33 Cmd and Addr signal input hold time *");
10945614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 34, spd->data_setup,
10955614e71bSYork Sun 	       " spd->data_setup,  * 34 Data signal input setup time *");
10965614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 35, spd->data_hold,
10975614e71bSYork Sun 	       " spd->data_hold,   * 35 Data signal input hold time *");
10985614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 36, spd->twr,
10995614e71bSYork Sun 	       " spd->twr,         * 36 Write Recovery time tWR *");
11005614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 37, spd->twtr,
11015614e71bSYork Sun 	       " spd->twtr,        * 37 Int write to read delay tWTR *");
11025614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 38, spd->trtp,
11035614e71bSYork Sun 	       " spd->trtp,        * 38 Int read to precharge delay tRTP *");
11045614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 39, spd->mem_probe,
11055614e71bSYork Sun 	       " spd->mem_probe,   * 39 Mem analysis probe characteristics *");
11065614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 40, spd->trctrfc_ext,
11075614e71bSYork Sun 	       " spd->trctrfc_ext, * 40 Extensions to trc and trfc *");
11085614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 41, spd->trc,
11095614e71bSYork Sun 	       " spd->trc,         * 41 Min Active to Auto refresh time tRC *");
11105614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 42, spd->trfc,
11115614e71bSYork Sun 	       " spd->trfc,        * 42 Min Auto to Active period tRFC *");
11125614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 43, spd->tckmax,
11135614e71bSYork Sun 	       " spd->tckmax,      * 43 Max device cycle time tCKmax *");
11145614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 44, spd->tdqsq,
11155614e71bSYork Sun 	       " spd->tdqsq,       * 44 Max DQS to DQ skew *");
11165614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 45, spd->tqhs,
11175614e71bSYork Sun 	       " spd->tqhs,        * 45 Max Read DataHold skew tQHS *");
11185614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 46, spd->pll_relock,
11195614e71bSYork Sun 	       " spd->pll_relock,  * 46 PLL Relock time *");
11205614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 47, spd->t_casemax,
11215614e71bSYork Sun 	       " spd->t_casemax,    * 47 t_casemax *");
11225614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 48, spd->psi_ta_dram,
11235614e71bSYork Sun 	       " spd->psi_ta_dram,   * 48 Thermal Resistance of DRAM Package "
11245614e71bSYork Sun 	       "from Top (Case) to Ambient (Psi T-A DRAM) *");
11255614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 49, spd->dt0_mode,
11265614e71bSYork Sun 	       " spd->dt0_mode,    * 49 DRAM Case Temperature Rise from "
11275614e71bSYork Sun 	       "Ambient due to Activate-Precharge/Mode Bits "
11285614e71bSYork Sun 	       "(DT0/Mode Bits) *)");
11295614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 50, spd->dt2n_dt2q,
11305614e71bSYork Sun 	       " spd->dt2n_dt2q,   * 50 DRAM Case Temperature Rise from "
11315614e71bSYork Sun 	       "Ambient due to Precharge/Quiet Standby "
11325614e71bSYork Sun 	       "(DT2N/DT2Q) *");
11335614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 51, spd->dt2p,
11345614e71bSYork Sun 	       " spd->dt2p,        * 51 DRAM Case Temperature Rise from "
11355614e71bSYork Sun 	       "Ambient due to Precharge Power-Down (DT2P) *");
11365614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 52, spd->dt3n,
11375614e71bSYork Sun 	       " spd->dt3n,        * 52 DRAM Case Temperature Rise from "
11385614e71bSYork Sun 	       "Ambient due to Active Standby (DT3N) *");
11395614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 53, spd->dt3pfast,
11405614e71bSYork Sun 	       " spd->dt3pfast,    * 53 DRAM Case Temperature Rise from "
11415614e71bSYork Sun 	       "Ambient due to Active Power-Down with Fast PDN Exit "
11425614e71bSYork Sun 	       "(DT3Pfast) *");
11435614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 54, spd->dt3pslow,
11445614e71bSYork Sun 	       " spd->dt3pslow,    * 54 DRAM Case Temperature Rise from "
11455614e71bSYork Sun 	       "Ambient due to Active Power-Down with Slow PDN Exit "
11465614e71bSYork Sun 	       "(DT3Pslow) *");
11475614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 55, spd->dt4r_dt4r4w,
11485614e71bSYork Sun 	       " spd->dt4r_dt4r4w, * 55 DRAM Case Temperature Rise from "
11495614e71bSYork Sun 	       "Ambient due to Page Open Burst Read/DT4R4W Mode Bit "
11505614e71bSYork Sun 	       "(DT4R/DT4R4W Mode Bit) *");
11515614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 56, spd->dt5b,
11525614e71bSYork Sun 	       " spd->dt5b,        * 56 DRAM Case Temperature Rise from "
11535614e71bSYork Sun 	       "Ambient due to Burst Refresh (DT5B) *");
11545614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 57, spd->dt7,
11555614e71bSYork Sun 	       " spd->dt7,         * 57 DRAM Case Temperature Rise from "
11565614e71bSYork Sun 	       "Ambient due to Bank Interleave Reads with "
11575614e71bSYork Sun 	       "Auto-Precharge (DT7) *");
11585614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 58, spd->psi_ta_pll,
11595614e71bSYork Sun 	       " spd->psi_ta_pll,    * 58 Thermal Resistance of PLL Package form"
11605614e71bSYork Sun 	       " Top (Case) to Ambient (Psi T-A PLL) *");
11615614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 59, spd->psi_ta_reg,
11625614e71bSYork Sun 	       " spd->psi_ta_reg,    * 59 Thermal Reisitance of Register Package"
11635614e71bSYork Sun 	       " from Top (Case) to Ambient (Psi T-A Register) *");
11645614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 60, spd->dtpllactive,
11655614e71bSYork Sun 	       " spd->dtpllactive, * 60 PLL Case Temperature Rise from "
11665614e71bSYork Sun 	       "Ambient due to PLL Active (DT PLL Active) *");
11675614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 61, spd->dtregact,
11685614e71bSYork Sun 	       " spd->dtregact,    "
11695614e71bSYork Sun 	       "* 61 Register Case Temperature Rise from Ambient due to "
11705614e71bSYork Sun 	       "Register Active/Mode Bit (DT Register Active/Mode Bit) *");
11715614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 62, spd->spd_rev,
11725614e71bSYork Sun 	       " spd->spd_rev,     * 62 SPD Data Revision Code *");
11735614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 63, spd->cksum,
11745614e71bSYork Sun 	       " spd->cksum,       * 63 Checksum for bytes 0-62 *");
11755614e71bSYork Sun 
11765614e71bSYork Sun 	printf("%-3d-%3d: ",  64, 71);
11775614e71bSYork Sun 
11785614e71bSYork Sun 	for (i = 0; i < 8; i++)
11795614e71bSYork Sun 		printf("%02x", spd->mid[i]);
11805614e71bSYork Sun 
11815614e71bSYork Sun 	printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
11825614e71bSYork Sun 
11835614e71bSYork Sun 	printf("%-3d    : %02x %s\n", 72, spd->mloc,
11845614e71bSYork Sun 	       " spd->mloc,        * 72 Manufacturing Location *");
11855614e71bSYork Sun 
11865614e71bSYork Sun 	printf("%-3d-%3d: >>",  73, 90);
11875614e71bSYork Sun 	for (i = 0; i < 18; i++)
11885614e71bSYork Sun 		printf("%c", spd->mpart[i]);
11895614e71bSYork Sun 
11905614e71bSYork Sun 
11915614e71bSYork Sun 	printf("<<* 73 Manufacturer's Part Number *\n");
11925614e71bSYork Sun 
11935614e71bSYork Sun 	printf("%-3d-%3d: %02x %02x %s\n", 91, 92, spd->rev[0], spd->rev[1],
11945614e71bSYork Sun 	       "* 91 Revision Code *");
11955614e71bSYork Sun 	printf("%-3d-%3d: %02x %02x %s\n", 93, 94, spd->mdate[0], spd->mdate[1],
11965614e71bSYork Sun 	       "* 93 Manufacturing Date *");
11975614e71bSYork Sun 	printf("%-3d-%3d: ", 95, 98);
11985614e71bSYork Sun 
11995614e71bSYork Sun 	for (i = 0; i < 4; i++)
12005614e71bSYork Sun 		printf("%02x", spd->sernum[i]);
12015614e71bSYork Sun 
12025614e71bSYork Sun 	printf("* 95 Assembly Serial Number *\n");
12035614e71bSYork Sun 
12045614e71bSYork Sun 	printf("%-3d-%3d: ", 99, 127);
12055614e71bSYork Sun 	for (i = 0; i < 27; i++)
12065614e71bSYork Sun 		printf("%02x", spd->mspec[i]);
12075614e71bSYork Sun 
12085614e71bSYork Sun 
12095614e71bSYork Sun 	printf("* 99 Manufacturer Specific Data *\n");
12105614e71bSYork Sun }
12115614e71bSYork Sun #endif
12125614e71bSYork Sun 
12135614e71bSYork Sun #ifdef CONFIG_SYS_FSL_DDR3
12145614e71bSYork Sun void ddr3_spd_dump(const ddr3_spd_eeprom_t *spd)
12155614e71bSYork Sun {
12165614e71bSYork Sun 	unsigned int i;
12175614e71bSYork Sun 
12185614e71bSYork Sun 	/* General Section: Bytes 0-59 */
12195614e71bSYork Sun 
12205614e71bSYork Sun #define PRINT_NXS(x, y, z...) printf("%-3d    : %02x " z "\n", x, (u8)y);
12215614e71bSYork Sun #define PRINT_NNXXS(n0, n1, x0, x1, s) \
12225614e71bSYork Sun 	printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1);
12235614e71bSYork Sun 
12245614e71bSYork Sun 	PRINT_NXS(0, spd->info_size_crc,
12255614e71bSYork Sun 		"info_size_crc  bytes written into serial memory, "
12265614e71bSYork Sun 		"CRC coverage");
12275614e71bSYork Sun 	PRINT_NXS(1, spd->spd_rev,
12285614e71bSYork Sun 		"spd_rev        SPD Revision");
12295614e71bSYork Sun 	PRINT_NXS(2, spd->mem_type,
12305614e71bSYork Sun 		"mem_type       Key Byte / DRAM Device Type");
12315614e71bSYork Sun 	PRINT_NXS(3, spd->module_type,
12325614e71bSYork Sun 		"module_type    Key Byte / Module Type");
12335614e71bSYork Sun 	PRINT_NXS(4, spd->density_banks,
12345614e71bSYork Sun 		"density_banks  SDRAM Density and Banks");
12355614e71bSYork Sun 	PRINT_NXS(5, spd->addressing,
12365614e71bSYork Sun 		"addressing     SDRAM Addressing");
12375614e71bSYork Sun 	PRINT_NXS(6, spd->module_vdd,
12385614e71bSYork Sun 		"module_vdd     Module Nominal Voltage, VDD");
12395614e71bSYork Sun 	PRINT_NXS(7, spd->organization,
12405614e71bSYork Sun 		"organization   Module Organization");
12415614e71bSYork Sun 	PRINT_NXS(8, spd->bus_width,
12425614e71bSYork Sun 		"bus_width      Module Memory Bus Width");
12435614e71bSYork Sun 	PRINT_NXS(9, spd->ftb_div,
12445614e71bSYork Sun 		"ftb_div        Fine Timebase (FTB) Dividend / Divisor");
12455614e71bSYork Sun 	PRINT_NXS(10, spd->mtb_dividend,
12465614e71bSYork Sun 		"mtb_dividend   Medium Timebase (MTB) Dividend");
12475614e71bSYork Sun 	PRINT_NXS(11, spd->mtb_divisor,
12485614e71bSYork Sun 		"mtb_divisor    Medium Timebase (MTB) Divisor");
12495614e71bSYork Sun 	PRINT_NXS(12, spd->tck_min,
12505614e71bSYork Sun 		  "tck_min        SDRAM Minimum Cycle Time");
12515614e71bSYork Sun 	PRINT_NXS(13, spd->res_13,
12525614e71bSYork Sun 		"res_13         Reserved");
12535614e71bSYork Sun 	PRINT_NXS(14, spd->caslat_lsb,
12545614e71bSYork Sun 		"caslat_lsb     CAS Latencies Supported, LSB");
12555614e71bSYork Sun 	PRINT_NXS(15, spd->caslat_msb,
12565614e71bSYork Sun 		"caslat_msb     CAS Latencies Supported, MSB");
12575614e71bSYork Sun 	PRINT_NXS(16, spd->taa_min,
12585614e71bSYork Sun 		  "taa_min        Min CAS Latency Time");
12595614e71bSYork Sun 	PRINT_NXS(17, spd->twr_min,
12605614e71bSYork Sun 		  "twr_min        Min Write REcovery Time");
12615614e71bSYork Sun 	PRINT_NXS(18, spd->trcd_min,
12625614e71bSYork Sun 		  "trcd_min       Min RAS# to CAS# Delay Time");
12635614e71bSYork Sun 	PRINT_NXS(19, spd->trrd_min,
12645614e71bSYork Sun 		  "trrd_min       Min Row Active to Row Active Delay Time");
12655614e71bSYork Sun 	PRINT_NXS(20, spd->trp_min,
12665614e71bSYork Sun 		  "trp_min        Min Row Precharge Delay Time");
12675614e71bSYork Sun 	PRINT_NXS(21, spd->tras_trc_ext,
12685614e71bSYork Sun 		  "tras_trc_ext   Upper Nibbles for tRAS and tRC");
12695614e71bSYork Sun 	PRINT_NXS(22, spd->tras_min_lsb,
12705614e71bSYork Sun 		  "tras_min_lsb   Min Active to Precharge Delay Time, LSB");
12715614e71bSYork Sun 	PRINT_NXS(23, spd->trc_min_lsb,
12725614e71bSYork Sun 		  "trc_min_lsb Min Active to Active/Refresh Delay Time, LSB");
12735614e71bSYork Sun 	PRINT_NXS(24, spd->trfc_min_lsb,
12745614e71bSYork Sun 		  "trfc_min_lsb   Min Refresh Recovery Delay Time LSB");
12755614e71bSYork Sun 	PRINT_NXS(25, spd->trfc_min_msb,
12765614e71bSYork Sun 		  "trfc_min_msb   Min Refresh Recovery Delay Time MSB");
12775614e71bSYork Sun 	PRINT_NXS(26, spd->twtr_min,
12785614e71bSYork Sun 		  "twtr_min Min Internal Write to Read Command Delay Time");
12795614e71bSYork Sun 	PRINT_NXS(27, spd->trtp_min,
12805614e71bSYork Sun 		  "trtp_min "
12815614e71bSYork Sun 		  "Min Internal Read to Precharge Command Delay Time");
12825614e71bSYork Sun 	PRINT_NXS(28, spd->tfaw_msb,
12835614e71bSYork Sun 		  "tfaw_msb       Upper Nibble for tFAW");
12845614e71bSYork Sun 	PRINT_NXS(29, spd->tfaw_min,
12855614e71bSYork Sun 		  "tfaw_min       Min Four Activate Window Delay Time");
12865614e71bSYork Sun 	PRINT_NXS(30, spd->opt_features,
12875614e71bSYork Sun 		"opt_features   SDRAM Optional Features");
12885614e71bSYork Sun 	PRINT_NXS(31, spd->therm_ref_opt,
12895614e71bSYork Sun 		"therm_ref_opt  SDRAM Thermal and Refresh Opts");
12905614e71bSYork Sun 	PRINT_NXS(32, spd->therm_sensor,
12915614e71bSYork Sun 		"therm_sensor  SDRAM Thermal Sensor");
12925614e71bSYork Sun 	PRINT_NXS(33, spd->device_type,
12935614e71bSYork Sun 		"device_type  SDRAM Device Type");
12945614e71bSYork Sun 	PRINT_NXS(34, spd->fine_tck_min,
12955614e71bSYork Sun 		  "fine_tck_min  Fine offset for tCKmin");
12965614e71bSYork Sun 	PRINT_NXS(35, spd->fine_taa_min,
12975614e71bSYork Sun 		  "fine_taa_min  Fine offset for tAAmin");
12985614e71bSYork Sun 	PRINT_NXS(36, spd->fine_trcd_min,
12995614e71bSYork Sun 		  "fine_trcd_min Fine offset for tRCDmin");
13005614e71bSYork Sun 	PRINT_NXS(37, spd->fine_trp_min,
13015614e71bSYork Sun 		  "fine_trp_min  Fine offset for tRPmin");
13025614e71bSYork Sun 	PRINT_NXS(38, spd->fine_trc_min,
13035614e71bSYork Sun 		  "fine_trc_min  Fine offset for tRCmin");
13045614e71bSYork Sun 
13055614e71bSYork Sun 	printf("%-3d-%3d: ",  39, 59);  /* Reserved, General Section */
13065614e71bSYork Sun 
13075614e71bSYork Sun 	for (i = 39; i <= 59; i++)
13085614e71bSYork Sun 		printf("%02x ", spd->res_39_59[i - 39]);
13095614e71bSYork Sun 
13105614e71bSYork Sun 	puts("\n");
13115614e71bSYork Sun 
13125614e71bSYork Sun 	switch (spd->module_type) {
13135614e71bSYork Sun 	case 0x02:  /* UDIMM */
13145614e71bSYork Sun 	case 0x03:  /* SO-DIMM */
13155614e71bSYork Sun 	case 0x04:  /* Micro-DIMM */
13165614e71bSYork Sun 	case 0x06:  /* Mini-UDIMM */
13175614e71bSYork Sun 		PRINT_NXS(60, spd->mod_section.unbuffered.mod_height,
13185614e71bSYork Sun 			"mod_height    (Unbuffered) Module Nominal Height");
13195614e71bSYork Sun 		PRINT_NXS(61, spd->mod_section.unbuffered.mod_thickness,
13205614e71bSYork Sun 			"mod_thickness (Unbuffered) Module Maximum Thickness");
13215614e71bSYork Sun 		PRINT_NXS(62, spd->mod_section.unbuffered.ref_raw_card,
13225614e71bSYork Sun 			"ref_raw_card  (Unbuffered) Reference Raw Card Used");
13235614e71bSYork Sun 		PRINT_NXS(63, spd->mod_section.unbuffered.addr_mapping,
13245614e71bSYork Sun 			"addr_mapping  (Unbuffered) Address mapping from "
13255614e71bSYork Sun 			"Edge Connector to DRAM");
13265614e71bSYork Sun 		break;
13275614e71bSYork Sun 	case 0x01:  /* RDIMM */
13285614e71bSYork Sun 	case 0x05:  /* Mini-RDIMM */
13295614e71bSYork Sun 		PRINT_NXS(60, spd->mod_section.registered.mod_height,
13305614e71bSYork Sun 			"mod_height    (Registered) Module Nominal Height");
13315614e71bSYork Sun 		PRINT_NXS(61, spd->mod_section.registered.mod_thickness,
13325614e71bSYork Sun 			"mod_thickness (Registered) Module Maximum Thickness");
13335614e71bSYork Sun 		PRINT_NXS(62, spd->mod_section.registered.ref_raw_card,
13345614e71bSYork Sun 			"ref_raw_card  (Registered) Reference Raw Card Used");
13355614e71bSYork Sun 		PRINT_NXS(63, spd->mod_section.registered.modu_attr,
13365614e71bSYork Sun 			"modu_attr     (Registered) DIMM Module Attributes");
13375614e71bSYork Sun 		PRINT_NXS(64, spd->mod_section.registered.thermal,
13385614e71bSYork Sun 			"thermal       (Registered) Thermal Heat "
13395614e71bSYork Sun 			"Spreader Solution");
13405614e71bSYork Sun 		PRINT_NXS(65, spd->mod_section.registered.reg_id_lo,
13415614e71bSYork Sun 			"reg_id_lo     (Registered) Register Manufacturer ID "
13425614e71bSYork Sun 			"Code, LSB");
13435614e71bSYork Sun 		PRINT_NXS(66, spd->mod_section.registered.reg_id_hi,
13445614e71bSYork Sun 			"reg_id_hi     (Registered) Register Manufacturer ID "
13455614e71bSYork Sun 			"Code, MSB");
13465614e71bSYork Sun 		PRINT_NXS(67, spd->mod_section.registered.reg_rev,
13475614e71bSYork Sun 			"reg_rev       (Registered) Register "
13485614e71bSYork Sun 			"Revision Number");
13495614e71bSYork Sun 		PRINT_NXS(68, spd->mod_section.registered.reg_type,
13505614e71bSYork Sun 			"reg_type      (Registered) Register Type");
13515614e71bSYork Sun 		for (i = 69; i <= 76; i++) {
13525614e71bSYork Sun 			printf("%-3d    : %02x rcw[%d]\n", i,
13535614e71bSYork Sun 				spd->mod_section.registered.rcw[i-69], i-69);
13545614e71bSYork Sun 		}
13555614e71bSYork Sun 		break;
13565614e71bSYork Sun 	default:
13575614e71bSYork Sun 		/* Module-specific Section, Unsupported Module Type */
13585614e71bSYork Sun 		printf("%-3d-%3d: ", 60, 116);
13595614e71bSYork Sun 
13605614e71bSYork Sun 		for (i = 60; i <= 116; i++)
13615614e71bSYork Sun 			printf("%02x", spd->mod_section.uc[i - 60]);
13625614e71bSYork Sun 
13635614e71bSYork Sun 		break;
13645614e71bSYork Sun 	}
13655614e71bSYork Sun 
13665614e71bSYork Sun 	/* Unique Module ID: Bytes 117-125 */
13675614e71bSYork Sun 	PRINT_NXS(117, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106");
13685614e71bSYork Sun 	PRINT_NXS(118, spd->mmid_msb, "Module MfgID Code MSB - JEP-106");
13695614e71bSYork Sun 	PRINT_NXS(119, spd->mloc,     "Mfg Location");
13705614e71bSYork Sun 	PRINT_NNXXS(120, 121, spd->mdate[0], spd->mdate[1], "Mfg Date");
13715614e71bSYork Sun 
13725614e71bSYork Sun 	printf("%-3d-%3d: ", 122, 125);
13735614e71bSYork Sun 
13745614e71bSYork Sun 	for (i = 122; i <= 125; i++)
13755614e71bSYork Sun 		printf("%02x ", spd->sernum[i - 122]);
13765614e71bSYork Sun 	printf("   Module Serial Number\n");
13775614e71bSYork Sun 
13785614e71bSYork Sun 	/* CRC: Bytes 126-127 */
13795614e71bSYork Sun 	PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], "  SPD CRC");
13805614e71bSYork Sun 
13815614e71bSYork Sun 	/* Other Manufacturer Fields and User Space: Bytes 128-255 */
13825614e71bSYork Sun 	printf("%-3d-%3d: ", 128, 145);
13835614e71bSYork Sun 	for (i = 128; i <= 145; i++)
13845614e71bSYork Sun 		printf("%02x ", spd->mpart[i - 128]);
13855614e71bSYork Sun 	printf("   Mfg's Module Part Number\n");
13865614e71bSYork Sun 
13875614e71bSYork Sun 	PRINT_NNXXS(146, 147, spd->mrev[0], spd->mrev[1],
13885614e71bSYork Sun 		"Module Revision code");
13895614e71bSYork Sun 
13905614e71bSYork Sun 	PRINT_NXS(148, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106");
13915614e71bSYork Sun 	PRINT_NXS(149, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106");
13925614e71bSYork Sun 
13935614e71bSYork Sun 	printf("%-3d-%3d: ", 150, 175);
13945614e71bSYork Sun 	for (i = 150; i <= 175; i++)
13955614e71bSYork Sun 		printf("%02x ", spd->msd[i - 150]);
13965614e71bSYork Sun 	printf("   Mfg's Specific Data\n");
13975614e71bSYork Sun 
13985614e71bSYork Sun 	printf("%-3d-%3d: ", 176, 255);
13995614e71bSYork Sun 	for (i = 176; i <= 255; i++)
14005614e71bSYork Sun 		printf("%02x", spd->cust[i - 176]);
14015614e71bSYork Sun 	printf("   Mfg's Specific Data\n");
14025614e71bSYork Sun 
14035614e71bSYork Sun }
14045614e71bSYork Sun #endif
14055614e71bSYork Sun 
140634e026f9SYork Sun #ifdef CONFIG_SYS_FSL_DDR4
140734e026f9SYork Sun void ddr4_spd_dump(const struct ddr4_spd_eeprom_s *spd)
140834e026f9SYork Sun {
140934e026f9SYork Sun 	unsigned int i;
141034e026f9SYork Sun 
141134e026f9SYork Sun 	/* General Section: Bytes 0-127 */
141234e026f9SYork Sun 
141334e026f9SYork Sun #define PRINT_NXS(x, y, z...) printf("%-3d    : %02x " z "\n", x, (u8)y);
141434e026f9SYork Sun #define PRINT_NNXXS(n0, n1, x0, x1, s) \
141534e026f9SYork Sun 	printf("%-3d-%3d: %02x %02x " s "\n", n0, n1, x0, x1);
141634e026f9SYork Sun 
141734e026f9SYork Sun 	PRINT_NXS(0, spd->info_size_crc,
141834e026f9SYork Sun 		  "info_size_crc  bytes written into serial memory, CRC coverage");
141934e026f9SYork Sun 	PRINT_NXS(1, spd->spd_rev,
142034e026f9SYork Sun 		  "spd_rev        SPD Revision");
142134e026f9SYork Sun 	PRINT_NXS(2, spd->mem_type,
142234e026f9SYork Sun 		  "mem_type       Key Byte / DRAM Device Type");
142334e026f9SYork Sun 	PRINT_NXS(3, spd->module_type,
142434e026f9SYork Sun 		  "module_type    Key Byte / Module Type");
142534e026f9SYork Sun 	PRINT_NXS(4, spd->density_banks,
142634e026f9SYork Sun 		  "density_banks  SDRAM Density and Banks");
142734e026f9SYork Sun 	PRINT_NXS(5, spd->addressing,
142834e026f9SYork Sun 		  "addressing     SDRAM Addressing");
142934e026f9SYork Sun 	PRINT_NXS(6, spd->package_type,
143034e026f9SYork Sun 		  "package_type   Package type");
143134e026f9SYork Sun 	PRINT_NXS(7, spd->opt_feature,
143234e026f9SYork Sun 		  "opt_feature    Optional features");
143334e026f9SYork Sun 	PRINT_NXS(8, spd->thermal_ref,
143434e026f9SYork Sun 		  "thermal_ref    Thermal and Refresh options");
143534e026f9SYork Sun 	PRINT_NXS(9, spd->oth_opt_features,
143634e026f9SYork Sun 		  "oth_opt_features Other SDRAM optional features");
143734e026f9SYork Sun 	PRINT_NXS(10, spd->res_10,
143834e026f9SYork Sun 		  "res_10         Reserved");
143934e026f9SYork Sun 	PRINT_NXS(11, spd->module_vdd,
144034e026f9SYork Sun 		  "module_vdd     Module Nominal Voltage, VDD");
144134e026f9SYork Sun 	PRINT_NXS(12, spd->organization,
144234e026f9SYork Sun 		  "organization Module Organization");
144334e026f9SYork Sun 	PRINT_NXS(13, spd->bus_width,
144434e026f9SYork Sun 		  "bus_width      Module Memory Bus Width");
144534e026f9SYork Sun 	PRINT_NXS(14, spd->therm_sensor,
144634e026f9SYork Sun 		  "therm_sensor   Module Thermal Sensor");
144734e026f9SYork Sun 	PRINT_NXS(15, spd->ext_type,
144834e026f9SYork Sun 		  "ext_type       Extended module type");
144934e026f9SYork Sun 	PRINT_NXS(16, spd->res_16,
145034e026f9SYork Sun 		  "res_16       Reserved");
145134e026f9SYork Sun 	PRINT_NXS(17, spd->timebases,
145234e026f9SYork Sun 		  "timebases    MTb and FTB");
145334e026f9SYork Sun 	PRINT_NXS(18, spd->tck_min,
145434e026f9SYork Sun 		  "tck_min      tCKAVGmin");
145534e026f9SYork Sun 	PRINT_NXS(19, spd->tck_max,
145634e026f9SYork Sun 		  "tck_max      TCKAVGmax");
145734e026f9SYork Sun 	PRINT_NXS(20, spd->caslat_b1,
145834e026f9SYork Sun 		  "caslat_b1    CAS latencies, 1st byte");
145934e026f9SYork Sun 	PRINT_NXS(21, spd->caslat_b2,
146034e026f9SYork Sun 		  "caslat_b2    CAS latencies, 2nd byte");
146134e026f9SYork Sun 	PRINT_NXS(22, spd->caslat_b3,
146234e026f9SYork Sun 		  "caslat_b3    CAS latencies, 3rd byte ");
146334e026f9SYork Sun 	PRINT_NXS(23, spd->caslat_b4,
146434e026f9SYork Sun 		  "caslat_b4    CAS latencies, 4th byte");
146534e026f9SYork Sun 	PRINT_NXS(24, spd->taa_min,
146634e026f9SYork Sun 		  "taa_min      Min CAS Latency Time");
146734e026f9SYork Sun 	PRINT_NXS(25, spd->trcd_min,
146834e026f9SYork Sun 		  "trcd_min     Min RAS# to CAS# Delay Time");
146934e026f9SYork Sun 	PRINT_NXS(26, spd->trp_min,
147034e026f9SYork Sun 		  "trp_min      Min Row Precharge Delay Time");
147134e026f9SYork Sun 	PRINT_NXS(27, spd->tras_trc_ext,
147234e026f9SYork Sun 		  "tras_trc_ext Upper Nibbles for tRAS and tRC");
147334e026f9SYork Sun 	PRINT_NXS(28, spd->tras_min_lsb,
147434e026f9SYork Sun 		  "tras_min_lsb tRASmin, lsb");
147534e026f9SYork Sun 	PRINT_NXS(29, spd->trc_min_lsb,
147634e026f9SYork Sun 		  "trc_min_lsb  tRCmin, lsb");
147734e026f9SYork Sun 	PRINT_NXS(30, spd->trfc1_min_lsb,
147834e026f9SYork Sun 		  "trfc1_min_lsb  Min Refresh Recovery Delay Time, LSB");
147934e026f9SYork Sun 	PRINT_NXS(31, spd->trfc1_min_msb,
148034e026f9SYork Sun 		  "trfc1_min_msb  Min Refresh Recovery Delay Time, MSB ");
148134e026f9SYork Sun 	PRINT_NXS(32, spd->trfc2_min_lsb,
148234e026f9SYork Sun 		  "trfc2_min_lsb  Min Refresh Recovery Delay Time, LSB");
148334e026f9SYork Sun 	PRINT_NXS(33, spd->trfc2_min_msb,
148434e026f9SYork Sun 		  "trfc2_min_msb  Min Refresh Recovery Delay Time, MSB");
148534e026f9SYork Sun 	PRINT_NXS(34, spd->trfc4_min_lsb,
148634e026f9SYork Sun 		  "trfc4_min_lsb Min Refresh Recovery Delay Time, LSB");
148734e026f9SYork Sun 	PRINT_NXS(35, spd->trfc4_min_msb,
148834e026f9SYork Sun 		  "trfc4_min_msb Min Refresh Recovery Delay Time, MSB");
148934e026f9SYork Sun 	PRINT_NXS(36, spd->tfaw_msb,
149034e026f9SYork Sun 		  "tfaw_msb      Upper Nibble for tFAW");
149134e026f9SYork Sun 	PRINT_NXS(37, spd->tfaw_min,
149234e026f9SYork Sun 		  "tfaw_min      tFAW, lsb");
149334e026f9SYork Sun 	PRINT_NXS(38, spd->trrds_min,
149434e026f9SYork Sun 		  "trrds_min     tRRD_Smin, MTB");
149534e026f9SYork Sun 	PRINT_NXS(39, spd->trrdl_min,
149634e026f9SYork Sun 		  "trrdl_min     tRRD_Lmin, MTB");
149734e026f9SYork Sun 	PRINT_NXS(40, spd->tccdl_min,
149834e026f9SYork Sun 		  "tccdl_min     tCCS_Lmin, MTB");
149934e026f9SYork Sun 
150034e026f9SYork Sun 	printf("%-3d-%3d: ", 41, 59);  /* Reserved, General Section */
150134e026f9SYork Sun 	for (i = 41; i <= 59; i++)
150234e026f9SYork Sun 		printf("%02x ", spd->res_41[i - 41]);
150334e026f9SYork Sun 
150434e026f9SYork Sun 	puts("\n");
150534e026f9SYork Sun 	printf("%-3d-%3d: ", 60, 77);
150634e026f9SYork Sun 	for (i = 60; i <= 77; i++)
150734e026f9SYork Sun 		printf("%02x ", spd->mapping[i - 60]);
150834e026f9SYork Sun 	puts("   mapping[] Connector to SDRAM bit map\n");
150934e026f9SYork Sun 
151034e026f9SYork Sun 	PRINT_NXS(117, spd->fine_tccdl_min,
151134e026f9SYork Sun 		  "fine_tccdl_min Fine offset for tCCD_Lmin");
151234e026f9SYork Sun 	PRINT_NXS(118, spd->fine_trrdl_min,
151334e026f9SYork Sun 		  "fine_trrdl_min Fine offset for tRRD_Lmin");
151434e026f9SYork Sun 	PRINT_NXS(119, spd->fine_trrds_min,
151534e026f9SYork Sun 		  "fine_trrds_min Fine offset for tRRD_Smin");
151634e026f9SYork Sun 	PRINT_NXS(120, spd->fine_trc_min,
151734e026f9SYork Sun 		  "fine_trc_min   Fine offset for tRCmin");
151834e026f9SYork Sun 	PRINT_NXS(121, spd->fine_trp_min,
151934e026f9SYork Sun 		  "fine_trp_min   Fine offset for tRPmin");
152034e026f9SYork Sun 	PRINT_NXS(122, spd->fine_trcd_min,
152134e026f9SYork Sun 		  "fine_trcd_min  Fine offset for tRCDmin");
152234e026f9SYork Sun 	PRINT_NXS(123, spd->fine_taa_min,
152334e026f9SYork Sun 		  "fine_taa_min   Fine offset for tAAmin");
152434e026f9SYork Sun 	PRINT_NXS(124, spd->fine_tck_max,
152534e026f9SYork Sun 		  "fine_tck_max   Fine offset for tCKAVGmax");
152634e026f9SYork Sun 	PRINT_NXS(125, spd->fine_tck_min,
152734e026f9SYork Sun 		  "fine_tck_min   Fine offset for tCKAVGmin");
152834e026f9SYork Sun 
152934e026f9SYork Sun 	/* CRC: Bytes 126-127 */
153034e026f9SYork Sun 	PRINT_NNXXS(126, 127, spd->crc[0], spd->crc[1], "  SPD CRC");
153134e026f9SYork Sun 
153234e026f9SYork Sun 	switch (spd->module_type) {
153334e026f9SYork Sun 	case 0x02:  /* UDIMM */
153434e026f9SYork Sun 	case 0x03:  /* SO-DIMM */
153534e026f9SYork Sun 		PRINT_NXS(128, spd->mod_section.unbuffered.mod_height,
153634e026f9SYork Sun 			  "mod_height    (Unbuffered) Module Nominal Height");
153734e026f9SYork Sun 		PRINT_NXS(129, spd->mod_section.unbuffered.mod_thickness,
153834e026f9SYork Sun 			  "mod_thickness (Unbuffered) Module Maximum Thickness");
153934e026f9SYork Sun 		PRINT_NXS(130, spd->mod_section.unbuffered.ref_raw_card,
154034e026f9SYork Sun 			  "ref_raw_card  (Unbuffered) Reference Raw Card Used");
154134e026f9SYork Sun 		PRINT_NXS(131, spd->mod_section.unbuffered.addr_mapping,
154234e026f9SYork Sun 			  "addr_mapping  (Unbuffered) Address mapping from Edge Connector to DRAM");
154334e026f9SYork Sun 		PRINT_NNXXS(254, 255, spd->mod_section.unbuffered.crc[0],
154434e026f9SYork Sun 			    spd->mod_section.unbuffered.crc[1], "  Module CRC");
154534e026f9SYork Sun 		break;
154634e026f9SYork Sun 	case 0x01:  /* RDIMM */
154734e026f9SYork Sun 		PRINT_NXS(128, spd->mod_section.registered.mod_height,
154834e026f9SYork Sun 			  "mod_height    (Registered) Module Nominal Height");
154934e026f9SYork Sun 		PRINT_NXS(129, spd->mod_section.registered.mod_thickness,
155034e026f9SYork Sun 			  "mod_thickness (Registered) Module Maximum Thickness");
155134e026f9SYork Sun 		PRINT_NXS(130, spd->mod_section.registered.ref_raw_card,
155234e026f9SYork Sun 			  "ref_raw_card  (Registered) Reference Raw Card Used");
155334e026f9SYork Sun 		PRINT_NXS(131, spd->mod_section.registered.modu_attr,
155434e026f9SYork Sun 			  "modu_attr     (Registered) DIMM Module Attributes");
155534e026f9SYork Sun 		PRINT_NXS(132, spd->mod_section.registered.thermal,
155634e026f9SYork Sun 			  "thermal       (Registered) Thermal Heat Spreader Solution");
155734e026f9SYork Sun 		PRINT_NXS(133, spd->mod_section.registered.reg_id_lo,
155834e026f9SYork Sun 			  "reg_id_lo     (Registered) Register Manufacturer ID Code, LSB");
155934e026f9SYork Sun 		PRINT_NXS(134, spd->mod_section.registered.reg_id_hi,
156034e026f9SYork Sun 			  "reg_id_hi     (Registered) Register Manufacturer ID Code, MSB");
156134e026f9SYork Sun 		PRINT_NXS(135, spd->mod_section.registered.reg_rev,
156234e026f9SYork Sun 			  "reg_rev       (Registered) Register Revision Number");
156334e026f9SYork Sun 		PRINT_NXS(136, spd->mod_section.registered.reg_map,
156434e026f9SYork Sun 			  "reg_map       (Registered) Address mapping");
156534e026f9SYork Sun 		PRINT_NNXXS(254, 255, spd->mod_section.registered.crc[0],
156634e026f9SYork Sun 			    spd->mod_section.registered.crc[1], "  Module CRC");
156734e026f9SYork Sun 		break;
156834e026f9SYork Sun 	case 0x04:  /* LRDIMM */
156934e026f9SYork Sun 		PRINT_NXS(128, spd->mod_section.loadreduced.mod_height,
157034e026f9SYork Sun 			  "mod_height    (Loadreduced) Module Nominal Height");
157134e026f9SYork Sun 		PRINT_NXS(129, spd->mod_section.loadreduced.mod_thickness,
157234e026f9SYork Sun 			  "mod_thickness (Loadreduced) Module Maximum Thickness");
157334e026f9SYork Sun 		PRINT_NXS(130, spd->mod_section.loadreduced.ref_raw_card,
157434e026f9SYork Sun 			  "ref_raw_card  (Loadreduced) Reference Raw Card Used");
157534e026f9SYork Sun 		PRINT_NXS(131, spd->mod_section.loadreduced.modu_attr,
157634e026f9SYork Sun 			  "modu_attr     (Loadreduced) DIMM Module Attributes");
157734e026f9SYork Sun 		PRINT_NXS(132, spd->mod_section.loadreduced.thermal,
157834e026f9SYork Sun 			  "thermal       (Loadreduced) Thermal Heat Spreader Solution");
157934e026f9SYork Sun 		PRINT_NXS(133, spd->mod_section.loadreduced.reg_id_lo,
158034e026f9SYork Sun 			  "reg_id_lo     (Loadreduced) Register Manufacturer ID Code, LSB");
158134e026f9SYork Sun 		PRINT_NXS(134, spd->mod_section.loadreduced.reg_id_hi,
158234e026f9SYork Sun 			  "reg_id_hi     (Loadreduced) Register Manufacturer ID Code, MSB");
158334e026f9SYork Sun 		PRINT_NXS(135, spd->mod_section.loadreduced.reg_rev,
158434e026f9SYork Sun 			  "reg_rev       (Loadreduced) Register Revision Number");
158534e026f9SYork Sun 		PRINT_NXS(136, spd->mod_section.loadreduced.reg_map,
158634e026f9SYork Sun 			  "reg_map       (Loadreduced) Address mapping");
158734e026f9SYork Sun 		PRINT_NXS(137, spd->mod_section.loadreduced.reg_drv,
158834e026f9SYork Sun 			  "reg_drv       (Loadreduced) Reg output drive strength");
158934e026f9SYork Sun 		PRINT_NXS(138, spd->mod_section.loadreduced.reg_drv_ck,
159034e026f9SYork Sun 			  "reg_drv_ck    (Loadreduced) Reg output drive strength for CK");
159134e026f9SYork Sun 		PRINT_NXS(139, spd->mod_section.loadreduced.data_buf_rev,
159234e026f9SYork Sun 			  "data_buf_rev  (Loadreduced) Data Buffer Revision Numbe");
159334e026f9SYork Sun 		PRINT_NXS(140, spd->mod_section.loadreduced.vrefqe_r0,
159434e026f9SYork Sun 			  "vrefqe_r0     (Loadreduced) DRAM VrefDQ for Package Rank 0");
159534e026f9SYork Sun 		PRINT_NXS(141, spd->mod_section.loadreduced.vrefqe_r1,
159634e026f9SYork Sun 			  "vrefqe_r1     (Loadreduced) DRAM VrefDQ for Package Rank 1");
159734e026f9SYork Sun 		PRINT_NXS(142, spd->mod_section.loadreduced.vrefqe_r2,
159834e026f9SYork Sun 			  "vrefqe_r2     (Loadreduced) DRAM VrefDQ for Package Rank 2");
159934e026f9SYork Sun 		PRINT_NXS(143, spd->mod_section.loadreduced.vrefqe_r3,
160034e026f9SYork Sun 			  "vrefqe_r3     (Loadreduced) DRAM VrefDQ for Package Rank 3");
160134e026f9SYork Sun 		PRINT_NXS(144, spd->mod_section.loadreduced.data_intf,
160234e026f9SYork Sun 			  "data_intf     (Loadreduced) Data Buffer VrefDQ for DRAM Interface");
160334e026f9SYork Sun 		PRINT_NXS(145, spd->mod_section.loadreduced.data_drv_1866,
160434e026f9SYork Sun 			  "data_drv_1866 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
160534e026f9SYork Sun 		PRINT_NXS(146, spd->mod_section.loadreduced.data_drv_2400,
160634e026f9SYork Sun 			  "data_drv_2400 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
160734e026f9SYork Sun 		PRINT_NXS(147, spd->mod_section.loadreduced.data_drv_3200,
160834e026f9SYork Sun 			  "data_drv_3200 (Loadreduced) Data Buffer MDQ Drive Strength and RTT");
160934e026f9SYork Sun 		PRINT_NXS(148, spd->mod_section.loadreduced.dram_drv,
161034e026f9SYork Sun 			  "dram_drv      (Loadreduced) DRAM Drive Strength");
161134e026f9SYork Sun 		PRINT_NXS(149, spd->mod_section.loadreduced.dram_odt_1866,
161234e026f9SYork Sun 			  "dram_odt_1866 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
161334e026f9SYork Sun 		PRINT_NXS(150, spd->mod_section.loadreduced.dram_odt_2400,
161434e026f9SYork Sun 			  "dram_odt_2400 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
161534e026f9SYork Sun 		PRINT_NXS(151, spd->mod_section.loadreduced.dram_odt_3200,
161634e026f9SYork Sun 			  "dram_odt_3200 (Loadreduced) DRAM ODT (RTT_WR, RTT_NOM)");
161734e026f9SYork Sun 		PRINT_NXS(152, spd->mod_section.loadreduced.dram_odt_park_1866,
161834e026f9SYork Sun 			  "dram_odt_park_1866 (Loadreduced) DRAM ODT (RTT_PARK)");
161934e026f9SYork Sun 		PRINT_NXS(153, spd->mod_section.loadreduced.dram_odt_park_2400,
162034e026f9SYork Sun 			  "dram_odt_park_2400 (Loadreduced) DRAM ODT (RTT_PARK)");
162134e026f9SYork Sun 		PRINT_NXS(154, spd->mod_section.loadreduced.dram_odt_park_3200,
162234e026f9SYork Sun 			  "dram_odt_park_3200 (Loadreduced) DRAM ODT (RTT_PARK)");
162334e026f9SYork Sun 		PRINT_NNXXS(254, 255, spd->mod_section.loadreduced.crc[0],
162434e026f9SYork Sun 			    spd->mod_section.loadreduced.crc[1],
162534e026f9SYork Sun 			    "  Module CRC");
162634e026f9SYork Sun 		break;
162734e026f9SYork Sun 	default:
162834e026f9SYork Sun 		/* Module-specific Section, Unsupported Module Type */
162934e026f9SYork Sun 		printf("%-3d-%3d: ", 128, 255);
163034e026f9SYork Sun 
163134e026f9SYork Sun 		for (i = 128; i <= 255; i++)
1632353527d5SYork Sun 			printf("%02x", spd->mod_section.uc[i - 128]);
163334e026f9SYork Sun 
163434e026f9SYork Sun 		break;
163534e026f9SYork Sun 	}
163634e026f9SYork Sun 
163734e026f9SYork Sun 	/* Unique Module ID: Bytes 320-383 */
163834e026f9SYork Sun 	PRINT_NXS(320, spd->mmid_lsb, "Module MfgID Code LSB - JEP-106");
163934e026f9SYork Sun 	PRINT_NXS(321, spd->mmid_msb, "Module MfgID Code MSB - JEP-106");
164034e026f9SYork Sun 	PRINT_NXS(322, spd->mloc,     "Mfg Location");
164134e026f9SYork Sun 	PRINT_NNXXS(323, 324, spd->mdate[0], spd->mdate[1], "Mfg Date");
164234e026f9SYork Sun 
164334e026f9SYork Sun 	printf("%-3d-%3d: ", 325, 328);
164434e026f9SYork Sun 
164534e026f9SYork Sun 	for (i = 325; i <= 328; i++)
164634e026f9SYork Sun 		printf("%02x ", spd->sernum[i - 325]);
164734e026f9SYork Sun 	printf("   Module Serial Number\n");
164834e026f9SYork Sun 
164934e026f9SYork Sun 	printf("%-3d-%3d: ", 329, 348);
165034e026f9SYork Sun 	for (i = 329; i <= 348; i++)
165134e026f9SYork Sun 		printf("%02x ", spd->mpart[i - 329]);
165234e026f9SYork Sun 	printf("   Mfg's Module Part Number\n");
165334e026f9SYork Sun 
165434e026f9SYork Sun 	PRINT_NXS(349, spd->mrev, "Module Revision code");
165534e026f9SYork Sun 	PRINT_NXS(350, spd->dmid_lsb, "DRAM MfgID Code LSB - JEP-106");
165634e026f9SYork Sun 	PRINT_NXS(351, spd->dmid_msb, "DRAM MfgID Code MSB - JEP-106");
165734e026f9SYork Sun 	PRINT_NXS(352, spd->stepping, "DRAM stepping");
165834e026f9SYork Sun 
165934e026f9SYork Sun 	printf("%-3d-%3d: ", 353, 381);
166034e026f9SYork Sun 	for (i = 353; i <= 381; i++)
166134e026f9SYork Sun 		printf("%02x ", spd->msd[i - 353]);
166234e026f9SYork Sun 	printf("   Mfg's Specific Data\n");
166334e026f9SYork Sun }
166434e026f9SYork Sun #endif
166534e026f9SYork Sun 
16665614e71bSYork Sun static inline void generic_spd_dump(const generic_spd_eeprom_t *spd)
16675614e71bSYork Sun {
16685614e71bSYork Sun #if defined(CONFIG_SYS_FSL_DDR1)
16695614e71bSYork Sun 	ddr1_spd_dump(spd);
16705614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR2)
16715614e71bSYork Sun 	ddr2_spd_dump(spd);
16725614e71bSYork Sun #elif defined(CONFIG_SYS_FSL_DDR3)
16735614e71bSYork Sun 	ddr3_spd_dump(spd);
167434e026f9SYork Sun #elif defined(CONFIG_SYS_FSL_DDR4)
167534e026f9SYork Sun 	ddr4_spd_dump(spd);
16765614e71bSYork Sun #endif
16775614e71bSYork Sun }
16785614e71bSYork Sun 
16795614e71bSYork Sun static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo,
16805614e71bSYork Sun 			unsigned int ctrl_mask,
16815614e71bSYork Sun 			unsigned int dimm_mask,
16825614e71bSYork Sun 			unsigned int do_mask)
16835614e71bSYork Sun {
16845614e71bSYork Sun 	unsigned int i, j, retval;
16855614e71bSYork Sun 
16865614e71bSYork Sun 	/* STEP 1:  DIMM SPD data */
16875614e71bSYork Sun 	if (do_mask & STEP_GET_SPD) {
16885614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
16895614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
16905614e71bSYork Sun 				continue;
16915614e71bSYork Sun 
16925614e71bSYork Sun 			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
16935614e71bSYork Sun 				if (!(dimm_mask & (1 << j)))
16945614e71bSYork Sun 					continue;
16955614e71bSYork Sun 
16965614e71bSYork Sun 				printf("SPD info:  Controller=%u "
16975614e71bSYork Sun 						"DIMM=%u\n", i, j);
16985614e71bSYork Sun 				generic_spd_dump(
16995614e71bSYork Sun 					&(pinfo->spd_installed_dimms[i][j]));
17005614e71bSYork Sun 				printf("\n");
17015614e71bSYork Sun 			}
17025614e71bSYork Sun 			printf("\n");
17035614e71bSYork Sun 		}
17045614e71bSYork Sun 		printf("\n");
17055614e71bSYork Sun 	}
17065614e71bSYork Sun 
17075614e71bSYork Sun 	/* STEP 2:  DIMM Parameters */
17085614e71bSYork Sun 	if (do_mask & STEP_COMPUTE_DIMM_PARMS) {
17095614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
17105614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
17115614e71bSYork Sun 				continue;
17125614e71bSYork Sun 			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
17135614e71bSYork Sun 				if (!(dimm_mask & (1 << j)))
17145614e71bSYork Sun 					continue;
17155614e71bSYork Sun 				printf("DIMM parameters:  Controller=%u "
17165614e71bSYork Sun 						"DIMM=%u\n", i, j);
17175614e71bSYork Sun 				print_dimm_parameters(
17185614e71bSYork Sun 					&(pinfo->dimm_params[i][j]));
17195614e71bSYork Sun 				printf("\n");
17205614e71bSYork Sun 			}
17215614e71bSYork Sun 			printf("\n");
17225614e71bSYork Sun 		}
17235614e71bSYork Sun 		printf("\n");
17245614e71bSYork Sun 	}
17255614e71bSYork Sun 
17265614e71bSYork Sun 	/* STEP 3:  Common Parameters */
17275614e71bSYork Sun 	if (do_mask & STEP_COMPUTE_COMMON_PARMS) {
17285614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
17295614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
17305614e71bSYork Sun 				continue;
17315614e71bSYork Sun 			printf("\"lowest common\" DIMM parameters:  "
17325614e71bSYork Sun 					"Controller=%u\n", i);
17335614e71bSYork Sun 			print_lowest_common_dimm_parameters(
17345614e71bSYork Sun 				&pinfo->common_timing_params[i]);
17355614e71bSYork Sun 			printf("\n");
17365614e71bSYork Sun 		}
17375614e71bSYork Sun 		printf("\n");
17385614e71bSYork Sun 	}
17395614e71bSYork Sun 
17405614e71bSYork Sun 	/* STEP 4:  User Configuration Options */
17415614e71bSYork Sun 	if (do_mask & STEP_GATHER_OPTS) {
17425614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
17435614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
17445614e71bSYork Sun 				continue;
17455614e71bSYork Sun 			printf("User Config Options: Controller=%u\n", i);
17465614e71bSYork Sun 			print_memctl_options(&pinfo->memctl_opts[i]);
17475614e71bSYork Sun 			printf("\n");
17485614e71bSYork Sun 		}
17495614e71bSYork Sun 		printf("\n");
17505614e71bSYork Sun 	}
17515614e71bSYork Sun 
17525614e71bSYork Sun 	/* STEP 5:  Address assignment */
17535614e71bSYork Sun 	if (do_mask & STEP_ASSIGN_ADDRESSES) {
17545614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
17555614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
17565614e71bSYork Sun 				continue;
17575614e71bSYork Sun 			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
17585614e71bSYork Sun 				printf("Address Assignment: Controller=%u "
17595614e71bSYork Sun 						"DIMM=%u\n", i, j);
17605614e71bSYork Sun 				printf("Don't have this functionality yet\n");
17615614e71bSYork Sun 			}
17625614e71bSYork Sun 			printf("\n");
17635614e71bSYork Sun 		}
17645614e71bSYork Sun 		printf("\n");
17655614e71bSYork Sun 	}
17665614e71bSYork Sun 
17675614e71bSYork Sun 	/* STEP 6:  computed controller register values */
17685614e71bSYork Sun 	if (do_mask & STEP_COMPUTE_REGS) {
17695614e71bSYork Sun 		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
17705614e71bSYork Sun 			if (!(ctrl_mask & (1 << i)))
17715614e71bSYork Sun 				continue;
17725614e71bSYork Sun 			printf("Computed Register Values: Controller=%u\n", i);
17735614e71bSYork Sun 			print_fsl_memctl_config_regs(
17745614e71bSYork Sun 				&pinfo->fsl_ddr_config_reg[i]);
17755614e71bSYork Sun 			retval = check_fsl_memctl_config_regs(
17765614e71bSYork Sun 				&pinfo->fsl_ddr_config_reg[i]);
17775614e71bSYork Sun 			if (retval) {
17785614e71bSYork Sun 				printf("check_fsl_memctl_config_regs "
17795614e71bSYork Sun 					"result = %u\n", retval);
17805614e71bSYork Sun 			}
17815614e71bSYork Sun 			printf("\n");
17825614e71bSYork Sun 		}
17835614e71bSYork Sun 		printf("\n");
17845614e71bSYork Sun 	}
17855614e71bSYork Sun }
17865614e71bSYork Sun 
17875614e71bSYork Sun struct data_strings {
17885614e71bSYork Sun 	const char *data_name;
17895614e71bSYork Sun 	unsigned int step_mask;
17905614e71bSYork Sun 	unsigned int dimm_number_required;
17915614e71bSYork Sun };
17925614e71bSYork Sun 
17935614e71bSYork Sun #define DATA_OPTIONS(name, step, dimm) {#name, step, dimm}
17945614e71bSYork Sun 
17955614e71bSYork Sun static unsigned int fsl_ddr_parse_interactive_cmd(
17965614e71bSYork Sun 	char **argv,
17975614e71bSYork Sun 	int argc,
17985614e71bSYork Sun 	unsigned int *pstep_mask,
17995614e71bSYork Sun 	unsigned int *pctlr_mask,
18005614e71bSYork Sun 	unsigned int *pdimm_mask,
18015614e71bSYork Sun 	unsigned int *pdimm_number_required
18025614e71bSYork Sun 	 ) {
18035614e71bSYork Sun 
18045614e71bSYork Sun 	static const struct data_strings options[] = {
18055614e71bSYork Sun 		DATA_OPTIONS(spd, STEP_GET_SPD, 1),
18065614e71bSYork Sun 		DATA_OPTIONS(dimmparms, STEP_COMPUTE_DIMM_PARMS, 1),
18075614e71bSYork Sun 		DATA_OPTIONS(commonparms, STEP_COMPUTE_COMMON_PARMS, 0),
18085614e71bSYork Sun 		DATA_OPTIONS(opts, STEP_GATHER_OPTS, 0),
18095614e71bSYork Sun 		DATA_OPTIONS(addresses, STEP_ASSIGN_ADDRESSES, 0),
18105614e71bSYork Sun 		DATA_OPTIONS(regs, STEP_COMPUTE_REGS, 0),
18115614e71bSYork Sun 	};
18125614e71bSYork Sun 	static const unsigned int n_opts = ARRAY_SIZE(options);
18135614e71bSYork Sun 
18145614e71bSYork Sun 	unsigned int i, j;
18155614e71bSYork Sun 	unsigned int error = 0;
18165614e71bSYork Sun 
18175614e71bSYork Sun 	for (i = 1; i < argc; i++) {
18185614e71bSYork Sun 		unsigned int matched = 0;
18195614e71bSYork Sun 
18205614e71bSYork Sun 		for (j = 0; j < n_opts; j++) {
18215614e71bSYork Sun 			if (strcmp(options[j].data_name, argv[i]) != 0)
18225614e71bSYork Sun 				continue;
18235614e71bSYork Sun 			*pstep_mask |= options[j].step_mask;
18245614e71bSYork Sun 			*pdimm_number_required =
18255614e71bSYork Sun 				options[j].dimm_number_required;
18265614e71bSYork Sun 			matched = 1;
18275614e71bSYork Sun 			break;
18285614e71bSYork Sun 		}
18295614e71bSYork Sun 
18305614e71bSYork Sun 		if (matched)
18315614e71bSYork Sun 			continue;
18325614e71bSYork Sun 
18335614e71bSYork Sun 		if (argv[i][0] == 'c') {
18345614e71bSYork Sun 			char c = argv[i][1];
18355614e71bSYork Sun 			if (isdigit(c))
18365614e71bSYork Sun 				*pctlr_mask |= 1 << (c - '0');
18375614e71bSYork Sun 			continue;
18385614e71bSYork Sun 		}
18395614e71bSYork Sun 
18405614e71bSYork Sun 		if (argv[i][0] == 'd') {
18415614e71bSYork Sun 			char c = argv[i][1];
18425614e71bSYork Sun 			if (isdigit(c))
18435614e71bSYork Sun 				*pdimm_mask |= 1 << (c - '0');
18445614e71bSYork Sun 			continue;
18455614e71bSYork Sun 		}
18465614e71bSYork Sun 
18475614e71bSYork Sun 		printf("unknown arg %s\n", argv[i]);
18485614e71bSYork Sun 		*pstep_mask = 0;
18495614e71bSYork Sun 		error = 1;
18505614e71bSYork Sun 		break;
18515614e71bSYork Sun 	}
18525614e71bSYork Sun 
18535614e71bSYork Sun 	return error;
18545614e71bSYork Sun }
18555614e71bSYork Sun 
18565614e71bSYork Sun int fsl_ddr_interactive_env_var_exists(void)
18575614e71bSYork Sun {
18585614e71bSYork Sun 	char buffer[CONFIG_SYS_CBSIZE];
18595614e71bSYork Sun 
18605614e71bSYork Sun 	if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0)
18615614e71bSYork Sun 		return 1;
18625614e71bSYork Sun 
18635614e71bSYork Sun 	return 0;
18645614e71bSYork Sun }
18655614e71bSYork Sun 
18665614e71bSYork Sun unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set)
18675614e71bSYork Sun {
18685614e71bSYork Sun 	unsigned long long ddrsize;
18695614e71bSYork Sun 	const char *prompt = "FSL DDR>";
18705614e71bSYork Sun 	char buffer[CONFIG_SYS_CBSIZE];
18715614e71bSYork Sun 	char buffer2[CONFIG_SYS_CBSIZE];
18725614e71bSYork Sun 	char *p = NULL;
18735614e71bSYork Sun 	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated */
18745614e71bSYork Sun 	int argc;
18755614e71bSYork Sun 	unsigned int next_step = STEP_GET_SPD;
18765614e71bSYork Sun 	const char *usage = {
18775614e71bSYork Sun 		"commands:\n"
18785614e71bSYork Sun 		"print      print SPD and intermediate computed data\n"
18795614e71bSYork Sun 		"reset      reboot machine\n"
18805614e71bSYork Sun 		"recompute  reload SPD and options to default and recompute regs\n"
18815614e71bSYork Sun 		"edit       modify spd, parameter, or option\n"
18825614e71bSYork Sun 		"compute    recompute registers from current next_step to end\n"
18835614e71bSYork Sun 		"copy       copy parameters\n"
18845614e71bSYork Sun 		"next_step  shows current next_step\n"
18855614e71bSYork Sun 		"help       this message\n"
18865614e71bSYork Sun 		"go         program the memory controller and continue with u-boot\n"
18875614e71bSYork Sun 	};
18885614e71bSYork Sun 
18895614e71bSYork Sun 	if (var_is_set) {
18905614e71bSYork Sun 		if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) {
18915614e71bSYork Sun 			p = buffer2;
18925614e71bSYork Sun 		} else {
18935614e71bSYork Sun 			var_is_set = 0;
18945614e71bSYork Sun 		}
18955614e71bSYork Sun 	}
18965614e71bSYork Sun 
18975614e71bSYork Sun 	/*
18985614e71bSYork Sun 	 * The strategy for next_step is that it points to the next
18995614e71bSYork Sun 	 * step in the computation process that needs to be done.
19005614e71bSYork Sun 	 */
19015614e71bSYork Sun 	while (1) {
19025614e71bSYork Sun 		if (var_is_set) {
19035614e71bSYork Sun 			char *pend = strchr(p, ';');
19045614e71bSYork Sun 			if (pend) {
19055614e71bSYork Sun 				/* found command separator, copy sub-command */
19065614e71bSYork Sun 				*pend = '\0';
19075614e71bSYork Sun 				strcpy(buffer, p);
19085614e71bSYork Sun 				p = pend + 1;
19095614e71bSYork Sun 			} else {
19105614e71bSYork Sun 				/* separator not found, copy whole string */
19115614e71bSYork Sun 				strcpy(buffer, p);
19125614e71bSYork Sun 				p = NULL;
19135614e71bSYork Sun 				var_is_set = 0;
19145614e71bSYork Sun 			}
19155614e71bSYork Sun 		} else {
19165614e71bSYork Sun 			/*
19175614e71bSYork Sun 			 * No need to worry for buffer overflow here in
1918e1bf824dSSimon Glass 			 * this function;  cli_readline() maxes out at
1919e1bf824dSSimon Glass 			 * CFG_CBSIZE
19205614e71bSYork Sun 			 */
1921e1bf824dSSimon Glass 			cli_readline_into_buffer(prompt, buffer, 0);
19225614e71bSYork Sun 		}
1923e1bf824dSSimon Glass 		argc = cli_simple_parse_line(buffer, argv);
19245614e71bSYork Sun 		if (argc == 0)
19255614e71bSYork Sun 			continue;
19265614e71bSYork Sun 
19275614e71bSYork Sun 
19285614e71bSYork Sun 		if (strcmp(argv[0], "help") == 0) {
19295614e71bSYork Sun 			puts(usage);
19305614e71bSYork Sun 			continue;
19315614e71bSYork Sun 		}
19325614e71bSYork Sun 
19335614e71bSYork Sun 		if (strcmp(argv[0], "next_step") == 0) {
19345614e71bSYork Sun 			printf("next_step = 0x%02X (%s)\n",
19355614e71bSYork Sun 			       next_step,
19365614e71bSYork Sun 			       step_to_string(next_step));
19375614e71bSYork Sun 			continue;
19385614e71bSYork Sun 		}
19395614e71bSYork Sun 
19405614e71bSYork Sun 		if (strcmp(argv[0], "copy") == 0) {
19415614e71bSYork Sun 			unsigned int error = 0;
19425614e71bSYork Sun 			unsigned int step_mask = 0;
19435614e71bSYork Sun 			unsigned int src_ctlr_mask = 0;
19445614e71bSYork Sun 			unsigned int src_dimm_mask = 0;
19455614e71bSYork Sun 			unsigned int dimm_number_required = 0;
19465614e71bSYork Sun 			unsigned int src_ctlr_num = 0;
19475614e71bSYork Sun 			unsigned int src_dimm_num = 0;
19485614e71bSYork Sun 			unsigned int dst_ctlr_num = -1;
19495614e71bSYork Sun 			unsigned int dst_dimm_num = -1;
19505614e71bSYork Sun 			unsigned int i, num_dest_parms;
19515614e71bSYork Sun 
19525614e71bSYork Sun 			if (argc == 1) {
19535614e71bSYork Sun 				printf("copy <src c#> <src d#> <spd|dimmparms|commonparms|opts|addresses|regs> <dst c#> <dst d#>\n");
19545614e71bSYork Sun 				continue;
19555614e71bSYork Sun 			}
19565614e71bSYork Sun 
19575614e71bSYork Sun 			error = fsl_ddr_parse_interactive_cmd(
19585614e71bSYork Sun 				argv, argc,
19595614e71bSYork Sun 				&step_mask,
19605614e71bSYork Sun 				&src_ctlr_mask,
19615614e71bSYork Sun 				&src_dimm_mask,
19625614e71bSYork Sun 				&dimm_number_required
19635614e71bSYork Sun 			);
19645614e71bSYork Sun 
19655614e71bSYork Sun 			/* XXX: only dimm_number_required and step_mask will
19665614e71bSYork Sun 			   be used by this function.  Parse the controller and
19675614e71bSYork Sun 			   DIMM number separately because it is easier.  */
19685614e71bSYork Sun 
19695614e71bSYork Sun 			if (error)
19705614e71bSYork Sun 				continue;
19715614e71bSYork Sun 
19725614e71bSYork Sun 			/* parse source destination controller / DIMM */
19735614e71bSYork Sun 
19745614e71bSYork Sun 			num_dest_parms = dimm_number_required ? 2 : 1;
19755614e71bSYork Sun 
19765614e71bSYork Sun 			for (i = 0; i < argc; i++) {
19775614e71bSYork Sun 				if (argv[i][0] == 'c') {
19785614e71bSYork Sun 					char c = argv[i][1];
19795614e71bSYork Sun 					if (isdigit(c)) {
19805614e71bSYork Sun 						src_ctlr_num = (c - '0');
19815614e71bSYork Sun 						break;
19825614e71bSYork Sun 					}
19835614e71bSYork Sun 				}
19845614e71bSYork Sun 			}
19855614e71bSYork Sun 
19865614e71bSYork Sun 			for (i = 0; i < argc; i++) {
19875614e71bSYork Sun 				if (argv[i][0] == 'd') {
19885614e71bSYork Sun 					char c = argv[i][1];
19895614e71bSYork Sun 					if (isdigit(c)) {
19905614e71bSYork Sun 						src_dimm_num = (c - '0');
19915614e71bSYork Sun 						break;
19925614e71bSYork Sun 					}
19935614e71bSYork Sun 				}
19945614e71bSYork Sun 			}
19955614e71bSYork Sun 
19965614e71bSYork Sun 			/* parse destination controller / DIMM */
19975614e71bSYork Sun 
19985614e71bSYork Sun 			for (i = argc - 1; i >= argc - num_dest_parms; i--) {
19995614e71bSYork Sun 				if (argv[i][0] == 'c') {
20005614e71bSYork Sun 					char c = argv[i][1];
20015614e71bSYork Sun 					if (isdigit(c)) {
20025614e71bSYork Sun 						dst_ctlr_num = (c - '0');
20035614e71bSYork Sun 						break;
20045614e71bSYork Sun 					}
20055614e71bSYork Sun 				}
20065614e71bSYork Sun 			}
20075614e71bSYork Sun 
20085614e71bSYork Sun 			for (i = argc - 1; i >= argc - num_dest_parms; i--) {
20095614e71bSYork Sun 				if (argv[i][0] == 'd') {
20105614e71bSYork Sun 					char c = argv[i][1];
20115614e71bSYork Sun 					if (isdigit(c)) {
20125614e71bSYork Sun 						dst_dimm_num = (c - '0');
20135614e71bSYork Sun 						break;
20145614e71bSYork Sun 					}
20155614e71bSYork Sun 				}
20165614e71bSYork Sun 			}
20175614e71bSYork Sun 
20185614e71bSYork Sun 			/* TODO: validate inputs */
20195614e71bSYork Sun 
20205614e71bSYork Sun 			debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n",
20215614e71bSYork Sun 				src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask);
20225614e71bSYork Sun 
20235614e71bSYork Sun 
20245614e71bSYork Sun 			switch (step_mask) {
20255614e71bSYork Sun 
20265614e71bSYork Sun 			case STEP_GET_SPD:
20275614e71bSYork Sun 				memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]),
20285614e71bSYork Sun 					&(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]),
20295614e71bSYork Sun 					sizeof(pinfo->spd_installed_dimms[0][0]));
20305614e71bSYork Sun 				break;
20315614e71bSYork Sun 
20325614e71bSYork Sun 			case STEP_COMPUTE_DIMM_PARMS:
20335614e71bSYork Sun 				memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]),
20345614e71bSYork Sun 					&(pinfo->dimm_params[src_ctlr_num][src_dimm_num]),
20355614e71bSYork Sun 					sizeof(pinfo->dimm_params[0][0]));
20365614e71bSYork Sun 				break;
20375614e71bSYork Sun 
20385614e71bSYork Sun 			case STEP_COMPUTE_COMMON_PARMS:
20395614e71bSYork Sun 				memcpy(&(pinfo->common_timing_params[dst_ctlr_num]),
20405614e71bSYork Sun 					&(pinfo->common_timing_params[src_ctlr_num]),
20415614e71bSYork Sun 					sizeof(pinfo->common_timing_params[0]));
20425614e71bSYork Sun 				break;
20435614e71bSYork Sun 
20445614e71bSYork Sun 			case STEP_GATHER_OPTS:
20455614e71bSYork Sun 				memcpy(&(pinfo->memctl_opts[dst_ctlr_num]),
20465614e71bSYork Sun 					&(pinfo->memctl_opts[src_ctlr_num]),
20475614e71bSYork Sun 					sizeof(pinfo->memctl_opts[0]));
20485614e71bSYork Sun 				break;
20495614e71bSYork Sun 
20505614e71bSYork Sun 			/* someday be able to have addresses to copy addresses... */
20515614e71bSYork Sun 
20525614e71bSYork Sun 			case STEP_COMPUTE_REGS:
20535614e71bSYork Sun 				memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]),
20545614e71bSYork Sun 					&(pinfo->fsl_ddr_config_reg[src_ctlr_num]),
20555614e71bSYork Sun 					sizeof(pinfo->memctl_opts[0]));
20565614e71bSYork Sun 				break;
20575614e71bSYork Sun 
20585614e71bSYork Sun 			default:
20595614e71bSYork Sun 				printf("unexpected step_mask value\n");
20605614e71bSYork Sun 			}
20615614e71bSYork Sun 
20625614e71bSYork Sun 			continue;
20635614e71bSYork Sun 
20645614e71bSYork Sun 		}
20655614e71bSYork Sun 
20665614e71bSYork Sun 		if (strcmp(argv[0], "edit") == 0) {
20675614e71bSYork Sun 			unsigned int error = 0;
20685614e71bSYork Sun 			unsigned int step_mask = 0;
20695614e71bSYork Sun 			unsigned int ctlr_mask = 0;
20705614e71bSYork Sun 			unsigned int dimm_mask = 0;
20715614e71bSYork Sun 			char *p_element = NULL;
20725614e71bSYork Sun 			char *p_value = NULL;
20735614e71bSYork Sun 			unsigned int dimm_number_required = 0;
20745614e71bSYork Sun 			unsigned int ctrl_num;
20755614e71bSYork Sun 			unsigned int dimm_num;
20765614e71bSYork Sun 
20775614e71bSYork Sun 			if (argc == 1) {
20785614e71bSYork Sun 				/* Only the element and value must be last */
20795614e71bSYork Sun 				printf("edit <c#> <d#> "
20805614e71bSYork Sun 					"<spd|dimmparms|commonparms|opts|"
20815614e71bSYork Sun 					"addresses|regs> <element> <value>\n");
20825614e71bSYork Sun 				printf("for spd, specify byte number for "
20835614e71bSYork Sun 					"element\n");
20845614e71bSYork Sun 				continue;
20855614e71bSYork Sun 			}
20865614e71bSYork Sun 
20875614e71bSYork Sun 			error = fsl_ddr_parse_interactive_cmd(
20885614e71bSYork Sun 				argv, argc - 2,
20895614e71bSYork Sun 				&step_mask,
20905614e71bSYork Sun 				&ctlr_mask,
20915614e71bSYork Sun 				&dimm_mask,
20925614e71bSYork Sun 				&dimm_number_required
20935614e71bSYork Sun 			);
20945614e71bSYork Sun 
20955614e71bSYork Sun 			if (error)
20965614e71bSYork Sun 				continue;
20975614e71bSYork Sun 
20985614e71bSYork Sun 
20995614e71bSYork Sun 			/* Check arguments */
21005614e71bSYork Sun 
21015614e71bSYork Sun 			/* ERROR: If no steps were found */
21025614e71bSYork Sun 			if (step_mask == 0) {
21035614e71bSYork Sun 				printf("Error: No valid steps were specified "
21045614e71bSYork Sun 						"in argument.\n");
21055614e71bSYork Sun 				continue;
21065614e71bSYork Sun 			}
21075614e71bSYork Sun 
21085614e71bSYork Sun 			/* ERROR: If multiple steps were found */
21095614e71bSYork Sun 			if (step_mask & (step_mask - 1)) {
21105614e71bSYork Sun 				printf("Error: Multiple steps specified in "
21115614e71bSYork Sun 						"argument.\n");
21125614e71bSYork Sun 				continue;
21135614e71bSYork Sun 			}
21145614e71bSYork Sun 
21155614e71bSYork Sun 			/* ERROR: Controller not specified */
21165614e71bSYork Sun 			if (ctlr_mask == 0) {
21175614e71bSYork Sun 				printf("Error: controller number not "
21185614e71bSYork Sun 					"specified or no element and "
21195614e71bSYork Sun 					"value specified\n");
21205614e71bSYork Sun 				continue;
21215614e71bSYork Sun 			}
21225614e71bSYork Sun 
21235614e71bSYork Sun 			if (ctlr_mask & (ctlr_mask - 1)) {
21245614e71bSYork Sun 				printf("Error: multiple controllers "
21255614e71bSYork Sun 						"specified, %X\n", ctlr_mask);
21265614e71bSYork Sun 				continue;
21275614e71bSYork Sun 			}
21285614e71bSYork Sun 
21295614e71bSYork Sun 			/* ERROR: DIMM number not specified */
21305614e71bSYork Sun 			if (dimm_number_required && dimm_mask == 0) {
21315614e71bSYork Sun 				printf("Error: DIMM number number not "
21325614e71bSYork Sun 					"specified or no element and "
21335614e71bSYork Sun 					"value specified\n");
21345614e71bSYork Sun 				continue;
21355614e71bSYork Sun 			}
21365614e71bSYork Sun 
21375614e71bSYork Sun 			if (dimm_mask & (dimm_mask - 1)) {
21385614e71bSYork Sun 				printf("Error: multipled DIMMs specified\n");
21395614e71bSYork Sun 				continue;
21405614e71bSYork Sun 			}
21415614e71bSYork Sun 
21425614e71bSYork Sun 			p_element = argv[argc - 2];
21435614e71bSYork Sun 			p_value = argv[argc - 1];
21445614e71bSYork Sun 
21455614e71bSYork Sun 			ctrl_num = __ilog2(ctlr_mask);
21465614e71bSYork Sun 			dimm_num = __ilog2(dimm_mask);
21475614e71bSYork Sun 
21485614e71bSYork Sun 			switch (step_mask) {
21495614e71bSYork Sun 			case STEP_GET_SPD:
21505614e71bSYork Sun 				{
21515614e71bSYork Sun 					unsigned int element_num;
21525614e71bSYork Sun 					unsigned int value;
21535614e71bSYork Sun 
21545614e71bSYork Sun 					element_num = simple_strtoul(p_element,
21555614e71bSYork Sun 								     NULL, 0);
21565614e71bSYork Sun 					value = simple_strtoul(p_value,
21575614e71bSYork Sun 							       NULL, 0);
21585614e71bSYork Sun 					fsl_ddr_spd_edit(pinfo,
21595614e71bSYork Sun 							       ctrl_num,
21605614e71bSYork Sun 							       dimm_num,
21615614e71bSYork Sun 							       element_num,
21625614e71bSYork Sun 							       value);
21635614e71bSYork Sun 					next_step = STEP_COMPUTE_DIMM_PARMS;
21645614e71bSYork Sun 				}
21655614e71bSYork Sun 				break;
21665614e71bSYork Sun 
21675614e71bSYork Sun 			case STEP_COMPUTE_DIMM_PARMS:
21685614e71bSYork Sun 				fsl_ddr_dimm_parameters_edit(
21695614e71bSYork Sun 						 pinfo, ctrl_num, dimm_num,
21705614e71bSYork Sun 						 p_element, p_value);
21715614e71bSYork Sun 				next_step = STEP_COMPUTE_COMMON_PARMS;
21725614e71bSYork Sun 				break;
21735614e71bSYork Sun 
21745614e71bSYork Sun 			case STEP_COMPUTE_COMMON_PARMS:
21755614e71bSYork Sun 				lowest_common_dimm_parameters_edit(pinfo,
21765614e71bSYork Sun 						ctrl_num, p_element, p_value);
21775614e71bSYork Sun 				next_step = STEP_GATHER_OPTS;
21785614e71bSYork Sun 				break;
21795614e71bSYork Sun 
21805614e71bSYork Sun 			case STEP_GATHER_OPTS:
21815614e71bSYork Sun 				fsl_ddr_options_edit(pinfo, ctrl_num,
21825614e71bSYork Sun 							   p_element, p_value);
21835614e71bSYork Sun 				next_step = STEP_ASSIGN_ADDRESSES;
21845614e71bSYork Sun 				break;
21855614e71bSYork Sun 
21865614e71bSYork Sun 			case STEP_ASSIGN_ADDRESSES:
21875614e71bSYork Sun 				printf("editing of address assignment "
21885614e71bSYork Sun 						"not yet implemented\n");
21895614e71bSYork Sun 				break;
21905614e71bSYork Sun 
21915614e71bSYork Sun 			case STEP_COMPUTE_REGS:
21925614e71bSYork Sun 				{
21935614e71bSYork Sun 					fsl_ddr_regs_edit(pinfo,
21945614e71bSYork Sun 								ctrl_num,
21955614e71bSYork Sun 								p_element,
21965614e71bSYork Sun 								p_value);
21975614e71bSYork Sun 					next_step = STEP_PROGRAM_REGS;
21985614e71bSYork Sun 				}
21995614e71bSYork Sun 				break;
22005614e71bSYork Sun 
22015614e71bSYork Sun 			default:
22025614e71bSYork Sun 				printf("programming error\n");
22035614e71bSYork Sun 				while (1)
22045614e71bSYork Sun 					;
22055614e71bSYork Sun 				break;
22065614e71bSYork Sun 			}
22075614e71bSYork Sun 			continue;
22085614e71bSYork Sun 		}
22095614e71bSYork Sun 
22105614e71bSYork Sun 		if (strcmp(argv[0], "reset") == 0) {
22115614e71bSYork Sun 			/*
22125614e71bSYork Sun 			 * Reboot machine.
22135614e71bSYork Sun 			 * Args don't seem to matter because this
22145614e71bSYork Sun 			 * doesn't return
22155614e71bSYork Sun 			 */
22165614e71bSYork Sun 			do_reset(NULL, 0, 0, NULL);
22175614e71bSYork Sun 			printf("Reset didn't work\n");
22185614e71bSYork Sun 		}
22195614e71bSYork Sun 
22205614e71bSYork Sun 		if (strcmp(argv[0], "recompute") == 0) {
22215614e71bSYork Sun 			/*
22225614e71bSYork Sun 			 * Recalculate everything, starting with
22235614e71bSYork Sun 			 * loading SPD EEPROM from DIMMs
22245614e71bSYork Sun 			 */
22255614e71bSYork Sun 			next_step = STEP_GET_SPD;
22265614e71bSYork Sun 			ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
22275614e71bSYork Sun 			continue;
22285614e71bSYork Sun 		}
22295614e71bSYork Sun 
22305614e71bSYork Sun 		if (strcmp(argv[0], "compute") == 0) {
22315614e71bSYork Sun 			/*
22325614e71bSYork Sun 			 * Compute rest of steps starting at
22335614e71bSYork Sun 			 * the current next_step/
22345614e71bSYork Sun 			 */
22355614e71bSYork Sun 			ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
22365614e71bSYork Sun 			continue;
22375614e71bSYork Sun 		}
22385614e71bSYork Sun 
22395614e71bSYork Sun 		if (strcmp(argv[0], "print") == 0) {
22405614e71bSYork Sun 			unsigned int error = 0;
22415614e71bSYork Sun 			unsigned int step_mask = 0;
22425614e71bSYork Sun 			unsigned int ctlr_mask = 0;
22435614e71bSYork Sun 			unsigned int dimm_mask = 0;
22445614e71bSYork Sun 			unsigned int dimm_number_required = 0;
22455614e71bSYork Sun 
22465614e71bSYork Sun 			if (argc == 1) {
22475614e71bSYork Sun 				printf("print [c<n>] [d<n>] [spd] [dimmparms] "
22485614e71bSYork Sun 				  "[commonparms] [opts] [addresses] [regs]\n");
22495614e71bSYork Sun 				continue;
22505614e71bSYork Sun 			}
22515614e71bSYork Sun 
22525614e71bSYork Sun 			error = fsl_ddr_parse_interactive_cmd(
22535614e71bSYork Sun 				argv, argc,
22545614e71bSYork Sun 				&step_mask,
22555614e71bSYork Sun 				&ctlr_mask,
22565614e71bSYork Sun 				&dimm_mask,
22575614e71bSYork Sun 				&dimm_number_required
22585614e71bSYork Sun 			);
22595614e71bSYork Sun 
22605614e71bSYork Sun 			if (error)
22615614e71bSYork Sun 				continue;
22625614e71bSYork Sun 
22635614e71bSYork Sun 			/* If no particular controller was found, print all */
22645614e71bSYork Sun 			if (ctlr_mask == 0)
22655614e71bSYork Sun 				ctlr_mask = 0xFF;
22665614e71bSYork Sun 
22675614e71bSYork Sun 			/* If no particular dimm was found, print all dimms. */
22685614e71bSYork Sun 			if (dimm_mask == 0)
22695614e71bSYork Sun 				dimm_mask = 0xFF;
22705614e71bSYork Sun 
22715614e71bSYork Sun 			/* If no steps were found, print all steps. */
22725614e71bSYork Sun 			if (step_mask == 0)
22735614e71bSYork Sun 				step_mask = STEP_ALL;
22745614e71bSYork Sun 
22755614e71bSYork Sun 			fsl_ddr_printinfo(pinfo, ctlr_mask,
22765614e71bSYork Sun 						dimm_mask, step_mask);
22775614e71bSYork Sun 			continue;
22785614e71bSYork Sun 		}
22795614e71bSYork Sun 
22805614e71bSYork Sun 		if (strcmp(argv[0], "go") == 0) {
22815614e71bSYork Sun 			if (next_step)
22825614e71bSYork Sun 				ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
22835614e71bSYork Sun 			break;
22845614e71bSYork Sun 		}
22855614e71bSYork Sun 
22865614e71bSYork Sun 		printf("unknown command %s\n", argv[0]);
22875614e71bSYork Sun 	}
22885614e71bSYork Sun 
22895614e71bSYork Sun 	debug("end of memory = %llu\n", (u64)ddrsize);
22905614e71bSYork Sun 
22915614e71bSYork Sun 	return ddrsize;
22925614e71bSYork Sun }
2293