All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-08-25  9:58 ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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.

This patchset is based on v4.2-rc1.

Change from v7:
- Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
- Remove bus-range parsing in pcie-hisi.c.

Change from v6:
- Add Pratyush's Acked-by for 1/6 and 2/6.
- Add James' Tested-by for 3/6.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

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 v7:
- http://www.spinics.net/lists/devicetree/msg90690.html
Link of v6:
- http://www.spinics.net/lists/linux-pci/msg43669.html
Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
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

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html


Zhou Wang (4):
  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

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  13 ++
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 247 +++++++++++++++++++++
 11 files changed, 413 insertions(+), 179 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] 37+ messages in thread

* [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-08-25  9:58 ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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.

This patchset is based on v4.2-rc1.

Change from v7:
- Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
- Remove bus-range parsing in pcie-hisi.c.

Change from v6:
- Add Pratyush's Acked-by for 1/6 and 2/6.
- Add James' Tested-by for 3/6.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

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 v7:
- http://www.spinics.net/lists/devicetree/msg90690.html
Link of v6:
- http://www.spinics.net/lists/linux-pci/msg43669.html
Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
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

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html


Zhou Wang (4):
  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

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  13 ++
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 247 +++++++++++++++++++++
 11 files changed, 413 insertions(+), 179 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] 37+ messages in thread

* [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-08-25  9:58 ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 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.

This patchset is based on v4.2-rc1.

Change from v7:
- Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
  spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
- Remove bus-range parsing in pcie-hisi.c.

Change from v6:
- Add Pratyush's Acked-by for 1/6 and 2/6.
- Add James' Tested-by for 3/6.

Change from v5:
- Merge 1/6 in this series, discussion about this can be found in [1]

Change from v4:
- Change the author of 1/5 to Gabriele.
- Modify problems in 3/5 pointed by Bjorn.
- Modify spelling problems in 4/5.

Change from v3:
- Change 1/5 to what Gabriele suggested.
- Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.

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 v7:
- http://www.spinics.net/lists/devicetree/msg90690.html
Link of v6:
- http://www.spinics.net/lists/linux-pci/msg43669.html
Link of v5:
- http://www.spinics.net/lists/devicetree/msg87959.html
Link of v4:
- http://www.spinics.net/lists/arm-kernel/msg433050.html
Link of v3:
- http://www.spinics.net/lists/linux-pci/msg42539.html
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

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/359741.html


Zhou Wang (4):
  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

gabriele paoloni (2):
  PCI: designware: move calculation of bus addresses to DRA7xx
  ARM/PCI: remove align_resource in pci_sys_data

 .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
 MAINTAINERS                                        |   7 +
 arch/arm/include/asm/mach/pci.h                    |   5 -
 arch/arm/kernel/bios32.c                           |  12 +-
 drivers/pci/host/Kconfig                           |   8 +
 drivers/pci/host/Makefile                          |   1 +
 drivers/pci/host/pci-dra7xx.c                      |  13 ++
 drivers/pci/host/pci-keystone-dw.c                 |   2 +-
 drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
 drivers/pci/host/pcie-designware.h                 |  14 +-
 drivers/pci/host/pcie-hisi.c                       | 247 +++++++++++++++++++++
 11 files changed, 413 insertions(+), 179 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] 37+ messages in thread

* [PATCH v8 1/6] PCI: designware: move calculation of bus addresses to DRA7xx
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

From: gabriele paoloni <gabriele.paoloni@huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1

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

* [PATCH v8 1/6] PCI: designware: move calculation of bus addresses to DRA7xx
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

From: gabriele paoloni <gabriele.paoloni@huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1


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

* [PATCH v8 1/6] PCI: designware: move calculation of bus addresses to DRA7xx
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: gabriele paoloni <gabriele.paoloni@huawei.com>

Commit f4c55c5a3f7f "PCI: designware: Program ATU with untranslated
address" added the calculation of PCI BUS addresses in designware,
storing them in new fields added in "struct pcie_port". This
calculation is done for every designware user even if is only
applicable to DRA7xx.
This patch moves the calculation of the bus addresses to the DRA7xx
driver and is needed to allow the rework of designware to use
the new DT parsing API.

Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
---
 drivers/pci/host/pci-dra7xx.c      | 13 +++++++++++++
 drivers/pci/host/pcie-designware.c | 15 ++++-----------
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 80db09e..18ae7ff 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -61,6 +61,7 @@
 
 #define	PCIECTRL_DRA7XX_CONF_PHY_CS			0x010C
 #define	LINK_UP						BIT(16)
+#define	CPU_TO_BUS_ADDR					0x0FFFFFFF
 
 struct dra7xx_pcie {
 	void __iomem		*base;
@@ -139,6 +140,18 @@ static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
 static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
+
+	if (pp->io_mod_base)
+		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->mem_mod_base)
+		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+
+	if (pp->cfg0_mod_base) {
+		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	}
+
 	dra7xx_pcie_establish_link(pp);
 	if (IS_ENABLED(CONFIG_PCI_MSI))
 		dw_pcie_msi_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be..c5d407c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -366,14 +366,10 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	struct of_pci_range range;
 	struct of_pci_range_parser parser;
 	struct resource *cfg_res;
-	u32 val, na, ns;
+	u32 val, ns;
 	const __be32 *addrp;
 	int i, index, ret;
 
-	/* Find the address cell size and the number of cells in order to get
-	 * the untranslated address.
-	 */
-	of_property_read_u32(np, "#address-cells", &na);
 	ns = of_n_size_cells(np);
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
@@ -416,8 +412,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->io_mod_base = range.cpu_addr;
 		}
 		if (restype == IORESOURCE_MEM) {
 			of_pci_range_to_resource(&range, np, &pp->mem);
@@ -426,8 +421,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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);
+			pp->mem_mod_base = range.cpu_addr;
 		}
 		if (restype == 0) {
 			of_pci_range_to_resource(&range, np, &pp->cfg);
@@ -437,8 +431,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 			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->cfg0_mod_base = range.cpu_addr;
 			pp->cfg1_mod_base = pp->cfg0_mod_base +
 					    pp->cfg0_size;
 		}
-- 
1.9.1

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

* [PATCH v8 2/6] ARM/PCI: remove align_resource in pci_sys_data
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu

From: gabriele paoloni <gabriele.paoloni@huawei.com>

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>
Acked-by: Pratyush Anand <pratyush.anand@gmail.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

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

* [PATCH v8 2/6] ARM/PCI: remove align_resource in pci_sys_data
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu

From: gabriele paoloni <gabriele.paoloni@huawei.com>

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>
Acked-by: Pratyush Anand <pratyush.anand@gmail.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


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

* [PATCH v8 2/6] ARM/PCI: remove align_resource in pci_sys_data
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

From: gabriele paoloni <gabriele.paoloni@huawei.com>

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>
Acked-by: Pratyush Anand <pratyush.anand@gmail.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

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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-By: James Morse <james.morse@arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  14 +--
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 4 files changed, 90 insertions(+), 170 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..ac401be 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e2d1898 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>
@@ -69,16 +70,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)
 {
@@ -255,7 +247,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));
@@ -298,7 +290,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;
@@ -327,7 +319,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);
 }
@@ -363,14 +355,12 @@ int 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;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		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 = range.cpu_addr;
-		}
-		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 = range.cpu_addr;
-		}
-		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;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    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;
+			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;
+			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;
+			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,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	pp->root_bus_nr = pp->busn->start;
+	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
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	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);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +606,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) {
@@ -650,7 +630,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)
@@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	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..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	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;
-- 
1.9.1

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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-By: James Morse <james.morse@arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  14 +--
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 4 files changed, 90 insertions(+), 170 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..ac401be 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e2d1898 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>
@@ -69,16 +70,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)
 {
@@ -255,7 +247,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));
@@ -298,7 +290,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;
@@ -327,7 +319,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);
 }
@@ -363,14 +355,12 @@ int 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;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		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 = range.cpu_addr;
-		}
-		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 = range.cpu_addr;
-		}
-		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;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    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;
+			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;
+			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;
+			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,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	pp->root_bus_nr = pp->busn->start;
+	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
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	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);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +606,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) {
@@ -650,7 +630,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)
@@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	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..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	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;
-- 
1.9.1


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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 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.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-By: James Morse <james.morse@arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  14 +--
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 4 files changed, 90 insertions(+), 170 deletions(-)

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..ac401be 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e2d1898 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>
@@ -69,16 +70,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)
 {
@@ -255,7 +247,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));
@@ -298,7 +290,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;
@@ -327,7 +319,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);
 }
@@ -363,14 +355,12 @@ int 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;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		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 = range.cpu_addr;
-		}
-		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 = range.cpu_addr;
-		}
-		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;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    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;
+			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;
+			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;
+			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,
@@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	pp->root_bus_nr = pp->busn->start;
+	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
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	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);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +606,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) {
@@ -650,7 +630,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)
@@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	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..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@ struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	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;
-- 
1.9.1

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

* [PATCH v8 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

This patch adds PCIe host support for HiSilicon SoC Hip05.

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

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ 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_PCIE_IPROC_BCMA) += pcie-iproc-bcma.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..10e8eaa
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,247 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * 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/irqdomain.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 PCIe devices 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;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "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: %d\n", port_id);
+		return -EINVAL;
+	}
+	hisi_pcie->port_id = port_id;
+
+	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 rc_dbi 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)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+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",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1

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

* [PATCH v8 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

This patch adds PCIe host support for HiSilicon SoC Hip05.

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

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ 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_PCIE_IPROC_BCMA) += pcie-iproc-bcma.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..10e8eaa
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,247 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * 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/irqdomain.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 PCIe devices 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;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "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: %d\n", port_id);
+		return -EINVAL;
+	}
+	hisi_pcie->port_id = port_id;
+
+	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 rc_dbi 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)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+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",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1


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

* [PATCH v8 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 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     |   8 ++
 drivers/pci/host/Makefile    |   1 +
 drivers/pci/host/pcie-hisi.c | 247 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 256 insertions(+)
 create mode 100644 drivers/pci/host/pcie-hisi.c

diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index c132bdd..cd2b80b 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -145,4 +145,12 @@ config PCIE_IPROC_BCMA
 	  Say Y here if you want to use the Broadcom iProc PCIe controller
 	  through the BCMA bus interface
 
+config PCI_HISI
+	depends on OF && ARM64
+	bool "HiSilicon SoC HIP05 PCIe controller"
+	select PCIEPORTBUS
+	select PCIE_DW
+	help
+	  Say Y here if you want PCIe controller support on HiSilicon HIP05 SoC
+
 endmenu
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..ea1dbf2 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -17,3 +17,4 @@ 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_PCIE_IPROC_BCMA) += pcie-iproc-bcma.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..10e8eaa
--- /dev/null
+++ b/drivers/pci/host/pcie-hisi.c
@@ -0,0 +1,247 @@
+/*
+ * PCIe host controller driver for HiSilicon Hip05 SoC
+ *
+ * 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/irqdomain.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 PCIe devices 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;
+
+	msi_node = of_parse_phandle(np, "msi-parent", 0);
+	if (!msi_node) {
+		dev_err(pp->dev, "failed to find msi-parent\n");
+		return -ENODEV;
+	}
+
+	irq_domain = irq_find_host(msi_node);
+	if (!irq_domain) {
+		dev_err(pp->dev, "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: %d\n", port_id);
+		return -EINVAL;
+	}
+	hisi_pcie->port_id = port_id;
+
+	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 rc_dbi 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)
+		return ret;
+
+	platform_set_drvdata(pdev, hisi_pcie);
+
+	return 0;
+}
+
+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",
+		   .of_match_table = hisi_pcie_of_match,
+	},
+};
+
+module_platform_driver(hisi_pcie_driver);
-- 
1.9.1

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

* [PATCH v8 5/6] Documentation: DT: Add HiSilicon PCIe host binding
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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..2afc9d1
--- /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@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] 37+ messages in thread

* [PATCH v8 5/6] Documentation: DT: Add HiSilicon PCIe host binding
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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..2afc9d1
--- /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@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] 37+ messages in thread

* [PATCH v8 5/6] Documentation: DT: Add HiSilicon PCIe host binding
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 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..2afc9d1
--- /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] 37+ messages in thread

* [PATCH v8 6/6] MAINTAINERS: Add pcie-hisi maintainer
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-08-25  9:58   ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1@hisilicon.com>
+L:	linux-pci@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@lists.infradead.org
-- 
1.9.1

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

* [PATCH v8 6/6] MAINTAINERS: Add pcie-hisi maintainer
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 UTC (permalink / raw)
  To: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, gabriele.paoloni, lorenzo.pieralisi,
	james.morse, Liviu.Dudau, jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong3, qiujiang, xuwei5, liguozhu, Zhou Wang

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

diff --git a/MAINTAINERS b/MAINTAINERS
index 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+PCIE DRIVER FOR HISILICON
+M:	Zhou Wang <wangzhou1@hisilicon.com>
+L:	linux-pci@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@lists.infradead.org
-- 
1.9.1


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

* [PATCH v8 6/6] MAINTAINERS: Add pcie-hisi maintainer
@ 2015-08-25  9:58   ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-25  9:58 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 8133cef..7cd8e47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7854,6 +7854,13 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/pci/xgene-pci-msi.txt
 F:	drivers/pci/host/pci-xgene-msi.c
 
+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] 37+ messages in thread

* Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-08-25  9:58   ` Zhou Wang
@ 2015-08-27 12:56     ` Gabriel Fernandez
  -1 siblings, 0 replies; 37+ messages in thread
From: Gabriel Fernandez @ 2015-08-27 12:56 UTC (permalink / raw)
  To: Zhou Wang
  Cc: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann,
	Russell King, thomas.petazzoni, gabriele.paoloni,
	lorenzo.pieralisi, james.morse, Liviu Dudau, jason, robh,
	devicetree, linux-pci, xuwei5, qiuzhenfa, liudongdong3,
	zhangjukuo, liguozhu, qiujiang, linux-arm-kernel

Hi Zhou,

You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>

I tested your patchset with a STMicroelectronics PCIe controller.
This controller is based on designware PCIe driver and works on ARM32.

Please find my patchset here:
http://www.spinics.net/lists/kernel/msg2064266.html

Best Regards.

Gabriel.

On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> 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.
>
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
>
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
>
> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Tested-By: James Morse <james.morse@arm.com>
>
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  4 files changed, 90 insertions(+), 170 deletions(-)
>
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..ac401be 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>         dw_pcie_setup_rc(pp);
>
> -       if (pp->io_mod_base)
> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->io_base)
> +               pp->io_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->mem_mod_base)
> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->mem_base)
> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->cfg0_mod_base) {
> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->cfg0_base) {
> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>         }
>
>         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e2d1898 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>
> @@ -69,16 +70,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)
>  {
> @@ -255,7 +247,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));
> @@ -298,7 +290,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;
> @@ -327,7 +319,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);
>  }
> @@ -363,14 +355,12 @@ int 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;
> -       u32 val, ns;
> -       const __be32 *addrp;
> -       int i, index, ret;
> -
> -       ns = of_n_size_cells(np);
> +       LIST_HEAD(res);
> +       u32 val;
> +       int i, ret;
> +       struct resource_entry *win;
>
>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>         if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>                 pp->cfg1_size = resource_size(cfg_res)/2;
>                 pp->cfg0_base = cfg_res->start;
>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -               /* Find the untranslated configuration space address */
> -               index = of_property_match_string(np, "reg-names", "config");
> -               addrp = of_get_address(np, index, NULL, NULL);
> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>         } else {
>                 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 = range.cpu_addr;
> -               }
> -               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 = range.cpu_addr;
> -               }
> -               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;
> -
> -                       /* Find the untranslated configuration space address */
> -                       pp->cfg0_mod_base = range.cpu_addr;
> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> -                                           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;
> +                       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;
> +                       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;
> +                       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,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>
>         if (!pp->ops->rd_other_conf)
>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>                                           pp->mem_bus_addr, pp->mem_size);
>
>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>         val |= PORT_LOGIC_SPEED_CHANGE;
>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>
> -#ifdef CONFIG_PCI_MSI
> +       pp->root_bus_nr = pp->busn->start;
> +       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
>         dw_pcie_msi_chip.dev = pp->dev;
> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +       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);
> +
> +#ifdef CONFIG_ARM
> +       /* support old dtbs that incorrectly describe IRQs */
> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>
> -       pci_common_init_dev(pp->dev, &dw_pci);
> +       pci_assign_unassigned_bus_resources(bus);
> +       pci_bus_add_devices(bus);
>
>         return 0;
>  }
> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -626,7 +606,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) {
> @@ -650,7 +630,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)
> @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> -                                 &dw_pcie_ops, sys, &sys->resources);
> -       if (!bus)
> -               return NULL;
> -
> -       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..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>         u8                      root_bus_nr;
>         void __iomem            *dbi_base;
>         u64                     cfg0_base;
> -       u64                     cfg0_mod_base;
>         void __iomem            *va_cfg0_base;
>         u32                     cfg0_size;
>         u64                     cfg1_base;
> -       u64                     cfg1_mod_base;
>         void __iomem            *va_cfg1_base;
>         u32                     cfg1_size;
> -       u64                     io_base;
> -       u64                     io_mod_base;
> +       resource_size_t         io_base;
>         phys_addr_t             io_bus_addr;
>         u32                     io_size;
>         u64                     mem_base;
> -       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;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-27 12:56     ` Gabriel Fernandez
  0 siblings, 0 replies; 37+ messages in thread
From: Gabriel Fernandez @ 2015-08-27 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Zhou,

You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>

I tested your patchset with a STMicroelectronics PCIe controller.
This controller is based on designware PCIe driver and works on ARM32.

Please find my patchset here:
http://www.spinics.net/lists/kernel/msg2064266.html

Best Regards.

Gabriel.

On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> 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.
>
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
>
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
>
> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Tested-By: James Morse <james.morse@arm.com>
>
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  4 files changed, 90 insertions(+), 170 deletions(-)
>
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..ac401be 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>         dw_pcie_setup_rc(pp);
>
> -       if (pp->io_mod_base)
> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->io_base)
> +               pp->io_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->mem_mod_base)
> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->mem_base)
> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>
> -       if (pp->cfg0_mod_base) {
> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +       if (pp->cfg0_base) {
> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>         }
>
>         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e2d1898 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>
> @@ -69,16 +70,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)
>  {
> @@ -255,7 +247,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));
> @@ -298,7 +290,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;
> @@ -327,7 +319,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);
>  }
> @@ -363,14 +355,12 @@ int 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;
> -       u32 val, ns;
> -       const __be32 *addrp;
> -       int i, index, ret;
> -
> -       ns = of_n_size_cells(np);
> +       LIST_HEAD(res);
> +       u32 val;
> +       int i, ret;
> +       struct resource_entry *win;
>
>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>         if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>                 pp->cfg1_size = resource_size(cfg_res)/2;
>                 pp->cfg0_base = cfg_res->start;
>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -               /* Find the untranslated configuration space address */
> -               index = of_property_match_string(np, "reg-names", "config");
> -               addrp = of_get_address(np, index, NULL, NULL);
> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>         } else {
>                 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 = range.cpu_addr;
> -               }
> -               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 = range.cpu_addr;
> -               }
> -               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;
> -
> -                       /* Find the untranslated configuration space address */
> -                       pp->cfg0_mod_base = range.cpu_addr;
> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> -                                           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;
> +                       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;
> +                       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;
> +                       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,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>
>         if (!pp->ops->rd_other_conf)
>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>                                           pp->mem_bus_addr, pp->mem_size);
>
>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>         val |= PORT_LOGIC_SPEED_CHANGE;
>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>
> -#ifdef CONFIG_PCI_MSI
> +       pp->root_bus_nr = pp->busn->start;
> +       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
>         dw_pcie_msi_chip.dev = pp->dev;
> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +       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);
> +
> +#ifdef CONFIG_ARM
> +       /* support old dtbs that incorrectly describe IRQs */
> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>
> -       pci_common_init_dev(pp->dev, &dw_pci);
> +       pci_assign_unassigned_bus_resources(bus);
> +       pci_bus_add_devices(bus);
>
>         return 0;
>  }
> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>
>         if (bus->parent->number == pp->root_bus_nr) {
>                 type = PCIE_ATU_TYPE_CFG0;
> -               cpu_addr = pp->cfg0_mod_base;
> +               cpu_addr = pp->cfg0_base;
>                 cfg_size = pp->cfg0_size;
>                 va_cfg_base = pp->va_cfg0_base;
>         } else {
>                 type = PCIE_ATU_TYPE_CFG1;
> -               cpu_addr = pp->cfg1_mod_base;
> +               cpu_addr = pp->cfg1_base;
>                 cfg_size = pp->cfg1_size;
>                 va_cfg_base = pp->va_cfg1_base;
>         }
> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>                                   busdev, cfg_size);
>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>                                   pp->io_bus_addr, pp->io_size);
>
>         return ret;
> @@ -626,7 +606,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) {
> @@ -650,7 +630,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)
> @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> -                                 &dw_pcie_ops, sys, &sys->resources);
> -       if (!bus)
> -               return NULL;
> -
> -       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..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>         u8                      root_bus_nr;
>         void __iomem            *dbi_base;
>         u64                     cfg0_base;
> -       u64                     cfg0_mod_base;
>         void __iomem            *va_cfg0_base;
>         u32                     cfg0_size;
>         u64                     cfg1_base;
> -       u64                     cfg1_mod_base;
>         void __iomem            *va_cfg1_base;
>         u32                     cfg1_size;
> -       u64                     io_base;
> -       u64                     io_mod_base;
> +       resource_size_t         io_base;
>         phys_addr_t             io_bus_addr;
>         u32                     io_size;
>         u64                     mem_base;
> -       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;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* RE: [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-08-27 12:56     ` Gabriel Fernandez
  (?)
