MCC200 update - add LCD Progress Indicator
diff --git a/board/mcc200/auto_update.c b/board/mcc200/auto_update.c
index 9ccda72..cd6b391 100644
--- a/board/mcc200/auto_update.c
+++ b/board/mcc200/auto_update.c
@@ -106,6 +106,8 @@
 	{ AU_FL_ROOTFS_ST,	AU_FL_ROOTFS_ND,   },
 };
 
+ulong totsize;
+
 /* where to load files into memory */
 #define LOAD_ADDR ((unsigned char *)0x00200000)
 
@@ -130,6 +132,11 @@
 extern int flash_sect_protect (int, ulong, ulong);
 extern int flash_write (char *, ulong, ulong);
 extern int u_boot_hush_start(void);
+#ifdef CONFIG_PROGRESSBAR
+extern void show_progress(int, int);
+extern void lcd_puts (char *);
+extern void lcd_enable(void);
+#endif
 
 int au_check_cksum_valid(int idx, long nbytes)
 {
@@ -168,10 +175,12 @@
 #endif
 	if (nbytes < sizeof(*hdr)) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	/* check the hdr CRC */
@@ -180,22 +189,26 @@
 
 	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
 	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	if ((idx == IDX_ROOTFS) &&
 		( (hdr->ih_type != IH_TYPE_RAMDISK) || (hdr->ih_type != IH_TYPE_FILESYSTEM) )
 	   ) {
 		printf ("Image %s wrong type\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
 	/* recycle checksum */
@@ -203,13 +216,17 @@
 	/* for kernel and app the image header must also fit into flash */
 	if (idx != IDX_FIRMWARE)
 		checksum += sizeof(*hdr);
+
 	/* check the size does not exceed space in flash. HUSH scripts */
-	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
 		printf ("Image %s is bigger than FLASH\n", aufile[idx]);
+		ausize[idx] = 0;
 		return -1;
 	}
-	return 0;
+	/* Update with the real filesize */
+	ausize[idx] = (idx == IDX_FIRMWARE ? checksum + sizeof(*hdr) : checksum);
+
+	return checksum; /* return size to be written to flash */
 }
 
 int au_do_update(int idx, long sz)
@@ -254,6 +271,10 @@
 	debug ("flash_sect_erase(%lx, %lx);\n", start, end);
 	flash_sect_erase(start, end);
 	wait_ms(100);
+#ifdef CONFIG_PROGRESSBAR
+	show_progress(end - start, totsize);
+#endif
+
 	/* strip the header - except for the kernel and ramdisk */
 	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
 		addr = (char *)hdr;
@@ -278,6 +299,10 @@
 		return -1;
 	}
 
+#ifdef CONFIG_PROGRESSBAR
+	show_progress(nbytes, totsize);
+#endif
+
 	/* check the data CRC of the copy */
 	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
 		printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
@@ -300,7 +325,7 @@
 {
 	block_dev_desc_t *stor_dev;
 	long sz;
-	int i, res, bitmap_first, cnt, old_ctrlc, got_ctrlc;
+	int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc;
 	char *env;
 	long start, end;
 	uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0};
@@ -319,6 +344,7 @@
 	      (keypad_status1[1] != keypad_status2[1])) {
 		return 0;
 	}
+
 	au_usb_stor_curr_dev = -1;
 	/* start USB */
 	if (usb_stop() < 0) {
@@ -403,23 +429,50 @@
 	old_ctrlc = disable_ctrlc(0);
 
 	bitmap_first = 0;
-	/* just loop thru all the possible files */
+
+ 	/* validate the images first */
 	for (i = 0; i < AU_MAXFILES; i++) {
+		ulong imsize;
 		/* just read the header */
 		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
 		debug ("read %s sz %ld hdr %d\n",
 			aufile[i], sz, sizeof(image_header_t));
 		if (sz <= 0 || sz < sizeof(image_header_t)) {
 			debug ("%s not found\n", aufile[i]);
+			ausize[i] = 0;
 			continue;
 		}
-		if (au_check_header_valid(i, sz) < 0) {
+		/* au_check_header_valid() updates ausize[] */
+		if ((imsize = au_check_header_valid(i, sz)) < 0) {
 			debug ("%s header not valid\n", aufile[i]);
 			continue;
 		}
+		/* totsize accounts for image size and flash erase size */
+ 		totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start));
+	}
+
+#ifdef CONFIG_PROGRESSBAR
+	if (totsize) {
+		lcd_puts(" Update in progress\n");
+		lcd_enable();
+	}
+#endif
+
+	/* just loop thru all the possible files */
+	for (i = 0; i < AU_MAXFILES && totsize; i++) {
+		if (!ausize[i]) {
+			continue;
+		}
-		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
+		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
+
 		debug ("read %s sz %ld hdr %d\n",
 			aufile[i], sz, sizeof(image_header_t));
+
+		if (sz != ausize[i]) {
+			printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
+  			continue;
+  		}
+
 		if (sz <= 0 || sz <= sizeof(image_header_t)) {
 			debug ("%s not found\n", aufile[i]);
 			continue;
@@ -452,6 +505,16 @@
 	usb_stop();
 	/* restore the old state */
 	disable_ctrlc(old_ctrlc);
+#ifdef CONFIG_PROGRESSBAR
+	if (totsize) {
+		if (!res) {
+			lcd_puts("\n  Update completed\n");
+		} else {
+			lcd_puts("\n   Update error\n");
+		}
+		lcd_enable();
+	}
+#endif
 	return 0;
 }
 #endif /* CONFIG_AUTO_UPDATE */
diff --git a/board/mcc200/lcd.c b/board/mcc200/lcd.c
index b262516..98b86d1 100644
--- a/board/mcc200/lcd.c
+++ b/board/mcc200/lcd.c
@@ -24,13 +24,13 @@
 
 #ifdef CONFIG_LCD
 
-#define SWAPPED_LCD
+#undef SWAPPED_LCD /* For the previous h/w version */
 /*
  *  The name of the device used for communication
  * with the PSoC.
  */
 #define PSOC_PSC	MPC5XXX_PSC2
-#define PSOC_BAUD	500000UL
+#define PSOC_BAUD	230400UL
 
 #define RTS_ASSERT	1
 #define RTS_NEGATE	0
@@ -181,10 +181,35 @@
 		udelay (PSOC_WAIT_TIME);
 	}
 	if (!retries) {
-		printf ("%s Error: PSoC doesn't respond on "
+		printf ("%s Warning: PSoC doesn't respond on "
 			"RTS NEGATE\n",	__FUNCTION__);
 	}
 
 	return;
 }
+#ifdef CONFIG_PROGRESSBAR
+
+#define FONT_WIDTH      8 /* the same as VIDEO_FONT_WIDTH in video_font.h */
+void show_progress (int size, int tot)
+{
+	int cnt;
+	int i;
+	static int rc = 0;
+
+	rc += size;
+
+	cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot;
+
+	rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH);
+
+	for (i = 0; i < cnt; i++) {
+		lcd_putc(0xdc);
+	}
+
+	if (cnt) {
+		lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */
+	}
+}
+
+#endif
 #endif /* CONFIG_LCD */
diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h
index f60973b..621a81c 100644
--- a/include/configs/mcc200.h
+++ b/include/configs/mcc200.h
@@ -265,6 +265,7 @@
  */
 #if !defined(CONFIG_PRS200)
 #define CONFIG_LCD		1
+#define CONFIG_PROGRESSBAR 1
 #endif
 
 #if defined(CONFIG_LCD)