diff options
Diffstat (limited to 'target/linux/atheros')
-rw-r--r-- | target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c b/target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c index 035a61822..9040a43ec 100644 --- a/target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c +++ b/target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c @@ -30,7 +30,6 @@ #define AR531X_MEM_BASE 0x80800000UL #define AR531X_MEM_SIZE 0x00ffffffUL #define AR531X_IO_SIZE 0x00007fffUL - #define IDSEL_SHIFT 13 static spinlock_t ar531x_pci_lock = SPIN_LOCK_UNLOCKED; @@ -42,25 +41,24 @@ static int config_access(int busno, int dev, int func, int where, int size, u32 u32 reg; unsigned long flags; int ret = -1; - - if ((busno != 0) || (dev > 3) || (func > 2)) + if ((busno != 0) || ((dev != 0) && (dev != 3)) || (func > 2)) return ret; spin_lock_irqsave(&ar531x_pci_lock, flags); - + /* Select Configuration access */ reg = sysRegRead(AR5315_PCI_MISC_CONFIG); reg |= AR5315_PCIMISC_CFG_SEL; sysRegWrite(AR5315_PCI_MISC_CONFIG, reg); (void)sysRegRead(AR5315_PCI_MISC_CONFIG); - - address = (u32)cfgaddr + (1 << (IDSEL_SHIFT + dev)) + (func << 8) + where; + + address = (u32)cfgaddr + (1 << (IDSEL_SHIFT + dev)) + (func << 8) + where; if (size == 1) address ^= 0x3; else if (size == 2) address ^= 0x2; - + if (write) { if (size == 1) ret = put_dbe(ptr, (u8 *) address); @@ -82,9 +80,9 @@ static int config_access(int busno, int dev, int func, int where, int size, u32 reg &= ~AR5315_PCIMISC_CFG_SEL; sysRegWrite(AR5315_PCI_MISC_CONFIG, reg); (void)sysRegRead(AR5315_PCI_MISC_CONFIG); - + spin_unlock_irqrestore(&ar531x_pci_lock, flags); - + if (ret) { *((u32 *)ptr) = 0xffffffff; return PCIBIOS_DEVICE_NOT_FOUND; @@ -111,21 +109,23 @@ struct pci_ops ar531x_pci_ops = { static struct resource ar531x_mem_resource = { .name = "AR531x PCI MEM", .start = AR531X_MEM_BASE, - .end = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE - 1, + .end = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE - 1 + 0x4000000, .flags = IORESOURCE_MEM, }; static struct resource ar531x_io_resource = { .name = "AR531x PCI I/O", - .start = 0, - .end = AR531X_IO_SIZE, + .start = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE, + .end = AR531X_MEM_BASE + AR531X_MEM_SIZE - 1, .flags = IORESOURCE_IO, }; struct pci_controller ar531x_pci_controller = { - .pci_ops = &ar531x_pci_ops, + .pci_ops = &ar531x_pci_ops, .mem_resource = &ar531x_mem_resource, .io_resource = &ar531x_io_resource, + .mem_offset = 0x00000000UL, + .io_offset = 0x00000000UL, }; int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) @@ -145,18 +145,18 @@ int pcibios_plat_dev_init(struct pci_dev *dev) reg = sysRegRead(AR5315_PCI_INTEN_REG); reg &= ~AR5315_PCI_INT_ENABLE; sysRegWrite(AR5315_PCI_INTEN_REG, reg); - + reg = sysRegRead(AR5315_PCI_INT_STATUS); reg |= (AR5315_PCI_ABORT_INT | AR5315_PCI_EXT_INT); sysRegWrite(AR5315_PCI_INT_STATUS, reg); - + reg = sysRegRead(AR5315_PCI_INT_MASK); reg |= (AR5315_PCI_EXT_INT | AR5315_PCI_ABORT_INT); sysRegWrite(AR5315_PCI_INT_MASK, reg); - + reg = sysRegRead(AR5315_PCI_INTEN_REG); reg |= AR5315_PCI_INT_ENABLE; - sysRegWrite(AR5315_PCI_INTEN_REG, reg); + sysRegWrite(AR5315_PCI_INTEN_REG, reg); return 0; } @@ -167,7 +167,7 @@ static void ar5315_pci_fixup(struct pci_dev *dev) if ((PCI_SLOT(dev->devfn) != 3) || (PCI_FUNC(dev->devfn) != 0) || (bus->number != 0)) return; - + #define _DEV bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn) printk("PCI: fixing up device %d,%d,%d\n", _DEV); /* fix up mbars */ @@ -177,7 +177,7 @@ static void ar5315_pci_fixup(struct pci_dev *dev) config_access(_DEV, PCI_COMMAND, 4, PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| PCI_COMMAND_INVALIDATE|PCI_COMMAND_PARITY|PCI_COMMAND_SERR| - PCI_COMMAND_FAST_BACK, 1); + PCI_COMMAND_FAST_BACK, 1); #undef _DEV } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, ar5315_pci_fixup); @@ -189,13 +189,15 @@ int __init ar5315_pci_init(void) printk("AR531x PCI init... \n"); cfgaddr = (u32) ioremap_nocache(0x80000000, 1*1024*1024); /* Remap PCI config space */ - set_io_port_base((unsigned long) ioremap_nocache(AR531X_MEM_BASE + AR531X_IO_SIZE - 1, AR531X_IO_SIZE)); /* PCI I/O space */ + ar531x_pci_controller.io_map_base = + (unsigned long) ioremap_nocache(AR531X_MEM_BASE + AR531X_MEM_SIZE, AR531X_IO_SIZE); + set_io_port_base(ar531x_pci_controller.io_map_base); /* PCI I/O space */ reg = sysRegRead(AR5315_RESET); sysRegWrite(AR5315_RESET, reg | AR5315_RESET_PCIDMA); udelay(10*1000); - + sysRegWrite(AR5315_RESET, reg & ~AR5315_RESET_PCIDMA); sysRegRead(AR5315_RESET); /* read after */ @@ -219,13 +221,13 @@ int __init ar5315_pci_init(void) reg |= (IF_PCI | IF_PCI_HOST | IF_PCI_INTR | (IF_PCI_CLK_OUTPUT_CLK << IF_PCI_CLK_SHIFT)); sysRegWrite(AR5315_IF_CTL, reg); - + /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ reg = sysRegRead(AR5315_PCI_MISC_CONFIG); reg &= ~(AR5315_PCIMISC_RST_MODE); reg |= AR5315_PCIRST_LOW; sysRegWrite(AR5315_PCI_MISC_CONFIG, reg); - + /* wait for 100 ms */ udelay(100*1000); @@ -244,6 +246,12 @@ int __init ar5315_pci_init(void) udelay(500*1000); + /* dirty hack - anyone with a datasheet that knows the memory map ? */ + ioport_resource.start = 0x10000000; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0x10000000; + iomem_resource.end = 0xffffffff; + register_pci_controller(&ar531x_pci_controller); printk("done\n"); |