@ 2015-08-27 15:21         ` Gabriele Paoloni
  -1 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-08-27 15:21 UTC (permalink / raw)
  To: Gabriel Fernandez, Wangzhou (B)
  Cc: Bjorn Helgaas, jingoohan1-Re5JQEeQqe8AvxtiuMwx3w,
	pratyush.anand-Re5JQEeQqe8AvxtiuMwx3w, Arnd Bergmann,
	Russell King, thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	lorenzo.pieralisi-5wv7dgnIgG8, james.morse-5wv7dgnIgG8,
	Liviu Dudau, jason-NLaQJdtUoK4Be96aLqz0jA,
	robh-DgEjT+Ai2ygdnm+yROfE0A, devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, xuwei (O),
	qiuzhenfa, liudongdong (C), zhangjukuo, Liguozhu (Kenneth),
	qiujiang, linux-arm-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 23357 bytes --]

> -----Original Message-----
> From: linux-pci-owner@vger.kernel.org [mailto:linux-pci-owner@vger.kernel.org]
> On Behalf Of Gabriel Fernandez
> Sent: 27 August 2015 13:57
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; jingoohan1@gmail.com; pratyush.anand@gmail.com; Arnd
> Bergmann; Russell King; thomas.petazzoni@free-electrons.com; Gabriele Paoloni;
> lorenzo.pieralisi@arm.com; james.morse@arm.com; Liviu Dudau;
> jason@lakedaemon.net; robh@kernel.org; devicetree@vger.kernel.org; linux-
> pci@vger.kernel.org; xuwei (O); qiuzhenfa; liudongdong (C); zhangjukuo;
> Liguozhu (Kenneth); qiujiang; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
> 
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.

Many Thanks for this Gabriel

Cheers
Gab

> 
> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> > 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.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
> ARM64
> > according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> > with untranslated address" based on 1/6 in this series. we delete *_mod_base
> in
> > pcie-designware. This was discussed in [2]
> >
> > 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Tested-By: James Morse <james.morse@arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  14 +--
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pcie-designware.c | 230 +++++++++++++---------------------
> ---
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  4 files changed, 90 insertions(+), 170 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> > index 18ae7ff..ac401be 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
> >  {
> >         dw_pcie_setup_rc(pp);
> >
> > -       if (pp->io_mod_base)
> > -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->io_base)
> > +               pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->mem_mod_base)
> > -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->mem_base)
> > +               pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->cfg0_mod_base) {
> > -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->cfg0_base) {
> > +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >         }
> >
> >         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-
> designware.c
> > index c5d407c..e2d1898 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>
> > @@ -69,16 +70,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)
> >  {
> > @@ -255,7 +247,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));
> > @@ -298,7 +290,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;
> > @@ -327,7 +319,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);
> >  }
> > @@ -363,14 +355,12 @@ int 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;
> > -       u32 val, ns;
> > -       const __be32 *addrp;
> > -       int i, index, ret;
> > -
> > -       ns = of_n_size_cells(np);
> > +       LIST_HEAD(res);
> > +       u32 val;
> > +       int i, ret;
> > +       struct resource_entry *win;
> >
> >         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "config");
> >         if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                 pp->cfg1_size = resource_size(cfg_res)/2;
> >                 pp->cfg0_base = cfg_res->start;
> >                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -               /* Find the untranslated configuration space address */
> > -               index = of_property_match_string(np, "reg-names", "config");
> > -               addrp = of_get_address(np, index, NULL, NULL);
> > -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> >         } else {
> >                 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 = range.cpu_addr;
> > -               }
> > -               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 = range.cpu_addr;
> > -               }
> > -               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;
> > -
> > -                       /* Find the untranslated configuration space address
> */
> > -                       pp->cfg0_mod_base = range.cpu_addr;
> > -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -                                           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;
> > +                       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;
> > +                       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;
> > +                       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,
> > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >
> >         if (!pp->ops->rd_other_conf)
> >                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > -                                         PCIE_ATU_TYPE_MEM, pp-
> >mem_mod_base,
> > +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
> >                                           pp->mem_bus_addr, pp->mem_size);
> >
> >         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >         val |= PORT_LOGIC_SPEED_CHANGE;
> >         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +       pp->root_bus_nr = pp->busn->start;
> > +       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
> >         dw_pcie_msi_chip.dev = pp->dev;
> > -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +       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);
> > +
> > +#ifdef CONFIG_ARM
> > +       /* support old dtbs that incorrectly describe IRQs */
> > +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -       pci_common_init_dev(pp->dev, &dw_pci);
> > +       pci_assign_unassigned_bus_resources(bus);
> > +       pci_bus_add_devices(bus);
> >
> >         return 0;
> >  }
> > @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -626,7 +606,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) {
> > @@ -650,7 +630,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)
> > @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> > -                                 &dw_pcie_ops, sys, &sys->resources);
> > -       if (!bus)
> > -               return NULL;
> > -
> > -       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..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >         u8                      root_bus_nr;
> >         void __iomem            *dbi_base;
> >         u64                     cfg0_base;
> > -       u64                     cfg0_mod_base;
> >         void __iomem            *va_cfg0_base;
> >         u32                     cfg0_size;
> >         u64                     cfg1_base;
> > -       u64                     cfg1_mod_base;
> >         void __iomem            *va_cfg1_base;
> >         u32                     cfg1_size;
> > -       u64                     io_base;
> > -       u64                     io_mod_base;
> > +       resource_size_t         io_base;
> >         phys_addr_t             io_bus_addr;
> >         u32                     io_size;
> >         u64                     mem_base;
> > -       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;
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
N‹§²æìr¸›yúèšØb²X¬¶Ç§vØ^–)Þº{.nÇ+‰·zøœzÚÞz)í…æèw*\x1fjg¬±¨\x1e¶‰šŽŠÝ¢j.ïÛ°\½½MŽúgjÌæa×\x02››–' ™©Þ¢¸\f¢·¦j:+v‰¨ŠwèjØm¶Ÿÿ¾\a«‘êçzZ+ƒùšŽŠÝ¢j"ú!¶i

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

* RE: [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-27 15:21         ` Gabriele Paoloni
  0 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-08-27 15:21 UTC (permalink / raw)
  To: Gabriel Fernandez, Wangzhou (B)
  Cc: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann,
	Russell King, thomas.petazzoni, lorenzo.pieralisi, james.morse,
	Liviu Dudau, jason, robh, devicetree, linux-pci, xuwei (O),
	qiuzhenfa, liudongdong (C), zhangjukuo, Liguozhu (Kenneth),
	qiujiang, linux-arm-kernel

PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBsaW51eC1wY2ktb3duZXJAdmdl
ci5rZXJuZWwub3JnIFttYWlsdG86bGludXgtcGNpLW93bmVyQHZnZXIua2VybmVsLm9yZ10NCj4g
T24gQmVoYWxmIE9mIEdhYnJpZWwgRmVybmFuZGV6DQo+IFNlbnQ6IDI3IEF1Z3VzdCAyMDE1IDEz
OjU3DQo+IFRvOiBXYW5nemhvdSAoQikNCj4gQ2M6IEJqb3JuIEhlbGdhYXM7IGppbmdvb2hhbjFA
Z21haWwuY29tOyBwcmF0eXVzaC5hbmFuZEBnbWFpbC5jb207IEFybmQNCj4gQmVyZ21hbm47IFJ1
c3NlbGwgS2luZzsgdGhvbWFzLnBldGF6em9uaUBmcmVlLWVsZWN0cm9ucy5jb207IEdhYnJpZWxl
IFBhb2xvbmk7DQo+IGxvcmVuem8ucGllcmFsaXNpQGFybS5jb207IGphbWVzLm1vcnNlQGFybS5j
b207IExpdml1IER1ZGF1Ow0KPiBqYXNvbkBsYWtlZGFlbW9uLm5ldDsgcm9iaEBrZXJuZWwub3Jn
OyBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2VyLmtlcm5lbC5v
cmc7IHh1d2VpIChPKTsgcWl1emhlbmZhOyBsaXVkb25nZG9uZyAoQyk7IHpoYW5nanVrdW87DQo+
IExpZ3Vvemh1IChLZW5uZXRoKTsgcWl1amlhbmc7IGxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5m
cmFkZWFkLm9yZw0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHY4IDMvNl0gUENJOiBkZXNpZ253YXJl
OiBBZGQgQVJNNjQgc3VwcG9ydA0KPiANCj4gSGkgWmhvdSwNCj4gDQo+IFlvdSBjYW4gYWRkIG15
IFRlc3RlZC1ieTogR2FicmllbCBGZXJuYW5kZXogPGdhYnJpZWwuZmVybmFuZGV6QHN0LmNvbT4N
Cj4gDQo+IEkgdGVzdGVkIHlvdXIgcGF0Y2hzZXQgd2l0aCBhIFNUTWljcm9lbGVjdHJvbmljcyBQ
Q0llIGNvbnRyb2xsZXIuDQo+IFRoaXMgY29udHJvbGxlciBpcyBiYXNlZCBvbiBkZXNpZ253YXJl
IFBDSWUgZHJpdmVyIGFuZCB3b3JrcyBvbiBBUk0zMi4NCj4gDQo+IFBsZWFzZSBmaW5kIG15IHBh
dGNoc2V0IGhlcmU6DQo+IGh0dHA6Ly93d3cuc3Bpbmljcy5uZXQvbGlzdHMva2VybmVsL21zZzIw
NjQyNjYuaHRtbA0KPiANCj4gQmVzdCBSZWdhcmRzLg0KPiANCj4gR2FicmllbC4NCg0KTWFueSBU
aGFua3MgZm9yIHRoaXMgR2FicmllbA0KDQpDaGVlcnMNCkdhYg0KDQo+IA0KPiBPbiAyNSBBdWd1
c3QgMjAxNSBhdCAxMTo1OCwgWmhvdSBXYW5nIDx3YW5nemhvdTFAaGlzaWxpY29uLmNvbT4gd3Jv
dGU6DQo+ID4gVGhpcyBwYXRjaCB0cmllcyB0byB1bmlmeSBBUk0zMiBhbmQgQVJNNjQgUENJZSBp
biBkZXNpZ253YXJlIGRyaXZlci4gRGVsZXRlDQo+ID4gZnVuY3Rpb24gZHdfcGNpZV9zZXR1cCwg
ZHdfcGNpZV9zY2FuX2J1cywgZHdfcGNpZV9tYXBfaXJxIGFuZCBzdHJ1Y3QgaHdfcGNpLA0KPiA+
IG1vdmUgcmVsYXRlZCBvcGVyYXRpb25zIHRvIGR3X3BjaWVfaG9zdF9pbml0Lg0KPiA+DQo+ID4g
VGhpcyBwYXRjaCBhbHNvIHRyeSB0byB1c2Ugb2ZfcGNpX2dldF9ob3N0X2JyaWRnZV9yZXNvdXJj
ZXMgZm9yIEFSTTMyIGFuZA0KPiBBUk02NA0KPiA+IGFjY29yZGluZyB0byB0aGUgc3VnZ2VzdGlv
biBmb3IgR2FicmllbGVbMV0NCj4gPg0KPiA+IEZpbmFsbHkgdGhpcyBwYXRjaCByZXZlcnRzIGNv
bW1pdCBmNGM1NWM1YTNmN2YgIlBDSTogZGVzaWdud2FyZTogUHJvZ3JhbSBBVFUNCj4gPiB3aXRo
IHVudHJhbnNsYXRlZCBhZGRyZXNzIiBiYXNlZCBvbiAxLzYgaW4gdGhpcyBzZXJpZXMuIHdlIGRl
bGV0ZSAqX21vZF9iYXNlDQo+IGluDQo+ID4gcGNpZS1kZXNpZ253YXJlLiBUaGlzIHdhcyBkaXNj
dXNzZWQgaW4gWzJdDQo+ID4NCj4gPiBJIGhhdmUgY29tcGlsZWQgdGhlIGRyaXZlciB3aXRoIG11
bHRpX3Y3X2RlZmNvbmZpZy4gSG93ZXZlciwgSSBkb24ndCBoYXZlDQo+ID4gQVJNMzIgUENJZSBy
ZWxhdGVkIGJvYXJkIHRvIGRvIHRlc3QuIEl0IHdpbGwgYmUgYXBwcmVjaWF0ZWQgaWYgc29tZW9u
ZSBjb3VsZA0KPiA+IGhlbHAgdG8gdGVzdCBpdC4NCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFpo
b3UgV2FuZyA8d2FuZ3pob3UxQGhpc2lsaWNvbi5jb20+DQo+ID4gU2lnbmVkLW9mZi1ieTogR2Fi
cmllbGUgUGFvbG9uaSA8Z2FicmllbGUucGFvbG9uaUBodWF3ZWkuY29tPg0KPiA+IFNpZ25lZC1v
ZmYtYnk6IEFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQo+ID4gVGVzdGVkLUJ5OiBKYW1l
cyBNb3JzZSA8amFtZXMubW9yc2VAYXJtLmNvbT4NCj4gPg0KPiA+IFsxXSBodHRwOi8vd3d3LnNw
aW5pY3MubmV0L2xpc3RzL2xpbnV4LXBjaS9tc2c0MjE5NC5odG1sDQo+ID4gWzJdIGh0dHA6Ly93
d3cuc3Bpbmljcy5uZXQvbGlzdHMvYXJtLWtlcm5lbC9tc2c0MzY3NzkuaHRtbA0KPiA+IC0tLQ0K
PiA+ICBkcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYyAgICAgIHwgIDE0ICstLQ0KPiA+ICBk
cml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5jIHwgICAyICstDQo+ID4gIGRyaXZlcnMv
cGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMgfCAyMzAgKysrKysrKysrKysrKy0tLS0tLS0tLS0t
LS0tLS0tLS0tLQ0KPiAtLS0NCj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUu
aCB8ICAxNCArLS0NCj4gPiAgNCBmaWxlcyBjaGFuZ2VkLCA5MCBpbnNlcnRpb25zKCspLCAxNzAg
ZGVsZXRpb25zKC0pDQo+ID4NCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2kt
ZHJhN3h4LmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KPiA+IGluZGV4IDE4YWU3
ZmYuLmFjNDAxYmUgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4
LmMNCj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KPiA+IEBAIC0xNDEs
MTUgKzE0MSwxNSBAQCBzdGF0aWMgdm9pZCBkcmE3eHhfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBj
aWVfcG9ydCAqcHApDQo+ID4gIHsNCj4gPiAgICAgICAgIGR3X3BjaWVfc2V0dXBfcmMocHApOw0K
PiA+DQo+ID4gLSAgICAgICBpZiAocHAtPmlvX21vZF9iYXNlKQ0KPiA+IC0gICAgICAgICAgICAg
ICBwcC0+aW9fbW9kX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KPiA+ICsgICAgICAgaWYgKHBw
LT5pb19iYXNlKQ0KPiA+ICsgICAgICAgICAgICAgICBwcC0+aW9fYmFzZSAmPSBDUFVfVE9fQlVT
X0FERFI7DQo+ID4NCj4gPiAtICAgICAgIGlmIChwcC0+bWVtX21vZF9iYXNlKQ0KPiA+IC0gICAg
ICAgICAgICAgICBwcC0+bWVtX21vZF9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiArICAg
ICAgIGlmIChwcC0+bWVtX2Jhc2UpDQo+ID4gKyAgICAgICAgICAgICAgIHBwLT5tZW1fYmFzZSAm
PSBDUFVfVE9fQlVTX0FERFI7DQo+ID4NCj4gPiAtICAgICAgIGlmIChwcC0+Y2ZnMF9tb2RfYmFz
ZSkgew0KPiA+IC0gICAgICAgICAgICAgICBwcC0+Y2ZnMF9tb2RfYmFzZSAmPSBDUFVfVE9fQlVT
X0FERFI7DQo+ID4gLSAgICAgICAgICAgICAgIHBwLT5jZmcxX21vZF9iYXNlICY9IENQVV9UT19C
VVNfQUREUjsNCj4gPiArICAgICAgIGlmIChwcC0+Y2ZnMF9iYXNlKSB7DQo+ID4gKyAgICAgICAg
ICAgICAgIHBwLT5jZmcwX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KPiA+ICsgICAgICAgICAg
ICAgICBwcC0+Y2ZnMV9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiAgICAgICAgIH0NCj4g
Pg0KPiA+ICAgICAgICAgZHJhN3h4X3BjaWVfZXN0YWJsaXNoX2xpbmsocHApOw0KPiA+IGRpZmYg
LS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5jIGIvZHJpdmVycy9wY2kv
aG9zdC9wY2ktDQo+IGtleXN0b25lLWR3LmMNCj4gPiBpbmRleCBmMzQ4OTJlLi5iMWU0MTM1IDEw
MDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMNCj4gPiAr
KysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5jDQo+ID4gQEAgLTMyNyw3ICsz
MjcsNyBAQCBzdGF0aWMgdm9pZCBrc19kd19wY2llX2NsZWFyX2RiaV9tb2RlKHZvaWQgX19pb21l
bQ0KPiAqcmVnX3ZpcnQpDQo+ID4gIHZvaWQga3NfZHdfcGNpZV9zZXR1cF9yY19hcHBfcmVncyhz
dHJ1Y3Qga2V5c3RvbmVfcGNpZSAqa3NfcGNpZSkNCj4gPiAgew0KPiA+ICAgICAgICAgc3RydWN0
IHBjaWVfcG9ydCAqcHAgPSAma3NfcGNpZS0+cHA7DQo+ID4gLSAgICAgICB1MzIgc3RhcnQgPSBw
cC0+bWVtLnN0YXJ0LCBlbmQgPSBwcC0+bWVtLmVuZDsNCj4gPiArICAgICAgIHUzMiBzdGFydCA9
IHBwLT5tZW0tPnN0YXJ0LCBlbmQgPSBwcC0+bWVtLT5lbmQ7DQo+ID4gICAgICAgICBpbnQgaSwg
dHJfc2l6ZTsNCj4gPg0KPiA+ICAgICAgICAgLyogRGlzYWJsZSBCQVJzIGZvciBpbmJvdW5kIGFj
Y2VzcyAqLw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2Fy
ZS5jIGIvZHJpdmVycy9wY2kvaG9zdC9wY2llLQ0KPiBkZXNpZ253YXJlLmMNCj4gPiBpbmRleCBj
NWQ0MDdjLi5lMmQxODk4IDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1k
ZXNpZ253YXJlLmMNCj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5j
DQo+ID4gQEAgLTExLDYgKzExLDcgQEANCj4gPiAgICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNv
ZnR3YXJlIEZvdW5kYXRpb24uDQo+ID4gICAqLw0KPiA+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9o
YXJkaXJxLmg+DQo+ID4gICNpbmNsdWRlIDxsaW51eC9pcnEuaD4NCj4gPiAgI2luY2x1ZGUgPGxp
bnV4L2lycWRvbWFpbi5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgva2VybmVsLmg+DQo+ID4gQEAg
LTY5LDE2ICs3MCw3IEBADQo+ID4gICNkZWZpbmUgUENJRV9BVFVfRlVOQyh4KSAgICAgICAgICAg
ICAgICgoKHgpICYgMHg3KSA8PCAxNikNCj4gPiAgI2RlZmluZSBQQ0lFX0FUVV9VUFBFUl9UQVJH
RVQgICAgICAgICAgMHg5MUMNCj4gPg0KPiA+IC1zdGF0aWMgc3RydWN0IGh3X3BjaSBkd19wY2k7
DQo+ID4gLQ0KPiA+IC1zdGF0aWMgdW5zaWduZWQgbG9uZyBnbG9iYWxfaW9fb2Zmc2V0Ow0KPiA+
IC0NCj4gPiAtc3RhdGljIGlubGluZSBzdHJ1Y3QgcGNpZV9wb3J0ICpzeXNfdG9fcGNpZShzdHJ1
Y3QgcGNpX3N5c19kYXRhICpzeXMpDQo+ID4gLXsNCj4gPiAtICAgICAgIEJVR19PTighc3lzLT5w
cml2YXRlX2RhdGEpOw0KPiA+IC0NCj4gPiAtICAgICAgIHJldHVybiBzeXMtPnByaXZhdGVfZGF0
YTsNCj4gPiAtfQ0KPiA+ICtzdGF0aWMgc3RydWN0IHBjaV9vcHMgZHdfcGNpZV9vcHM7DQo+ID4N
Cj4gPiAgaW50IGR3X3BjaWVfY2ZnX3JlYWQodm9pZCBfX2lvbWVtICphZGRyLCBpbnQgd2hlcmUs
IGludCBzaXplLCB1MzIgKnZhbCkNCj4gPiAgew0KPiA+IEBAIC0yNTUsNyArMjQ3LDcgQEAgc3Rh
dGljIHZvaWQgZHdfcGNpZV9tc2lfc2V0X2lycShzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwNCj4gaW50
IGlycSkNCj4gPiAgc3RhdGljIGludCBhc3NpZ25faXJxKGludCBub19pcnFzLCBzdHJ1Y3QgbXNp
X2Rlc2MgKmRlc2MsIGludCAqcG9zKQ0KPiA+ICB7DQo+ID4gICAgICAgICBpbnQgaXJxLCBwb3Mw
LCBpOw0KPiA+IC0gICAgICAgc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBzeXNfdG9fcGNpZShkZXNj
LT5kZXYtPmJ1cy0+c3lzZGF0YSk7DQo+ID4gKyAgICAgICBzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9
IGRlc2MtPmRldi0+YnVzLT5zeXNkYXRhOw0KPiA+DQo+ID4gICAgICAgICBwb3MwID0gYml0bWFw
X2ZpbmRfZnJlZV9yZWdpb24ocHAtPm1zaV9pcnFfaW5fdXNlLCBNQVhfTVNJX0lSUVMsDQo+ID4g
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJfYmFzZV8yKG5vX2ly
cXMpKTsNCj4gPiBAQCAtMjk4LDcgKzI5MCw3IEBAIHN0YXRpYyBpbnQgZHdfbXNpX3NldHVwX2ly
cShzdHJ1Y3QgbXNpX2NvbnRyb2xsZXIgKmNoaXAsDQo+IHN0cnVjdCBwY2lfZGV2ICpwZGV2LA0K
PiA+ICB7DQo+ID4gICAgICAgICBpbnQgaXJxLCBwb3M7DQo+ID4gICAgICAgICBzdHJ1Y3QgbXNp
X21zZyBtc2c7DQo+ID4gLSAgICAgICBzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2ll
KHBkZXYtPmJ1cy0+c3lzZGF0YSk7DQo+ID4gKyAgICAgICBzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9
IHBkZXYtPmJ1cy0+c3lzZGF0YTsNCj4gPg0KPiA+ICAgICAgICAgaWYgKGRlc2MtPm1zaV9hdHRy
aWIuaXNfbXNpeCkNCj4gPiAgICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7DQo+ID4gQEAg
LTMyNyw3ICszMTksNyBAQCBzdGF0aWMgdm9pZCBkd19tc2lfdGVhcmRvd25faXJxKHN0cnVjdCBt
c2lfY29udHJvbGxlcg0KPiAqY2hpcCwgdW5zaWduZWQgaW50IGlycSkNCj4gPiAgew0KPiA+ICAg
ICAgICAgc3RydWN0IGlycV9kYXRhICpkYXRhID0gaXJxX2dldF9pcnFfZGF0YShpcnEpOw0KPiA+
ICAgICAgICAgc3RydWN0IG1zaV9kZXNjICptc2kgPSBpcnFfZGF0YV9nZXRfbXNpKGRhdGEpOw0K
PiA+IC0gICAgICAgc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBzeXNfdG9fcGNpZShtc2ktPmRldi0+
YnVzLT5zeXNkYXRhKTsNCj4gPiArICAgICAgIHN0cnVjdCBwY2llX3BvcnQgKnBwID0gbXNpLT5k
ZXYtPmJ1cy0+c3lzZGF0YTsNCj4gPg0KPiA+ICAgICAgICAgY2xlYXJfaXJxX3JhbmdlKHBwLCBp
cnEsIDEsIGRhdGEtPmh3aXJxKTsNCj4gPiAgfQ0KPiA+IEBAIC0zNjMsMTQgKzM1NSwxMiBAQCBp
bnQgZHdfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQo+ID4gIHsNCj4gPiAg
ICAgICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAgPSBwcC0+ZGV2LT5vZl9ub2RlOw0KPiA+ICAg
ICAgICAgc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiA9IHRvX3BsYXRmb3JtX2RldmljZShw
cC0+ZGV2KTsNCj4gPiAtICAgICAgIHN0cnVjdCBvZl9wY2lfcmFuZ2UgcmFuZ2U7DQo+ID4gLSAg
ICAgICBzdHJ1Y3Qgb2ZfcGNpX3JhbmdlX3BhcnNlciBwYXJzZXI7DQo+ID4gKyAgICAgICBzdHJ1
Y3QgcGNpX2J1cyAqYnVzOw0KPiA+ICAgICAgICAgc3RydWN0IHJlc291cmNlICpjZmdfcmVzOw0K
PiA+IC0gICAgICAgdTMyIHZhbCwgbnM7DQo+ID4gLSAgICAgICBjb25zdCBfX2JlMzIgKmFkZHJw
Ow0KPiA+IC0gICAgICAgaW50IGksIGluZGV4LCByZXQ7DQo+ID4gLQ0KPiA+IC0gICAgICAgbnMg
PSBvZl9uX3NpemVfY2VsbHMobnApOw0KPiA+ICsgICAgICAgTElTVF9IRUFEKHJlcyk7DQo+ID4g
KyAgICAgICB1MzIgdmFsOw0KPiA+ICsgICAgICAgaW50IGksIHJldDsNCj4gPiArICAgICAgIHN0
cnVjdCByZXNvdXJjZV9lbnRyeSAqd2luOw0KPiA+DQo+ID4gICAgICAgICBjZmdfcmVzID0gcGxh
dGZvcm1fZ2V0X3Jlc291cmNlX2J5bmFtZShwZGV2LCBJT1JFU09VUkNFX01FTSwNCj4gImNvbmZp
ZyIpOw0KPiA+ICAgICAgICAgaWYgKGNmZ19yZXMpIHsNCj4gPiBAQCAtMzc4LDg1ICszNjgsNjAg
QEAgaW50IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KPiA+ICAgICAg
ICAgICAgICAgICBwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZShjZmdfcmVzKS8yOw0KPiA+
ICAgICAgICAgICAgICAgICBwcC0+Y2ZnMF9iYXNlID0gY2ZnX3Jlcy0+c3RhcnQ7DQo+ID4gICAg
ICAgICAgICAgICAgIHBwLT5jZmcxX2Jhc2UgPSBjZmdfcmVzLT5zdGFydCArIHBwLT5jZmcwX3Np
emU7DQo+ID4gLQ0KPiA+IC0gICAgICAgICAgICAgICAvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQg
Y29uZmlndXJhdGlvbiBzcGFjZSBhZGRyZXNzICovDQo+ID4gLSAgICAgICAgICAgICAgIGluZGV4
ID0gb2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5wLCAicmVnLW5hbWVzIiwgImNvbmZpZyIpOw0K
PiA+IC0gICAgICAgICAgICAgICBhZGRycCA9IG9mX2dldF9hZGRyZXNzKG5wLCBpbmRleCwgTlVM
TCwgTlVMTCk7DQo+ID4gLSAgICAgICAgICAgICAgIHBwLT5jZmcwX21vZF9iYXNlID0gb2ZfcmVh
ZF9udW1iZXIoYWRkcnAsIG5zKTsNCj4gPiAtICAgICAgICAgICAgICAgcHAtPmNmZzFfbW9kX2Jh
c2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArIHBwLT5jZmcwX3NpemU7DQo+ID4gICAgICAgICB9IGVs
c2Ugew0KPiA+ICAgICAgICAgICAgICAgICBkZXZfZXJyKHBwLT5kZXYsICJtaXNzaW5nICpjb25m
aWcqIHJlZyBzcGFjZVxuIik7DQo+ID4gICAgICAgICB9DQo+ID4NCj4gPiAtICAgICAgIGlmIChv
Zl9wY2lfcmFuZ2VfcGFyc2VyX2luaXQoJnBhcnNlciwgbnApKSB7DQo+ID4gLSAgICAgICAgICAg
ICAgIGRldl9lcnIocHAtPmRldiwgIm1pc3NpbmcgcmFuZ2VzIHByb3BlcnR5XG4iKTsNCj4gPiAt
ICAgICAgICAgICAgICAgcmV0dXJuIC1FSU5WQUw7DQo+ID4gLSAgICAgICB9DQo+ID4gKyAgICAg
ICByZXQgPSBvZl9wY2lfZ2V0X2hvc3RfYnJpZGdlX3Jlc291cmNlcyhucCwgMCwgMHhmZiwgJnJl
cywgJnBwLQ0KPiA+aW9fYmFzZSk7DQo+ID4gKyAgICAgICBpZiAocmV0KQ0KPiA+ICsgICAgICAg
ICAgICAgICByZXR1cm4gcmV0Ow0KPiA+DQo+ID4gICAgICAgICAvKiBHZXQgdGhlIEkvTyBhbmQg
bWVtb3J5IHJhbmdlcyBmcm9tIERUICovDQo+ID4gLSAgICAgICBmb3JfZWFjaF9vZl9wY2lfcmFu
Z2UoJnBhcnNlciwgJnJhbmdlKSB7DQo+ID4gLSAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcg
cmVzdHlwZSA9IHJhbmdlLmZsYWdzICYgSU9SRVNPVVJDRV9UWVBFX0JJVFM7DQo+ID4gLQ0KPiA+
IC0gICAgICAgICAgICAgICBpZiAocmVzdHlwZSA9PSBJT1JFU09VUkNFX0lPKSB7DQo+ID4gLSAg
ICAgICAgICAgICAgICAgICAgICAgb2ZfcGNpX3JhbmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAs
ICZwcC0+aW8pOw0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgIHBwLT5pby5uYW1lID0gIkkv
TyI7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmlvLnN0YXJ0ID0gbWF4X3QocmVz
b3VyY2Vfc2l6ZV90LA0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgIFBDSUJJT1NfTUlOX0lPLA0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgIHJhbmdlLnBjaV9hZGRyICsNCj4gZ2xvYmFsX2lvX29mZnNldCk7DQo+
ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmlvLmVuZCA9IG1pbl90KHJlc291cmNlX3Np
emVfdCwNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU9f
U1BBQ0VfTElNSVQsDQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIHJhbmdlLnBjaV9hZGRyICsgcmFuZ2Uuc2l6ZQ0KPiA+IC0gICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICArIGdsb2JhbF9pb19vZmZzZXQgLSAxKTsNCj4gPiAtICAg
ICAgICAgICAgICAgICAgICAgICBwcC0+aW9fc2l6ZSA9IHJlc291cmNlX3NpemUoJnBwLT5pbyk7
DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmlvX2J1c19hZGRyID0gcmFuZ2UucGNp
X2FkZHI7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmlvX2Jhc2UgPSByYW5nZS5j
cHVfYWRkcjsNCj4gPiAtDQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgLyogRmluZCB0aGUg
dW50cmFuc2xhdGVkIElPIHNwYWNlIGFkZHJlc3MgKi8NCj4gPiAtICAgICAgICAgICAgICAgICAg
ICAgICBwcC0+aW9fbW9kX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsNCj4gPiAtICAgICAgICAgICAg
ICAgfQ0KPiA+IC0gICAgICAgICAgICAgICBpZiAocmVzdHlwZSA9PSBJT1JFU09VUkNFX01FTSkg
ew0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgIG9mX3BjaV9yYW5nZV90b19yZXNvdXJjZSgm
cmFuZ2UsIG5wLCAmcHAtPm1lbSk7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPm1l
bS5uYW1lID0gIk1FTSI7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPm1lbV9zaXpl
ID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPm1lbSk7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAg
cHAtPm1lbV9idXNfYWRkciA9IHJhbmdlLnBjaV9hZGRyOw0KPiA+IC0NCj4gPiAtICAgICAgICAg
ICAgICAgICAgICAgICAvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgTUVNIHNwYWNlIGFkZHJlc3Mg
Ki8NCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICBwcC0+bWVtX21vZF9iYXNlID0gcmFuZ2Uu
Y3B1X2FkZHI7DQo+ID4gLSAgICAgICAgICAgICAgIH0NCj4gPiAtICAgICAgICAgICAgICAgaWYg
KHJlc3R5cGUgPT0gMCkgew0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAgIG9mX3BjaV9yYW5n
ZV90b19yZXNvdXJjZSgmcmFuZ2UsIG5wLCAmcHAtPmNmZyk7DQo+ID4gLSAgICAgICAgICAgICAg
ICAgICAgICAgcHAtPmNmZzBfc2l6ZSA9IHJlc291cmNlX3NpemUoJnBwLT5jZmcpLzI7DQo+ID4g
LSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmNmZzFfc2l6ZSA9IHJlc291cmNlX3NpemUoJnBw
LT5jZmcpLzI7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmNmZzBfYmFzZSA9IHBw
LT5jZmcuc3RhcnQ7DQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmNmZzFfYmFzZSA9
IHBwLT5jZmcuc3RhcnQgKyBwcC0+Y2ZnMF9zaXplOw0KPiA+IC0NCj4gPiAtICAgICAgICAgICAg
ICAgICAgICAgICAvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgY29uZmlndXJhdGlvbiBzcGFjZSBh
ZGRyZXNzDQo+ICovDQo+ID4gLSAgICAgICAgICAgICAgICAgICAgICAgcHAtPmNmZzBfbW9kX2Jh
c2UgPSByYW5nZS5jcHVfYWRkcjsNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICBwcC0+Y2Zn
MV9tb2RfYmFzZSA9IHBwLT5jZmcwX21vZF9iYXNlICsNCj4gPiAtICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIHBwLT5jZmcwX3NpemU7DQo+ID4gKyAgICAgICByZXNv
dXJjZV9saXN0X2Zvcl9lYWNoX2VudHJ5KHdpbiwgJnJlcykgew0KPiA+ICsgICAgICAgICAgICAg
ICBzd2l0Y2ggKHJlc291cmNlX3R5cGUod2luLT5yZXMpKSB7DQo+ID4gKyAgICAgICAgICAgICAg
IGNhc2UgSU9SRVNPVVJDRV9JTzoNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+aW8g
PSB3aW4tPnJlczsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+aW8tPm5hbWUgPSAi
SS9PIjsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+aW9fc2l6ZSA9IHJlc291cmNl
X3NpemUocHAtPmlvKTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+aW9fYnVzX2Fk
ZHIgPSBwcC0+aW8tPnN0YXJ0IC0gd2luLT5vZmZzZXQ7DQo+ID4gKyAgICAgICAgICAgICAgICAg
ICAgICAgcmV0ID0gcGNpX3JlbWFwX2lvc3BhY2UocHAtPmlvLCBwcC0+aW9fYmFzZSk7DQo+ID4g
KyAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJldCkgew0KPiA+ICsgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgZGV2X3dhcm4ocHAtPmRldiwgImVycm9yICVkOiBmYWlsZWQgdG8gbWFw
DQo+IHJlc291cmNlICVwUlxuIiwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIHJldCwgcHAtPmlvKTsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgIGNvbnRpbnVlOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIH0NCj4gPiArICAgICAg
ICAgICAgICAgICAgICAgICBicmVhazsNCj4gPiArICAgICAgICAgICAgICAgY2FzZSBJT1JFU09V
UkNFX01FTToNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+bWVtID0gd2luLT5yZXM7
DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcHAtPm1lbS0+bmFtZSA9ICJNRU0iOw0KPiA+
ICsgICAgICAgICAgICAgICAgICAgICAgIHBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUocHAt
Pm1lbSk7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgcHAtPm1lbV9idXNfYWRkciA9IHBw
LT5tZW0tPnN0YXJ0IC0gd2luLT5vZmZzZXQ7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg
YnJlYWs7DQo+ID4gKyAgICAgICAgICAgICAgIGNhc2UgMDoNCj4gPiArICAgICAgICAgICAgICAg
ICAgICAgICBwcC0+Y2ZnID0gd2luLT5yZXM7DQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAg
cHAtPmNmZzBfc2l6ZSA9IHJlc291cmNlX3NpemUocHAtPmNmZykvMjsNCj4gPiArICAgICAgICAg
ICAgICAgICAgICAgICBwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZShwcC0+Y2ZnKS8yOw0K
PiA+ICsgICAgICAgICAgICAgICAgICAgICAgIHBwLT5jZmcwX2Jhc2UgPSBwcC0+Y2ZnLT5zdGFy
dDsNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBwcC0+Y2ZnMV9iYXNlID0gcHAtPmNmZy0+
c3RhcnQgKyBwcC0+Y2ZnMF9zaXplOw0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgIGJyZWFr
Ow0KPiA+ICsgICAgICAgICAgICAgICBjYXNlIElPUkVTT1VSQ0VfQlVTOg0KPiA+ICsgICAgICAg
ICAgICAgICAgICAgICAgIHBwLT5idXNuID0gd2luLT5yZXM7DQo+ID4gKyAgICAgICAgICAgICAg
ICAgICAgICAgYnJlYWs7DQo+ID4gKyAgICAgICAgICAgICAgIGRlZmF1bHQ6DQo+ID4gKyAgICAg
ICAgICAgICAgICAgICAgICAgY29udGludWU7DQo+ID4gICAgICAgICAgICAgICAgIH0NCj4gPiAg
ICAgICAgIH0NCj4gPg0KPiA+IC0gICAgICAgcmV0ID0gb2ZfcGNpX3BhcnNlX2J1c19yYW5nZShu
cCwgJnBwLT5idXNuKTsNCj4gPiAtICAgICAgIGlmIChyZXQgPCAwKSB7DQo+ID4gLSAgICAgICAg
ICAgICAgIHBwLT5idXNuLm5hbWUgPSBucC0+bmFtZTsNCj4gPiAtICAgICAgICAgICAgICAgcHAt
PmJ1c24uc3RhcnQgPSAwOw0KPiA+IC0gICAgICAgICAgICAgICBwcC0+YnVzbi5lbmQgPSAweGZm
Ow0KPiA+IC0gICAgICAgICAgICAgICBwcC0+YnVzbi5mbGFncyA9IElPUkVTT1VSQ0VfQlVTOw0K
PiA+IC0gICAgICAgICAgICAgICBkZXZfZGJnKHBwLT5kZXYsICJmYWlsZWQgdG8gcGFyc2UgYnVz
LXJhbmdlIHByb3BlcnR5OiAlZCwNCj4gdXNpbmcgZGVmYXVsdCAlcFJcbiIsDQo+ID4gLSAgICAg
ICAgICAgICAgICAgICAgICAgcmV0LCAmcHAtPmJ1c24pOw0KPiA+IC0gICAgICAgfQ0KPiA+IC0N
Cj4gPiAgICAgICAgIGlmICghcHAtPmRiaV9iYXNlKSB7DQo+ID4gLSAgICAgICAgICAgICAgIHBw
LT5kYmlfYmFzZSA9IGRldm1faW9yZW1hcChwcC0+ZGV2LCBwcC0+Y2ZnLnN0YXJ0LA0KPiA+IC0g
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvdXJjZV9zaXplKCZwcC0+
Y2ZnKSk7DQo+ID4gKyAgICAgICAgICAgICAgIHBwLT5kYmlfYmFzZSA9IGRldm1faW9yZW1hcChw
cC0+ZGV2LCBwcC0+Y2ZnLT5zdGFydCwNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgcmVzb3VyY2Vfc2l6ZShwcC0+Y2ZnKSk7DQo+ID4gICAgICAgICAgICAgICAg
IGlmICghcHAtPmRiaV9iYXNlKSB7DQo+ID4gICAgICAgICAgICAgICAgICAgICAgICAgZGV2X2Vy
cihwcC0+ZGV2LCAiZXJyb3Igd2l0aCBpb3JlbWFwXG4iKTsNCj4gPiAgICAgICAgICAgICAgICAg
ICAgICAgICByZXR1cm4gLUVOT01FTTsNCj4gPiAgICAgICAgICAgICAgICAgfQ0KPiA+ICAgICAg
ICAgfQ0KPiA+DQo+ID4gLSAgICAgICBwcC0+bWVtX2Jhc2UgPSBwcC0+bWVtLnN0YXJ0Ow0KPiA+
ICsgICAgICAgcHAtPm1lbV9iYXNlID0gcHAtPm1lbS0+c3RhcnQ7DQo+ID4NCj4gPiAgICAgICAg
IGlmICghcHAtPnZhX2NmZzBfYmFzZSkgew0KPiA+ICAgICAgICAgICAgICAgICBwcC0+dmFfY2Zn
MF9iYXNlID0gZGV2bV9pb3JlbWFwKHBwLT5kZXYsIHBwLT5jZmcwX2Jhc2UsDQo+ID4gQEAgLTUw
NSw3ICs0NzAsNyBAQCBpbnQgZHdfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBjaWVfcG9ydCAqcHAp
DQo+ID4NCj4gPiAgICAgICAgIGlmICghcHAtPm9wcy0+cmRfb3RoZXJfY29uZikNCj4gPiAgICAg
ICAgICAgICAgICAgZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9O
X0lOREVYMSwNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQ
Q0lFX0FUVV9UWVBFX01FTSwgcHAtDQo+ID5tZW1fbW9kX2Jhc2UsDQo+ID4gKyAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJRV9BVFVfVFlQRV9NRU0sIHBwLT5tZW1f
YmFzZSwNCj4gPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcC0+
bWVtX2J1c19hZGRyLCBwcC0+bWVtX3NpemUpOw0KPiA+DQo+ID4gICAgICAgICBkd19wY2llX3dy
X293bl9jb25mKHBwLCBQQ0lfQkFTRV9BRERSRVNTXzAsIDQsIDApOw0KPiA+IEBAIC01MTcsMTUg
KzQ4MiwzMCBAQCBpbnQgZHdfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQo+
ID4gICAgICAgICB2YWwgfD0gUE9SVF9MT0dJQ19TUEVFRF9DSEFOR0U7DQo+ID4gICAgICAgICBk
d19wY2llX3dyX293bl9jb25mKHBwLCBQQ0lFX0xJTktfV0lEVEhfU1BFRURfQ09OVFJPTCwgNCwg
dmFsKTsNCj4gPg0KPiA+IC0jaWZkZWYgQ09ORklHX1BDSV9NU0kNCj4gPiArICAgICAgIHBwLT5y
b290X2J1c19uciA9IHBwLT5idXNuLT5zdGFydDsNCj4gPiArICAgICAgIGJ1cyA9IHBjaV9jcmVh
dGVfcm9vdF9idXMocHAtPmRldiwgcHAtPnJvb3RfYnVzX25yLCAmZHdfcGNpZV9vcHMsDQo+ID4g
KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBwLCAmcmVzKTsNCj4gPiArICAgICAg
IGlmICghYnVzKQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gLUVOT01FTTsNCj4gPiArDQo+
ID4gKyNpZmRlZiBDT05GSUdfR0VORVJJQ19NU0lfSVJRX0RPTUFJTg0KPiA+ICsgICAgICAgYnVz
LT5tc2kgPSBjb250YWluZXJfb2YoJnBwLT5pcnFfZG9tYWluLCBzdHJ1Y3QgbXNpX2NvbnRyb2xs
ZXIsDQo+IGRvbWFpbik7DQo+ID4gKyNlbHNlDQo+ID4gICAgICAgICBkd19wY2llX21zaV9jaGlw
LmRldiA9IHBwLT5kZXY7DQo+ID4gLSAgICAgICBkd19wY2kubXNpX2N0cmwgPSAmZHdfcGNpZV9t
c2lfY2hpcDsNCj4gPiArICAgICAgIGJ1cy0+bXNpID0gJmR3X3BjaWVfbXNpX2NoaXA7DQo+ID4g
ICNlbmRpZg0KPiA+DQo+ID4gLSAgICAgICBkd19wY2kubnJfY29udHJvbGxlcnMgPSAxOw0KPiA+
IC0gICAgICAgZHdfcGNpLnByaXZhdGVfZGF0YSA9ICh2b2lkICoqKSZwcDsNCj4gPiArICAgICAg
IHBjaV9zY2FuX2NoaWxkX2J1cyhidXMpOw0KPiA+ICsgICAgICAgaWYgKHBwLT5vcHMtPnNjYW5f
YnVzKQ0KPiA+ICsgICAgICAgICAgICAgICBwcC0+b3BzLT5zY2FuX2J1cyhwcCk7DQo+ID4gKw0K
PiA+ICsjaWZkZWYgQ09ORklHX0FSTQ0KPiA+ICsgICAgICAgLyogc3VwcG9ydCBvbGQgZHRicyB0
aGF0IGluY29ycmVjdGx5IGRlc2NyaWJlIElSUXMgKi8NCj4gPiArICAgICAgIHBjaV9maXh1cF9p
cnFzKHBjaV9jb21tb25fc3dpenpsZSwgb2ZfaXJxX3BhcnNlX2FuZF9tYXBfcGNpKTsNCj4gPiAr
I2VuZGlmDQo+ID4NCj4gPiAtICAgICAgIHBjaV9jb21tb25faW5pdF9kZXYocHAtPmRldiwgJmR3
X3BjaSk7DQo+ID4gKyAgICAgICBwY2lfYXNzaWduX3VuYXNzaWduZWRfYnVzX3Jlc291cmNlcyhi
dXMpOw0KPiA+ICsgICAgICAgcGNpX2J1c19hZGRfZGV2aWNlcyhidXMpOw0KPiA+DQo+ID4gICAg
ICAgICByZXR1cm4gMDsNCj4gPiAgfQ0KPiA+IEBAIC01NDQsMTIgKzUyNCwxMiBAQCBzdGF0aWMg
aW50IGR3X3BjaWVfcmRfb3RoZXJfY29uZihzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwNCj4gc3RydWN0
IHBjaV9idXMgKmJ1cywNCj4gPg0KPiA+ICAgICAgICAgaWYgKGJ1cy0+cGFyZW50LT5udW1iZXIg
PT0gcHAtPnJvb3RfYnVzX25yKSB7DQo+ID4gICAgICAgICAgICAgICAgIHR5cGUgPSBQQ0lFX0FU
VV9UWVBFX0NGRzA7DQo+ID4gLSAgICAgICAgICAgICAgIGNwdV9hZGRyID0gcHAtPmNmZzBfbW9k
X2Jhc2U7DQo+ID4gKyAgICAgICAgICAgICAgIGNwdV9hZGRyID0gcHAtPmNmZzBfYmFzZTsNCj4g
PiAgICAgICAgICAgICAgICAgY2ZnX3NpemUgPSBwcC0+Y2ZnMF9zaXplOw0KPiA+ICAgICAgICAg
ICAgICAgICB2YV9jZmdfYmFzZSA9IHBwLT52YV9jZmcwX2Jhc2U7DQo+ID4gICAgICAgICB9IGVs
c2Ugew0KPiA+ICAgICAgICAgICAgICAgICB0eXBlID0gUENJRV9BVFVfVFlQRV9DRkcxOw0KPiA+
IC0gICAgICAgICAgICAgICBjcHVfYWRkciA9IHBwLT5jZmcxX21vZF9iYXNlOw0KPiA+ICsgICAg
ICAgICAgICAgICBjcHVfYWRkciA9IHBwLT5jZmcxX2Jhc2U7DQo+ID4gICAgICAgICAgICAgICAg
IGNmZ19zaXplID0gcHAtPmNmZzFfc2l6ZTsNCj4gPiAgICAgICAgICAgICAgICAgdmFfY2ZnX2Jh
c2UgPSBwcC0+dmFfY2ZnMV9iYXNlOw0KPiA+ICAgICAgICAgfQ0KPiA+IEBAIC01NTksNyArNTM5
LDcgQEAgc3RhdGljIGludCBkd19wY2llX3JkX290aGVyX2NvbmYoc3RydWN0IHBjaWVfcG9ydCAq
cHAsDQo+IHN0cnVjdCBwY2lfYnVzICpidXMsDQo+ID4gICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgIGJ1c2RldiwgY2ZnX3NpemUpOw0KPiA+ICAgICAgICAgcmV0ID0gZHdfcGNpZV9j
ZmdfcmVhZCh2YV9jZmdfYmFzZSArIGFkZHJlc3MsIHdoZXJlLCBzaXplLCB2YWwpOw0KPiA+ICAg
ICAgICAgZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVY
MCwNCj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJRV9BVFVfVFlQRV9J
TywgcHAtPmlvX21vZF9iYXNlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fYmFzZSwNCj4gPiAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgcHAtPmlvX2J1c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQo+ID4NCj4gPiAg
ICAgICAgIHJldHVybiByZXQ7DQo+ID4gQEAgLTU3OSwxMiArNTU5LDEyIEBAIHN0YXRpYyBpbnQg
ZHdfcGNpZV93cl9vdGhlcl9jb25mKHN0cnVjdCBwY2llX3BvcnQgKnBwLA0KPiBzdHJ1Y3QgcGNp
X2J1cyAqYnVzLA0KPiA+DQo+ID4gICAgICAgICBpZiAoYnVzLT5wYXJlbnQtPm51bWJlciA9PSBw
cC0+cm9vdF9idXNfbnIpIHsNCj4gPiAgICAgICAgICAgICAgICAgdHlwZSA9IFBDSUVfQVRVX1RZ
UEVfQ0ZHMDsNCj4gPiAtICAgICAgICAgICAgICAgY3B1X2FkZHIgPSBwcC0+Y2ZnMF9tb2RfYmFz
ZTsNCj4gPiArICAgICAgICAgICAgICAgY3B1X2FkZHIgPSBwcC0+Y2ZnMF9iYXNlOw0KPiA+ICAg
ICAgICAgICAgICAgICBjZmdfc2l6ZSA9IHBwLT5jZmcwX3NpemU7DQo+ID4gICAgICAgICAgICAg
ICAgIHZhX2NmZ19iYXNlID0gcHAtPnZhX2NmZzBfYmFzZTsNCj4gPiAgICAgICAgIH0gZWxzZSB7
DQo+ID4gICAgICAgICAgICAgICAgIHR5cGUgPSBQQ0lFX0FUVV9UWVBFX0NGRzE7DQo+ID4gLSAg
ICAgICAgICAgICAgIGNwdV9hZGRyID0gcHAtPmNmZzFfbW9kX2Jhc2U7DQo+ID4gKyAgICAgICAg
ICAgICAgIGNwdV9hZGRyID0gcHAtPmNmZzFfYmFzZTsNCj4gPiAgICAgICAgICAgICAgICAgY2Zn
X3NpemUgPSBwcC0+Y2ZnMV9zaXplOw0KPiA+ICAgICAgICAgICAgICAgICB2YV9jZmdfYmFzZSA9
IHBwLT52YV9jZmcxX2Jhc2U7DQo+ID4gICAgICAgICB9DQo+ID4gQEAgLTU5NCw3ICs1NzQsNyBA
QCBzdGF0aWMgaW50IGR3X3BjaWVfd3Jfb3RoZXJfY29uZihzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwN
Cj4gc3RydWN0IHBjaV9idXMgKmJ1cywNCj4gPiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgYnVzZGV2LCBjZmdfc2l6ZSk7DQo+ID4gICAgICAgICByZXQgPSBkd19wY2llX2NmZ193
cml0ZSh2YV9jZmdfYmFzZSArIGFkZHJlc3MsIHdoZXJlLCBzaXplLCB2YWwpOw0KPiA+ICAgICAg
ICAgZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVYMCwN
Cj4gPiAtICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJRV9BVFVfVFlQRV9JTywg
cHAtPmlvX21vZF9iYXNlLA0KPiA+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQ
Q0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fYmFzZSwNCj4gPiAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgcHAtPmlvX2J1c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQo+ID4NCj4gPiAgICAg
ICAgIHJldHVybiByZXQ7DQo+ID4gQEAgLTYyNiw3ICs2MDYsNyBAQCBzdGF0aWMgaW50IGR3X3Bj
aWVfdmFsaWRfY29uZmlnKHN0cnVjdCBwY2llX3BvcnQgKnBwLA0KPiA+ICBzdGF0aWMgaW50IGR3
X3BjaWVfcmRfY29uZihzdHJ1Y3QgcGNpX2J1cyAqYnVzLCB1MzIgZGV2Zm4sIGludCB3aGVyZSwN
Cj4gPiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSwgdTMyICp2YWwpDQo+ID4gIHsN
Cj4gPiAtICAgICAgIHN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoYnVzLT5zeXNk
YXRhKTsNCj4gPiArICAgICAgIHN0cnVjdCBwY2llX3BvcnQgKnBwID0gYnVzLT5zeXNkYXRhOw0K
PiA+ICAgICAgICAgaW50IHJldDsNCj4gPg0KPiA+ICAgICAgICAgaWYgKGR3X3BjaWVfdmFsaWRf
Y29uZmlnKHBwLCBidXMsIFBDSV9TTE9UKGRldmZuKSkgPT0gMCkgew0KPiA+IEBAIC02NTAsNyAr
NjMwLDcgQEAgc3RhdGljIGludCBkd19wY2llX3JkX2NvbmYoc3RydWN0IHBjaV9idXMgKmJ1cywg
dTMyDQo+IGRldmZuLCBpbnQgd2hlcmUsDQo+ID4gIHN0YXRpYyBpbnQgZHdfcGNpZV93cl9jb25m
KHN0cnVjdCBwY2lfYnVzICpidXMsIHUzMiBkZXZmbiwNCj4gPiAgICAgICAgICAgICAgICAgICAg
ICAgICBpbnQgd2hlcmUsIGludCBzaXplLCB1MzIgdmFsKQ0KPiA+ICB7DQo+ID4gLSAgICAgICBz
dHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKGJ1cy0+c3lzZGF0YSk7DQo+ID4gKyAg
ICAgICBzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IGJ1cy0+c3lzZGF0YTsNCj4gPiAgICAgICAgIGlu
dCByZXQ7DQo+ID4NCj4gPiAgICAgICAgIGlmIChkd19wY2llX3ZhbGlkX2NvbmZpZyhwcCwgYnVz
LCBQQ0lfU0xPVChkZXZmbikpID09IDApDQo+ID4gQEAgLTY3NCw2MiArNjU0LDYgQEAgc3RhdGlj
IHN0cnVjdCBwY2lfb3BzIGR3X3BjaWVfb3BzID0gew0KPiA+ICAgICAgICAgLndyaXRlID0gZHdf
cGNpZV93cl9jb25mLA0KPiA+ICB9Ow0KPiA+DQo+ID4gLXN0YXRpYyBpbnQgZHdfcGNpZV9zZXR1
cChpbnQgbnIsIHN0cnVjdCBwY2lfc3lzX2RhdGEgKnN5cykNCj4gPiAtew0KPiA+IC0gICAgICAg
c3RydWN0IHBjaWVfcG9ydCAqcHA7DQo+ID4gLQ0KPiA+IC0gICAgICAgcHAgPSBzeXNfdG9fcGNp
ZShzeXMpOw0KPiA+IC0NCj4gPiAtICAgICAgIGlmIChnbG9iYWxfaW9fb2Zmc2V0IDwgU1pfMU0g
JiYgcHAtPmlvX3NpemUgPiAwKSB7DQo+ID4gLSAgICAgICAgICAgICAgIHN5cy0+aW9fb2Zmc2V0
ID0gZ2xvYmFsX2lvX29mZnNldCAtIHBwLT5pb19idXNfYWRkcjsNCj4gPiAtICAgICAgICAgICAg
ICAgcGNpX2lvcmVtYXBfaW8oZ2xvYmFsX2lvX29mZnNldCwgcHAtPmlvX2Jhc2UpOw0KPiA+IC0g
ICAgICAgICAgICAgICBnbG9iYWxfaW9fb2Zmc2V0ICs9IFNaXzY0SzsNCj4gPiAtICAgICAgICAg
ICAgICAgcGNpX2FkZF9yZXNvdXJjZV9vZmZzZXQoJnN5cy0+cmVzb3VyY2VzLCAmcHAtPmlvLA0K
PiA+IC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXMtPmlvX29mZnNl
dCk7DQo+ID4gLSAgICAgICB9DQo+ID4gLQ0KPiA+IC0gICAgICAgc3lzLT5tZW1fb2Zmc2V0ID0g
cHAtPm1lbS5zdGFydCAtIHBwLT5tZW1fYnVzX2FkZHI7DQo+ID4gLSAgICAgICBwY2lfYWRkX3Jl
c291cmNlX29mZnNldCgmc3lzLT5yZXNvdXJjZXMsICZwcC0+bWVtLCBzeXMtPm1lbV9vZmZzZXQp
Ow0KPiA+IC0gICAgICAgcGNpX2FkZF9yZXNvdXJjZSgmc3lzLT5yZXNvdXJjZXMsICZwcC0+YnVz
bik7DQo+ID4gLQ0KPiA+IC0gICAgICAgcmV0dXJuIDE7DQo+ID4gLX0NCj4gPiAtDQo+ID4gLXN0
YXRpYyBzdHJ1Y3QgcGNpX2J1cyAqZHdfcGNpZV9zY2FuX2J1cyhpbnQgbnIsIHN0cnVjdCBwY2lf
c3lzX2RhdGEgKnN5cykNCj4gPiAtew0KPiA+IC0gICAgICAgc3RydWN0IHBjaV9idXMgKmJ1czsN
Cj4gPiAtICAgICAgIHN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoc3lzKTsNCj4g
PiAtDQo+ID4gLSAgICAgICBwcC0+cm9vdF9idXNfbnIgPSBzeXMtPmJ1c25yOw0KPiA+IC0gICAg
ICAgYnVzID0gcGNpX3NjYW5fcm9vdF9idXMocHAtPmRldiwgc3lzLT5idXNuciwNCj4gPiAtICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmR3X3BjaWVfb3BzLCBzeXMsICZzeXMtPnJl
c291cmNlcyk7DQo+ID4gLSAgICAgICBpZiAoIWJ1cykNCj4gPiAtICAgICAgICAgICAgICAgcmV0
dXJuIE5VTEw7DQo+ID4gLQ0KPiA+IC0gICAgICAgaWYgKGJ1cyAmJiBwcC0+b3BzLT5zY2FuX2J1
cykNCj4gPiAtICAgICAgICAgICAgICAgcHAtPm9wcy0+c2Nhbl9idXMocHApOw0KPiA+IC0NCj4g
PiAtICAgICAgIHJldHVybiBidXM7DQo+ID4gLX0NCj4gPiAtDQo+ID4gLXN0YXRpYyBpbnQgZHdf
cGNpZV9tYXBfaXJxKGNvbnN0IHN0cnVjdCBwY2lfZGV2ICpkZXYsIHU4IHNsb3QsIHU4IHBpbikN
Cj4gPiAtew0KPiA+IC0gICAgICAgc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBzeXNfdG9fcGNpZShk
ZXYtPmJ1cy0+c3lzZGF0YSk7DQo+ID4gLSAgICAgICBpbnQgaXJxOw0KPiA+IC0NCj4gPiAtICAg
ICAgIGlycSA9IG9mX2lycV9wYXJzZV9hbmRfbWFwX3BjaShkZXYsIHNsb3QsIHBpbik7DQo+ID4g
LSAgICAgICBpZiAoIWlycSkNCj4gPiAtICAgICAgICAgICAgICAgaXJxID0gcHAtPmlycTsNCj4g
PiAtDQo+ID4gLSAgICAgICByZXR1cm4gaXJxOw0KPiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0aWMg
c3RydWN0IGh3X3BjaSBkd19wY2kgPSB7DQo+ID4gLSAgICAgICAuc2V0dXAgICAgICAgICAgPSBk
d19wY2llX3NldHVwLA0KPiA+IC0gICAgICAgLnNjYW4gICAgICAgICAgID0gZHdfcGNpZV9zY2Fu
X2J1cywNCj4gPiAtICAgICAgIC5tYXBfaXJxICAgICAgICA9IGR3X3BjaWVfbWFwX2lycSwNCj4g
PiAtfTsNCj4gPiAtDQo+ID4gIHZvaWQgZHdfcGNpZV9zZXR1cF9yYyhzdHJ1Y3QgcGNpZV9wb3J0
ICpwcCkNCj4gPiAgew0KPiA+ICAgICAgICAgdTMyIHZhbDsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJp
dmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaCBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS0N
Cj4gZGVzaWdud2FyZS5oDQo+ID4gaW5kZXggZDBiYmQyNy4uMjY0Yzk2OSAxMDA2NDQNCj4gPiAt
LS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5oDQo+ID4gKysrIGIvZHJpdmVy
cy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaA0KPiA+IEBAIC0yNywyNSArMjcsMjEgQEAgc3Ry
dWN0IHBjaWVfcG9ydCB7DQo+ID4gICAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICByb290
X2J1c19ucjsNCj4gPiAgICAgICAgIHZvaWQgX19pb21lbSAgICAgICAgICAgICpkYmlfYmFzZTsN
Cj4gPiAgICAgICAgIHU2NCAgICAgICAgICAgICAgICAgICAgIGNmZzBfYmFzZTsNCj4gPiAtICAg
ICAgIHU2NCAgICAgICAgICAgICAgICAgICAgIGNmZzBfbW9kX2Jhc2U7DQo+ID4gICAgICAgICB2
b2lkIF9faW9tZW0gICAgICAgICAgICAqdmFfY2ZnMF9iYXNlOw0KPiA+ICAgICAgICAgdTMyICAg
ICAgICAgICAgICAgICAgICAgY2ZnMF9zaXplOw0KPiA+ICAgICAgICAgdTY0ICAgICAgICAgICAg
ICAgICAgICAgY2ZnMV9iYXNlOw0KPiA+IC0gICAgICAgdTY0ICAgICAgICAgICAgICAgICAgICAg
Y2ZnMV9tb2RfYmFzZTsNCj4gPiAgICAgICAgIHZvaWQgX19pb21lbSAgICAgICAgICAgICp2YV9j
ZmcxX2Jhc2U7DQo+ID4gICAgICAgICB1MzIgICAgICAgICAgICAgICAgICAgICBjZmcxX3NpemU7
DQo+ID4gLSAgICAgICB1NjQgICAgICAgICAgICAgICAgICAgICBpb19iYXNlOw0KPiA+IC0gICAg
ICAgdTY0ICAgICAgICAgICAgICAgICAgICAgaW9fbW9kX2Jhc2U7DQo+ID4gKyAgICAgICByZXNv
dXJjZV9zaXplX3QgICAgICAgICBpb19iYXNlOw0KPiA+ICAgICAgICAgcGh5c19hZGRyX3QgICAg
ICAgICAgICAgaW9fYnVzX2FkZHI7DQo+ID4gICAgICAgICB1MzIgICAgICAgICAgICAgICAgICAg
ICBpb19zaXplOw0KPiA+ICAgICAgICAgdTY0ICAgICAgICAgICAgICAgICAgICAgbWVtX2Jhc2U7
DQo+ID4gLSAgICAgICB1NjQgICAgICAgICAgICAgICAgICAgICBtZW1fbW9kX2Jhc2U7DQo+ID4g
ICAgICAgICBwaHlzX2FkZHJfdCAgICAgICAgICAgICBtZW1fYnVzX2FkZHI7DQo+ID4gICAgICAg
ICB1MzIgICAgICAgICAgICAgICAgICAgICBtZW1fc2l6ZTsNCj4gPiAtICAgICAgIHN0cnVjdCBy
ZXNvdXJjZSAgICAgICAgIGNmZzsNCj4gPiAtICAgICAgIHN0cnVjdCByZXNvdXJjZSAgICAgICAg
IGlvOw0KPiA+IC0gICAgICAgc3RydWN0IHJlc291cmNlICAgICAgICAgbWVtOw0KPiA+IC0gICAg
ICAgc3RydWN0IHJlc291cmNlICAgICAgICAgYnVzbjsNCj4gPiArICAgICAgIHN0cnVjdCByZXNv
dXJjZSAgICAgICAgICpjZmc7DQo+ID4gKyAgICAgICBzdHJ1Y3QgcmVzb3VyY2UgICAgICAgICAq
aW87DQo+ID4gKyAgICAgICBzdHJ1Y3QgcmVzb3VyY2UgICAgICAgICAqbWVtOw0KPiA+ICsgICAg
ICAgc3RydWN0IHJlc291cmNlICAgICAgICAgKmJ1c247DQo+ID4gICAgICAgICBpbnQgICAgICAg
ICAgICAgICAgICAgICBpcnE7DQo+ID4gICAgICAgICB1MzIgICAgICAgICAgICAgICAgICAgICBs
YW5lczsNCj4gPiAgICAgICAgIHN0cnVjdCBwY2llX2hvc3Rfb3BzICAgICpvcHM7DQo+ID4gLS0N
Cj4gPiAxLjkuMQ0KPiA+DQo+ID4NCj4gPiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fXw0KPiA+IGxpbnV4LWFybS1rZXJuZWwgbWFpbGluZyBsaXN0DQo+ID4g
bGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnDQo+ID4gaHR0cDovL2xpc3RzLmlu
ZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1hcm0ta2VybmVsDQo+IC0tDQo+IFRv
IHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBs
aW51eC1wY2kiIGluDQo+IHRoZSBib2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5r
ZXJuZWwub3JnDQo+IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5v
cmcvbWFqb3Jkb21vLWluZm8uaHRtbA0K

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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-27 15:21         ` Gabriele Paoloni
  0 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-08-27 15:21 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 Gabriel Fernandez
> Sent: 27 August 2015 13:57
> To: Wangzhou (B)
> Cc: Bjorn Helgaas; jingoohan1 at gmail.com; pratyush.anand at gmail.com; Arnd
> Bergmann; Russell King; thomas.petazzoni at free-electrons.com; Gabriele Paoloni;
> lorenzo.pieralisi at arm.com; james.morse at arm.com; Liviu Dudau;
> jason at lakedaemon.net; robh at kernel.org; devicetree at vger.kernel.org; linux-
> pci at vger.kernel.org; xuwei (O); qiuzhenfa; liudongdong (C); zhangjukuo;
> Liguozhu (Kenneth); qiujiang; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
> 
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.

Many Thanks for this Gabriel

Cheers
Gab

> 
> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> > 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.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
> ARM64
> > according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> > with untranslated address" based on 1/6 in this series. we delete *_mod_base
> in
> > pcie-designware. This was discussed in [2]
> >
> > 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Tested-By: James Morse <james.morse@arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  14 +--
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pcie-designware.c | 230 +++++++++++++---------------------
> ---
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  4 files changed, 90 insertions(+), 170 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> > index 18ae7ff..ac401be 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
> >  {
> >         dw_pcie_setup_rc(pp);
> >
> > -       if (pp->io_mod_base)
> > -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->io_base)
> > +               pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->mem_mod_base)
> > -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->mem_base)
> > +               pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->cfg0_mod_base) {
> > -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->cfg0_base) {
> > +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >         }
> >
> >         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-
> designware.c
> > index c5d407c..e2d1898 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>
> > @@ -69,16 +70,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)
> >  {
> > @@ -255,7 +247,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));
> > @@ -298,7 +290,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;
> > @@ -327,7 +319,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);
> >  }
> > @@ -363,14 +355,12 @@ int 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;
> > -       u32 val, ns;
> > -       const __be32 *addrp;
> > -       int i, index, ret;
> > -
> > -       ns = of_n_size_cells(np);
> > +       LIST_HEAD(res);
> > +       u32 val;
> > +       int i, ret;
> > +       struct resource_entry *win;
> >
> >         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> "config");
> >         if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                 pp->cfg1_size = resource_size(cfg_res)/2;
> >                 pp->cfg0_base = cfg_res->start;
> >                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -               /* Find the untranslated configuration space address */
> > -               index = of_property_match_string(np, "reg-names", "config");
> > -               addrp = of_get_address(np, index, NULL, NULL);
> > -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> >         } else {
> >                 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 = range.cpu_addr;
> > -               }
> > -               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 = range.cpu_addr;
> > -               }
> > -               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;
> > -
> > -                       /* Find the untranslated configuration space address
> */
> > -                       pp->cfg0_mod_base = range.cpu_addr;
> > -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -                                           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;
> > +                       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;
> > +                       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;
> > +                       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,
> > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >
> >         if (!pp->ops->rd_other_conf)
> >                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > -                                         PCIE_ATU_TYPE_MEM, pp-
> >mem_mod_base,
> > +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
> >                                           pp->mem_bus_addr, pp->mem_size);
> >
> >         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >         val |= PORT_LOGIC_SPEED_CHANGE;
> >         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +       pp->root_bus_nr = pp->busn->start;
> > +       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
> >         dw_pcie_msi_chip.dev = pp->dev;
> > -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +       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);
> > +
> > +#ifdef CONFIG_ARM
> > +       /* support old dtbs that incorrectly describe IRQs */
> > +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -       pci_common_init_dev(pp->dev, &dw_pci);
> > +       pci_assign_unassigned_bus_resources(bus);
> > +       pci_bus_add_devices(bus);
> >
> >         return 0;
> >  }
> > @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp,
> struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -626,7 +606,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) {
> > @@ -650,7 +630,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)
> > @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> > -                                 &dw_pcie_ops, sys, &sys->resources);
> > -       if (!bus)
> > -               return NULL;
> > -
> > -       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..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >         u8                      root_bus_nr;
> >         void __iomem            *dbi_base;
> >         u64                     cfg0_base;
> > -       u64                     cfg0_mod_base;
> >         void __iomem            *va_cfg0_base;
> >         u32                     cfg0_size;
> >         u64                     cfg1_base;
> > -       u64                     cfg1_mod_base;
> >         void __iomem            *va_cfg1_base;
> >         u32                     cfg1_size;
> > -       u64                     io_base;
> > -       u64                     io_mod_base;
> > +       resource_size_t         io_base;
> >         phys_addr_t             io_bus_addr;
> >         u32                     io_size;
> >         u64                     mem_base;
> > -       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;
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> --
> 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] 37+ messages in thread

* Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-08-27 12:56     ` Gabriel Fernandez
  (?)
