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>
This commit is contained in:
Andrew Sharp 2012-08-29 14:16:32 +00:00 committed by Wolfgang Denk
parent 98c397a6ed
commit 69fd2d3b05
2 changed files with 32 additions and 10 deletions

7
README
View File

@ -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

View File

@ -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);