aboutsummaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
Diffstat (limited to 'target')
-rw-r--r--target/linux/atheros/files/arch/mips/atheros/ar5315/pci.c54
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 035a618221..9040a43ecd 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");