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