linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
@ 2015-07-01  9:43 Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource Zhou Wang
                   ` (4 more replies)
  0 siblings, 5 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds PCIe host support for Hisilicon Soc Hip05. The PCIe hosts
use PCIe IP core from Synopsys, So this driver is base on designware PCIe driver.

Hip05 is an ARMv8 architecture Soc. It should be able to use ARM64 PCIe API in
designeware PCIe driver. So this patch also adds ARM64 support for designware
pcie.

I tested this patchset on D02 board of Hisilicon with Intel 82599 networking
card. It works well.

This patchset is based on v4.1-rc8.

Change from v2:
- move struct pci_dev *dev and struct pci_sys_data *sys in
  pcibios_align_resource in 1/5.
- Add Gabriele's codes in 2/5 which delete unnecessary information parse and
  use of_pci_get_host_bridge_resources for both ARM32 and ARM64.
- Add maintainer patch 5/5.

Change from RFC v1:
- Add 1/4 patch by Arnd which removes align_resource callback in ARM
  pcibios_align_resource.
- Change head file in pcie-designware from asm/hardirq.h to linux/hardirq.h.
- Set pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx.
- Remove unnecessary parentheses of some macros in pcie-hisi.
- Use macro to replace some magic values.
- Merge two loops together and add some comments about it in context_config
  function in pcie-hisi.
- Modify some value of items in pcie node example in binding document. 

Change from RFC:
- delete dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
  merge related operations into dw_pcie_host_init.

Link of v2:
- http://www.spinics.net/lists/linux-pci/msg41844.html
Link of RFC v1:
- http://www.spinics.net/lists/linux-pci/msg41305.html
Link of RFC:
- http://www.spinics.net/lists/linux-pci/msg40434.html

Zhou Wang (5):
  ARM/PCI: remove align_resource callback in pcibios_align_resource
  PCI: designware: Add ARM64 support
  PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
  Documentation: DT: Add Hisilicon PCIe host binding
  MAINTAINERS: Add pcie-hisi maintainer

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/kernel/bios32.c                           |   6 -
 drivers/pci/host/Kconfig                           |   5 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |   1 +
 drivers/pci/host/pci-exynos.c                      |   2 +-
 drivers/pci/host/pci-imx6.c                        |   2 +-
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pci-keystone.c                    |   2 +-
 drivers/pci/host/pci-layerscape.c                  |   2 +-
 drivers/pci/host/pci-mvebu.c                       |  47 ++--
 drivers/pci/host/pcie-designware.c                 | 242 ++++++++-----------
 drivers/pci/host/pcie-designware.h                 |  10 +-
 drivers/pci/host/pcie-hisi.c                       | 258 +++++++++++++++++++++
 drivers/pci/host/pcie-spear13xx.c                  |   2 +-
 drivers/pci/setup-res.c                            |  27 ++-
 include/linux/pci.h                                |   3 +
 18 files changed, 482 insertions(+), 183 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
 create mode 100644 drivers/pci/host/pcie-hisi.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
@ 2015-07-01  9:43 ` Zhou Wang
  2015-07-02 17:50   ` Liviu Dudau
  2015-07-01  9:43 ` [PATCH v3 2/5] PCI: designware: Add ARM64 support Zhou Wang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch had added by Arnd Bergmann during last reviewing of v1 patchset[1].

PCI core codes call pcibios_align_resource(). In ARM specific one, it will
dereference pci_sys_data and call sys->align_resource. If we try to unify ARM
and ARM64 PCIe API in pcie-designware. it will bring kernel crash when run into
this dereferencing.

However, in ARM there is only pci-mvebu which implements align_resource. So
add align_resource call back in pci_host_bridge structure and override
pcibios_align_resource with it.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>

[1] http://www.spinics.net/lists/linux-pci/msg41671.html
---
 arch/arm/kernel/bios32.c     |  6 ------
 drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++----------------
 drivers/pci/setup-res.c      | 27 ++++++++++++++++++++-----
 include/linux/pci.h          |  3 +++
 4 files changed, 55 insertions(+), 28 deletions(-)

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..b01189f 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -588,8 +587,6 @@ char * __init pcibios_setup(char *str)
 resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
-	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,9 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
-
 	return start;
 }
 
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 1ab8635..155d05f 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -22,6 +22,8 @@
 #include <linux/of_pci.h>
 #include <linux/of_platform.h>
 
+#include "../pci.h" /* HACK to see pci_find_host_bridge */
+
 /*
  * PCIe unit register offsets.
  */
@@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
 	return 1;
 }
 
-static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+static resource_size_t mvebu_pcie_align_resource(void *data,
+						 const struct resource *res,
+						 resource_size_t size,
+						 resource_size_t align)
 {
-	struct mvebu_pcie *pcie = sys_to_pcie(sys);
-	struct pci_bus *bus;
+	struct pci_dev *dev = data;
 
-	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
-				  &mvebu_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
+	resource_size_t start = res->start;
 
-	pci_scan_child_bus(bus);
+	if (res->flags & IORESOURCE_IO && start & 0x300)
+		start = (start + 0x3ff) & ~0x3ff;
 
-	return bus;
-}
+	start = (start + align - 1) & ~(align - 1);
 
-static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
-						 const struct resource *res,
-						 resource_size_t start,
-						 resource_size_t size,
-						 resource_size_t align)
-{
 	if (dev->bus->number != 0)
 		return start;
 
@@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
 		return start;
 }
 
+static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+	struct mvebu_pcie *pcie = sys_to_pcie(sys);
+	struct pci_host_bridge *phb;
+	struct pci_bus *bus;
+
+	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
+				  &mvebu_pcie_ops, sys, &sys->resources);
+	if (!bus)
+		return NULL;
+
+	phb = pci_find_host_bridge(bus);
+	phb->align_resource = mvebu_pcie_align_resource;
+
+	pci_scan_child_bus(bus);
+
+	return bus;
+}
+
 static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
 {
 	struct hw_pci hw;
@@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
 	hw.scan           = mvebu_pcie_scan_bus;
 	hw.map_irq        = of_irq_parse_and_map_pci;
 	hw.ops            = &mvebu_pcie_ops;
-	hw.align_resource = mvebu_pcie_align_resource;
 
 	pci_common_init(&hw);
 }
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 232f925..73abca7 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 }
 
 static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
-		int resno, resource_size_t size, resource_size_t align)
+		int resno, resource_size_t size, resource_size_t align,
+		resource_size_t (*alignf)(void *,
+					  const struct resource *,
+					  resource_size_t,
+					  resource_size_t))
 {
 	struct resource *res = dev->resource + resno;
 	resource_size_t min;
@@ -217,7 +221,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	 */
 	ret = pci_bus_alloc_resource(bus, res, size, align, min,
 				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
-				     pcibios_align_resource, dev);
+				     alignf, dev);
 	if (ret == 0)
 		return 0;
 
@@ -229,7 +233,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
 		ret = pci_bus_alloc_resource(bus, res, size, align, min,
 					     IORESOURCE_PREFETCH,
-					     pcibios_align_resource, dev);
+					     alignf, dev);
 		if (ret == 0)
 			return 0;
 	}
@@ -242,7 +246,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 	 */
 	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
 		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
-					     pcibios_align_resource, dev);
+					     alignf, dev);
 
 	return ret;
 }
@@ -251,10 +255,23 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
 				resource_size_t size, resource_size_t min_align)
 {
 	struct pci_bus *bus;
+	struct pci_host_bridge *phb;
+	resource_size_t (*alignf)(void *,
+				  const struct resource *,
+				  resource_size_t,
+				  resource_size_t);
 	int ret;
 
 	bus = dev->bus;
-	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
+	phb = pci_find_host_bridge(bus);
+
+	if (phb->align_resource)
+		alignf = phb->align_resource;
+	else
+		alignf = pcibios_align_resource;
+
+	while ((ret = __pci_assign_resource(bus, dev, resno, size,
+					    min_align, alignf))) {
 		if (!bus->parent || !bus->self->transparent)
 			break;
 		bus = bus->parent;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 353db8d..39e48fc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -404,6 +404,9 @@ struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
 	struct list_head windows;	/* resource_entry */
+	resource_size_t (*align_resource)(void *data,
+			 const struct resource *res,
+			 resource_size_t size, resource_size_t align);
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
 	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource Zhou Wang
@ 2015-07-01  9:43 ` Zhou Wang
  2015-07-01 13:29   ` Gabriele Paoloni
  2015-07-01  9:43 ` [PATCH v3 3/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init. Also set pp->root_bus_nr = 0 in
each PCIe host driver which is based on pcie-designware. This patch also try
to use of_pci_get_host_bridge_resources for ARM32 and ARM64 according to the
suggestion for Gabriele[1]

I tested this patch on D02 board of Hisilicon. It works well.
I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Tested-by: James Morse <james.morse@arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
---
 drivers/pci/host/pci-dra7xx.c      |   1 +
 drivers/pci/host/pci-exynos.c      |   2 +-
 drivers/pci/host/pci-imx6.c        |   2 +-
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pci-keystone.c    |   2 +-
 drivers/pci/host/pci-layerscape.c  |   2 +-
 drivers/pci/host/pcie-designware.c | 242 +++++++++++++++----------------------
 drivers/pci/host/pcie-designware.h |  10 +-
 drivers/pci/host/pcie-spear13xx.c  |   2 +-
 9 files changed, 110 insertions(+), 155 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 2d57e19..5c8b6ab 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 
 	pp = &dra7xx->pp;
 	pp->dev = dev;
+	pp->root_bus_nr = 0;
 	pp->ops = &dra7xx_pcie_host_ops;
 
 	pp->irq = platform_get_irq(pdev, 1);
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index c139237..4b6db6c 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &exynos_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index fdb9536..c4a80c5 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &imx6_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 75333b0..df91f5e 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
 			return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &keystone_pcie_host_ops;
 	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
 	if (ret) {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index 4a6e62f..5c7a9c4 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
 	pp = &pcie->pp;
 	pp->dev = pcie->dev;
 	pp->dbi_base = pcie->dbi;
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &ls_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 2e9f84f..844febee 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -67,16 +68,7 @@
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
-
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -342,16 +334,24 @@ static const struct irq_domain_ops msi_domain_ops = {
 	.map = dw_pcie_msi_map,
 };
 
-int dw_pcie_host_init(struct pcie_port *pp)
+int __init dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
+	LIST_HEAD(res);
 	u32 val, na, ns;
 	const __be32 *addrp;
 	int i, index, ret;
+	int rlen;
+	struct resource_entry *win;
+	const __be32 *parser_range_end = of_get_property(np, "ranges", &rlen);
+
+	if (parser_range_end == NULL)
+			return -ENOENT;
+	parser_range_end += rlen/sizeof(__be32);
+
 
 	/* Find the address cell size and the number of cells in order to get
 	 * the untranslated address.
@@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = of_read_number(parser.range -
-							 parser.np + na, ns);
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = of_read_number(parser.range -
-							  parser.np + na, ns);
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			/* magic 5 below comes from magic na and ns in
+			 * of_pci_range_parser_init()                 */
+			pp->io_mod_base = of_read_number(parser_range_end -
+					of_n_addr_cells(np) - 5 + na, ns);
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+				ret, pp->io);
+			continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			pp->mem_mod_base = of_read_number(parser_range_end -
+					of_n_addr_cells(np) - 5 + na, ns);
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
 
 			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = of_read_number(parser.range -
-							   parser.np + na, ns);
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+			pp->cfg0_mod_base = of_read_number(parser_range_end -
+					of_n_addr_cells(np) - 5 + na, ns);
+			pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	if (pp->ops->host_init)
 		pp->ops->host_init(pp);
 
-	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
+	if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)
+			!= PCIBIOS_SUCCESSFUL)
+		return -EINVAL;
 
 	/* program correct class for RC */
-	dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI);
+	if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI)
+			!= PCIBIOS_SUCCESSFUL)
+		return -EINVAL;
+
+	if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val)
+			!= PCIBIOS_SUCCESSFUL)
+		return -EINVAL;
 
-	dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
 	val |= PORT_LOGIC_SPEED_CHANGE;
-	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
-	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val)
+			!= PCIBIOS_SUCCESSFUL)
+		return -EINVAL;
+
+	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+			      pp, &res);
+	if (!bus)
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
+
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_create_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	pci_scan_child_bus(bus);
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..ab78710 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -34,7 +34,7 @@ struct pcie_port {
 	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
+	resource_size_t			io_base;
 	u64			io_mod_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
@@ -42,10 +42,10 @@ struct pcie_port {
 	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index 020d788..e78ddf8 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
 		return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &spear13xx_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 3/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05
  2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 2/5] PCI: designware: Add ARM64 support Zhou Wang
@ 2015-07-01  9:43 ` Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 4/5] Documentation: DT: Add Hisilicon PCIe host binding Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 5/5] MAINTAINERS: Add pcie-hisi maintainer Zhou Wang
  4 siblings, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds PCIe host support for Hisilicon Soc Hip05.

Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
---
 drivers/pci/host/Kconfig     |   5 +
 drivers/pci/host/Makefile    |   1 +
 drivers/pci/host/pcie-hisi.c | 258 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+)
 create mode 100644 drivers/pci/host/pcie-hisi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 1dfb567..486d822 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -125,4 +125,9 @@ config PCIE_IPROC_PLATFORM
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the generic platform bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "Hisilicon Soc HIP05 PCIe controller"
+	select PCIE_DW
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index f733b4e..562142e 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
 obj-$(CONFIG_PCI_VERSATILE) += pci-versatile.o
 obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o
 obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o
