Comments
Patch
@@ -12,3 +12,7 @@ config PPC_MSI_BITMAP
depends on PCI_MSI
default y if MPIC
default y if FSL_PCI
+
+config XILINX_VIRTEX_PCI
+ bool
+ depends on PCI
@@ -34,6 +34,7 @@ obj-$(CONFIG_IPIC) += ipic.o
obj-$(CONFIG_4xx) += uic.o
obj-$(CONFIG_4xx_SOC) += ppc4xx_soc.o
obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o
+obj-$(CONFIG_XILINX_VIRTEX_PCI) += virtex_pci.o
obj-$(CONFIG_OF_RTC) += of_rtc.o
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_4xx) += ppc4xx_pci.o
new file mode 100644
@@ -0,0 +1,99 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/pci.h>
+#include <mm/mmu_decl.h>
+#include <asm/io.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS 0x114
+
+#define PCI_HOST_ENABLE_CMD PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+
+static void fixup_virtex_pci_bridge(struct pci_dev *dev)
+{
+ struct pci_controller *hose;
+ int i;
+
+ if (dev->devfn || dev->bus->self)
+ return;
+
+ hose = pci_bus_to_host(dev->bus);
+ if (!hose)
+ return;
+
+ if(!of_device_is_compatible(hose->dn, "xlnx,plbv46-pci-1.03.a"))
+ return;
+
+ /* Hide the PCI host BARs from the kernel as their content doesn't
+ * fit well in the resource management
+ */
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++)
+ {
+ dev->resource[i].start = 0;
+ dev->resource[i].end = 0;
+ dev->resource[i].flags = 0;
+ }
+
+ dev_info(&dev->dev, "PCI: Hiding Xilinx plb-pci host bridge
resources %s\n", pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_virtex_pci_bridge);
+
+void virtex_pci_init(void)
+{
+ struct pci_controller *hose;
+ struct resource r;
+ void __iomem *pci_reg;
+ struct device_node *pci_node = of_find_compatible_node(NULL,
NULL, "xlnx,plbv46-pci-1.03.a");
+
+ if(!pci_node)
+ return;
+
+ printk("Found a Xilinx plb-pci host bridge\n");
+
+ if(of_address_to_resource(pci_node, 0, &r))
+ {
+ printk("No address for Xilinx plb-pci host bridge\n");
+ return;
+ }
+
+ hose = pcibios_alloc_controller(pci_node);
+ if (!hose)
+ return;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0;
+
+ /* Setup config space */
+ setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR, r.start +
XPLB_PCI_DATA, PPC_INDIRECT_TYPE_SET_CFG_TYPE);
+
+ /* According to the xilinx plbv46_pci documentation the soft-core starts
+ * a self-init when the bus master enable bit is set. Without this bit
+ * set the pci bus can't be scanned.
+ */
+ early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+ /* Set the max latency timer to 255 */
+ early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+ /* Set the max bus number to 255 */
+ pci_reg = of_iomap(pci_node, 0);
+ out_8(pci_reg + XPLB_PCI_BUS, 0xff);
+ iounmap(pci_reg);