bcm53xx: move iProc patches that went mainline
[openwrt.git] / target / linux / bcm53xx / patches-4.1 / 146-PCI-iproc-Add-outbound-mapping-support.patch
diff --git a/target/linux/bcm53xx/patches-4.1/146-PCI-iproc-Add-outbound-mapping-support.patch b/target/linux/bcm53xx/patches-4.1/146-PCI-iproc-Add-outbound-mapping-support.patch
deleted file mode 100644 (file)
index b65d305..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-From e99a187b5c5f60fe55ca586f82ac1a3557fb166a Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Fri, 16 Oct 2015 08:18:24 -0500
-Subject: [PATCH 146/147] PCI: iproc: Add outbound mapping support
-
-Certain SoCs require the PCIe outbound mapping to be configured in
-software.  Add support for those chips.
-
-[jonmason: Use %pap format when printing size_t to avoid warnings in 32-bit
-build.]
-[arnd: Use div64_u64() instead of "%" to avoid __aeabi_uldivmod link error
-in 32-bit build.]
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Jon Mason <jonmason@broadcom.com>
-Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
----
- drivers/pci/host/pcie-iproc-platform.c |  27 ++++++++
- drivers/pci/host/pcie-iproc.c          | 115 +++++++++++++++++++++++++++++++++
- drivers/pci/host/pcie-iproc.h          |  17 +++++
- 3 files changed, 159 insertions(+)
-
---- a/drivers/pci/host/pcie-iproc-platform.c
-+++ b/drivers/pci/host/pcie-iproc-platform.c
-@@ -54,6 +54,33 @@ static int iproc_pcie_pltfm_probe(struct
-               return -ENOMEM;
-       }
-+      if (of_property_read_bool(np, "brcm,pcie-ob")) {
-+              u32 val;
-+
-+              ret = of_property_read_u32(np, "brcm,pcie-ob-axi-offset",
-+                                         &val);
-+              if (ret) {
-+                      dev_err(pcie->dev,
-+                              "missing brcm,pcie-ob-axi-offset property\n");
-+                      return ret;
-+              }
-+              pcie->ob.axi_offset = val;
-+
-+              ret = of_property_read_u32(np, "brcm,pcie-ob-window-size",
-+                                         &val);
-+              if (ret) {
-+                      dev_err(pcie->dev,
-+                              "missing brcm,pcie-ob-window-size property\n");
-+                      return ret;
-+              }
-+              pcie->ob.window_size = (resource_size_t)val * SZ_1M;
-+
-+              if (of_property_read_bool(np, "brcm,pcie-ob-oarr-size"))
-+                      pcie->ob.set_oarr_size = true;
-+
-+              pcie->need_ob_cfg = true;
-+      }
-+
-       /* PHY use is optional */
-       pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy");
-       if (IS_ERR(pcie->phy)) {
---- a/drivers/pci/host/pcie-iproc.c
-+++ b/drivers/pci/host/pcie-iproc.c
-@@ -66,6 +66,18 @@
- #define PCIE_DL_ACTIVE_SHIFT         2
- #define PCIE_DL_ACTIVE               BIT(PCIE_DL_ACTIVE_SHIFT)
-+#define OARR_VALID_SHIFT             0
-+#define OARR_VALID                   BIT(OARR_VALID_SHIFT)
-+#define OARR_SIZE_CFG_SHIFT          1
-+#define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)
-+
-+#define OARR_LO(window)              (0xd20 + (window) * 8)
-+#define OARR_HI(window)              (0xd24 + (window) * 8)
-+#define OMAP_LO(window)              (0xd40 + (window) * 8)
-+#define OMAP_HI(window)              (0xd44 + (window) * 8)
-+
-+#define MAX_NUM_OB_WINDOWS           2
-+
- static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
- {
-       struct iproc_pcie *pcie;
-@@ -212,6 +224,101 @@ static void iproc_pcie_enable(struct ipr
-       writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN);
- }
-+/**
-+ * Some iProc SoCs require the SW to configure the outbound address mapping
-+ *
-+ * Outbound address translation:
-+ *
-+ * iproc_pcie_address = axi_address - axi_offset
-+ * OARR = iproc_pcie_address
-+ * OMAP = pci_addr
-+ *
-+ * axi_addr -> iproc_pcie_address -> OARR -> OMAP -> pci_address
-+ */
-+static int iproc_pcie_setup_ob(struct iproc_pcie *pcie, u64 axi_addr,
-+                             u64 pci_addr, resource_size_t size)
-+{
-+      struct iproc_pcie_ob *ob = &pcie->ob;
-+      unsigned i;
-+      u64 max_size = (u64)ob->window_size * MAX_NUM_OB_WINDOWS;
-+      u64 remainder;
-+
-+      if (size > max_size) {
-+              dev_err(pcie->dev,
-+                      "res size 0x%pap exceeds max supported size 0x%llx\n",
-+                      &size, max_size);
-+              return -EINVAL;
-+      }
-+
-+      div64_u64_rem(size, ob->window_size, &remainder);
-+      if (remainder) {
-+              dev_err(pcie->dev,
-+                      "res size %pap needs to be multiple of window size %pap\n",
-+                      &size, &ob->window_size);
-+              return -EINVAL;
-+      }
-+
-+      if (axi_addr < ob->axi_offset) {
-+              dev_err(pcie->dev,
-+                      "axi address %pap less than offset %pap\n",
-+                      &axi_addr, &ob->axi_offset);
-+              return -EINVAL;
-+      }
-+
-+      /*
-+       * Translate the AXI address to the internal address used by the iProc
-+       * PCIe core before programming the OARR
-+       */
-+      axi_addr -= ob->axi_offset;
-+
-+      for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) {
-+              writel(lower_32_bits(axi_addr) | OARR_VALID |
-+                     (ob->set_oarr_size ? 1 : 0), pcie->base + OARR_LO(i));
-+              writel(upper_32_bits(axi_addr), pcie->base + OARR_HI(i));
-+              writel(lower_32_bits(pci_addr), pcie->base + OMAP_LO(i));
-+              writel(upper_32_bits(pci_addr), pcie->base + OMAP_HI(i));
-+
-+              size -= ob->window_size;
-+              if (size == 0)
-+                      break;
-+
-+              axi_addr += ob->window_size;
-+              pci_addr += ob->window_size;
-+      }
-+
-+      return 0;
-+}
-+
-+static int iproc_pcie_map_ranges(struct iproc_pcie *pcie,
-+                               struct list_head *resources)
-+{
-+      struct resource_entry *window;
-+      int ret;
-+
-+      resource_list_for_each_entry(window, resources) {
-+              struct resource *res = window->res;
-+              u64 res_type = resource_type(res);
-+
-+              switch (res_type) {
-+              case IORESOURCE_IO:
-+              case IORESOURCE_BUS:
-+                      break;
-+              case IORESOURCE_MEM:
-+                      ret = iproc_pcie_setup_ob(pcie, res->start,
-+                                                res->start - window->offset,
-+                                                resource_size(res));
-+                      if (ret)
-+                              return ret;
-+                      break;
-+              default:
-+                      dev_err(pcie->dev, "invalid resource %pR\n", res);
-+                      return -EINVAL;
-+              }
-+      }
-+
-+      return 0;
-+}
-+
- int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
- {
-       int ret;
-@@ -235,6 +342,14 @@ int iproc_pcie_setup(struct iproc_pcie *
-       iproc_pcie_reset(pcie);
-+      if (pcie->need_ob_cfg) {
-+              ret = iproc_pcie_map_ranges(pcie, res);
-+              if (ret) {
-+                      dev_err(pcie->dev, "map failed\n");
-+                      goto err_power_off_phy;
-+              }
-+      }
-+
- #ifdef CONFIG_ARM
-       pcie->sysdata.private_data = pcie;
-       sysdata = &pcie->sysdata;
---- a/drivers/pci/host/pcie-iproc.h
-+++ b/drivers/pci/host/pcie-iproc.h
-@@ -15,6 +15,19 @@
- #define _PCIE_IPROC_H
- /**
-+ * iProc PCIe outbound mapping
-+ * @set_oarr_size: indicates the OARR size bit needs to be set
-+ * @axi_offset: offset from the AXI address to the internal address used by
-+ * the iProc PCIe core
-+ * @window_size: outbound window size
-+ */
-+struct iproc_pcie_ob {
-+      bool set_oarr_size;
-+      resource_size_t axi_offset;
-+      resource_size_t window_size;
-+};
-+
-+/**
-  * iProc PCIe device
-  * @dev: pointer to device data structure
-  * @base: PCIe host controller I/O register base
-@@ -23,6 +36,8 @@
-  * @phy: optional PHY device that controls the Serdes
-  * @irqs: interrupt IDs
-  * @map_irq: function callback to map interrupts
-+ * @need_ob_cfg: indidates SW needs to configure the outbound mapping window
-+ * @ob: outbound mapping parameters
-  */
- struct iproc_pcie {
-       struct device *dev;
-@@ -33,6 +48,8 @@ struct iproc_pcie {
-       struct pci_bus *root_bus;
-       struct phy *phy;
-       int (*map_irq)(const struct pci_dev *, u8, u8);
-+      bool need_ob_cfg;
-+      struct iproc_pcie_ob ob;
- };
- int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res);