diff options
| author | Wolfgang Denk <wd@pollux.denx.de> | 2006-03-12 21:31:38 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@pollux.denx.de> | 2006-03-12 21:31:38 +0100 | 
| commit | 7b230f61db319d87d51449d4620d520822813fbb (patch) | |
| tree | 4ab1907f8a19b51240ee9853bfe8acaad05c041c | |
| parent | a3f0169880a44ac06de5177e7926d7c732368663 (diff) | |
| parent | dffb70f3305daa16625ec9d5b02a2c0d23ff84b3 (diff) | |
| download | olio-uboot-2014.01-7b230f61db319d87d51449d4620d520822813fbb.tar.xz olio-uboot-2014.01-7b230f61db319d87d51449d4620d520822813fbb.zip | |
Merge with git://git.kernel.org/pub/scm/boot/u-boot/u-boot.git#pci
| -rw-r--r-- | CHANGELOG | 18 | ||||
| -rw-r--r-- | drivers/pci.c | 1 | ||||
| -rw-r--r-- | drivers/pci_auto.c | 58 | ||||
| -rw-r--r-- | drivers/pci_indirect.c | 16 | ||||
| -rw-r--r-- | include/pci.h | 4 | 
5 files changed, 86 insertions, 11 deletions
| @@ -2,6 +2,24 @@  Changes since U-Boot 1.1.4:  ====================================================================== +* Fixed PCI indirect config ops to handle multiple PCI controllers +  We need to adjust the bus number we are trying to access based +  on which PCI controller its on +  Patch by Kumar Gala 12 Jan 2006 + +* 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 +  * Add helper function for generic flat device tree fixups for mpc83xx    Patch by Kumar Gala, 11 Jan 2006 diff --git a/drivers/pci.c b/drivers/pci.c index 536003066..3c24b99c3 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -459,6 +459,7 @@ int pci_hose_scan_bus(struct pci_controller *hose, int bus)  					      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 3302457a3..15f74328f 100644 --- a/drivers/pci_auto.c +++ b/drivers/pci_auto.c @@ -77,6 +77,7 @@ int pciauto_region_allocate(struct pci_region* res, unsigned int size, unsigned  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 @@ void pciauto_setup_device(struct pci_controller *hose,  				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 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,  					 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 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,  		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 @@ static void pciauto_prescan_setup_bridge(struct pci_controller *hose,  		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 @@ static void pciauto_postscan_setup_bridge(struct pci_controller *hose,  					  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 @@ static void pciauto_postscan_setup_bridge(struct pci_controller *hose,  					(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 @@ void pciauto_config_init(struct pci_controller *hose)  			    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 @@ void pciauto_config_init(struct pci_controller *hose)  		    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 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)  	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 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)  			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 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)  		 * 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/drivers/pci_indirect.c b/drivers/pci_indirect.c index e8f19f570..f0c4a1ccf 100644 --- a/drivers/pci_indirect.c +++ b/drivers/pci_indirect.c @@ -36,6 +36,10 @@ static int								 \  indirect_##rw##_config_##size(struct pci_controller *hose, 		 \  			      pci_dev_t dev, int offset, type val)	 \  {									 \ +	u32 b, d,f;							 \ +	b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);		 \ +	b = b - hose->first_busno;					 \ +	dev = PCI_BDF(b, d, f);						 \  	out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); 	 \  	sync();								 \  	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);	 \ @@ -47,6 +51,10 @@ static int                                                               \  indirect_##rw##_config_##size(struct pci_controller *hose,               \  			      pci_dev_t dev, int offset, type val)       \  {                                                                        \ +	u32 b, d,f;							 \ +	b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);		 \ +	b = b - hose->first_busno;					 \ +	dev = PCI_BDF(b, d, f);						 \  	*(hose->cfg_addr) = dev | (offset & 0xfc) | 0x80000000;          \  	sync();                                                          \  	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);       \ @@ -58,6 +66,10 @@ static int								 \  indirect_##rw##_config_##size(struct pci_controller *hose, 		 \  			      pci_dev_t dev, int offset, type val)	 \  {									 \ +	u32 b, d,f;							 \ +	b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);		 \ +	b = b - hose->first_busno;					 \ +	dev = PCI_BDF(b, d, f);						 \  	if (PCI_BUS(dev) > 0)                                            \  		out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000001); \  	else                                                             \ @@ -71,6 +83,10 @@ static int								 \  indirect_##rw##_config_##size(struct pci_controller *hose, 		 \  			      pci_dev_t dev, int offset, type val)	 \  {									 \ +	u32 b, d,f;							 \ +	b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev);		 \ +	b = b - hose->first_busno;					 \ +	dev = PCI_BDF(b, d, f);						 \  	out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); 	 \  	cfg_##rw(val, hose->cfg_data + (offset & mask), type, op);	 \  	return 0;    					 		 \ diff --git a/include/pci.h b/include/pci.h index 4bb2df27e..0fc00e427 100644 --- a/include/pci.h +++ b/include/pci.h @@ -309,6 +309,7 @@ struct pci_region {  #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 @@ struct pci_controller {  	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 int pciauto_region_allocate(struct pci_region* res, unsigned int size, un  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); |