Merge with git://git.kernel.org/pub/scm/boot/u-boot/u-boot.git#pci
This commit is contained in:
commit
7b230f61db
18
CHANGELOG
18
CHANGELOG
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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; \
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user