From 8a42eac7442816934567215cdc0de4e94df5b6d1 Mon Sep 17 00:00:00 2001
From: dzu <dzu>
Date: Mon, 29 Sep 2003 21:55:54 +0000
Subject: [PATCH] * Adapt TRAB configuration and auto_update to new memory
 layout

---
 CHANGELOG                |  2 +
 board/trab/auto_update.c | 23 ++++++-----
 cpu/arm920t/usb_ohci.c   | 85 +++++++++++++++++++++++++++++++++++-----
 include/configs/trab.h   |  2 +-
 4 files changed, 91 insertions(+), 21 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 2ce5ccf5a9..6563c683d7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@
 Changes for U-Boot 1.0.0:
 ======================================================================
 
+* Adapt TRAB configuration and auto_update to new memory layout
+
 * Add configuration for wtk board
 
 * Add support for the Sharp LQ065T9DR51U LCD display
diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c
index 9371637e92..c9c61eaabe 100644
--- a/board/trab/auto_update.c
+++ b/board/trab/auto_update.c
@@ -105,14 +105,14 @@ struct flash_layout
 #define AU_FL_APP_ND		0x005BFFFF
 #define AU_FL_DISK_ST		0x005C0000
 #define AU_FL_DISK_ND		0x00FFFFFF
-#else						/*  8 MB Flash, 16 MB RAM */
+#else						/*  8 MB Flash, 32 MB RAM */
 #define AU_FL_FIRMWARE_ST	0x00000000
-#define AU_FL_FIRMWARE_ND	0x0003FFFF
-#define AU_FL_KERNEL_ST		0x00040000
-#define AU_FL_KERNEL_ND		0x0011FFFF
-#define AU_FL_APP_ST		0x00120000
-#define AU_FL_APP_ND		0x003FFFFF
-#define AU_FL_DISK_ST		0x00400000
+#define AU_FL_FIRMWARE_ND	0x0005FFFF
+#define AU_FL_KERNEL_ST		0x00060000
+#define AU_FL_KERNEL_ND		0x0013FFFF
+#define AU_FL_APP_ST		0x00140000
+#define AU_FL_APP_ND		0x0067FFFF
+#define AU_FL_DISK_ST		0x00680000
 #define AU_FL_DISK_ND		0x007DFFFF
 #define AU_FL_VFD_ST		0x007E0000
 #define AU_FL_VFD_ND		0x007FFFFF
@@ -186,8 +186,8 @@ struct flash_layout aufl_layout[AU_MAXFILES - 3] = { \
 #define LOAD_ADDR ((unsigned char *)0x0C100100)
 /* where to build strings in memory - 256 bytes should be enough */
 #define STRING_ADDR ((char *)0x0C100000)
-/* the disk is the largest image */
-#define MAX_LOADSZ ausize[IDX_DISK]
+/* the app is the largest image */
+#define MAX_LOADSZ ausize[IDX_APP]
 
 /* externals */
 extern int fat_register_device(block_dev_desc_t *, int);
@@ -222,7 +222,7 @@ au_check_valid(int idx, long nbytes)
 #endif
 	if (ntohl(hdr->ih_magic) != IH_MAGIC ||
 	    hdr->ih_arch != IH_CPU_ARM ||
-	    nbytes < ntohl(hdr->ih_size))
+	    nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size)))
 	{
 		printf ("Image %s bad MAGIC or ARCH or SIZE\n", aufile[idx]);
 		return -1;
@@ -589,6 +589,9 @@ do_auto_update(void)
 		 */
 		if (got_ctrlc == 0)
 			au_update_eeprom(i);
+		else
+			/* enable the power switch */
+			*CPLD_VFD_BK &= ~POWER_OFF;
 	}
 	usb_stop();
 	/* restore the old state */
