powerpc/mpc8xxxx: FSL DDR debugger auto run of stored commands

This patch adds the ability for the FSL DDR interactive debugger to
automatically run the sequence of commands stored in the ddr_interactive
environment variable.  Commands are separated using ';'.

ddr_interactive=compute; edit c0 d0 dimmparms caslat_X 0x3FC0; go

Signed-off-by: James Yang <James.Yang@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
index c8b0f91..4dd55fc 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr.h
@@ -86,7 +86,8 @@
 		unsigned int memctl_interleaved,
 		unsigned int ctrl_num);
 
-unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo);
+int fsl_ddr_interactive_env_var_exists(void);
+unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set);
 void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
 			   unsigned int ctrl_num);
 
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
index e5ee775..46257c9 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
@@ -1430,11 +1430,23 @@
 	return error;
 }
 
-unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo)
+int fsl_ddr_interactive_env_var_exists(void)
+{
+	char buffer[CONFIG_SYS_CBSIZE];
+
+	if (getenv_f("ddr_interactive", buffer, CONFIG_SYS_CBSIZE) >= 0)
+		return 1;
+
+	return 0;
+}
+
+unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set)
 {
 	unsigned long long ddrsize;
 	const char *prompt = "FSL DDR>";
 	char buffer[CONFIG_SYS_CBSIZE];
+	char buffer2[CONFIG_SYS_CBSIZE];
+	char *p = NULL;
 	char *argv[CONFIG_SYS_MAXARGS + 1];	/* NULL terminated */
 	int argc;
 	unsigned int next_step = STEP_GET_SPD;
@@ -1451,16 +1463,39 @@
 		"go         program the memory controller and continue with u-boot\n"
 	};
 
+	if (var_is_set) {
+		if (getenv_f("ddr_interactive", buffer2, CONFIG_SYS_CBSIZE) > 0) {
+			p = buffer2;
+		} else {
+			var_is_set = 0;
+		}
+	}
+
 	/*
 	 * The strategy for next_step is that it points to the next
 	 * step in the computation process that needs to be done.
 	 */
 	while (1) {
-		/*
-		 * No need to worry for buffer overflow here in
-		 * this function;  readline() maxes out at CFG_CBSIZE
-		 */
-		readline_into_buffer(prompt, buffer, 0);
+		if (var_is_set) {
+			char *pend = strchr(p, ';');
+			if (pend) {
+				/* found command separator, copy sub-command */
+				*pend = '\0';
+				strcpy(buffer, p);
+				p = pend + 1;
+			} else {
+				/* separator not found, copy whole string */
+				strcpy(buffer, p);
+				p = NULL;
+				var_is_set = 0;
+			}
+		} else {
+			/*
+			 * No need to worry for buffer overflow here in
+			 * this function;  readline() maxes out at CFG_CBSIZE
+			 */
+			readline_into_buffer(prompt, buffer, 0);
+		}
 		argc = parse_line(buffer, argv);
 		if (argc == 0)
 			continue;
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/main.c b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
index a33c9e2..5311a26 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/main.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/main.c
@@ -532,10 +532,10 @@
 
 	/* Compute it once normally. */
 #ifdef CONFIG_FSL_DDR_INTERACTIVE
-	if (getenv("ddr_interactive")) {
-		total_memory = fsl_ddr_interactive(&info);
-	} else if (tstc() && (getc() == 'd')) {	/* we got a key press of 'd' */
-		total_memory = fsl_ddr_interactive(&info);
+	if (tstc() && (getc() == 'd')) {	/* we got a key press of 'd' */
+		total_memory = fsl_ddr_interactive(&info, 0);
+	} else if (fsl_ddr_interactive_env_var_exists()) {
+		total_memory = fsl_ddr_interactive(&info, 1);
 	} else
 #endif
 		total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0);