2 * arch/arm/mach-kirkwood/pcie.c
4 * PCIe functions for Marvell Kirkwood SoCs
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include <linux/slab.h>
14 #include <linux/mbus.h>
16 #include <asm/mach/pci.h>
17 #include <plat/pcie.h>
18 #include <mach/bridge-regs.h>
21 void __init
kirkwood_pcie_id(u32
*dev
, u32
*rev
)
23 *dev
= orion_pcie_dev_id((void __iomem
*)PCIE_VIRT_BASE
);
24 *rev
= orion_pcie_rev((void __iomem
*)PCIE_VIRT_BASE
);
32 struct resource res
[2];
35 static int pcie_port_map
[2];
36 static int num_pcie_ports
;
38 static inline struct pcie_port
*bus_to_port(struct pci_bus
*bus
)
40 struct pci_sys_data
*sys
= bus
->sysdata
;
41 return sys
->private_data
;
44 static int pcie_valid_config(struct pcie_port
*pp
, int bus
, int dev
)
47 * Don't go out when trying to access --
48 * 1. nonexisting device on local bus
49 * 2. where there's no device connected (no link)
51 if (bus
== pp
->root_bus_nr
&& dev
== 0)
54 if (!orion_pcie_link_up(pp
->base
))
57 if (bus
== pp
->root_bus_nr
&& dev
!= 1)
65 * PCIe config cycles are done by programming the PCIE_CONF_ADDR register
66 * and then reading the PCIE_CONF_DATA register. Need to make sure these
67 * transactions are atomic.
70 static int pcie_rd_conf(struct pci_bus
*bus
, u32 devfn
, int where
,
73 struct pcie_port
*pp
= bus_to_port(bus
);
77 if (pcie_valid_config(pp
, bus
->number
, PCI_SLOT(devfn
)) == 0) {
79 return PCIBIOS_DEVICE_NOT_FOUND
;
82 spin_lock_irqsave(&pp
->conf_lock
, flags
);
83 ret
= orion_pcie_rd_conf(pp
->base
, bus
, devfn
, where
, size
, val
);
84 spin_unlock_irqrestore(&pp
->conf_lock
, flags
);
89 static int pcie_wr_conf(struct pci_bus
*bus
, u32 devfn
,
90 int where
, int size
, u32 val
)
92 struct pcie_port
*pp
= bus_to_port(bus
);
96 if (pcie_valid_config(pp
, bus
->number
, PCI_SLOT(devfn
)) == 0)
97 return PCIBIOS_DEVICE_NOT_FOUND
;
99 spin_lock_irqsave(&pp
->conf_lock
, flags
);
100 ret
= orion_pcie_wr_conf(pp
->base
, bus
, devfn
, where
, size
, val
);
101 spin_unlock_irqrestore(&pp
->conf_lock
, flags
);
106 static struct pci_ops pcie_ops
= {
107 .read
= pcie_rd_conf
,
108 .write
= pcie_wr_conf
,
111 static int __init
pcie0_ioresources_setup(struct pci_sys_data
*sys
)
113 struct pcie_port
*pp
= (struct pcie_port
*)sys
->private_data
;
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];
129 pp
->res
[1].name
= "PCIe 0 MEM";
130 pp
->res
[1].start
= KIRKWOOD_PCIE_MEM_PHYS_BASE
;
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];
137 sys
->resource
[2] = NULL
;
143 static int __init
pcie1_ioresources_setup(struct pci_sys_data
*sys
)
145 struct pcie_port
*pp
= (struct pcie_port
*)sys
->private_data
;
150 pp
->res
[0].name
= "PCIe 1 I/O Space";
151 pp
->res
[0].start
= KIRKWOOD_PCIE1_IO_PHYS_BASE
;
152 pp
->res
[0].end
= pp
->res
[0].start
+ KIRKWOOD_PCIE1_IO_SIZE
- 1;
153 pp
->res
[0].flags
= IORESOURCE_IO
;
154 if (request_resource(&ioport_resource
, &pp
->res
[0]))
155 panic("Request PCIe 1 IO resource failed\n");
156 sys
->resource
[0] = &pp
->res
[0];
161 pp
->res
[1].name
= "PCIe 1 MEM";
162 pp
->res
[1].start
= KIRKWOOD_PCIE1_MEM_PHYS_BASE
;
163 pp
->res
[1].end
= pp
->res
[1].start
+ KIRKWOOD_PCIE1_MEM_SIZE
- 1;
164 pp
->res
[1].flags
= IORESOURCE_MEM
;
165 if (request_resource(&iomem_resource
, &pp
->res
[1]))
166 panic("Request PCIe 1 Memory resource failed\n");
167 sys
->resource
[1] = &pp
->res
[1];
169 sys
->resource
[2] = NULL
;
175 static int __init
kirkwood_pcie_setup(int nr
, struct pci_sys_data
*sys
)
177 extern unsigned int kirkwood_clk_ctrl
;
178 struct pcie_port
*pp
;
181 if (nr
>= num_pcie_ports
)
184 index
= pcie_port_map
[nr
];
185 printk(KERN_INFO
"PCI: bus%d uses PCIe port %d\n", sys
->busnr
, index
);
187 pp
= kzalloc(sizeof(*pp
), GFP_KERNEL
);
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
);
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
);
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
);
208 panic("PCIe setup: invalid controller");
212 * Generic PCIe unit setup.
214 orion_pcie_set_local_bus_nr(pp
->base
, sys
->busnr
);
216 orion_pcie_setup(pp
->base
, &kirkwood_mbus_dram_info
);
221 static void __devinit
rc_pci_fixup(struct pci_dev
*dev
)
224 * Prevent enumeration of root complex.
226 if (dev
->bus
->parent
== NULL
&& dev
->devfn
== 0) {
229 for (i
= 0; i
< DEVICE_COUNT_RESOURCE
; i
++) {
230 dev
->resource
[i
].start
= 0;
231 dev
->resource
[i
].end
= 0;
232 dev
->resource
[i
].flags
= 0;
236 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL
, PCI_ANY_ID
, rc_pci_fixup
);
238 static struct pci_bus __init
*
239 kirkwood_pcie_scan_bus(int nr
, struct pci_sys_data
*sys
)
243 if (nr
< num_pcie_ports
) {
244 bus
= pci_scan_bus(sys
->busnr
, &pcie_ops
, sys
);
253 static int __init
kirkwood_pcie_map_irq(struct pci_dev
*dev
, u8 slot
, u8 pin
)
255 struct pcie_port
*pp
= bus_to_port(dev
->bus
);
260 static struct hw_pci kirkwood_pci __initdata
= {
261 .swizzle
= pci_std_swizzle
,
262 .setup
= kirkwood_pcie_setup
,
263 .scan
= kirkwood_pcie_scan_bus
,
264 .map_irq
= kirkwood_pcie_map_irq
,
267 static void __init
add_pcie_port(int index
, unsigned long base
)
269 printk(KERN_INFO
"Kirkwood PCIe port %d: ", index
);
271 if (orion_pcie_link_up((void __iomem
*)base
)) {
272 printk(KERN_INFO
"link up\n");
273 pcie_port_map
[num_pcie_ports
++] = index
;
275 printk(KERN_INFO
"link down, ignoring\n");
278 void __init
kirkwood_pcie_init(unsigned int portmask
)
280 if (portmask
& KW_PCIE0
)
281 add_pcie_port(0, PCIE_VIRT_BASE
);
283 if (portmask
& KW_PCIE1
)
284 add_pcie_port(1, PCIE1_VIRT_BASE
);
286 kirkwood_pci
.nr_controllers
= num_pcie_ports
;
287 pci_common_init(&kirkwood_pci
);