diff --git a/cpu/arm920t/usb_ohci.c b/cpu/arm920t/usb_ohci.c
index 8d3901ba19..bd7e6ca941 100644
--- a/cpu/arm920t/usb_ohci.c
+++ b/cpu/arm920t/usb_ohci.c
@@ -51,8 +51,6 @@
 #define	OHCI_CONTROL_INIT \
 	(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
 
-#define OHCI_UNLINK_TIMEOUT	(CFG_HZ / 10)
-
 #define readl(a) (*((vu_long *)(a)))
 #define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a))
 
@@ -85,6 +83,10 @@ struct ohci_hcca *phcca;
 struct ohci_device ohci_dev;
 /* urb_priv */
 urb_priv_t urb_priv;
+/* RHSC flag */
+int got_rhsc;
+/* device which was disconnected */
+struct usb_device *devgone;
 
 /*-------------------------------------------------------------------------*/
 
@@ -952,8 +954,29 @@ static unsigned char root_hub_str_index1[] =
 
 /* request to virtual root hub */
 
-static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
-		int transfer_len, struct devrequest *cmd)
+int rh_check_port_status(ohci_t *controller)
+{
+	__u32 temp, ndp, i;
+	int res;
+
+	res = -1;
+	temp = roothub_a (controller);
+	ndp = (temp & RH_A_NDP);
+	for (i = 0; i < ndp; i++) {
+		temp = roothub_portstatus (controller, i);
+		/* check for a device disconnect */
+		if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+			(RH_PS_PESC | RH_PS_CSC)) &&
+			((temp & RH_PS_CCS) == 0)) {
+			res = i;
+			break;
+		}
+	}
+	return res;
+}
+
+static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+		void *buffer, int transfer_len, struct devrequest *cmd)
 {
 	void * data = buffer;
 	int leni = transfer_len;
@@ -1178,6 +1201,12 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 	int maxsize = usb_maxpacket(dev, pipe);
 	int timeout;
 
+	/* device pulled? Shortcut the action. */
+	if (devgone == dev) {
+		dev->status = USB_ST_CRC_ERR;
+		return 0;
+	}
+
 #ifdef DEBUG
 	urb_priv.actual_length = 0;
 	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe));
@@ -1210,7 +1239,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		/* check whether the controller is done */
 		stat = hc_interrupt();
 		if (stat < 0) {
-			stat = 1;
+			stat = USB_ST_CRC_ERR;
 			break;
 		}
 		if (stat >= 0 && stat != 0xff) {
@@ -1220,11 +1249,33 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 		if (--timeout) {
 			wait_ms(1);
 		} else {
-			err("CTL:TIMEOUT");
-			stat = 1;
+			err("CTL:TIMEOUT ");
+			stat = USB_ST_CRC_ERR;
 			break;
 		}
 	}
+	/* we got an Root Hub Status Change interrupt */
+	if (got_rhsc) {
+#ifdef DEBUG
+		ohci_dump_roothub (&gohci, 1);
+#endif
+		got_rhsc = 0;
+		/* abuse timeout */
+		timeout = rh_check_port_status(&gohci);
+		if (timeout >= 0) {
+#if 0 /* this does nothing useful, but leave it here in case that changes */
+			/* the called routine adds 1 to the passed value */
+			usb_hub_port_connect_change(gohci.rh.dev, timeout - 1);
+#endif
+			/*
+			 * XXX
+			 * This is potentially dangerous because it assumes
+			 * that only one device is ever plugged in!
+			 */
+			devgone = dev;
+		}
+	}
+
 	dev->status = stat;
   	dev->act_len = transfer_len;
 
@@ -1264,10 +1315,12 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			pipe);
 		return -1;
 	}
-	if (((pipe >> 8) & 0x7f) == gohci.rh.devnum)
+	if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) {
+		gohci.rh.dev = dev;
 		/* root hub - redirect */
 		return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len,
 			setup);
+	}
 
 	return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0);
 }
@@ -1356,9 +1409,17 @@ static int hc_start (ohci_t * ohci)
 	ohci->disabled = 0;
  	writel (ohci->hc_control, &ohci->regs->control);
 
-	/* Choose the interrupts we care about now, others later on demand */
-	mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+	/* disable all interrupts */
+	mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
+			OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC |
+			OHCI_INTR_OC | OHCI_INTR_MIE);
+	writel (mask, &ohci->regs->intrdisable);
+	/* clear all interrupts */
+	mask &= ~OHCI_INTR_MIE;
 	writel (mask, &ohci->regs->intrstatus);
+	/* Choose the interrupts we care about now  - but w/o MIE */
+	mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
+	writel (mask, &ohci->regs->intrenable);
 
 #ifdef	OHCI_USE_NPS
 	/* required for AMD-756 and some Mac platforms */
@@ -1397,6 +1458,10 @@ hc_interrupt (void)
 
 	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */
 
+	if (ints & OHCI_INTR_RHSC) {
+		got_rhsc = 1;
+	}
+
 	if (ints & OHCI_INTR_UE) {
 		ohci->disabled++;
 		err ("OHCI Unrecoverable Error, controller usb-%s disabled",
diff --git a/include/configs/trab.h b/include/configs/trab.h
index 80a4b58380..e6b43d6605 100644
--- a/include/configs/trab.h
+++ b/include/configs/trab.h
@@ -28,8 +28,8 @@
 
 #ifdef CONFIG_OLD_VERSION		/* Old configuration:		*/
 #define	CONFIG_RAM_16MB			/*	16 MB SDRAM		*/
-#define CONFIG_FLASH_8MB		/*	 8 MB Flash		*/
 #endif
+#define CONFIG_FLASH_8MB		/*	 8 MB Flash		*/
 
 /*
  * If we are developing, we might want to start armboot from ram
-- 
2.39.5