--- /dev/null
+From 5d92f41c48c5e3c6fa5be87e3d6fca57e2fbb127 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:15 -0700
+Subject: [PATCH 1/7] PCI: iproc: Fix code comment to match code
+
+Fix code comment in pcie-iproc.h so it matches the code.
+
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/host/pcie-iproc.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/host/pcie-iproc.h
++++ b/drivers/pci/host/pcie-iproc.h
+@@ -20,11 +20,11 @@
+ * iProc PCIe device
+ * @dev: pointer to device data structure
+ * @base: PCIe host controller I/O register base
+- * @resources: linked list of all PCI resources
+ * @sysdata: Per PCI controller data (ARM-specific)
+ * @root_bus: pointer to root bus
+ * @phy: optional PHY device that controls the Serdes
+ * @irqs: interrupt IDs
++ * @map_irq: function callback to map interrupts
+ */
+ struct iproc_pcie {
+ struct device *dev;
--- /dev/null
+From 98aac697a83db6e1d004e5d61cf6c976a0b1c35a Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:16 -0700
+Subject: [PATCH 2/7] PCI: iproc: Remove unused struct iproc_pcie.irqs[]
+
+Remove unused struct iproc_pcie member irqs[] and unused #define
+IPROC_PCIE_MAX_NUM_IRQS.
+
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/host/pcie-iproc.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.h
++++ b/drivers/pci/host/pcie-iproc.h
+@@ -14,8 +14,6 @@
+ #ifndef _PCIE_IPROC_H
+ #define _PCIE_IPROC_H
+
+-#define IPROC_PCIE_MAX_NUM_IRQS 6
+-
+ /**
+ * iProc PCIe device
+ * @dev: pointer to device data structure
+@@ -34,7 +32,6 @@ struct iproc_pcie {
+ #endif
+ struct pci_bus *root_bus;
+ struct phy *phy;
+- int irqs[IPROC_PCIE_MAX_NUM_IRQS];
+ int (*map_irq)(const struct pci_dev *, u8, u8);
+ };
+
--- /dev/null
+From bdb8a1844f3113ec08915d1e8e3fd5686fb2fb78 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:17 -0700
+Subject: [PATCH 3/7] PCI: iproc: Call pci_fixup_irqs() for ARM64 as well as
+ ARM
+
+After 459a07721c11 ("PCI: Build setup-irq.o for arm64"), we build
+setup-irq.o for arm64, so we can use pci_fixup_irqs() on both arm and
+arm64.
+
+Remove the "#ifdef CONFIG_ARM" around the call to pci_fixup_irqs().
+
+[bhelgaas: changelog]
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/host/pcie-iproc.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -237,9 +237,7 @@ int iproc_pcie_setup(struct iproc_pcie *
+
+ pci_scan_child_bus(bus);
+ pci_assign_unassigned_bus_resources(bus);
+-#ifdef CONFIG_ARM
+ pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
+-#endif
+ pci_bus_add_devices(bus);
+
+ return 0;
--- /dev/null
+From 199ff14100095d52cd1b232cc0f3b12f348b5b07 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:18 -0700
+Subject: [PATCH 4/7] PCI: iproc: Fix PCIe reset logic
+
+The current reset logic does not always properly reset the device. For
+example, in the case when the perst_b signal is already de-asserted in the
+bootloader, the current reset logic fails to trigger a proper assert ->
+de-assert reset sequence.
+
+Fix the issue by always triggering the proper reset sequence.
+
+Also explicitly select the desired reset source, i.e., perst_b, and reduce
+the wait time after the device comes out of reset from 250 ms to 100 ms,
+based on recommendation from the ASIC team.
+
+Tested-by: Vladimir Dreizin <vdreizin@broadcom.com>
+Tested-by: Darren Edamura <dedamura@broadcom.com>
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Vladimir Dreizin <vdreizin@broadcom.com>
+Reviewed-by: Trac Hoang <trhoang@broadcom.com>
+Reviewed-by: Scott Branden <sbranden@broadcom.com>
+---
+ drivers/pci/host/pcie-iproc.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -31,6 +31,8 @@
+ #include "pcie-iproc.h"
+
+ #define CLK_CONTROL_OFFSET 0x000
++#define EP_PERST_SOURCE_SELECT_SHIFT 2
++#define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
+ #define EP_MODE_SURVIVE_PERST_SHIFT 1
+ #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
+ #define RC_PCIE_RST_OUTPUT_SHIFT 0
+@@ -119,15 +121,18 @@ static void iproc_pcie_reset(struct ipro
+ u32 val;
+
+ /*
+- * Configure the PCIe controller as root complex and send a downstream
+- * reset
++ * Select perst_b signal as reset source. Put the device into reset,
++ * and then bring it out of reset
+ */
+- val = EP_MODE_SURVIVE_PERST | RC_PCIE_RST_OUTPUT;
++ val = readl(pcie->base + CLK_CONTROL_OFFSET);
++ val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
++ ~RC_PCIE_RST_OUTPUT;
+ writel(val, pcie->base + CLK_CONTROL_OFFSET);
+ udelay(250);
+- val &= ~EP_MODE_SURVIVE_PERST;
++
++ val |= RC_PCIE_RST_OUTPUT;
+ writel(val, pcie->base + CLK_CONTROL_OFFSET);
+- msleep(250);
++ msleep(100);
+ }
+
+ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
--- /dev/null
+From aaf22ab4e916afa68a2e1aed4e913b76cbd58276 Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:19 -0700
+Subject: [PATCH 5/7] PCI: iproc: Improve link detection logic
+
+Improve the link detection logic by explicitly querying the link status
+register to ensure link is active.
+
+Also force class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host
+configuration space register.
+
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Anup Patel <anup.patel@broadcom.com>
+Reviewed-by: Scott Branden <sbranden@broadcom.com>
+---
+ drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------
+ 1 file changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -60,6 +60,12 @@
+ #define SYS_RC_INTX_EN 0x330
+ #define SYS_RC_INTX_MASK 0xf
+
++#define PCIE_LINK_STATUS_OFFSET 0xf0c
++#define PCIE_PHYLINKUP_SHIFT 3
++#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
++#define PCIE_DL_ACTIVE_SHIFT 2
++#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
++
+ static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
+ {
+ struct iproc_pcie *pcie;
+@@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct ipro
+ static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
+ {
+ u8 hdr_type;
+- u32 link_ctrl;
++ u32 link_ctrl, class, val;
+ u16 pos, link_status;
+- int link_is_active = 0;
++ bool link_is_active = false;
++
++ val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
++ if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
++ dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
++ return -ENODEV;
++ }
+
+ /* make sure we are not in EP mode */
+ pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
+@@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct
+ }
+
+ /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
+- pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
+- PCI_CLASS_BRIDGE_PCI);
++#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
++#define PCI_CLASS_BRIDGE_MASK 0xffff00
++#define PCI_CLASS_BRIDGE_SHIFT 8
++ pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
++ class &= ~PCI_CLASS_BRIDGE_MASK;
++ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
++ pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
+
+ /* check link status to see if link is active */
+ pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
+ if (link_status & PCI_EXP_LNKSTA_NLW)
+- link_is_active = 1;
++ link_is_active = true;
+
+ if (!link_is_active) {
+ /* try GEN 1 link speed */
+@@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct
+ pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
+ &link_status);
+ if (link_status & PCI_EXP_LNKSTA_NLW)
+- link_is_active = 1;
++ link_is_active = true;
+ }
+ }
+
--- /dev/null
+From 8d0afa1a93be2da954c85392bbc7b2264c9d241c Mon Sep 17 00:00:00 2001
+From: Ray Jui <rjui@broadcom.com>
+Date: Tue, 15 Sep 2015 17:39:20 -0700
+Subject: [PATCH 6/7] PCI: iproc: Update PCIe device tree bindings
+
+Update the device tree bindings with added support for outbound mapping
+configurations.
+
+Signed-off-by: Ray Jui <rjui@broadcom.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ .../devicetree/bindings/pci/brcm,iproc-pcie.txt | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
++++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
+@@ -17,6 +17,21 @@ Optional properties:
+ - phys: phandle of the PCIe PHY device
+ - phy-names: must be "pcie-phy"
+
++- brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done
++by the ASIC after power on reset. In this case, SW needs to configure it
++
++If the brcm,pcie-ob property is present, the following properties become
++effective:
++
++Required:
++- brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal
++address used by the iProc PCIe core (not the PCIe address)
++- brcm,pcie-ob-window-size: The outbound address mapping window size (in MB)
++
++Optional:
++- brcm,pcie-ob-oarr-size: Some iProc SoCs need the OARR size bit to be set to
++increase the outbound window size
++
+ Example:
+ pcie0: pcie@18012000 {
+ compatible = "brcm,iproc-pcie";
+@@ -38,6 +53,11 @@ Example:
+
+ phys = <&phy 0 5>;
+ phy-names = "pcie-phy";
++
++ brcm,pcie-ob;
++ brcm,pcie-ob-oarr-size;
++ brcm,pcie-ob-axi-offset = <0x00000000>;
++ brcm,pcie-ob-window-size = <256>;
+ };
+
+ pcie1: pcie@18013000 {
--- /dev/null
+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 7/7] 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);
--- /dev/null
+From be908d21b2e9c2cab1ef568dfca4f9777611b3dd Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Fri, 16 Oct 2015 12:04:04 -0700
+Subject: [PATCH] PCI: iproc: Fix header comment "Corporation" misspelling
+
+Fix an obvious "Broadcom Corporation" typo in a header comment.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Ray Jui <rjui@broadcom.com>
+---
+ drivers/pci/host/pcie-iproc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/host/pcie-iproc.c
++++ b/drivers/pci/host/pcie-iproc.c
+@@ -1,6 +1,6 @@
+ /*
+ * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
+- * Copyright (C) 2015 Broadcom Corporatcommon ion
++ * Copyright (C) 2015 Broadcom Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+++ /dev/null
-From 5d92f41c48c5e3c6fa5be87e3d6fca57e2fbb127 Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:15 -0700
-Subject: [PATCH 140/147] PCI: iproc: Fix code comment to match code
-
-Fix code comment in pcie-iproc.h so it matches the code.
-
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
----
- drivers/pci/host/pcie-iproc.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pci/host/pcie-iproc.h
-+++ b/drivers/pci/host/pcie-iproc.h
-@@ -20,11 +20,11 @@
- * iProc PCIe device
- * @dev: pointer to device data structure
- * @base: PCIe host controller I/O register base
-- * @resources: linked list of all PCI resources
- * @sysdata: Per PCI controller data (ARM-specific)
- * @root_bus: pointer to root bus
- * @phy: optional PHY device that controls the Serdes
- * @irqs: interrupt IDs
-+ * @map_irq: function callback to map interrupts
- */
- struct iproc_pcie {
- struct device *dev;
+++ /dev/null
-From 98aac697a83db6e1d004e5d61cf6c976a0b1c35a Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:16 -0700
-Subject: [PATCH 141/147] PCI: iproc: Remove unused struct iproc_pcie.irqs[]
-
-Remove unused struct iproc_pcie member irqs[] and unused #define
-IPROC_PCIE_MAX_NUM_IRQS.
-
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
----
- drivers/pci/host/pcie-iproc.h | 3 ---
- 1 file changed, 3 deletions(-)
-
---- a/drivers/pci/host/pcie-iproc.h
-+++ b/drivers/pci/host/pcie-iproc.h
-@@ -14,8 +14,6 @@
- #ifndef _PCIE_IPROC_H
- #define _PCIE_IPROC_H
-
--#define IPROC_PCIE_MAX_NUM_IRQS 6
--
- /**
- * iProc PCIe device
- * @dev: pointer to device data structure
-@@ -34,7 +32,6 @@ struct iproc_pcie {
- #endif
- struct pci_bus *root_bus;
- struct phy *phy;
-- int irqs[IPROC_PCIE_MAX_NUM_IRQS];
- int (*map_irq)(const struct pci_dev *, u8, u8);
- };
-
+++ /dev/null
-From bdb8a1844f3113ec08915d1e8e3fd5686fb2fb78 Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:17 -0700
-Subject: [PATCH 142/147] PCI: iproc: Call pci_fixup_irqs() for ARM64 as well
- as ARM
-
-After 459a07721c11 ("PCI: Build setup-irq.o for arm64"), we build
-setup-irq.o for arm64, so we can use pci_fixup_irqs() on both arm and
-arm64.
-
-Remove the "#ifdef CONFIG_ARM" around the call to pci_fixup_irqs().
-
-[bhelgaas: changelog]
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
----
- drivers/pci/host/pcie-iproc.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/pci/host/pcie-iproc.c
-+++ b/drivers/pci/host/pcie-iproc.c
-@@ -237,9 +237,7 @@ int iproc_pcie_setup(struct iproc_pcie *
-
- pci_scan_child_bus(bus);
- pci_assign_unassigned_bus_resources(bus);
--#ifdef CONFIG_ARM
- pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
--#endif
- pci_bus_add_devices(bus);
-
- return 0;
+++ /dev/null
-From 199ff14100095d52cd1b232cc0f3b12f348b5b07 Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:18 -0700
-Subject: [PATCH 143/147] PCI: iproc: Fix PCIe reset logic
-
-The current reset logic does not always properly reset the device. For
-example, in the case when the perst_b signal is already de-asserted in the
-bootloader, the current reset logic fails to trigger a proper assert ->
-de-assert reset sequence.
-
-Fix the issue by always triggering the proper reset sequence.
-
-Also explicitly select the desired reset source, i.e., perst_b, and reduce
-the wait time after the device comes out of reset from 250 ms to 100 ms,
-based on recommendation from the ASIC team.
-
-Tested-by: Vladimir Dreizin <vdreizin@broadcom.com>
-Tested-by: Darren Edamura <dedamura@broadcom.com>
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-Reviewed-by: Vladimir Dreizin <vdreizin@broadcom.com>
-Reviewed-by: Trac Hoang <trhoang@broadcom.com>
-Reviewed-by: Scott Branden <sbranden@broadcom.com>
----
- drivers/pci/host/pcie-iproc.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/pci/host/pcie-iproc.c
-+++ b/drivers/pci/host/pcie-iproc.c
-@@ -31,6 +31,8 @@
- #include "pcie-iproc.h"
-
- #define CLK_CONTROL_OFFSET 0x000
-+#define EP_PERST_SOURCE_SELECT_SHIFT 2
-+#define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
- #define EP_MODE_SURVIVE_PERST_SHIFT 1
- #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
- #define RC_PCIE_RST_OUTPUT_SHIFT 0
-@@ -119,15 +121,18 @@ static void iproc_pcie_reset(struct ipro
- u32 val;
-
- /*
-- * Configure the PCIe controller as root complex and send a downstream
-- * reset
-+ * Select perst_b signal as reset source. Put the device into reset,
-+ * and then bring it out of reset
- */
-- val = EP_MODE_SURVIVE_PERST | RC_PCIE_RST_OUTPUT;
-+ val = readl(pcie->base + CLK_CONTROL_OFFSET);
-+ val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
-+ ~RC_PCIE_RST_OUTPUT;
- writel(val, pcie->base + CLK_CONTROL_OFFSET);
- udelay(250);
-- val &= ~EP_MODE_SURVIVE_PERST;
-+
-+ val |= RC_PCIE_RST_OUTPUT;
- writel(val, pcie->base + CLK_CONTROL_OFFSET);
-- msleep(250);
-+ msleep(100);
- }
-
- static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
+++ /dev/null
-From aaf22ab4e916afa68a2e1aed4e913b76cbd58276 Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:19 -0700
-Subject: [PATCH 144/147] PCI: iproc: Improve link detection logic
-
-Improve the link detection logic by explicitly querying the link status
-register to ensure link is active.
-
-Also force class to PCI_CLASS_BRIDGE_PCI (0x0604) through the host
-configuration space register.
-
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-Reviewed-by: Anup Patel <anup.patel@broadcom.com>
-Reviewed-by: Scott Branden <sbranden@broadcom.com>
----
- drivers/pci/host/pcie-iproc.c | 29 +++++++++++++++++++++++------
- 1 file changed, 23 insertions(+), 6 deletions(-)
-
---- a/drivers/pci/host/pcie-iproc.c
-+++ b/drivers/pci/host/pcie-iproc.c
-@@ -60,6 +60,12 @@
- #define SYS_RC_INTX_EN 0x330
- #define SYS_RC_INTX_MASK 0xf
-
-+#define PCIE_LINK_STATUS_OFFSET 0xf0c
-+#define PCIE_PHYLINKUP_SHIFT 3
-+#define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT)
-+#define PCIE_DL_ACTIVE_SHIFT 2
-+#define PCIE_DL_ACTIVE BIT(PCIE_DL_ACTIVE_SHIFT)
-+
- static inline struct iproc_pcie *iproc_data(struct pci_bus *bus)
- {
- struct iproc_pcie *pcie;
-@@ -138,9 +144,15 @@ static void iproc_pcie_reset(struct ipro
- static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)
- {
- u8 hdr_type;
-- u32 link_ctrl;
-+ u32 link_ctrl, class, val;
- u16 pos, link_status;
-- int link_is_active = 0;
-+ bool link_is_active = false;
-+
-+ val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET);
-+ if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
-+ dev_err(pcie->dev, "PHY or data link is INACTIVE!\n");
-+ return -ENODEV;
-+ }
-
- /* make sure we are not in EP mode */
- pci_bus_read_config_byte(bus, 0, PCI_HEADER_TYPE, &hdr_type);
-@@ -150,14 +162,19 @@ static int iproc_pcie_check_link(struct
- }
-
- /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
-- pci_bus_write_config_word(bus, 0, PCI_CLASS_DEVICE,
-- PCI_CLASS_BRIDGE_PCI);
-+#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c
-+#define PCI_CLASS_BRIDGE_MASK 0xffff00
-+#define PCI_CLASS_BRIDGE_SHIFT 8
-+ pci_bus_read_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, &class);
-+ class &= ~PCI_CLASS_BRIDGE_MASK;
-+ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
-+ pci_bus_write_config_dword(bus, 0, PCI_BRIDGE_CTRL_REG_OFFSET, class);
-
- /* check link status to see if link is active */
- pos = pci_bus_find_capability(bus, 0, PCI_CAP_ID_EXP);
- pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA, &link_status);
- if (link_status & PCI_EXP_LNKSTA_NLW)
-- link_is_active = 1;
-+ link_is_active = true;
-
- if (!link_is_active) {
- /* try GEN 1 link speed */
-@@ -181,7 +198,7 @@ static int iproc_pcie_check_link(struct
- pci_bus_read_config_word(bus, 0, pos + PCI_EXP_LNKSTA,
- &link_status);
- if (link_status & PCI_EXP_LNKSTA_NLW)
-- link_is_active = 1;
-+ link_is_active = true;
- }
- }
-
+++ /dev/null
-From 8d0afa1a93be2da954c85392bbc7b2264c9d241c Mon Sep 17 00:00:00 2001
-From: Ray Jui <rjui@broadcom.com>
-Date: Tue, 15 Sep 2015 17:39:20 -0700
-Subject: [PATCH 145/147] PCI: iproc: Update PCIe device tree bindings
-
-Update the device tree bindings with added support for outbound mapping
-configurations.
-
-Signed-off-by: Ray Jui <rjui@broadcom.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
----
- .../devicetree/bindings/pci/brcm,iproc-pcie.txt | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
---- a/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
-+++ b/Documentation/devicetree/bindings/pci/brcm,iproc-pcie.txt
-@@ -17,6 +17,21 @@ Optional properties:
- - phys: phandle of the PCIe PHY device
- - phy-names: must be "pcie-phy"
-
-+- brcm,pcie-ob: Some iProc SoCs do not have the outbound address mapping done
-+by the ASIC after power on reset. In this case, SW needs to configure it
-+
-+If the brcm,pcie-ob property is present, the following properties become
-+effective:
-+
-+Required:
-+- brcm,pcie-ob-axi-offset: The offset from the AXI address to the internal
-+address used by the iProc PCIe core (not the PCIe address)
-+- brcm,pcie-ob-window-size: The outbound address mapping window size (in MB)
-+
-+Optional:
-+- brcm,pcie-ob-oarr-size: Some iProc SoCs need the OARR size bit to be set to
-+increase the outbound window size
-+
- Example:
- pcie0: pcie@18012000 {
- compatible = "brcm,iproc-pcie";
-@@ -38,6 +53,11 @@ Example:
-
- phys = <&phy 0 5>;
- phy-names = "pcie-phy";
-+
-+ brcm,pcie-ob;
-+ brcm,pcie-ob-oarr-size;
-+ brcm,pcie-ob-axi-offset = <0x00000000>;
-+ brcm,pcie-ob-window-size = <256>;
- };
-
- pcie1: pcie@18013000 {
+++ /dev/null
-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);
+++ /dev/null
-From be908d21b2e9c2cab1ef568dfca4f9777611b3dd Mon Sep 17 00:00:00 2001
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Fri, 16 Oct 2015 12:04:04 -0700
-Subject: [PATCH 147/147] PCI: iproc: Fix header comment "Corporation"
- misspelling
-
-Fix an obvious "Broadcom Corporation" typo in a header comment.
-
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-Acked-by: Ray Jui <rjui@broadcom.com>
----
- drivers/pci/host/pcie-iproc.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/pci/host/pcie-iproc.c
-+++ b/drivers/pci/host/pcie-iproc.c
-@@ -1,6 +1,6 @@
- /*
- * Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
-- * Copyright (C) 2015 Broadcom Corporatcommon ion
-+ * Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as