diff options
| author | Andrew Sharp <andywyse6@gmail.com> | 2012-08-29 14:16:32 +0000 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2012-09-02 14:19:05 +0200 | 
| commit | 69fd2d3b0559f221a45e9a86b8ead16490f4e47b (patch) | |
| tree | 7ae77696446e7c1f4935400cf1b767e79cff6e07 | |
| parent | 98c397a6ed3fe58f336f6717831faa99333d72a7 (diff) | |
| download | olio-uboot-2014.01-69fd2d3b0559f221a45e9a86b8ead16490f4e47b.tar.xz olio-uboot-2014.01-69fd2d3b0559f221a45e9a86b8ead16490f4e47b.zip | |
pci: add CONFIG_PCI_ENUM_ONLY for platforms that don't need PCI setup done
Introduce CONFIG_PCI_ENUM_ONLY variable for platforms that just want a
quick enumberation of the PCI devices, but don't need any setup work done.
This is very beneficial on platforms that have u-boot loaded by another
boot loader which does a more sophisticated job of setup of PCI devices
than u-boot.  That way, u-boot can just read what's there and get on
with life.  This is what SeaBIOS does.
Signed-off-by: Andrew Sharp <andywyse6@gmail.com>
| -rw-r--r-- | README | 7 | ||||
| -rw-r--r-- | drivers/pci/pci_auto.c | 35 | 
2 files changed, 32 insertions, 10 deletions
| @@ -3377,6 +3377,13 @@ Low Level (hardware related) configuration options:  		Disable PCI-Express on systems where it is supported but not  		required. +- CONFIG_PCI_ENUM_ONLY +		Only scan through and get the devices on the busses. +		Don't do any setup work, presumably because someone or +		something has already done it, and we don't need to do it +		a second time.	Useful for platforms that are pre-booted +		by coreboot or similar. +  - CONFIG_SYS_SRIO:  		Chip has SRIO or not diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 9a42ede56..ae61e2490 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -90,12 +90,14 @@ void pciauto_setup_device(struct pci_controller *hose,  			  struct pci_region *io)  {  	pci_addr_t bar_response; -	pci_addr_t bar_value;  	pci_size_t bar_size;  	u16 cmdstat = 0; -	struct pci_region *bar_res;  	int bar, bar_nr = 0; +#ifndef CONFIG_PCI_ENUM_ONLY +	pci_addr_t bar_value; +	struct pci_region *bar_res;  	int found_mem64 = 0; +#endif  	pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);  	cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; @@ -103,20 +105,26 @@ void pciauto_setup_device(struct pci_controller *hose,  	for (bar = PCI_BASE_ADDRESS_0;  		bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) {  		/* Tickle the BAR and get the response */ +#ifndef CONFIG_PCI_ENUM_ONLY  		pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); +#endif  		pci_hose_read_config_dword(hose, dev, bar, &bar_response);  		/* If BAR is not implemented go to the next BAR */  		if (!bar_response)  			continue; +#ifndef CONFIG_PCI_ENUM_ONLY  		found_mem64 = 0; +#endif  		/* Check the BAR type and set our address mask */  		if (bar_response & PCI_BASE_ADDRESS_SPACE) {  			bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))  				   & 0xffff) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY  			bar_res = io; +#endif  			DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size);  		} else { @@ -124,26 +132,34 @@ void pciauto_setup_device(struct pci_controller *hose,  			     PCI_BASE_ADDRESS_MEM_TYPE_64) {  				u32 bar_response_upper;  				u64 bar64; + +#ifndef CONFIG_PCI_ENUM_ONLY  				pci_hose_write_config_dword(hose, dev, bar + 4,  					0xffffffff); +#endif  				pci_hose_read_config_dword(hose, dev, bar + 4,  					&bar_response_upper);  				bar64 = ((u64)bar_response_upper << 32) | bar_response;  				bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; +#ifndef CONFIG_PCI_ENUM_ONLY  				found_mem64 = 1; +#endif  			} else {  				bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);  			} +#ifndef CONFIG_PCI_ENUM_ONLY  			if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))  				bar_res = prefetch;  			else  				bar_res = mem; +#endif  			DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size);  		} +#ifndef CONFIG_PCI_ENUM_ONLY  		if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) {  			/* Write it out and update our limit */  			pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value); @@ -162,9 +178,10 @@ void pciauto_setup_device(struct pci_controller *hose,  #endif  			} -			cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? -				PCI_COMMAND_IO : PCI_COMMAND_MEMORY;  		} +#endif +		cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? +			PCI_COMMAND_IO : PCI_COMMAND_MEMORY;  		DEBUGF("\n"); @@ -357,12 +374,6 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)  	pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);  	switch (class) { -	case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ -		DEBUGF("PCI AutoConfig: Found PowerPC device\n"); -		pciauto_setup_device(hose, dev, 6, hose->pci_mem, -				     hose->pci_prefetch, hose->pci_io); -		break; -  	case PCI_CLASS_BRIDGE_PCI:  		hose->current_busno++;  		pciauto_setup_device(hose, dev, 2, hose->pci_mem, @@ -429,6 +440,10 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)  			hose->pci_prefetch, hose->pci_io);  		break;  #endif + +	case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ +		DEBUGF("PCI AutoConfig: Found PowerPC device\n"); +  	default:  		pciauto_setup_device(hose, dev, 6, hose->pci_mem,  			hose->pci_prefetch, hose->pci_io); |