aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-kirkwood
diff options
context:
space:
mode:
authorSaeed Bishara <saeed@marvell.com>2010-06-08 07:21:34 -0400
committerNicolas Pitre <nico@fluxnic.net>2010-07-16 22:01:59 -0400
commitffd58bd2e45168de21d257d26ee32843b286d3b3 (patch)
tree6015a09c82add039c532a6cc41502c5eae31ccd4 /arch/arm/mach-kirkwood
parent35fe2fc44ac4202261317ccce2ef69991bc01c57 (diff)
[ARM] Kirkwood: add support for PCIe1
This patch extends the kirkwood's PCIe support up to 2 controllers as in the 6282 devices. Signed-off-by: Saeed Bishara <saeed@marvell.com> Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
Diffstat (limited to 'arch/arm/mach-kirkwood')
-rw-r--r--arch/arm/mach-kirkwood/addr-map.c10
-rw-r--r--arch/arm/mach-kirkwood/common.c21
-rw-r--r--arch/arm/mach-kirkwood/common.h5
-rw-r--r--arch/arm/mach-kirkwood/db88f6281-bp-setup.c10
-rw-r--r--arch/arm/mach-kirkwood/include/mach/bridge-regs.h3
-rw-r--r--arch/arm/mach-kirkwood/include/mach/irqs.h1
-rw-r--r--arch/arm/mach-kirkwood/include/mach/kirkwood.h35
-rw-r--r--arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/openrd-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/pcie.c188
-rw-r--r--arch/arm/mach-kirkwood/rd88f6192-nas-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/rd88f6281-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/t5325-setup.c2
-rw-r--r--arch/arm/mach-kirkwood/ts219-setup.c6
-rw-r--r--arch/arm/mach-kirkwood/ts41x-setup.c2
15 files changed, 219 insertions, 72 deletions
diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c
index 2e69168fc699..8d03bcef5182 100644
--- a/arch/arm/mach-kirkwood/addr-map.c
+++ b/arch/arm/mach-kirkwood/addr-map.c
@@ -31,6 +31,8 @@
31#define ATTR_DEV_CS0 0x3e 31#define ATTR_DEV_CS0 0x3e
32#define ATTR_PCIE_IO 0xe0 32#define ATTR_PCIE_IO 0xe0
33#define ATTR_PCIE_MEM 0xe8 33#define ATTR_PCIE_MEM 0xe8
34#define ATTR_PCIE1_IO 0xd0
35#define ATTR_PCIE1_MEM 0xd8
34#define ATTR_SRAM 0x01 36#define ATTR_SRAM 0x01
35 37
36/* 38/*
@@ -106,17 +108,21 @@ void __init kirkwood_setup_cpu_mbus(void)
106 TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE); 108 TARGET_PCIE, ATTR_PCIE_IO, KIRKWOOD_PCIE_IO_BUS_BASE);
107 setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE, 109 setup_cpu_win(1, KIRKWOOD_PCIE_MEM_PHYS_BASE, KIRKWOOD_PCIE_MEM_SIZE,
108 TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE); 110 TARGET_PCIE, ATTR_PCIE_MEM, KIRKWOOD_PCIE_MEM_BUS_BASE);
111 setup_cpu_win(2, KIRKWOOD_PCIE1_IO_PHYS_BASE, KIRKWOOD_PCIE1_IO_SIZE,
112 TARGET_PCIE, ATTR_PCIE1_IO, KIRKWOOD_PCIE1_IO_BUS_BASE);
113 setup_cpu_win(3, KIRKWOOD_PCIE1_MEM_PHYS_BASE, KIRKWOOD_PCIE1_MEM_SIZE,
114 TARGET_PCIE, ATTR_PCIE1_MEM, KIRKWOOD_PCIE1_MEM_BUS_BASE);
109 115
110 /* 116 /*
111 * Setup window for NAND controller. 117 * Setup window for NAND controller.
112 */ 118 */
113 setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, 119 setup_cpu_win(4, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE,
114 TARGET_DEV_BUS, ATTR_DEV_NAND, -1); 120 TARGET_DEV_BUS, ATTR_DEV_NAND, -1);
115 121
116 /* 122 /*
117 * Setup window for SRAM. 123 * Setup window for SRAM.
118 */ 124 */
119 setup_cpu_win(3, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE, 125 setup_cpu_win(5, KIRKWOOD_SRAM_PHYS_BASE, KIRKWOOD_SRAM_SIZE,
120 TARGET_SRAM, ATTR_SRAM, -1); 126 TARGET_SRAM, ATTR_SRAM, -1);
121 127
122 /* 128 /*
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c
index 4ccfdf97aa25..9dd67c7b4459 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 = {
44 .length = KIRKWOOD_PCIE_IO_SIZE, 44 .length = KIRKWOOD_PCIE_IO_SIZE,
45 .type = MT_DEVICE, 45 .type = MT_DEVICE,
46 }, { 46 }, {
47 .virtual = KIRKWOOD_PCIE1_IO_VIRT_BASE,
48 .pfn = __phys_to_pfn(KIRKWOOD_PCIE1_IO_PHYS_BASE),
49 .length = KIRKWOOD_PCIE1_IO_SIZE,
50 .type = MT_DEVICE,
51 }, {
47 .virtual = KIRKWOOD_REGS_VIRT_BASE, 52 .virtual = KIRKWOOD_REGS_VIRT_BASE,
48 .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), 53 .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE),
49 .length = KIRKWOOD_REGS_SIZE, 54 .length = KIRKWOOD_REGS_SIZE,
@@ -960,12 +965,14 @@ void __init kirkwood_init(void)
960static int __init kirkwood_clock_gate(void) 965static int __init kirkwood_clock_gate(void)
961{ 966{
962 unsigned int curr = readl(CLOCK_GATING_CTRL); 967 unsigned int curr = readl(CLOCK_GATING_CTRL);
968 u32 dev, rev;
963 969
970 kirkwood_pcie_id(&dev, &rev);
964 printk(KERN_DEBUG "Gating clock of unused units\n"); 971 printk(KERN_DEBUG "Gating clock of unused units\n");
965 printk(KERN_DEBUG "before: 0x%08x\n", curr); 972 printk(KERN_DEBUG "before: 0x%08x\n", curr);
966 973
967 /* Make sure those units are accessible */ 974 /* Make sure those units are accessible */
968 writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0, CLOCK_GATING_CTRL); 975 writel(curr | CGC_SATA0 | CGC_SATA1 | CGC_PEX0 | CGC_PEX1, CLOCK_GATING_CTRL);
969 976
970 /* For SATA: first shutdown the phy */ 977 /* For SATA: first shutdown the phy */
971 if (!(kirkwood_clk_ctrl & CGC_SATA0)) { 978 if (!(kirkwood_clk_ctrl & CGC_SATA0)) {
@@ -990,6 +997,18 @@ static int __init kirkwood_clock_gate(void)
990 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); 997 writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL);
991 } 998 }
992 999
1000 /* For PCIe 1: first shutdown the phy */
1001 if (dev == MV88F6282_DEV_ID) {
1002 if (!(kirkwood_clk_ctrl & CGC_PEX1)) {
1003 writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL);
1004 while (1)
1005 if (readl(PCIE1_STATUS) & 0x1)
1006 break;
1007 writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL);
1008 }
1009 } else /* keep this bit set for devices that don't have PCIe1 */
1010 kirkwood_clk_ctrl |= CGC_PEX1;
1011
993 /* Now gate clock the required units */ 1012 /* Now gate clock the required units */
994 writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL); 1013 writel(kirkwood_clk_ctrl, CLOCK_GATING_CTRL);
995 printk(KERN_DEBUG " after: 0x%08x\n", readl(CLOCK_GATING_CTRL)); 1014 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 05e8a8a5692e..5b2c1c18d641 100644
--- a/arch/arm/mach-kirkwood/common.h
+++ b/arch/arm/mach-kirkwood/common.h
@@ -18,6 +18,9 @@ struct mvsdio_platform_data;
18struct mtd_partition; 18struct mtd_partition;
19struct mtd_info; 19struct mtd_info;
20 20
21#define KW_PCIE0 (1 << 0)
22#define KW_PCIE1 (1 << 1)
23
21/* 24/*
22 * Basic Kirkwood init functions used early by machine-setup. 25 * Basic Kirkwood init functions used early by machine-setup.
23 */ 26 */
@@ -34,7 +37,7 @@ void kirkwood_ehci_init(void);
34void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); 37void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
35void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data); 38void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data);
36void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq); 39void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
37void kirkwood_pcie_init(void); 40void kirkwood_pcie_init(unsigned int portmask);
38void kirkwood_sata_init(struct mv_sata_platform_data *sata_data); 41void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);
39void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data); 42void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data);
40void kirkwood_spi_init(void); 43void 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 db93504aafbc..16f6691e7c68 100644
--- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
+++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c
@@ -82,9 +82,15 @@ static void __init db88f6281_init(void)
82 82
83static int __init db88f6281_pci_init(void) 83static int __init db88f6281_pci_init(void)
84{ 84{
85 if (machine_is_db88f6281_bp()) 85 if (machine_is_db88f6281_bp()) {
86 kirkwood_pcie_init(); 86 u32 dev, rev;
87 87
88 kirkwood_pcie_id(&dev, &rev);
89 if (dev == MV88F6282_DEV_ID)
90 kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
91 else
92 kirkwood_pcie_init(KW_PCIE0);
93 }
88 return 0; 94 return 0;
89} 95}
90subsys_initcall(db88f6281_pci_init); 96subsys_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 418f5017c50e..aff0e1327e38 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 @@
59#define CGC_SATA1 (1 << 15) 59#define CGC_SATA1 (1 << 15)
60#define CGC_XOR1 (1 << 16) 60#define CGC_XOR1 (1 << 16)
61#define CGC_CRYPTO (1 << 17) 61#define CGC_CRYPTO (1 << 17)
62#define CGC_PEX1 (1 << 18)
62#define CGC_GE1 (1 << 19) 63#define CGC_GE1 (1 << 19)
63#define CGC_TDM (1 << 20) 64#define CGC_TDM (1 << 20)
64#define CGC_RESERVED ((1 << 18) | (0x6 << 21)) 65#define CGC_RESERVED (0x6 << 21)
65 66
66#endif 67#endif
diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h
index f00a0a45a67e..9da2eb59180b 100644
--- a/arch/arm/mach-kirkwood/include/mach/irqs.h
+++ b/arch/arm/mach-kirkwood/include/mach/irqs.h
@@ -23,6 +23,7 @@
23#define IRQ_KIRKWOOD_XOR_10 7 23#define IRQ_KIRKWOOD_XOR_10 7
24#define IRQ_KIRKWOOD_XOR_11 8 24#define IRQ_KIRKWOOD_XOR_11 8
25#define IRQ_KIRKWOOD_PCIE 9 25#define IRQ_KIRKWOOD_PCIE 9
26#define IRQ_KIRKWOOD_PCIE1 10
26#define IRQ_KIRKWOOD_GE00_SUM 11 27#define IRQ_KIRKWOOD_GE00_SUM 11
27#define IRQ_KIRKWOOD_GE01_SUM 15 28#define IRQ_KIRKWOOD_GE01_SUM 15
28#define IRQ_KIRKWOOD_USB 19 29#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 dd7eddbd5902..d141af4c2744 100644
--- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h
+++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h
@@ -16,36 +16,48 @@
16 * Marvell Kirkwood address maps. 16 * Marvell Kirkwood address maps.
17 * 17 *
18 * phys 18 * phys
19 * e0000000 PCIe Memory space 19 * e0000000 PCIe #0 Memory space
20 * e8000000 PCIe #1 Memory space
20 * f1000000 on-chip peripheral registers 21 * f1000000 on-chip peripheral registers
21 * f2000000 PCIe I/O space 22 * f2000000 PCIe #0 I/O space
22 * f3000000 NAND controller address window 23 * f3000000 PCIe #1 I/O space
23 * f4000000 Security Accelerator SRAM 24 * f4000000 NAND controller address window
25 * f5000000 Security Accelerator SRAM
24 * 26 *
25 * virt phys size 27 * virt phys size
26 * fee00000 f1000000 1M on-chip peripheral registers 28 * fed00000 f1000000 1M on-chip peripheral registers
27 * fef00000 f2000000 1M PCIe I/O space 29 * fee00000 f2000000 1M PCIe #0 I/O space
30 * fef00000 f3000000 1M PCIe #1 I/O space
28 */ 31 */
29 32
30#define KIRKWOOD_SRAM_PHYS_BASE 0xf4000000 33#define KIRKWOOD_SRAM_PHYS_BASE 0xf5000000
31#define KIRKWOOD_SRAM_SIZE SZ_2K 34#define KIRKWOOD_SRAM_SIZE SZ_2K
32 35
33#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf3000000 36#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000
34#define KIRKWOOD_NAND_MEM_SIZE SZ_1K 37#define KIRKWOOD_NAND_MEM_SIZE SZ_1K
35 38
39#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000
40#define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000
41#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000
42#define KIRKWOOD_PCIE1_IO_SIZE SZ_1M
43
36#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 44#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000
37#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfef00000 45#define KIRKWOOD_PCIE_IO_VIRT_BASE 0xfee00000
38#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000 46#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000
39#define KIRKWOOD_PCIE_IO_SIZE SZ_1M 47#define KIRKWOOD_PCIE_IO_SIZE SZ_1M
40 48
41#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 49#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000
42#define KIRKWOOD_REGS_VIRT_BASE 0xfee00000 50#define KIRKWOOD_REGS_VIRT_BASE 0xfed00000
43#define KIRKWOOD_REGS_SIZE SZ_1M 51#define KIRKWOOD_REGS_SIZE SZ_1M
44 52
45#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000 53#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000
46#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000 54#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000
47#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M 55#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M
48 56
57#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xe8000000
58#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xe8000000
59#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M
60
49/* 61/*
50 * Register Map 62 * Register Map
51 */ 63 */
@@ -72,6 +84,9 @@
72#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000) 84#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x40000)
73#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70) 85#define PCIE_LINK_CTRL (PCIE_VIRT_BASE | 0x70)
74#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04) 86#define PCIE_STATUS (PCIE_VIRT_BASE | 0x1a04)
87#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x44000)
88#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE | 0x70)
89#define PCIE1_STATUS (PCIE1_VIRT_BASE | 0x1a04)
75 90
76#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000) 91#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x50000)
77 92
diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c
index 5e6f711b1c67..c6b92b42eb4e 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)
155static int __init mv88f6281gtw_ge_pci_init(void) 155static int __init mv88f6281gtw_ge_pci_init(void)
156{ 156{
157 if (machine_is_mv88f6281gtw_ge()) 157 if (machine_is_mv88f6281gtw_ge())
158 kirkwood_pcie_init(); 158 kirkwood_pcie_init(KW_PCIE0);
159 159
160 return 0; 160 return 0;
161} 161}
diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c
index a48103649eba..fd64cd2b4e0a 100644
--- a/arch/arm/mach-kirkwood/openrd-setup.c
+++ b/arch/arm/mach-kirkwood/openrd-setup.c
@@ -93,7 +93,7 @@ static int __init openrd_pci_init(void)
93 if (machine_is_openrd_base() || 93 if (machine_is_openrd_base() ||
94 machine_is_openrd_client() || 94 machine_is_openrd_client() ||
95 machine_is_openrd_ultimate()) 95 machine_is_openrd_ultimate())
96 kirkwood_pcie_init(); 96 kirkwood_pcie_init(KW_PCIE0);
97 97
98 return 0; 98 return 0;
99} 99}
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index dee1eff50d39..49c4fc6b7a59 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -18,29 +18,43 @@
18#include <mach/bridge-regs.h> 18#include <mach/bridge-regs.h>
19#include "common.h" 19#include "common.h"
20 20
21void __init kirkwood_pcie_id(u32 *dev, u32 *rev)
22{
23 *dev = orion_pcie_dev_id((void __iomem *)PCIE_VIRT_BASE);
24 *rev = orion_pcie_rev((void __iomem *)PCIE_VIRT_BASE);
25}
21 26
22#define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE) 27struct pcie_port {
28 u8 root_bus_nr;
29 void __iomem *base;
30 spinlock_t conf_lock;
31 int irq;
32 struct resource res[2];
33};
23 34
24void __init kirkwood_pcie_id(u32 *dev, u32 *rev) 35static int pcie_port_map[2];
36static int num_pcie_ports;
37
38static inline struct pcie_port *bus_to_port(struct pci_bus *bus)
25{ 39{
26 *dev = orion_pcie_dev_id(PCIE_BASE); 40 struct pci_sys_data *sys = bus->sysdata;
27 *rev = orion_pcie_rev(PCIE_BASE); 41 return sys->private_data;
28} 42}
29 43
30static int pcie_valid_config(int bus, int dev) 44static int pcie_valid_config(struct pcie_port *pp, int bus, int dev)
31{ 45{
32 /* 46 /*
33 * Don't go out when trying to access -- 47 * Don't go out when trying to access --
34 * 1. nonexisting device on local bus 48 * 1. nonexisting device on local bus
35 * 2. where there's no device connected (no link) 49 * 2. where there's no device connected (no link)
36 */ 50 */
37 if (bus == 0 && dev == 0) 51 if (bus == pp->root_bus_nr && dev == 0)
38 return 1; 52 return 1;
39 53
40 if (!orion_pcie_link_up(PCIE_BASE)) 54 if (!orion_pcie_link_up(pp->base))
41 return 0; 55 return 0;
42 56
43 if (bus == 0 && dev != 1) 57 if (bus == pp->root_bus_nr && dev != 1)
44 return 0; 58 return 0;
45 59
46 return 1; 60 return 1;
@@ -52,22 +66,22 @@ static int pcie_valid_config(int bus, int dev)
52 * and then reading the PCIE_CONF_DATA register. Need to make sure these 66 * and then reading the PCIE_CONF_DATA register. Need to make sure these
53 * transactions are atomic. 67 * transactions are atomic.
54 */ 68 */
55static DEFINE_SPINLOCK(kirkwood_pcie_lock);
56 69
57static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 70static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
58 int size, u32 *val) 71 int size, u32 *val)
59{ 72{
73 struct pcie_port *pp = bus_to_port(bus);
60 unsigned long flags; 74 unsigned long flags;
61 int ret; 75 int ret;
62 76
63 if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { 77 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
64 *val = 0xffffffff; 78 *val = 0xffffffff;
65 return PCIBIOS_DEVICE_NOT_FOUND; 79 return PCIBIOS_DEVICE_NOT_FOUND;
66 } 80 }
67 81
68 spin_lock_irqsave(&kirkwood_pcie_lock, flags); 82 spin_lock_irqsave(&pp->conf_lock, flags);
69 ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val); 83 ret = orion_pcie_rd_conf(pp->base, bus, devfn, where, size, val);
70 spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); 84 spin_unlock_irqrestore(&pp->conf_lock, flags);
71 85
72 return ret; 86 return ret;
73} 87}
@@ -75,15 +89,16 @@ static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
75static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, 89static int pcie_wr_conf(struct pci_bus *bus, u32 devfn,
76 int where, int size, u32 val) 90 int where, int size, u32 val)
77{ 91{
92 struct pcie_port *pp = bus_to_port(bus);
78 unsigned long flags; 93 unsigned long flags;
79 int ret; 94 int ret;
80 95
81 if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) 96 if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
82 return PCIBIOS_DEVICE_NOT_FOUND; 97 return PCIBIOS_DEVICE_NOT_FOUND;
83 98
84 spin_lock_irqsave(&kirkwood_pcie_lock, flags); 99 spin_lock_irqsave(&pp->conf_lock, flags);
85 ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val); 100 ret = orion_pcie_wr_conf(pp->base, bus, devfn, where, size, val);
86 spin_unlock_irqrestore(&kirkwood_pcie_lock, flags); 101 spin_unlock_irqrestore(&pp->conf_lock, flags);
87 102
88 return ret; 103 return ret;
89} 104}
@@ -93,50 +108,112 @@ static struct pci_ops pcie_ops = {
93 .write = pcie_wr_conf, 108 .write = pcie_wr_conf,
94}; 109};
95 110
96 111static int __init pcie0_ioresources_setup(struct pci_sys_data *sys)
97static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
98{ 112{
99 struct resource *res; 113 struct pcie_port *pp = (struct pcie_port *)sys->private_data;
100 extern unsigned int kirkwood_clk_ctrl;
101 114
102 /* 115 /*
103 * Generic PCIe unit setup. 116 * IORESOURCE_IO
104 */ 117 */
105 orion_pcie_setup(PCIE_BASE, &kirkwood_mbus_dram_info); 118 pp->res[0].name = "PCIe 0 I/O Space";
119 pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE;
120 pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1;
121 pp->res[0].flags = IORESOURCE_IO;
122 if (request_resource(&ioport_resource, &pp->res[0]))
123 panic("Request PCIe 0 IO resource failed\n");
124 sys->resource[0] = &pp->res[0];
106 125
107 /* 126 /*
108 * Request resources. 127 * IORESOURCE_MEM
109 */ 128 */
110 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); 129 pp->res[1].name = "PCIe 0 MEM";
111 if (!res) 130 pp->res[1].start = KIRKWOOD_PCIE_MEM_PHYS_BASE;
112 panic("pcie_setup unable to alloc resources"); 131 pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1;
132 pp->res[1].flags = IORESOURCE_MEM;
133 if (request_resource(&iomem_resource, &pp->res[1]))
134 panic("Request PCIe 0 Memory resource failed\n");
135 sys->resource[1] = &pp->res[1];
136
137 sys->resource[2] = NULL;
138 sys->io_offset = 0;
139
140 return 1;
141}
142
143static int __init pcie1_ioresources_setup(struct pci_sys_data *sys)
144{
145 struct pcie_port *pp = (struct pcie_port *)sys->private_data;
113 146
114 /* 147 /*
115 * IORESOURCE_IO 148 * IORESOURCE_IO
116 */ 149 */
117 res[0].name = "PCIe I/O Space"; 150 pp->res[0].name = "PCIe 1 I/O Space";
118 res[0].flags = IORESOURCE_IO; 151 pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE;
119 res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE; 152 pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1;
120 res[0].end = res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; 153 pp->res[0].flags = IORESOURCE_IO;
121 if (request_resource(&ioport_resource, &res[0])) 154 if (request_resource(&ioport_resource, &pp->res[0]))
122 panic("Request PCIe IO resource failed\n"); 155 panic("Request PCIe 1 IO resource failed\n");
123 sys->resource[0] = &res[0]; 156 sys->resource[0] = &pp->res[0];
124 157
125 /* 158 /*
126 * IORESOURCE_MEM 159 * IORESOURCE_MEM
127 */ 160 */
128 res[1].name = "PCIe Memory Space"; 161 pp->res[1].name = "PCIe 1 MEM";
129 res[1].flags = IORESOURCE_MEM; 162 pp->res[1].start = KIRKWOOD_PCIE1_MEM_PHYS_BASE;
130 res[1].start = KIRKWOOD_PCIE_MEM_BUS_BASE; 163 pp->res[1].end = pp->res[1].start + KIRKWOOD_PCIE1_MEM_SIZE - 1;
131 res[1].end = res[1].start + KIRKWOOD_PCIE_MEM_SIZE - 1; 164 pp->res[1].flags = IORESOURCE_MEM;
132 if (request_resource(&iomem_resource, &res[1])) 165 if (request_resource(&iomem_resource, &pp->res[1]))
133 panic("Request PCIe Memory resource failed\n"); 166 panic("Request PCIe 1 Memory resource failed\n");
134 sys->resource[1] = &res[1]; 167 sys->resource[1] = &pp->res[1];
135 168
136 sys->resource[2] = NULL; 169 sys->resource[2] = NULL;
137 sys->io_offset = 0; 170 sys->io_offset = 0;
138 171
139 kirkwood_clk_ctrl |= CGC_PEX0; 172 return 1;
173}
174
175static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
176{
177 extern unsigned int kirkwood_clk_ctrl;
178 struct pcie_port *pp;
179 int index;
180
181 if (nr >= num_pcie_ports)
182 return 0;
183
184 index = pcie_port_map[nr];
185 printk(KERN_INFO "PCI: bus%d uses PCIe port %d\n", sys->busnr, index);
186
187 pp = kzalloc(sizeof(*pp), GFP_KERNEL);
188 if (!pp)
189 panic("PCIe: failed to allocate pcie_port data");
190 sys->private_data = pp;
191 pp->root_bus_nr = sys->busnr;
192 spin_lock_init(&pp->conf_lock);
193
194 switch (index) {
195 case 0:
196 pp->base = (void __iomem *)PCIE_VIRT_BASE;
197 pp->irq = IRQ_KIRKWOOD_PCIE;
198 kirkwood_clk_ctrl |= CGC_PEX0;
199 pcie0_ioresources_setup(sys);
200 break;
201 case 1:
202 pp->base = (void __iomem *)PCIE1_VIRT_BASE;
203 pp->irq = IRQ_KIRKWOOD_PCIE1;
204 kirkwood_clk_ctrl |= CGC_PEX1;
205 pcie1_ioresources_setup(sys);
206 break;
207 default:
208 panic("PCIe setup: invalid controller");
209 }
210
211 /*
212 * Generic PCIe unit setup.
213 */
214 orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
215
216 orion_pcie_setup(pp->base, &kirkwood_mbus_dram_info);
140 217
141 return 1; 218 return 1;
142} 219}
@@ -163,7 +240,7 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
163{ 240{
164 struct pci_bus *bus; 241 struct pci_bus *bus;
165 242
166 if (nr == 0) { 243 if (nr < num_pcie_ports) {
167 bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); 244 bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
168 } else { 245 } else {
169 bus = NULL; 246 bus = NULL;
@@ -175,18 +252,37 @@ kirkwood_pcie_scan_bus(int nr, struct pci_sys_data *sys)
175 252
176static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 253static int __init kirkwood_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
177{ 254{
178 return IRQ_KIRKWOOD_PCIE; 255 struct pcie_port *pp = bus_to_port(dev->bus);
256
257 return pp->irq;
179} 258}
180 259
181static struct hw_pci kirkwood_pci __initdata = { 260static struct hw_pci kirkwood_pci __initdata = {
182 .nr_controllers = 1,
183 .swizzle = pci_std_swizzle, 261 .swizzle = pci_std_swizzle,
184 .setup = kirkwood_pcie_setup, 262 .setup = kirkwood_pcie_setup,
185 .scan = kirkwood_pcie_scan_bus, 263 .scan = kirkwood_pcie_scan_bus,
186 .map_irq = kirkwood_pcie_map_irq, 264 .map_irq = kirkwood_pcie_map_irq,
187}; 265};
188 266
189void __init kirkwood_pcie_init(void) 267static void __init add_pcie_port(int index, unsigned long base)
268{
269 printk(KERN_INFO "Kirkwood PCIe port %d: ", index);
270
271 if (orion_pcie_link_up((void __iomem *)base)) {
272 printk(KERN_INFO "link up\n");
273 pcie_port_map[num_pcie_ports++] = index;
274 } else
275 printk(KERN_INFO "link down, ignoring\n");
276}
277
278void __init kirkwood_pcie_init(unsigned int portmask)
190{ 279{
280 if (portmask & KW_PCIE0)
281 add_pcie_port(0, PCIE_VIRT_BASE);
282
283 if (portmask & KW_PCIE1)
284 add_pcie_port(1, PCIE1_VIRT_BASE);
285
286 kirkwood_pci.nr_controllers = num_pcie_ports;
191 pci_common_init(&kirkwood_pci); 287 pci_common_init(&kirkwood_pci);
192} 288}
diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
index 3bf6304158f6..c34718c2cfe5 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)
71static int __init rd88f6192_pci_init(void) 71static int __init rd88f6192_pci_init(void)
72{ 72{
73 if (machine_is_rd88f6192_nas()) 73 if (machine_is_rd88f6192_nas())
74 kirkwood_pcie_init(); 74 kirkwood_pcie_init(KW_PCIE0);
75 75
76 return 0; 76 return 0;
77} 77}
diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index 31708ddbc83e..3d1477135e12 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)
107static int __init rd88f6281_pci_init(void) 107static int __init rd88f6281_pci_init(void)
108{ 108{
109 if (machine_is_rd88f6281()) 109 if (machine_is_rd88f6281())
110 kirkwood_pcie_init(); 110 kirkwood_pcie_init(KW_PCIE0);
111 111
112 return 0; 112 return 0;
113} 113}
diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c
index 6a94daa04ca2..d01bf89cedbe 100644
--- a/arch/arm/mach-kirkwood/t5325-setup.c
+++ b/arch/arm/mach-kirkwood/t5325-setup.c
@@ -176,7 +176,7 @@ static void __init hp_t5325_init(void)
176static int __init hp_t5325_pci_init(void) 176static int __init hp_t5325_pci_init(void)
177{ 177{
178 if (machine_is_t5325()) 178 if (machine_is_t5325())
179 kirkwood_pcie_init(); 179 kirkwood_pcie_init(KW_PCIE0);
180 180
181 return 0; 181 return 0;
182} 182}
diff --git a/arch/arm/mach-kirkwood/ts219-setup.c b/arch/arm/mach-kirkwood/ts219-setup.c
index 063979d1babb..a5bd7fde04a9 100644
--- a/arch/arm/mach-kirkwood/ts219-setup.c
+++ b/arch/arm/mach-kirkwood/ts219-setup.c
@@ -111,10 +111,10 @@ static void __init qnap_ts219_init(void)
111 111
112static int __init ts219_pci_init(void) 112static int __init ts219_pci_init(void)
113{ 113{
114 if (machine_is_ts219()) 114 if (machine_is_ts219())
115 kirkwood_pcie_init(); 115 kirkwood_pcie_init(KW_PCIE0);
116 116
117 return 0; 117 return 0;
118} 118}
119subsys_initcall(ts219_pci_init); 119subsys_initcall(ts219_pci_init);
120 120
diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c
index e9d85d7cc674..2e14afef07a2 100644
--- a/arch/arm/mach-kirkwood/ts41x-setup.c
+++ b/arch/arm/mach-kirkwood/ts41x-setup.c
@@ -141,7 +141,7 @@ static void __init qnap_ts41x_init(void)
141static int __init ts41x_pci_init(void) 141static int __init ts41x_pci_init(void)
142{ 142{
143 if (machine_is_ts41x()) 143 if (machine_is_ts41x())
144 kirkwood_pcie_init(); 144 kirkwood_pcie_init(KW_PCIE0);
145 145
146 return 0; 146 return 0;
147} 147}