@ 2015-08-28  7:14       ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-28  7:14 UTC (permalink / raw)
  To: Gabriel Fernandez
  Cc: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann,
	Russell King, thomas.petazzoni, gabriele.paoloni,
	lorenzo.pieralisi, james.morse, Liviu Dudau, jason, robh,
	devicetree, linux-pci, xuwei5, qiuzhenfa, liudongdong3,
	zhangjukuo, liguozhu, qiujiang, linux-arm-kernel

On 2015/8/27 20:56, Gabriel Fernandez wrote:
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
>

Hi Gabriel,

It is very helpful to test this patch. Many thanks!

Best Regards,
Zhou

> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
>> 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.
>>
>> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
>> according to the suggestion for Gabriele[1]
>>
>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
>> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
>> pcie-designware. This was discussed in [2]
>>
>> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Tested-By: James Morse <james.morse@arm.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>> ---
>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>>  drivers/pci/host/pcie-designware.h |  14 +--
>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
>> index 18ae7ff..ac401be 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>>  {
>>         dw_pcie_setup_rc(pp);
>>
>> -       if (pp->io_mod_base)
>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->io_base)
>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->mem_mod_base)
>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->mem_base)
>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->cfg0_mod_base) {
>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->cfg0_base) {
>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>         }
>>
>>         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index c5d407c..e2d1898 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>
>> @@ -69,16 +70,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)
>>  {
>> @@ -255,7 +247,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));
>> @@ -298,7 +290,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;
>> @@ -327,7 +319,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);
>>  }
>> @@ -363,14 +355,12 @@ int 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;
>> -       u32 val, ns;
>> -       const __be32 *addrp;
>> -       int i, index, ret;
>> -
>> -       ns = of_n_size_cells(np);
>> +       LIST_HEAD(res);
>> +       u32 val;
>> +       int i, ret;
>> +       struct resource_entry *win;
>>
>>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>>         if (cfg_res) {
>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>                 pp->cfg0_base = cfg_res->start;
>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>> -
>> -               /* Find the untranslated configuration space address */
>> -               index = of_property_match_string(np, "reg-names", "config");
>> -               addrp = of_get_address(np, index, NULL, NULL);
>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>>         } else {
>>                 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 = range.cpu_addr;
>> -               }
>> -               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 = range.cpu_addr;
>> -               }
>> -               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;
>> -
>> -                       /* Find the untranslated configuration space address */
>> -                       pp->cfg0_mod_base = range.cpu_addr;
>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>> -                                           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;
>> +                       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;
>> +                       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;
>> +                       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,
>> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>
>>         if (!pp->ops->rd_other_conf)
>>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
>> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
>> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>>                                           pp->mem_bus_addr, pp->mem_size);
>>
>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>>
>> -#ifdef CONFIG_PCI_MSI
>> +       pp->root_bus_nr = pp->busn->start;
>> +       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
>>         dw_pcie_msi_chip.dev = pp->dev;
>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>> +       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);
>> +
>> +#ifdef CONFIG_ARM
>> +       /* support old dtbs that incorrectly describe IRQs */
>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +#endif
>>
>> -       pci_common_init_dev(pp->dev, &dw_pci);
>> +       pci_assign_unassigned_bus_resources(bus);
>> +       pci_bus_add_devices(bus);
>>
>>         return 0;
>>  }
>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -626,7 +606,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) {
>> @@ -650,7 +630,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)
>> @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>> -                                 &dw_pcie_ops, sys, &sys->resources);
>> -       if (!bus)
>> -               return NULL;
>> -
>> -       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..264c969 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -27,25 +27,21 @@ struct pcie_port {
>>         u8                      root_bus_nr;
>>         void __iomem            *dbi_base;
>>         u64                     cfg0_base;
>> -       u64                     cfg0_mod_base;
>>         void __iomem            *va_cfg0_base;
>>         u32                     cfg0_size;
>>         u64                     cfg1_base;
>> -       u64                     cfg1_mod_base;
>>         void __iomem            *va_cfg1_base;
>>         u32                     cfg1_size;
>> -       u64                     io_base;
>> -       u64                     io_mod_base;
>> +       resource_size_t         io_base;
>>         phys_addr_t             io_bus_addr;
>>         u32                     io_size;
>>         u64                     mem_base;
>> -       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;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 

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

* Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-28  7:14       ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-28  7:14 UTC (permalink / raw)
  To: Gabriel Fernandez
  Cc: Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann,
	Russell King, thomas.petazzoni, gabriele.paoloni,
	lorenzo.pieralisi, james.morse, Liviu Dudau, jason, robh,
	devicetree, linux-pci, xuwei5, qiuzhenfa, liudongdong3,
	zhangjukuo, liguozhu, qiujiang, linux-arm-kernel

On 2015/8/27 20:56, Gabriel Fernandez wrote:
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
>

Hi Gabriel,

It is very helpful to test this patch. Many thanks!

Best Regards,
Zhou

> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
>> 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.
>>
>> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
>> according to the suggestion for Gabriele[1]
>>
>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
>> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
>> pcie-designware. This was discussed in [2]
>>
>> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Tested-By: James Morse <james.morse@arm.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>> ---
>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>>  drivers/pci/host/pcie-designware.h |  14 +--
>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
>> index 18ae7ff..ac401be 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>>  {
>>         dw_pcie_setup_rc(pp);
>>
>> -       if (pp->io_mod_base)
>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->io_base)
>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->mem_mod_base)
>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->mem_base)
>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->cfg0_mod_base) {
>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->cfg0_base) {
>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>         }
>>
>>         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index c5d407c..e2d1898 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>
>> @@ -69,16 +70,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)
>>  {
>> @@ -255,7 +247,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));
>> @@ -298,7 +290,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;
>> @@ -327,7 +319,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);
>>  }
>> @@ -363,14 +355,12 @@ int 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;
>> -       u32 val, ns;
>> -       const __be32 *addrp;
>> -       int i, index, ret;
>> -
>> -       ns = of_n_size_cells(np);
>> +       LIST_HEAD(res);
>> +       u32 val;
>> +       int i, ret;
>> +       struct resource_entry *win;
>>
>>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>>         if (cfg_res) {
>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>                 pp->cfg0_base = cfg_res->start;
>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>> -
>> -               /* Find the untranslated configuration space address */
>> -               index = of_property_match_string(np, "reg-names", "config");
>> -               addrp = of_get_address(np, index, NULL, NULL);
>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>>         } else {
>>                 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 = range.cpu_addr;
>> -               }
>> -               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 = range.cpu_addr;
>> -               }
>> -               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;
>> -
>> -                       /* Find the untranslated configuration space address */
>> -                       pp->cfg0_mod_base = range.cpu_addr;
>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>> -                                           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;
>> +                       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;
>> +                       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;
>> +                       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,
>> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>
>>         if (!pp->ops->rd_other_conf)
>>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
>> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
>> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>>                                           pp->mem_bus_addr, pp->mem_size);
>>
>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>>
>> -#ifdef CONFIG_PCI_MSI
>> +       pp->root_bus_nr = pp->busn->start;
>> +       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
>>         dw_pcie_msi_chip.dev = pp->dev;
>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>> +       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);
>> +
>> +#ifdef CONFIG_ARM
>> +       /* support old dtbs that incorrectly describe IRQs */
>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +#endif
>>
>> -       pci_common_init_dev(pp->dev, &dw_pci);
>> +       pci_assign_unassigned_bus_resources(bus);
>> +       pci_bus_add_devices(bus);
>>
>>         return 0;
>>  }
>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -626,7 +606,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) {
>> @@ -650,7 +630,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)
>> @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>> -                                 &dw_pcie_ops, sys, &sys->resources);
>> -       if (!bus)
>> -               return NULL;
>> -
>> -       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..264c969 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -27,25 +27,21 @@ struct pcie_port {
>>         u8                      root_bus_nr;
>>         void __iomem            *dbi_base;
>>         u64                     cfg0_base;
>> -       u64                     cfg0_mod_base;
>>         void __iomem            *va_cfg0_base;
>>         u32                     cfg0_size;
>>         u64                     cfg1_base;
>> -       u64                     cfg1_mod_base;
>>         void __iomem            *va_cfg1_base;
>>         u32                     cfg1_size;
>> -       u64                     io_base;
>> -       u64                     io_mod_base;
>> +       resource_size_t         io_base;
>>         phys_addr_t             io_bus_addr;
>>         u32                     io_size;
>>         u64                     mem_base;
>> -       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;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 



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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-08-28  7:14       ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-08-28  7:14 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/8/27 20:56, Gabriel Fernandez wrote:
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
>

Hi Gabriel,

It is very helpful to test this patch. Many thanks!

Best Regards,
Zhou

> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
>> 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.
>>
>> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
>> according to the suggestion for Gabriele[1]
>>
>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
>> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
>> pcie-designware. This was discussed in [2]
>>
>> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>> Tested-By: James Morse <james.morse@arm.com>
>>
>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>> ---
>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>  drivers/pci/host/pcie-designware.c | 230 +++++++++++++------------------------
>>  drivers/pci/host/pcie-designware.h |  14 +--
>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>
>> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
>> index 18ae7ff..ac401be 100644
>> --- a/drivers/pci/host/pci-dra7xx.c
>> +++ b/drivers/pci/host/pci-dra7xx.c
>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>>  {
>>         dw_pcie_setup_rc(pp);
>>
>> -       if (pp->io_mod_base)
>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->io_base)
>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->mem_mod_base)
>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->mem_base)
>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>
>> -       if (pp->cfg0_mod_base) {
>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>> +       if (pp->cfg0_base) {
>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>         }
>>
>>         dra7xx_pcie_establish_link(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/pcie-designware.c b/drivers/pci/host/pcie-designware.c
>> index c5d407c..e2d1898 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>
>> @@ -69,16 +70,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)
>>  {
>> @@ -255,7 +247,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));
>> @@ -298,7 +290,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;
>> @@ -327,7 +319,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);
>>  }
>> @@ -363,14 +355,12 @@ int 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;
>> -       u32 val, ns;
>> -       const __be32 *addrp;
>> -       int i, index, ret;
>> -
>> -       ns = of_n_size_cells(np);
>> +       LIST_HEAD(res);
>> +       u32 val;
>> +       int i, ret;
>> +       struct resource_entry *win;
>>
>>         cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>>         if (cfg_res) {
>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>                 pp->cfg0_base = cfg_res->start;
>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>> -
>> -               /* Find the untranslated configuration space address */
>> -               index = of_property_match_string(np, "reg-names", "config");
>> -               addrp = of_get_address(np, index, NULL, NULL);
>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>> -               pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>>         } else {
>>                 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 = range.cpu_addr;
>> -               }
>> -               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 = range.cpu_addr;
>> -               }
>> -               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;
>> -
>> -                       /* Find the untranslated configuration space address */
>> -                       pp->cfg0_mod_base = range.cpu_addr;
>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>> -                                           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;
>> +                       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;
>> +                       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;
>> +                       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,
>> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>
>>         if (!pp->ops->rd_other_conf)
>>                 dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
>> -                                         PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
>> +                                         PCIE_ATU_TYPE_MEM, pp->mem_base,
>>                                           pp->mem_bus_addr, pp->mem_size);
>>
>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
>> @@ -517,15 +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>>
>> -#ifdef CONFIG_PCI_MSI
>> +       pp->root_bus_nr = pp->busn->start;
>> +       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
>>         dw_pcie_msi_chip.dev = pp->dev;
>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>> +       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);
>> +
>> +#ifdef CONFIG_ARM
>> +       /* support old dtbs that incorrectly describe IRQs */
>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>> +#endif
>>
>> -       pci_common_init_dev(pp->dev, &dw_pci);
>> +       pci_assign_unassigned_bus_resources(bus);
>> +       pci_bus_add_devices(bus);
>>
>>         return 0;
>>  }
>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>
>>         if (bus->parent->number == pp->root_bus_nr) {
>>                 type = PCIE_ATU_TYPE_CFG0;
>> -               cpu_addr = pp->cfg0_mod_base;
>> +               cpu_addr = pp->cfg0_base;
>>                 cfg_size = pp->cfg0_size;
>>                 va_cfg_base = pp->va_cfg0_base;
>>         } else {
>>                 type = PCIE_ATU_TYPE_CFG1;
>> -               cpu_addr = pp->cfg1_mod_base;
>> +               cpu_addr = pp->cfg1_base;
>>                 cfg_size = pp->cfg1_size;
>>                 va_cfg_base = pp->va_cfg1_base;
>>         }
>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>>                                   busdev, cfg_size);
>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>> -                                 PCIE_ATU_TYPE_IO, pp->io_mod_base,
>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>                                   pp->io_bus_addr, pp->io_size);
>>
>>         return ret;
>> @@ -626,7 +606,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) {
>> @@ -650,7 +630,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)
>> @@ -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>> -                                 &dw_pcie_ops, sys, &sys->resources);
>> -       if (!bus)
>> -               return NULL;
>> -
>> -       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..264c969 100644
>> --- a/drivers/pci/host/pcie-designware.h
>> +++ b/drivers/pci/host/pcie-designware.h
>> @@ -27,25 +27,21 @@ struct pcie_port {
>>         u8                      root_bus_nr;
>>         void __iomem            *dbi_base;
>>         u64                     cfg0_base;
>> -       u64                     cfg0_mod_base;
>>         void __iomem            *va_cfg0_base;
>>         u32                     cfg0_size;
>>         u64                     cfg1_base;
>> -       u64                     cfg1_mod_base;
>>         void __iomem            *va_cfg1_base;
>>         u32                     cfg1_size;
>> -       u64                     io_base;
>> -       u64                     io_mod_base;
>> +       resource_size_t         io_base;
>>         phys_addr_t             io_bus_addr;
>>         u32                     io_size;
>>         u64                     mem_base;
>> -       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;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> .
> 

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

* RE: [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
  2015-08-25  9:58 ` Zhou Wang
  (?)
@ 2015-09-07  8:17   ` Gabriele Paoloni
  -1 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-09-07  8:17 UTC (permalink / raw)
  To: Wangzhou (B),
	Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, lorenzo.pieralisi, james.morse, Liviu.Dudau,
	jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong (C), qiujiang, xuwei (O), Liguozhu (Kenneth)

Hi Bjorn and all

Do you have any comment on this patchset? I think we should be close to a final one...

Thanks and Regards

Gab

> -----Original Message-----
> From: Wangzhou (B)
> Sent: 25 August 2015 10:59
> To: Bjorn Helgaas; jingoohan1@gmail.com; pratyush.anand@gmail.com; Arnd
> Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-electrons.com;
> Gabriele Paoloni; lorenzo.pieralisi@arm.com; james.morse@arm.com;
> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org
> Cc: linux-pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> devicetree@vger.kernel.org; zhangjukuo; qiuzhenfa; liudongdong (C); qiujiang;
> xuwei (O); Liguozhu (Kenneth); Wangzhou (B)
> Subject: [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
> Hip05
> 
> 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.
> 
> This patchset is based on v4.2-rc1.
> 
> Change from v7:
> - Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
>   spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
> - Remove bus-range parsing in pcie-hisi.c.
> 
> Change from v6:
> - Add Pratyush's Acked-by for 1/6 and 2/6.
> - Add James' Tested-by for 3/6.
> 
> Change from v5:
> - Merge 1/6 in this series, discussion about this can be found in [1]
> 
> Change from v4:
> - Change the author of 1/5 to Gabriele.
> - Modify problems in 3/5 pointed by Bjorn.
> - Modify spelling problems in 4/5.
> 
> Change from v3:
> - Change 1/5 to what Gabriele suggested.
> - Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.
> 
> 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 v7:
> - http://www.spinics.net/lists/devicetree/msg90690.html
> Link of v6:
> - http://www.spinics.net/lists/linux-pci/msg43669.html
> Link of v5:
> - http://www.spinics.net/lists/devicetree/msg87959.html
> Link of v4:
> - http://www.spinics.net/lists/arm-kernel/msg433050.html
> Link of v3:
> - http://www.spinics.net/lists/linux-pci/msg42539.html
> 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
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-
> July/359741.html
> 
> 
> Zhou Wang (4):
>   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
> 
> gabriele paoloni (2):
>   PCI: designware: move calculation of bus addresses to DRA7xx
>   ARM/PCI: remove align_resource in pci_sys_data
> 
>  .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
>  MAINTAINERS                                        |   7 +
>  arch/arm/include/asm/mach/pci.h                    |   5 -
>  arch/arm/kernel/bios32.c                           |  12 +-
>  drivers/pci/host/Kconfig                           |   8 +
>  drivers/pci/host/Makefile                          |   1 +
>  drivers/pci/host/pci-dra7xx.c                      |  13 ++
>  drivers/pci/host/pci-keystone-dw.c                 |   2 +-
>  drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
>  drivers/pci/host/pcie-designware.h                 |  14 +-
>  drivers/pci/host/pcie-hisi.c                       | 247
> +++++++++++++++++++++
>  11 files changed, 413 insertions(+), 179 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] 37+ messages in thread

* RE: [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-09-07  8:17   ` Gabriele Paoloni
  0 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-09-07  8:17 UTC (permalink / raw)
  To: Wangzhou (B),
	Bjorn Helgaas, jingoohan1, pratyush.anand, Arnd Bergmann, linux,
	thomas.petazzoni, lorenzo.pieralisi, james.morse, Liviu.Dudau,
	jason, robh
  Cc: linux-pci, linux-arm-kernel, devicetree, zhangjukuo, qiuzhenfa,
	liudongdong (C), qiujiang, xuwei (O), Liguozhu (Kenneth)

SGkgQmpvcm4gYW5kIGFsbA0KDQpEbyB5b3UgaGF2ZSBhbnkgY29tbWVudCBvbiB0aGlzIHBhdGNo
c2V0PyBJIHRoaW5rIHdlIHNob3VsZCBiZSBjbG9zZSB0byBhIGZpbmFsIG9uZS4uLg0KDQpUaGFu
a3MgYW5kIFJlZ2FyZHMNCg0KR2FiDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4g
RnJvbTogV2FuZ3pob3UgKEIpDQo+IFNlbnQ6IDI1IEF1Z3VzdCAyMDE1IDEwOjU5DQo+IFRvOiBC
am9ybiBIZWxnYWFzOyBqaW5nb29oYW4xQGdtYWlsLmNvbTsgcHJhdHl1c2guYW5hbmRAZ21haWwu
Y29tOyBBcm5kDQo+IEJlcmdtYW5uOyBsaW51eEBhcm0ubGludXgub3JnLnVrOyB0aG9tYXMucGV0
YXp6b25pQGZyZWUtZWxlY3Ryb25zLmNvbTsNCj4gR2FicmllbGUgUGFvbG9uaTsgbG9yZW56by5w
aWVyYWxpc2lAYXJtLmNvbTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gTGl2aXUuRHVkYXVAYXJt
LmNvbTsgamFzb25AbGFrZWRhZW1vbi5uZXQ7IHJvYmhAa2VybmVsLm9yZw0KPiBDYzogbGludXgt
cGNpQHZnZXIua2VybmVsLm9yZzsgbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3Jn
Ow0KPiBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsgemhhbmdqdWt1bzsgcWl1emhlbmZhOyBs
aXVkb25nZG9uZyAoQyk7IHFpdWppYW5nOw0KPiB4dXdlaSAoTyk7IExpZ3Vvemh1IChLZW5uZXRo
KTsgV2FuZ3pob3UgKEIpDQo+IFN1YmplY3Q6IFtQQVRDSCB2OCAwLzZdIFBDSTogaGlzaTogQWRk
IFBDSWUgaG9zdCBzdXBwb3J0IGZvciBIaVNpbGljb24gU29DDQo+IEhpcDA1DQo+IA0KPiBUaGlz
IHBhdGNoc2V0IGFkZHMgUENJZSBob3N0IHN1cHBvcnQgZm9yIEhpU2lsaWNvbiBTb0MgSGlwMDUu
IFRoZSBQQ0llIGhvc3RzDQo+IHVzZSBQQ0llIElQIGNvcmUgZnJvbSBTeW5vcHN5cywgU28gdGhp
cyBkcml2ZXIgaXMgYmFzZSBvbiBkZXNpZ253YXJlIFBDSWUNCj4gZHJpdmVyLg0KPiANCj4gSGlw
MDUgaXMgYW4gQVJNdjggYXJjaGl0ZWN0dXJlIFNvQy4gSXQgc2hvdWxkIGJlIGFibGUgdG8gdXNl
IEFSTTY0IFBDSWUgQVBJIGluDQo+IGRlc2lnbmV3YXJlIFBDSWUgZHJpdmVyLiBTbyB0aGlzIHBh
dGNoIGFsc28gYWRkcyBBUk02NCBzdXBwb3J0IGZvciBkZXNpZ253YXJlDQo+IHBjaWUuDQo+IA0K
PiBUaGlzIHBhdGNoc2V0IGlzIGJhc2VkIG9uIHY0LjItcmMxLg0KPiANCj4gQ2hhbmdlIGZyb20g
djc6DQo+IC0gUmVtb3ZlIHBwLT5yb290X2J1c19uciA9IDAgaW4gZHJhN3h4LCBleHlub3MsIGlt
eDYsIGtleXN0b25lLCBsYXllcnNjYXBlLA0KPiAgIHNwZWFyMTN4eC4gUGFzcyBwcC0+YnVzbi0+
c3RhcnQgdG8gcGNpX2NyZWF0ZV9yb290X2J1cyBhcyByb290IGJ1cyBudW1iZXIuDQo+IC0gUmVt
b3ZlIGJ1cy1yYW5nZSBwYXJzaW5nIGluIHBjaWUtaGlzaS5jLg0KPiANCj4gQ2hhbmdlIGZyb20g
djY6DQo+IC0gQWRkIFByYXR5dXNoJ3MgQWNrZWQtYnkgZm9yIDEvNiBhbmQgMi82Lg0KPiAtIEFk
ZCBKYW1lcycgVGVzdGVkLWJ5IGZvciAzLzYuDQo+IA0KPiBDaGFuZ2UgZnJvbSB2NToNCj4gLSBN
ZXJnZSAxLzYgaW4gdGhpcyBzZXJpZXMsIGRpc2N1c3Npb24gYWJvdXQgdGhpcyBjYW4gYmUgZm91
bmQgaW4gWzFdDQo+IA0KPiBDaGFuZ2UgZnJvbSB2NDoNCj4gLSBDaGFuZ2UgdGhlIGF1dGhvciBv
ZiAxLzUgdG8gR2FicmllbGUuDQo+IC0gTW9kaWZ5IHByb2JsZW1zIGluIDMvNSBwb2ludGVkIGJ5
IEJqb3JuLg0KPiAtIE1vZGlmeSBzcGVsbGluZyBwcm9ibGVtcyBpbiA0LzUuDQo+IA0KPiBDaGFu
Z2UgZnJvbSB2MzoNCj4gLSBDaGFuZ2UgMS81IHRvIHdoYXQgR2FicmllbGUgc3VnZ2VzdGVkLg0K
PiAtIFVzZSB3aW4tPl9fcmVzLnN0YXJ0IHRvIGdldCAqX21vZF9iYXNlIGluIDIvNSwgdGhpcyBm
aXggYSBidWcgaW4gdjMgc2VyaWVzLg0KPiANCj4gQ2hhbmdlIGZyb20gdjI6DQo+IC0gTW92ZSBz
dHJ1Y3QgcGNpX2RldiAqZGV2IGFuZCBzdHJ1Y3QgcGNpX3N5c19kYXRhICpzeXMgaW4NCj4gICBw
Y2liaW9zX2FsaWduX3Jlc291cmNlIGluIDEvNS4NCj4gLSBBZGQgR2FicmllbGUncyBjb2RlcyBp
biAyLzUgd2hpY2ggZGVsZXRlIHVubmVjZXNzYXJ5IGluZm9ybWF0aW9uIHBhcnNlIGFuZA0KPiAg
IHVzZSBvZl9wY2lfZ2V0X2hvc3RfYnJpZGdlX3Jlc291cmNlcyBmb3IgYm90aCBBUk0zMiBhbmQg
QVJNNjQuDQo+IC0gQWRkIG1haW50YWluZXIgcGF0Y2ggNS81Lg0KPiANCj4gQ2hhbmdlIGZyb20g
UkZDIHYxOg0KPiAtIEFkZCAxLzQgcGF0Y2ggYnkgQXJuZCB3aGljaCByZW1vdmVzIGFsaWduX3Jl
c291cmNlIGNhbGxiYWNrIGluIEFSTQ0KPiAgIHBjaWJpb3NfYWxpZ25fcmVzb3VyY2UuDQo+IC0g
Q2hhbmdlIGhlYWQgZmlsZSBpbiBwY2llLWRlc2lnbndhcmUgZnJvbSBhc20vaGFyZGlycS5oIHRv
IGxpbnV4L2hhcmRpcnEuaC4NCj4gLSBTZXQgcHAtPnJvb3RfYnVzX25yID0gMCBpbiBkcmE3eHgs
IGV4eW5vcywgaW14Niwga2V5c3RvbmUsIGxheWVyc2NhcGUsDQo+ICAgc3BlYXIxM3h4Lg0KPiAt
IFJlbW92ZSB1bm5lY2Vzc2FyeSBwYXJlbnRoZXNlcyBvZiBzb21lIG1hY3JvcyBpbiBwY2llLWhp
c2kuDQo+IC0gVXNlIG1hY3JvIHRvIHJlcGxhY2Ugc29tZSBtYWdpYyB2YWx1ZXMuDQo+IC0gTWVy
Z2UgdHdvIGxvb3BzIHRvZ2V0aGVyIGFuZCBhZGQgc29tZSBjb21tZW50cyBhYm91dCBpdCBpbiBj
b250ZXh0X2NvbmZpZw0KPiAgIGZ1bmN0aW9uIGluIHBjaWUtaGlzaS4NCj4gLSBNb2RpZnkgc29t
ZSB2YWx1ZSBvZiBpdGVtcyBpbiBwY2llIG5vZGUgZXhhbXBsZSBpbiBiaW5kaW5nIGRvY3VtZW50
Lg0KPiANCj4gQ2hhbmdlIGZyb20gUkZDOg0KPiAtIGRlbGV0ZSBkd19wY2llX3NldHVwLCBkd19w
Y2llX3NjYW5fYnVzLCBkd19wY2llX21hcF9pcnEgYW5kIHN0cnVjdCBod19wY2ksDQo+ICAgbWVy
Z2UgcmVsYXRlZCBvcGVyYXRpb25zIGludG8gZHdfcGNpZV9ob3N0X2luaXQuDQo+IA0KPiBMaW5r
IG9mIHY3Og0KPiAtIGh0dHA6Ly93d3cuc3Bpbmljcy5uZXQvbGlzdHMvZGV2aWNldHJlZS9tc2c5
MDY5MC5odG1sDQo+IExpbmsgb2YgdjY6DQo+IC0gaHR0cDovL3d3dy5zcGluaWNzLm5ldC9saXN0
cy9saW51eC1wY2kvbXNnNDM2NjkuaHRtbA0KPiBMaW5rIG9mIHY1Og0KPiAtIGh0dHA6Ly93d3cu
c3Bpbmljcy5uZXQvbGlzdHMvZGV2aWNldHJlZS9tc2c4Nzk1OS5odG1sDQo+IExpbmsgb2YgdjQ6
DQo+IC0gaHR0cDovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9hcm0ta2VybmVsL21zZzQzMzA1MC5o
dG1sDQo+IExpbmsgb2YgdjM6DQo+IC0gaHR0cDovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51
eC1wY2kvbXNnNDI1MzkuaHRtbA0KPiBMaW5rIG9mIHYyOg0KPiAtIGh0dHA6Ly93d3cuc3Bpbmlj
cy5uZXQvbGlzdHMvbGludXgtcGNpL21zZzQxODQ0Lmh0bWwNCj4gTGluayBvZiBSRkMgdjE6DQo+
IC0gaHR0cDovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51eC1wY2kvbXNnNDEzMDUuaHRtbA0K
PiBMaW5rIG9mIFJGQzoNCj4gLSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LXBj
aS9tc2c0MDQzNC5odG1sDQo+IA0KPiBbMV0gaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvcGlw
ZXJtYWlsL2xpbnV4LWFybS1rZXJuZWwvMjAxNS0NCj4gSnVseS8zNTk3NDEuaHRtbA0KPiANCj4g
DQo+IFpob3UgV2FuZyAoNCk6DQo+ICAgUENJOiBkZXNpZ253YXJlOiBBZGQgQVJNNjQgc3VwcG9y
dA0KPiAgIFBDSTogaGlzaTogQWRkIFBDSWUgaG9zdCBzdXBwb3J0IGZvciBIaVNpbGljb24gU29D
IEhpcDA1DQo+ICAgRG9jdW1lbnRhdGlvbjogRFQ6IEFkZCBIaVNpbGljb24gUENJZSBob3N0IGJp
bmRpbmcNCj4gICBNQUlOVEFJTkVSUzogQWRkIHBjaWUtaGlzaSBtYWludGFpbmVyDQo+IA0KPiBn
YWJyaWVsZSBwYW9sb25pICgyKToNCj4gICBQQ0k6IGRlc2lnbndhcmU6IG1vdmUgY2FsY3VsYXRp
b24gb2YgYnVzIGFkZHJlc3NlcyB0byBEUkE3eHgNCj4gICBBUk0vUENJOiByZW1vdmUgYWxpZ25f
cmVzb3VyY2UgaW4gcGNpX3N5c19kYXRhDQo+IA0KPiAgLi4uL2RldmljZXRyZWUvYmluZGluZ3Mv
cGNpL2hpc2lsaWNvbi1wY2llLnR4dCAgICAgfCAgNDYgKysrKw0KPiAgTUFJTlRBSU5FUlMgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDcgKw0KPiAgYXJjaC9hcm0v
aW5jbHVkZS9hc20vbWFjaC9wY2kuaCAgICAgICAgICAgICAgICAgICAgfCAgIDUgLQ0KPiAgYXJj
aC9hcm0va2VybmVsL2Jpb3MzMi5jICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgMTIgKy0N
Cj4gIGRyaXZlcnMvcGNpL2hvc3QvS2NvbmZpZyAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg
ICA4ICsNCj4gIGRyaXZlcnMvcGNpL2hvc3QvTWFrZWZpbGUgICAgICAgICAgICAgICAgICAgICAg
ICAgIHwgICAxICsNCj4gIGRyaXZlcnMvcGNpL2hvc3QvcGNpLWRyYTd4eC5jICAgICAgICAgICAg
ICAgICAgICAgIHwgIDEzICsrDQo+ICBkcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5j
ICAgICAgICAgICAgICAgICB8ICAgMiArLQ0KPiAgZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2ln
bndhcmUuYyAgICAgICAgICAgICAgICAgfCAyMzcgKysrKysrKy0tLS0tLS0tLS0tLS0NCj4gIGRy
aXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmggICAgICAgICAgICAgICAgIHwgIDE0ICst
DQo+ICBkcml2ZXJzL3BjaS9ob3N0L3BjaWUtaGlzaS5jICAgICAgICAgICAgICAgICAgICAgICB8
IDI0Nw0KPiArKysrKysrKysrKysrKysrKysrKysNCj4gIDExIGZpbGVzIGNoYW5nZWQsIDQxMyBp
bnNlcnRpb25zKCspLCAxNzkgZGVsZXRpb25zKC0pDQo+ICBjcmVhdGUgbW9kZSAxMDA2NDQgRG9j
dW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3BjaS9oaXNpbGljb24tcGNpZS50eHQNCj4g
IGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL3BjaS9ob3N0L3BjaWUtaGlzaS5jDQo+IA0KPiAt
LQ0KPiAxLjkuMQ0KDQo=

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

* [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05
@ 2015-09-07  8:17   ` Gabriele Paoloni
  0 siblings, 0 replies; 37+ messages in thread
From: Gabriele Paoloni @ 2015-09-07  8:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Bjorn and all

Do you have any comment on this patchset? I think we should be close to a final one...

Thanks and Regards

Gab

> -----Original Message-----
> From: Wangzhou (B)
> Sent: 25 August 2015 10:59
> To: Bjorn Helgaas; jingoohan1 at gmail.com; pratyush.anand at gmail.com; Arnd
> Bergmann; linux at arm.linux.org.uk; thomas.petazzoni at free-electrons.com;
> Gabriele Paoloni; lorenzo.pieralisi at arm.com; james.morse at arm.com;
> Liviu.Dudau at arm.com; jason at lakedaemon.net; robh at kernel.org
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; zhangjukuo; qiuzhenfa; liudongdong (C); qiujiang;
> xuwei (O); Liguozhu (Kenneth); Wangzhou (B)
> Subject: [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC
> Hip05
> 
> 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.
> 
> This patchset is based on v4.2-rc1.
> 
> Change from v7:
> - Remove pp->root_bus_nr = 0 in dra7xx, exynos, imx6, keystone, layerscape,
>   spear13xx. Pass pp->busn->start to pci_create_root_bus as root bus number.
> - Remove bus-range parsing in pcie-hisi.c.
> 
> Change from v6:
> - Add Pratyush's Acked-by for 1/6 and 2/6.
> - Add James' Tested-by for 3/6.
> 
> Change from v5:
> - Merge 1/6 in this series, discussion about this can be found in [1]
> 
> Change from v4:
> - Change the author of 1/5 to Gabriele.
> - Modify problems in 3/5 pointed by Bjorn.
> - Modify spelling problems in 4/5.
> 
> Change from v3:
> - Change 1/5 to what Gabriele suggested.
> - Use win->__res.start to get *_mod_base in 2/5, this fix a bug in v3 series.
> 
> 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 v7:
> - http://www.spinics.net/lists/devicetree/msg90690.html
> Link of v6:
> - http://www.spinics.net/lists/linux-pci/msg43669.html
> Link of v5:
> - http://www.spinics.net/lists/devicetree/msg87959.html
> Link of v4:
> - http://www.spinics.net/lists/arm-kernel/msg433050.html
> Link of v3:
> - http://www.spinics.net/lists/linux-pci/msg42539.html
> 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
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-
> July/359741.html
> 
> 
> Zhou Wang (4):
>   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
> 
> gabriele paoloni (2):
>   PCI: designware: move calculation of bus addresses to DRA7xx
>   ARM/PCI: remove align_resource in pci_sys_data
> 
>  .../devicetree/bindings/pci/hisilicon-pcie.txt     |  46 ++++
>  MAINTAINERS                                        |   7 +
>  arch/arm/include/asm/mach/pci.h                    |   5 -
>  arch/arm/kernel/bios32.c                           |  12 +-
>  drivers/pci/host/Kconfig                           |   8 +
>  drivers/pci/host/Makefile                          |   1 +
>  drivers/pci/host/pci-dra7xx.c                      |  13 ++
>  drivers/pci/host/pci-keystone-dw.c                 |   2 +-
>  drivers/pci/host/pcie-designware.c                 | 237 +++++++-------------
>  drivers/pci/host/pcie-designware.h                 |  14 +-
>  drivers/pci/host/pcie-hisi.c                       | 247
> +++++++++++++++++++++
>  11 files changed, 413 insertions(+), 179 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] 37+ messages in thread

* RE: [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-08-27 12:56     ` Gabriel Fernandez
@ 2015-09-07 12:17       ` Lian M.H.
  -1 siblings, 0 replies; 37+ messages in thread
From: Lian M.H. @ 2015-09-07 12:17 UTC (permalink / raw)
  To: Gabriel Fernandez, Zhou Wang
  Cc: thomas.petazzoni, robh, lorenzo.pieralisi, Russell King,
	gabriele.paoloni, Arnd Bergmann, devicetree, jingoohan1,
	pratyush.anand, Liviu Dudau, xuwei5, james.morse, qiuzhenfa,
	liudongdong3, linux-pci, Bjorn Helgaas, zhangjukuo,
	liguozhu@hisilicon.com

Hi Zhou,

You can aslo add my Tested-by: Minghuan Lian <Minghuan.Lian@freescale.com>

I submitted my patch based on your patchset. It works well on our SoC ls1021(arm32) ls1043(arm64) and ls2085(arm64)

Best Regards.
Minghuan

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org]
> On Behalf Of Gabriel Fernandez
> Sent: Thursday, August 27, 2015 8:57 PM
> To: Zhou Wang <wangzhou1@hisilicon.com>
> Cc: thomas.petazzoni@free-electrons.com; robh@kernel.org;
> lorenzo.pieralisi@arm.com; Russell King <linux@arm.linux.org.uk>;
> gabriele.paoloni@huawei.com; Arnd Bergmann <arnd@arndb.de>;
> devicetree@vger.kernel.org; jingoohan1@gmail.com;
> pratyush.anand@gmail.com; Liviu Dudau <Liviu.Dudau@arm.com>;
> xuwei5@hisilicon.com; james.morse@arm.com; qiuzhenfa@hisilicon.com;
> liudongdong3@huawei.com; linux-pci@vger.kernel.org; Bjorn Helgaas
> <bhelgaas@google.com>; zhangjukuo@huawei.com; liguozhu@hisilicon.com;
> qiujiang@huawei.com; linux-arm-kernel@lists.infradead.org;
> jason@lakedaemon.net
> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
> 
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
> 
> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> > 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.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> > and ARM64 according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > Program ATU with untranslated address" based on 1/6 in this series. we
> > delete *_mod_base in pcie-designware. This was discussed in [2]
> >
> > 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Tested-By: James Morse <james.morse@arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  14 +--
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pcie-designware.c | 230
> > +++++++++++++------------------------
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  4 files changed, 90 insertions(+), 170 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c
> > b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..ac401be 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> > pcie_port *pp)  {
> >         dw_pcie_setup_rc(pp);
> >
> > -       if (pp->io_mod_base)
> > -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->io_base)
> > +               pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->mem_mod_base)
> > -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->mem_base)
> > +               pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->cfg0_mod_base) {
> > -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->cfg0_base) {
> > +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >         }
> >
> >         dra7xx_pcie_establish_link(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/pcie-designware.c
> > b/drivers/pci/host/pcie-designware.c
> > index c5d407c..e2d1898 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>
> > @@ -69,16 +70,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)  { @@ -255,7 +247,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));
> @@
> > -298,7 +290,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;
> > @@ -327,7 +319,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);  } @@ -363,14
> > +355,12 @@ int 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;
> > -       u32 val, ns;
> > -       const __be32 *addrp;
> > -       int i, index, ret;
> > -
> > -       ns = of_n_size_cells(np);
> > +       LIST_HEAD(res);
> > +       u32 val;
> > +       int i, ret;
> > +       struct resource_entry *win;
> >
> >         cfg_res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "config");
> >         if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                 pp->cfg1_size = resource_size(cfg_res)/2;
> >                 pp->cfg0_base = cfg_res->start;
> >                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -               /* Find the untranslated configuration space address */
> > -               index = of_property_match_string(np, "reg-names",
> "config");
> > -               addrp = of_get_address(np, index, NULL, NULL);
> > -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -               pp->cfg1_mod_base = pp->cfg0_mod_base +
> pp->cfg0_size;
> >         } else {
> >                 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 = range.cpu_addr;
> > -               }
> > -               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 = range.cpu_addr;
> > -               }
> > -               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;
> > -
> > -                       /* Find the untranslated configuration space
> address */
> > -                       pp->cfg0_mod_base = range.cpu_addr;
> > -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -                                           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;
> > +                       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;
> > +                       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;
> > +                       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, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct
> > pcie_port *pp)
> >
> >         if (!pp->ops->rd_other_conf)
> >                 dw_pcie_prog_outbound_atu(pp,
> PCIE_ATU_REGION_INDEX1,
> > -                                         PCIE_ATU_TYPE_MEM,
> pp->mem_mod_base,
> > +                                         PCIE_ATU_TYPE_MEM,
> > + pp->mem_base,
> >                                           pp->mem_bus_addr,
> > pp->mem_size);
> >
> >         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@
> -517,15
> > +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >         val |= PORT_LOGIC_SPEED_CHANGE;
> >         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL,
> 4,
> > val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +       pp->root_bus_nr = pp->busn->start;
> > +       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
> >         dw_pcie_msi_chip.dev = pp->dev;
> > -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +       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);
> > +
> > +#ifdef CONFIG_ARM
> > +       /* support old dtbs that incorrectly describe IRQs */
> > +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -       pci_common_init_dev(pp->dev, &dw_pci);
> > +       pci_assign_unassigned_bus_resources(bus);
> > +       pci_bus_add_devices(bus);
> >
> >         return 0;
> >  }
> > @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO,
> pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO,
> pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -626,7 +606,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) { @@
> > -650,7 +630,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) @@
> > -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> > -                                 &dw_pcie_ops, sys,
> &sys->resources);
> > -       if (!bus)
> > -               return NULL;
> > -
> > -       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..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >         u8                      root_bus_nr;
> >         void __iomem            *dbi_base;
> >         u64                     cfg0_base;
> > -       u64                     cfg0_mod_base;
> >         void __iomem            *va_cfg0_base;
> >         u32                     cfg0_size;
> >         u64                     cfg1_base;
> > -       u64                     cfg1_mod_base;
> >         void __iomem            *va_cfg1_base;
> >         u32                     cfg1_size;
> > -       u64                     io_base;
> > -       u64                     io_mod_base;
> > +       resource_size_t         io_base;
> >         phys_addr_t             io_bus_addr;
> >         u32                     io_size;
> >         u64                     mem_base;
> > -       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;
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-09-07 12:17       ` Lian M.H.
  0 siblings, 0 replies; 37+ messages in thread
From: Lian M.H. @ 2015-09-07 12:17 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Zhou,

You can aslo add my Tested-by: Minghuan Lian <Minghuan.Lian@freescale.com>

I submitted my patch based on your patchset. It works well on our SoC ls1021(arm32) ls1043(arm64) and ls2085(arm64)

Best Regards.
Minghuan

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> On Behalf Of Gabriel Fernandez
> Sent: Thursday, August 27, 2015 8:57 PM
> To: Zhou Wang <wangzhou1@hisilicon.com>
> Cc: thomas.petazzoni at free-electrons.com; robh at kernel.org;
> lorenzo.pieralisi at arm.com; Russell King <linux@arm.linux.org.uk>;
> gabriele.paoloni at huawei.com; Arnd Bergmann <arnd@arndb.de>;
> devicetree at vger.kernel.org; jingoohan1 at gmail.com;
> pratyush.anand at gmail.com; Liviu Dudau <Liviu.Dudau@arm.com>;
> xuwei5 at hisilicon.com; james.morse at arm.com; qiuzhenfa at hisilicon.com;
> liudongdong3 at huawei.com; linux-pci at vger.kernel.org; Bjorn Helgaas
> <bhelgaas@google.com>; zhangjukuo at huawei.com; liguozhu at hisilicon.com;
> qiujiang at huawei.com; linux-arm-kernel at lists.infradead.org;
> jason at lakedaemon.net
> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
> 
> Hi Zhou,
> 
> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> I tested your patchset with a STMicroelectronics PCIe controller.
> This controller is based on designware PCIe driver and works on ARM32.
> 
> Please find my patchset here:
> http://www.spinics.net/lists/kernel/msg2064266.html
> 
> Best Regards.
> 
> Gabriel.
> 
> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
> > 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.
> >
> > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> > and ARM64 according to the suggestion for Gabriele[1]
> >
> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > Program ATU with untranslated address" based on 1/6 in this series. we
> > delete *_mod_base in pcie-designware. This was discussed in [2]
> >
> > 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > Tested-By: James Morse <james.morse@arm.com>
> >
> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > ---
> >  drivers/pci/host/pci-dra7xx.c      |  14 +--
> >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> >  drivers/pci/host/pcie-designware.c | 230
> > +++++++++++++------------------------
> >  drivers/pci/host/pcie-designware.h |  14 +--
> >  4 files changed, 90 insertions(+), 170 deletions(-)
> >
> > diff --git a/drivers/pci/host/pci-dra7xx.c
> > b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..ac401be 100644
> > --- a/drivers/pci/host/pci-dra7xx.c
> > +++ b/drivers/pci/host/pci-dra7xx.c
> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> > pcie_port *pp)  {
> >         dw_pcie_setup_rc(pp);
> >
> > -       if (pp->io_mod_base)
> > -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->io_base)
> > +               pp->io_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->mem_mod_base)
> > -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->mem_base)
> > +               pp->mem_base &= CPU_TO_BUS_ADDR;
> >
> > -       if (pp->cfg0_mod_base) {
> > -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > +       if (pp->cfg0_base) {
> > +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
> >         }
> >
> >         dra7xx_pcie_establish_link(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/pcie-designware.c
> > b/drivers/pci/host/pcie-designware.c
> > index c5d407c..e2d1898 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>
> > @@ -69,16 +70,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)  { @@ -255,7 +247,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));
> @@
> > -298,7 +290,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;
> > @@ -327,7 +319,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);  } @@ -363,14
> > +355,12 @@ int 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;
> > -       u32 val, ns;
> > -       const __be32 *addrp;
> > -       int i, index, ret;
> > -
> > -       ns = of_n_size_cells(np);
> > +       LIST_HEAD(res);
> > +       u32 val;
> > +       int i, ret;
> > +       struct resource_entry *win;
> >
> >         cfg_res = platform_get_resource_byname(pdev,
> IORESOURCE_MEM, "config");
> >         if (cfg_res) {
> > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                 pp->cfg1_size = resource_size(cfg_res)/2;
> >                 pp->cfg0_base = cfg_res->start;
> >                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > -
> > -               /* Find the untranslated configuration space address */
> > -               index = of_property_match_string(np, "reg-names",
> "config");
> > -               addrp = of_get_address(np, index, NULL, NULL);
> > -               pp->cfg0_mod_base = of_read_number(addrp, ns);
> > -               pp->cfg1_mod_base = pp->cfg0_mod_base +
> pp->cfg0_size;
> >         } else {
> >                 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 = range.cpu_addr;
> > -               }
> > -               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 = range.cpu_addr;
> > -               }
> > -               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;
> > -
> > -                       /* Find the untranslated configuration space
> address */
> > -                       pp->cfg0_mod_base = range.cpu_addr;
> > -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
> > -                                           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;
> > +                       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;
> > +                       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;
> > +                       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, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct
> > pcie_port *pp)
> >
> >         if (!pp->ops->rd_other_conf)
> >                 dw_pcie_prog_outbound_atu(pp,
> PCIE_ATU_REGION_INDEX1,
> > -                                         PCIE_ATU_TYPE_MEM,
> pp->mem_mod_base,
> > +                                         PCIE_ATU_TYPE_MEM,
> > + pp->mem_base,
> >                                           pp->mem_bus_addr,
> > pp->mem_size);
> >
> >         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@
> -517,15
> > +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >         val |= PORT_LOGIC_SPEED_CHANGE;
> >         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL,
> 4,
> > val);
> >
> > -#ifdef CONFIG_PCI_MSI
> > +       pp->root_bus_nr = pp->busn->start;
> > +       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
> >         dw_pcie_msi_chip.dev = pp->dev;
> > -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > +       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);
> > +
> > +#ifdef CONFIG_ARM
> > +       /* support old dtbs that incorrectly describe IRQs */
> > +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > +#endif
> >
> > -       pci_common_init_dev(pp->dev, &dw_pci);
> > +       pci_assign_unassigned_bus_resources(bus);
> > +       pci_bus_add_devices(bus);
> >
> >         return 0;
> >  }
> > @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO,
> pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> >
> >         if (bus->parent->number == pp->root_bus_nr) {
> >                 type = PCIE_ATU_TYPE_CFG0;
> > -               cpu_addr = pp->cfg0_mod_base;
> > +               cpu_addr = pp->cfg0_base;
> >                 cfg_size = pp->cfg0_size;
> >                 va_cfg_base = pp->va_cfg0_base;
> >         } else {
> >                 type = PCIE_ATU_TYPE_CFG1;
> > -               cpu_addr = pp->cfg1_mod_base;
> > +               cpu_addr = pp->cfg1_base;
> >                 cfg_size = pp->cfg1_size;
> >                 va_cfg_base = pp->va_cfg1_base;
> >         }
> > @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> *pp, struct pci_bus *bus,
> >                                   busdev, cfg_size);
> >         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> >         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > -                                 PCIE_ATU_TYPE_IO,
> pp->io_mod_base,
> > +                                 PCIE_ATU_TYPE_IO, pp->io_base,
> >                                   pp->io_bus_addr, pp->io_size);
> >
> >         return ret;
> > @@ -626,7 +606,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) { @@
> > -650,7 +630,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) @@
> > -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
> > -                                 &dw_pcie_ops, sys,
> &sys->resources);
> > -       if (!bus)
> > -               return NULL;
> > -
> > -       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..264c969 100644
> > --- a/drivers/pci/host/pcie-designware.h
> > +++ b/drivers/pci/host/pcie-designware.h
> > @@ -27,25 +27,21 @@ struct pcie_port {
> >         u8                      root_bus_nr;
> >         void __iomem            *dbi_base;
> >         u64                     cfg0_base;
> > -       u64                     cfg0_mod_base;
> >         void __iomem            *va_cfg0_base;
> >         u32                     cfg0_size;
> >         u64                     cfg1_base;
> > -       u64                     cfg1_mod_base;
> >         void __iomem            *va_cfg1_base;
> >         u32                     cfg1_size;
> > -       u64                     io_base;
> > -       u64                     io_mod_base;
> > +       resource_size_t         io_base;
> >         phys_addr_t             io_bus_addr;
> >         u32                     io_size;
> >         u64                     mem_base;
> > -       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;
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
  2015-09-07 12:17       ` Lian M.H.
  (?)
