forked from Minki/linux
[ARM] Kirkwood: add support for PCIe1
This patch extends the kirkwood's PCIe support up to 2 controllers as in the 6282 devices. Signed-off-by: Saeed Bishara <saeed@marvell.com> Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
This commit is contained in:
parent
35fe2fc44a
commit
ffd58bd2e4
@ -31,6 +31,8 @@
|
|||||||
#define ATTR_DEV_CS0 0x3e
|
#define ATTR_DEV_CS0 0x3e
|
||||||
#define ATTR_PCIE_IO 0xe0
|
#define ATTR_PCIE_IO 0xe0
|
||||||
#define ATTR_PCIE_MEM 0xe8
|
#define ATTR_PCIE_MEM 0xe8
|
||||||
|
#define ATTR_PCIE1_IO 0xd0
|
||||||
|
#define ATTR_PCIE1_MEM 0xd8
|
||||||
#define ATTR_SRAM 0x01
|
#define ATTR_SRAM 0x01
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
|
|||||||
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
|
TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
|
||||||
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
|
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
|
||||||
TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
|
TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
|
||||||
|
setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
|
||||||
|
TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
|
||||||
|
setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
|
||||||
|
TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup window for NAND controller.
|
* Setup window for NAND controller.
|
||||||
*/
|
*/
|
||||||
setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
|
setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
|
||||||
TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
|
TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup window for SRAM.
|
* Setup window for SRAM.
|
||||||
*/
|
*/
|
||||||
setup_cpu_win(3, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
|
setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
|
||||||
TARGET_SRAM, ATTR_SRAM, -1);
|
TARGET_SRAM, ATTR_SRAM, -1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,6 +43,11 @@ static struct map_desc kirkwood_io_desc[] __initdata = {
|
|||||||
.pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
|
.pfn = __phys_to_pfn(KIRKWOOD_PCIE_IO_PHYS_BASE),
|
||||||
.length = KIRKWOOD_PCIE_IO_SIZE,
|
.length = KIRKWOOD_PCIE_IO_SIZE,
|
||||||
.type = MT_DEVICE,
|
.type = MT_DEVICE,
|
||||||
|
}, {
|
||||||
|
.virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
|
||||||
|
.pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
|
||||||
|
.length = KIRKWOOD_PCIE1_IO_SIZE,
|
||||||
|
.type = MT_DEVICE,
|
||||||
}, {
|
}, {
|
||||||
.virtual = KIRKWOOD_REGS_VIRT_BASE,
|
.virtual = KIRKWOOD_REGS_VIRT_BASE,
|
||||||
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
|
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
|
||||||
@ -960,12 +965,14 @@ void __init kirkwood_init(void)
|
|||||||
static int __init kirkwood_clock_gate(void)
|
static int __init kirkwood_clock_gate(void)
|
||||||
{
|
{
|
||||||
unsigned int curr = readl(CLOCK_GATING_CTRL);
|
unsigned int curr = readl(CLOCK_GATING_CTRL);
|
||||||
|
u32 dev, rev;
|
||||||
|
|
||||||
|
kirkwood_pcie_id(&dev, &rev);
|
||||||
printk(KERN_DEBUG "Gating clock of unused units\n");
|
printk(KERN_DEBUG "Gating clock of unused units\n");
|
||||||
printk(KERN_DEBUG "before: 0x%08x\n", curr);
|
printk(KERN_DEBUG "before: 0x%08x\n", curr);
|
||||||
|
|
||||||
/* Make sure those units are accessible */
|
/* Make sure those units are accessible */
|
||||||
writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0, CLOCK_GATING_CTRL);
|
writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
|
||||||
|
|
||||||
/* For SATA: first shutdown the phy */
|
/* For SATA: first shutdown the phy */
|
||||||
if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
|
if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
|
||||||
@ -990,6 +997,18 @@ static int __init kirkwood_clock_gate(void)
|
|||||||
writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
|
writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For PCIe 1: first shutdown the phy */
|
||||||
|
if (dev == MV88F6282_DEV_ID) {
|
||||||
|
if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
|
||||||
|
writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
|
||||||
|
while (1)
|
||||||
|
if (readl(PCIE1_STATUS) & 0x1)
|
||||||
|
break;
|
||||||
|
writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
|
||||||
|
}
|
||||||
|
} else /* keep this bit set for devices that don't have PCIe1 */
|
||||||
|
kirkwood_clk_ctrl |= CGC_PEX1;
|
||||||
|
|
||||||
/* Now gate clock the required units */
|
/* Now gate clock the required units */
|
||||||
writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
|
writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
|
||||||
printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
|
printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
|
||||||
|
@ -18,6 +18,9 @@ struct mvsdio_platform_data;
|
|||||||
struct mtd_partition;
|
struct mtd_partition;
|
||||||
struct mtd_info;
|
struct mtd_info;
|
||||||
|
|
||||||
|
#define KW_PCIE0 (1 << 0)
|
||||||
|
#define KW_PCIE1 (1 << 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic Kirkwood init functions used early by machine-setup.
|
* Basic Kirkwood init functions used early by machine-setup.
|
||||||
*/
|
*/
|
||||||
@ -34,7 +37,7 @@ void kirkwood_ehci_init(void);
|
|||||||
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
|
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
|
||||||
void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
|
void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
|
||||||
void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
|
void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
|
||||||
void kirkwood_pcie_init(void);
|
void kirkwood_pcie_init(unsigned int portmask);
|
||||||
void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
|
void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
|
||||||
void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
|
void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
|
||||||
void kirkwood_spi_init(void);
|
void kirkwood_spi_init(void);
|
||||||
|
@ -82,9 +82,15 @@ static void __init db88f6281_init(void)
|
|||||||
|
|
||||||
static int __init db88f6281_pci_init(void)
|
static int __init db88f6281_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_db88f6281_bp())
|
if (machine_is_db88f6281_bp()) {
|
||||||
kirkwood_pcie_init();
|
u32 dev, rev;
|
||||||
|
|
||||||
|
kirkwood_pcie_id(&dev, &rev);
|
||||||
|
if (dev == MV88F6282_DEV_ID)
|
||||||
|
kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
|
||||||
|
else
|
||||||
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
subsys_initcall(db88f6281_pci_init);
|
subsys_initcall(db88f6281_pci_init);
|
||||||
|
@ -59,8 +59,9 @@
|
|||||||
#define CGC_SATA1 (1 << 15)
|
#define CGC_SATA1 (1 << 15)
|
||||||
#define CGC_XOR1 (1 << 16)
|
#define CGC_XOR1 (1 << 16)
|
||||||
#define CGC_CRYPTO (1 << 17)
|
#define CGC_CRYPTO (1 << 17)
|
||||||
|
#define CGC_PEX1 (1 << 18)
|
||||||
#define CGC_GE1 (1 << 19)
|
#define CGC_GE1 (1 << 19)
|
||||||
#define CGC_TDM (1 << 20)
|
#define CGC_TDM (1 << 20)
|
||||||
#define CGC_RESERVED ((1 << 18) | (0x6 << 21))
|
#define CGC_RESERVED (0x6 << 21)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#define IRQ_KIRKWOOD_XOR_10 7
|
#define IRQ_KIRKWOOD_XOR_10 7
|
||||||
#define IRQ_KIRKWOOD_XOR_11 8
|
#define IRQ_KIRKWOOD_XOR_11 8
|
||||||
#define IRQ_KIRKWOOD_PCIE 9
|
#define IRQ_KIRKWOOD_PCIE 9
|
||||||
|
#define IRQ_KIRKWOOD_PCIE1 10
|
||||||
#define IRQ_KIRKWOOD_GE00_SUM 11
|
#define IRQ_KIRKWOOD_GE00_SUM 11
|
||||||
#define IRQ_KIRKWOOD_GE01_SUM 15
|
#define IRQ_KIRKWOOD_GE01_SUM 15
|
||||||
#define IRQ_KIRKWOOD_USB 19
|
#define IRQ_KIRKWOOD_USB 19
|
||||||
|
@ -16,36 +16,48 @@
|
|||||||
* Marvell Kirkwood address maps.
|
* Marvell Kirkwood address maps.
|
||||||
*
|
*
|
||||||
* phys
|
* phys
|
||||||
* e0000000 PCIe Memory space
|
* e0000000 PCIe #0 Memory space
|
||||||
|
* e8000000 PCIe #1 Memory space
|
||||||
* f1000000 on-chip peripheral registers
|
* f1000000 on-chip peripheral registers
|
||||||
* f2000000 PCIe I/O space
|
* f2000000 PCIe #0 I/O space
|
||||||
* f3000000 NAND controller address window
|
* f3000000 PCIe #1 I/O space
|
||||||
* f4000000 Security Accelerator SRAM
|
* f4000000 NAND controller address window
|
||||||
|
* f5000000 Security Accelerator SRAM
|
||||||
*
|
*
|
||||||
* virt phys size
|
* virt phys size
|
||||||
* fee00000 f1000000 1M on-chip peripheral registers
|
* fed00000 f1000000 1M on-chip peripheral registers
|
||||||
* fef00000 f2000000 1M PCIe I/O space
|
* fee00000 f2000000 1M PCIe #0 I/O space
|
||||||
|
* fef00000 f3000000 1M PCIe #1 I/O space
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define KIRKWOOD_SRAM_PHYS_BASE 0xf4000000
|
#define KIRKWOOD_SRAM_PHYS_BASE 0xf5000000
|
||||||
#define KIRKWOOD_SRAM_SIZE SZ_2K
|
#define KIRKWOOD_SRAM_SIZE SZ_2K
|
||||||
|
|
||||||
#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf3000000
|
#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000
|
||||||
#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
|
#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
|
||||||
|
|
||||||
|
#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
|
||||||
|
#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000
|
||||||
|
#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000
|
||||||
|
#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
|
||||||
|
|
||||||
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
|
#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
|
||||||
#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfef00000
|
#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
|
||||||
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
|
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
|
||||||
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
|
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
|
||||||
|
|
||||||
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
|
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
|
||||||
#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000
|
#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000
|
||||||
#define KIRKWOOD_REGS_SIZE SZ_1M
|
#define KIRKWOOD_REGS_SIZE SZ_1M
|
||||||
|
|
||||||
#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
|
#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
|
||||||
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
|
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
|
||||||
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
|
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
|
||||||
|
|
||||||
|
#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xe8000000
|
||||||
|
#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xe8000000
|
||||||
|
#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register Map
|
* Register Map
|
||||||
*/
|
*/
|
||||||
@ -72,6 +84,9 @@
|
|||||||
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
|
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
|
||||||
#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
|
#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
|
||||||
#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
|
#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
|
||||||
|
#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
|
||||||
|
#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE | 0x70)
|
||||||
|
#define PCIE1_STATUS (PCIE1_VIRT_BASE | 0x1a04)
|
||||||
|
|
||||||
#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
|
#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
|
|||||||
static int __init mv88f6281gtw_ge_pci_init(void)
|
static int __init mv88f6281gtw_ge_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_mv88f6281gtw_ge())
|
if (machine_is_mv88f6281gtw_ge())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ static int __init openrd_pci_init(void)
|
|||||||
if (machine_is_openrd_base() ||
|
if (machine_is_openrd_base() ||
|
||||||
machine_is_openrd_client() ||
|
machine_is_openrd_client() ||
|
||||||
machine_is_openrd_ultimate())
|
machine_is_openrd_ultimate())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,29 +18,43 @@
|
|||||||
#include <mach/bridge-regs.h>
|
#include <mach/bridge-regs.h>
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
|
|
||||||
|
|
||||||
void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
|
void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
|
||||||
{
|
{
|
||||||
*dev = orion_pcie_dev_id(PCIE_BASE);
|
*dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
|
||||||
*rev = orion_pcie_rev(PCIE_BASE);
|
*rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcie_valid_config(int bus, int dev)
|
struct pcie_port {
|
||||||
|
u8 root_bus_nr;
|
||||||
|
void __iomem *base;
|
||||||
|
spinlock_t conf_lock;
|
||||||
|
int irq;
|
||||||
|
struct resource res[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
static int pcie_port_map[2];
|
||||||
|
static int num_pcie_ports;
|
||||||
|
|
||||||
|
static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
|
||||||
|
{
|
||||||
|
struct pci_sys_data *sys = bus->sysdata;
|
||||||
|
return sys->private_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Don't go out when trying to access --
|
* Don't go out when trying to access --
|
||||||
* 1. nonexisting device on local bus
|
* 1. nonexisting device on local bus
|
||||||
* 2. where there's no device connected (no link)
|
* 2. where there's no device connected (no link)
|
||||||
*/
|
*/
|
||||||
if (bus == 0 && dev == 0)
|
if (bus == pp->root_bus_nr && dev == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!orion_pcie_link_up(PCIE_BASE))
|
if (!orion_pcie_link_up(pp->base))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (bus == 0 && dev != 1)
|
if (bus == pp->root_bus_nr && dev != 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -52,22 +66,22 @@ static int pcie_valid_config(int bus, int dev)
|
|||||||
* and then reading the PCIE_CONF_DATA register. Need to make sure these
|
* and then reading the PCIE_CONF_DATA register. Need to make sure these
|
||||||
* transactions are atomic.
|
* transactions are atomic.
|
||||||
*/
|
*/
|
||||||
static DEFINE_SPINLOCK(kirkwood_pcie_lock);
|
|
||||||
|
|
||||||
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
||||||
int size, u32 *val)
|
int size, u32 *val)
|
||||||
{
|
{
|
||||||
|
struct pcie_port *pp = bus_to_port(bus);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) {
|
if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
|
||||||
*val = 0xffffffff;
|
*val = 0xffffffff;
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&kirkwood_pcie_lock, flags);
|
spin_lock_irqsave(&pp->conf_lock, flags);
|
||||||
ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
|
ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
|
||||||
spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
|
spin_unlock_irqrestore(&pp->conf_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -75,15 +89,16 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
|||||||
static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||||
int where, int size, u32 val)
|
int where, int size, u32 val)
|
||||||
{
|
{
|
||||||
|
struct pcie_port *pp = bus_to_port(bus);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0)
|
if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
spin_lock_irqsave(&kirkwood_pcie_lock, flags);
|
spin_lock_irqsave(&pp->conf_lock, flags);
|
||||||
ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
|
ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
|
||||||
spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
|
spin_unlock_irqrestore(&pp->conf_lock, flags);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -93,50 +108,112 @@ static struct pci_ops pcie_ops = {
|
|||||||
.write = pcie_wr_conf,
|
.write = pcie_wr_conf,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int __init pcie0_ioresources_setup(struct pci_sys_data *sys)
|
||||||
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
|
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct pcie_port *pp = (struct pcie_port *)sys->private_data;
|
||||||
extern unsigned int kirkwood_clk_ctrl;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Generic PCIe unit setup.
|
|
||||||
*/
|
|
||||||
orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Request resources.
|
|
||||||
*/
|
|
||||||
res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
|
|
||||||
if (!res)
|
|
||||||
panic("pcie_setup unable to alloc resources");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IORESOURCE_IO
|
* IORESOURCE_IO
|
||||||
*/
|
*/
|
||||||
res[0].name = "PCIe I/O Space";
|
pp->res[0].name = "PCIe 0 I/O Space";
|
||||||
res[0].flags = IORESOURCE_IO;
|
pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
|
||||||
res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
|
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
|
||||||
res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
|
pp->res[0].flags = IORESOURCE_IO;
|
||||||
if (request_resource(&ioport_resource, &res[0]))
|
if (request_resource(&ioport_resource, &pp->res[0]))
|
||||||
panic("Request PCIe IO resource failed\n");
|
panic("Request PCIe 0 IO resource failed\n");
|
||||||
sys->resource[0] = &res[0];
|
sys->resource[0] = &pp->res[0];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IORESOURCE_MEM
|
* IORESOURCE_MEM
|
||||||
*/
|
*/
|
||||||
res[1].name = "PCIe Memory Space";
|
pp->res[1].name = "PCIe 0 MEM";
|
||||||
res[1].flags = IORESOURCE_MEM;
|
pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
|
||||||
res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
|
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
|
||||||
res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
|
pp->res[1].flags = IORESOURCE_MEM;
|
||||||
if (request_resource(&iomem_resource, &res[1]))
|
if (request_resource(&iomem_resource, &pp->res[1]))
|
||||||
panic("Request PCIe Memory resource failed\n");
|
panic("Request PCIe 0 Memory resource failed\n");
|
||||||
sys->resource[1] = &res[1];
|
sys->resource[1] = &pp->res[1];
|
||||||
|
|
||||||
sys->resource[2] = NULL;
|
sys->resource[2] = NULL;
|
||||||
sys->io_offset = 0;
|
sys->io_offset = 0;
|
||||||
|
|
||||||
kirkwood_clk_ctrl |= CGC_PEX0;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init pcie1_ioresources_setup(struct pci_sys_data *sys)
|
||||||
|
{
|
||||||
|
struct pcie_port *pp = (struct pcie_port *)sys->private_data;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IORESOURCE_IO
|
||||||
|
*/
|
||||||
|
pp->res[0].name = "PCIe 1 I/O Space";
|
||||||
|
pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE;
|
||||||
|
pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
|
||||||
|
pp->res[0].flags = IORESOURCE_IO;
|
||||||
|
if (request_resource(&ioport_resource, &pp->res[0]))
|
||||||
|
panic("Request PCIe 1 IO resource failed\n");
|
||||||
|
sys->resource[0] = &pp->res[0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IORESOURCE_MEM
|
||||||
|
*/
|
||||||
|
pp->res[1].name = "PCIe 1 MEM";
|
||||||
|
pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
|
||||||
|
pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
|
||||||
|
pp->res[1].flags = IORESOURCE_MEM;
|
||||||
|
if (request_resource(&iomem_resource, &pp->res[1]))
|
||||||
|
panic("Request PCIe 1 Memory resource failed\n");
|
||||||
|
sys->resource[1] = &pp->res[1];
|
||||||
|
|
||||||
|
sys->resource[2] = NULL;
|
||||||
|
sys->io_offset = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
|
||||||
|
{
|
||||||
|
extern unsigned int kirkwood_clk_ctrl;
|
||||||
|
struct pcie_port *pp;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
if (nr >= num_pcie_ports)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
index = pcie_port_map[nr];
|
||||||
|
printk(KERN_INFO "PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
|
||||||
|
|
||||||
|
pp = kzalloc(sizeof(*pp), GFP_KERNEL);
|
||||||
|
if (!pp)
|
||||||
|
panic("PCIe: failed to allocate pcie_port data");
|
||||||
|
sys->private_data = pp;
|
||||||
|
pp->root_bus_nr = sys->busnr;
|
||||||
|
spin_lock_init(&pp->conf_lock);
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
pp->base = (void __iomem *)PCIE_VIRT_BASE;
|
||||||
|
pp->irq = IRQ_KIRKWOOD_PCIE;
|
||||||
|
kirkwood_clk_ctrl |= CGC_PEX0;
|
||||||
|
pcie0_ioresources_setup(sys);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
pp->base = (void __iomem *)PCIE1_VIRT_BASE;
|
||||||
|
pp->irq = IRQ_KIRKWOOD_PCIE1;
|
||||||
|
kirkwood_clk_ctrl |= CGC_PEX1;
|
||||||
|
pcie1_ioresources_setup(sys);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
panic("PCIe setup: invalid controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic PCIe unit setup.
|
||||||
|
*/
|
||||||
|
orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
|
||||||
|
|
||||||
|
orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -163,7 +240,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||||||
{
|
{
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
|
|
||||||
if (nr == 0) {
|
if (nr < num_pcie_ports) {
|
||||||
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
|
||||||
} else {
|
} else {
|
||||||
bus = NULL;
|
bus = NULL;
|
||||||
@ -175,18 +252,37 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
|
|||||||
|
|
||||||
static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
|
||||||
{
|
{
|
||||||
return IRQ_KIRKWOOD_PCIE;
|
struct pcie_port *pp = bus_to_port(dev->bus);
|
||||||
|
|
||||||
|
return pp->irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hw_pci kirkwood_pci __initdata = {
|
static struct hw_pci kirkwood_pci __initdata = {
|
||||||
.nr_controllers = 1,
|
|
||||||
.swizzle = pci_std_swizzle,
|
.swizzle = pci_std_swizzle,
|
||||||
.setup = kirkwood_pcie_setup,
|
.setup = kirkwood_pcie_setup,
|
||||||
.scan = kirkwood_pcie_scan_bus,
|
.scan = kirkwood_pcie_scan_bus,
|
||||||
.map_irq = kirkwood_pcie_map_irq,
|
.map_irq = kirkwood_pcie_map_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init kirkwood_pcie_init(void)
|
static void __init add_pcie_port(int index, unsigned long base)
|
||||||
{
|
{
|
||||||
|
printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
|
||||||
|
|
||||||
|
if (orion_pcie_link_up((void __iomem *)base)) {
|
||||||
|
printk(KERN_INFO "link up\n");
|
||||||
|
pcie_port_map[num_pcie_ports++] = index;
|
||||||
|
} else
|
||||||
|
printk(KERN_INFO "link down, ignoring\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init kirkwood_pcie_init(unsigned int portmask)
|
||||||
|
{
|
||||||
|
if (portmask & KW_PCIE0)
|
||||||
|
add_pcie_port(0, PCIE_VIRT_BASE);
|
||||||
|
|
||||||
|
if (portmask & KW_PCIE1)
|
||||||
|
add_pcie_port(1, PCIE1_VIRT_BASE);
|
||||||
|
|
||||||
|
kirkwood_pci.nr_controllers = num_pcie_ports;
|
||||||
pci_common_init(&kirkwood_pci);
|
pci_common_init(&kirkwood_pci);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ static void __init rd88f6192_init(void)
|
|||||||
static int __init rd88f6192_pci_init(void)
|
static int __init rd88f6192_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_rd88f6192_nas())
|
if (machine_is_rd88f6192_nas())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ static void __init rd88f6281_init(void)
|
|||||||
static int __init rd88f6281_pci_init(void)
|
static int __init rd88f6281_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_rd88f6281())
|
if (machine_is_rd88f6281())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ static void __init hp_t5325_init(void)
|
|||||||
static int __init hp_t5325_pci_init(void)
|
static int __init hp_t5325_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_t5325())
|
if (machine_is_t5325())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -111,10 +111,10 @@ static void __init qnap_ts219_init(void)
|
|||||||
|
|
||||||
static int __init ts219_pci_init(void)
|
static int __init ts219_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_ts219())
|
if (machine_is_ts219())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
subsys_initcall(ts219_pci_init);
|
subsys_initcall(ts219_pci_init);
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ static void __init qnap_ts41x_init(void)
|
|||||||
static int __init ts41x_pci_init(void)
|
static int __init ts41x_pci_init(void)
|
||||||
{
|
{
|
||||||
if (machine_is_ts41x())
|
if (machine_is_ts41x())
|
||||||
kirkwood_pcie_init();
|
kirkwood_pcie_init(KW_PCIE0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user