From: Robert Richter <rric@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>,
Grant Likely <grant.likely@linaro.org>,
Rob Herring <robh+dt@kernel.org>
Cc: devicetree@vger.kernel.org, Arnd Bergmann <arnd@arndb.de>,
Liviu Dudau <liviu.dudau@arm.com>,
Will Deacon <will.deacon@arm.com>,
linux-kernel@vger.kernel.org,
Robert Richter <rrichter@cavium.com>,
linux-pci@vger.kernel.org, Sunil Goutham <sgoutham@cavium.com>,
linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/6] pci, thunder: Add support for Thunder PCIe host controller
Date: Wed, 24 Sep 2014 17:37:43 +0200 [thread overview]
Message-ID: <1411573068-12952-2-git-send-email-rric@kernel.org> (raw)
In-Reply-To: <1411573068-12952-1-git-send-email-rric@kernel.org>
From: Sunil Goutham <sgoutham@cavium.com>
This patch adds support for PCI host controller of Cavium Thunder
SoCs.
Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
drivers/pci/host/Kconfig | 8 ++
drivers/pci/host/Makefile | 1 +
drivers/pci/host/pcie-thunder.c | 246 ++++++++++++++++++++++++++++++++++++++++
include/linux/pci_ids.h | 2 +
4 files changed, 257 insertions(+)
create mode 100644 drivers/pci/host/pcie-thunder.c
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 90f5ccacce4b..269c3ff786bc 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -63,4 +63,12 @@ config PCIE_SPEAR13XX
help
Say Y here if you want PCIe support on SPEAr13XX SoCs.
+config PCI_THUNDER
+ bool "Thunder PCIe host controller"
+ depends on ARM64 || COMPILE_TEST
+ depends on OF_PCI
+ depends on PCI_MSI
+ help
+ Say Y here if you want internal PCI support on Thunder SoC.
+
endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index d0e88f114ff9..fd8041da1719 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o
obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
+obj-$(CONFIG_PCI_THUNDER) += pcie-thunder.o
diff --git a/drivers/pci/host/pcie-thunder.c b/drivers/pci/host/pcie-thunder.c
new file mode 100644
index 000000000000..947fad3b1980
--- /dev/null
+++ b/drivers/pci/host/pcie-thunder.c
@@ -0,0 +1,246 @@
+/*
+ * PCIe host controller driver for Cavium Thunder SOC
+ *
+ * Copyright (C) 2014, Cavium Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_irq.h>
+#include <linux/of_pci.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/msi.h>
+
+#define PCI_DEVICE_ID_THUNDER_BRIDGE 0xa002
+
+#define THUNDER_PCIE_BUS_SHIFT 20
+#define THUNDER_PCIE_DEV_SHIFT 15
+#define THUNDER_PCIE_FUNC_SHIFT 12
+
+struct thunder_pcie {
+ struct device_node *node;
+ struct device *dev;
+ void __iomem *cfg_base;
+ struct msi_chip *msi;
+};
+
+/*
+ * This bridge is just for the sake of supporting ARI for
+ * downstream devices. No resources are attached to it.
+ * Copy upstream root bus resources to bridge which aide in
+ * resource claiming for downstream devices
+ */
+static void pci_bridge_resource_fixup(struct pci_dev *dev)
+{
+ struct pci_bus *bus;
+ int resno;
+
+ bus = dev->subordinate;
+ for (resno = 0; resno < PCI_BRIDGE_RESOURCE_NUM; resno++) {
+ bus->resource[resno] = pci_bus_resource_n(bus->parent,
+ PCI_BRIDGE_RESOURCE_NUM + resno);
+ }
+
+ for (resno = PCI_BRIDGE_RESOURCES;
+ resno <= PCI_BRIDGE_RESOURCE_END; resno++) {
+ dev->resource[resno].start = dev->resource[resno].end = 0;
+ dev->resource[resno].flags = 0;
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_THUNDER_BRIDGE,
+ pci_bridge_resource_fixup);
+
+/*
+ * All PCIe devices in Thunder have fixed resources, shouldn't be reassigned.
+ * Also claim the device's valid resources to set 'res->parent' hierarchy.
+ */
+static void pci_dev_resource_fixup(struct pci_dev *dev)
+{
+ struct resource *res;
+ int resno;
+
+ for (resno = 0; resno < PCI_NUM_RESOURCES; resno++)
+ dev->resource[resno].flags |= IORESOURCE_PCI_FIXED;
+
+ for (resno = 0; resno < PCI_BRIDGE_RESOURCES; resno++) {
+ res = &dev->resource[resno];
+ if (res->parent || !(res->flags & IORESOURCE_MEM))
+ continue;
+ pci_claim_resource(dev, resno);
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CAVIUM, PCI_ANY_ID,
+ pci_dev_resource_fixup);
+
+static void __iomem *thunder_pcie_cfg_base(struct thunder_pcie *pcie,
+ unsigned int bus, unsigned int devfn)
+{
+ return pcie->cfg_base + ((bus << THUNDER_PCIE_BUS_SHIFT)
+ | (PCI_SLOT(devfn) << THUNDER_PCIE_DEV_SHIFT)
+ | (PCI_FUNC(devfn) << THUNDER_PCIE_FUNC_SHIFT));
+}
+
+static int thunder_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ struct thunder_pcie *pcie = bus->sysdata;
+ void __iomem *addr;
+ unsigned int busnr = bus->number;
+
+ if (busnr > 255 || devfn > 255 || reg > 4095)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = thunder_pcie_cfg_base(pcie, busnr, devfn) + reg;
+
+ switch (size) {
+ case 1:
+ *val = readb(addr);
+ break;
+ case 2:
+ *val = readw(addr);
+ break;
+ case 4:
+ *val = readl(addr);
+ break;
+ default:
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int thunder_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ struct thunder_pcie *pcie = bus->sysdata;
+ void __iomem *addr;
+ unsigned int busnr = bus->number;
+
+ if (busnr > 255 || devfn > 255 || reg > 4095)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = thunder_pcie_cfg_base(pcie, busnr, devfn) + reg;
+
+ switch (size) {
+ case 1:
+ writeb(val, addr);
+ break;
+ case 2:
+ writew(val, addr);
+ break;
+ case 4:
+ writel(val, addr);
+ break;
+ default:
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops thunder_pcie_ops = {
+ .read = thunder_pcie_read_config,
+ .write = thunder_pcie_write_config,
+};
+
+static int thunder_pcie_msi_enable(struct thunder_pcie *pcie,
+ struct pci_bus *bus)
+{
+ struct device_node *msi_node;
+
+ msi_node = of_parse_phandle(pcie->node, "msi-parent", 0);
+ if (!msi_node)
+ return -ENODEV;
+
+ pcie->msi = of_pci_find_msi_chip_by_node(msi_node);
+ if (!pcie->msi)
+ return -ENODEV;
+
+ pcie->msi->dev = pcie->dev;
+ bus->msi = pcie->msi;
+
+ return 0;
+}
+
+static int thunder_pcie_probe(struct platform_device *pdev)
+{
+ struct thunder_pcie *pcie;
+ struct resource *cfg_base;
+ struct pci_bus *bus;
+ int ret;
+ LIST_HEAD(res);
+
+ pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pcie->node = of_node_get(pdev->dev.of_node);
+ pcie->dev = &pdev->dev;
+
+ /* Get controller's configuration space range */
+ cfg_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pcie->cfg_base = devm_ioremap_resource(&pdev->dev, cfg_base);
+ if (IS_ERR(pcie->cfg_base)) {
+ ret = PTR_ERR(pcie->cfg_base);
+ goto err_ioremap;
+ }
+
+ ret = of_pci_get_host_bridge_resources(pdev->dev.of_node,
+ 0, 255, &res, NULL);
+ if (ret)
+ goto err_get_host;
+
+ bus = pci_create_root_bus(&pdev->dev, 0, &thunder_pcie_ops, pcie, &res);
+ if (!bus) {
+ ret = -ENODEV;
+ goto err_root_bus;
+ }
+
+ /* Set reference to MSI chip */
+ ret = thunder_pcie_msi_enable(pcie, bus);
+ if (ret)
+ goto err_msi;
+
+ platform_set_drvdata(pdev, pcie);
+
+ pci_scan_child_bus(bus);
+ pci_bus_add_devices(bus);
+
+ return 0;
+err_msi:
+ pci_remove_root_bus(bus);
+err_root_bus:
+ pci_free_resource_list(&res);
+err_get_host:
+ devm_ioremap_release(pcie->dev, pcie->cfg_base);
+err_ioremap:
+ of_node_put(pcie->node);
+ kfree(pcie);
+ return ret;
+}
+
+static const struct of_device_id thunder_pcie_of_match[] = {
+ { .compatible = "cavium,thunder-pcie", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, thunder_pcie_of_match);
+
+static struct platform_driver thunder_pcie_driver = {
+ .driver = {
+ .name = "thunder-pcie",
+ .owner = THIS_MODULE,
+ .of_match_table = thunder_pcie_of_match,
+ },
+ .probe = thunder_pcie_probe,
+};
+module_platform_driver(thunder_pcie_driver);
+
+MODULE_AUTHOR("Sunil Goutham");
+MODULE_DESCRIPTION("Cavium Thunder PCIe host controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 6ed0bb73a864..60f16b888c9d 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2322,6 +2322,8 @@
#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb
+#define PCI_VENDOR_ID_CAVIUM 0x177d
+
#define PCI_VENDOR_ID_BELKIN 0x1799
#define PCI_DEVICE_ID_BELKIN_F5D7010V7 0x701f
--
2.1.0
next parent reply other threads:[~2014-09-24 15:37 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1411573068-12952-1-git-send-email-rric@kernel.org>
2014-09-24 15:37 ` Robert Richter [this message]
2014-09-24 16:12 ` [PATCH 1/6] pci, thunder: Add support for Thunder PCIe host controller Arnd Bergmann
2014-09-24 16:49 ` Will Deacon
2014-09-30 9:14 ` Sunil Kovvuri
2014-09-24 15:37 ` [PATCH 2/6] GICv3: Add ITS entry to THUNDER dts Robert Richter
2015-06-25 23:19 ` Chalamarla, Tirumalesh
2015-06-26 9:00 ` Marc Zyngier
2014-09-24 15:37 ` [PATCH 3/6] pci, thunder: Add PCIe host controller devicetree bindings Robert Richter
2014-09-24 16:06 ` Arnd Bergmann
2014-09-24 18:04 ` Sunil Kovvuri
[not found] ` <CA+sq2Ce8sb=YGma05qEk_992Mc9M92TxCk+RWsyi6tY-FVOCXw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-24 18:34 ` Arnd Bergmann
2014-09-24 19:07 ` Sunil Kovvuri
2014-09-25 7:31 ` Arnd Bergmann
2014-09-25 16:16 ` Bjorn Helgaas
2014-09-25 19:26 ` Arnd Bergmann
[not found] ` <201409252126.38945.arnd-r2nGTMty4D4@public.gmane.org>
2014-09-25 20:10 ` Bjorn Helgaas
[not found] ` <CAErSpo5rhL7pLha-yWt7sZUBmAnwA6FkacL+sWXBKkSzsuC7Sg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-09-25 20:22 ` Arnd Bergmann
2014-09-25 20:49 ` Bjorn Helgaas
2014-09-26 18:26 ` Rob Herring
2014-09-30 9:11 ` Sunil Kovvuri
2014-10-07 14:27 ` Robert Richter
[not found] ` <20141007142744.GE31556-vWBEXY7mpu73kLQC+b9v0A@public.gmane.org>
2014-10-07 15:01 ` Liviu Dudau
2014-10-08 8:49 ` Robert Richter
2014-10-08 16:44 ` Liviu Dudau
[not found] ` <20141008164432.GC15382-2JSQmVVBSi7ZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2014-10-09 6:23 ` Robert Richter
2014-09-24 15:37 ` [PATCH 4/6] pci, thunder: Document " Robert Richter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1411573068-12952-2-git-send-email-rric@kernel.org \
--to=rric@kernel.org \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=devicetree@vger.kernel.org \
--cc=grant.likely@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=liviu.dudau@arm.com \
--cc=robh+dt@kernel.org \
--cc=rrichter@cavium.com \
--cc=sgoutham@cavium.com \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).