@ 2015-09-08  8:39           ` Zhou Wang
  -1 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-09-08  8:39 UTC (permalink / raw)
  To: Lian M.H.
  Cc: Gabriel Fernandez,
	thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	robh-DgEjT+Ai2ygdnm+yROfE0A, lorenzo.pieralisi-5wv7dgnIgG8,
	Russell King, gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA,
	Arnd Bergmann, devicetree-u79uwXL29TY76Z2rM5mHXA,
	jingoohan1-Re5JQEeQqe8AvxtiuMwx3w,
	pratyush.anand-Re5JQEeQqe8AvxtiuMwx3w, Liviu Dudau,
	xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, james.morse-5wv7dgnIgG8,
	qiuzhenfa-C8/M+/jPZTeaMJb+Lgu22Q,
	liudongdong3-hv44wF8Li93QT0dZR+AlfA,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Bjorn Helgaas,
	zhangjukuo-hv44wF8Li93QT0dZR+AlfA@public.gmane.org

On 2015/9/7 20:17, Lian M.H. wrote:
> Hi Zhou,
> 
> You can aslo add my Tested-by: Minghuan Lian <Minghuan.Lian-KZfg59tc24xl57MIdRCFDg@public.gmane.org>
> 
> I submitted my patch based on your patchset. It works well on our SoC ls1021(arm32) ls1043(arm64) and ls2085(arm64)
> 
> Best Regards.
> Minghuan

Hi Minghuan,

Many thanks for your testing. Will add your Tested-by in next version :)

Best Regards,
Zhou

> 
>> -----Original Message-----
>> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org]
>> On Behalf Of Gabriel Fernandez
>> Sent: Thursday, August 27, 2015 8:57 PM
>> To: Zhou Wang <wangzhou1-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
>> Cc: thomas.petazzoni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org; robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org;
>> lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org; Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>;
>> gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA@public.gmane.org; Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>;
>> devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; jingoohan1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org;
>> pratyush.anand-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org; Liviu Dudau <Liviu.Dudau-5wv7dgnIgG8@public.gmane.org>;
>> xuwei5-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org; james.morse-5wv7dgnIgG8@public.gmane.org; qiuzhenfa-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org;
>> liudongdong3-hv44wF8Li93QT0dZR+AlfA@public.gmane.org; linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; Bjorn Helgaas
>> <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>; zhangjukuo-hv44wF8Li93QT0dZR+AlfA@public.gmane.org; liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org;
>> qiujiang-hv44wF8Li93QT0dZR+AlfA@public.gmane.org; linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org;
>> jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org
>> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
>>
>> Hi Zhou,
>>
>> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
>>
>> I tested your patchset with a STMicroelectronics PCIe controller.
>> This controller is based on designware PCIe driver and works on ARM32.
>>
>> Please find my patchset here:
>> http://www.spinics.net/lists/kernel/msg2064266.html
>>
>> Best Regards.
>>
>> Gabriel.
>>
>> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org> wrote:
>>> 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.
>>>
>>> This patch also try to use of_pci_get_host_bridge_resources for ARM32
>>> and ARM64 according to the suggestion for Gabriele[1]
>>>
>>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
>>> Program ATU with untranslated address" based on 1/6 in this series. we
>>> delete *_mod_base in pcie-designware. This was discussed in [2]
>>>
>>> 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-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
>>> Signed-off-by: Gabriele Paoloni <gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>>> Signed-off-by: Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>
>>> Tested-By: James Morse <james.morse-5wv7dgnIgG8@public.gmane.org>
>>>
>>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>>> ---
>>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>>  drivers/pci/host/pcie-designware.c | 230
>>> +++++++++++++------------------------
>>>  drivers/pci/host/pcie-designware.h |  14 +--
>>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>>
>>> diff --git a/drivers/pci/host/pci-dra7xx.c
>>> b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..ac401be 100644
>>> --- a/drivers/pci/host/pci-dra7xx.c
>>> +++ b/drivers/pci/host/pci-dra7xx.c
>>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
>>> pcie_port *pp)  {
>>>         dw_pcie_setup_rc(pp);
>>>
>>> -       if (pp->io_mod_base)
>>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->io_base)
>>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->mem_mod_base)
>>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->mem_base)
>>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->cfg0_mod_base) {
>>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->cfg0_base) {
>>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>>         }
>>>
>>>         dra7xx_pcie_establish_link(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/pcie-designware.c
>>> b/drivers/pci/host/pcie-designware.c
>>> index c5d407c..e2d1898 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>
>>> @@ -69,16 +70,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)  { @@ -255,7 +247,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));
>> @@
>>> -298,7 +290,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;
>>> @@ -327,7 +319,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);  } @@ -363,14
>>> +355,12 @@ int 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;
>>> -       u32 val, ns;
>>> -       const __be32 *addrp;
>>> -       int i, index, ret;
>>> -
>>> -       ns = of_n_size_cells(np);
>>> +       LIST_HEAD(res);
>>> +       u32 val;
>>> +       int i, ret;
>>> +       struct resource_entry *win;
>>>
>>>         cfg_res = platform_get_resource_byname(pdev,
>> IORESOURCE_MEM, "config");
>>>         if (cfg_res) {
>>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>>                 pp->cfg0_base = cfg_res->start;
>>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>>> -
>>> -               /* Find the untranslated configuration space address */
>>> -               index = of_property_match_string(np, "reg-names",
>> "config");
>>> -               addrp = of_get_address(np, index, NULL, NULL);
>>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>>> -               pp->cfg1_mod_base = pp->cfg0_mod_base +
>> pp->cfg0_size;
>>>         } else {
>>>                 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 = range.cpu_addr;
>>> -               }
>>> -               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 = range.cpu_addr;
>>> -               }
>>> -               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;
>>> -
>>> -                       /* Find the untranslated configuration space
>> address */
>>> -                       pp->cfg0_mod_base = range.cpu_addr;
>>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>>> -                                           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;
>>> +                       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;
>>> +                       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;
>>> +                       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, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct
>>> pcie_port *pp)
>>>
>>>         if (!pp->ops->rd_other_conf)
>>>                 dw_pcie_prog_outbound_atu(pp,
>> PCIE_ATU_REGION_INDEX1,
>>> -                                         PCIE_ATU_TYPE_MEM,
>> pp->mem_mod_base,
>>> +                                         PCIE_ATU_TYPE_MEM,
>>> + pp->mem_base,
>>>                                           pp->mem_bus_addr,
>>> pp->mem_size);
>>>
>>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@
>> -517,15
>>> +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL,
>> 4,
>>> val);
>>>
>>> -#ifdef CONFIG_PCI_MSI
>>> +       pp->root_bus_nr = pp->busn->start;
>>> +       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
>>>         dw_pcie_msi_chip.dev = pp->dev;
>>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>>> +       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);
>>> +
>>> +#ifdef CONFIG_ARM
>>> +       /* support old dtbs that incorrectly describe IRQs */
>>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>>> +#endif
>>>
>>> -       pci_common_init_dev(pp->dev, &dw_pci);
>>> +       pci_assign_unassigned_bus_resources(bus);
>>> +       pci_bus_add_devices(bus);
>>>
>>>         return 0;
>>>  }
>>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -626,7 +606,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) { @@
>>> -650,7 +630,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) @@
>>> -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>>> -                                 &dw_pcie_ops, sys,
>> &sys->resources);
>>> -       if (!bus)
>>> -               return NULL;
>>> -
>>> -       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..264c969 100644
>>> --- a/drivers/pci/host/pcie-designware.h
>>> +++ b/drivers/pci/host/pcie-designware.h
>>> @@ -27,25 +27,21 @@ struct pcie_port {
>>>         u8                      root_bus_nr;
>>>         void __iomem            *dbi_base;
>>>         u64                     cfg0_base;
>>> -       u64                     cfg0_mod_base;
>>>         void __iomem            *va_cfg0_base;
>>>         u32                     cfg0_size;
>>>         u64                     cfg1_base;
>>> -       u64                     cfg1_mod_base;
>>>         void __iomem            *va_cfg1_base;
>>>         u32                     cfg1_size;
>>> -       u64                     io_base;
>>> -       u64                     io_mod_base;
>>> +       resource_size_t         io_base;
>>>         phys_addr_t             io_bus_addr;
>>>         u32                     io_size;
>>>         u64                     mem_base;
>>> -       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;
>>> --
>>> 1.9.1
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-09-08  8:39           ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-09-08  8:39 UTC (permalink / raw)
  To: Lian M.H.
  Cc: Gabriel Fernandez, thomas.petazzoni, robh, lorenzo.pieralisi,
	Russell King, gabriele.paoloni, Arnd Bergmann, devicetree,
	jingoohan1, pratyush.anand, Liviu Dudau, xuwei5, james.morse,
	qiuzhenfa, liudongdong3, linux-pci, Bjorn Helgaas, zhangjukuo,
	liguozhu, qiujiang, linux-arm-kernel, jason

On 2015/9/7 20:17, Lian M.H. wrote:
> Hi Zhou,
> 
> You can aslo add my Tested-by: Minghuan Lian <Minghuan.Lian@freescale.com>
> 
> I submitted my patch based on your patchset. It works well on our SoC ls1021(arm32) ls1043(arm64) and ls2085(arm64)
> 
> Best Regards.
> Minghuan

Hi Minghuan,

Many thanks for your testing. Will add your Tested-by in next version :)

Best Regards,
Zhou

> 
>> -----Original Message-----
>> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces@lists.infradead.org]
>> On Behalf Of Gabriel Fernandez
>> Sent: Thursday, August 27, 2015 8:57 PM
>> To: Zhou Wang <wangzhou1@hisilicon.com>
>> Cc: thomas.petazzoni@free-electrons.com; robh@kernel.org;
>> lorenzo.pieralisi@arm.com; Russell King <linux@arm.linux.org.uk>;
>> gabriele.paoloni@huawei.com; Arnd Bergmann <arnd@arndb.de>;
>> devicetree@vger.kernel.org; jingoohan1@gmail.com;
>> pratyush.anand@gmail.com; Liviu Dudau <Liviu.Dudau@arm.com>;
>> xuwei5@hisilicon.com; james.morse@arm.com; qiuzhenfa@hisilicon.com;
>> liudongdong3@huawei.com; linux-pci@vger.kernel.org; Bjorn Helgaas
>> <bhelgaas@google.com>; zhangjukuo@huawei.com; liguozhu@hisilicon.com;
>> qiujiang@huawei.com; linux-arm-kernel@lists.infradead.org;
>> jason@lakedaemon.net
>> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
>>
>> Hi Zhou,
>>
>> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> I tested your patchset with a STMicroelectronics PCIe controller.
>> This controller is based on designware PCIe driver and works on ARM32.
>>
>> Please find my patchset here:
>> http://www.spinics.net/lists/kernel/msg2064266.html
>>
>> Best Regards.
>>
>> Gabriel.
>>
>> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
>>> 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.
>>>
>>> This patch also try to use of_pci_get_host_bridge_resources for ARM32
>>> and ARM64 according to the suggestion for Gabriele[1]
>>>
>>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
>>> Program ATU with untranslated address" based on 1/6 in this series. we
>>> delete *_mod_base in pcie-designware. This was discussed in [2]
>>>
>>> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>>> Tested-By: James Morse <james.morse@arm.com>
>>>
>>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>>> ---
>>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>>  drivers/pci/host/pcie-designware.c | 230
>>> +++++++++++++------------------------
>>>  drivers/pci/host/pcie-designware.h |  14 +--
>>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>>
>>> diff --git a/drivers/pci/host/pci-dra7xx.c
>>> b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..ac401be 100644
>>> --- a/drivers/pci/host/pci-dra7xx.c
>>> +++ b/drivers/pci/host/pci-dra7xx.c
>>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
>>> pcie_port *pp)  {
>>>         dw_pcie_setup_rc(pp);
>>>
>>> -       if (pp->io_mod_base)
>>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->io_base)
>>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->mem_mod_base)
>>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->mem_base)
>>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->cfg0_mod_base) {
>>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->cfg0_base) {
>>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>>         }
>>>
>>>         dra7xx_pcie_establish_link(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/pcie-designware.c
>>> b/drivers/pci/host/pcie-designware.c
>>> index c5d407c..e2d1898 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>
>>> @@ -69,16 +70,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)  { @@ -255,7 +247,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));
>> @@
>>> -298,7 +290,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;
>>> @@ -327,7 +319,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);  } @@ -363,14
>>> +355,12 @@ int 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;
>>> -       u32 val, ns;
>>> -       const __be32 *addrp;
>>> -       int i, index, ret;
>>> -
>>> -       ns = of_n_size_cells(np);
>>> +       LIST_HEAD(res);
>>> +       u32 val;
>>> +       int i, ret;
>>> +       struct resource_entry *win;
>>>
>>>         cfg_res = platform_get_resource_byname(pdev,
>> IORESOURCE_MEM, "config");
>>>         if (cfg_res) {
>>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>>                 pp->cfg0_base = cfg_res->start;
>>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>>> -
>>> -               /* Find the untranslated configuration space address */
>>> -               index = of_property_match_string(np, "reg-names",
>> "config");
>>> -               addrp = of_get_address(np, index, NULL, NULL);
>>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>>> -               pp->cfg1_mod_base = pp->cfg0_mod_base +
>> pp->cfg0_size;
>>>         } else {
>>>                 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 = range.cpu_addr;
>>> -               }
>>> -               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 = range.cpu_addr;
>>> -               }
>>> -               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;
>>> -
>>> -                       /* Find the untranslated configuration space
>> address */
>>> -                       pp->cfg0_mod_base = range.cpu_addr;
>>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>>> -                                           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;
>>> +                       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;
>>> +                       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;
>>> +                       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, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct
>>> pcie_port *pp)
>>>
>>>         if (!pp->ops->rd_other_conf)
>>>                 dw_pcie_prog_outbound_atu(pp,
>> PCIE_ATU_REGION_INDEX1,
>>> -                                         PCIE_ATU_TYPE_MEM,
>> pp->mem_mod_base,
>>> +                                         PCIE_ATU_TYPE_MEM,
>>> + pp->mem_base,
>>>                                           pp->mem_bus_addr,
>>> pp->mem_size);
>>>
>>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@
>> -517,15
>>> +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL,
>> 4,
>>> val);
>>>
>>> -#ifdef CONFIG_PCI_MSI
>>> +       pp->root_bus_nr = pp->busn->start;
>>> +       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
>>>         dw_pcie_msi_chip.dev = pp->dev;
>>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>>> +       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);
>>> +
>>> +#ifdef CONFIG_ARM
>>> +       /* support old dtbs that incorrectly describe IRQs */
>>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>>> +#endif
>>>
>>> -       pci_common_init_dev(pp->dev, &dw_pci);
>>> +       pci_assign_unassigned_bus_resources(bus);
>>> +       pci_bus_add_devices(bus);
>>>
>>>         return 0;
>>>  }
>>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -626,7 +606,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) { @@
>>> -650,7 +630,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) @@
>>> -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>>> -                                 &dw_pcie_ops, sys,
>> &sys->resources);
>>> -       if (!bus)
>>> -               return NULL;
>>> -
>>> -       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..264c969 100644
>>> --- a/drivers/pci/host/pcie-designware.h
>>> +++ b/drivers/pci/host/pcie-designware.h
>>> @@ -27,25 +27,21 @@ struct pcie_port {
>>>         u8                      root_bus_nr;
>>>         void __iomem            *dbi_base;
>>>         u64                     cfg0_base;
>>> -       u64                     cfg0_mod_base;
>>>         void __iomem            *va_cfg0_base;
>>>         u32                     cfg0_size;
>>>         u64                     cfg1_base;
>>> -       u64                     cfg1_mod_base;
>>>         void __iomem            *va_cfg1_base;
>>>         u32                     cfg1_size;
>>> -       u64                     io_base;
>>> -       u64                     io_mod_base;
>>> +       resource_size_t         io_base;
>>>         phys_addr_t             io_bus_addr;
>>>         u32                     io_size;
>>>         u64                     mem_base;
>>> -       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;
>>> --
>>> 1.9.1
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel@lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



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

* [PATCH v8 3/6] PCI: designware: Add ARM64 support
@ 2015-09-08  8:39           ` Zhou Wang
  0 siblings, 0 replies; 37+ messages in thread
