Merge branch 'pci'
diff --git a/CHANGELOG b/CHANGELOG
index 6dc76d2..1aa8f31 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,19 @@
 Changes since U-Boot 1.1.4:
 ======================================================================
 
+* Report back PCI bus when doing table based device config
+  Patch by Kumar Gala 11 Jan 2006
+
+* Added support for PCI prefetchable region and BARs
+  If a host controller sets up a region as prefetchable and
+  a device's BAR denotes it as prefetchable, allocate the
+  BAR into the prefetch region.
+
+  If a BAR is prefetchable and no prefetchable region has
+  been setup by the controller we fall back to allocating
+  the BAR into the normally memory region.
+  Patch by Kumar Gala 11 Jan 2006
+
 * Only disable the MPC83xx watchdog if its enabled out of reset.
   If its disabled out of reset SW can later enable it if so desired
   Patch by Kumar Gala, 11 Jan 2006
diff --git a/drivers/pci.c b/drivers/pci.c
index 5360030..3c24b99 100644
--- a/drivers/pci.c
+++ b/drivers/pci.c
@@ -459,6 +459,7 @@
 					      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
 			if (cfg) {
 				cfg->config_device(hose, dev, cfg);
+				sub_bus = max(sub_bus, hose->current_busno);
 #ifdef CONFIG_PCI_PNP
 			} else {
 				int n = pciauto_config_device(hose, dev);
diff --git a/drivers/pci_auto.c b/drivers/pci_auto.c
index 3302457..15f7432 100644
--- a/drivers/pci_auto.c
+++ b/drivers/pci_auto.c
@@ -77,6 +77,7 @@
 void pciauto_setup_device(struct pci_controller *hose,
 			  pci_dev_t dev, int bars_num,
 			  struct pci_region *mem,
+			  struct pci_region *prefetch,
 			  struct pci_region *io)
 {
 	unsigned int bar_value, bar_response, bar_size;
@@ -111,7 +112,10 @@
 				found_mem64 = 1;
 
 			bar_size = ~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1;
-			bar_res = mem;
+			if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
+				bar_res = prefetch;
+			else
+				bar_res = mem;
 
 			DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%x, ", bar_nr, bar_size);
 		}
@@ -148,6 +152,7 @@
 					 pci_dev_t dev, int sub_bus)
 {
 	struct pci_region *pci_mem = hose->pci_mem;
+	struct pci_region *pci_prefetch = hose->pci_prefetch;
 	struct pci_region *pci_io = hose->pci_io;
 	unsigned int cmdstat;
 
@@ -169,6 +174,21 @@
 		cmdstat |= PCI_COMMAND_MEMORY;
 	}
 
+	if (pci_prefetch) {
+		/* Round memory allocator to 1MB boundary */
+		pciauto_region_align(pci_prefetch, 0x100000);
+
+		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
+		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
+					(pci_prefetch->bus_lower & 0xfff00000) >> 16);
+
+		cmdstat |= PCI_COMMAND_MEMORY;
+	} else {
+		/* We don't support prefetchable memory for now, so disable */
+		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
+		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
+	}
+
 	if (pci_io) {
 		/* Round I/O allocator to 4KB boundary */
 		pciauto_region_align(pci_io, 0x1000);
@@ -181,10 +201,6 @@
 		cmdstat |= PCI_COMMAND_IO;
 	}
 
-	/* We don't support prefetchable memory for now, so disable */
-	pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
-	pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x1000);
-
 	/* Enable memory and I/O accesses, enable bus master */
 	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
 }
@@ -193,6 +209,7 @@
 					  pci_dev_t dev, int sub_bus)
 {
 	struct pci_region *pci_mem = hose->pci_mem;
+	struct pci_region *pci_prefetch = hose->pci_prefetch;
 	struct pci_region *pci_io = hose->pci_io;
 
 	/* Configure bus number registers */
@@ -206,6 +223,14 @@
 					(pci_mem->bus_lower-1) >> 16);
 	}
 
+	if (pci_prefetch) {
+		/* Round memory allocator to 1MB boundary */
+		pciauto_region_align(pci_prefetch, 0x100000);
+
+		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
+					(pci_prefetch->bus_lower-1) >> 16);
+	}
+
 	if (pci_io) {
 		/* Round I/O allocator to 4KB boundary */
 		pciauto_region_align(pci_io, 0x1000);
@@ -239,6 +264,11 @@
 			    hose->pci_mem->size < hose->regions[i].size)
 				hose->pci_mem = hose->regions + i;
 			break;
+		case (PCI_REGION_MEM | PCI_REGION_PREFETCH):
+			if (!hose->pci_prefetch ||
+			    hose->pci_prefetch->size < hose->regions[i].size)
+				hose->pci_prefetch = hose->regions + i;
+			break;
 		}
 	}
 
@@ -251,6 +281,14 @@
 		    hose->pci_mem->bus_start + hose->pci_mem->size - 1);
 	}
 
+	if (hose->pci_prefetch) {
+		pciauto_region_init(hose->pci_prefetch);
+
+		DEBUGF("PCI Autoconfig: Prefetchable Memory region: [%lx-%lx]\n",
+		    hose->pci_prefetch->bus_start,
+		    hose->pci_prefetch->bus_start + hose->pci_prefetch->size - 1);
+	}
+
 	if (hose->pci_io) {
 		pciauto_region_init(hose->pci_io);
 
@@ -275,7 +313,7 @@
 	switch(class) {
 	case PCI_CLASS_BRIDGE_PCI:
 		hose->current_busno++;
-		pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_io);
+		pciauto_setup_device(hose, dev, 2, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 
 		DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
 
@@ -301,12 +339,12 @@
 			return sub_bus;
 		}
 
-		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 		break;
 
 	case PCI_CLASS_BRIDGE_CARDBUS:
 		/* just do a minimal setup of the bridge, let the OS take care of the rest */
-		pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
+		pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 
 		DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n", PCI_DEV(dev));
 
@@ -328,11 +366,11 @@
 		 * the PIMMR window to be allocated (BAR0 - 1MB size)
 		 */
 		DEBUGF("PCI Autoconfig: Broken bridge found, only minimal config\n");
-		pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_io);
+		pciauto_setup_device(hose, dev, 0, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 		break;
 #endif
 	default:
-		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_io);
+		pciauto_setup_device(hose, dev, 6, hose->pci_mem, hose->pci_prefetch, hose->pci_io);
 		break;
 	}
 
diff --git a/include/pci.h b/include/pci.h
index 8f19997..f78a769 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -309,6 +309,7 @@
 #define PCI_REGION_MEM		0x00000000	/* PCI memory space */
 #define PCI_REGION_IO		0x00000001	/* PCI IO space */
 #define PCI_REGION_TYPE		0x00000001
+#define PCI_REGION_PREFETCH	0x00000008	/* prefetchable PCI memory */
 
 #define PCI_REGION_MEMORY	0x00000100	/* System memory */
 #define PCI_REGION_RO		0x00000200	/* Read-only memory */
@@ -386,7 +387,7 @@
 	int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
 
 	/* Used by auto config */
-	struct pci_region *pci_mem, *pci_io;
+	struct pci_region *pci_mem, *pci_io, *pci_prefetch;
 
 	/* Used by ppc405 autoconfig*/
 	struct pci_region *pci_fb;
@@ -472,6 +473,7 @@
 extern void pciauto_setup_device(struct pci_controller *hose,
 				 pci_dev_t dev, int bars_num,
 				 struct pci_region *mem,
+				 struct pci_region *prefetch,
 				 struct pci_region *io);
 int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);