* [PATCH 1/3] [ARM] Kirkwood: add support for rev A1 of the 88f6192 and 88f6180 chips.
@ 2010-06-01 15:09 Saeed Bishara
2010-06-01 15:09 ` [PATCH 2/3] [ARM] Kirkwood: Add support for 88f6282 Saeed Bishara
0 siblings, 1 reply; 16+ messages in thread
From: Saeed Bishara @ 2010-06-01 15:09 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
arch/arm/mach-kirkwood/common.c | 4 ++++
arch/arm/mach-kirkwood/include/mach/kirkwood.h | 2 ++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 6072eaa..c780c4a 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -891,11 +891,15 @@ static char * __init kirkwood_id(void)
return "MV88F6192-Z0";
else if (rev == MV88F6192_REV_A0)
return "MV88F6192-A0";
+ else if (rev == MV88F6192_REV_A1)
+ return "MV88F6192-A1";
else
return "MV88F6192-Rev-Unsupported";
} else if (dev == MV88F6180_DEV_ID) {
if (rev == MV88F6180_REV_A0)
return "MV88F6180-Rev-A0";
+ else if (rev == MV88F6180_REV_A1)
+ return "MV88F6180-Rev-A1";
else
return "MV88F6180-Rev-Unsupported";
} else {
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index a15cf0e..d61b9aa 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -107,8 +107,10 @@
#define MV88F6192_DEV_ID 0x6192
#define MV88F6192_REV_Z0 0
#define MV88F6192_REV_A0 2
+#define MV88F6192_REV_A1 3
#define MV88F6180_DEV_ID 0x6180
#define MV88F6180_REV_A0 2
+#define MV88F6180_REV_A1 3
#endif
--
1.6.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] [ARM] Kirkwood: Add support for 88f6282
2010-06-01 15:09 [PATCH 1/3] [ARM] Kirkwood: add support for rev A1 of the 88f6192 and 88f6180 chips Saeed Bishara
@ 2010-06-01 15:09 ` Saeed Bishara
2010-06-01 15:09 ` [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1 Saeed Bishara
0 siblings, 1 reply; 16+ messages in thread
From: Saeed Bishara @ 2010-06-01 15:09 UTC (permalink / raw)
To: linux-arm-kernel
The 6282 SoC is compatible to 6280 and features faster CPU, DDR3, additional
PCIe interface, and LCD controller. More infromation can be found here:
http://www.marvell.com/products/processors/embedded/armada_300/armada_310.pdf
Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
arch/arm/mach-kirkwood/common.c | 13 ++++++++++---
arch/arm/mach-kirkwood/include/mach/kirkwood.h | 2 ++
arch/arm/mach-kirkwood/mpp.c | 3 ++-
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index c780c4a..4ccfdf9 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -402,7 +402,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data)
u32 dev, rev;
kirkwood_pcie_id(&dev, &rev);
- if (rev == 0) /* catch all Kirkwood Z0's */
+ if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */
mvsdio_data->clock = 100000000;
else
mvsdio_data->clock = 200000000;
@@ -847,8 +847,10 @@ int __init kirkwood_find_tclk(void)
u32 dev, rev;
kirkwood_pcie_id(&dev, &rev);
- if (dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 ||
- rev == MV88F6281_REV_A1))
+
+ if ((dev == MV88F6281_DEV_ID && (rev == MV88F6281_REV_A0 ||
+ rev == MV88F6281_REV_A1)) ||
+ (dev == MV88F6282_DEV_ID))
return 200000000;
return 166666667;
@@ -902,6 +904,11 @@ static char * __init kirkwood_id(void)
return "MV88F6180-Rev-A1";
else
return "MV88F6180-Rev-Unsupported";
+ } else if (dev == MV88F6282_DEV_ID) {
+ if (rev == MV88F6282_REV_A0)
+ return "MV88F6282-Rev-A0";
+ else
+ return "MV88F6282-Rev-Unsupported";
} else {
return "Device-Unknown";
}
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index d61b9aa..dd7eddb 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -113,4 +113,6 @@
#define MV88F6180_REV_A0 2
#define MV88F6180_REV_A1 3
+#define MV88F6282_DEV_ID 0x6282
+#define MV88F6282_REV_A0 0
#endif
diff --git a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c
index a5900f6..065187d 100644
--- a/arch/arm/mach-kirkwood/mpp.c
+++ b/arch/arm/mach-kirkwood/mpp.c
@@ -23,7 +23,8 @@ static unsigned int __init kirkwood_variant(void)
kirkwood_pcie_id(&dev, &rev);
- if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
+ if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) ||
+ (dev == MV88F6282_DEV_ID))
return MPP_F6281_MASK;
if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
return MPP_F6192_MASK;
--
1.6.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-01 15:09 ` [PATCH 2/3] [ARM] Kirkwood: Add support for 88f6282 Saeed Bishara
@ 2010-06-01 15:09 ` Saeed Bishara
2010-06-01 19:55 ` Nicolas Pitre
0 siblings, 1 reply; 16+ messages in thread
From: Saeed Bishara @ 2010-06-01 15:09 UTC (permalink / raw)
To: linux-arm-kernel
This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
arch/arm/mach-kirkwood/addr-map.c | 10 +-
arch/arm/mach-kirkwood/common.h | 2 +-
arch/arm/mach-kirkwood/db88f6281-bp-setup.c | 10 +-
arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 +
arch/arm/mach-kirkwood/include/mach/irqs.h | 1 +
arch/arm/mach-kirkwood/include/mach/kirkwood.h | 10 ++
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c | 2 +-
arch/arm/mach-kirkwood/openrd-setup.c | 2 +-
arch/arm/mach-kirkwood/pcie.c | 153 +++++++++++++++------
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | 2 +-
arch/arm/mach-kirkwood/rd88f6281-setup.c | 2 +-
arch/arm/mach-kirkwood/ts219-setup.c | 6 +-
arch/arm/mach-kirkwood/ts41x-setup.c | 2 +-
13 files changed, 151 insertions(+), 52 deletions(-)
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 2e69168..8d03bce 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -31,6 +31,8 @@
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
+#define ATTR_PCIE1_IO 0xd0
+#define ATTR_PCIE1_MEM 0xd8
#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);
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
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_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);
/*
* 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);
/*
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 05e8a8a..876f71a 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -34,7 +34,7 @@ void kirkwood_ehci_init(void);
void kirkwood_ge00_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_pcie_init(void);
+void kirkwood_pcie_init(int init_port0, int init_port1);
void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
void kirkwood_spi_init(void);
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 39bdf4b..b11b5fe 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -74,9 +74,15 @@ static void __init db88f6281_init(void)
static int __init db88f6281_pci_init(void)
{
- if (machine_is_db88f6281_bp())
- kirkwood_pcie_init();
+ if (machine_is_db88f6281_bp()) {
+ u32 dev, rev;
+ int init_port1 = 0;
+ kirkwood_pcie_id(&dev, &rev);
+ if (dev == MV88F6282_DEV_ID)
+ init_port1 = 1;
+ kirkwood_pcie_init(1, init_port1);
+ }
return 0;
}
subsys_initcall(db88f6281_pci_init);
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 418f501..2026b30 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -59,6 +59,7 @@
#define CGC_SATA1 (1 << 15)
#define CGC_XOR1 (1 << 16)
#define CGC_CRYPTO (1 << 17)
+#define CGC_PEX1 (1 << 18)
#define CGC_GE1 (1 << 19)
#define CGC_TDM (1 << 20)
#define CGC_RESERVED ((1 << 18) | (0x6 << 21))
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
index f00a0a4..9da2eb5 100644
--- a/arch/arm/mach-kirkwood/include/mach/irqs.h
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -23,6 +23,7 @@
#define IRQ_KIRKWOOD_XOR_10 7
#define IRQ_KIRKWOOD_XOR_11 8
#define IRQ_KIRKWOOD_PCIE 9
+#define IRQ_KIRKWOOD_PCIE1 10
#define IRQ_KIRKWOOD_GE00_SUM 11
#define IRQ_KIRKWOOD_GE01_SUM 15
#define IRQ_KIRKWOOD_USB 19
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index dd7eddb..058f06b 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -38,6 +38,11 @@
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
+#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf5000000
+#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfed00000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000
+#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
+
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000
#define KIRKWOOD_REGS_SIZE SZ_1M
@@ -46,6 +51,10 @@
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
+#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xd8000000
+#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xd8000000
+#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M
+
/*
* Register Map
*/
@@ -72,6 +81,7 @@
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
+#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 5e6f711..6e67f3c 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
static int __init mv88f6281gtw_ge_pci_init(void)
{
if (machine_is_mv88f6281gtw_ge())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(0, 1);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index ad3f1ec..4174f48 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -85,7 +85,7 @@ static void __init openrd_init(void)
static int __init openrd_pci_init(void)
{
if (machine_is_openrd_base() || machine_is_openrd_client())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(0, 1);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index dee1eff..5c33324 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -21,26 +21,40 @@
#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
+struct pcie_port {
+ u8 index;
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ char io_space_name[16];
+ char mem_space_name[16];
+ struct resource res[2];
+};
+
+static struct pcie_port pcie_port[2];
+static int num_pcie_ports;
+static struct pcie_port *bus_to_port(int bus);
+
void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
{
*dev = orion_pcie_dev_id(PCIE_BASE);
*rev = orion_pcie_rev(PCIE_BASE);
}
-static int pcie_valid_config(int bus, int dev)
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
{
/*
* Don't go out when trying to access --
* 1. nonexisting device on local bus
* 2. where there's no device connected (no link)
*/
- if (bus == 0 && dev == 0)
+ if (bus == pp->root_bus_nr && dev == 0)
return 1;
- if (!orion_pcie_link_up(PCIE_BASE))
+ if (!orion_pcie_link_up(pp->base))
return 0;
- if (bus == 0 && dev != 1)
+ if (bus == pp->root_bus_nr && dev != 1)
return 0;
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
* transactions are atomic.
*/
-static DEFINE_SPINLOCK(kirkwood_pcie_lock);
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
+ struct pcie_port *pp = bus_to_port(bus->number);
unsigned long flags;
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;
return PCIBIOS_DEVICE_NOT_FOUND;
}
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
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,
int where, int size, u32 val)
{
+ struct pcie_port *pp = bus_to_port(bus->number);
unsigned long flags;
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;
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret;
}
@@ -96,51 +111,84 @@ static struct pci_ops pcie_ops = {
static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
{
- struct resource *res;
extern unsigned int kirkwood_clk_ctrl;
+ struct pcie_port *pp;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ pp = &pcie_port[nr];
+ pp->root_bus_nr = sys->busnr;
/*
* Generic PCIe unit setup.
*/
- orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
+ orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
+
+ orion_pcie_setup(pp->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
*/
- res[0].name = "PCIe I/O Space";
- res[0].flags = IORESOURCE_IO;
- res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
- res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
- if (request_resource(&ioport_resource, &res[0]))
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+ pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
+ } else {
+ 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 IO resource failed\n");
- sys->resource[0] = &res[0];
+ sys->resource[0] = &pp->res[0];
/*
* IORESOURCE_MEM
*/
- res[1].name = "PCIe Memory Space";
- res[1].flags = IORESOURCE_MEM;
- res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
- res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
- if (request_resource(&iomem_resource, &res[1]))
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
+ } else {
+ 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 Memory resource failed\n");
- sys->resource[1] = &res[1];
+ sys->resource[1] = &pp->res[1];
sys->resource[2] = NULL;
sys->io_offset = 0;
- kirkwood_clk_ctrl |= CGC_PEX0;
-
+ if (nr == 0)
+ kirkwood_clk_ctrl |= CGC_PEX0;
+ else
+ kirkwood_clk_ctrl |= CGC_PEX1;
return 1;
}
+static struct pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = num_pcie_ports - 1; i >= 0; i--) {
+ int rbus = pcie_port[i].root_bus_nr;
+ if (rbus != -1 && rbus <= bus)
+ break;
+ }
+
+ return i >= 0 ? pcie_port + i : NULL;
+}
+
static void __devinit rc_pci_fixup(struct pci_dev *dev)
{
/*
@@ -163,7 +211,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct pci_bus *bus;
- if (nr == 0) {
+ if (nr < num_pcie_ports) {
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
} else {
bus = NULL;
@@ -175,18 +223,45 @@ 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)
{
- return IRQ_KIRKWOOD_PCIE;
+ struct pcie_port *pp = bus_to_port(dev->bus->number);
+
+ return pp->index ? IRQ_KIRKWOOD_PCIE1 : IRQ_KIRKWOOD_PCIE;
}
static struct hw_pci kirkwood_pci __initdata = {
- .nr_controllers = 1,
+ .nr_controllers = 2,
.swizzle = pci_std_swizzle,
.setup = kirkwood_pcie_setup,
.scan = kirkwood_pcie_scan_bus,
.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)) {
+ struct pcie_port *pp = &pcie_port[num_pcie_ports++];
+
+ printk(KERN_INFO "link up\n");
+
+ pp->index = index;
+ pp->root_bus_nr = -1;
+ pp->base = (void __iomem *)base;
+ spin_lock_init(&pp->conf_lock);
+ memset(pp->res, 0, sizeof(pp->res));
+ } else {
+ printk(KERN_INFO "link down, ignoring\n");
+ }
+}
+
+void __init kirkwood_pcie_init(int init_port0, int init_port1)
+{
+ if (init_port0)
+ add_pcie_port(0, PCIE_VIRT_BASE);
+
+ if (init_port1)
+ add_pcie_port(1, PCIE1_VIRT_BASE);
+
pci_common_init(&kirkwood_pci);
}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 3bf6304..e982bb7 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -71,7 +71,7 @@ static void __init rd88f6192_init(void)
static int __init rd88f6192_pci_init(void)
{
if (machine_is_rd88f6192_nas())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(0, 1);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 31708dd..5b455b2 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -107,7 +107,7 @@ static void __init rd88f6281_init(void)
static int __init rd88f6281_pci_init(void)
{
if (machine_is_rd88f6281())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(0, 1);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index 2830f0f..5fe8811 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -110,10 +110,10 @@ static void __init qnap_ts219_init(void)
static int __init ts219_pci_init(void)
{
- if (machine_is_ts219())
- kirkwood_pcie_init();
+ if (machine_is_ts219())
+ kirkwood_pcie_init(1, 0);
- return 0;
+ return 0;
}
subsys_initcall(ts219_pci_init);
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index de49c2d..8505d30 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -136,7 +136,7 @@ static void __init qnap_ts41x_init(void)
static int __init ts41x_pci_init(void)
{
if (machine_is_ts41x())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(1, 0);
return 0;
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-01 15:09 ` [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1 Saeed Bishara
@ 2010-06-01 19:55 ` Nicolas Pitre
2010-06-02 10:34 ` saeed bishara
2010-06-03 11:43 ` saeed bishara
0 siblings, 2 replies; 16+ messages in thread
From: Nicolas Pitre @ 2010-06-01 19:55 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, 1 Jun 2010, Saeed Bishara wrote:
> This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
>
> Signed-off-by: Saeed Bishara <saeed@marvell.com>
Comments below.
[...]
> diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
> index 5e6f711..6e67f3c 100644
> --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
> +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
> @@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
> static int __init mv88f6281gtw_ge_pci_init(void)
> {
> if (machine_is_mv88f6281gtw_ge())
> - kirkwood_pcie_init();
> + kirkwood_pcie_init(0, 1);
This is going to initialize the non existing PCIe1 and disable PCIe0.
You made the same mistake multiple times.
[...]
> diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
> index dee1eff..5c33324 100644
> --- a/arch/arm/mach-kirkwood/pcie.c
> +++ b/arch/arm/mach-kirkwood/pcie.c
> @@ -21,26 +21,40 @@
>
> #define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
Is this PCIE_BASE still used?
> +struct pcie_port {
> + u8 index;
> + u8 root_bus_nr;
> + void __iomem *base;
> + spinlock_t conf_lock;
> + char io_space_name[16];
> + char mem_space_name[16];
> + struct resource res[2];
> +};
> +
> +static struct pcie_port pcie_port[2];
> +static int num_pcie_ports;
> +static struct pcie_port *bus_to_port(int bus);
You should move the actual function here allowing you to get rid of that
forward declaration.
> void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
> {
> *dev = orion_pcie_dev_id(PCIE_BASE);
> *rev = orion_pcie_rev(PCIE_BASE);
> }
>
> -static int pcie_valid_config(int bus, int dev)
> +static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
> {
> /*
> * Don't go out when trying to access --
> * 1. nonexisting device on local bus
> * 2. where there's no device connected (no link)
> */
> - if (bus == 0 && dev == 0)
> + if (bus == pp->root_bus_nr && dev == 0)
> return 1;
>
> - if (!orion_pcie_link_up(PCIE_BASE))
> + if (!orion_pcie_link_up(pp->base))
> return 0;
>
> - if (bus == 0 && dev != 1)
> + if (bus == pp->root_bus_nr && dev != 1)
> return 0;
>
> 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
> * transactions are atomic.
> */
> -static DEFINE_SPINLOCK(kirkwood_pcie_lock);
>
> static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> int size, u32 *val)
> {
> + struct pcie_port *pp = bus_to_port(bus->number);
> unsigned long flags;
> 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;
> return PCIBIOS_DEVICE_NOT_FOUND;
> }
>
> - spin_lock_irqsave(&kirkwood_pcie_lock, flags);
> - ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
> - spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
> + spin_lock_irqsave(&pp->conf_lock, flags);
> + ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
> + spin_unlock_irqrestore(&pp->conf_lock, flags);
>
> 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,
> int where, int size, u32 val)
> {
> + struct pcie_port *pp = bus_to_port(bus->number);
> unsigned long flags;
> 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;
>
> - spin_lock_irqsave(&kirkwood_pcie_lock, flags);
> - ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
> - spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
> + spin_lock_irqsave(&pp->conf_lock, flags);
> + ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
> + spin_unlock_irqrestore(&pp->conf_lock, flags);
>
> return ret;
> }
> @@ -96,51 +111,84 @@ static struct pci_ops pcie_ops = {
>
> static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
> {
> - struct resource *res;
> extern unsigned int kirkwood_clk_ctrl;
> + struct pcie_port *pp;
> +
> + if (nr >= num_pcie_ports)
> + return 0;
> +
> + pp = &pcie_port[nr];
> + pp->root_bus_nr = sys->busnr;
>
> /*
> * Generic PCIe unit setup.
> */
> - orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
> + orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
> +
> + orion_pcie_setup(pp->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
> */
> - res[0].name = "PCIe I/O Space";
> - res[0].flags = IORESOURCE_IO;
> - res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
> - res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
> - if (request_resource(&ioport_resource, &res[0]))
> + snprintf(pp->io_space_name, sizeof(pp->io_space_name),
> + "PCIe %d I/O", pp->index);
> + pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
> + pp->res[0].name = pp->io_space_name;
> + if (pp->index == 0) {
> + pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
> + pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
> + } else {
> + 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 IO resource failed\n");
> - sys->resource[0] = &res[0];
> + sys->resource[0] = &pp->res[0];
>
> /*
> * IORESOURCE_MEM
> */
> - res[1].name = "PCIe Memory Space";
> - res[1].flags = IORESOURCE_MEM;
> - res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
> - res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
> - if (request_resource(&iomem_resource, &res[1]))
> + snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
> + "PCIe %d MEM", pp->index);
> + pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
> + pp->res[1].name = pp->mem_space_name;
> + if (pp->index == 0) {
> + pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
> + pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
> + } else {
> + 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 Memory resource failed\n");
> - sys->resource[1] = &res[1];
> + sys->resource[1] = &pp->res[1];
>
> sys->resource[2] = NULL;
> sys->io_offset = 0;
>
> - kirkwood_clk_ctrl |= CGC_PEX0;
> -
> + if (nr == 0)
> + kirkwood_clk_ctrl |= CGC_PEX0;
> + else
> + kirkwood_clk_ctrl |= CGC_PEX1;
> return 1;
> }
>
> +static struct pcie_port *bus_to_port(int bus)
> +{
> + int i;
> +
> + for (i = num_pcie_ports - 1; i >= 0; i--) {
> + int rbus = pcie_port[i].root_bus_nr;
> + if (rbus != -1 && rbus <= bus)
> + break;
> + }
> +
> + return i >= 0 ? pcie_port + i : NULL;
> +}
I think this looks like a bit too much code for what this does. To
simplify things, you could:
1) Duplicate kirkwood_pcie_setup() into kirkwood_pcie0_setup() and
kirkwood_pcie1_setup() instead. This will remove a couple
"if (pp->index == 0)" and the snprintf() which could remain
purely static initializations.
2) Remove bus_to_port() entirely, and store the address of the appropriate
struct pcie_port instance into the sysdata pointer of the pci_bus
structure. This struct pcie_port could even be kmalloc'd as needed.
> static void __devinit rc_pci_fixup(struct pci_dev *dev)
> {
> /*
> @@ -163,7 +211,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> {
> struct pci_bus *bus;
>
> - if (nr == 0) {
> + if (nr < num_pcie_ports) {
> bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
> } else {
> bus = NULL;
> @@ -175,18 +223,45 @@ 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)
> {
> - return IRQ_KIRKWOOD_PCIE;
> + struct pcie_port *pp = bus_to_port(dev->bus->number);
> +
> + return pp->index ? IRQ_KIRKWOOD_PCIE1 : IRQ_KIRKWOOD_PCIE;
Maybe having pp->irq and returning that directly would be better.
> static struct hw_pci kirkwood_pci __initdata = {
> - .nr_controllers = 1,
> + .nr_controllers = 2,
I think this should be initialized at run time to 2 only when running on
a 6282.
> .swizzle = pci_std_swizzle,
> .setup = kirkwood_pcie_setup,
> .scan = kirkwood_pcie_scan_bus,
> .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)) {
> + struct pcie_port *pp = &pcie_port[num_pcie_ports++];
> +
> + printk(KERN_INFO "link up\n");
> +
> + pp->index = index;
> + pp->root_bus_nr = -1;
> + pp->base = (void __iomem *)base;
> + spin_lock_init(&pp->conf_lock);
> + memset(pp->res, 0, sizeof(pp->res));
> + } else {
> + printk(KERN_INFO "link down, ignoring\n");
> + }
> +}
> +
> +void __init kirkwood_pcie_init(int init_port0, int init_port1)
And instead of having (int init_port0, int init_port1), this should be
(int port) which is much less error prone as demonstrated by your own
kirkwood_pcie_init(0, 1) usage. Those machines with both PCIe ports
would simply have to call this twice.
Nicolas
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-01 19:55 ` Nicolas Pitre
@ 2010-06-02 10:34 ` saeed bishara
2010-06-02 19:29 ` Nicolas Pitre
2010-06-03 11:43 ` saeed bishara
1 sibling, 1 reply; 16+ messages in thread
From: saeed bishara @ 2010-06-02 10:34 UTC (permalink / raw)
To: linux-arm-kernel
> I think this looks like a bit too much code for what this does. ?To
> simplify things, you could:
>
> 1) Duplicate kirkwood_pcie_setup() into kirkwood_pcie0_setup() and
> ? kirkwood_pcie1_setup() instead. ?This will remove a couple
> ? "if (pp->index == 0)" and the snprintf() which could remain
> ? purely static initializations.
>
> 2) Remove bus_to_port() entirely, and store the address of the appropriate
> ? struct pcie_port instance into the sysdata pointer of the pci_bus
> ? structure. ?This struct pcie_port could even be kmalloc'd as needed.
The sysdata already used by arm to store the pci_sys_data, I think we
will have to add a private pointer to the pci_sys_data structure, that
pointer will hold mach specific data per pci controller. this pointer
is needed for any platform that has multiple pci controller. agree?
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-02 10:34 ` saeed bishara
@ 2010-06-02 19:29 ` Nicolas Pitre
0 siblings, 0 replies; 16+ messages in thread
From: Nicolas Pitre @ 2010-06-02 19:29 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, 2 Jun 2010, saeed bishara wrote:
> > I think this looks like a bit too much code for what this does. ?To
> > simplify things, you could:
> >
> > 1) Duplicate kirkwood_pcie_setup() into kirkwood_pcie0_setup() and
> > ? kirkwood_pcie1_setup() instead. ?This will remove a couple
> > ? "if (pp->index == 0)" and the snprintf() which could remain
> > ? purely static initializations.
> >
> > 2) Remove bus_to_port() entirely, and store the address of the appropriate
> > ? struct pcie_port instance into the sysdata pointer of the pci_bus
> > ? structure. ?This struct pcie_port could even be kmalloc'd as needed.
> The sysdata already used by arm to store the pci_sys_data,
Ah, you're right.
> I think we will have to add a private pointer to the pci_sys_data
> structure, that pointer will hold mach specific data per pci
> controller. this pointer is needed for any platform that has multiple
> pci controller. agree?
Yes.
Nicolas
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-01 19:55 ` Nicolas Pitre
2010-06-02 10:34 ` saeed bishara
@ 2010-06-03 11:43 ` saeed bishara
2010-06-03 16:30 ` Nicolas Pitre
1 sibling, 1 reply; 16+ messages in thread
From: saeed bishara @ 2010-06-03 11:43 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jun 1, 2010 at 10:55 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> On Tue, 1 Jun 2010, Saeed Bishara wrote:
>
>> This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
>>
>> Signed-off-by: Saeed Bishara <saeed@marvell.com>
>
> Comments below.
>
> [...]
>> diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
>> index 5e6f711..6e67f3c 100644
>> --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
>> +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
>> @@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
>> ?static int __init mv88f6281gtw_ge_pci_init(void)
>> ?{
>> ? ? ? if (machine_is_mv88f6281gtw_ge())
>> - ? ? ? ? ? ? kirkwood_pcie_init();
>> + ? ? ? ? ? ? kirkwood_pcie_init(0, 1);
>
> This is going to initialize the non existing PCIe1 and disable PCIe0.
> You made the same mistake multiple times.
right :(
>
> [...]
>> diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
>> index dee1eff..5c33324 100644
>> --- a/arch/arm/mach-kirkwood/pcie.c
>> +++ b/arch/arm/mach-kirkwood/pcie.c
>> @@ -21,26 +21,40 @@
>>
>> ?#define PCIE_BASE ? ?((void __iomem *)PCIE_VIRT_BASE)
>
> Is this PCIE_BASE still used?
yes, but as it only used by kirkwood_pcei_id(), it will be removed
>
>> +struct pcie_port {
>> + ? ? u8 ? ? ? ? ? ? ? ? ? ? ?index;
>> + ? ? u8 ? ? ? ? ? ? ? ? ? ? ?root_bus_nr;
>> + ? ? void __iomem ? ? ? ? ? ?*base;
>> + ? ? spinlock_t ? ? ? ? ? ? ?conf_lock;
>> + ? ? char ? ? ? ? ? ? ? ? ? ?io_space_name[16];
>> + ? ? char ? ? ? ? ? ? ? ? ? ?mem_space_name[16];
>> + ? ? struct resource ? ? ? ? res[2];
>> +};
>> +
>> +static struct pcie_port pcie_port[2];
>> +static int num_pcie_ports;
>> +static struct pcie_port *bus_to_port(int bus);
>
> You should move the actual function here allowing you to get rid of that
> forward declaration.
>
>
>> ?void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
>> ?{
>> ? ? ? *dev = orion_pcie_dev_id(PCIE_BASE);
>> ? ? ? *rev = orion_pcie_rev(PCIE_BASE);
>> ?}
>>
>> -static int pcie_valid_config(int bus, int dev)
>> +static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
>> ?{
>> ? ? ? /*
>> ? ? ? ?* Don't go out when trying to access --
>> ? ? ? ?* 1. nonexisting device on local bus
>> ? ? ? ?* 2. where there's no device connected (no link)
>> ? ? ? ?*/
>> - ? ? if (bus == 0 && dev == 0)
>> + ? ? if (bus == pp->root_bus_nr && dev == 0)
>> ? ? ? ? ? ? ? return 1;
>>
>> - ? ? if (!orion_pcie_link_up(PCIE_BASE))
>> + ? ? if (!orion_pcie_link_up(pp->base))
>> ? ? ? ? ? ? ? return 0;
>>
>> - ? ? if (bus == 0 && dev != 1)
>> + ? ? if (bus == pp->root_bus_nr && dev != 1)
>> ? ? ? ? ? ? ? return 0;
>>
>> ? ? ? 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
>> ? * transactions are atomic.
>> ? */
>> -static DEFINE_SPINLOCK(kirkwood_pcie_lock);
>>
>> ?static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>> ? ? ? ? ? ? ? ? ? ? ? int size, u32 *val)
>> ?{
>> + ? ? struct pcie_port *pp = bus_to_port(bus->number);
>> ? ? ? unsigned long flags;
>> ? ? ? 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;
>> ? ? ? ? ? ? ? return PCIBIOS_DEVICE_NOT_FOUND;
>> ? ? ? }
>>
>> - ? ? spin_lock_irqsave(&kirkwood_pcie_lock, flags);
>> - ? ? ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
>> - ? ? spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
>> + ? ? spin_lock_irqsave(&pp->conf_lock, flags);
>> + ? ? ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
>> + ? ? spin_unlock_irqrestore(&pp->conf_lock, flags);
>>
>> ? ? ? 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,
>> ? ? ? ? ? ? ? ? ? ? ? int where, int size, u32 val)
>> ?{
>> + ? ? struct pcie_port *pp = bus_to_port(bus->number);
>> ? ? ? unsigned long flags;
>> ? ? ? 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;
>>
>> - ? ? spin_lock_irqsave(&kirkwood_pcie_lock, flags);
>> - ? ? ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
>> - ? ? spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
>> + ? ? spin_lock_irqsave(&pp->conf_lock, flags);
>> + ? ? ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
>> + ? ? spin_unlock_irqrestore(&pp->conf_lock, flags);
>>
>> ? ? ? return ret;
>> ?}
>> @@ -96,51 +111,84 @@ static struct pci_ops pcie_ops = {
>>
>> ?static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
>> ?{
>> - ? ? struct resource *res;
>> ? ? ? extern unsigned int kirkwood_clk_ctrl;
>> + ? ? struct pcie_port *pp;
>> +
>> + ? ? if (nr >= num_pcie_ports)
>> + ? ? ? ? ? ? return 0;
>> +
>> + ? ? pp = &pcie_port[nr];
>> + ? ? pp->root_bus_nr = sys->busnr;
>>
>> ? ? ? /*
>> ? ? ? ?* Generic PCIe unit setup.
>> ? ? ? ?*/
>> - ? ? orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
>> + ? ? orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
>> +
>> + ? ? orion_pcie_setup(pp->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
>> ? ? ? ?*/
>> - ? ? res[0].name = "PCIe I/O Space";
>> - ? ? res[0].flags = IORESOURCE_IO;
>> - ? ? res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
>> - ? ? res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
>> - ? ? if (request_resource(&ioport_resource, &res[0]))
>> + ? ? snprintf(pp->io_space_name, sizeof(pp->io_space_name),
>> + ? ? ? ? ? ? ?"PCIe %d I/O", pp->index);
>> + ? ? pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
>> + ? ? pp->res[0].name = pp->io_space_name;
>> + ? ? if (pp->index == 0) {
>> + ? ? ? ? ? ? pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
>> + ? ? ? ? ? ? pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
>> + ? ? } else {
>> + ? ? ? ? ? ? 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 IO resource failed\n");
>> - ? ? sys->resource[0] = &res[0];
>> + ? ? sys->resource[0] = &pp->res[0];
>>
>> ? ? ? /*
>> ? ? ? ?* IORESOURCE_MEM
>> ? ? ? ?*/
>> - ? ? res[1].name = "PCIe Memory Space";
>> - ? ? res[1].flags = IORESOURCE_MEM;
>> - ? ? res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
>> - ? ? res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
>> - ? ? if (request_resource(&iomem_resource, &res[1]))
>> + ? ? snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
>> + ? ? ? ? ? ? ?"PCIe %d MEM", pp->index);
>> + ? ? pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
>> + ? ? pp->res[1].name = pp->mem_space_name;
>> + ? ? if (pp->index == 0) {
>> + ? ? ? ? ? ? pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
>> + ? ? ? ? ? ? pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
>> + ? ? } else {
>> + ? ? ? ? ? ? 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 Memory resource failed\n");
>> - ? ? sys->resource[1] = &res[1];
>> + ? ? sys->resource[1] = &pp->res[1];
>>
>> ? ? ? sys->resource[2] = NULL;
>> ? ? ? sys->io_offset = 0;
>>
>> - ? ? kirkwood_clk_ctrl |= CGC_PEX0;
>> -
>> + ? ? if (nr == 0)
>> + ? ? ? ? ? ? kirkwood_clk_ctrl |= CGC_PEX0;
>> + ? ? else
>> + ? ? ? ? ? ? kirkwood_clk_ctrl |= CGC_PEX1;
>> ? ? ? return 1;
>> ?}
>>
>> +static struct pcie_port *bus_to_port(int bus)
>> +{
>> + ? ? int i;
>> +
>> + ? ? for (i = num_pcie_ports - 1; i >= 0; i--) {
>> + ? ? ? ? ? ? int rbus = pcie_port[i].root_bus_nr;
>> + ? ? ? ? ? ? if (rbus != -1 && rbus <= bus)
>> + ? ? ? ? ? ? ? ? ? ? break;
>> + ? ? }
>> +
>> + ? ? return i >= 0 ? pcie_port + i : NULL;
>> +}
>
> I think this looks like a bit too much code for what this does. ?To
> simplify things, you could:
>
> 1) Duplicate kirkwood_pcie_setup() into kirkwood_pcie0_setup() and
> ? kirkwood_pcie1_setup() instead. ?This will remove a couple
> ? "if (pp->index == 0)" and the snprintf() which could remain
> ? purely static initializations.
>
> 2) Remove bus_to_port() entirely, and store the address of the appropriate
> ? struct pcie_port instance into the sysdata pointer of the pci_bus
> ? structure. ?This struct pcie_port could even be kmalloc'd as needed.
>
>> ?static void __devinit rc_pci_fixup(struct pci_dev *dev)
>> ?{
>> ? ? ? /*
>> @@ -163,7 +211,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>> ?{
>> ? ? ? struct pci_bus *bus;
>>
>> - ? ? if (nr == 0) {
>> + ? ? if (nr < num_pcie_ports) {
>> ? ? ? ? ? ? ? bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
>> ? ? ? } else {
>> ? ? ? ? ? ? ? bus = NULL;
>> @@ -175,18 +223,45 @@ 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)
>> ?{
>> - ? ? return IRQ_KIRKWOOD_PCIE;
>> + ? ? struct pcie_port *pp = bus_to_port(dev->bus->number);
>> +
>> + ? ? return pp->index ? IRQ_KIRKWOOD_PCIE1 : IRQ_KIRKWOOD_PCIE;
>
> Maybe having pp->irq and returning that directly would be better.
>
>> ?static struct hw_pci kirkwood_pci __initdata = {
>> - ? ? .nr_controllers = 1,
>> + ? ? .nr_controllers = 2,
>
> I think this should be initialized at run time to 2 only when running on
> a 6282.
I will set it to number of requested ports that have a link
>
>> ? ? ? .swizzle ? ? ? ?= pci_std_swizzle,
>> ? ? ? .setup ? ? ? ? ?= kirkwood_pcie_setup,
>> ? ? ? .scan ? ? ? ? ? = kirkwood_pcie_scan_bus,
>> ? ? ? .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)) {
>> + ? ? ? ? ? ? struct pcie_port *pp = &pcie_port[num_pcie_ports++];
>> +
>> + ? ? ? ? ? ? printk(KERN_INFO "link up\n");
>> +
>> + ? ? ? ? ? ? pp->index = index;
>> + ? ? ? ? ? ? pp->root_bus_nr = -1;
>> + ? ? ? ? ? ? pp->base = (void __iomem *)base;
>> + ? ? ? ? ? ? spin_lock_init(&pp->conf_lock);
>> + ? ? ? ? ? ? memset(pp->res, 0, sizeof(pp->res));
>> + ? ? } else {
>> + ? ? ? ? ? ? printk(KERN_INFO "link down, ignoring\n");
>> + ? ? }
>> +}
>> +
>> +void __init kirkwood_pcie_init(int init_port0, int init_port1)
>
> And instead of having (int init_port0, int init_port1), this should be
> (int port) which is much less error prone as demonstrated by your own
> kirkwood_pcie_init(0, 1) usage. ?Those machines with both PCIe ports
> would simply have to call this twice.
nico, this is different from other controller, we can't have multiple
registrations as the pci_commont_init() can't be called multiple
times.
>
>
> Nicolas
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1
2010-06-03 11:43 ` saeed bishara
@ 2010-06-03 16:30 ` Nicolas Pitre
2010-06-06 10:24 ` [PATCH 3/3 v3] " Saeed Bishara
0 siblings, 1 reply; 16+ messages in thread
From: Nicolas Pitre @ 2010-06-03 16:30 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 3 Jun 2010, saeed bishara wrote:
> On Tue, Jun 1, 2010 at 10:55 PM, Nicolas Pitre <nico@fluxnic.net> wrote:
> > On Tue, 1 Jun 2010, Saeed Bishara wrote:
> >> +void __init kirkwood_pcie_init(int init_port0, int init_port1)
> >
> > And instead of having (int init_port0, int init_port1), this should be
> > (int port) which is much less error prone as demonstrated by your own
> > kirkwood_pcie_init(0, 1) usage. ?Those machines with both PCIe ports
> > would simply have to call this twice.
> nico, this is different from other controller, we can't have multiple
> registrations as the pci_commont_init() can't be called multiple
> times.
OK. In that case that would be better to have only one argument and
define some flag bits for it:
#define KW_PCIE0 (1 << 0)
#define KW_PCIE1 (1 << 1)
void __init kirkwood_pcie_init(int portmask)
And usage would be:
kirkwood_pcie_init(KW_PCIE0 | KW_PCIE1);
This is much easier to review, and less prone to errors.
Nicolas
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v3] [ARM] Kirkwood: add support for PCIe1
2010-06-03 16:30 ` Nicolas Pitre
@ 2010-06-06 10:24 ` Saeed Bishara
2010-06-07 8:04 ` Benjamin Zores
0 siblings, 1 reply; 16+ messages in thread
From: Saeed Bishara @ 2010-06-06 10:24 UTC (permalink / raw)
To: linux-arm-kernel
This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
arch/arm/mach-kirkwood/addr-map.c | 10 +-
arch/arm/mach-kirkwood/common.h | 5 +-
arch/arm/mach-kirkwood/db88f6281-bp-setup.c | 10 +-
arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 +
arch/arm/mach-kirkwood/include/mach/irqs.h | 1 +
arch/arm/mach-kirkwood/include/mach/kirkwood.h | 10 +
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c | 2 +-
arch/arm/mach-kirkwood/openrd-setup.c | 2 +-
arch/arm/mach-kirkwood/pcie.c | 187 +++++++++++++++-----
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | 2 +-
arch/arm/mach-kirkwood/rd88f6281-setup.c | 2 +-
arch/arm/mach-kirkwood/ts219-setup.c | 6 +-
arch/arm/mach-kirkwood/ts41x-setup.c | 2 +-
13 files changed, 180 insertions(+), 60 deletions(-)
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 2e69168..8d03bce 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -31,6 +31,8 @@
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
+#define ATTR_PCIE1_IO 0xd0
+#define ATTR_PCIE1_MEM 0xd8
#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);
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
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_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);
/*
* 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);
/*
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 05e8a8a..5b2c1c1 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -18,6 +18,9 @@ struct mvsdio_platform_data;
struct mtd_partition;
struct mtd_info;
+#define KW_PCIE0 (1 << 0)
+#define KW_PCIE1 (1 << 1)
+
/*
* 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_ge01_init(struct mv643xx_eth_platform_data *eth_data);
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_sdio_init(struct mvsdio_platform_data *mvsdio_data);
void kirkwood_spi_init(void);
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 39bdf4b..c428348 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -74,9 +74,15 @@ static void __init db88f6281_init(void)
static int __init db88f6281_pci_init(void)
{
- if (machine_is_db88f6281_bp())
- kirkwood_pcie_init();
+ if (machine_is_db88f6281_bp()) {
+ 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;
}
subsys_initcall(db88f6281_pci_init);
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 418f501..2026b30 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -59,6 +59,7 @@
#define CGC_SATA1 (1 << 15)
#define CGC_XOR1 (1 << 16)
#define CGC_CRYPTO (1 << 17)
+#define CGC_PEX1 (1 << 18)
#define CGC_GE1 (1 << 19)
#define CGC_TDM (1 << 20)
#define CGC_RESERVED ((1 << 18) | (0x6 << 21))
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
index f00a0a4..9da2eb5 100644
--- a/arch/arm/mach-kirkwood/include/mach/irqs.h
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -23,6 +23,7 @@
#define IRQ_KIRKWOOD_XOR_10 7
#define IRQ_KIRKWOOD_XOR_11 8
#define IRQ_KIRKWOOD_PCIE 9
+#define IRQ_KIRKWOOD_PCIE1 10
#define IRQ_KIRKWOOD_GE00_SUM 11
#define IRQ_KIRKWOOD_GE01_SUM 15
#define IRQ_KIRKWOOD_USB 19
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index dd7eddb..058f06b 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -38,6 +38,11 @@
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
+#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf5000000
+#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfed00000
+#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000
+#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
+
#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000
#define KIRKWOOD_REGS_SIZE SZ_1M
@@ -46,6 +51,10 @@
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
+#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xd8000000
+#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xd8000000
+#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M
+
/*
* Register Map
*/
@@ -72,6 +81,7 @@
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
+#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 5e6f711..c6b92b4 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
static int __init mv88f6281gtw_ge_pci_init(void)
{
if (machine_is_mv88f6281gtw_ge())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index ad3f1ec..2400207 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -85,7 +85,7 @@ static void __init openrd_init(void)
static int __init openrd_pci_init(void)
{
if (machine_is_openrd_base() || machine_is_openrd_client())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index dee1eff..89201a9 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -18,29 +18,43 @@
#include <mach/bridge-regs.h>
#include "common.h"
+void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
+ *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
+}
-#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
+struct pcie_port {
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ int irq;
+ struct resource res[2];
+};
-void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+static int pcie_port_map[2];
+static int num_pcie_ports;
+
+static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
{
- *dev = orion_pcie_dev_id(PCIE_BASE);
- *rev = orion_pcie_rev(PCIE_BASE);
+ struct pci_sys_data *sys = bus->sysdata;
+ return sys->private_data;
}
-static int pcie_valid_config(int bus, int dev)
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
{
/*
* Don't go out when trying to access --
* 1. nonexisting device on local bus
* 2. where there's no device connected (no link)
*/
- if (bus == 0 && dev == 0)
+ if (bus == pp->root_bus_nr && dev == 0)
return 1;
- if (!orion_pcie_link_up(PCIE_BASE))
+ if (!orion_pcie_link_up(pp->base))
return 0;
- if (bus == 0 && dev != 1)
+ if (bus == pp->root_bus_nr && dev != 1)
return 0;
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
* transactions are atomic.
*/
-static DEFINE_SPINLOCK(kirkwood_pcie_lock);
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
+ struct pcie_port *pp = bus_to_port(bus);
unsigned long flags;
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;
return PCIBIOS_DEVICE_NOT_FOUND;
}
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
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,
int where, int size, u32 val)
{
+ struct pcie_port *pp = bus_to_port(bus);
unsigned long flags;
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;
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret;
}
@@ -93,50 +108,109 @@ static struct pci_ops pcie_ops = {
.write = pcie_wr_conf,
};
-
-static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+static int __init pcie0_ioresouces_setup(struct pci_sys_data *sys)
{
- struct resource *res;
- extern unsigned int kirkwood_clk_ctrl;
-
+ struct pcie_port *pp = (struct pcie_port *)sys->private_data;
/*
- * Generic PCIe unit setup.
+ * IORESOURCE_IO
*/
- orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
+ pp->res[0].name = "PCIe 0 I/O Space";
+ pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+ pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe 0 IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
/*
- * Request resources.
+ * IORESOURCE_MEM
*/
- res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
- if (!res)
- panic("pcie_setup unable to alloc resources");
+ pp->res[1].name = "PCIe 0 MEM";
+ pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe 0 Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ sys->resource[2] = NULL;
+ sys->io_offset = 0;
+ return 1;
+}
+
+static int __init pcie1_ioresouces_setup(struct pci_sys_data *sys)
+{
+ struct pcie_port *pp = (struct pcie_port *)sys->private_data;
/*
* IORESOURCE_IO
*/
- res[0].name = "PCIe I/O Space";
- res[0].flags = IORESOURCE_IO;
- res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
- res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
- if (request_resource(&ioport_resource, &res[0]))
- panic("Request PCIe IO resource failed\n");
- sys->resource[0] = &res[0];
+ 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
*/
- res[1].name = "PCIe Memory Space";
- res[1].flags = IORESOURCE_MEM;
- res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
- res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
- if (request_resource(&iomem_resource, &res[1]))
- panic("Request PCIe Memory resource failed\n");
- sys->resource[1] = &res[1];
+ 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;
- kirkwood_clk_ctrl |= CGC_PEX0;
+ 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_ioresouces_setup(sys);
+ break;
+ case 1:
+ pp->base = (void __iomem *)PCIE1_VIRT_BASE;
+ pp->irq = IRQ_KIRKWOOD_PCIE1;
+ kirkwood_clk_ctrl |= CGC_PEX1;
+ pcie1_ioresouces_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;
}
@@ -163,7 +237,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct pci_bus *bus;
- if (nr == 0) {
+ if (nr < num_pcie_ports) {
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
} else {
bus = NULL;
@@ -175,18 +249,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)
{
- return IRQ_KIRKWOOD_PCIE;
+ struct pcie_port *pp = bus_to_port(dev->bus);
+
+ return pp->irq;
}
static struct hw_pci kirkwood_pci __initdata = {
- .nr_controllers = 1,
.swizzle = pci_std_swizzle,
.setup = kirkwood_pcie_setup,
.scan = kirkwood_pcie_scan_bus,
.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);
}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 3bf6304..c34718c 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -71,7 +71,7 @@ static void __init rd88f6192_init(void)
static int __init rd88f6192_pci_init(void)
{
if (machine_is_rd88f6192_nas())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 31708dd..3d14771 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -107,7 +107,7 @@ static void __init rd88f6281_init(void)
static int __init rd88f6281_pci_init(void)
{
if (machine_is_rd88f6281())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index 2830f0f..7250087 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -110,10 +110,10 @@ static void __init qnap_ts219_init(void)
static int __init ts219_pci_init(void)
{
- if (machine_is_ts219())
- kirkwood_pcie_init();
+ if (machine_is_ts219())
+ kirkwood_pcie_init(KW_PCIE0);
- return 0;
+ return 0;
}
subsys_initcall(ts219_pci_init);
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index de49c2d..a122868 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -136,7 +136,7 @@ static void __init qnap_ts41x_init(void)
static int __init ts41x_pci_init(void)
{
if (machine_is_ts41x())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3 v3] [ARM] Kirkwood: add support for PCIe1
2010-06-06 10:24 ` [PATCH 3/3 v3] " Saeed Bishara
@ 2010-06-07 8:04 ` Benjamin Zores
2010-06-08 11:20 ` saeed bishara
0 siblings, 1 reply; 16+ messages in thread
From: Benjamin Zores @ 2010-06-07 8:04 UTC (permalink / raw)
To: linux-arm-kernel
On 06/06/2010 12:24, Saeed Bishara wrote:
> This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
>
> diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
> index 39bdf4b..c428348 100644
> --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
> +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
> @@ -74,9 +74,15 @@ static void __init db88f6281_init(void)
>
> static int __init db88f6281_pci_init(void)
> {
> - if (machine_is_db88f6281_bp())
> - kirkwood_pcie_init();
> + if (machine_is_db88f6281_bp()) {
> + 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;
>
This is still not likely to be possible: I don't think a given board can
have 2 different SoCs.
> +#define CGC_PEX1 (1<< 18)
> #define CGC_GE1 (1<< 19)
> #define CGC_TDM (1<< 20)
> #define CGC_RESERVED ((1<< 18) | (0x6<< 21))
>
(1 << 18) is no longer reserved.
Except from that you still miss the mapping definition and phy
initialization in common.c
See
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017176.html
for details.
Ben
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v3] [ARM] Kirkwood: add support for PCIe1
2010-06-07 8:04 ` Benjamin Zores
@ 2010-06-08 11:20 ` saeed bishara
2010-06-08 11:21 ` [PATCH 3/3 v4] " Saeed Bishara
0 siblings, 1 reply; 16+ messages in thread
From: saeed bishara @ 2010-06-08 11:20 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Jun 7, 2010 at 11:04 AM, Benjamin Zores
<benjamin.zores@alcatel-lucent.com> wrote:
> On 06/06/2010 12:24, Saeed Bishara wrote:
>>
>> This patch extens the kirkwood's PCIe support up to 2 controllers as in
>> the 6282 devices.
>>
>> diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
>> b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
>> index 39bdf4b..c428348 100644
>> --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
>> +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
>> @@ -74,9 +74,15 @@ static void __init db88f6281_init(void)
>>
>> ?static int __init db88f6281_pci_init(void)
>> ?{
>> - ? ? ? if (machine_is_db88f6281_bp())
>> - ? ? ? ? ? ? ? kirkwood_pcie_init();
>> + ? ? ? if (machine_is_db88f6281_bp()) {
>> + ? ? ? ? ? ? ? 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;
>>
>
> This is still not likely to be possible: I don't think a given board can
> have 2 different SoCs.
well, it works because the 6282 is "pin-compatible" to 6281 and the
differences between the two boards are the additional pcie and few
mpps that set by the bootloader.
>
>> +#define CGC_PEX1 ? ? ? ? ? ? ? (1<< ?18)
>> ?#define CGC_GE1 ? ? ? ? ? ? ? ? ? ? ? (1<< ?19)
>> ?#define CGC_TDM ? ? ? ? ? ? ? ? ? ? ? (1<< ?20)
>> ?#define CGC_RESERVED ? ? ? ? ?((1<< ?18) | (0x6<< ?21))
>>
>
> (1 << 18) is no longer reserved.
>
> Except from that you still miss the mapping definition and phy
> initialization in common.c
>
> See
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017176.html
> for details.
I applied your comments except to the io table, I don't think it's
worth to add, the pcie0 entry is always added even if that interface
is not used.
saeed
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v4] [ARM] Kirkwood: add support for PCIe1
2010-06-08 11:20 ` saeed bishara
@ 2010-06-08 11:21 ` Saeed Bishara
2010-06-08 11:43 ` Benjamin Zores
0 siblings, 1 reply; 16+ messages in thread
From: Saeed Bishara @ 2010-06-08 11:21 UTC (permalink / raw)
To: linux-arm-kernel
This patch extens the kirkwood's PCIe support up to 2 controllers as in the 6282 devices.
Signed-off-by: Saeed Bishara <saeed@marvell.com>
---
arch/arm/mach-kirkwood/addr-map.c | 10 +-
arch/arm/mach-kirkwood/common.c | 21 +++-
arch/arm/mach-kirkwood/common.h | 5 +-
arch/arm/mach-kirkwood/db88f6281-bp-setup.c | 10 +-
arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 3 +-
arch/arm/mach-kirkwood/include/mach/irqs.h | 1 +
arch/arm/mach-kirkwood/include/mach/kirkwood.h | 35 +++-
arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c | 2 +-
arch/arm/mach-kirkwood/openrd-setup.c | 2 +-
arch/arm/mach-kirkwood/pcie.c | 187 +++++++++++++++-----
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | 2 +-
arch/arm/mach-kirkwood/rd88f6281-setup.c | 2 +-
arch/arm/mach-kirkwood/ts219-setup.c | 6 +-
arch/arm/mach-kirkwood/ts41x-setup.c | 2 +-
14 files changed, 216 insertions(+), 72 deletions(-)
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 2e69168..8d03bce 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -31,6 +31,8 @@
#define ATTR_DEV_CS0 0x3e
#define ATTR_PCIE_IO 0xe0
#define ATTR_PCIE_MEM 0xe8
+#define ATTR_PCIE1_IO 0xd0
+#define ATTR_PCIE1_MEM 0xd8
#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);
setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
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_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);
/*
* 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);
/*
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 4ccfdf9..9dd67c7 100644
--- a/arch/arm/mach-kirkwood/common.c
+++ b/arch/arm/mach-kirkwood/common.c
@@ -44,6 +44,11 @@ static struct map_desc kirkwood_io_desc[] __initdata = {
.length = KIRKWOOD_PCIE_IO_SIZE,
.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,
.pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
.length = KIRKWOOD_REGS_SIZE,
@@ -960,12 +965,14 @@ void __init kirkwood_init(void)
static int __init kirkwood_clock_gate(void)
{
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 "before: 0x%08x\n", curr);
/* 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 */
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);
}
+ /* 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 */
writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL));
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h
index 05e8a8a..5b2c1c1 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -18,6 +18,9 @@ struct mvsdio_platform_data;
struct mtd_partition;
struct mtd_info;
+#define KW_PCIE0 (1 << 0)
+#define KW_PCIE1 (1 << 1)
+
/*
* 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_ge01_init(struct mv643xx_eth_platform_data *eth_data);
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_sdio_init(struct mvsdio_platform_data *mvsdio_data);
void kirkwood_spi_init(void);
diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
index 39bdf4b..c428348 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -74,9 +74,15 @@ static void __init db88f6281_init(void)
static int __init db88f6281_pci_init(void)
{
- if (machine_is_db88f6281_bp())
- kirkwood_pcie_init();
+ if (machine_is_db88f6281_bp()) {
+ 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;
}
subsys_initcall(db88f6281_pci_init);
diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
index 418f501..aff0e13 100644
--- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
+++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h
@@ -59,8 +59,9 @@
#define CGC_SATA1 (1 << 15)
#define CGC_XOR1 (1 << 16)
#define CGC_CRYPTO (1 << 17)
+#define CGC_PEX1 (1 << 18)
#define CGC_GE1 (1 << 19)
#define CGC_TDM (1 << 20)
-#define CGC_RESERVED ((1 << 18) | (0x6 << 21))
+#define CGC_RESERVED (0x6 << 21)
#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
index f00a0a4..9da2eb5 100644
--- a/arch/arm/mach-kirkwood/include/mach/irqs.h
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -23,6 +23,7 @@
#define IRQ_KIRKWOOD_XOR_10 7
#define IRQ_KIRKWOOD_XOR_11 8
#define IRQ_KIRKWOOD_PCIE 9
+#define IRQ_KIRKWOOD_PCIE1 10
#define IRQ_KIRKWOOD_GE00_SUM 11
#define IRQ_KIRKWOOD_GE01_SUM 15
#define IRQ_KIRKWOOD_USB 19
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
index dd7eddb..d141af4 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -16,36 +16,48 @@
* Marvell Kirkwood address maps.
*
* phys
- * e0000000 PCIe Memory space
+ * e0000000 PCIe #0 Memory space
+ * e8000000 PCIe #1 Memory space
* f1000000 on-chip peripheral registers
- * f2000000 PCIe I/O space
- * f3000000 NAND controller address window
- * f4000000 Security Accelerator SRAM
+ * f2000000 PCIe #0 I/O space
+ * f3000000 PCIe #1 I/O space
+ * f4000000 NAND controller address window
+ * f5000000 Security Accelerator SRAM
*
* virt phys size
- * fee00000 f1000000 1M on-chip peripheral registers
- * fef00000 f2000000 1M PCIe I/O space
+ * fed00000 f1000000 1M on-chip peripheral registers
+ * 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_NAND_MEM_PHYS_BASE 0xf3000000
+#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000
#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_VIRT_BASE 0xfef00000
+#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
#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_PCIE_MEM_PHYS_BASE 0xe0000000
#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
#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
*/
@@ -72,6 +84,9 @@
#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
#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)
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 5e6f711..c6b92b4 100644
--- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
+++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
@@ -155,7 +155,7 @@ static void __init mv88f6281gtw_ge_init(void)
static int __init mv88f6281gtw_ge_pci_init(void)
{
if (machine_is_mv88f6281gtw_ge())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index ad3f1ec..2400207 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -85,7 +85,7 @@ static void __init openrd_init(void)
static int __init openrd_pci_init(void)
{
if (machine_is_openrd_base() || machine_is_openrd_client())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index dee1eff..89201a9 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -18,29 +18,43 @@
#include <mach/bridge-regs.h>
#include "common.h"
+void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+{
+ *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
+ *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
+}
-#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
+struct pcie_port {
+ u8 root_bus_nr;
+ void __iomem *base;
+ spinlock_t conf_lock;
+ int irq;
+ struct resource res[2];
+};
-void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
+static int pcie_port_map[2];
+static int num_pcie_ports;
+
+static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
{
- *dev = orion_pcie_dev_id(PCIE_BASE);
- *rev = orion_pcie_rev(PCIE_BASE);
+ struct pci_sys_data *sys = bus->sysdata;
+ return sys->private_data;
}
-static int pcie_valid_config(int bus, int dev)
+static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
{
/*
* Don't go out when trying to access --
* 1. nonexisting device on local bus
* 2. where there's no device connected (no link)
*/
- if (bus == 0 && dev == 0)
+ if (bus == pp->root_bus_nr && dev == 0)
return 1;
- if (!orion_pcie_link_up(PCIE_BASE))
+ if (!orion_pcie_link_up(pp->base))
return 0;
- if (bus == 0 && dev != 1)
+ if (bus == pp->root_bus_nr && dev != 1)
return 0;
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
* transactions are atomic.
*/
-static DEFINE_SPINLOCK(kirkwood_pcie_lock);
static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val)
{
+ struct pcie_port *pp = bus_to_port(bus);
unsigned long flags;
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;
return PCIBIOS_DEVICE_NOT_FOUND;
}
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
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,
int where, int size, u32 val)
{
+ struct pcie_port *pp = bus_to_port(bus);
unsigned long flags;
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;
- spin_lock_irqsave(&kirkwood_pcie_lock, flags);
- ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val);
- spin_unlock_irqrestore(&kirkwood_pcie_lock, flags);
+ spin_lock_irqsave(&pp->conf_lock, flags);
+ ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret;
}
@@ -93,50 +108,109 @@ static struct pci_ops pcie_ops = {
.write = pcie_wr_conf,
};
-
-static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
+static int __init pcie0_ioresouces_setup(struct pci_sys_data *sys)
{
- struct resource *res;
- extern unsigned int kirkwood_clk_ctrl;
-
+ struct pcie_port *pp = (struct pcie_port *)sys->private_data;
/*
- * Generic PCIe unit setup.
+ * IORESOURCE_IO
*/
- orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info);
+ pp->res[0].name = "PCIe 0 I/O Space";
+ pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
+ pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe 0 IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
/*
- * Request resources.
+ * IORESOURCE_MEM
*/
- res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
- if (!res)
- panic("pcie_setup unable to alloc resources");
+ pp->res[1].name = "PCIe 0 MEM";
+ pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
+ pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe 0 Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ sys->resource[2] = NULL;
+ sys->io_offset = 0;
+ return 1;
+}
+
+static int __init pcie1_ioresouces_setup(struct pci_sys_data *sys)
+{
+ struct pcie_port *pp = (struct pcie_port *)sys->private_data;
/*
* IORESOURCE_IO
*/
- res[0].name = "PCIe I/O Space";
- res[0].flags = IORESOURCE_IO;
- res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE;
- res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
- if (request_resource(&ioport_resource, &res[0]))
- panic("Request PCIe IO resource failed\n");
- sys->resource[0] = &res[0];
+ 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
*/
- res[1].name = "PCIe Memory Space";
- res[1].flags = IORESOURCE_MEM;
- res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE;
- res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
- if (request_resource(&iomem_resource, &res[1]))
- panic("Request PCIe Memory resource failed\n");
- sys->resource[1] = &res[1];
+ 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;
- kirkwood_clk_ctrl |= CGC_PEX0;
+ 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_ioresouces_setup(sys);
+ break;
+ case 1:
+ pp->base = (void __iomem *)PCIE1_VIRT_BASE;
+ pp->irq = IRQ_KIRKWOOD_PCIE1;
+ kirkwood_clk_ctrl |= CGC_PEX1;
+ pcie1_ioresouces_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;
}
@@ -163,7 +237,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct pci_bus *bus;
- if (nr == 0) {
+ if (nr < num_pcie_ports) {
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
} else {
bus = NULL;
@@ -175,18 +249,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)
{
- return IRQ_KIRKWOOD_PCIE;
+ struct pcie_port *pp = bus_to_port(dev->bus);
+
+ return pp->irq;
}
static struct hw_pci kirkwood_pci __initdata = {
- .nr_controllers = 1,
.swizzle = pci_std_swizzle,
.setup = kirkwood_pcie_setup,
.scan = kirkwood_pcie_scan_bus,
.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);
}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 3bf6304..c34718c 100644
--- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
@@ -71,7 +71,7 @@ static void __init rd88f6192_init(void)
static int __init rd88f6192_pci_init(void)
{
if (machine_is_rd88f6192_nas())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 31708dd..3d14771 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -107,7 +107,7 @@ static void __init rd88f6281_init(void)
static int __init rd88f6281_pci_init(void)
{
if (machine_is_rd88f6281())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index 2830f0f..7250087 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -110,10 +110,10 @@ static void __init qnap_ts219_init(void)
static int __init ts219_pci_init(void)
{
- if (machine_is_ts219())
- kirkwood_pcie_init();
+ if (machine_is_ts219())
+ kirkwood_pcie_init(KW_PCIE0);
- return 0;
+ return 0;
}
subsys_initcall(ts219_pci_init);
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index de49c2d..a122868 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -136,7 +136,7 @@ static void __init qnap_ts41x_init(void)
static int __init ts41x_pci_init(void)
{
if (machine_is_ts41x())
- kirkwood_pcie_init();
+ kirkwood_pcie_init(KW_PCIE0);
return 0;
}
--
1.6.0.4
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3 v4] [ARM] Kirkwood: add support for PCIe1
2010-06-08 11:21 ` [PATCH 3/3 v4] " Saeed Bishara
@ 2010-06-08 11:43 ` Benjamin Zores
2010-06-08 12:20 ` saeed bishara
0 siblings, 1 reply; 16+ messages in thread
From: Benjamin Zores @ 2010-06-08 11:43 UTC (permalink / raw)
To: linux-arm-kernel
On 08/06/2010 13:21, Saeed Bishara wrote:
> @@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
> TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
> setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
> 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);
>
>
I'd have used an id, and incremented it at each setup_cpu_win() call.
Also only doing the last 2 calls on 6282.
> /* 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);
>
>
Why not (pseudo code):
int flags = curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0;
if (6282) flags |= CGC_PEX1;
writel(flags, ...);
> + /* 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;
>
>
the else part is useless with the proposal above i guess.
Except from that, when using your patch I was unable to boot kernel
anymore on 6281 boards.
I have a quite similar patch that however uses preinit() calls in pcie.c
for the board to boot again.
I'd like to send it but I'm in discussion with your company whether or
not I'm allowed to do so.
In the same way I do have patches for MPP and 2nd TWSI interface support
if it may help.
Ben
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v4] [ARM] Kirkwood: add support for PCIe1
2010-06-08 11:43 ` Benjamin Zores
@ 2010-06-08 12:20 ` saeed bishara
2010-06-08 12:43 ` Benjamin Zores
0 siblings, 1 reply; 16+ messages in thread
From: saeed bishara @ 2010-06-08 12:20 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jun 8, 2010 at 2:43 PM, Benjamin Zores
<benjamin.zores@alcatel-lucent.com> wrote:
> On 08/06/2010 13:21, Saeed Bishara wrote:
>>
>> @@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
>> ? ? ? ? ? ? ? ? ? ? ?TARGET_PCIE, ATTR_PCIE_IO,
>> KIRKWOOD_PCIE_IO_BUS_BASE);
>> ? ? ? ?setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE,
>> KIRKWOOD_PCIE_MEM_SIZE,
>> ? ? ? ? ? ? ? ? ? ? ?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);
>>
>>
>
> I'd have used an id, and incremented it at each setup_cpu_win() call.
> Also only doing the last 2 calls on 6282.
>
>> ? ? ? ?/* 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);
>>
>>
>
> Why not (pseudo code):
>
> int flags = curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0;
> if (6282) flags |= CGC_PEX1;
> writel(flags, ...);
>
>> + ? ? ? /* 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;
>>
>>
>
> the else part is useless with the proposal above i guess.
>
> Except from that, when using your patch I was unable to boot kernel anymore
> on 6281 boards.
can you try the patch I send regarding nand mpps?
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v4] [ARM] Kirkwood: add support for PCIe1
2010-06-08 12:20 ` saeed bishara
@ 2010-06-08 12:43 ` Benjamin Zores
2010-06-08 12:49 ` saeed bishara
0 siblings, 1 reply; 16+ messages in thread
From: Benjamin Zores @ 2010-06-08 12:43 UTC (permalink / raw)
To: linux-arm-kernel
On 08/06/2010 14:20, saeed bishara wrote:
> On Tue, Jun 8, 2010 at 2:43 PM, Benjamin Zores
> <benjamin.zores@alcatel-lucent.com> wrote:
>
>> On 08/06/2010 13:21, Saeed Bishara wrote:
>>
>>> @@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
>>> TARGET_PCIE, ATTR_PCIE_IO,
>>> KIRKWOOD_PCIE_IO_BUS_BASE);
>>> setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE,
>>> KIRKWOOD_PCIE_MEM_SIZE,
>>> 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);
>>>
>>>
>>>
>> I'd have used an id, and incremented it at each setup_cpu_win() call.
>> Also only doing the last 2 calls on 6282.
>>
>>
>>> /* 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);
>>>
>>>
>>>
>> Why not (pseudo code):
>>
>> int flags = curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0;
>> if (6282) flags |= CGC_PEX1;
>> writel(flags, ...);
>>
>>
>>> + /* 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;
>>>
>>>
>>>
>> the else part is useless with the proposal above i guess.
>>
>> Except from that, when using your patch I was unable to boot kernel anymore
>> on 6281 boards.
>>
> can you try the patch I send regarding nand mpps?
>
Unfortunately no, I'm running on OpenRD currently.
Ben
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/3 v4] [ARM] Kirkwood: add support for PCIe1
2010-06-08 12:43 ` Benjamin Zores
@ 2010-06-08 12:49 ` saeed bishara
0 siblings, 0 replies; 16+ messages in thread
From: saeed bishara @ 2010-06-08 12:49 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Jun 8, 2010 at 3:43 PM, Benjamin Zores
<benjamin.zores@alcatel-lucent.com> wrote:
> On 08/06/2010 14:20, saeed bishara wrote:
>>
>> On Tue, Jun 8, 2010 at 2:43 PM, Benjamin Zores
>> <benjamin.zores@alcatel-lucent.com> ?wrote:
>>
>>>
>>> On 08/06/2010 13:21, Saeed Bishara wrote:
>>>
>>>>
>>>> @@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
>>>> ? ? ? ? ? ? ? ? ? ? ?TARGET_PCIE, ATTR_PCIE_IO,
>>>> KIRKWOOD_PCIE_IO_BUS_BASE);
>>>> ? ? ? ?setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE,
>>>> KIRKWOOD_PCIE_MEM_SIZE,
>>>> ? ? ? ? ? ? ? ? ? ? ?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);
>>>>
>>>>
>>>>
>>>
>>> I'd have used an id, and incremented it at each setup_cpu_win() call.
>>> Also only doing the last 2 calls on 6282.
>>>
>>>
>>>>
>>>> ? ? ? ?/* 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);
>>>>
>>>>
>>>>
>>>
>>> Why not (pseudo code):
>>>
>>> int flags = curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0;
>>> if (6282) flags |= CGC_PEX1;
>>> writel(flags, ...);
>>>
>>>
>>>>
>>>> + ? ? ? /* 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;
>>>>
>>>>
>>>>
>>>
>>> the else part is useless with the proposal above i guess.
>>>
>>> Except from that, when using your patch I was unable to boot kernel
>>> anymore
>>> on 6281 boards.
>>>
>>
>> can you try the patch I send regarding nand mpps?
>>
>
> Unfortunately no, I'm running on OpenRD currently.
does it boot if you remove the kirkwood_nand_init?
> Ben
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2010-06-08 12:49 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-01 15:09 [PATCH 1/3] [ARM] Kirkwood: add support for rev A1 of the 88f6192 and 88f6180 chips Saeed Bishara
2010-06-01 15:09 ` [PATCH 2/3] [ARM] Kirkwood: Add support for 88f6282 Saeed Bishara
2010-06-01 15:09 ` [PATCH 3/3] [ARM] Kirkwood: add support for PCIe1 Saeed Bishara
2010-06-01 19:55 ` Nicolas Pitre
2010-06-02 10:34 ` saeed bishara
2010-06-02 19:29 ` Nicolas Pitre
2010-06-03 11:43 ` saeed bishara
2010-06-03 16:30 ` Nicolas Pitre
2010-06-06 10:24 ` [PATCH 3/3 v3] " Saeed Bishara
2010-06-07 8:04 ` Benjamin Zores
2010-06-08 11:20 ` saeed bishara
2010-06-08 11:21 ` [PATCH 3/3 v4] " Saeed Bishara
2010-06-08 11:43 ` Benjamin Zores
2010-06-08 12:20 ` saeed bishara
2010-06-08 12:43 ` Benjamin Zores
2010-06-08 12:49 ` saeed bishara
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).