aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRoderick Colenbrander <thunderbird2k@gmail.com>2009-06-06 12:14:22 -0400
committerGrant Likely <grant.likely@secretlab.ca>2009-06-06 12:14:22 -0400
commit64f16502475ddf663169369fffff6da9b10ea9fb (patch)
treef87337788f02c425e821955905a04e5e293f81e6 /arch
parentbaf75b0a42a1b3f6fca80f8949b6141eaff61b0d (diff)
powerpc/virtex: Add support for Xilinx PCI host bridge
This patch adds support for the Xilinx plbv46-pci-1.03.a PCI host bridge IPcore. Signed-off-by: Roderick Colenbrander <thunderbird2k@gmail.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/xilinx_pci.h21
-rw-r--r--arch/powerpc/platforms/40x/virtex.c2
-rw-r--r--arch/powerpc/platforms/44x/virtex.c2
-rw-r--r--arch/powerpc/platforms/Kconfig4
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/xilinx_pci.c132
6 files changed, 162 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/xilinx_pci.h b/arch/powerpc/include/asm/xilinx_pci.h
new file mode 100644
index 000000000000..7a8275caf6af
--- /dev/null
+++ b/arch/powerpc/include/asm/xilinx_pci.h
@@ -0,0 +1,21 @@
1/*
2 * Xilinx pci external definitions
3 *
4 * Copyright 2009 Roderick Colenbrander
5 * Copyright 2009 Secret Lab Technologies Ltd.
6 *
7 * This file is licensed under the terms of the GNU General Public License
8 * version 2. This program is licensed "as is" without any warranty of any
9 * kind, whether express or implied.
10 */
11
12#ifndef INCLUDE_XILINX_PCI
13#define INCLUDE_XILINX_PCI
14
15#ifdef CONFIG_XILINX_PCI
16extern void __init xilinx_pci_init(void);
17#else
18static inline void __init xilinx_pci_init(void) { return; }
19#endif
20
21#endif /* INCLUDE_XILINX_PCI */
diff --git a/arch/powerpc/platforms/40x/virtex.c b/arch/powerpc/platforms/40x/virtex.c
index fc7fb001276c..d0fc6866b00c 100644
--- a/arch/powerpc/platforms/40x/virtex.c
+++ b/arch/powerpc/platforms/40x/virtex.c
@@ -14,6 +14,7 @@
14#include <asm/prom.h> 14#include <asm/prom.h>
15#include <asm/time.h> 15#include <asm/time.h>
16#include <asm/xilinx_intc.h> 16#include <asm/xilinx_intc.h>
17#include <asm/xilinx_pci.h>
17#include <asm/ppc4xx.h> 18#include <asm/ppc4xx.h>
18 19
19static struct of_device_id xilinx_of_bus_ids[] __initdata = { 20static struct of_device_id xilinx_of_bus_ids[] __initdata = {
@@ -47,6 +48,7 @@ static int __init virtex_probe(void)
47define_machine(virtex) { 48define_machine(virtex) {
48 .name = "Xilinx Virtex", 49 .name = "Xilinx Virtex",
49 .probe = virtex_probe, 50 .probe = virtex_probe,
51 .setup_arch = xilinx_pci_init,
50 .init_IRQ = xilinx_intc_init_tree, 52 .init_IRQ = xilinx_intc_init_tree,
51 .get_irq = xilinx_intc_get_irq, 53 .get_irq = xilinx_intc_get_irq,
52 .restart = ppc4xx_reset_system, 54 .restart = ppc4xx_reset_system,
diff --git a/arch/powerpc/platforms/44x/virtex.c b/arch/powerpc/platforms/44x/virtex.c
index 68637faf70ae..cf96ccaa760c 100644
--- a/arch/powerpc/platforms/44x/virtex.c
+++ b/arch/powerpc/platforms/44x/virtex.c
@@ -16,6 +16,7 @@
16#include <asm/prom.h> 16#include <asm/prom.h>
17#include <asm/time.h> 17#include <asm/time.h>
18#include <asm/xilinx_intc.h> 18#include <asm/xilinx_intc.h>
19#include <asm/xilinx_pci.h>
19#include <asm/reg.h> 20#include <asm/reg.h>
20#include <asm/ppc4xx.h> 21#include <asm/ppc4xx.h>
21#include "44x.h" 22#include "44x.h"
@@ -53,6 +54,7 @@ static int __init virtex_probe(void)
53define_machine(virtex) { 54define_machine(virtex) {
54 .name = "Xilinx Virtex440", 55 .name = "Xilinx Virtex440",
55 .probe = virtex_probe, 56 .probe = virtex_probe,
57 .setup_arch = xilinx_pci_init,
56 .init_IRQ = xilinx_intc_init_tree, 58 .init_IRQ = xilinx_intc_init_tree,
57 .get_irq = xilinx_intc_get_irq, 59 .get_irq = xilinx_intc_get_irq,
58 .calibrate_decr = generic_calibrate_decr, 60 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index e3e87078d03f..04a8061045c4 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -329,4 +329,8 @@ config MCU_MPC8349EMITX
329 also register MCU GPIOs with the generic GPIO API, so you'll able 329 also register MCU GPIOs with the generic GPIO API, so you'll able
330 to use MCU pins as GPIOs. 330 to use MCU pins as GPIOs.
331 331
332config XILINX_PCI
333 bool "Xilinx PCI host bridge support"
334 depends on PCI && XILINX_VIRTEX
335
332endmenu 336endmenu
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index b33b28a6fe12..2d1c87dd5d14 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_IPIC) += ipic.o
34obj-$(CONFIG_4xx) += uic.o 34obj-$(CONFIG_4xx) += uic.o
35obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o 35obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o
36obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o 36obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o
37obj-$(CONFIG_XILINX_PCI) += xilinx_pci.o
37obj-$(CONFIG_OF_RTC) += of_rtc.o 38obj-$(CONFIG_OF_RTC) += of_rtc.o
38ifeq ($(CONFIG_PCI),y) 39ifeq ($(CONFIG_PCI),y)
39obj-$(CONFIG_4xx) += ppc4xx_pci.o 40obj-$(CONFIG_4xx) += ppc4xx_pci.o
diff --git a/arch/powerpc/sysdev/xilinx_pci.c b/arch/powerpc/sysdev/xilinx_pci.c
new file mode 100644
index 000000000000..1453b0eed220
--- /dev/null
+++ b/arch/powerpc/sysdev/xilinx_pci.c
@@ -0,0 +1,132 @@
1/*
2 * PCI support for Xilinx plbv46_pci soft-core which can be used on
3 * Xilinx Virtex ML410 / ML510 boards.
4 *
5 * Copyright 2009 Roderick Colenbrander
6 * Copyright 2009 Secret Lab Technologies Ltd.
7 *
8 * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
9 * by Benjamin Herrenschmidt.
10 * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
11 *
12 * This file is licensed under the terms of the GNU General Public License
13 * version 2. This program is licensed "as is" without any warranty of any
14 * kind, whether express or implied.
15 */
16
17#include <linux/ioport.h>
18#include <linux/of.h>
19#include <linux/pci.h>
20#include <mm/mmu_decl.h>
21#include <asm/io.h>
22#include <asm/xilinx_pci.h>
23
24#define XPLB_PCI_ADDR 0x10c
25#define XPLB_PCI_DATA 0x110
26#define XPLB_PCI_BUS 0x114
27
28#define PCI_HOST_ENABLE_CMD PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
29
30static struct of_device_id xilinx_pci_match[] = {
31 { .compatible = "xlnx,plbv46-pci-1.03.a", },
32 {}
33};
34
35/**
36 * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
37 */
38static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
39{
40 struct pci_controller *hose;
41 int i;
42
43 if (dev->devfn || dev->bus->self)
44 return;
45
46 hose = pci_bus_to_host(dev->bus);
47 if (!hose)
48 return;
49
50 if (!of_match_node(xilinx_pci_match, hose->dn))
51 return;
52
53 /* Hide the PCI host BARs from the kernel as their content doesn't
54 * fit well in the resource management
55 */
56 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
57 dev->resource[i].start = 0;
58 dev->resource[i].end = 0;
59 dev->resource[i].flags = 0;
60 }
61
62 dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
63 pci_name(dev));
64}
65DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
66
67/**
68 * xilinx_pci_exclude_device - Don't do config access for non-root bus
69 *
70 * This is a hack. Config access to any bus other than bus 0 does not
71 * currently work on the ML510 so we prevent it here.
72 */
73static int
74xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
75{
76 return (bus != 0);
77}
78
79/**
80 * xilinx_pci_init - Find and register a Xilinx PCI host bridge
81 */
82void __init xilinx_pci_init(void)
83{
84 struct pci_controller *hose;
85 struct resource r;
86 void __iomem *pci_reg;
87 struct device_node *pci_node;
88
89 pci_node = of_find_matching_node(NULL, xilinx_pci_match);
90 if(!pci_node)
91 return;
92
93 if (of_address_to_resource(pci_node, 0, &r)) {
94 pr_err("xilinx-pci: cannot resolve base address\n");
95 return;
96 }
97
98 hose = pcibios_alloc_controller(pci_node);
99 if (!hose) {
100 pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
101 return;
102 }
103
104 /* Setup config space */
105 setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
106 r.start + XPLB_PCI_DATA,
107 PPC_INDIRECT_TYPE_SET_CFG_TYPE);
108
109 /* According to the xilinx plbv46_pci documentation the soft-core starts
110 * a self-init when the bus master enable bit is set. Without this bit
111 * set the pci bus can't be scanned.
112 */
113 early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
114
115 /* Set the max latency timer to 255 */
116 early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
117
118 /* Set the max bus number to 255 */
119 pci_reg = of_iomap(pci_node, 0);
120 out_8(pci_reg + XPLB_PCI_BUS, 0xff);
121 iounmap(pci_reg);
122
123 /* Nothing past the root bridge is working right now. By default
124 * exclude config access to anything except bus 0 */
125 if (!ppc_md.pci_exclude_device)
126 ppc_md.pci_exclude_device = xilinx_pci_exclude_device;
127
128 /* Register the host bridge with the linux kernel! */
129 pci_process_bridge_OF_ranges(hose, pci_node, 1);
130
131 pr_info("xilinx-pci: Registered PCI host bridge\n");
132}