+obj-$(CONFIG_PCI_HISI) += pcie-hisi.o
diff --git a/drivers/pci/host/pcie-hisi.c b/drivers/pci/host/pcie-hisi.c
new file mode 100644
index 0000000..8328add
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,258 @@
+/*
+ * PCIe host controller driver for Hisilicon Hip05 SoCs
+ *
+ * Copyright (C) 2015 Hisilicon Co., Ltd. http://www.hisilicon.com
+ *
+ * Author: Zhou Wang <wangzhou1@hisilicon.com>
+ *         Dacai Zhu <zhudacai@hisilicon.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+
+#include "pcie-designware.h"
+
+#define PCIE_SUBCTRL_MODE_REG                           0x2800
+#define PCIE_SUBCTRL_SYS_STATE4_REG                     0x6818
+#define PCIE_SLV_DBI_MODE                               0x0
+#define PCIE_SLV_SYSCTRL_MODE                           0x1
+#define PCIE_SLV_CONTENT_MODE                           0x2
+#define PCIE_SLV_MSI_ASID                               0x10
+#define PCIE_LTSSM_LINKUP_STATE                         0x11
+#define PCIE_LTSSM_STATE_MASK                           0x3F
+#define PCIE_MSI_ASID_ENABLE                            (0x1 << 12)
+#define PCIE_MSI_ASID_VALUE                             (0x1 << 16)
+#define PCIE_MSI_TRANS_ENABLE                           (0x1 << 12)
+#define PCIE_MSI_TRANS_REG                              0x1c8
+#define PCIE_MSI_LOW_ADDRESS                            0x1b4
+#define PCIE_MSI_HIGH_ADDRESS                           0x1c4
+#define PCIE_MSI_ADDRESS_VAL                            0xb7010040
+
+#define to_hisi_pcie(x)	container_of(x, struct hisi_pcie, pp)
+
+struct hisi_pcie {
+	void __iomem *subctrl_base;
+	void __iomem *reg_base;
+	struct msi_controller *msi;
+	u32 port_id;
+	struct pcie_port pp;
+};
+
+static inline void hisi_pcie_subctrl_writel(struct hisi_pcie *pcie,
+					    u32 val, u32 reg)
+{
+	writel(val, pcie->subctrl_base + reg);
+}
+
+static inline u32 hisi_pcie_subctrl_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->subctrl_base + reg);
+}
+
+static inline void hisi_pcie_apb_writel(struct hisi_pcie *pcie,
+					u32 val, u32 reg)
+{
+	writel(val, pcie->reg_base + reg);
+}
+
+static inline u32 hisi_pcie_apb_readl(struct hisi_pcie *pcie, u32 reg)
+{
+	return readl(pcie->reg_base + reg);
+}
+
+/*
+ * Change mode to indicate the same reg_base to base of PCIe host configure
+ * registers, base of RC configure space or base of vmid/asid context table
+ */
+static void hisi_pcie_change_apb_mode(struct hisi_pcie *pcie, u32 mode)
+{
+	u32 val;
+	u32 bit_mask;
+	u32 bit_shift;
+	u32 port_id = pcie->port_id;
+	u32 reg = PCIE_SUBCTRL_MODE_REG + 0x100 * port_id;
+
+	if ((port_id == 1) || (port_id == 2)) {
+		bit_mask = 0xc;
+		bit_shift = 0x2;
+	} else {
+		bit_mask = 0x6;
+		bit_shift = 0x1;
+	}
+
+	val = hisi_pcie_subctrl_readl(pcie, reg);
+	val = (val & (~bit_mask)) | (mode << bit_shift);
+	hisi_pcie_subctrl_writel(pcie, val, reg);
+}
+
+/* Configure vmid/asid table in PCIe host */
+static void hisi_pcie_config_context(struct hisi_pcie *pcie)
+{
+	int i;
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_CONTENT_MODE);
+
+	/*
+	 * init vmid and asid tables for all PCIes device as 0
+	 * vmid table: 0 ~ 0x3ff, asid table: 0x400 ~ 0x7ff
+	 */
+	for (i = 0; i < 0x800; i++)
+		hisi_pcie_apb_writel(pcie, 0x0, i * 4);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_SYSCTRL_MODE);
+
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ADDRESS_VAL, PCIE_MSI_LOW_ADDRESS);
+	hisi_pcie_apb_writel(pcie, 0x0, PCIE_MSI_HIGH_ADDRESS);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_ASID_ENABLE | PCIE_MSI_ASID_VALUE,
+			     PCIE_SLV_MSI_ASID);
+	hisi_pcie_apb_writel(pcie, PCIE_MSI_TRANS_ENABLE, PCIE_MSI_TRANS_REG);
+
+	hisi_pcie_change_apb_mode(pcie, PCIE_SLV_DBI_MODE);
+}
+
+static int hisi_pcie_link_up(struct pcie_port *pp)
+{
+	u32 val;
+
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	val = hisi_pcie_subctrl_readl(hisi_pcie, PCIE_SUBCTRL_SYS_STATE4_REG +
+				      0x100 * hisi_pcie->port_id);
+
+	return ((val & PCIE_LTSSM_STATE_MASK) == PCIE_LTSSM_LINKUP_STATE);
+}
+
+static
+int hisi_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
+{
+	struct device_node *msi_node;
+	struct irq_domain *irq_domain;
+	struct device_node *np = pp->dev->of_node;
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		pr_err("failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		pr_err("failed to find irq domain\n");
+		return -ENODEV;
+	}
+
+	pp->irq_domain = irq_domain;
+
+	return 0;
+}
+
+static struct pcie_host_ops hisi_pcie_host_ops = {
+	.link_up = hisi_pcie_link_up,
+	.msi_host_init = hisi_pcie_msi_host_init,
+};
+
+static int __init hisi_add_pcie_port(struct pcie_port *pp,
+				     struct platform_device *pdev)
+{
+	int ret;
+	u32 port_id;
+	struct resource busn;
+
+	struct hisi_pcie *hisi_pcie = to_hisi_pcie(pp);
+
+	if (of_property_read_u32(pdev->dev.of_node, "port-id", &port_id)) {
+		dev_err(&pdev->dev, "failed to read port-id\n");
+		return -EINVAL;
+	}
+	if (port_id > 3) {
+		dev_err(&pdev->dev, "Invalid port-id\n");
+		return -EINVAL;
+	}
+
+	hisi_pcie->port_id = port_id;
+
+	if (of_pci_parse_bus_range(pdev->dev.of_node, &busn)) {
+		dev_err(&pdev->dev, "failed to parse bus-ranges\n");
+		return -EINVAL;
+	}
+
+	pp->root_bus_nr = busn.start;
+	pp->ops = &hisi_pcie_host_ops;
+
+	hisi_pcie_config_context(hisi_pcie);
+
+	ret = dw_pcie_host_init(pp);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize host\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __init hisi_pcie_probe(struct platform_device *pdev)
+{
+	struct hisi_pcie *hisi_pcie;
+	struct pcie_port *pp;
+	struct resource *reg;
+	struct resource *subctrl;
+	int ret;
+
+	hisi_pcie = devm_kzalloc(&pdev->dev, sizeof(*hisi_pcie), GFP_KERNEL);
+	if (!hisi_pcie)
+		return -ENOMEM;
+
+	pp = &hisi_pcie->pp;
+	pp->dev = &pdev->dev;
+
+	subctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "subctrl");
+	hisi_pcie->subctrl_base = devm_ioremap_nocache(&pdev->dev,
+					subctrl->start, resource_size(subctrl));
+	if (IS_ERR(hisi_pcie->subctrl_base)) {
+		dev_err(pp->dev, "cannot get subctrl base\n");
+		return PTR_ERR(hisi_pcie->subctrl_base);
+	}
+
+	reg = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rc_dbi");
+	hisi_pcie->reg_base = devm_ioremap_resource(&pdev->dev, reg);
+	if (IS_ERR(hisi_pcie->reg_base)) {
+		dev_err(pp->dev, "cannot get reg base\n");
+		return PTR_ERR(hisi_pcie->reg_base);
+	}
+
+	hisi_pcie->pp.dbi_base = hisi_pcie->reg_base;
+
+	ret = hisi_add_pcie_port(pp, pdev);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return ret;
+}
+
+static const struct of_device_id hisi_pcie_of_match[] = {
+	{.compatible = "hisilicon,hip05-pcie",},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, hisi_pcie_of_match);
+
+static struct platform_driver hisi_pcie_driver = {
+	.probe  = hisi_pcie_probe,
+	.driver = {
+		   .name = "hisi-pcie",
+		   .owner = THIS_MODULE,
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 4/5] Documentation: DT: Add Hisilicon PCIe host binding
  2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
                   ` (2 preceding siblings ...)
  2015-07-01  9:43 ` [PATCH v3 3/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
@ 2015-07-01  9:43 ` Zhou Wang
  2015-07-01  9:43 ` [PATCH v3 5/5] MAINTAINERS: Add pcie-hisi maintainer Zhou Wang
  4 siblings, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds related DTS binding document for Hisilicon PCIe host driver.

Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
---
 .../devicetree/bindings/pci/hisilicon-pcie.txt     | 46 ++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pci/hisilicon-pcie.txt

diff --git a/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
new file mode 100644
index 0000000..6c9b827
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
@@ -0,0 +1,46 @@
+Hisilicon PCIe host bridge DT description
+
+Hisilicon PCIe host controller is based on Designware PCI core.
+It shares common functions with PCIe Designware core driver and inherits
+common properties defined in
+Documentation/devicetree/bindings/pci/designware-pci.txt.
+
+Additional properties are described here:
+
+Required properties:
+- compatible: Should contain "hisilicon,hip05-pcie".
+- reg: Should contain rc_dbi, subctrl, config registers location and length.
+- reg-names: Must include the following entries:
+  "rc_dbi": controller configuration registers;
+  "subctrl": whole PCIe hosts configuration registers;
+  "config": PCIe configuration space registers.
+- msi-parent: Should be its_pcie which is an its receiving MSI interrupts.
+- port-id: Should be 0, 1, 2 or 3.
+
+Optional properties:
+- status: Either "ok" or "disabled".
+- dma-coherent: Present if dma operations are coherent.
+
+Example:
+	pcie at 0xb0080000 {
+		compatible = "hisilicon,hip05-pcie", "snps,dw-pcie";
+		reg = <0 0xb0080000 0 0x10000>, <0 0xb0000000 0 0x10000>,
+		      <0x220 0x00000000 0 0x2000>;
+		reg-names = "rc_dbi", "subctrl", "config";
+		bus-range = <0  15>;
+		msi-parent = <&its_pcie>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		device_type = "pci";
+		dma-coherent;
+		ranges = <0x82000000 0 0x00000000 0x220 0x00000000 0 0x10000000>;
+		num-lanes = <8>;
+		port-id = <1>;
+		#interrupts-cells = <1>;
+		interrupts-map-mask = <0xf800 0 0 7>;
+		interrupts-map = <0x0 0 0 1 &mbigen_pcie 1 10
+				  0x0 0 0 2 &mbigen_pcie 2 11
+				  0x0 0 0 3 &mbigen_pcie 3 12
+				  0x0 0 0 4 &mbigen_pcie 4 13>;
+		status = "ok";
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 5/5] MAINTAINERS: Add pcie-hisi maintainer
  2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
                   ` (3 preceding siblings ...)
  2015-07-01  9:43 ` [PATCH v3 4/5] Documentation: DT: Add Hisilicon PCIe host binding Zhou Wang
@ 2015-07-01  9:43 ` Zhou Wang
  4 siblings, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-01  9:43 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..3f083d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7594,6 +7594,13 @@ L:	linux-pci at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/host/*spear*
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1@hisilicon.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/pci/hisilicon-pcie.txt
+F:	drivers/pci/host/pcie-hisi.c
+
 PCMCIA SUBSYSTEM
 P:	Linux PCMCIA Team
 L:	linux-pcmcia at lists.infradead.org
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01  9:43 ` [PATCH v3 2/5] PCI: designware: Add ARM64 support Zhou Wang
@ 2015-07-01 13:29   ` Gabriele Paoloni
  2015-07-01 14:26     ` James Morse
  2015-07-02  1:16     ` Zhou Wang
  0 siblings, 2 replies; 22+ messages in thread
From: Gabriele Paoloni @ 2015-07-01 13:29 UTC (permalink / raw)
  To: linux-arm-kernel

Adding to the recipients list the authors of the drivers that depend on Synopsys Designware and that are not included

Respectively:
pci-dra7xx Kishon Vijay Abraham I <kishon@ti.com>
pci-imx6 Sean Cross <xobs@kosagi.com>
pci-keystone Murali Karicheri <m-karicheri2@ti.com>
pci-layerscape Minghuan Lian <Minghuan.Lian@freescale.com>

Driver Authors already included:
pci-exynos Jingoo Han <jg1.han@samsung.com>
pcie-spear13xx Pratyush Anand <pratyush.anand@st.com>

Cheers

Gab

> -----Original Message-----
> From: Wangzhou (B)
> Sent: Wednesday, July 01, 2015 10:44 AM
> To: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; Gabriele
> Paoloni; James Morse; Liviu Dudau
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; Liguozhu (Kenneth); Wangzhou (B)
> Subject: [PATCH v3 2/5] PCI: designware: Add ARM64 support
> 
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> hw_pci,
> move related operations to dw_pcie_host_init. Also set pp->root_bus_nr
> = 0 in
> each PCIe host driver which is based on pcie-designware. This patch
> also try
> to use of_pci_get_host_bridge_resources for ARM32 and ARM64 according
> to the
> suggestion for Gabriele[1]
> 
> I tested this patch on D02 board of Hisilicon. It works well.
> I have compiled the driver with multi_v7_defconfig. However, I don't
> have
> ARM32 PCIe related board to do test. It will be appreciated if someone
> could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> Tested-by: James Morse <james.morse@arm.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |   1 +
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 242 +++++++++++++++--------------
> --------
>  drivers/pci/host/pcie-designware.h |  10 +-
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 110 insertions(+), 155 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> dra7xx.c
> index 2d57e19..5c8b6ab 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct
> dra7xx_pcie *dra7xx,
> 
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
> 
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
> exynos.c
> index c139237..4b6db6c 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct
> pcie_port *pp,
>  		}
>  	}
> 
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
> 
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index fdb9536..c4a80c5 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct
> pcie_port *pp,
>  		}
>  	}
> 
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
> 
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-
> keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem
> *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
> 
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
> keystone.c
> index 75333b0..df91f5e 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct
> keystone_pcie *ks_pcie,
>  			return ret;
>  	}
> 
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-
> layerscape.c
> index 4a6e62f..5c7a9c4 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
> 
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c
> b/drivers/pci/host/pcie-designware.c
> index 2e9f84f..844febee 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
> 
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -67,16 +68,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
> 
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
> 
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
> *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
> 
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller
> *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
> 
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct
> msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
> 
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -342,16 +334,24 @@ static const struct irq_domain_ops msi_domain_ops
> = {
>  	.map = dw_pcie_msi_map,
>  };
> 
> -int dw_pcie_host_init(struct pcie_port *pp)
> +int __init dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> +	LIST_HEAD(res);
>  	u32 val, na, ns;
>  	const __be32 *addrp;
>  	int i, index, ret;
> +	int rlen;
> +	struct resource_entry *win;
> +	const __be32 *parser_range_end = of_get_property(np, "ranges",
> &rlen);
> +
> +	if (parser_range_end == NULL)
> +			return -ENOENT;
> +	parser_range_end += rlen/sizeof(__be32);
> +
> 
>  	/* Find the address cell size and the number of cells in order to
> get
>  	 * the untranslated address.
> @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
> 
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> >io_base);
> +	if (ret)
> +		return ret;
> 
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = of_read_number(parser.range -
> -							 parser.np + na, ns);
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = of_read_number(parser.range -
> -							  parser.np + na, ns);
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			/* magic 5 below comes from magic na and ns in
> +			 * of_pci_range_parser_init()                 */
> +			pp->io_mod_base = of_read_number(parser_range_end -
> +					of_n_addr_cells(np) - 5 + na, ns);
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map
> resource %pR\n",
> +				ret, pp->io);
> +			continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			pp->mem_mod_base = of_read_number(parser_range_end -
> +					of_n_addr_cells(np) - 5 + na, ns);
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> 
>  			/* Find the untranslated configuration space address
> */
> -			pp->cfg0_mod_base = of_read_number(parser.range -
> -							   parser.np + na, ns);
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +			pp->cfg0_mod_base = of_read_number(parser_range_end -
> +					of_n_addr_cells(np) - 5 + na, ns);
> +			pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
> 
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
> 
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
> 
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	if (pp->ops->host_init)
>  		pp->ops->host_init(pp);
> 
> -	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> +	if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)
> +			!= PCIBIOS_SUCCESSFUL)
> +		return -EINVAL;
> 
>  	/* program correct class for RC */
> -	dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
> PCI_CLASS_BRIDGE_PCI);
> +	if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
> PCI_CLASS_BRIDGE_PCI)
> +			!= PCIBIOS_SUCCESSFUL)
> +		return -EINVAL;
> +
> +	if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,
> &val)
> +			!= PCIBIOS_SUCCESSFUL)
> +		return -EINVAL;
> 
> -	dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
>  	val |= PORT_LOGIC_SPEED_CHANGE;
> -	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> 
> -#ifdef CONFIG_PCI_MSI
> -	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val)
> +			!= PCIBIOS_SUCCESSFUL)
> +		return -EINVAL;
> +
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +			      pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> domain);
> +#else
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
> 
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> 
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
> +
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
> 
>  	return 0;
>  }
> @@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port
> *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
> 
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32
> devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
> 
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
> 
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> >mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
> *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_create_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	pci_scan_child_bus(bus);
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h
> b/drivers/pci/host/pcie-designware.h
> index d0bbd27..ab78710 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -34,7 +34,7 @@ struct pcie_port {
>  	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> +	resource_size_t			io_base;
>  	u64			io_mod_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
> @@ -42,10 +42,10 @@ struct pcie_port {
>  	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-
> spear13xx.c
> index 020d788..e78ddf8 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port
> *pp,
>  		return ret;
>  	}
> 
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
> 
>  	ret = dw_pcie_host_init(pp);
> --
> 1.9.1

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 13:29   ` Gabriele Paoloni
@ 2015-07-01 14:26     ` James Morse
  2015-07-01 16:47       ` Gabriele Paoloni
  2015-07-07  3:44       ` Zhou Wang
  2015-07-02  1:16     ` Zhou Wang
  1 sibling, 2 replies; 22+ messages in thread
From: James Morse @ 2015-07-01 14:26 UTC (permalink / raw)
  To: linux-arm-kernel

Zhou Wang wrote:
> I tested this patch on D02 board of Hisilicon. It works well.
> I have compiled the driver with multi_v7_defconfig. However, I don't
> have
> ARM32 PCIe related board to do test. It will be appreciated if someone
> could
> help to test it.
>
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> Tested-by: James Morse <james.morse@arm.com>

Tests on this new series, using the same i.MX 6Quad board, are not working.

The network card is no longer detected, and I get a lockup when removing
the root bridge and rescanning.

Partial dmesg output below. Significantly, the lines:
> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using [bus
00-ff]
are new.

Both series are applied to v4.1, use the same .config file, and the same dtb.
I will investigate further.

(Re-testing v2 works, so this isn't an interim hardware failure)

Thanks,

James



root at localhost:~# dmesg | grep -i pci
[    0.126184] PCI: CLS 0 bytes, default 64
[    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
[    0.152142]   No bus range found for /soc/pcie at 0x01000000, using [bus 00-ff]
[    0.154183] imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
[    0.154201] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.154215] pci_bus 0000:00: root bus resource [???
0x01f00000-0x01f7ffff flags 0x0]
[    0.154228] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    0.154270] pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
[    0.154306] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
[    0.154333] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
[    0.154352] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
[    0.154377] pci 0000:00:00.0: IOMMU is currently not supported for PCI
[    0.154429] pci 0000:00:00.0: supports D1
[    0.154440] pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
[    0.154683] PCI: bus0: Fast back to back transfers disabled
[    0.154806] PCI: bus1: Fast back to back transfers enabled
[    0.154884] pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
[    0.154903] pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-0x0110ffff
pref]
[    0.154917] pci 0000:00:00.0: PCI bridge to [bus 01]
[    0.155145] pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
[    0.155161] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
[    0.155279] aer 0000:00:00.0:pcie02: service driver aer loaded
[    1.188840] ehci-pci: EHCI PCI platform driver
[    1.232518] ohci-pci: OHCI PCI platform driver

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 14:26     ` James Morse
@ 2015-07-01 16:47       ` Gabriele Paoloni
  2015-07-01 17:32         ` James Morse
  2015-07-07  3:44       ` Zhou Wang
  1 sibling, 1 reply; 22+ messages in thread
From: Gabriele Paoloni @ 2015-07-01 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of James Morse
> Sent: Wednesday, July 01, 2015 3:27 PM
> To: Gabriele Paoloni; Wangzhou (B); Bjorn Helgaas; Jingoo Han; Pratyush
> Anand; Arnd Bergmann; Liviu Dudau; kishon at ti.com; xobs at kosagi.com; m-
> karicheri2 at ti.com; Minghuan.Lian at freescale.com
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; Liguozhu (Kenneth)
> Subject: Re: [PATCH v3 2/5] PCI: designware: Add ARM64 support
> 
> Zhou Wang wrote:
> > I tested this patch on D02 board of Hisilicon. It works well.
> > I have compiled the driver with multi_v7_defconfig. However, I don't
> > have
> > ARM32 PCIe related board to do test. It will be appreciated if
> someone
> > could
> > help to test it.
> >
> > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> > Tested-by: James Morse <james.morse@arm.com>
> 
> Tests on this new series, using the same i.MX 6Quad board, are not
> working.
> 
> The network card is no longer detected, and I get a lockup when
> removing
> the root bridge and rescanning.
> 
> Partial dmesg output below. Significantly, the lines:
> > [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> > [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
> [bus
> 00-ff]
> are new.
> 
> Both series are applied to v4.1, use the same .config file, and the
> same dtb.
> I will investigate further.
> 
> (Re-testing v2 works, so this isn't an interim hardware failure)

This is a bit weird....

Patch 2/5 is the only one that affect platforms different from Hisilicon

The only difference between V3 patch[2/5] and v2 patch[2/4] is

*************
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
**************
That is present in v3 but not in v2. And it should affect keystone only....so using patch v3 on the same branch where you applied patch v2 I would expect the same results...

> 
> Thanks,
> 
> James
> 
> 
> 
> root at localhost:~# dmesg | grep -i pci
> [    0.126184] PCI: CLS 0 bytes, default 64
> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
> [bus 00-ff]
> [    0.154183] imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
> [    0.154201] pci_bus 0000:00: root bus resource [bus 00-ff]
> [    0.154215] pci_bus 0000:00: root bus resource [???
> 0x01f00000-0x01f7ffff flags 0x0]
> [    0.154228] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
> [    0.154270] pci_bus 0000:00: root bus resource [mem 0x01000000-
> 0x01efffff]
> [    0.154306] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
> [    0.154333] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
> [    0.154352] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff
> pref]
> [    0.154377] pci 0000:00:00.0: IOMMU is currently not supported for
> PCI
> [    0.154429] pci 0000:00:00.0: supports D1
> [    0.154440] pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
> [    0.154683] PCI: bus0: Fast back to back transfers disabled
> [    0.154806] PCI: bus1: Fast back to back transfers enabled
> [    0.154884] pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-
> 0x010fffff]
> [    0.154903] pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-
> 0x0110ffff
> pref]
> [    0.154917] pci 0000:00:00.0: PCI bridge to [bus 01]
> [    0.155145] pcieport 0000:00:00.0: Signaling PME through PCIe PME
> interrupt
> [    0.155161] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme
> loaded
> [    0.155279] aer 0000:00:00.0:pcie02: service driver aer loaded
> [    1.188840] ehci-pci: EHCI PCI platform driver
> [    1.232518] ohci-pci: OHCI PCI platform driver
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 16:47       ` Gabriele Paoloni
@ 2015-07-01 17:32         ` James Morse
  2015-07-02  1:38           ` Zhou Wang
  2015-07-02  7:24           ` Gabriele Paoloni
  0 siblings, 2 replies; 22+ messages in thread
From: James Morse @ 2015-07-01 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

Gabriele Paoloni wrote:
>> Both series are applied to v4.1, use the same .config file, and the
>> same dtb.
>> I will investigate further.
>>
>> (Re-testing v2 works, so this isn't an interim hardware failure)
>
> This is a bit weird....
>
> Patch 2/5 is the only one that affect platforms different from Hisilicon
>
> The only difference between V3 patch[2/5] and v2 patch[2/4] is

Between v3:2/5 and your replacement for v2:2/4, which arrived after I had
tested the v2 series. As the patch has been replaced with a different one -
neither 'tested-by' is true any more.

It looks like the BAR containing the bridge window is not being assigned,
so no devices on bus 1 are discovered.

I will send the full v2 and v3 dmesg output separately.


Thanks,

James

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 13:29   ` Gabriele Paoloni
  2015-07-01 14:26     ` James Morse
@ 2015-07-02  1:16     ` Zhou Wang
  1 sibling, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-02  1:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/1 21:29, Gabriele Paoloni wrote:
> Adding to the recipients list the authors of the drivers that depend on Synopsys Designware and that are not included
> 
> Respectively:
> pci-dra7xx Kishon Vijay Abraham I <kishon@ti.com>
> pci-imx6 Sean Cross <xobs@kosagi.com>
> pci-keystone Murali Karicheri <m-karicheri2@ti.com>
> pci-layerscape Minghuan Lian <Minghuan.Lian@freescale.com>
> 
> Driver Authors already included:
> pci-exynos Jingoo Han <jg1.han@samsung.com>
> pcie-spear13xx Pratyush Anand <pratyush.anand@st.com>
> 
> Cheers
> 
> Gab
> 

Hi Gab,

Many thanks for adding the related guys.

Regards,
Zhou

>> -----Original Message-----
>> From: Wangzhou (B)
>> Sent: Wednesday, July 01, 2015 10:44 AM
>> To: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; Gabriele
>> Paoloni; James Morse; Liviu Dudau
>> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>> qiuzhenfa; Liguozhu (Kenneth); Wangzhou (B)
>> Subject: [PATCH v3 2/5] PCI: designware: Add ARM64 support
>>
>> This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
>> Delete
>> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
>> hw_pci,
>> move related operations to dw_pcie_host_init. Also set pp->root_bus_nr
>> = 0 in
>> each PCIe host driver which is based on pcie-designware. This patch
>> also try
>> to use of_pci_get_host_bridge_resources for ARM32 and ARM64 according
>> to the
>> suggestion for Gabriele[1]
>>
>> I tested this patch on D02 board of Hisilicon. It works well.
>> I have compiled the driver with multi_v7_defconfig. However, I don't
>> have
>> ARM32 PCIe related board to do test. It will be appreciated if someone
>> could
>> help to test it.
>>
>> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>> Tested-by: James Morse <james.morse@arm.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>> ---
>>  drivers/pci/host/pci-dra7xx.c      |   1 +
>>  drivers/pci/host/pci-exynos.c      |   2 +-
>>  drivers/pci/host/pci-imx6.c        |   2 +-
>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>  drivers/pci/host/pci-keystone.c    |   2 +-
>>  drivers/pci/host/pci-layerscape.c  |   2 +-
>>  drivers/pci/host/pcie-designware.c | 242 +++++++++++++++--------------
>> --------
>>  drivers/pci/host/pcie-designware.h |  10 +-
>>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>>  9 files changed, 110 insertions(+), 155 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
>> dra7xx.c
>> index 2d57e19..5c8b6ab 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -280,6 +280,7 @@ static int __init dra7xx_add_pcie_port(struct
>> dra7xx_pcie *dra7xx,
>>
>>  	pp = &dra7xx->pp;
>>  	pp->dev = dev;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &dra7xx_pcie_host_ops;
>>
>>  	pp->irq = platform_get_irq(pdev, 1);
>> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
>> exynos.c
>> index c139237..4b6db6c 100644
>> --- a/drivers/pci/host/pci-exynos.c
>> +++ b/drivers/pci/host/pci-exynos.c
>> @@ -534,7 +534,7 @@ static int __init exynos_add_pcie_port(struct
>> pcie_port *pp,
>>  		}
>>  	}
>>
>> -	pp->root_bus_nr = -1;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &exynos_pcie_host_ops;
>>
>>  	ret = dw_pcie_host_init(pp);
>> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
>> index fdb9536..c4a80c5 100644
>> --- a/drivers/pci/host/pci-imx6.c
>> +++ b/drivers/pci/host/pci-imx6.c
>> @@ -541,7 +541,7 @@ static int __init imx6_add_pcie_port(struct
>> pcie_port *pp,
>>  		}
>>  	}
>>
>> -	pp->root_bus_nr = -1;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &imx6_pcie_host_ops;
>>
>>  	ret = dw_pcie_host_init(pp);
>> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-
>> keystone-dw.c
>> index f34892e..b1e4135 100644
>> --- a/drivers/pci/host/pci-keystone-dw.c
>> +++ b/drivers/pci/host/pci-keystone-dw.c
>> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem
>> *reg_virt)
>>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>>  {
>>  	struct pcie_port *pp = &ks_pcie->pp;
>> -	u32 start = pp->mem.start, end = pp->mem.end;
>> +	u32 start = pp->mem->start, end = pp->mem->end;
>>  	int i, tr_size;
>>
>>  	/* Disable BARs for inbound access */
>> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
>> keystone.c
>> index 75333b0..df91f5e 100644
>> --- a/drivers/pci/host/pci-keystone.c
>> +++ b/drivers/pci/host/pci-keystone.c
>> @@ -312,7 +312,7 @@ static int __init ks_add_pcie_port(struct
>> keystone_pcie *ks_pcie,
>>  			return ret;
>>  	}
>>
>> -	pp->root_bus_nr = -1;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &keystone_pcie_host_ops;
>>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>>  	if (ret) {
>> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-
>> layerscape.c
>> index 4a6e62f..5c7a9c4 100644
>> --- a/drivers/pci/host/pci-layerscape.c
>> +++ b/drivers/pci/host/pci-layerscape.c
>> @@ -101,7 +101,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>>  	pp = &pcie->pp;
>>  	pp->dev = pcie->dev;
>>  	pp->dbi_base = pcie->dbi;
>> -	pp->root_bus_nr = -1;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &ls_pcie_host_ops;
>>
>>  	ret = dw_pcie_host_init(pp);
>> diff --git a/drivers/pci/host/pcie-designware.c
>> b/drivers/pci/host/pcie-designware.c
>> index 2e9f84f..844febee 100644
>> --- a/drivers/pci/host/pcie-designware.c
>> +++ b/drivers/pci/host/pcie-designware.c
>> @@ -11,6 +11,7 @@
>>   * published by the Free Software Foundation.
>>   */
>>
>> +#include <linux/hardirq.h>
>>  #include <linux/irq.h>
>>  #include <linux/irqdomain.h>
>>  #include <linux/kernel.h>
>> @@ -67,16 +68,7 @@
>>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>>  #define PCIE_ATU_UPPER_TARGET		0x91C
>>
>> -static struct hw_pci dw_pci;
>> -
>> -static unsigned long global_io_offset;
>> -
>> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
>> -{
>> -	BUG_ON(!sys->private_data);
>> -
>> -	return sys->private_data;
>> -}
>> +static struct pci_ops dw_pcie_ops;
>>
>>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>>  {
>> @@ -238,7 +230,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
>> *pp, int irq)
>>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>>  {
>>  	int irq, pos0, i;
>> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
>> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>>
>>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>>  				       order_base_2(no_irqs));
>> @@ -281,7 +273,7 @@ static int dw_msi_setup_irq(struct msi_controller
>> *chip, struct pci_dev *pdev,
>>  {
>>  	int irq, pos;
>>  	struct msi_msg msg;
>> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
>> +	struct pcie_port *pp = pdev->bus->sysdata;
>>
>>  	if (desc->msi_attrib.is_msix)
>>  		return -EINVAL;
>> @@ -310,7 +302,7 @@ static void dw_msi_teardown_irq(struct
>> msi_controller *chip, unsigned int irq)
>>  {
>>  	struct irq_data *data = irq_get_irq_data(irq);
>>  	struct msi_desc *msi = irq_data_get_msi(data);
>> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
>> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>>
>>  	clear_irq_range(pp, irq, 1, data->hwirq);
>>  }
>> @@ -342,16 +334,24 @@ static const struct irq_domain_ops msi_domain_ops
>> = {
>>  	.map = dw_pcie_msi_map,
>>  };
>>
>> -int dw_pcie_host_init(struct pcie_port *pp)
>> +int __init dw_pcie_host_init(struct pcie_port *pp)
>>  {
>>  	struct device_node *np = pp->dev->of_node;
>>  	struct platform_device *pdev = to_platform_device(pp->dev);
>> -	struct of_pci_range range;
>> -	struct of_pci_range_parser parser;
>> +	struct pci_bus *bus;
>>  	struct resource *cfg_res;
>> +	LIST_HEAD(res);
>>  	u32 val, na, ns;
>>  	const __be32 *addrp;
>>  	int i, index, ret;
>> +	int rlen;
>> +	struct resource_entry *win;
>> +	const __be32 *parser_range_end = of_get_property(np, "ranges",
>> &rlen);
>> +
>> +	if (parser_range_end == NULL)
>> +			return -ENOENT;
>> +	parser_range_end += rlen/sizeof(__be32);
>> +
>>
>>  	/* Find the address cell size and the number of cells in order to
>> get
>>  	 * the untranslated address.
>> @@ -375,78 +375,67 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>  		dev_err(pp->dev, "missing *config* reg space\n");
>>  	}
>>
>> -	if (of_pci_range_parser_init(&parser, np)) {
>> -		dev_err(pp->dev, "missing ranges property\n");
>> -		return -EINVAL;
>> -	}
>> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
>>> io_base);
>> +	if (ret)
>> +		return ret;
>>
>>  	/* Get the I/O and memory ranges from DT */
>> -	for_each_of_pci_range(&parser, &range) {
>> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
>> -
>> -		if (restype == IORESOURCE_IO) {
>> -			of_pci_range_to_resource(&range, np, &pp->io);
>> -			pp->io.name = "I/O";
>> -			pp->io.start = max_t(resource_size_t,
>> -					     PCIBIOS_MIN_IO,
>> -					     range.pci_addr + global_io_offset);
>> -			pp->io.end = min_t(resource_size_t,
>> -					   IO_SPACE_LIMIT,
>> -					   range.pci_addr + range.size
>> -					   + global_io_offset - 1);
>> -			pp->io_size = resource_size(&pp->io);
>> -			pp->io_bus_addr = range.pci_addr;
>> -			pp->io_base = range.cpu_addr;
>> -
>> -			/* Find the untranslated IO space address */
>> -			pp->io_mod_base = of_read_number(parser.range -
>> -							 parser.np + na, ns);
>> -		}
>> -		if (restype == IORESOURCE_MEM) {
>> -			of_pci_range_to_resource(&range, np, &pp->mem);
>> -			pp->mem.name = "MEM";
>> -			pp->mem_size = resource_size(&pp->mem);
>> -			pp->mem_bus_addr = range.pci_addr;
>> -
>> -			/* Find the untranslated MEM space address */
>> -			pp->mem_mod_base = of_read_number(parser.range -
>> -							  parser.np + na, ns);
>> -		}
>> -		if (restype == 0) {
>> -			of_pci_range_to_resource(&range, np, &pp->cfg);
>> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
>> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
>> -			pp->cfg0_base = pp->cfg.start;
>> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
>> +	resource_list_for_each_entry(win, &res) {
>> +		switch (resource_type(win->res)) {
>> +		case IORESOURCE_IO:
>> +			pp->io = win->res;
>> +			pp->io->name = "I/O";
>> +			pp->io_size = resource_size(pp->io);
>> +			pp->io_bus_addr = pp->io->start - win->offset;
>> +			/* magic 5 below comes from magic na and ns in
>> +			 * of_pci_range_parser_init()                 */
>> +			pp->io_mod_base = of_read_number(parser_range_end -
>> +					of_n_addr_cells(np) - 5 + na, ns);
>> +			ret = pci_remap_iospace(pp->io, pp->io_base);
>> +			if (ret) {
>> +				dev_warn(pp->dev, "error %d: failed to map
>> resource %pR\n",
>> +				ret, pp->io);
>> +			continue;
>> +			}
>> +			break;
>> +		case IORESOURCE_MEM:
>> +			pp->mem = win->res;
>> +			pp->mem->name = "MEM";
>> +			pp->mem_size = resource_size(pp->mem);
>> +			pp->mem_bus_addr = pp->mem->start - win->offset;
>> +			pp->mem_mod_base = of_read_number(parser_range_end -
>> +					of_n_addr_cells(np) - 5 + na, ns);
>> +			break;
>> +		case 0:
>> +			pp->cfg = win->res;
>> +			pp->cfg0_size = resource_size(pp->cfg)/2;
>> +			pp->cfg1_size = resource_size(pp->cfg)/2;
>> +			pp->cfg0_base = pp->cfg->start;
>> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
>>
>>  			/* Find the untranslated configuration space address
>> */
>> -			pp->cfg0_mod_base = of_read_number(parser.range -
>> -							   parser.np + na, ns);
>> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
>> -					    pp->cfg0_size;
>> +			pp->cfg0_mod_base = of_read_number(parser_range_end -
>> +					of_n_addr_cells(np) - 5 + na, ns);
>> +			pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>> +			break;
>> +		case IORESOURCE_BUS:
>> +			pp->busn = win->res;
>> +			break;
>> +		default:
>> +			continue;
>>  		}
>>  	}
>>
>> -	ret = of_pci_parse_bus_range(np, &pp->busn);
>> -	if (ret < 0) {
>> -		pp->busn.name = np->name;
>> -		pp->busn.start = 0;
>> -		pp->busn.end = 0xff;
>> -		pp->busn.flags = IORESOURCE_BUS;
>> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
>> using default %pR\n",
>> -			ret, &pp->busn);
>> -	}
>> -
>>  	if (!pp->dbi_base) {
>> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
>> -					resource_size(&pp->cfg));
>> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
>> +					resource_size(pp->cfg));
>>  		if (!pp->dbi_base) {
>>  			dev_err(pp->dev, "error with ioremap\n");
>>  			return -ENOMEM;
>>  		}
>>  	}
>>
>> -	pp->mem_base = pp->mem.start;
>> +	pp->mem_base = pp->mem->start;
>>
>>  	if (!pp->va_cfg0_base) {
>>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
>> @@ -493,24 +482,47 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>  	if (pp->ops->host_init)
>>  		pp->ops->host_init(pp);
>>
>> -	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>> +	if (dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0)
>> +			!= PCIBIOS_SUCCESSFUL)
>> +		return -EINVAL;
>>
>>  	/* program correct class for RC */
>> -	dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
>> PCI_CLASS_BRIDGE_PCI);
>> +	if (dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2,
>> PCI_CLASS_BRIDGE_PCI)
>> +			!= PCIBIOS_SUCCESSFUL)
>> +		return -EINVAL;
>> +
>> +	if (dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,
>> &val)
>> +			!= PCIBIOS_SUCCESSFUL)
>> +		return -EINVAL;
>>
>> -	dw_pcie_rd_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, &val);
>>  	val |= PORT_LOGIC_SPEED_CHANGE;
>> -	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>>
>> -#ifdef CONFIG_PCI_MSI
>> -	dw_pcie_msi_chip.dev = pp->dev;
>> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>> +	if (dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val)
>> +			!= PCIBIOS_SUCCESSFUL)
>> +		return -EINVAL;
>> +
>> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
>> +			      pp, &res);
>> +	if (!bus)
>> +		return -ENOMEM;
>> +
>> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
>> domain);
>> +#else
>> +	bus->msi = &dw_pcie_msi_chip;
>>  #endif
>>
>> -	dw_pci.nr_controllers = 1;
>> -	dw_pci.private_data = (void **)&pp;
>> +	pci_scan_child_bus(bus);
>> +	if (pp->ops->scan_bus)
>> +		pp->ops->scan_bus(pp);
>>
>> -	pci_common_init_dev(pp->dev, &dw_pci);
>> +#ifdef CONFIG_ARM
>> +	/* support old dtbs that incorrectly describe IRQs */
>> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +#endif
>> +
>> +	pci_assign_unassigned_bus_resources(bus);
>> +	pci_bus_add_devices(bus);
>>
>>  	return 0;
>>  }
>> @@ -653,7 +665,7 @@ static int dw_pcie_valid_config(struct pcie_port
>> *pp,
>>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>>  			int size, u32 *val)
>>  {
>> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
>> +	struct pcie_port *pp = bus->sysdata;
>>  	int ret;
>>
>>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
>> @@ -677,7 +689,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32
>> devfn, int where,
>>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>>  			int where, int size, u32 val)
>>  {
>> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
>> +	struct pcie_port *pp = bus->sysdata;
>>  	int ret;
>>
>>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
>> @@ -701,64 +713,6 @@ static struct pci_ops dw_pcie_ops = {
>>  	.write = dw_pcie_wr_conf,
>>  };
>>
>> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
>> -{
>> -	struct pcie_port *pp;
>> -
>> -	pp = sys_to_pcie(sys);
>> -
>> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
>> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
>> -		pci_ioremap_io(global_io_offset, pp->io_base);
>> -		global_io_offset += SZ_64K;
>> -		pci_add_resource_offset(&sys->resources, &pp->io,
>> -					sys->io_offset);
>> -	}
>> -
>> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
>> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
>>> mem_offset);
>> -	pci_add_resource(&sys->resources, &pp->busn);
>> -
>> -	return 1;
>> -}
>> -
>> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
>> *sys)
>> -{
>> -	struct pci_bus *bus;
>> -	struct pcie_port *pp = sys_to_pcie(sys);
>> -
>> -	pp->root_bus_nr = sys->busnr;
>> -	bus = pci_create_root_bus(pp->dev, sys->busnr,
>> -				  &dw_pcie_ops, sys, &sys->resources);
>> -	if (!bus)
>> -		return NULL;
>> -
>> -	pci_scan_child_bus(bus);
>> -
>> -	if (bus && pp->ops->scan_bus)
>> -		pp->ops->scan_bus(pp);
>> -
>> -	return bus;
>> -}
>> -
>> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>> -{
>> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
>> -	int irq;
>> -
>> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
>> -	if (!irq)
>> -		irq = pp->irq;
>> -
>> -	return irq;
>> -}
>> -
>> -static struct hw_pci dw_pci = {
>> -	.setup		= dw_pcie_setup,
>> -	.scan		= dw_pcie_scan_bus,
>> -	.map_irq	= dw_pcie_map_irq,
>> -};
>> -
>>  void dw_pcie_setup_rc(struct pcie_port *pp)
>>  {
>>  	u32 val;
>> diff --git a/drivers/pci/host/pcie-designware.h
>> b/drivers/pci/host/pcie-designware.h
>> index d0bbd27..ab78710 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -34,7 +34,7 @@ struct pcie_port {
>>  	u64			cfg1_mod_base;
>>  	void __iomem		*va_cfg1_base;
>>  	u32			cfg1_size;
>> -	u64			io_base;
>> +	resource_size_t			io_base;
>>  	u64			io_mod_base;
>>  	phys_addr_t		io_bus_addr;
>>  	u32			io_size;
>> @@ -42,10 +42,10 @@ struct pcie_port {
>>  	u64			mem_mod_base;
>>  	phys_addr_t		mem_bus_addr;
>>  	u32			mem_size;
>> -	struct resource		cfg;
>> -	struct resource		io;
>> -	struct resource		mem;
>> -	struct resource		busn;
>> +	struct resource		*cfg;
>> +	struct resource		*io;
>> +	struct resource		*mem;
>> +	struct resource		*busn;
>>  	int			irq;
>>  	u32			lanes;
>>  	struct pcie_host_ops	*ops;
>> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-
>> spear13xx.c
>> index 020d788..e78ddf8 100644
>> --- a/drivers/pci/host/pcie-spear13xx.c
>> +++ b/drivers/pci/host/pcie-spear13xx.c
>> @@ -287,7 +287,7 @@ static int spear13xx_add_pcie_port(struct pcie_port
>> *pp,
>>  		return ret;
>>  	}
>>
>> -	pp->root_bus_nr = -1;
>> +	pp->root_bus_nr = 0;
>>  	pp->ops = &spear13xx_pcie_host_ops;
>>
>>  	ret = dw_pcie_host_init(pp);
>> --
>> 1.9.1
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 17:32         ` James Morse
@ 2015-07-02  1:38           ` Zhou Wang
  2015-07-02  7:24           ` Gabriele Paoloni
  1 sibling, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-02  1:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/2 1:32, James Morse wrote:
> Gabriele Paoloni wrote:
>>> Both series are applied to v4.1, use the same .config file, and the
>>> same dtb.
>>> I will investigate further.
>>>
>>> (Re-testing v2 works, so this isn't an interim hardware failure)
>>
>> This is a bit weird....
>>
>> Patch 2/5 is the only one that affect platforms different from Hisilicon
>>
>> The only difference between V3 patch[2/5] and v2 patch[2/4] is
> 
> Between v3:2/5 and your replacement for v2:2/4, which arrived after I had
> tested the v2 series. As the patch has been replaced with a different one -
> neither 'tested-by' is true any more.
>

Hi James,

Firstly, many thanks for your test!

Yes. v3:2/5 had merged Gabriele's codes in. So if you made test on original
v2 patchset and v3 patchset, I think the differences include Gabriele's codes
and codes in pci-keystone-dw.c.

As the patch has been replaced with a different one, I think I should have
added 'tested-by' after it passes your test, is this right?

> It looks like the BAR containing the bridge window is not being assigned,
> so no devices on bus 1 are discovered.
> 
> I will send the full v2 and v3 dmesg output separately.
> 

Thanks, I will debug the problem according your log.

Regards,
Zhou

> 
> Thanks,
> 
> James
> 
> 
> .
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 17:32         ` James Morse
  2015-07-02  1:38           ` Zhou Wang
@ 2015-07-02  7:24           ` Gabriele Paoloni
  2015-07-02 17:40             ` James Morse
  1 sibling, 1 reply; 22+ messages in thread
From: Gabriele Paoloni @ 2015-07-02  7:24 UTC (permalink / raw)
  To: linux-arm-kernel



> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of James Morse
> Sent: 01 July 2015 18:33
> To: Gabriele Paoloni; Wangzhou (B); Bjorn Helgaas; Jingoo Han; Pratyush
> Anand; Arnd Bergmann; Liviu Dudau; kishon at ti.com; xobs at kosagi.com; m-
> karicheri2 at ti.com; Minghuan.Lian at freescale.com
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; Liguozhu (Kenneth)
> Subject: Re: [PATCH v3 2/5] PCI: designware: Add ARM64 support
> 
> Gabriele Paoloni wrote:
> >> Both series are applied to v4.1, use the same .config file, and the
> >> same dtb.
> >> I will investigate further.
> >>
> >> (Re-testing v2 works, so this isn't an interim hardware failure)
> >
> > This is a bit weird....
> >
> > Patch 2/5 is the only one that affect platforms different from
> Hisilicon
> >
> > The only difference between V3 patch[2/5] and v2 patch[2/4] is
> 
> Between v3:2/5 and your replacement for v2:2/4, which arrived after I
> had
> tested the v2 series. As the patch has been replaced with a different
> one -
> neither 'tested-by' is true any more.

Sorry I misread your previous email

> 
> It looks like the BAR containing the bridge window is not being assigned,
> so no devices on bus 1 are discovered.

Can you confirm the dtsi you are using..."imx6qdl.dtsi" ?

Thanks

Gab

> 
> I will send the full v2 and v3 dmesg output separately.
> 
> 
> Thanks,
> 
> James
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-02  7:24           ` Gabriele Paoloni
@ 2015-07-02 17:40             ` James Morse
  0 siblings, 0 replies; 22+ messages in thread
From: James Morse @ 2015-07-02 17:40 UTC (permalink / raw)
  To: linux-arm-kernel

On 02/07/15 08:24, Gabriele Paoloni wrote:
>> It looks like the BAR containing the bridge window is not being assigned,
>> so no devices on bus 1 are discovered.
> 
> Can you confirm the dtsi you are using..."imx6qdl.dtsi" ?

Yes, that looks right.

The on-disk file was 'imx6q-sabrelite.dtb' when I received the board, I
replaced it with the one from the v4.1 kernel tree.

Decompiled from /sys/firmware/fdt (to eliminate bootloader trickery), the
pcie section reads:
pcie at 0x01000000 {
	compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
	reg = <0x1ffc000 0x4000 0x1f00000 0x80000>;
	reg-names = "dbi", "config";
	#address-cells = <0x3>;
	#size-cells = <0x2>;
	device_type = "pci";
	ranges = <0x800 0x0 0x1f00000 0x1f00000 0x0 0x80000 0x81000000 0x0 0x0
0x1f80000 0x0 0x10000 0x82000000 0x0 0x1000000 0x1000000 0x0 0xf00000>;
	num-lanes = <0x1>;
	interrupts = <0x0 0x78 0x4>;
	interrupt-names = "msi";
	#interrupt-cells = <0x1>;
	interrupt-map-mask = <0x0 0x0 0x0 0x7>;
	interrupt-map = <0x0 0x0 0x0 0x1 0x1 0x0 0x7b 0x4 0x0 0x0 0x0 0x2 0x1 0x0
0x7a 0x4 0x0 0x0 0x0 0x3 0x1 0x0 0x79 0x4 0x0 0x0 0x0 0x4 0x1 0x0 0x78 0x4>;
	clocks = <0x3 0x90 0x3 0xce 0x3 0xbd>;
	clock-names = "pcie", "pcie_bus", "pcie_phy";
	status = "okay";
};



James

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-01  9:43 ` [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource Zhou Wang
@ 2015-07-02 17:50   ` Liviu Dudau
  2015-07-07  5:44     ` Zhou Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Liviu Dudau @ 2015-07-02 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jul 01, 2015 at 10:43:33AM +0100, Zhou Wang wrote:
> This patch had added by Arnd Bergmann during last reviewing of v1 patchset[1].
> 
> PCI core codes call pcibios_align_resource(). In ARM specific one, it will
> dereference pci_sys_data and call sys->align_resource. If we try to unify ARM
> and ARM64 PCIe API in pcie-designware. it will bring kernel crash when run into
> this dereferencing.
> 
> However, in ARM there is only pci-mvebu which implements align_resource. So
> add align_resource call back in pci_host_bridge structure and override
> pcibios_align_resource with it.
> 
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg41671.html
> ---
>  arch/arm/kernel/bios32.c     |  6 ------
>  drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++----------------
>  drivers/pci/setup-res.c      | 27 ++++++++++++++++++++-----
>  include/linux/pci.h          |  3 +++
>  4 files changed, 55 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index fcbbbb1..b01189f 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  		sys->busnr   = busnr;
>  		sys->swizzle = hw->swizzle;
>  		sys->map_irq = hw->map_irq;
> -		sys->align_resource = hw->align_resource;
>  		INIT_LIST_HEAD(&sys->resources);
>  
>  		if (hw->private_data)
> @@ -588,8 +587,6 @@ char * __init pcibios_setup(char *str)
>  resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  				resource_size_t size, resource_size_t align)
>  {
> -	struct pci_dev *dev = data;
> -	struct pci_sys_data *sys = dev->sysdata;
>  	resource_size_t start = res->start;
>  
>  	if (res->flags & IORESOURCE_IO && start & 0x300)
> @@ -597,9 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  
>  	start = (start + align - 1) & ~(align - 1);
>  
> -	if (sys->align_resource)
> -		return sys->align_resource(dev, res, start, size, align);
> -
>  	return start;
>  }
>  
> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> index 1ab8635..155d05f 100644
> --- a/drivers/pci/host/pci-mvebu.c
> +++ b/drivers/pci/host/pci-mvebu.c
> @@ -22,6 +22,8 @@
>  #include <linux/of_pci.h>
>  #include <linux/of_platform.h>
>  
> +#include "../pci.h" /* HACK to see pci_find_host_bridge */
> +
>  /*
>   * PCIe unit register offsets.
>   */
> @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
>  	return 1;
>  }
>  
> -static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> +static resource_size_t mvebu_pcie_align_resource(void *data,
> +						 const struct resource *res,
> +						 resource_size_t size,
> +						 resource_size_t align)
>  {
> -	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> -	struct pci_bus *bus;
> +	struct pci_dev *dev = data;
>  
> -	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> -				  &mvebu_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> +	resource_size_t start = res->start;
>  
> -	pci_scan_child_bus(bus);
> +	if (res->flags & IORESOURCE_IO && start & 0x300)
> +		start = (start + 0x3ff) & ~0x3ff;
>  
> -	return bus;
> -}
> +	start = (start + align - 1) & ~(align - 1);

Honestly, I don't see here anything that is mvebu specific. Could you move
this function in the generic pci/host area and have a flag in the pci_host_bridge
structure whether the function should be called or not? I know that in a way
that looks very close to the existing implementation which uses pcibios_align_resource,
but the problem with pcibios_ version is that it is arch specific and not driver
specific the way we want.

Having this version as a generic implementation would also remove at least 2 more
arch version, possibly more after testing by the arch maintainers.

Best regards,
Liviu

>  
> -static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
> -						 const struct resource *res,
> -						 resource_size_t start,
> -						 resource_size_t size,
> -						 resource_size_t align)
> -{
>  	if (dev->bus->number != 0)
>  		return start;
>  
> @@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
>  		return start;
>  }
>  
> +static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> +{
> +	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> +	struct pci_host_bridge *phb;
> +	struct pci_bus *bus;
> +
> +	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> +				  &mvebu_pcie_ops, sys, &sys->resources);
> +	if (!bus)
> +		return NULL;
> +
> +	phb = pci_find_host_bridge(bus);
> +	phb->align_resource = mvebu_pcie_align_resource;
> +
> +	pci_scan_child_bus(bus);
> +
> +	return bus;
> +}
> +
>  static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
>  {
>  	struct hw_pci hw;
> @@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
>  	hw.scan           = mvebu_pcie_scan_bus;
>  	hw.map_irq        = of_irq_parse_and_map_pci;
>  	hw.ops            = &mvebu_pcie_ops;
> -	hw.align_resource = mvebu_pcie_align_resource;
>  
>  	pci_common_init(&hw);
>  }
> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> index 232f925..73abca7 100644
> --- a/drivers/pci/setup-res.c
> +++ b/drivers/pci/setup-res.c
> @@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
>  }
>  
>  static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
> -		int resno, resource_size_t size, resource_size_t align)
> +		int resno, resource_size_t size, resource_size_t align,
> +		resource_size_t (*alignf)(void *,
> +					  const struct resource *,
> +					  resource_size_t,
> +					  resource_size_t))
>  {
>  	struct resource *res = dev->resource + resno;
>  	resource_size_t min;
> @@ -217,7 +221,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	 */
>  	ret = pci_bus_alloc_resource(bus, res, size, align, min,
>  				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
> -				     pcibios_align_resource, dev);
> +				     alignf, dev);
>  	if (ret == 0)
>  		return 0;
>  
> @@ -229,7 +233,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
>  		ret = pci_bus_alloc_resource(bus, res, size, align, min,
>  					     IORESOURCE_PREFETCH,
> -					     pcibios_align_resource, dev);
> +					     alignf, dev);
>  		if (ret == 0)
>  			return 0;
>  	}
> @@ -242,7 +246,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>  	 */
>  	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
>  		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
> -					     pcibios_align_resource, dev);
> +					     alignf, dev);
>  
>  	return ret;
>  }
> @@ -251,10 +255,23 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
>  				resource_size_t size, resource_size_t min_align)
>  {
>  	struct pci_bus *bus;
> +	struct pci_host_bridge *phb;
> +	resource_size_t (*alignf)(void *,
> +				  const struct resource *,
> +				  resource_size_t,
> +				  resource_size_t);
>  	int ret;
>  
>  	bus = dev->bus;
> -	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
> +	phb = pci_find_host_bridge(bus);
> +
> +	if (phb->align_resource)
> +		alignf = phb->align_resource;
> +	else
> +		alignf = pcibios_align_resource;
> +
> +	while ((ret = __pci_assign_resource(bus, dev, resno, size,
> +					    min_align, alignf))) {
>  		if (!bus->parent || !bus->self->transparent)
>  			break;
>  		bus = bus->parent;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 353db8d..39e48fc 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -404,6 +404,9 @@ struct pci_host_bridge {
>  	struct device dev;
>  	struct pci_bus *bus;		/* root bus */
>  	struct list_head windows;	/* resource_entry */
> +	resource_size_t (*align_resource)(void *data,
> +			 const struct resource *res,
> +			 resource_size_t size, resource_size_t align);
>  	void (*release_fn)(struct pci_host_bridge *);
>  	void *release_data;
>  	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
> -- 
> 1.9.1
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-01 14:26     ` James Morse
  2015-07-01 16:47       ` Gabriele Paoloni
@ 2015-07-07  3:44       ` Zhou Wang
  2015-07-10  8:53         ` Gabriele Paoloni
  1 sibling, 1 reply; 22+ messages in thread
From: Zhou Wang @ 2015-07-07  3:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/1 22:26, James Morse wrote:
> Zhou Wang wrote:
>> I tested this patch on D02 board of Hisilicon. It works well.
>> I have compiled the driver with multi_v7_defconfig. However, I don't
>> have
>> ARM32 PCIe related board to do test. It will be appreciated if someone
>> could
>> help to test it.
>>
>> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>> Tested-by: James Morse <james.morse@arm.com>
> 
> Tests on this new series, using the same i.MX 6Quad board, are not working.
> 
> The network card is no longer detected, and I get a lockup when removing
> the root bridge and rescanning.
> 
> Partial dmesg output below. Significantly, the lines:
>> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
>> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using [bus
> 00-ff]
> are new.
> 
> Both series are applied to v4.1, use the same .config file, and the same dtb.
> I will investigate further.
> 
> (Re-testing v2 works, so this isn't an interim hardware failure)
> 
> Thanks,
> 
> James
>

Hi James,

There are something wrong with v3 patch.

pp->io_mod_base = of_read_number(parser_range_end -
		of_n_addr_cells(np) - 5 + na, ns);
pp->mem_mod_base = of_read_number(parser_range_end -
		of_n_addr_cells(np) - 5 + na, ns);
pp->cfg0_mod_base = of_read_number(parser_range_end -
		of_n_addr_cells(np) - 5 + na, ns);
are wrong.

The ranges item in your dts is:
ranges = <0x800 0x0 0x1f00000 0x1f00000 0x0 0x80000
	  0x81000000 0x0 0x0  0x1f80000 0x0 0x10000
	  0x82000000 0x0 0x1000000 0x1000000 0x0 0xf00000>;
parser_range_end points to the end of ranges(0xf00000) directly. In v2 patch,
of_read_number is of_read_number(parser.range - parser.np + na, ns); parser.range
points to the end of each line in ranges item.

When I did test on D02 board with intel82599 card, I set ranges item as:
ranges = <0x03000000 0 0xb0000000 0x220 0x00000000 0 0xf000000>;
It is just one line. In this case, parser_range_end is same with parser.range.
That is why it happened to work well on D02 board.

very sorry to bother you about this problem.

Thanks,
Zhou

> 
> 
> root at localhost:~# dmesg | grep -i pci
> [    0.126184] PCI: CLS 0 bytes, default 64
> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using [bus 00-ff]
> [    0.154183] imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00
> [    0.154201] pci_bus 0000:00: root bus resource [bus 00-ff]
> [    0.154215] pci_bus 0000:00: root bus resource [???
> 0x01f00000-0x01f7ffff flags 0x0]
> [    0.154228] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
> [    0.154270] pci_bus 0000:00: root bus resource [mem 0x01000000-0x01efffff]
> [    0.154306] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
> [    0.154333] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
> [    0.154352] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
> [    0.154377] pci 0000:00:00.0: IOMMU is currently not supported for PCI
> [    0.154429] pci 0000:00:00.0: supports D1
> [    0.154440] pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
> [    0.154683] PCI: bus0: Fast back to back transfers disabled
> [    0.154806] PCI: bus1: Fast back to back transfers enabled
> [    0.154884] pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-0x010fffff]
> [    0.154903] pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-0x0110ffff
> pref]
> [    0.154917] pci 0000:00:00.0: PCI bridge to [bus 01]
> [    0.155145] pcieport 0000:00:00.0: Signaling PME through PCIe PME interrupt
> [    0.155161] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme loaded
> [    0.155279] aer 0000:00:00.0:pcie02: service driver aer loaded
> [    1.188840] ehci-pci: EHCI PCI platform driver
> [    1.232518] ohci-pci: OHCI PCI platform driver
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> .
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-02 17:50   ` Liviu Dudau
@ 2015-07-07  5:44     ` Zhou Wang
  2015-07-07  9:22       ` Liviu Dudau
  0 siblings, 1 reply; 22+ messages in thread
From: Zhou Wang @ 2015-07-07  5:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/3 1:50, Liviu Dudau wrote:
> On Wed, Jul 01, 2015 at 10:43:33AM +0100, Zhou Wang wrote:
>> This patch had added by Arnd Bergmann during last reviewing of v1 patchset[1].
>>
>> PCI core codes call pcibios_align_resource(). In ARM specific one, it will
>> dereference pci_sys_data and call sys->align_resource. If we try to unify ARM
>> and ARM64 PCIe API in pcie-designware. it will bring kernel crash when run into
>> this dereferencing.
>>
>> However, in ARM there is only pci-mvebu which implements align_resource. So
>> add align_resource call back in pci_host_bridge structure and override
>> pcibios_align_resource with it.
>>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
>> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg41671.html
>> ---
>>  arch/arm/kernel/bios32.c     |  6 ------
>>  drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++----------------
>>  drivers/pci/setup-res.c      | 27 ++++++++++++++++++++-----
>>  include/linux/pci.h          |  3 +++
>>  4 files changed, 55 insertions(+), 28 deletions(-)
>>
>> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
>> index fcbbbb1..b01189f 100644
>> --- a/arch/arm/kernel/bios32.c
>> +++ b/arch/arm/kernel/bios32.c
>> @@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>>  		sys->busnr   = busnr;
>>  		sys->swizzle = hw->swizzle;
>>  		sys->map_irq = hw->map_irq;
>> -		sys->align_resource = hw->align_resource;
>>  		INIT_LIST_HEAD(&sys->resources);
>>  
>>  		if (hw->private_data)
>> @@ -588,8 +587,6 @@ char * __init pcibios_setup(char *str)
>>  resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>>  				resource_size_t size, resource_size_t align)
>>  {
>> -	struct pci_dev *dev = data;
>> -	struct pci_sys_data *sys = dev->sysdata;
>>  	resource_size_t start = res->start;
>>  
>>  	if (res->flags & IORESOURCE_IO && start & 0x300)
>> @@ -597,9 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>>  
>>  	start = (start + align - 1) & ~(align - 1);
>>  
>> -	if (sys->align_resource)
>> -		return sys->align_resource(dev, res, start, size, align);
>> -
>>  	return start;
>>  }
>>  
>> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
>> index 1ab8635..155d05f 100644
>> --- a/drivers/pci/host/pci-mvebu.c
>> +++ b/drivers/pci/host/pci-mvebu.c
>> @@ -22,6 +22,8 @@
>>  #include <linux/of_pci.h>
>>  #include <linux/of_platform.h>
>>  
>> +#include "../pci.h" /* HACK to see pci_find_host_bridge */
>> +
>>  /*
>>   * PCIe unit register offsets.
>>   */
>> @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
>>  	return 1;
>>  }
>>  
>> -static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>> +static resource_size_t mvebu_pcie_align_resource(void *data,
>> +						 const struct resource *res,
>> +						 resource_size_t size,
>> +						 resource_size_t align)
>>  {
>> -	struct mvebu_pcie *pcie = sys_to_pcie(sys);
>> -	struct pci_bus *bus;
>> +	struct pci_dev *dev = data;
>>  
>> -	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
>> -				  &mvebu_pcie_ops, sys, &sys->resources);
>> -	if (!bus)
>> -		return NULL;
>> +	resource_size_t start = res->start;
>>  
>> -	pci_scan_child_bus(bus);
>> +	if (res->flags & IORESOURCE_IO && start & 0x300)
>> +		start = (start + 0x3ff) & ~0x3ff;
>>  
>> -	return bus;
>> -}
>> +	start = (start + align - 1) & ~(align - 1);
> 
> Honestly, I don't see here anything that is mvebu specific. Could you move

What I mean is that there is only mvebu who implemented sys->align_resource callback in ARM
arch.

> this function in the generic pci/host area and have a flag in the pci_host_bridge
> structure whether the function should be called or not? I know that in a way
> that looks very close to the existing implementation which uses pcibios_align_resource,

I am confused about "the existing implementation". Now pcibios_align_resource are
implemented by each arch code and are called directly. Did I miss anything about
pcibios_align_resource?

Best rgards,
Zhou

> but the problem with pcibios_ version is that it is arch specific and not driver
> specific the way we want.
> 
> Having this version as a generic implementation would also remove at least 2 more
> arch version, possibly more after testing by the arch maintainers.
> 
> Best regards,
> Liviu
> 
>>  
>> -static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
>> -						 const struct resource *res,
>> -						 resource_size_t start,
>> -						 resource_size_t size,
>> -						 resource_size_t align)
>> -{
>>  	if (dev->bus->number != 0)
>>  		return start;
>>  
>> @@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
>>  		return start;
>>  }
>>  
>> +static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
>> +{
>> +	struct mvebu_pcie *pcie = sys_to_pcie(sys);
>> +	struct pci_host_bridge *phb;
>> +	struct pci_bus *bus;
>> +
>> +	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
>> +				  &mvebu_pcie_ops, sys, &sys->resources);
>> +	if (!bus)
>> +		return NULL;
>> +
>> +	phb = pci_find_host_bridge(bus);
>> +	phb->align_resource = mvebu_pcie_align_resource;
>> +
>> +	pci_scan_child_bus(bus);
>> +
>> +	return bus;
>> +}
>> +
>>  static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
>>  {
>>  	struct hw_pci hw;
>> @@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
>>  	hw.scan           = mvebu_pcie_scan_bus;
>>  	hw.map_irq        = of_irq_parse_and_map_pci;
>>  	hw.ops            = &mvebu_pcie_ops;
>> -	hw.align_resource = mvebu_pcie_align_resource;
>>  
>>  	pci_common_init(&hw);
>>  }
>> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
>> index 232f925..73abca7 100644
>> --- a/drivers/pci/setup-res.c
>> +++ b/drivers/pci/setup-res.c
>> @@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
>>  }
>>  
>>  static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>> -		int resno, resource_size_t size, resource_size_t align)
>> +		int resno, resource_size_t size, resource_size_t align,
>> +		resource_size_t (*alignf)(void *,
>> +					  const struct resource *,
>> +					  resource_size_t,
>> +					  resource_size_t))
>>  {
>>  	struct resource *res = dev->resource + resno;
>>  	resource_size_t min;
>> @@ -217,7 +221,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>>  	 */
>>  	ret = pci_bus_alloc_resource(bus, res, size, align, min,
>>  				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
>> -				     pcibios_align_resource, dev);
>> +				     alignf, dev);
>>  	if (ret == 0)
>>  		return 0;
>>  
>> @@ -229,7 +233,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>>  	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
>>  		ret = pci_bus_alloc_resource(bus, res, size, align, min,
>>  					     IORESOURCE_PREFETCH,
>> -					     pcibios_align_resource, dev);
>> +					     alignf, dev);
>>  		if (ret == 0)
>>  			return 0;
>>  	}
>> @@ -242,7 +246,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
>>  	 */
>>  	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
>>  		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
>> -					     pcibios_align_resource, dev);
>> +					     alignf, dev);
>>  
>>  	return ret;
>>  }
>> @@ -251,10 +255,23 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
>>  				resource_size_t size, resource_size_t min_align)
>>  {
>>  	struct pci_bus *bus;
>> +	struct pci_host_bridge *phb;
>> +	resource_size_t (*alignf)(void *,
>> +				  const struct resource *,
>> +				  resource_size_t,
>> +				  resource_size_t);
>>  	int ret;
>>  
>>  	bus = dev->bus;
>> -	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
>> +	phb = pci_find_host_bridge(bus);
>> +
>> +	if (phb->align_resource)
>> +		alignf = phb->align_resource;
>> +	else
>> +		alignf = pcibios_align_resource;
>> +
>> +	while ((ret = __pci_assign_resource(bus, dev, resno, size,
>> +					    min_align, alignf))) {
>>  		if (!bus->parent || !bus->self->transparent)
>>  			break;
>>  		bus = bus->parent;
>> diff --git a/include/linux/pci.h b/include/linux/pci.h
>> index 353db8d..39e48fc 100644
>> --- a/include/linux/pci.h
>> +++ b/include/linux/pci.h
>> @@ -404,6 +404,9 @@ struct pci_host_bridge {
>>  	struct device dev;
>>  	struct pci_bus *bus;		/* root bus */
>>  	struct list_head windows;	/* resource_entry */
>> +	resource_size_t (*align_resource)(void *data,
>> +			 const struct resource *res,
>> +			 resource_size_t size, resource_size_t align);
>>  	void (*release_fn)(struct pci_host_bridge *);
>>  	void *release_data;
>>  	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
>> -- 
>> 1.9.1
>>
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-07  5:44     ` Zhou Wang
@ 2015-07-07  9:22       ` Liviu Dudau
  2015-07-17 10:02         ` Gabriele Paoloni
  0 siblings, 1 reply; 22+ messages in thread
From: Liviu Dudau @ 2015-07-07  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jul 07, 2015 at 06:44:01AM +0100, Zhou Wang wrote:
> On 2015/7/3 1:50, Liviu Dudau wrote:
> > On Wed, Jul 01, 2015 at 10:43:33AM +0100, Zhou Wang wrote:
> >> This patch had added by Arnd Bergmann during last reviewing of v1 patchset[1].
> >>
> >> PCI core codes call pcibios_align_resource(). In ARM specific one, it will
> >> dereference pci_sys_data and call sys->align_resource. If we try to unify ARM
> >> and ARM64 PCIe API in pcie-designware. it will bring kernel crash when run into
> >> this dereferencing.
> >>
> >> However, in ARM there is only pci-mvebu which implements align_resource. So
> >> add align_resource call back in pci_host_bridge structure and override
> >> pcibios_align_resource with it.
> >>
> >> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> >> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> >> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> >>
> >> [1] http://www.spinics.net/lists/linux-pci/msg41671.html
> >> ---
> >>  arch/arm/kernel/bios32.c     |  6 ------
> >>  drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++----------------
> >>  drivers/pci/setup-res.c      | 27 ++++++++++++++++++++-----
> >>  include/linux/pci.h          |  3 +++
> >>  4 files changed, 55 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> >> index fcbbbb1..b01189f 100644
> >> --- a/arch/arm/kernel/bios32.c
> >> +++ b/arch/arm/kernel/bios32.c
> >> @@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
> >>  		sys->busnr   = busnr;
> >>  		sys->swizzle = hw->swizzle;
> >>  		sys->map_irq = hw->map_irq;
> >> -		sys->align_resource = hw->align_resource;
> >>  		INIT_LIST_HEAD(&sys->resources);
> >>  
> >>  		if (hw->private_data)
> >> @@ -588,8 +587,6 @@ char * __init pcibios_setup(char *str)
> >>  resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> >>  				resource_size_t size, resource_size_t align)
> >>  {
> >> -	struct pci_dev *dev = data;
> >> -	struct pci_sys_data *sys = dev->sysdata;
> >>  	resource_size_t start = res->start;
> >>  
> >>  	if (res->flags & IORESOURCE_IO && start & 0x300)
> >> @@ -597,9 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> >>  
> >>  	start = (start + align - 1) & ~(align - 1);
> >>  
> >> -	if (sys->align_resource)
> >> -		return sys->align_resource(dev, res, start, size, align);
> >> -
> >>  	return start;
> >>  }
> >>  
> >> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
> >> index 1ab8635..155d05f 100644
> >> --- a/drivers/pci/host/pci-mvebu.c
> >> +++ b/drivers/pci/host/pci-mvebu.c
> >> @@ -22,6 +22,8 @@
> >>  #include <linux/of_pci.h>
> >>  #include <linux/of_platform.h>
> >>  
> >> +#include "../pci.h" /* HACK to see pci_find_host_bridge */
> >> +
> >>  /*
> >>   * PCIe unit register offsets.
> >>   */
> >> @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
> >>  	return 1;
> >>  }
> >>  
> >> -static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> >> +static resource_size_t mvebu_pcie_align_resource(void *data,
> >> +						 const struct resource *res,
> >> +						 resource_size_t size,
> >> +						 resource_size_t align)
> >>  {
> >> -	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> >> -	struct pci_bus *bus;
> >> +	struct pci_dev *dev = data;
> >>  
> >> -	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> >> -				  &mvebu_pcie_ops, sys, &sys->resources);
> >> -	if (!bus)
> >> -		return NULL;
> >> +	resource_size_t start = res->start;
> >>  
> >> -	pci_scan_child_bus(bus);
> >> +	if (res->flags & IORESOURCE_IO && start & 0x300)
> >> +		start = (start + 0x3ff) & ~0x3ff;
> >>  
> >> -	return bus;
> >> -}
> >> +	start = (start + align - 1) & ~(align - 1);
> > 
> > Honestly, I don't see here anything that is mvebu specific. Could you move
> 
> What I mean is that there is only mvebu who implemented sys->align_resource callback in ARM
> arch.
> 
> > this function in the generic pci/host area and have a flag in the pci_host_bridge
> > structure whether the function should be called or not? I know that in a way
> > that looks very close to the existing implementation which uses pcibios_align_resource,
> 
> I am confused about "the existing implementation". Now pcibios_align_resource are
> implemented by each arch code and are called directly. Did I miss anything about
> pcibios_align_resource?

Sorry, I meant existing implementation_s_ and yes, I was reffering to the arch specific
code. If you look at the cris, frv/mb93090-mb00, m68k, microblaze, powerpc, unicore32
and x86 they all share the code with your version, plus or minus additional checks.
I was thinking that for those arch versions that match your version you can create just
one version and use it as the alignf function.

Best regards,
Liviu

> 
> Best rgards,
> Zhou
> 
> > but the problem with pcibios_ version is that it is arch specific and not driver
> > specific the way we want.
> > 
> > Having this version as a generic implementation would also remove at least 2 more
> > arch version, possibly more after testing by the arch maintainers.
> > 
> > Best regards,
> > Liviu
> > 
> >>  
> >> -static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
> >> -						 const struct resource *res,
> >> -						 resource_size_t start,
> >> -						 resource_size_t size,
> >> -						 resource_size_t align)
> >> -{
> >>  	if (dev->bus->number != 0)
> >>  		return start;
> >>  
> >> @@ -796,6 +791,25 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
> >>  		return start;
> >>  }
> >>  
> >> +static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> >> +{
> >> +	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> >> +	struct pci_host_bridge *phb;
> >> +	struct pci_bus *bus;
> >> +
> >> +	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> >> +				  &mvebu_pcie_ops, sys, &sys->resources);
> >> +	if (!bus)
> >> +		return NULL;
> >> +
> >> +	phb = pci_find_host_bridge(bus);
> >> +	phb->align_resource = mvebu_pcie_align_resource;
> >> +
> >> +	pci_scan_child_bus(bus);
> >> +
> >> +	return bus;
> >> +}
> >> +
> >>  static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
> >>  {
> >>  	struct hw_pci hw;
> >> @@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
> >>  	hw.scan           = mvebu_pcie_scan_bus;
> >>  	hw.map_irq        = of_irq_parse_and_map_pci;
> >>  	hw.ops            = &mvebu_pcie_ops;
> >> -	hw.align_resource = mvebu_pcie_align_resource;
> >>  
> >>  	pci_common_init(&hw);
> >>  }
> >> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> >> index 232f925..73abca7 100644
> >> --- a/drivers/pci/setup-res.c
> >> +++ b/drivers/pci/setup-res.c
> >> @@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
> >>  }
> >>  
> >>  static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
> >> -		int resno, resource_size_t size, resource_size_t align)
> >> +		int resno, resource_size_t size, resource_size_t align,
> >> +		resource_size_t (*alignf)(void *,
> >> +					  const struct resource *,
> >> +					  resource_size_t,
> >> +					  resource_size_t))
> >>  {
> >>  	struct resource *res = dev->resource + resno;
> >>  	resource_size_t min;
> >> @@ -217,7 +221,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
> >>  	 */
> >>  	ret = pci_bus_alloc_resource(bus, res, size, align, min,
> >>  				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
> >> -				     pcibios_align_resource, dev);
> >> +				     alignf, dev);
> >>  	if (ret == 0)
> >>  		return 0;
> >>  
> >> @@ -229,7 +233,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
> >>  	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
> >>  		ret = pci_bus_alloc_resource(bus, res, size, align, min,
> >>  					     IORESOURCE_PREFETCH,
> >> -					     pcibios_align_resource, dev);
> >> +					     alignf, dev);
> >>  		if (ret == 0)
> >>  			return 0;
> >>  	}
> >> @@ -242,7 +246,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
> >>  	 */
> >>  	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
> >>  		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
> >> -					     pcibios_align_resource, dev);
> >> +					     alignf, dev);
> >>  
> >>  	return ret;
> >>  }
> >> @@ -251,10 +255,23 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno,
> >>  				resource_size_t size, resource_size_t min_align)
> >>  {
> >>  	struct pci_bus *bus;
> >> +	struct pci_host_bridge *phb;
> >> +	resource_size_t (*alignf)(void *,
> >> +				  const struct resource *,
> >> +				  resource_size_t,
> >> +				  resource_size_t);
> >>  	int ret;
> >>  
> >>  	bus = dev->bus;
> >> -	while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
> >> +	phb = pci_find_host_bridge(bus);
> >> +
> >> +	if (phb->align_resource)
> >> +		alignf = phb->align_resource;
> >> +	else
> >> +		alignf = pcibios_align_resource;
> >> +
> >> +	while ((ret = __pci_assign_resource(bus, dev, resno, size,
> >> +					    min_align, alignf))) {
> >>  		if (!bus->parent || !bus->self->transparent)
> >>  			break;
> >>  		bus = bus->parent;
> >> diff --git a/include/linux/pci.h b/include/linux/pci.h
> >> index 353db8d..39e48fc 100644
> >> --- a/include/linux/pci.h
> >> +++ b/include/linux/pci.h
> >> @@ -404,6 +404,9 @@ struct pci_host_bridge {
> >>  	struct device dev;
> >>  	struct pci_bus *bus;		/* root bus */
> >>  	struct list_head windows;	/* resource_entry */
> >> +	resource_size_t (*align_resource)(void *data,
> >> +			 const struct resource *res,
> >> +			 resource_size_t size, resource_size_t align);
> >>  	void (*release_fn)(struct pci_host_bridge *);
> >>  	void *release_data;
> >>  	unsigned int ignore_reset_delay:1;	/* for entire hierarchy */
> >> -- 
> >> 1.9.1
> >>
> > 
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-07  3:44       ` Zhou Wang
@ 2015-07-10  8:53         ` Gabriele Paoloni
  2015-07-10  9:36           ` Zhou Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Gabriele Paoloni @ 2015-07-10  8:53 UTC (permalink / raw)
  To: linux-arm-kernel

I have just sent this patch "[PATCH] Store PCIe controllers address in struct of_pci_range".

It would be needed by "pcie_designware.c" to retrieve the PCI controller addresses from "win->__res.start".

So we do not need to retrieve info from the DT parser anymore and we can use the new PCI DT parsing API

This problem was already discussed in this thread:
http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317743.html


> -----Original Message-----
> From: Wangzhou (B)
> Sent: Tuesday, July 07, 2015 4:44 AM
> To: James Morse
> Cc: Gabriele Paoloni; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd
> Bergmann; Liviu Dudau; kishon at ti.com; xobs at kosagi.com; m-
> karicheri2 at ti.com; Minghuan.Lian at freescale.com; linux-
> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> qiuzhenfa; Liguozhu (Kenneth)
> Subject: Re: [PATCH v3 2/5] PCI: designware: Add ARM64 support
> 
> On 2015/7/1 22:26, James Morse wrote:
> > Zhou Wang wrote:
> >> I tested this patch on D02 board of Hisilicon. It works well.
> >> I have compiled the driver with multi_v7_defconfig. However, I don't
> >> have
> >> ARM32 PCIe related board to do test. It will be appreciated if
> someone
> >> could
> >> help to test it.
> >>
> >> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> >> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> >> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> >> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> >> Tested-by: James Morse <james.morse@arm.com>
> >
> > Tests on this new series, using the same i.MX 6Quad board, are not
> working.
> >
> > The network card is no longer detected, and I get a lockup when
> removing
> > the root bridge and rescanning.
> >
> > Partial dmesg output below. Significantly, the lines:
> >> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> >> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
> [bus
> > 00-ff]
> > are new.
> >
> > Both series are applied to v4.1, use the same .config file, and the
> same dtb.
> > I will investigate further.
> >
> > (Re-testing v2 works, so this isn't an interim hardware failure)
> >
> > Thanks,
> >
> > James
> >
> 
> Hi James,
> 
> There are something wrong with v3 patch.
> 
> pp->io_mod_base = of_read_number(parser_range_end -
> 		of_n_addr_cells(np) - 5 + na, ns);
> pp->mem_mod_base = of_read_number(parser_range_end -
> 		of_n_addr_cells(np) - 5 + na, ns);
> pp->cfg0_mod_base = of_read_number(parser_range_end -
> 		of_n_addr_cells(np) - 5 + na, ns);
> are wrong.
> 
> The ranges item in your dts is:
> ranges = <0x800 0x0 0x1f00000 0x1f00000 0x0 0x80000
> 	  0x81000000 0x0 0x0  0x1f80000 0x0 0x10000
> 	  0x82000000 0x0 0x1000000 0x1000000 0x0 0xf00000>;
> parser_range_end points to the end of ranges(0xf00000) directly. In v2
> patch,
> of_read_number is of_read_number(parser.range - parser.np + na, ns);
> parser.range
> points to the end of each line in ranges item.
> 
> When I did test on D02 board with intel82599 card, I set ranges item as:
> ranges = <0x03000000 0 0xb0000000 0x220 0x00000000 0 0xf000000>;
> It is just one line. In this case, parser_range_end is same with
> parser.range.
> That is why it happened to work well on D02 board.
> 
> very sorry to bother you about this problem.
> 
> Thanks,
> Zhou
> 
> >
> >
> > root at localhost:~# dmesg | grep -i pci
> > [    0.126184] PCI: CLS 0 bytes, default 64
> > [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
> > [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
> [bus 00-ff]
> > [    0.154183] imx6q-pcie 1ffc000.pcie: PCI host bridge to bus
> 0000:00
> > [    0.154201] pci_bus 0000:00: root bus resource [bus 00-ff]
> > [    0.154215] pci_bus 0000:00: root bus resource [???
> > 0x01f00000-0x01f7ffff flags 0x0]
> > [    0.154228] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
> > [    0.154270] pci_bus 0000:00: root bus resource [mem 0x01000000-
> 0x01efffff]
> > [    0.154306] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
> > [    0.154333] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
> > [    0.154352] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff
> pref]
> > [    0.154377] pci 0000:00:00.0: IOMMU is currently not supported for
> PCI
> > [    0.154429] pci 0000:00:00.0: supports D1
> > [    0.154440] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
> D3cold
> > [    0.154683] PCI: bus0: Fast back to back transfers disabled
> > [    0.154806] PCI: bus1: Fast back to back transfers enabled
> > [    0.154884] pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-
> 0x010fffff]
> > [    0.154903] pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-
> 0x0110ffff
> > pref]
> > [    0.154917] pci 0000:00:00.0: PCI bridge to [bus 01]
> > [    0.155145] pcieport 0000:00:00.0: Signaling PME through PCIe PME
> interrupt
> > [    0.155161] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme
> loaded
> > [    0.155279] aer 0000:00:00.0:pcie02: service driver aer loaded
> > [    1.188840] ehci-pci: EHCI PCI platform driver
> > [    1.232518] ohci-pci: OHCI PCI platform driver
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pci"
> in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> > .
> >
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 2/5] PCI: designware: Add ARM64 support
  2015-07-10  8:53         ` Gabriele Paoloni
@ 2015-07-10  9:36           ` Zhou Wang
  0 siblings, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-10  9:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/10 16:53, Gabriele Paoloni wrote:
> I have just sent this patch "[PATCH] Store PCIe controllers address in struct of_pci_range".
> 
> It would be needed by "pcie_designware.c" to retrieve the PCI controller addresses from "win->__res.start".
> 
> So we do not need to retrieve info from the DT parser anymore and we can use the new PCI DT parsing API
> 
> This problem was already discussed in this thread:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/317743.html
> 
> 

Hi Gab,

Thanks for your patch.

That means I can use something like: pp->io_mod_base = win->__res.start
to get io_mod_base, mem_mod_base and cfg0_mod_base.

will send my v4 series based on your patch.

Best regards,
Zhou

>> -----Original Message-----
>> From: Wangzhou (B)
>> Sent: Tuesday, July 07, 2015 4:44 AM
>> To: James Morse
>> Cc: Gabriele Paoloni; Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd
>> Bergmann; Liviu Dudau; kishon at ti.com; xobs at kosagi.com; m-
>> karicheri2 at ti.com; Minghuan.Lian at freescale.com; linux-
>> pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>> devicetree at vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>> qiuzhenfa; Liguozhu (Kenneth)
>> Subject: Re: [PATCH v3 2/5] PCI: designware: Add ARM64 support
>>
>> On 2015/7/1 22:26, James Morse wrote:
>>> Zhou Wang wrote:
>>>> I tested this patch on D02 board of Hisilicon. It works well.
>>>> I have compiled the driver with multi_v7_defconfig. However, I don't
>>>> have
>>>> ARM32 PCIe related board to do test. It will be appreciated if
>> someone
>>>> could
>>>> help to test it.
>>>>
>>>> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
>>>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>>>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>>>> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
>>>> Tested-by: James Morse <james.morse@arm.com>
>>>
>>> Tests on this new series, using the same i.MX 6Quad board, are not
>> working.
>>>
>>> The network card is no longer detected, and I get a lockup when
>> removing
>>> the root bridge and rescanning.
>>>
>>> Partial dmesg output below. Significantly, the lines:
>>>> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
>>>> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
>> [bus
>>> 00-ff]
>>> are new.
>>>
>>> Both series are applied to v4.1, use the same .config file, and the
>> same dtb.
>>> I will investigate further.
>>>
>>> (Re-testing v2 works, so this isn't an interim hardware failure)
>>>
>>> Thanks,
>>>
>>> James
>>>
>>
>> Hi James,
>>
>> There are something wrong with v3 patch.
>>
>> pp->io_mod_base = of_read_number(parser_range_end -
>> 		of_n_addr_cells(np) - 5 + na, ns);
>> pp->mem_mod_base = of_read_number(parser_range_end -
>> 		of_n_addr_cells(np) - 5 + na, ns);
>> pp->cfg0_mod_base = of_read_number(parser_range_end -
>> 		of_n_addr_cells(np) - 5 + na, ns);
>> are wrong.
>>
>> The ranges item in your dts is:
>> ranges = <0x800 0x0 0x1f00000 0x1f00000 0x0 0x80000
>> 	  0x81000000 0x0 0x0  0x1f80000 0x0 0x10000
>> 	  0x82000000 0x0 0x1000000 0x1000000 0x0 0xf00000>;
>> parser_range_end points to the end of ranges(0xf00000) directly. In v2
>> patch,
>> of_read_number is of_read_number(parser.range - parser.np + na, ns);
>> parser.range
>> points to the end of each line in ranges item.
>>
>> When I did test on D02 board with intel82599 card, I set ranges item as:
>> ranges = <0x03000000 0 0xb0000000 0x220 0x00000000 0 0xf000000>;
>> It is just one line. In this case, parser_range_end is same with
>> parser.range.
>> That is why it happened to work well on D02 board.
>>
>> very sorry to bother you about this problem.
>>
>> Thanks,
>> Zhou
>>
>>>
>>>
>>> root at localhost:~# dmesg | grep -i pci
>>> [    0.126184] PCI: CLS 0 bytes, default 64
>>> [    0.152128] PCI host bridge /soc/pcie at 0x01000000 ranges:
>>> [    0.152142]   No bus range found for /soc/pcie at 0x01000000, using
>> [bus 00-ff]
>>> [    0.154183] imx6q-pcie 1ffc000.pcie: PCI host bridge to bus
>> 0000:00
>>> [    0.154201] pci_bus 0000:00: root bus resource [bus 00-ff]
>>> [    0.154215] pci_bus 0000:00: root bus resource [???
>>> 0x01f00000-0x01f7ffff flags 0x0]
>>> [    0.154228] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
>>> [    0.154270] pci_bus 0000:00: root bus resource [mem 0x01000000-
>> 0x01efffff]
>>> [    0.154306] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
>>> [    0.154333] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
>>> [    0.154352] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff
>> pref]
>>> [    0.154377] pci 0000:00:00.0: IOMMU is currently not supported for
>> PCI
>>> [    0.154429] pci 0000:00:00.0: supports D1
>>> [    0.154440] pci 0000:00:00.0: PME# supported from D0 D1 D3hot
>> D3cold
>>> [    0.154683] PCI: bus0: Fast back to back transfers disabled
>>> [    0.154806] PCI: bus1: Fast back to back transfers enabled
>>> [    0.154884] pci 0000:00:00.0: BAR 0: assigned [mem 0x01000000-
>> 0x010fffff]
>>> [    0.154903] pci 0000:00:00.0: BAR 6: assigned [mem 0x01100000-
>> 0x0110ffff
>>> pref]
>>> [    0.154917] pci 0000:00:00.0: PCI bridge to [bus 01]
>>> [    0.155145] pcieport 0000:00:00.0: Signaling PME through PCIe PME
>> interrupt
>>> [    0.155161] pcie_pme 0000:00:00.0:pcie01: service driver pcie_pme
>> loaded
>>> [    0.155279] aer 0000:00:00.0:pcie02: service driver aer loaded
>>> [    1.188840] ehci-pci: EHCI PCI platform driver
>>> [    1.232518] ohci-pci: OHCI PCI platform driver
>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe linux-pci"
>> in
>>> the body of a message to majordomo at vger.kernel.org
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>> .
>>>
>>
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-07  9:22       ` Liviu Dudau
@ 2015-07-17 10:02         ` Gabriele Paoloni
  2015-07-21  3:26           ` Zhou Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Gabriele Paoloni @ 2015-07-17 10:02 UTC (permalink / raw)
  To: linux-arm-kernel

The following patch is maybe a better solution

Gab

-----------------------
This patch is needed in order to unify the PCIe designware
framework for ARM and ARM64 architectures.
In the PCIe designware unification process we are calling
pci_create_root_bus() passing a "sysdata" parameter
that is the same for both ARM and ARM64 and is of type
"struct pcie_port*". In the ARM case this will cause
a problem with the function pcibios_align_resource();
in fact this will cast "dev->sysdata" to "struct pci_sys_data*",
whereas designware had passed a "struct pcie_port*" pointer.

This patch solves the issue by removing "align_resource" from
"pci_sys_data" struct and defining a static global function pointer
in "bios32.c"

Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
---
 arch/arm/include/asm/mach/pci.h |  5 -----
 arch/arm/kernel/bios32.c        | 12 ++++++++----
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 28b9bb3..8a4e4de 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -58,11 +58,6 @@ struct pci_sys_data {
 					/* IRQ mapping				*/
 	int		(*map_irq)(const struct pci_dev *, u8, u8);
 					/* Resource alignement requirements	*/
-	resource_size_t (*align_resource)(struct pci_dev *dev,
-					  const struct resource *res,
-					  resource_size_t start,
-					  resource_size_t size,
-					  resource_size_t align);
 	void		*private_data;	/* platform controller private data	*/
 };
 
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index fcbbbb1..4cdc64d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -17,6 +17,11 @@
 #include <asm/mach/pci.h>
 
 static int debug_pci;
+static resource_size_t (*align_resource)(struct pci_dev *dev,
+		  const struct resource *res,
+		  resource_size_t start,
+		  resource_size_t size,
+		  resource_size_t align) = NULL;
 
 #ifdef CONFIG_PCI_MSI
 struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
@@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
 		sys->busnr   = busnr;
 		sys->swizzle = hw->swizzle;
 		sys->map_irq = hw->map_irq;
-		sys->align_resource = hw->align_resource;
+		align_resource = hw->align_resource;
 		INIT_LIST_HEAD(&sys->resources);
 
 		if (hw->private_data)
@@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 				resource_size_t size, resource_size_t align)
 {
 	struct pci_dev *dev = data;
-	struct pci_sys_data *sys = dev->sysdata;
 	resource_size_t start = res->start;
 
 	if (res->flags & IORESOURCE_IO && start & 0x300)
@@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 
 	start = (start + align - 1) & ~(align - 1);
 
-	if (sys->align_resource)
-		return sys->align_resource(dev, res, start, size, align);
+	if (align_resource)
+		return align_resource(dev, res, start, size, align);
 
 	return start;
 }
-- 
1.9.1

> -----Original Message-----
> From: linux-pci-owner at vger.kernel.org [mailto:linux-pci-
> owner at vger.kernel.org] On Behalf Of Liviu Dudau
> Sent: Tuesday, July 07, 2015 10:22 AM
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; Jingoo Han; Pratyush Anand; Arnd Bergmann; Gabriele
> Paoloni; James Morse; linux-pci at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; devicetree at vger.kernel.org; Yuanzhichang;
> Zhudacai; zhangjukuo; qiuzhenfa; Liguozhu (Kenneth)
> Subject: Re: [PATCH v3 1/5] ARM/PCI: remove align_resource callback in
> pcibios_align_resource
> 
> On Tue, Jul 07, 2015 at 06:44:01AM +0100, Zhou Wang wrote:
> > On 2015/7/3 1:50, Liviu Dudau wrote:
> > > On Wed, Jul 01, 2015 at 10:43:33AM +0100, Zhou Wang wrote:
> > >> This patch had added by Arnd Bergmann during last reviewing of v1
> patchset[1].
> > >>
> > >> PCI core codes call pcibios_align_resource(). In ARM specific one,
> it will
> > >> dereference pci_sys_data and call sys->align_resource. If we try
> to unify ARM
> > >> and ARM64 PCIe API in pcie-designware. it will bring kernel crash
> when run into
> > >> this dereferencing.
> > >>
> > >> However, in ARM there is only pci-mvebu which implements
> align_resource. So
> > >> add align_resource call back in pci_host_bridge structure and
> override
> > >> pcibios_align_resource with it.
> > >>
> > >> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > >> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> > >> Tested-by: Fabrice Gasnier <fabrice.gasnier@st.com>
> > >>
> > >> [1] http://www.spinics.net/lists/linux-pci/msg41671.html
> > >> ---
> > >>  arch/arm/kernel/bios32.c     |  6 ------
> > >>  drivers/pci/host/pci-mvebu.c | 47 ++++++++++++++++++++++++++++---
> -------------
> > >>  drivers/pci/setup-res.c      | 27 ++++++++++++++++++++-----
> > >>  include/linux/pci.h          |  3 +++
> > >>  4 files changed, 55 insertions(+), 28 deletions(-)
> > >>
> > >> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> > >> index fcbbbb1..b01189f 100644
> > >> --- a/arch/arm/kernel/bios32.c
> > >> +++ b/arch/arm/kernel/bios32.c
> > >> @@ -468,7 +468,6 @@ static void pcibios_init_hw(struct device
> *parent, struct hw_pci *hw,
> > >>  		sys->busnr   = busnr;
> > >>  		sys->swizzle = hw->swizzle;
> > >>  		sys->map_irq = hw->map_irq;
> > >> -		sys->align_resource = hw->align_resource;
> > >>  		INIT_LIST_HEAD(&sys->resources);
> > >>
> > >>  		if (hw->private_data)
> > >> @@ -588,8 +587,6 @@ char * __init pcibios_setup(char *str)
> > >>  resource_size_t pcibios_align_resource(void *data, const struct
> resource *res,
> > >>  				resource_size_t size, resource_size_t
> align)
> > >>  {
> > >> -	struct pci_dev *dev = data;
> > >> -	struct pci_sys_data *sys = dev->sysdata;
> > >>  	resource_size_t start = res->start;
> > >>
> > >>  	if (res->flags & IORESOURCE_IO && start & 0x300)
> > >> @@ -597,9 +594,6 @@ resource_size_t pcibios_align_resource(void
> *data, const struct resource *res,
> > >>
> > >>  	start = (start + align - 1) & ~(align - 1);
> > >>
> > >> -	if (sys->align_resource)
> > >> -		return sys->align_resource(dev, res, start, size,
> align);
> > >> -
> > >>  	return start;
> > >>  }
> > >>
> > >> diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-
> mvebu.c
> > >> index 1ab8635..155d05f 100644
> > >> --- a/drivers/pci/host/pci-mvebu.c
> > >> +++ b/drivers/pci/host/pci-mvebu.c
> > >> @@ -22,6 +22,8 @@
> > >>  #include <linux/of_pci.h>
> > >>  #include <linux/of_platform.h>
> > >>
> > >> +#include "../pci.h" /* HACK to see pci_find_host_bridge */
> > >> +
> > >>  /*
> > >>   * PCIe unit register offsets.
> > >>   */
> > >> @@ -751,27 +753,20 @@ static int mvebu_pcie_setup(int nr, struct
> pci_sys_data *sys)
> > >>  	return 1;
> > >>  }
> > >>
> > >> -static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct
> pci_sys_data *sys)
> > >> +static resource_size_t mvebu_pcie_align_resource(void *data,
> > >> +						 const struct resource *res,
> > >> +						 resource_size_t size,
> > >> +						 resource_size_t align)
> > >>  {
> > >> -	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> > >> -	struct pci_bus *bus;
> > >> +	struct pci_dev *dev = data;
> > >>
> > >> -	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> > >> -				  &mvebu_pcie_ops, sys, &sys->resources);
> > >> -	if (!bus)
> > >> -		return NULL;
> > >> +	resource_size_t start = res->start;
> > >>
> > >> -	pci_scan_child_bus(bus);
> > >> +	if (res->flags & IORESOURCE_IO && start & 0x300)
> > >> +		start = (start + 0x3ff) & ~0x3ff;
> > >>
> > >> -	return bus;
> > >> -}
> > >> +	start = (start + align - 1) & ~(align - 1);
> > >
> > > Honestly, I don't see here anything that is mvebu specific. Could
> you move
> >
> > What I mean is that there is only mvebu who implemented sys-
> >align_resource callback in ARM
> > arch.
> >
> > > this function in the generic pci/host area and have a flag in the
> pci_host_bridge
> > > structure whether the function should be called or not? I know that
> in a way
> > > that looks very close to the existing implementation which uses
> pcibios_align_resource,
> >
> > I am confused about "the existing implementation". Now
> pcibios_align_resource are
> > implemented by each arch code and are called directly. Did I miss
> anything about
> > pcibios_align_resource?
> 
> Sorry, I meant existing implementation_s_ and yes, I was reffering to
> the arch specific
> code. If you look at the cris, frv/mb93090-mb00, m68k, microblaze,
> powerpc, unicore32
> and x86 they all share the code with your version, plus or minus
> additional checks.
> I was thinking that for those arch versions that match your version you
> can create just
> one version and use it as the alignf function.
> 
> Best regards,
> Liviu
> 
> >
> > Best rgards,
> > Zhou
> >
> > > but the problem with pcibios_ version is that it is arch specific
> and not driver
> > > specific the way we want.
> > >
> > > Having this version as a generic implementation would also remove
> at least 2 more
> > > arch version, possibly more after testing by the arch maintainers.
> > >
> > > Best regards,
> > > Liviu
> > >
> > >>
> > >> -static resource_size_t mvebu_pcie_align_resource(struct pci_dev
> *dev,
> > >> -						 const struct resource *res,
> > >> -						 resource_size_t start,
> > >> -						 resource_size_t size,
> > >> -						 resource_size_t align)
> > >> -{
> > >>  	if (dev->bus->number != 0)
> > >>  		return start;
> > >>
> > >> @@ -796,6 +791,25 @@ static resource_size_t
> mvebu_pcie_align_resource(struct pci_dev *dev,
> > >>  		return start;
> > >>  }
> > >>
> > >> +static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct
> pci_sys_data *sys)
> > >> +{
> > >> +	struct mvebu_pcie *pcie = sys_to_pcie(sys);
> > >> +	struct pci_host_bridge *phb;
> > >> +	struct pci_bus *bus;
> > >> +
> > >> +	bus = pci_create_root_bus(&pcie->pdev->dev, sys->busnr,
> > >> +				  &mvebu_pcie_ops, sys, &sys->resources);
> > >> +	if (!bus)
> > >> +		return NULL;
> > >> +
> > >> +	phb = pci_find_host_bridge(bus);
> > >> +	phb->align_resource = mvebu_pcie_align_resource;
> > >> +
> > >> +	pci_scan_child_bus(bus);
> > >> +
> > >> +	return bus;
> > >> +}
> > >> +
> > >>  static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
> > >>  {
> > >>  	struct hw_pci hw;
> > >> @@ -812,7 +826,6 @@ static void mvebu_pcie_enable(struct
> mvebu_pcie *pcie)
> > >>  	hw.scan           = mvebu_pcie_scan_bus;
> > >>  	hw.map_irq        = of_irq_parse_and_map_pci;
> > >>  	hw.ops            = &mvebu_pcie_ops;
> > >> -	hw.align_resource = mvebu_pcie_align_resource;
> > >>
> > >>  	pci_common_init(&hw);
> > >>  }
> > >> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> > >> index 232f925..73abca7 100644
> > >> --- a/drivers/pci/setup-res.c
> > >> +++ b/drivers/pci/setup-res.c
> > >> @@ -200,7 +200,11 @@ static int pci_revert_fw_address(struct
> resource *res, struct pci_dev *dev,
> > >>  }
> > >>
> > >>  static int __pci_assign_resource(struct pci_bus *bus, struct
> pci_dev *dev,
> > >> -		int resno, resource_size_t size, resource_size_t
> align)
> > >> +		int resno, resource_size_t size, resource_size_t
> align,
> > >> +		resource_size_t (*alignf)(void *,
> > >> +					  const struct resource *,
> > >> +					  resource_size_t,
> > >> +					  resource_size_t))
> > >>  {
> > >>  	struct resource *res = dev->resource + resno;
> > >>  	resource_size_t min;
> > >> @@ -217,7 +221,7 @@ static int __pci_assign_resource(struct
> pci_bus *bus, struct pci_dev *dev,
> > >>  	 */
> > >>  	ret = pci_bus_alloc_resource(bus, res, size, align, min,
> > >>  				     IORESOURCE_PREFETCH |
> IORESOURCE_MEM_64,
> > >> -				     pcibios_align_resource, dev);
> > >> +				     alignf, dev);
> > >>  	if (ret == 0)
> > >>  		return 0;
> > >>
> > >> @@ -229,7 +233,7 @@ static int __pci_assign_resource(struct
> pci_bus *bus, struct pci_dev *dev,
> > >>  	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
> > >>  		ret = pci_bus_alloc_resource(bus, res, size, align,
> min,
> > >>  					     IORESOURCE_PREFETCH,
> > >> -					     pcibios_align_resource, dev);
> > >> +					     alignf, dev);
> > >>  		if (ret == 0)
> > >>  			return 0;
> > >>  	}
> > >> @@ -242,7 +246,7 @@ static int __pci_assign_resource(struct
> pci_bus *bus, struct pci_dev *dev,
> > >>  	 */
> > >>  	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
> > >>  		ret = pci_bus_alloc_resource(bus, res, size, align,
> min, 0,
> > >> -					     pcibios_align_resource, dev);
> > >> +					     alignf, dev);
> > >>
> > >>  	return ret;
> > >>  }
> > >> @@ -251,10 +255,23 @@ static int _pci_assign_resource(struct
> pci_dev *dev, int resno,
> > >>  				resource_size_t size, resource_size_t
> min_align)
> > >>  {
> > >>  	struct pci_bus *bus;
> > >> +	struct pci_host_bridge *phb;
> > >> +	resource_size_t (*alignf)(void *,
> > >> +				  const struct resource *,
> > >> +				  resource_size_t,
> > >> +				  resource_size_t);
> > >>  	int ret;
> > >>
> > >>  	bus = dev->bus;
> > >> -	while ((ret = __pci_assign_resource(bus, dev, resno, size,
> min_align))) {
> > >> +	phb = pci_find_host_bridge(bus);
> > >> +
> > >> +	if (phb->align_resource)
> > >> +		alignf = phb->align_resource;
> > >> +	else
> > >> +		alignf = pcibios_align_resource;
> > >> +
> > >> +	while ((ret = __pci_assign_resource(bus, dev, resno, size,
> > >> +					    min_align, alignf))) {
> > >>  		if (!bus->parent || !bus->self->transparent)
> > >>  			break;
> > >>  		bus = bus->parent;
> > >> diff --git a/include/linux/pci.h b/include/linux/pci.h
> > >> index 353db8d..39e48fc 100644
> > >> --- a/include/linux/pci.h
> > >> +++ b/include/linux/pci.h
> > >> @@ -404,6 +404,9 @@ struct pci_host_bridge {
> > >>  	struct device dev;
> > >>  	struct pci_bus *bus;		/* root bus */
> > >>  	struct list_head windows;	/* resource_entry */
> > >> +	resource_size_t (*align_resource)(void *data,
> > >> +			 const struct resource *res,
> > >> +			 resource_size_t size, resource_size_t align);
> > >>  	void (*release_fn)(struct pci_host_bridge *);
> > >>  	void *release_data;
> > >>  	unsigned int ignore_reset_delay:1;	/* for entire hierarchy
> */
> > >> --
> > >> 1.9.1
> > >>
> > >
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-pci"
> in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> 
> --
> ====================
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---------------
>     ?\_(?)_/?
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource
  2015-07-17 10:02         ` Gabriele Paoloni
@ 2015-07-21  3:26           ` Zhou Wang
  0 siblings, 0 replies; 22+ messages in thread
From: Zhou Wang @ 2015-07-21  3:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/7/17 18:02, Gabriele Paoloni wrote:
> The following patch is maybe a better solution
> 
> Gab
>

Hi Gab,

Many thanks for your patch, I think this patch is cleaner than 1/4 in v2 patchset.
I will merge this one in my new series.

Thanks?
Zhou

> -----------------------
> This patch is needed in order to unify the PCIe designware
> framework for ARM and ARM64 architectures.
> In the PCIe designware unification process we are calling
> pci_create_root_bus() passing a "sysdata" parameter
> that is the same for both ARM and ARM64 and is of type
> "struct pcie_port*". In the ARM case this will cause
> a problem with the function pcibios_align_resource();
> in fact this will cast "dev->sysdata" to "struct pci_sys_data*",
> whereas designware had passed a "struct pcie_port*" pointer.
> 
> This patch solves the issue by removing "align_resource" from
> "pci_sys_data" struct and defining a static global function pointer
> in "bios32.c"
> 
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> ---
>  arch/arm/include/asm/mach/pci.h |  5 -----
>  arch/arm/kernel/bios32.c        | 12 ++++++++----
>  2 files changed, 8 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
> index 28b9bb3..8a4e4de 100644
> --- a/arch/arm/include/asm/mach/pci.h
> +++ b/arch/arm/include/asm/mach/pci.h
> @@ -58,11 +58,6 @@ struct pci_sys_data {
>  					/* IRQ mapping				*/
>  	int		(*map_irq)(const struct pci_dev *, u8, u8);
>  					/* Resource alignement requirements	*/
> -	resource_size_t (*align_resource)(struct pci_dev *dev,
> -					  const struct resource *res,
> -					  resource_size_t start,
> -					  resource_size_t size,
> -					  resource_size_t align);
>  	void		*private_data;	/* platform controller private data	*/
>  };
>  
> diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
> index fcbbbb1..4cdc64d 100644
> --- a/arch/arm/kernel/bios32.c
> +++ b/arch/arm/kernel/bios32.c
> @@ -17,6 +17,11 @@
>  #include <asm/mach/pci.h>
>  
>  static int debug_pci;
> +static resource_size_t (*align_resource)(struct pci_dev *dev,
> +		  const struct resource *res,
> +		  resource_size_t start,
> +		  resource_size_t size,
> +		  resource_size_t align) = NULL;
>  
>  #ifdef CONFIG_PCI_MSI
>  struct msi_controller *pcibios_msi_controller(struct pci_dev *dev)
> @@ -468,7 +473,7 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
>  		sys->busnr   = busnr;
>  		sys->swizzle = hw->swizzle;
>  		sys->map_irq = hw->map_irq;
> -		sys->align_resource = hw->align_resource;
> +		align_resource = hw->align_resource;
>  		INIT_LIST_HEAD(&sys->resources);
>  
>  		if (hw->private_data)
> @@ -589,7 +594,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  				resource_size_t size, resource_size_t align)
>  {
>  	struct pci_dev *dev = data;
> -	struct pci_sys_data *sys = dev->sysdata;
>  	resource_size_t start = res->start;
>  
>  	if (res->flags & IORESOURCE_IO && start & 0x300)
> @@ -597,8 +601,8 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
>  
>  	start = (start + align - 1) & ~(align - 1);
>  
> -	if (sys->align_resource)
> -		return sys->align_resource(dev, res, start, size, align);
> +	if (align_resource)
> +		return align_resource(dev, res, start, size, align);
>  
>  	return start;
>  }
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2015-07-21  3:26 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-01  9:43 [PATCH v3 0/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
2015-07-01  9:43 ` [PATCH v3 1/5] ARM/PCI: remove align_resource callback in pcibios_align_resource Zhou Wang
2015-07-02 17:50   ` Liviu Dudau
2015-07-07  5:44     ` Zhou Wang
2015-07-07  9:22       ` Liviu Dudau
2015-07-17 10:02         ` Gabriele Paoloni
2015-07-21  3:26           ` Zhou Wang
2015-07-01  9:43 ` [PATCH v3 2/5] PCI: designware: Add ARM64 support Zhou Wang
2015-07-01 13:29   ` Gabriele Paoloni
2015-07-01 14:26     ` James Morse
2015-07-01 16:47       ` Gabriele Paoloni
2015-07-01 17:32         ` James Morse
2015-07-02  1:38           ` Zhou Wang
2015-07-02  7:24           ` Gabriele Paoloni
2015-07-02 17:40             ` James Morse
2015-07-07  3:44       ` Zhou Wang
2015-07-10  8:53         ` Gabriele Paoloni
2015-07-10  9:36           ` Zhou Wang
2015-07-02  1:16     ` Zhou Wang
2015-07-01  9:43 ` [PATCH v3 3/5] PCI: hisi: Add PCIe host support for Hisilicon Soc Hip05 Zhou Wang
2015-07-01  9:43 ` [PATCH v3 4/5] Documentation: DT: Add Hisilicon PCIe host binding Zhou Wang
2015-07-01  9:43 ` [PATCH v3 5/5] MAINTAINERS: Add pcie-hisi maintainer Zhou Wang

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).