From: Zhou Wang @ 2015-09-08  8:39 UTC (permalink / raw)
  To: linux-arm-kernel

On 2015/9/7 20:17, Lian M.H. wrote:
> Hi Zhou,
> 
> You can aslo add my Tested-by: Minghuan Lian <Minghuan.Lian@freescale.com>
> 
> I submitted my patch based on your patchset. It works well on our SoC ls1021(arm32) ls1043(arm64) and ls2085(arm64)
> 
> Best Regards.
> Minghuan

Hi Minghuan,

Many thanks for your testing. Will add your Tested-by in next version :)

Best Regards,
Zhou

> 
>> -----Original Message-----
>> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
>> On Behalf Of Gabriel Fernandez
>> Sent: Thursday, August 27, 2015 8:57 PM
>> To: Zhou Wang <wangzhou1@hisilicon.com>
>> Cc: thomas.petazzoni at free-electrons.com; robh at kernel.org;
>> lorenzo.pieralisi at arm.com; Russell King <linux@arm.linux.org.uk>;
>> gabriele.paoloni at huawei.com; Arnd Bergmann <arnd@arndb.de>;
>> devicetree at vger.kernel.org; jingoohan1 at gmail.com;
>> pratyush.anand at gmail.com; Liviu Dudau <Liviu.Dudau@arm.com>;
>> xuwei5 at hisilicon.com; james.morse at arm.com; qiuzhenfa at hisilicon.com;
>> liudongdong3 at huawei.com; linux-pci at vger.kernel.org; Bjorn Helgaas
>> <bhelgaas@google.com>; zhangjukuo at huawei.com; liguozhu at hisilicon.com;
>> qiujiang at huawei.com; linux-arm-kernel at lists.infradead.org;
>> jason at lakedaemon.net
>> Subject: Re: [PATCH v8 3/6] PCI: designware: Add ARM64 support
>>
>> Hi Zhou,
>>
>> You can add my Tested-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> I tested your patchset with a STMicroelectronics PCIe controller.
>> This controller is based on designware PCIe driver and works on ARM32.
>>
>> Please find my patchset here:
>> http://www.spinics.net/lists/kernel/msg2064266.html
>>
>> Best Regards.
>>
>> Gabriel.
>>
>> On 25 August 2015 at 11:58, Zhou Wang <wangzhou1@hisilicon.com> wrote:
>>> 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.
>>>
>>> This patch also try to use of_pci_get_host_bridge_resources for ARM32
>>> and ARM64 according to the suggestion for Gabriele[1]
>>>
>>> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
>>> Program ATU with untranslated address" based on 1/6 in this series. we
>>> delete *_mod_base in pcie-designware. This was discussed in [2]
>>>
>>> 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: Gabriele Paoloni <gabriele.paoloni@huawei.com>
>>> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
>>> Tested-By: James Morse <james.morse@arm.com>
>>>
>>> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
>>> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
>>> ---
>>>  drivers/pci/host/pci-dra7xx.c      |  14 +--
>>>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>>>  drivers/pci/host/pcie-designware.c | 230
>>> +++++++++++++------------------------
>>>  drivers/pci/host/pcie-designware.h |  14 +--
>>>  4 files changed, 90 insertions(+), 170 deletions(-)
>>>
>>> diff --git a/drivers/pci/host/pci-dra7xx.c
>>> b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..ac401be 100644
>>> --- a/drivers/pci/host/pci-dra7xx.c
>>> +++ b/drivers/pci/host/pci-dra7xx.c
>>> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
>>> pcie_port *pp)  {
>>>         dw_pcie_setup_rc(pp);
>>>
>>> -       if (pp->io_mod_base)
>>> -               pp->io_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->io_base)
>>> +               pp->io_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->mem_mod_base)
>>> -               pp->mem_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->mem_base)
>>> +               pp->mem_base &= CPU_TO_BUS_ADDR;
>>>
>>> -       if (pp->cfg0_mod_base) {
>>> -               pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
>>> -               pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
>>> +       if (pp->cfg0_base) {
>>> +               pp->cfg0_base &= CPU_TO_BUS_ADDR;
>>> +               pp->cfg1_base &= CPU_TO_BUS_ADDR;
>>>         }
>>>
>>>         dra7xx_pcie_establish_link(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/pcie-designware.c
>>> b/drivers/pci/host/pcie-designware.c
>>> index c5d407c..e2d1898 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>
>>> @@ -69,16 +70,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)  { @@ -255,7 +247,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));
>> @@
>>> -298,7 +290,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;
>>> @@ -327,7 +319,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);  } @@ -363,14
>>> +355,12 @@ int 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;
>>> -       u32 val, ns;
>>> -       const __be32 *addrp;
>>> -       int i, index, ret;
>>> -
>>> -       ns = of_n_size_cells(np);
>>> +       LIST_HEAD(res);
>>> +       u32 val;
>>> +       int i, ret;
>>> +       struct resource_entry *win;
>>>
>>>         cfg_res = platform_get_resource_byname(pdev,
>> IORESOURCE_MEM, "config");
>>>         if (cfg_res) {
>>> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>                 pp->cfg1_size = resource_size(cfg_res)/2;
>>>                 pp->cfg0_base = cfg_res->start;
>>>                 pp->cfg1_base = cfg_res->start + pp->cfg0_size;
>>> -
>>> -               /* Find the untranslated configuration space address */
>>> -               index = of_property_match_string(np, "reg-names",
>> "config");
>>> -               addrp = of_get_address(np, index, NULL, NULL);
>>> -               pp->cfg0_mod_base = of_read_number(addrp, ns);
>>> -               pp->cfg1_mod_base = pp->cfg0_mod_base +
>> pp->cfg0_size;
>>>         } else {
>>>                 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 = range.cpu_addr;
>>> -               }
>>> -               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 = range.cpu_addr;
>>> -               }
>>> -               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;
>>> -
>>> -                       /* Find the untranslated configuration space
>> address */
>>> -                       pp->cfg0_mod_base = range.cpu_addr;
>>> -                       pp->cfg1_mod_base = pp->cfg0_mod_base +
>>> -                                           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;
>>> +                       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;
>>> +                       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;
>>> +                       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, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct
>>> pcie_port *pp)
>>>
>>>         if (!pp->ops->rd_other_conf)
>>>                 dw_pcie_prog_outbound_atu(pp,
>> PCIE_ATU_REGION_INDEX1,
>>> -                                         PCIE_ATU_TYPE_MEM,
>> pp->mem_mod_base,
>>> +                                         PCIE_ATU_TYPE_MEM,
>>> + pp->mem_base,
>>>                                           pp->mem_bus_addr,
>>> pp->mem_size);
>>>
>>>         dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@
>> -517,15
>>> +482,30 @@ int dw_pcie_host_init(struct pcie_port *pp)
>>>         val |= PORT_LOGIC_SPEED_CHANGE;
>>>         dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL,
>> 4,
>>> val);
>>>
>>> -#ifdef CONFIG_PCI_MSI
>>> +       pp->root_bus_nr = pp->busn->start;
>>> +       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
>>>         dw_pcie_msi_chip.dev = pp->dev;
>>> -       dw_pci.msi_ctrl = &dw_pcie_msi_chip;
>>> +       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);
>>> +
>>> +#ifdef CONFIG_ARM
>>> +       /* support old dtbs that incorrectly describe IRQs */
>>> +       pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
>>> +#endif
>>>
>>> -       pci_common_init_dev(pp->dev, &dw_pci);
>>> +       pci_assign_unassigned_bus_resources(bus);
>>> +       pci_bus_add_devices(bus);
>>>
>>>         return 0;
>>>  }
>>> @@ -544,12 +524,12 @@ static int dw_pcie_rd_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -559,7 +539,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -579,12 +559,12 @@ static int dw_pcie_wr_other_conf(struct
>>> pcie_port *pp, struct pci_bus *bus,
>>>
>>>         if (bus->parent->number == pp->root_bus_nr) {
>>>                 type = PCIE_ATU_TYPE_CFG0;
>>> -               cpu_addr = pp->cfg0_mod_base;
>>> +               cpu_addr = pp->cfg0_base;
>>>                 cfg_size = pp->cfg0_size;
>>>                 va_cfg_base = pp->va_cfg0_base;
>>>         } else {
>>>                 type = PCIE_ATU_TYPE_CFG1;
>>> -               cpu_addr = pp->cfg1_mod_base;
>>> +               cpu_addr = pp->cfg1_base;
>>>                 cfg_size = pp->cfg1_size;
>>>                 va_cfg_base = pp->va_cfg1_base;
>>>         }
>>> @@ -594,7 +574,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
>> *pp, struct pci_bus *bus,
>>>                                   busdev, cfg_size);
>>>         ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>>>         dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
>>> -                                 PCIE_ATU_TYPE_IO,
>> pp->io_mod_base,
>>> +                                 PCIE_ATU_TYPE_IO, pp->io_base,
>>>                                   pp->io_bus_addr, pp->io_size);
>>>
>>>         return ret;
>>> @@ -626,7 +606,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) { @@
>>> -650,7 +630,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) @@
>>> -674,62 +654,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_scan_root_bus(pp->dev, sys->busnr,
>>> -                                 &dw_pcie_ops, sys,
>> &sys->resources);
>>> -       if (!bus)
>>> -               return NULL;
>>> -
>>> -       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..264c969 100644
>>> --- a/drivers/pci/host/pcie-designware.h
>>> +++ b/drivers/pci/host/pcie-designware.h
>>> @@ -27,25 +27,21 @@ struct pcie_port {
>>>         u8                      root_bus_nr;
>>>         void __iomem            *dbi_base;
>>>         u64                     cfg0_base;
>>> -       u64                     cfg0_mod_base;
>>>         void __iomem            *va_cfg0_base;
>>>         u32                     cfg0_size;
>>>         u64                     cfg1_base;
>>> -       u64                     cfg1_mod_base;
>>>         void __iomem            *va_cfg1_base;
>>>         u32                     cfg1_size;
>>> -       u64                     io_base;
>>> -       u64                     io_mod_base;
>>> +       resource_size_t         io_base;
>>>         phys_addr_t             io_bus_addr;
>>>         u32                     io_size;
>>>         u64                     mem_base;
>>> -       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;
>>> --
>>> 1.9.1
>>>
>>>
>>> _______________________________________________
>>> linux-arm-kernel mailing list
>>> linux-arm-kernel at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2015-09-08  8:40 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-25  9:58 [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05 Zhou Wang
2015-08-25  9:58 ` Zhou Wang
2015-08-25  9:58 ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 1/6] PCI: designware: move calculation of bus addresses to DRA7xx Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 2/6] ARM/PCI: remove align_resource in pci_sys_data Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 3/6] PCI: designware: Add ARM64 support Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-27 12:56   ` Gabriel Fernandez
2015-08-27 12:56     ` Gabriel Fernandez
     [not found]     ` <CAG374jDDY4COvM_UTfGmJfbXQrMywYB511-fZiWen3GU9VhQvw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-08-27 15:21       ` Gabriele Paoloni
2015-08-27 15:21         ` Gabriele Paoloni
2015-08-27 15:21         ` Gabriele Paoloni
2015-08-28  7:14     ` Zhou Wang
2015-08-28  7:14       ` Zhou Wang
2015-08-28  7:14       ` Zhou Wang
2015-09-07 12:17     ` Lian M.H.
2015-09-07 12:17       ` Lian M.H.
     [not found]       ` <DM2PR0301MB0640B12D45C6D292AB08AED5E2540-Cwg/PA1lyPkDupGAvHvivZwN6zqB+hSMnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2015-09-08  8:39         ` Zhou Wang
2015-09-08  8:39           ` Zhou Wang
2015-09-08  8:39           ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 4/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05 Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 5/6] Documentation: DT: Add HiSilicon PCIe host binding Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58 ` [PATCH v8 6/6] MAINTAINERS: Add pcie-hisi maintainer Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-08-25  9:58   ` Zhou Wang
2015-09-07  8:17 ` [PATCH v8 0/6] PCI: hisi: Add PCIe host support for HiSilicon SoC Hip05 Gabriele Paoloni
2015-09-07  8:17   ` Gabriele Paoloni
2015-09-07  8:17   ` Gabriele Paoloni

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.