summaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-layerscape-ep.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-09 14:57:08 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-09 14:57:08 -0800
commit2901752c14b8e1b7dd898d2e5245c93e531aa624 (patch)
tree98780bc17593a3d79e7b3fe2ecf23f2e8882a39a /drivers/pci/controller/dwc/pci-layerscape-ep.c
parent96a6de1a541c86e9e67b9c310c14db4099bd1cbc (diff)
parentdd92b6677e3d0d78e261a7f00f28e753bab41d24 (diff)
downloadlinux-2901752c14b8e1b7dd898d2e5245c93e531aa624.tar.bz2
Merge tag 'pci-v5.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: - Use match_string() instead of reimplementing it (Andy Shevchenko) - Enable SERR# forwarding for all bridges (Bharat Kumar Gogada) - Use Latency Tolerance Reporting if already enabled by platform (Bjorn Helgaas) - Save/restore LTR info for suspend/resume (Bjorn Helgaas) - Fix DPC use of uninitialized data (Dongdong Liu) - Probe bridge window attributes only once at enumeration-time to fix device accesses during rescan (Bjorn Helgaas) - Return BAR size (not "size -1 ") from pci_size() to simplify code (Du Changbin) - Use config header type (not class code) identify bridges more reliably (Honghui Zhang) - Work around Intel Denverton incorrect Trace Hub BAR size reporting (Alexander Shishkin) - Reorder pciehp cached state/hardware state updates to avoid missed interrupts (Mika Westerberg) - Turn ibmphp semaphores into completions or mutexes (Arnd Bergmann) - Mark expected switch fall-through (Mathieu Malaterre) - Use of_node_name_eq() for node name comparisons (Rob Herring) - Add ACS and pciehp quirks for HXT SD4800 (Shunyong Yang) - Consolidate Rohm Vendor ID definitions (Andy Shevchenko) - Use u32 (not __u32) for things not exposed to userspace (Logan Gunthorpe) - Fix locking semantics of bus and slot reset interfaces (Alex Williamson) - Update PCIEPORTBUS Kconfig help text (Hou Zhiqiang) - Allow portdrv to claim subtractive decode Ports so PCIe services will work for them (Honghui Zhang) - Report PCIe links that become degraded at run-time (Alexandru Gagniuc) - Blacklist Gigabyte X299 Root Port power management to fix Thunderbolt hotplug (Mika Westerberg) - Revert runtime PM suspend/resume callbacks that broke PME on network cable plug (Mika Westerberg) - Disable Data Link State Changed interrupts to prevent wakeup immediately after suspend (Mika Westerberg) - Extend altera to support Stratix 10 (Ley Foon Tan) - Allow building altera driver on ARM64 (Ley Foon Tan) - Replace Douglas with Tom Joseph as Cadence PCI host/endpoint maintainer (Lorenzo Pieralisi) - Add DT support for R-Car RZ/G2E (R8A774C0) (Fabrizio Castro) - Add dra72x/dra74x/dra76x SoC compatible strings (Kishon Vijay Abraham I) - Enable x2 mode support for dra72x/dra74x/dra76x SoC (Kishon Vijay Abraham I) - Configure dra7xx PHY to PCIe mode (Kishon Vijay Abraham I) - Simplify dwc (remove unnecessary header includes, name variables consistently, reduce inverted logic, etc) (Gustavo Pimentel) - Add i.MX8MQ support (Andrey Smirnov) - Add message to help debug dwc MSI-X mask bit errors (Gustavo Pimentel) - Work around imx7d PCIe PLL erratum (Trent Piepho) - Don't assert qcom reset GPIO during probe (Bjorn Andersson) - Skip dwc MSI init if MSIs have been disabled (Lucas Stach) - Use memcpy_fromio()/memcpy_toio() instead of plain memcpy() in PCI endpoint framework (Wen Yang) - Add interface to discover supported endpoint features to replace a bitfield that wasn't flexible enough (Kishon Vijay Abraham I) - Implement the new supported-feature interface for designware-plat, dra7xx, rockchip, cadence (Kishon Vijay Abraham I) - Fix issues with 64-bit BAR in endpoints (Kishon Vijay Abraham I) - Add layerscape endpoint mode support (Xiaowei Bao) - Remove duplicate struct hv_vp_set in favor of struct hv_vpset (Maya Nakamura) - Rework hv_irq_unmask() to use cpumask_to_vpset() instead of open-coded reimplementation (Maya Nakamura) - Align Hyper-V struct retarget_msi_interrupt arguments (Maya Nakamura) - Fix mediatek MMIO size computation to enable full size of available MMIO space (Honghui Zhang) - Fix mediatek DMA window size computation to allow endpoint DMA access to full DRAM address range (Honghui Zhang) - Fix mvebu prefetchable BAR regression caused by common bridge emulation that assumed all bridges had prefetchable windows (Thomas Petazzoni) - Make advk_pci_bridge_emul_ops static (Wei Yongjun) - Configure MPS settings for VMD root ports (Jon Derrick) * tag 'pci-v5.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (92 commits) PCI: Update PCIEPORTBUS Kconfig help text PCI: Fix "try" semantics of bus and slot reset PCI/LINK: Report degraded links via link bandwidth notification dt-bindings: PCI: altera: Add altr,pcie-root-port-2.0 PCI: altera: Enable driver on ARM64 PCI: altera: Add Stratix 10 PCIe support PCI/PME: Fix possible use-after-free on remove PCI: aardvark: Make symbol 'advk_pci_bridge_emul_ops' static PCI: dwc: skip MSI init if MSIs have been explicitly disabled PCI: hv: Refactor hv_irq_unmask() to use cpumask_to_vpset() PCI: hv: Replace hv_vp_set with hv_vpset PCI: hv: Add __aligned(8) to struct retarget_msi_interrupt PCI: mediatek: Enlarge PCIe2AHB window size to support 4GB DRAM PCI: mediatek: Fix memory mapped IO range size computation PCI: dwc: Remove superfluous shifting in definitions PCI: dwc: Make use of GENMASK/FIELD_PREP PCI: dwc: Make use of BIT() in constant definitions PCI: dwc: Share code for dw_pcie_rd/wr_other_conf() PCI: dwc: Make use of IS_ALIGNED() PCI: imx6: Add code to request/control "pcie_aux" clock for i.MX8MQ ...
Diffstat (limited to 'drivers/pci/controller/dwc/pci-layerscape-ep.c')
-rw-r--r--drivers/pci/controller/dwc/pci-layerscape-ep.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-layerscape-ep.c b/drivers/pci/controller/dwc/pci-layerscape-ep.c
new file mode 100644
index 000000000000..a42c9c3ae1cc
--- /dev/null
+++ b/drivers/pci/controller/dwc/pci-layerscape-ep.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe controller EP driver for Freescale Layerscape SoCs
+ *
+ * Copyright (C) 2018 NXP Semiconductor.
+ *
+ * Author: Xiaowei Bao <xiaowei.bao@nxp.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/resource.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_DBI2_OFFSET 0x1000 /* DBI2 base address*/
+
+struct ls_pcie_ep {
+ struct dw_pcie *pci;
+};
+
+#define to_ls_pcie_ep(x) dev_get_drvdata((x)->dev)
+
+static int ls_pcie_establish_link(struct dw_pcie *pci)
+{
+ return 0;
+}
+
+static const struct dw_pcie_ops ls_pcie_ep_ops = {
+ .start_link = ls_pcie_establish_link,
+};
+
+static const struct of_device_id ls_pcie_ep_of_match[] = {
+ { .compatible = "fsl,ls-pcie-ep",},
+ { },
+};
+
+static const struct pci_epc_features ls_pcie_epc_features = {
+ .linkup_notifier = false,
+ .msi_capable = true,
+ .msix_capable = false,
+};
+
+static const struct pci_epc_features*
+ls_pcie_ep_get_features(struct dw_pcie_ep *ep)
+{
+ return &ls_pcie_epc_features;
+}
+
+static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ enum pci_barno bar;
+
+ for (bar = BAR_0; bar <= BAR_5; bar++)
+ dw_pcie_ep_reset_bar(pci, bar);
+}
+
+static int ls_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+ enum pci_epc_irq_type type, u16 interrupt_num)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+
+ switch (type) {
+ case PCI_EPC_IRQ_LEGACY:
+ return dw_pcie_ep_raise_legacy_irq(ep, func_no);
+ case PCI_EPC_IRQ_MSI:
+ return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
+ case PCI_EPC_IRQ_MSIX:
+ return dw_pcie_ep_raise_msix_irq(ep, func_no, interrupt_num);
+ default:
+ dev_err(pci->dev, "UNKNOWN IRQ type\n");
+ return -EINVAL;
+ }
+}
+
+static struct dw_pcie_ep_ops pcie_ep_ops = {
+ .ep_init = ls_pcie_ep_init,
+ .raise_irq = ls_pcie_ep_raise_irq,
+ .get_features = ls_pcie_ep_get_features,
+};
+
+static int __init ls_add_pcie_ep(struct ls_pcie_ep *pcie,
+ struct platform_device *pdev)
+{
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+ struct dw_pcie_ep *ep;
+ struct resource *res;
+ int ret;
+
+ ep = &pci->ep;
+ ep->ops = &pcie_ep_ops;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+ if (!res)
+ return -EINVAL;
+
+ ep->phys_base = res->start;
+ ep->addr_size = resource_size(res);
+
+ ret = dw_pcie_ep_init(ep);
+ if (ret) {
+ dev_err(dev, "failed to initialize endpoint\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __init ls_pcie_ep_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct dw_pcie *pci;
+ struct ls_pcie_ep *pcie;
+ struct resource *dbi_base;
+ int ret;
+
+ pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
+ if (!pci)
+ return -ENOMEM;
+
+ dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+ pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
+ if (IS_ERR(pci->dbi_base))
+ return PTR_ERR(pci->dbi_base);
+
+ pci->dbi_base2 = pci->dbi_base + PCIE_DBI2_OFFSET;
+ pci->dev = dev;
+ pci->ops = &ls_pcie_ep_ops;
+ pcie->pci = pci;
+
+ platform_set_drvdata(pdev, pcie);
+
+ ret = ls_add_pcie_ep(pcie, pdev);
+
+ return ret;
+}
+
+static struct platform_driver ls_pcie_ep_driver = {
+ .driver = {
+ .name = "layerscape-pcie-ep",
+ .of_match_table = ls_pcie_ep_of_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver_probe(ls_pcie_ep_driver, ls_pcie_ep_probe);