#include <asm/pci-bridge.h>
#include <asm/machdep.h>
-#ifdef CONFIG_PPC_INDIRECT_PCI_BE
-#define PCI_CFG_OUT out_be32
-#else
-#define PCI_CFG_OUT out_le32
-#endif
-
static int
indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
int len, u32 *val)
else
reg = offset & 0xfc;
- PCI_CFG_OUT(hose->cfg_addr,
- (0x80000000 | (bus_no << 16)
- | (devfn << 8) | reg | cfg_type));
+ if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
+ out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+ else
+ out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
/*
* Note: the caller has already checked that offset is
else
reg = offset & 0xfc;
- PCI_CFG_OUT(hose->cfg_addr,
- (0x80000000 | (bus_no << 16)
- | (devfn << 8) | reg | cfg_type));
+ if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
+ out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
+ else
+ out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
+ (devfn << 8) | reg | cfg_type));
/* surpress setting of PCI_PRIMARY_BUS */
if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
(bus->number == hose->first_busno))
val &= 0xffffff00;
+ /* Workaround for PCI_28 Errata in 440EPx/GRx */
+ if ((hose->indirect_type & PPC_INDIRECT_TYPE_BROKEN_MRM) &&
+ offset == PCI_CACHE_LINE_SIZE) {
+ val = 0;
+ }
+
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
static struct pci_ops indirect_pci_ops =
{
- indirect_read_config,
- indirect_write_config
+ .read = indirect_read_config,
+ .write = indirect_write_config,
};
void __init
-setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr,
- void __iomem * cfg_data)
+setup_indirect_pci(struct pci_controller* hose,
+ resource_size_t cfg_addr,
+ resource_size_t cfg_data, u32 flags)
{
- hose->cfg_addr = cfg_addr;
- hose->cfg_data = cfg_data;
- hose->ops = &indirect_pci_ops;
-}
-
-void __init
-setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
-{
- unsigned long base = cfg_addr & PAGE_MASK;
- void __iomem *mbase, *addr, *data;
+ resource_size_t base = cfg_addr & PAGE_MASK;
+ void __iomem *mbase;
mbase = ioremap(base, PAGE_SIZE);
- addr = mbase + (cfg_addr & ~PAGE_MASK);
+ hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
if ((cfg_data & PAGE_MASK) != base)
mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
- data = mbase + (cfg_data & ~PAGE_MASK);
- setup_indirect_pci_nomap(hose, addr, data);
+ hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
+ hose->ops = &indirect_pci_ops;
+ hose->indirect_type = flags;
}